From b6d4d83443a833471b77bee6ea48c1ac856448da Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Wed, 8 Apr 2015 20:47:55 +0200 Subject: [PATCH 01/36] Start working on the testbed application --- testbed/CMakeLists.txt | 38 + testbed/Gui.cpp | 32 + testbed/Gui.h | 63 + testbed/Main.cpp | 38 + testbed/Scene.cpp | 185 + testbed/Scene.h | 137 + testbed/TestbedApplication.cpp | 263 + testbed/TestbedApplication.h | 143 + testbed/common/Box.cpp | 239 + testbed/common/Box.h | 131 + testbed/common/Capsule.cpp | 179 + testbed/common/Capsule.h | 94 + testbed/common/Cone.cpp | 179 + testbed/common/Cone.h | 93 + testbed/common/ConvexMesh.cpp | 218 + testbed/common/ConvexMesh.h | 84 + testbed/common/Cylinder.cpp | 179 + testbed/common/Cylinder.h | 93 + testbed/common/Dumbbell.cpp | 216 + testbed/common/Dumbbell.h | 91 + testbed/common/Line.cpp | 59 + testbed/common/Line.h | 79 + testbed/common/Sphere.cpp | 179 + testbed/common/Sphere.h | 90 + testbed/common/Viewer.cpp | 342 + testbed/common/Viewer.h | 208 + testbed/common/VisualContactPoint.cpp | 115 + testbed/common/VisualContactPoint.h | 73 + .../examples/collisionshapes/CMakeLists.txt | 42 + .../collisionshapes/CollisionShapes.cpp | 152 + testbed/examples/collisionshapes/Scene.cpp | 444 + testbed/examples/collisionshapes/Scene.h | 158 + testbed/examples/cubes/CMakeLists.txt | 34 + testbed/examples/cubes/Cubes.cpp | 148 + testbed/examples/cubes/Scene.cpp | 197 + testbed/examples/cubes/Scene.h | 120 + testbed/examples/joints/CMakeLists.txt | 34 + testbed/examples/joints/Joints.cpp | 149 + testbed/examples/joints/Scene.cpp | 394 + testbed/examples/joints/Scene.h | 172 + testbed/examples/raycast/CMakeLists.txt | 43 + testbed/examples/raycast/Raycast.cpp | 155 + testbed/examples/raycast/Scene.cpp | 307 + testbed/examples/raycast/Scene.h | 200 + testbed/glfw/.gitignore | 70 + testbed/glfw/CMake/amd64-mingw32msvc.cmake | 13 + testbed/glfw/CMake/i586-mingw32msvc.cmake | 13 + testbed/glfw/CMake/i686-pc-mingw32.cmake | 13 + testbed/glfw/CMake/i686-w64-mingw32.cmake | 13 + testbed/glfw/CMake/modules/FindEGL.cmake | 16 + testbed/glfw/CMake/modules/FindGLESv1.cmake | 16 + testbed/glfw/CMake/modules/FindGLESv2.cmake | 16 + testbed/glfw/CMake/modules/FindMir.cmake | 18 + testbed/glfw/CMake/modules/FindWayland.cmake | 66 + .../glfw/CMake/modules/FindXKBCommon.cmake | 34 + testbed/glfw/CMake/x86_64-w64-mingw32.cmake | 13 + testbed/glfw/CMakeLists.txt | 586 + testbed/glfw/COPYING.txt | 22 + testbed/glfw/README.md | 294 + testbed/glfw/cmake_uninstall.cmake.in | 29 + testbed/glfw/deps/EGL/eglext.h | 565 + testbed/glfw/deps/GL/glext.h | 11626 ++++++++++++++++ testbed/glfw/deps/GL/glxext.h | 906 ++ testbed/glfw/deps/GL/wglext.h | 840 ++ testbed/glfw/deps/KHR/khrplatform.h | 282 + testbed/glfw/deps/getopt.c | 230 + testbed/glfw/deps/getopt.h | 57 + testbed/glfw/deps/glad.c | 728 + testbed/glfw/deps/glad/glad.h | 1925 +++ testbed/glfw/deps/tinycthread.c | 593 + testbed/glfw/deps/tinycthread.h | 440 + testbed/glfw/docs/CMakeLists.txt | 5 + testbed/glfw/docs/Doxyfile.in | 1863 +++ testbed/glfw/docs/DoxygenLayout.xml | 188 + testbed/glfw/docs/build.dox | 303 + testbed/glfw/docs/compat.dox | 179 + testbed/glfw/docs/compile.dox | 315 + testbed/glfw/docs/context.dox | 329 + testbed/glfw/docs/extra.css | 1 + testbed/glfw/docs/extra.less | 370 + testbed/glfw/docs/footer.html | 7 + testbed/glfw/docs/header.html | 34 + testbed/glfw/docs/input.dox | 588 + testbed/glfw/docs/internal.dox | 116 + testbed/glfw/docs/intro.dox | 347 + testbed/glfw/docs/main.dox | 47 + testbed/glfw/docs/monitor.dox | 204 + testbed/glfw/docs/moving.dox | 494 + testbed/glfw/docs/news.dox | 292 + testbed/glfw/docs/quick.dox | 328 + testbed/glfw/docs/rift.dox | 199 + testbed/glfw/docs/spaces.svg | 872 ++ testbed/glfw/docs/window.dox | 803 ++ testbed/glfw/examples/CMakeLists.txt | 80 + testbed/glfw/examples/boing.c | 669 + testbed/glfw/examples/gears.c | 372 + testbed/glfw/examples/heightmap.c | 509 + testbed/glfw/examples/particles.c | 1061 ++ testbed/glfw/examples/simple.c | 102 + testbed/glfw/examples/splitview.c | 511 + testbed/glfw/examples/wave.c | 452 + testbed/glfw/include/GLFW/glfw3.h | 3355 +++++ testbed/glfw/include/GLFW/glfw3native.h | 356 + testbed/glfw/src/CMakeLists.txt | 95 + testbed/glfw/src/cocoa_init.m | 272 + testbed/glfw/src/cocoa_monitor.m | 439 + testbed/glfw/src/cocoa_platform.h | 124 + testbed/glfw/src/cocoa_window.m | 1284 ++ testbed/glfw/src/context.c | 665 + testbed/glfw/src/egl_context.c | 533 + testbed/glfw/src/egl_context.h | 85 + testbed/glfw/src/glfw3.pc.in | 13 + testbed/glfw/src/glfw3Config.cmake.in | 15 + testbed/glfw/src/glfw_config.h.in | 87 + testbed/glfw/src/glx_context.c | 558 + testbed/glfw/src/glx_context.h | 120 + testbed/glfw/src/init.c | 201 + testbed/glfw/src/input.c | 596 + testbed/glfw/src/internal.h | 886 ++ testbed/glfw/src/iokit_joystick.h | 61 + testbed/glfw/src/iokit_joystick.m | 506 + testbed/glfw/src/linux_joystick.c | 322 + testbed/glfw/src/linux_joystick.h | 63 + testbed/glfw/src/mach_time.c | 71 + testbed/glfw/src/mir_init.c | 101 + testbed/glfw/src/mir_monitor.c | 138 + testbed/glfw/src/mir_platform.h | 110 + testbed/glfw/src/mir_window.c | 687 + testbed/glfw/src/monitor.c | 442 + testbed/glfw/src/nsgl_context.h | 62 + testbed/glfw/src/nsgl_context.m | 314 + testbed/glfw/src/posix_time.c | 97 + testbed/glfw/src/posix_time.h | 49 + testbed/glfw/src/posix_tls.c | 66 + testbed/glfw/src/posix_tls.h | 49 + testbed/glfw/src/wgl_context.c | 709 + testbed/glfw/src/wgl_context.h | 89 + testbed/glfw/src/win32_init.c | 394 + testbed/glfw/src/win32_monitor.c | 348 + testbed/glfw/src/win32_platform.h | 250 + testbed/glfw/src/win32_time.c | 86 + testbed/glfw/src/win32_tls.c | 69 + testbed/glfw/src/win32_tls.h | 48 + testbed/glfw/src/win32_window.c | 1312 ++ testbed/glfw/src/window.c | 740 + testbed/glfw/src/winmm_joystick.c | 177 + testbed/glfw/src/winmm_joystick.h | 47 + testbed/glfw/src/wl_init.c | 630 + testbed/glfw/src/wl_monitor.c | 250 + testbed/glfw/src/wl_platform.h | 140 + testbed/glfw/src/wl_window.c | 524 + testbed/glfw/src/x11_init.c | 816 ++ testbed/glfw/src/x11_monitor.c | 490 + testbed/glfw/src/x11_platform.h | 259 + testbed/glfw/src/x11_window.c | 1935 +++ testbed/glfw/src/xkb_unicode.c | 889 ++ testbed/glfw/src/xkb_unicode.h | 33 + testbed/glfw/tests/CMakeLists.txt | 81 + testbed/glfw/tests/accuracy.c | 128 + testbed/glfw/tests/clipboard.c | 149 + testbed/glfw/tests/cursor.c | 289 + testbed/glfw/tests/cursoranim.c | 135 + testbed/glfw/tests/defaults.c | 131 + testbed/glfw/tests/empty.c | 129 + testbed/glfw/tests/events.c | 581 + testbed/glfw/tests/fsaa.c | 162 + testbed/glfw/tests/gamma.c | 181 + testbed/glfw/tests/glfwinfo.c | 429 + testbed/glfw/tests/iconify.c | 254 + testbed/glfw/tests/joysticks.c | 234 + testbed/glfw/tests/modes.c | 240 + testbed/glfw/tests/peter.c | 151 + testbed/glfw/tests/reopen.c | 177 + testbed/glfw/tests/sharing.c | 184 + testbed/glfw/tests/tearing.c | 130 + testbed/glfw/tests/threads.c | 135 + testbed/glfw/tests/title.c | 76 + testbed/glfw/tests/windows.c | 117 + testbed/meshes/capsule.obj | 1060 ++ testbed/meshes/cone.obj | 101 + testbed/meshes/convexmesh.obj | 125 + testbed/meshes/cylinder.obj | 293 + testbed/meshes/dumbbell.obj | 1396 ++ testbed/meshes/sphere.obj | 997 ++ testbed/opengl-framework/CMakeLists.txt | 84 + .../opengl-framework/cmake/FindFREEGLUT.cmake | 32 + testbed/opengl-framework/cmake/FindGLEW.cmake | 65 + testbed/opengl-framework/src/Camera.cpp | 97 + testbed/opengl-framework/src/Camera.h | 181 + .../src/FrameBufferObject.cpp | 115 + .../opengl-framework/src/FrameBufferObject.h | 105 + testbed/opengl-framework/src/Light.cpp | 100 + testbed/opengl-framework/src/Light.h | 181 + testbed/opengl-framework/src/Mesh.cpp | 176 + testbed/opengl-framework/src/Mesh.h | 411 + .../opengl-framework/src/MeshReaderWriter.cpp | 393 + .../opengl-framework/src/MeshReaderWriter.h | 96 + testbed/opengl-framework/src/Object3D.cpp | 41 + testbed/opengl-framework/src/Object3D.h | 149 + testbed/opengl-framework/src/Shader.cpp | 206 + testbed/opengl-framework/src/Shader.h | 260 + testbed/opengl-framework/src/Texture2D.cpp | 84 + testbed/opengl-framework/src/Texture2D.h | 142 + .../src/TextureReaderWriter.cpp | 332 + .../src/TextureReaderWriter.h | 79 + .../src/VertexBufferObject.cpp | 84 + .../opengl-framework/src/VertexBufferObject.h | 106 + testbed/opengl-framework/src/definitions.h | 39 + testbed/opengl-framework/src/maths/Color.h | 85 + testbed/opengl-framework/src/maths/Matrix3.h | 279 + testbed/opengl-framework/src/maths/Matrix4.h | 427 + testbed/opengl-framework/src/maths/Vector2.h | 159 + testbed/opengl-framework/src/maths/Vector3.h | 203 + testbed/opengl-framework/src/maths/Vector4.h | 167 + .../opengl-framework/src/openglframework.h | 48 + testbed/shaders/depth.frag | 32 + testbed/shaders/depth.vert | 36 + testbed/shaders/phong.frag | 67 + testbed/shaders/phong.vert | 50 + 219 files changed, 73886 insertions(+) create mode 100644 testbed/CMakeLists.txt create mode 100644 testbed/Gui.cpp create mode 100644 testbed/Gui.h create mode 100644 testbed/Main.cpp create mode 100644 testbed/Scene.cpp create mode 100644 testbed/Scene.h create mode 100644 testbed/TestbedApplication.cpp create mode 100644 testbed/TestbedApplication.h create mode 100644 testbed/common/Box.cpp create mode 100644 testbed/common/Box.h create mode 100644 testbed/common/Capsule.cpp create mode 100644 testbed/common/Capsule.h create mode 100644 testbed/common/Cone.cpp create mode 100644 testbed/common/Cone.h create mode 100644 testbed/common/ConvexMesh.cpp create mode 100644 testbed/common/ConvexMesh.h create mode 100644 testbed/common/Cylinder.cpp create mode 100644 testbed/common/Cylinder.h create mode 100644 testbed/common/Dumbbell.cpp create mode 100644 testbed/common/Dumbbell.h create mode 100644 testbed/common/Line.cpp create mode 100644 testbed/common/Line.h create mode 100644 testbed/common/Sphere.cpp create mode 100644 testbed/common/Sphere.h create mode 100644 testbed/common/Viewer.cpp create mode 100644 testbed/common/Viewer.h create mode 100644 testbed/common/VisualContactPoint.cpp create mode 100644 testbed/common/VisualContactPoint.h create mode 100644 testbed/examples/collisionshapes/CMakeLists.txt create mode 100644 testbed/examples/collisionshapes/CollisionShapes.cpp create mode 100644 testbed/examples/collisionshapes/Scene.cpp create mode 100644 testbed/examples/collisionshapes/Scene.h create mode 100644 testbed/examples/cubes/CMakeLists.txt create mode 100644 testbed/examples/cubes/Cubes.cpp create mode 100644 testbed/examples/cubes/Scene.cpp create mode 100644 testbed/examples/cubes/Scene.h create mode 100644 testbed/examples/joints/CMakeLists.txt create mode 100644 testbed/examples/joints/Joints.cpp create mode 100644 testbed/examples/joints/Scene.cpp create mode 100644 testbed/examples/joints/Scene.h create mode 100644 testbed/examples/raycast/CMakeLists.txt create mode 100644 testbed/examples/raycast/Raycast.cpp create mode 100644 testbed/examples/raycast/Scene.cpp create mode 100644 testbed/examples/raycast/Scene.h create mode 100644 testbed/glfw/.gitignore create mode 100644 testbed/glfw/CMake/amd64-mingw32msvc.cmake create mode 100644 testbed/glfw/CMake/i586-mingw32msvc.cmake create mode 100644 testbed/glfw/CMake/i686-pc-mingw32.cmake create mode 100644 testbed/glfw/CMake/i686-w64-mingw32.cmake create mode 100644 testbed/glfw/CMake/modules/FindEGL.cmake create mode 100644 testbed/glfw/CMake/modules/FindGLESv1.cmake create mode 100644 testbed/glfw/CMake/modules/FindGLESv2.cmake create mode 100644 testbed/glfw/CMake/modules/FindMir.cmake create mode 100644 testbed/glfw/CMake/modules/FindWayland.cmake create mode 100644 testbed/glfw/CMake/modules/FindXKBCommon.cmake create mode 100644 testbed/glfw/CMake/x86_64-w64-mingw32.cmake create mode 100644 testbed/glfw/CMakeLists.txt create mode 100644 testbed/glfw/COPYING.txt create mode 100644 testbed/glfw/README.md create mode 100644 testbed/glfw/cmake_uninstall.cmake.in create mode 100644 testbed/glfw/deps/EGL/eglext.h create mode 100644 testbed/glfw/deps/GL/glext.h create mode 100644 testbed/glfw/deps/GL/glxext.h create mode 100644 testbed/glfw/deps/GL/wglext.h create mode 100644 testbed/glfw/deps/KHR/khrplatform.h create mode 100644 testbed/glfw/deps/getopt.c create mode 100644 testbed/glfw/deps/getopt.h create mode 100644 testbed/glfw/deps/glad.c create mode 100644 testbed/glfw/deps/glad/glad.h create mode 100644 testbed/glfw/deps/tinycthread.c create mode 100644 testbed/glfw/deps/tinycthread.h create mode 100644 testbed/glfw/docs/CMakeLists.txt create mode 100644 testbed/glfw/docs/Doxyfile.in create mode 100644 testbed/glfw/docs/DoxygenLayout.xml create mode 100644 testbed/glfw/docs/build.dox create mode 100644 testbed/glfw/docs/compat.dox create mode 100644 testbed/glfw/docs/compile.dox create mode 100644 testbed/glfw/docs/context.dox create mode 100644 testbed/glfw/docs/extra.css create mode 100644 testbed/glfw/docs/extra.less create mode 100644 testbed/glfw/docs/footer.html create mode 100644 testbed/glfw/docs/header.html create mode 100644 testbed/glfw/docs/input.dox create mode 100644 testbed/glfw/docs/internal.dox create mode 100644 testbed/glfw/docs/intro.dox create mode 100644 testbed/glfw/docs/main.dox create mode 100644 testbed/glfw/docs/monitor.dox create mode 100644 testbed/glfw/docs/moving.dox create mode 100644 testbed/glfw/docs/news.dox create mode 100644 testbed/glfw/docs/quick.dox create mode 100644 testbed/glfw/docs/rift.dox create mode 100644 testbed/glfw/docs/spaces.svg create mode 100644 testbed/glfw/docs/window.dox create mode 100644 testbed/glfw/examples/CMakeLists.txt create mode 100644 testbed/glfw/examples/boing.c create mode 100644 testbed/glfw/examples/gears.c create mode 100644 testbed/glfw/examples/heightmap.c create mode 100644 testbed/glfw/examples/particles.c create mode 100644 testbed/glfw/examples/simple.c create mode 100644 testbed/glfw/examples/splitview.c create mode 100644 testbed/glfw/examples/wave.c create mode 100644 testbed/glfw/include/GLFW/glfw3.h create mode 100644 testbed/glfw/include/GLFW/glfw3native.h create mode 100644 testbed/glfw/src/CMakeLists.txt create mode 100644 testbed/glfw/src/cocoa_init.m create mode 100644 testbed/glfw/src/cocoa_monitor.m create mode 100644 testbed/glfw/src/cocoa_platform.h create mode 100644 testbed/glfw/src/cocoa_window.m create mode 100644 testbed/glfw/src/context.c create mode 100644 testbed/glfw/src/egl_context.c create mode 100644 testbed/glfw/src/egl_context.h create mode 100644 testbed/glfw/src/glfw3.pc.in create mode 100644 testbed/glfw/src/glfw3Config.cmake.in create mode 100644 testbed/glfw/src/glfw_config.h.in create mode 100644 testbed/glfw/src/glx_context.c create mode 100644 testbed/glfw/src/glx_context.h create mode 100644 testbed/glfw/src/init.c create mode 100644 testbed/glfw/src/input.c create mode 100644 testbed/glfw/src/internal.h create mode 100644 testbed/glfw/src/iokit_joystick.h create mode 100644 testbed/glfw/src/iokit_joystick.m create mode 100644 testbed/glfw/src/linux_joystick.c create mode 100644 testbed/glfw/src/linux_joystick.h create mode 100644 testbed/glfw/src/mach_time.c create mode 100644 testbed/glfw/src/mir_init.c create mode 100644 testbed/glfw/src/mir_monitor.c create mode 100644 testbed/glfw/src/mir_platform.h create mode 100644 testbed/glfw/src/mir_window.c create mode 100644 testbed/glfw/src/monitor.c create mode 100644 testbed/glfw/src/nsgl_context.h create mode 100644 testbed/glfw/src/nsgl_context.m create mode 100644 testbed/glfw/src/posix_time.c create mode 100644 testbed/glfw/src/posix_time.h create mode 100644 testbed/glfw/src/posix_tls.c create mode 100644 testbed/glfw/src/posix_tls.h create mode 100644 testbed/glfw/src/wgl_context.c create mode 100644 testbed/glfw/src/wgl_context.h create mode 100644 testbed/glfw/src/win32_init.c create mode 100644 testbed/glfw/src/win32_monitor.c create mode 100644 testbed/glfw/src/win32_platform.h create mode 100644 testbed/glfw/src/win32_time.c create mode 100644 testbed/glfw/src/win32_tls.c create mode 100644 testbed/glfw/src/win32_tls.h create mode 100644 testbed/glfw/src/win32_window.c create mode 100644 testbed/glfw/src/window.c create mode 100644 testbed/glfw/src/winmm_joystick.c create mode 100644 testbed/glfw/src/winmm_joystick.h create mode 100644 testbed/glfw/src/wl_init.c create mode 100644 testbed/glfw/src/wl_monitor.c create mode 100644 testbed/glfw/src/wl_platform.h create mode 100644 testbed/glfw/src/wl_window.c create mode 100644 testbed/glfw/src/x11_init.c create mode 100644 testbed/glfw/src/x11_monitor.c create mode 100644 testbed/glfw/src/x11_platform.h create mode 100644 testbed/glfw/src/x11_window.c create mode 100644 testbed/glfw/src/xkb_unicode.c create mode 100644 testbed/glfw/src/xkb_unicode.h create mode 100644 testbed/glfw/tests/CMakeLists.txt create mode 100644 testbed/glfw/tests/accuracy.c create mode 100644 testbed/glfw/tests/clipboard.c create mode 100644 testbed/glfw/tests/cursor.c create mode 100644 testbed/glfw/tests/cursoranim.c create mode 100644 testbed/glfw/tests/defaults.c create mode 100644 testbed/glfw/tests/empty.c create mode 100644 testbed/glfw/tests/events.c create mode 100644 testbed/glfw/tests/fsaa.c create mode 100644 testbed/glfw/tests/gamma.c create mode 100644 testbed/glfw/tests/glfwinfo.c create mode 100644 testbed/glfw/tests/iconify.c create mode 100644 testbed/glfw/tests/joysticks.c create mode 100644 testbed/glfw/tests/modes.c create mode 100644 testbed/glfw/tests/peter.c create mode 100644 testbed/glfw/tests/reopen.c create mode 100644 testbed/glfw/tests/sharing.c create mode 100644 testbed/glfw/tests/tearing.c create mode 100644 testbed/glfw/tests/threads.c create mode 100644 testbed/glfw/tests/title.c create mode 100644 testbed/glfw/tests/windows.c create mode 100644 testbed/meshes/capsule.obj create mode 100644 testbed/meshes/cone.obj create mode 100644 testbed/meshes/convexmesh.obj create mode 100644 testbed/meshes/cylinder.obj create mode 100644 testbed/meshes/dumbbell.obj create mode 100644 testbed/meshes/sphere.obj create mode 100644 testbed/opengl-framework/CMakeLists.txt create mode 100644 testbed/opengl-framework/cmake/FindFREEGLUT.cmake create mode 100644 testbed/opengl-framework/cmake/FindGLEW.cmake create mode 100644 testbed/opengl-framework/src/Camera.cpp create mode 100644 testbed/opengl-framework/src/Camera.h create mode 100644 testbed/opengl-framework/src/FrameBufferObject.cpp create mode 100644 testbed/opengl-framework/src/FrameBufferObject.h create mode 100644 testbed/opengl-framework/src/Light.cpp create mode 100644 testbed/opengl-framework/src/Light.h create mode 100644 testbed/opengl-framework/src/Mesh.cpp create mode 100644 testbed/opengl-framework/src/Mesh.h create mode 100644 testbed/opengl-framework/src/MeshReaderWriter.cpp create mode 100644 testbed/opengl-framework/src/MeshReaderWriter.h create mode 100644 testbed/opengl-framework/src/Object3D.cpp create mode 100644 testbed/opengl-framework/src/Object3D.h create mode 100644 testbed/opengl-framework/src/Shader.cpp create mode 100644 testbed/opengl-framework/src/Shader.h create mode 100644 testbed/opengl-framework/src/Texture2D.cpp create mode 100644 testbed/opengl-framework/src/Texture2D.h create mode 100644 testbed/opengl-framework/src/TextureReaderWriter.cpp create mode 100644 testbed/opengl-framework/src/TextureReaderWriter.h create mode 100644 testbed/opengl-framework/src/VertexBufferObject.cpp create mode 100644 testbed/opengl-framework/src/VertexBufferObject.h create mode 100644 testbed/opengl-framework/src/definitions.h create mode 100644 testbed/opengl-framework/src/maths/Color.h create mode 100644 testbed/opengl-framework/src/maths/Matrix3.h create mode 100644 testbed/opengl-framework/src/maths/Matrix4.h create mode 100644 testbed/opengl-framework/src/maths/Vector2.h create mode 100644 testbed/opengl-framework/src/maths/Vector3.h create mode 100644 testbed/opengl-framework/src/maths/Vector4.h create mode 100644 testbed/opengl-framework/src/openglframework.h create mode 100644 testbed/shaders/depth.frag create mode 100644 testbed/shaders/depth.vert create mode 100644 testbed/shaders/phong.frag create mode 100644 testbed/shaders/phong.vert diff --git a/testbed/CMakeLists.txt b/testbed/CMakeLists.txt new file mode 100644 index 00000000..1d0365f3 --- /dev/null +++ b/testbed/CMakeLists.txt @@ -0,0 +1,38 @@ +# Minimum cmake version required +cmake_minimum_required(VERSION 2.6) + +# Project configuration +PROJECT(Testbed) + +# Where to build the executables +SET(EXECUTABLE_OUTPUT_PATH "${OUR_EXECUTABLE_OUTPUT_PATH}/testbed") +SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}) +SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${EXECUTABLE_OUTPUT_PATH}) +SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${EXECUTABLE_OUTPUT_PATH}) + +ADD_SUBDIRECTORY(opengl-framework/) +ADD_SUBDIRECTORY(glfw/) + +# Copy the shaders used for the demo into the build directory +FILE(COPY "shaders/" DESTINATION "${EXECUTABLE_OUTPUT_PATH}/shaders/") + +# Headers +MESSAGE("Test" "${OPENGLFRAMEWORK_DIR}") +INCLUDE_DIRECTORIES("opengl-framework/src/" "glfw/include/" "common/") + +# Source files +SET(TESTBED_SOURCES + Main.cpp + TestbedApplication.h + TestbedApplication.cpp + Gui.h + Gui.cpp + Scene.h + Scene.cpp +) + +# Create the executable +ADD_EXECUTABLE(testbed ${TESTBED_SOURCES}) + +# Link with libraries +TARGET_LINK_LIBRARIES(testbed reactphysics3d openglframework glfw ${GLFW_LIBRARIES}) diff --git a/testbed/Gui.cpp b/testbed/Gui.cpp new file mode 100644 index 00000000..f7ff23eb --- /dev/null +++ b/testbed/Gui.cpp @@ -0,0 +1,32 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Libraries +#include "Gui.h" + +// Display the GUI +void Gui::display() { + +} diff --git a/testbed/Gui.h b/testbed/Gui.h new file mode 100644 index 00000000..b2853d0e --- /dev/null +++ b/testbed/Gui.h @@ -0,0 +1,63 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +#ifndef GUI_H +#define GUI_H + +// Libraries + + +// Class Gui +class Gui { + + private : + + // -------------------- Constants -------------------- // + + + // -------------------- Attributes -------------------- // + + + // -------------------- Methods -------------------- // + + + public : + + // -------------------- Methods -------------------- // + + /// Constructor + Gui(); + + /// Destructor + ~Gui(); + + /// Display the GUI + void display(); + + // -------------------- Methods -------------------- // + +}; + +#endif diff --git a/testbed/Main.cpp b/testbed/Main.cpp new file mode 100644 index 00000000..39fd038f --- /dev/null +++ b/testbed/Main.cpp @@ -0,0 +1,38 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Libraries +#include "TestbedApplication.h" + +// Main function +int main(int argc, char** argv) { + + // Create and start the testbed application + TestbedApplication& application = TestbedApplication::getInstance(); + application.init(); + application.startMainLoop(); + + return 0; +} diff --git a/testbed/Scene.cpp b/testbed/Scene.cpp new file mode 100644 index 00000000..c5db2d5f --- /dev/null +++ b/testbed/Scene.cpp @@ -0,0 +1,185 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Libraries +#include "Scene.h" + +using namespace openglframework; + +// Constructor +Scene::Scene(const std::string& name) : mName(name) { + +} + +// Set the scene position (where the camera needs to look at) +void Scene::setScenePosition(const openglframework::Vector3& position, float sceneRadius) { + + // Set the position and radius of the scene + mCenterScene = position; + mCamera.setSceneRadius(sceneRadius); + + // Reset the camera position and zoom in order to view all the scene + resetCameraToViewAll(); +} + +// Set the camera so that we can view the whole scene +void Scene::resetCameraToViewAll() { + + // Move the camera to the origin of the scene + mCamera.translateWorld(-mCamera.getOrigin()); + + // Move the camera to the center of the scene + mCamera.translateWorld(mCenterScene); + + // Set the zoom of the camera so that the scene center is + // in negative view direction of the camera + mCamera.setZoom(1.0); +} + +// Map the mouse x,y coordinates to a point on a sphere +bool Scene::mapMouseCoordinatesToSphere(double xMouse, double yMouse, Vector3& spherePoint) const { + + // Get the window dimension + int width, height; + glfwGetWindowSize(mWindow, &width, &height); + + if ((xMouse >= 0) && (xMouse <= width) && (yMouse >= 0) && (yMouse <= height)) { + float x = float(xMouse - 0.5f * width) / float(width); + float y = float(0.5f * height - yMouse) / float(height); + float sinx = sin(PI * x * 0.5f); + float siny = sin(PI * y * 0.5f); + float sinx2siny2 = sinx * sinx + siny * siny; + + // Compute the point on the sphere + spherePoint.x = sinx; + spherePoint.y = siny; + spherePoint.z = (sinx2siny2 < 1.0) ? sqrt(1.0f - sinx2siny2) : 0.0f; + + return true; + } + + return false; +} + +// Called when a mouse button event occurs +void Scene::mouseButtonEvent(int button, int action, int mods) { + + // Get the mouse cursor position + double x, y; + glfwGetCursorPos(mWindow, &x, &y); + + // If the mouse button is pressed + if (action == GLFW_PRESS) { + mLastMouseX = x; + mLastMouseY = y; + mIsLastPointOnSphereValid = mapMouseCoordinatesToSphere(x, y, mLastPointOnSphere); + } + else { // If the mouse button is released + mIsLastPointOnSphereValid = false; + } +} + +// Called when a mouse motion event occurs +void Scene::mouseMotionEvent(double xMouse, double yMouse) { + + int leftButtonState = glfwGetMouseButton(mWindow, GLFW_MOUSE_BUTTON_LEFT); + int rightButtonState = glfwGetMouseButton(mWindow, GLFW_MOUSE_BUTTON_RIGHT); + int middleButtonState = glfwGetMouseButton(mWindow, GLFW_MOUSE_BUTTON_MIDDLE); + int altKeyState = glfwGetKey(mWindow, GLFW_KEY_LEFT_ALT); + + // Zoom + if (leftButtonState == GLFW_PRESS && altKeyState == GLFW_PRESS) { + + // Get the window dimension + int width, height; + glfwGetWindowSize(mWindow, &width, &height); + + float dy = static_cast(yMouse - mLastMouseY); + float h = static_cast(height); + + // Zoom the camera + zoom(-dy / h); + } + // Translation + else if (middleButtonState == GLFW_PRESS || rightButtonState == GLFW_PRESS || + (leftButtonState == GLFW_PRESS && altKeyState == GLFW_PRESS)) { + translate(xMouse, yMouse); + } + // Rotation + else if (leftButtonState == GLFW_PRESS) { + rotate(xMouse, yMouse); + } + + // Remember the mouse position + mLastMouseX = xMouse; + mLastMouseY = yMouse; + mIsLastPointOnSphereValid = mapMouseCoordinatesToSphere(xMouse, yMouse, mLastPointOnSphere); +} + +// Called when a scrolling event occurs +void Scene::scrollingEvent(float xAxis, float yAxis) { + zoom(yAxis * SCROLL_SENSITIVITY); +} + +// Zoom the camera +void Scene::zoom(float zoomDiff) { + + // Zoom the camera + mCamera.setZoom(zoomDiff); +} + +// Translate the camera +void Scene::translate(int xMouse, int yMouse) { + float dx = static_cast(xMouse - mLastMouseX); + float dy = static_cast(yMouse - mLastMouseY); + + // Translate the camera + mCamera.translateCamera(-dx / float(mCamera.getWidth()), + -dy / float(mCamera.getHeight()), mCenterScene); +} + +// Rotate the camera +void Scene::rotate(int xMouse, int yMouse) { + + if (mIsLastPointOnSphereValid) { + + Vector3 newPoint3D; + bool isNewPointOK = mapMouseCoordinatesToSphere(xMouse, yMouse, newPoint3D); + + if (isNewPointOK) { + Vector3 axis = mLastPointOnSphere.cross(newPoint3D); + float cosAngle = mLastPointOnSphere.dot(newPoint3D); + + float epsilon = std::numeric_limits::epsilon(); + if (fabs(cosAngle) < 1.0f && axis.length() > epsilon) { + axis.normalize(); + float angle = 2.0f * acos(cosAngle); + + // Rotate the camera around the center of the scene + mCamera.rotateAroundLocalPoint(axis, -angle, mCenterScene); + } + } + } +} diff --git a/testbed/Scene.h b/testbed/Scene.h new file mode 100644 index 00000000..7251da60 --- /dev/null +++ b/testbed/Scene.h @@ -0,0 +1,137 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +#ifndef SCENE_H +#define SCENE_H + +// Libraries +#include "openglframework.h" + +// Class Scene +// Abstract class that represents a 3D scene. +class Scene { + + protected: + + // -------------------- Attributes -------------------- // + + /// Scene name + std::string mName; + + /// Camera + openglframework::Camera mCamera; + + /// Center of the scene + openglframework::Vector3 mCenterScene; + + /// Last mouse coordinates on the windows + double mLastMouseX, mLastMouseY; + + /// Last point computed on a sphere (for camera rotation) + openglframework::Vector3 mLastPointOnSphere; + + /// True if the last point computed on a sphere (for camera rotation) is valid + bool mIsLastPointOnSphereValid; + + // -------------------- Methods -------------------- // + + /// Set the scene position (where the camera needs to look at) + void setScenePosition(const openglframework::Vector3& position, float sceneRadius); + + /// Set the camera so that we can view the whole scene + void resetCameraToViewAll(); + + /// Map mouse coordinates to coordinates on the sphere + bool mapMouseCoordinatesToSphere(double xMouse, double yMouse, + openglframework::Vector3& spherePoint) const; + + + /// Zoom the camera + void zoom(float zoomDiff); + + /// Translate the camera + void translate(int xMouse, int yMouse); + + /// Rotate the camera + void rotate(int xMouse, int yMouse); + + public: + + // -------------------- Methods -------------------- // + + /// Constructor + Scene(const std::string& name); + + /// Destructor + virtual ~Scene(); + + /// Initialize the scene + virtual void init()=0; + + /// Reshape the view + virtual void reshape(int width, int height); + + /// Update the scene (take a simulation step) + virtual void update()=0; + + /// Render the scene + virtual void render()=0; + + /// Reset the scene + virtual void reset()=0; + + /// Called when a keyboard event occurs + virtual void keyboardEvent(int key, int scancode, int action, int mods); + + /// Called when a mouse button event occurs + virtual void mouseButtonEvent(int button, int action, int mods); + + /// Called when a mouse motion event occurs + virtual void mouseMotionEvent(double xMouse, double yMouse); + + /// Called when a scrolling event occurs + virtual void scrollingEvent(float xAxis, float yAxis); + + /// Return a reference to the camera + const openglframework::Camera& getCamera() const; +}; + +// Called when a keyboard event occurs +inline void Scene::keyboardEvent(int key, int scancode, int action, int mods) { + +} + +/// Reshape the view +inline void Scene::reshape(int width, int height) { + mCamera.setDimensions(width, height); +} + +// Return a reference to the camera +inline const openglframework::Camera& Scene::getCamera() const { + return mCamera; +} + + +#endif diff --git a/testbed/TestbedApplication.cpp b/testbed/TestbedApplication.cpp new file mode 100644 index 00000000..ef695cca --- /dev/null +++ b/testbed/TestbedApplication.cpp @@ -0,0 +1,263 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Libraries +#include "TestbedApplication.h" +#include "openglframework.h" +#include +#include +#include + +using namespace openglframework; + +// Initialization of static variables +const float TestbedApplication::SCROLL_SENSITIVITY = 0.02f; + +// Create and return the singleton instance of this class +TestbedApplication& TestbedApplication::getInstance() { + static TestbedApplication instance; + return instance; +} + +// Constructor +TestbedApplication::TestbedApplication() : mFPS(0), mNbFrames(0), mPreviousTime(0) { + + mIsMultisamplingActive = true; + mWidth = 1000; + mHeight = 800; +} + +// Destructor +TestbedApplication::~TestbedApplication() { + + // TODO : Check that this method is called at the end + + // Destroy the window + glfwDestroyWindow(mWindow); + + // Terminate GLFW + glfwTerminate(); +} + +// Initialize the viewer +void TestbedApplication::init() { + + // Set the GLFW error callback method + glfwSetErrorCallback(error_callback); + + // Initialize the GLFW library + if (!glfwInit()) { + std::exit(EXIT_FAILURE); + } + + // Active the multi-sampling by default + if (mIsMultisamplingActive) { + glfwWindowHint(GLFW_SAMPLES, 4); + } + + // Create the GLFW window + mWindow = glfwCreateWindow(mWidth, mHeight, + "ReactPhysics3D Testbed", NULL, NULL); + if (!mWindow) { + glfwTerminate(); + std::exit(EXIT_FAILURE); + } + glfwMakeContextCurrent(mWindow); + + // Disable Vertical Synchronization + glfwSwapInterval(0); + + // Initialize the GLEW library + GLenum errorGLEW = glewInit(); + if (errorGLEW != GLEW_OK) { + + // Problem: glewInit failed, something is wrong + std::cerr << "GLEW Error : " << glewGetErrorString(errorGLEW) << std::endl; + assert(false); + std::exit(EXIT_FAILURE); + } + + if (mIsMultisamplingActive) { + glEnable(GL_MULTISAMPLE); + } + + glfwSetKeyCallback(mWindow, keyboard); + glfwSetMouseButtonCallback(mWindow, mouseButton); + glfwSetCursorPosCallback(mWindow, mouseMotion); + glfwSetScrollCallback(mWindow, scroll); + + // Define the background color (black) + glClearColor(0.0, 0.0, 0.0, 1.0); +} + +void TestbedApplication::update() { + + // Physics simulation + mCurrentScene->update(); + + // Compute the current framerate + //application->computeFPS(); +} + +// Render +void TestbedApplication::render() { + + // Render the scene + mCurrentScene->render(); + + // Display the GUI + mGUI.display(); + + // Check the OpenGL errors + checkOpenGLErrors(); +} + +// Set the dimension of the camera viewport +void TestbedApplication::reshape() { + + // Get the framebuffer dimension + int width, height; + glfwGetFramebufferSize(mWindow, &width, &height); + + // Resize the camera viewport of the current scene + mCurrentScene->reshape(width, height); + + glViewport(0, 0, width, height); +} + +// Start the main loop where rendering occur +void TestbedApplication::startMainLoop() { + + // Loop until the user closes the window + while (!glfwWindowShouldClose(mWindow)) { + + // Reshape the viewport + reshape(); + + // Call the update function + update(); + + // Swap front and back buffers + glfwSwapBuffers(mWindow); + + // Process events + glfwPollEvents(); + } +} + +// Check the OpenGL errors +void TestbedApplication::checkOpenGLErrors() { + GLenum glError; + + // Get the OpenGL errors + glError = glGetError(); + + // While there are errors + while (glError != GL_NO_ERROR) { + + // Get the error string + const GLubyte* stringError = gluErrorString(glError); + + // Display the error + if (stringError) + std::cerr << "OpenGL Error #" << glError << "(" << gluErrorString(glError) << std::endl; + else + std::cerr << "OpenGL Error #" << glError << " (no message available)" << std::endl; + + // Get the next error + glError = glGetError(); + } +} + + +// Compute the FPS +void TestbedApplication::computeFPS() { + + mNbFrames++; + + // Get the number of milliseconds since glutInit called + mCurrentTime = glfwGetTime(); + + // Calculate time passed + double timeInterval = mCurrentTime - mPreviousTime; + + // Update the FPS counter each second + if(timeInterval > 1.0) { + + // calculate the number of frames per second + mFPS = static_cast(mNbFrames) / timeInterval; + + // Set time + mPreviousTime = mCurrentTime; + + // Reset frame count + mNbFrames = 0; + } +} + +// GLFW error callback method +void TestbedApplication::error_callback(int error, const char* description) { + fputs(description, stderr); +} + +// Display the GUI +void TestbedApplication::displayGUI() { + + // Display the FPS + displayFPS(); +} + +// Display the FPS +void TestbedApplication::displayFPS() { + + /* + std::stringstream ss; + ss << mFPS; + std::string fpsString = ss.str(); + std::string windowTitle = mWindowTitle + " | FPS : " + fpsString; + glfwSetWindowTitle(mWindow, windowTitle.c_str()); + */ +} + +// Callback method to receive keyboard events +void TestbedApplication::keyboard(GLFWwindow* window, int key, int scancode, + int action, int mods) { + getInstance().mCurrentScene->keyboardEvent(key, scancode, action, mods); +} + +// Callback method to receive scrolling events +void TestbedApplication::scroll(GLFWwindow* window, double xAxis, double yAxis) { + getInstance().mCurrentScene->scrollingEvent(xAxis, yAxis); +} + +// Called when a mouse button event occurs +void TestbedApplication::mouseButton(GLFWwindow* window, int button, int action, int mods) { + getInstance().mCurrentScene->mouseButtonEvent(button, action, mods); +} + +// Called when a mouse motion event occurs +void TestbedApplication::mouseMotion(GLFWwindow* window, double x, double y) { + getInstance().mCurrentScene->mouseMotionEvent(x, y); +} diff --git a/testbed/TestbedApplication.h b/testbed/TestbedApplication.h new file mode 100644 index 00000000..8165d84c --- /dev/null +++ b/testbed/TestbedApplication.h @@ -0,0 +1,143 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +#ifndef TESTBED_APPLICATION_H +#define TESTBED_APPLICATION_H + +// Libraries +#include "openglframework.h" +#include "GUI.h" +#include "Scene.h" +#include + +/// Class TestbedApplication +/// Singleton class representing the application. +class TestbedApplication { + + private : + + // -------------------- Constants -------------------- // + + static const float SCROLL_SENSITIVITY; + + // -------------------- Attributes -------------------- // + + /// GLFW window + GLFWwindow* mWindow; + + /// Graphical User Interface + Gui mGUI; + + /// List of 3D scenes + std::vector mScenes; + + /// Current 3D scene + Scene* mCurrentScene; + + /// Current number of frames per seconds + double mFPS; + + /// Number of frames during the last second + int mNbFrames; + + /// Current time for fps computation + double mCurrentTime; + + /// Previous time for fps computation + double mPreviousTime; + + /// True if multisampling is active + bool mIsMultisamplingActive; + + /// Width and height of the window + int mWidth, mHeight; + + // -------------------- Methods -------------------- // + + /// Private constructor (for the singleton class) + TestbedApplication(); + + /// Private copy-constructor (for the singleton class) + TestbedApplication(TestbedApplication const&); + + /// Private assignment operator (for the singleton class) + void operator=(TestbedApplication const&); + + /// Update + void update(); + + /// Called when the windows is reshaped + void reshape(); + + /// Render + void render(); + + /// Check the OpenGL errors + static void checkOpenGLErrors(); + + /// Display the FPS + void displayFPS(); + + /// Compute the FPS + void computeFPS(); + + /// Display the GUI + void displayGUI(); + + /// GLFW error callback method + static void error_callback(int error, const char* description); + + /// Callback method to receive keyboard events + static void keyboard(GLFWwindow* window, int key, int scancode, int action, int mods); + + /// Callback method to receive scrolling events + static void scroll(GLFWwindow* window, double xAxis, double yAxis); + + /// Called when a mouse button event occurs + static void mouseButton(GLFWwindow* window, int button, int action, int mods); + + /// Called when a mouse motion event occurs + static void mouseMotion(GLFWwindow* window, double x, double y); + + public : + + // -------------------- Methods -------------------- // + + /// Create and return the singleton instance of this class + static TestbedApplication& getInstance(); + + /// Destructor + ~TestbedApplication(); + + /// Initialize the viewer + void init(); + + /// Start the main loop where rendering occur + void startMainLoop(); +}; + + + +#endif diff --git a/testbed/common/Box.cpp b/testbed/common/Box.cpp new file mode 100644 index 00000000..d0c7a1df --- /dev/null +++ b/testbed/common/Box.cpp @@ -0,0 +1,239 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Libraries +#include "Box.h" + +// Macros +#define MEMBER_OFFSET(s,m) ((char *)NULL + (offsetof(s,m))) + +// Initialize static variables +openglframework::VertexBufferObject Box::mVBOVertices(GL_ARRAY_BUFFER); +openglframework::VertexBufferObject Box::mVBOIndices(GL_ELEMENT_ARRAY_BUFFER); +bool Box::areVBOsCreated = false; +VertexData Box::mCubeVertices[8] = { + {openglframework::Vector3(1,1,1),openglframework::Vector3(1,1,1),openglframework::Color(1,0,0,1)}, + {openglframework::Vector3(-1,1,1),openglframework::Vector3(-1,1,1),openglframework::Color(1,0,0,1)}, + {openglframework::Vector3(-1,-1,1),openglframework::Vector3(-1,-1,1),openglframework::Color(1,0,0,1)}, + {openglframework::Vector3(1,-1,1),openglframework::Vector3(1,-1,1),openglframework::Color(1,0,0,1)}, + {openglframework::Vector3(1,-1,-1),openglframework::Vector3(1,-1,-1),openglframework::Color(1,0,0,1)}, + {openglframework::Vector3(-1,-1,-1),openglframework::Vector3(-1,-1,-1),openglframework::Color(1,0,0,1)}, + {openglframework::Vector3(-1,1,-1),openglframework::Vector3(-1,1,-1),openglframework::Color(1,0,0,1)}, + {openglframework::Vector3(1,1,-1),openglframework::Vector3(1,1,-1),openglframework::Color(1,0,0,1)} +}; +GLuint Box::mCubeIndices[36] = { 0, 1, 2, + 2, 3, 0, + 7, 4, 5, + 5, 6, 7, + 6, 5, 2, + 2, 1, 6, + 7, 0, 3, + 3, 4, 7, + 7, 6, 1, + 1, 0, 7, + 3, 2, 5, + 5, 4, 3}; + +// Constructor +Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &position, + reactphysics3d::CollisionWorld* world) + : openglframework::Object3D(), mColor(0.5f, 0.5f, 0.5f, 1.0f) { + + // Initialize the size of the box + mSize[0] = size.x * 0.5f; + mSize[1] = size.y * 0.5f; + mSize[2] = size.z * 0.5f; + + // Compute the scaling matrix + mScalingMatrix = openglframework::Matrix4(mSize[0], 0, 0, 0, + 0, mSize[1], 0, 0, + 0, 0, mSize[2], 0, + 0, 0, 0, 1); + + // Initialize the position where the cube will be rendered + translateWorld(position); + + // Create the collision shape for the rigid body (box shape) + // ReactPhysics3D will clone this object to create an internal one. Therefore, + // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() + const rp3d::BoxShape collisionShape(rp3d::Vector3(mSize[0], mSize[1], mSize[2])); + + // Initial position and orientation of the rigid body + rp3d::Vector3 initPosition(position.x, position.y, position.z); + rp3d::Quaternion initOrientation = rp3d::Quaternion::identity(); + rp3d::Transform transform(initPosition, initOrientation); + + // Create a rigid body in the dynamics world + mRigidBody = world->createCollisionBody(transform); + + // Add the collision shape to the body + mRigidBody->addCollisionShape(collisionShape, rp3d::Transform::identity()); + + // If the Vertex Buffer object has not been created yet + if (!areVBOsCreated) { + // Create the Vertex Buffer + createVBO(); + } + + mTransformMatrix = mTransformMatrix * mScalingMatrix; +} + +// Constructor +Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &position, + float mass, reactphysics3d::DynamicsWorld* world) + : openglframework::Object3D(), mColor(0.5f, 0.5f, 0.5f, 1.0f) { + + // Initialize the size of the box + mSize[0] = size.x * 0.5f; + mSize[1] = size.y * 0.5f; + mSize[2] = size.z * 0.5f; + + // Compute the scaling matrix + mScalingMatrix = openglframework::Matrix4(mSize[0], 0, 0, 0, + 0, mSize[1], 0, 0, + 0, 0, mSize[2], 0, + 0, 0, 0, 1); + + // Initialize the position where the cube will be rendered + translateWorld(position); + + // Create the collision shape for the rigid body (box shape) + // ReactPhysics3D will clone this object to create an internal one. Therefore, + // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() + const rp3d::BoxShape collisionShape(rp3d::Vector3(mSize[0], mSize[1], mSize[2])); + + // Initial position and orientation of the rigid body + rp3d::Vector3 initPosition(position.x, position.y, position.z); + rp3d::Quaternion initOrientation = rp3d::Quaternion::identity(); + rp3d::Transform transform(initPosition, initOrientation); + + // Create a rigid body in the dynamics world + rp3d::RigidBody* body = world->createRigidBody(transform); + + // Add the collision shape to the body + body->addCollisionShape(collisionShape, rp3d::Transform::identity(), mass); + + mRigidBody = body; + + // If the Vertex Buffer object has not been created yet + if (!areVBOsCreated) { + // Create the Vertex Buffer + createVBO(); + } + + mTransformMatrix = mTransformMatrix * mScalingMatrix; +} + +// Destructor +Box::~Box() { + +} + +// Render the cube at the correct position and with the correct orientation +void Box::render(openglframework::Shader& shader, + const openglframework::Matrix4& worldToCameraMatrix) { + + // Bind the shader + shader.bind(); + + // Set the model to camera matrix + const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix; + shader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix); + + // Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the + // model-view matrix) + const openglframework::Matrix3 normalMatrix = + localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose(); + shader.setMatrix3x3Uniform("normalMatrix", normalMatrix); + + // Set the vertex color + openglframework::Vector4 color(mColor.r, mColor.g, mColor.b, mColor.a); + shader.setVector4Uniform("vertexColor", color); + + // Bind the vertices VBO + mVBOVertices.bind(); + + // Enable the vertex, normal and color arrays + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + + // Set the arrays pointers + glVertexPointer(3, GL_FLOAT, sizeof(VertexData), MEMBER_OFFSET(VertexData, position)); + glNormalPointer(GL_FLOAT, sizeof(VertexData), MEMBER_OFFSET(VertexData, normal)); + glColorPointer(3, GL_FLOAT, sizeof(VertexData), MEMBER_OFFSET(VertexData, color)); + + // Bind the indices VBO + mVBOIndices.bind(); + + // Draw the geometry of the box + glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, (char*)NULL); + + // Unbind the VBOs + mVBOVertices.unbind(); + mVBOIndices.unbind(); + + // Disable the arrays + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + + // Unbind the shader + shader.unbind(); +} + +// Update the transform matrix of the box +void Box::updateTransform() { + + // Get the interpolated transform of the rigid body + rp3d::Transform transform = mRigidBody->getInterpolatedTransform(); + + // Compute the transform used for rendering the box + rp3d::decimal matrix[16]; + transform.getOpenGLMatrix(matrix); + openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12], + matrix[1], matrix[5], matrix[9], matrix[13], + matrix[2], matrix[6], matrix[10], matrix[14], + matrix[3], matrix[7], matrix[11], matrix[15]); + + // Apply the scaling matrix to have the correct box dimensions + mTransformMatrix = newMatrix * mScalingMatrix; +} + +// Create the Vertex Buffer Objects used to render to box with OpenGL. +/// We create two VBOs (one for vertices and one for indices) to render all the boxes +/// in the simulation. +void Box::createVBO() { + + // Create the VBOs + mVBOVertices.create(); + mVBOIndices.create(); + + // Copy the data into the VBOs + mVBOVertices.copyDataIntoVBO(sizeof(mCubeVertices), mCubeVertices, GL_STATIC_DRAW); + mVBOIndices.copyDataIntoVBO(sizeof(mCubeIndices), mCubeIndices, GL_STATIC_DRAW); + + areVBOsCreated = true; +} diff --git a/testbed/common/Box.h b/testbed/common/Box.h new file mode 100644 index 00000000..2cc333d8 --- /dev/null +++ b/testbed/common/Box.h @@ -0,0 +1,131 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +#ifndef BOX_H +#define BOX_H + +// Libraries +#include "openglframework.h" +#include "reactphysics3d.h" + +// Structure VertexData +struct VertexData { + + /// Vertex position + openglframework::Vector3 position; + + /// Vertex normal + openglframework::Vector3 normal; + + // Vertex color + openglframework::Color color; +}; + +// Class Box +class Box : public openglframework::Object3D { + + private : + + // -------------------- Attributes -------------------- // + + /// Size of each side of the box + float mSize[3]; + + /// Rigid body used to simulate the dynamics of the box + rp3d::CollisionBody* mRigidBody; + + /// Scaling matrix (applied to a cube to obtain the correct box dimensions) + openglframework::Matrix4 mScalingMatrix; + + /// Vertex Buffer Object for the vertices data used to render the box with OpenGL + static openglframework::VertexBufferObject mVBOVertices; + + /// Vertex Buffer Object for the indices used to render the box with OpenGL + static openglframework::VertexBufferObject mVBOIndices; + + /// Vertex data for each vertex of the cube (used to render the box) + static VertexData mCubeVertices[8]; + + /// Indices of the cube (used to render the box) + static GLuint mCubeIndices[36]; + + /// True if the VBOs have already been created + static bool areVBOsCreated; + + /// Main color of the box + openglframework::Color mColor; + + // -------------------- Methods -------------------- // + + /// Create a Vertex Buffer Object to render to box with OpenGL + static void createVBO(); + + public : + + // -------------------- Methods -------------------- // + + /// Constructor + Box(const openglframework::Vector3& size, const openglframework::Vector3& position, + reactphysics3d::CollisionWorld* world); + + /// Constructor + Box(const openglframework::Vector3& size, const openglframework::Vector3& position, + float mass, reactphysics3d::DynamicsWorld *world); + + /// Destructor + ~Box(); + + /// Return a pointer to the collision body of the box + reactphysics3d::CollisionBody* getCollisionBody(); + + /// Return a pointer to the rigid body of the box + reactphysics3d::RigidBody* getRigidBody(); + + /// Update the transform matrix of the box + void updateTransform(); + + /// Render the cube at the correct position and with the correct orientation + void render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix); + + /// Set the color of the box + void setColor(const openglframework::Color& color); +}; + +// Return a pointer to the collision body of the box +inline rp3d::CollisionBody* Box::getCollisionBody() { + return mRigidBody; +} + +// Return a pointer to the rigid body of the box +inline rp3d::RigidBody* Box::getRigidBody() { + return dynamic_cast(mRigidBody); +} + +// Set the color of the box +inline void Box::setColor(const openglframework::Color& color) { + mColor = color; +} + +#endif diff --git a/testbed/common/Capsule.cpp b/testbed/common/Capsule.cpp new file mode 100644 index 00000000..faf8484e --- /dev/null +++ b/testbed/common/Capsule.cpp @@ -0,0 +1,179 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Libraries +#include "Capsule.h" + +// Constructor +Capsule::Capsule(float radius, float height, const openglframework::Vector3& position, + reactphysics3d::CollisionWorld* world, + const std::string& meshFolderPath) + : openglframework::Mesh(), mRadius(radius), mHeight(height) { + + // Load the mesh from a file + openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "capsule.obj", *this); + + // Calculate the normals of the mesh + calculateNormals(); + + // Compute the scaling matrix + mScalingMatrix = openglframework::Matrix4(mRadius, 0, 0, 0, + 0, (mHeight + 2.0f * mRadius) / 3.0f, 0,0, + 0, 0, mRadius, 0, + 0, 0, 0, 1.0f); + + // Initialize the position where the sphere will be rendered + translateWorld(position); + + // Create the collision shape for the rigid body (sphere shape) + // ReactPhysics3D will clone this object to create an internal one. Therefore, + // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() + const rp3d::CapsuleShape collisionShape(mRadius, mHeight); + + // Initial position and orientation of the rigid body + rp3d::Vector3 initPosition(position.x, position.y, position.z); + rp3d::Quaternion initOrientation = rp3d::Quaternion::identity(); + rp3d::Transform transform(initPosition, initOrientation); + + // Create a rigid body corresponding in the dynamics world + mRigidBody = world->createCollisionBody(transform); + + // Add a collision shape to the body and specify the mass of the shape + mRigidBody->addCollisionShape(collisionShape, rp3d::Transform::identity()); + + mTransformMatrix = mTransformMatrix * mScalingMatrix; +} + +// Constructor +Capsule::Capsule(float radius, float height, const openglframework::Vector3& position, + float mass, reactphysics3d::DynamicsWorld* dynamicsWorld, + const std::string& meshFolderPath) + : openglframework::Mesh(), mRadius(radius), mHeight(height) { + + // Load the mesh from a file + openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "capsule.obj", *this); + + // Calculate the normals of the mesh + calculateNormals(); + + // Compute the scaling matrix + mScalingMatrix = openglframework::Matrix4(mRadius, 0, 0, 0, + 0, (mHeight + 2.0f * mRadius) / 3.0f, 0,0, + 0, 0, mRadius, 0, + 0, 0, 0, 1.0f); + + // Initialize the position where the sphere will be rendered + translateWorld(position); + + // Create the collision shape for the rigid body (sphere shape) + // ReactPhysics3D will clone this object to create an internal one. Therefore, + // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() + const rp3d::CapsuleShape collisionShape(mRadius, mHeight); + + // Initial position and orientation of the rigid body + rp3d::Vector3 initPosition(position.x, position.y, position.z); + rp3d::Quaternion initOrientation = rp3d::Quaternion::identity(); + rp3d::Transform transform(initPosition, initOrientation); + + // Create a rigid body corresponding in the dynamics world + rp3d::RigidBody* body = dynamicsWorld->createRigidBody(transform); + + // Add a collision shape to the body and specify the mass of the shape + body->addCollisionShape(collisionShape, rp3d::Transform::identity(), mass); + + mRigidBody = body; + + mTransformMatrix = mTransformMatrix * mScalingMatrix; +} + +// Destructor +Capsule::~Capsule() { + + // Destroy the mesh + destroy(); +} + +// Render the sphere at the correct position and with the correct orientation +void Capsule::render(openglframework::Shader& shader, + const openglframework::Matrix4& worldToCameraMatrix) { + + // Bind the shader + shader.bind(); + + // Set the model to camera matrix + const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix; + shader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix); + + // Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the + // model-view matrix) + const openglframework::Matrix3 normalMatrix = + localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose(); + shader.setMatrix3x3Uniform("normalMatrix", normalMatrix); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + if (hasTexture()) { + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + } + + glVertexPointer(3, GL_FLOAT, 0, getVerticesPointer()); + glNormalPointer(GL_FLOAT, 0, getNormalsPointer()); + if(hasTexture()) { + glTexCoordPointer(2, GL_FLOAT, 0, getUVTextureCoordinatesPointer()); + } + + // For each part of the mesh + for (unsigned int i=0; igetInterpolatedTransform(); + + // Compute the transform used for rendering the sphere + rp3d::decimal matrix[16]; + transform.getOpenGLMatrix(matrix); + openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12], + matrix[1], matrix[5], matrix[9], matrix[13], + matrix[2], matrix[6], matrix[10], matrix[14], + matrix[3], matrix[7], matrix[11], matrix[15]); + + // Apply the scaling matrix to have the correct sphere dimensions + mTransformMatrix = newMatrix * mScalingMatrix; +} diff --git a/testbed/common/Capsule.h b/testbed/common/Capsule.h new file mode 100644 index 00000000..2ce438d1 --- /dev/null +++ b/testbed/common/Capsule.h @@ -0,0 +1,94 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +#ifndef CAPSULE_H +#define CAPSULE_H + +// Libraries +#include "openglframework.h" +#include "reactphysics3d.h" + +// Class Sphere +class Capsule : public openglframework::Mesh { + + private : + + // -------------------- Attributes -------------------- // + + /// Radius of the capsule + float mRadius; + + /// Height of the capsule + float mHeight; + + /// Rigid body used to simulate the dynamics of the sphere + rp3d::CollisionBody* mRigidBody; + + /// Scaling matrix (applied to a sphere to obtain the correct sphere dimensions) + openglframework::Matrix4 mScalingMatrix; + + // -------------------- Methods -------------------- // + + public : + + // -------------------- Methods -------------------- // + + /// Constructor + Capsule(float radius, float height, const openglframework::Vector3& position, + reactphysics3d::CollisionWorld* world, const std::string& meshFolderPath); + + /// Constructor + Capsule(float radius, float height, const openglframework::Vector3& position, + float mass, reactphysics3d::DynamicsWorld* dynamicsWorld, + const std::string& meshFolderPath); + + /// Destructor + ~Capsule(); + + /// Return a pointer to the collision body of the box + reactphysics3d::CollisionBody* getCollisionBody(); + + /// Return a pointer to the rigid body of the box + reactphysics3d::RigidBody* getRigidBody(); + + /// Update the transform matrix of the sphere + void updateTransform(); + + /// Render the sphere at the correct position and with the correct orientation + void render(openglframework::Shader& shader, + const openglframework::Matrix4& worldToCameraMatrix); +}; + +// Return a pointer to the collision body of the box +inline rp3d::CollisionBody* Capsule::getCollisionBody() { + return mRigidBody; +} + +// Return a pointer to the rigid body of the box +inline rp3d::RigidBody* Capsule::getRigidBody() { + return dynamic_cast(mRigidBody); +} + +#endif diff --git a/testbed/common/Cone.cpp b/testbed/common/Cone.cpp new file mode 100644 index 00000000..9e3f24b6 --- /dev/null +++ b/testbed/common/Cone.cpp @@ -0,0 +1,179 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Libraries +#include "Cone.h" + +// Constructor +Cone::Cone(float radius, float height, const openglframework::Vector3 &position, + reactphysics3d::CollisionWorld* world, + const std::string& meshFolderPath) + : openglframework::Mesh(), mRadius(radius), mHeight(height) { + + // Load the mesh from a file + openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "cone.obj", *this); + + // Calculate the normals of the mesh + calculateNormals(); + + // Compute the scaling matrix + mScalingMatrix = openglframework::Matrix4(mRadius, 0, 0, 0, + 0, mHeight, 0, 0, + 0, 0, mRadius, 0, + 0, 0, 0, 1); + + // Initialize the position where the cone will be rendered + translateWorld(position); + + // Create the collision shape for the rigid body (cone shape) + // ReactPhysics3D will clone this object to create an internal one. Therefore, + // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() + const rp3d::ConeShape collisionShape(mRadius, mHeight); + + // Initial position and orientation of the rigid body + rp3d::Vector3 initPosition(position.x, position.y, position.z); + rp3d::Quaternion initOrientation = rp3d::Quaternion::identity(); + rp3d::Transform transform(initPosition, initOrientation); + + // Create a rigid body corresponding to the cone in the dynamics world + mRigidBody = world->createCollisionBody(transform); + + // Add a collision shape to the body and specify the mass of the shape + mRigidBody->addCollisionShape(collisionShape, rp3d::Transform::identity()); + + mTransformMatrix = mTransformMatrix * mScalingMatrix; +} + +// Constructor +Cone::Cone(float radius, float height, const openglframework::Vector3 &position, + float mass, reactphysics3d::DynamicsWorld* dynamicsWorld, + const std::string& meshFolderPath) + : openglframework::Mesh(), mRadius(radius), mHeight(height) { + + // Load the mesh from a file + openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "cone.obj", *this); + + // Calculate the normals of the mesh + calculateNormals(); + + // Compute the scaling matrix + mScalingMatrix = openglframework::Matrix4(mRadius, 0, 0, 0, + 0, mHeight, 0, 0, + 0, 0, mRadius, 0, + 0, 0, 0, 1); + + // Initialize the position where the cone will be rendered + translateWorld(position); + + // Create the collision shape for the rigid body (cone shape) + // ReactPhysics3D will clone this object to create an internal one. Therefore, + // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() + const rp3d::ConeShape collisionShape(mRadius, mHeight); + + // Initial position and orientation of the rigid body + rp3d::Vector3 initPosition(position.x, position.y, position.z); + rp3d::Quaternion initOrientation = rp3d::Quaternion::identity(); + rp3d::Transform transform(initPosition, initOrientation); + + // Create a rigid body corresponding to the cone in the dynamics world + rp3d::RigidBody* body = dynamicsWorld->createRigidBody(transform); + + // Add a collision shape to the body and specify the mass of the shape + body->addCollisionShape(collisionShape, rp3d::Transform::identity(), mass); + + mRigidBody = body; + + mTransformMatrix = mTransformMatrix * mScalingMatrix; +} + +// Destructor +Cone::~Cone() { + + // Destroy the mesh + destroy(); +} + +// Render the cone at the correct position and with the correct orientation +void Cone::render(openglframework::Shader& shader, + const openglframework::Matrix4& worldToCameraMatrix) { + + // Bind the shader + shader.bind(); + + // Set the model to camera matrix + const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix; + shader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix); + + // Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the + // model-view matrix) + const openglframework::Matrix3 normalMatrix = + localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose(); + shader.setMatrix3x3Uniform("normalMatrix", normalMatrix); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + if (hasTexture()) { + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + } + + glVertexPointer(3, GL_FLOAT, 0, getVerticesPointer()); + glNormalPointer(GL_FLOAT, 0, getNormalsPointer()); + if(hasTexture()) { + glTexCoordPointer(2, GL_FLOAT, 0, getUVTextureCoordinatesPointer()); + } + + // For each part of the mesh + for (unsigned int i=0; igetInterpolatedTransform(); + + // Compute the transform used for rendering the cone + rp3d::decimal matrix[16]; + transform.getOpenGLMatrix(matrix); + openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12], + matrix[1], matrix[5], matrix[9], matrix[13], + matrix[2], matrix[6], matrix[10], matrix[14], + matrix[3], matrix[7], matrix[11], matrix[15]); + + // Apply the scaling matrix to have the correct cone dimensions + mTransformMatrix = newMatrix * mScalingMatrix; +} diff --git a/testbed/common/Cone.h b/testbed/common/Cone.h new file mode 100644 index 00000000..d3002eab --- /dev/null +++ b/testbed/common/Cone.h @@ -0,0 +1,93 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +#ifndef CONE_H +#define CONE_H + +// Libraries +#include "openglframework.h" +#include "reactphysics3d.h" + +// Class Cone +class Cone : public openglframework::Mesh { + + private : + + // -------------------- Attributes -------------------- // + + /// Radius of the cone + float mRadius; + + /// Height of the cone + float mHeight; + + /// Rigid body used to simulate the dynamics of the cone + rp3d::CollisionBody* mRigidBody; + + /// Scaling matrix (applied to a sphere to obtain the correct cone dimensions) + openglframework::Matrix4 mScalingMatrix; + + // -------------------- Methods -------------------- // + + public : + + // -------------------- Methods -------------------- // + + /// Constructor + Cone(float radius, float height, const openglframework::Vector3& position, + rp3d::CollisionWorld* world, const std::string& meshFolderPath); + + /// Constructor + Cone(float radius, float height, const openglframework::Vector3& position, + float mass, rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath); + + /// Destructor + ~Cone(); + + /// Return a pointer to the collision body of the box + reactphysics3d::CollisionBody* getCollisionBody(); + + /// Return a pointer to the rigid body of the box + reactphysics3d::RigidBody* getRigidBody(); + + /// Update the transform matrix of the cone + void updateTransform(); + + /// Render the cone at the correct position and with the correct orientation + void render(openglframework::Shader& shader, + const openglframework::Matrix4& worldToCameraMatrix); +}; + +// Return a pointer to the collision body of the box +inline rp3d::CollisionBody* Cone::getCollisionBody() { + return mRigidBody; +} + +// Return a pointer to the rigid body of the box +inline rp3d::RigidBody* Cone::getRigidBody() { + return dynamic_cast(mRigidBody); +} + +#endif diff --git a/testbed/common/ConvexMesh.cpp b/testbed/common/ConvexMesh.cpp new file mode 100644 index 00000000..dbb2c28a --- /dev/null +++ b/testbed/common/ConvexMesh.cpp @@ -0,0 +1,218 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Libraries +#include "ConvexMesh.h" + +// Constructor +ConvexMesh::ConvexMesh(const openglframework::Vector3 &position, + reactphysics3d::CollisionWorld* world, + const std::string& meshFolderPath) + : openglframework::Mesh() { + + // Load the mesh from a file + openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "convexmesh.obj", *this); + + // Calculate the normals of the mesh + calculateNormals(); + + // Initialize the position where the sphere will be rendered + translateWorld(position); + + // Convert the vertices array to the rp3d::decimal type + rp3d::decimal* vertices = new rp3d::decimal[3 * mVertices.size()]; + for (int i=0; i < mVertices.size(); i++) { + vertices[3 * i] = static_cast(mVertices[i].x); + vertices[3 * i + 1] = static_cast(mVertices[i].y); + vertices[3 * i + 2] = static_cast(mVertices[i].z); + } + + // Create the collision shape for the rigid body (convex mesh shape) + // ReactPhysics3D will clone this object to create an internal one. Therefore, + // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() + + rp3d::ConvexMeshShape collisionShape(vertices, mVertices.size(), 3 * sizeof(rp3d::decimal)); + + delete[] vertices; + + // Add the edges information of the mesh into the convex mesh collision shape. + // This is optional but it really speed up the convex mesh collision detection at the + // cost of some additional memory to store the edges inside the collision shape. + for (unsigned int i=0; icreateCollisionBody(transform); + + // Add a collision shape to the body and specify the mass of the collision shape + mRigidBody->addCollisionShape(collisionShape, rp3d::Transform::identity()); +} + +// Constructor +ConvexMesh::ConvexMesh(const openglframework::Vector3 &position, float mass, + reactphysics3d::DynamicsWorld* dynamicsWorld, + const std::string& meshFolderPath) + : openglframework::Mesh() { + + // Load the mesh from a file + openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "convexmesh.obj", *this); + + // Calculate the normals of the mesh + calculateNormals(); + + // Initialize the position where the sphere will be rendered + translateWorld(position); + + // Convert the vertices array to the rp3d::decimal type + rp3d::decimal* vertices = new rp3d::decimal[3 * mVertices.size()]; + for (int i=0; i < mVertices.size(); i++) { + vertices[3 * i] = static_cast(mVertices[i].x); + vertices[3 * i + 1] = static_cast(mVertices[i].y); + vertices[3 * i + 2] = static_cast(mVertices[i].z); + } + + // Create the collision shape for the rigid body (convex mesh shape) + // ReactPhysics3D will clone this object to create an internal one. Therefore, + // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() + rp3d::ConvexMeshShape collisionShape(vertices, mVertices.size(), 3 * sizeof(rp3d::decimal)); + + delete[] vertices; + + // Add the edges information of the mesh into the convex mesh collision shape. + // This is optional but it really speed up the convex mesh collision detection at the + // cost of some additional memory to store the edges inside the collision shape. + for (unsigned int i=0; icreateRigidBody(transform); + + // Add a collision shape to the body and specify the mass of the collision shape + body->addCollisionShape(collisionShape, rp3d::Transform::identity(), mass); + + mRigidBody = body; +} + +// Destructor +ConvexMesh::~ConvexMesh() { + + // Destroy the mesh + destroy(); +} + +// Render the sphere at the correct position and with the correct orientation +void ConvexMesh::render(openglframework::Shader& shader, + const openglframework::Matrix4& worldToCameraMatrix) { + + // Bind the shader + shader.bind(); + + // Set the model to camera matrix + const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix; + shader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix); + + // Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the + // model-view matrix) + const openglframework::Matrix3 normalMatrix = + localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose(); + shader.setMatrix3x3Uniform("normalMatrix", normalMatrix); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + if (hasTexture()) { + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + } + + glVertexPointer(3, GL_FLOAT, 0, getVerticesPointer()); + glNormalPointer(GL_FLOAT, 0, getNormalsPointer()); + if(hasTexture()) { + glTexCoordPointer(2, GL_FLOAT, 0, getUVTextureCoordinatesPointer()); + } + + // For each part of the mesh + for (unsigned int i=0; igetInterpolatedTransform(); + + // Compute the transform used for rendering the sphere + rp3d::decimal matrix[16]; + transform.getOpenGLMatrix(matrix); + openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12], + matrix[1], matrix[5], matrix[9], matrix[13], + matrix[2], matrix[6], matrix[10], matrix[14], + matrix[3], matrix[7], matrix[11], matrix[15]); + + // Apply the scaling matrix to have the correct sphere dimensions + mTransformMatrix = newMatrix; +} diff --git a/testbed/common/ConvexMesh.h b/testbed/common/ConvexMesh.h new file mode 100644 index 00000000..f97ec5ec --- /dev/null +++ b/testbed/common/ConvexMesh.h @@ -0,0 +1,84 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +#ifndef CONVEX_MESH_H +#define CONVEX_MESH_H + +// Libraries +#include "openglframework.h" +#include "reactphysics3d.h" + +// Class ConvexMesh +class ConvexMesh : public openglframework::Mesh { + + private : + + // -------------------- Attributes -------------------- // + + /// Rigid body used to simulate the dynamics of the mesh + rp3d::CollisionBody* mRigidBody; + + // -------------------- Methods -------------------- // + + public : + + // -------------------- Methods -------------------- // + + /// Constructor + ConvexMesh(const openglframework::Vector3& position, + rp3d::CollisionWorld* world, const std::string& meshFolderPath); + + /// Constructor + ConvexMesh(const openglframework::Vector3& position, float mass, + rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath); + + /// Destructor + ~ConvexMesh(); + + /// Return a pointer to the collision body of the box + reactphysics3d::CollisionBody* getCollisionBody(); + + /// Return a pointer to the rigid body of the box + reactphysics3d::RigidBody* getRigidBody(); + + /// Update the transform matrix of the mesh + void updateTransform(); + + /// Render the mesh at the correct position and with the correct orientation + void render(openglframework::Shader& shader, + const openglframework::Matrix4& worldToCameraMatrix); +}; + +// Return a pointer to the collision body of the box +inline rp3d::CollisionBody* ConvexMesh::getCollisionBody() { + return mRigidBody; +} + +// Return a pointer to the rigid body of the box +inline rp3d::RigidBody* ConvexMesh::getRigidBody() { + return dynamic_cast(mRigidBody); +} + +#endif diff --git a/testbed/common/Cylinder.cpp b/testbed/common/Cylinder.cpp new file mode 100644 index 00000000..7c2b7690 --- /dev/null +++ b/testbed/common/Cylinder.cpp @@ -0,0 +1,179 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Libraries +#include "Cylinder.h" + +// Constructor +Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& position, + reactphysics3d::CollisionWorld* world, + const std::string& meshFolderPath) + : openglframework::Mesh(), mRadius(radius), mHeight(height) { + + // Load the mesh from a file + openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "cylinder.obj", *this); + + // Calculate the normals of the mesh + calculateNormals(); + + // Compute the scaling matrix + mScalingMatrix = openglframework::Matrix4(mRadius, 0, 0, 0, + 0, mHeight, 0, 0, + 0, 0, mRadius, 0, + 0, 0, 0, 1); + + // Initialize the position where the cylinder will be rendered + translateWorld(position); + + // Create the collision shape for the rigid body (cylinder shape) + // ReactPhysics3D will clone this object to create an internal one. Therefore, + // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() + const rp3d::CylinderShape collisionShape(mRadius, mHeight); + + // Initial position and orientation of the rigid body + rp3d::Vector3 initPosition(position.x, position.y, position.z); + rp3d::Quaternion initOrientation = rp3d::Quaternion::identity(); + rp3d::Transform transform(initPosition, initOrientation); + + // Create a rigid body corresponding to the cylinder in the dynamics world + mRigidBody = world->createCollisionBody(transform); + + // Add a collision shape to the body and specify the mass of the shape + mRigidBody->addCollisionShape(collisionShape, rp3d::Transform::identity()); + + mTransformMatrix = mTransformMatrix * mScalingMatrix; +} + +// Constructor +Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& position, + float mass, reactphysics3d::DynamicsWorld* dynamicsWorld, + const std::string& meshFolderPath) + : openglframework::Mesh(), mRadius(radius), mHeight(height) { + + // Load the mesh from a file + openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "cylinder.obj", *this); + + // Calculate the normals of the mesh + calculateNormals(); + + // Compute the scaling matrix + mScalingMatrix = openglframework::Matrix4(mRadius, 0, 0, 0, + 0, mHeight, 0, 0, + 0, 0, mRadius, 0, + 0, 0, 0, 1); + + // Initialize the position where the cylinder will be rendered + translateWorld(position); + + // Create the collision shape for the rigid body (cylinder shape) + // ReactPhysics3D will clone this object to create an internal one. Therefore, + // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() + const rp3d::CylinderShape collisionShape(mRadius, mHeight); + + // Initial position and orientation of the rigid body + rp3d::Vector3 initPosition(position.x, position.y, position.z); + rp3d::Quaternion initOrientation = rp3d::Quaternion::identity(); + rp3d::Transform transform(initPosition, initOrientation); + + // Create a rigid body corresponding to the cylinder in the dynamics world + rp3d::RigidBody* body = dynamicsWorld->createRigidBody(transform); + + // Add a collision shape to the body and specify the mass of the shape + body->addCollisionShape(collisionShape, rp3d::Transform::identity(), mass); + + mTransformMatrix = mTransformMatrix * mScalingMatrix; + + mRigidBody = body; +} + +// Destructor +Cylinder::~Cylinder() { + + // Destroy the mesh + destroy(); +} + +// Render the cylinder at the correct position and with the correct orientation +void Cylinder::render(openglframework::Shader& shader, + const openglframework::Matrix4& worldToCameraMatrix) { + + // Bind the shader + shader.bind(); + + // Set the model to camera matrix + const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix; + shader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix); + + // Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the + // model-view matrix) + const openglframework::Matrix3 normalMatrix = + localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose(); + shader.setMatrix3x3Uniform("normalMatrix", normalMatrix); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + if (hasTexture()) { + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + } + + glVertexPointer(3, GL_FLOAT, 0, getVerticesPointer()); + glNormalPointer(GL_FLOAT, 0, getNormalsPointer()); + if(hasTexture()) { + glTexCoordPointer(2, GL_FLOAT, 0, getUVTextureCoordinatesPointer()); + } + + // For each part of the mesh + for (unsigned int i=0; igetInterpolatedTransform(); + + // Compute the transform used for rendering the cylinder + rp3d::decimal matrix[16]; + transform.getOpenGLMatrix(matrix); + openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12], + matrix[1], matrix[5], matrix[9], matrix[13], + matrix[2], matrix[6], matrix[10], matrix[14], + matrix[3], matrix[7], matrix[11], matrix[15]); + + // Apply the scaling matrix to have the correct cylinder dimensions + mTransformMatrix = newMatrix * mScalingMatrix; +} diff --git a/testbed/common/Cylinder.h b/testbed/common/Cylinder.h new file mode 100644 index 00000000..9236fe20 --- /dev/null +++ b/testbed/common/Cylinder.h @@ -0,0 +1,93 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +#ifndef CYLINDER_H +#define CYLINDER_H + +// Libraries +#include "openglframework.h" +#include "reactphysics3d.h" + +// Class Cylinder +class Cylinder : public openglframework::Mesh { + + private : + + // -------------------- Attributes -------------------- // + + /// Radius of the cylinder + float mRadius; + + /// Height of the cylinder + float mHeight; + + /// Rigid body used to simulate the dynamics of the cylinder + rp3d::CollisionBody* mRigidBody; + + /// Scaling matrix (applied to a sphere to obtain the correct cylinder dimensions) + openglframework::Matrix4 mScalingMatrix; + + // -------------------- Methods -------------------- // + + public : + + // -------------------- Methods -------------------- // + + /// Constructor + Cylinder(float radius, float height, const openglframework::Vector3& position, + rp3d::CollisionWorld* world, const std::string &meshFolderPath); + + /// Constructor + Cylinder(float radius, float height, const openglframework::Vector3& position, + float mass, rp3d::DynamicsWorld* dynamicsWorld, const std::string &meshFolderPath); + + /// Destructor + ~Cylinder(); + + /// Return a pointer to the collision body of the box + reactphysics3d::CollisionBody* getCollisionBody(); + + /// Return a pointer to the rigid body of the box + reactphysics3d::RigidBody* getRigidBody(); + + /// Update the transform matrix of the cylinder + void updateTransform(); + + /// Render the cylinder at the correct position and with the correct orientation + void render(openglframework::Shader& shader, + const openglframework::Matrix4& worldToCameraMatrix); +}; + +// Return a pointer to the collision body of the box +inline rp3d::CollisionBody* Cylinder::getCollisionBody() { + return mRigidBody; +} + +// Return a pointer to the rigid body of the box +inline rp3d::RigidBody* Cylinder::getRigidBody() { + return dynamic_cast(mRigidBody); +} + +#endif diff --git a/testbed/common/Dumbbell.cpp b/testbed/common/Dumbbell.cpp new file mode 100644 index 00000000..a358db61 --- /dev/null +++ b/testbed/common/Dumbbell.cpp @@ -0,0 +1,216 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Libraries +#include "Dumbbell.h" + +// Constructor +Dumbbell::Dumbbell(const openglframework::Vector3 &position, + reactphysics3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath) + : openglframework::Mesh() { + + // Load the mesh from a file + openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "dumbbell.obj", *this); + + // Calculate the normals of the mesh + calculateNormals(); + + // Identity scaling matrix + mScalingMatrix.setToIdentity(); + + // Initialize the position where the sphere will be rendered + translateWorld(position); + + // Create a sphere collision shape for the two ends of the dumbbell + // ReactPhysics3D will clone this object to create an internal one. Therefore, + // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() + const rp3d::decimal radiusSphere = rp3d::decimal(1.5); + const rp3d::decimal massSphere = rp3d::decimal(2.0); + const rp3d::SphereShape sphereCollisionShape(radiusSphere); + + // Create a cylinder collision shape for the middle of the dumbbell + // ReactPhysics3D will clone this object to create an internal one. Therefore, + // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() + const rp3d::decimal radiusCylinder = rp3d::decimal(0.5); + const rp3d::decimal heightCylinder = rp3d::decimal(8.0); + const rp3d::decimal massCylinder = rp3d::decimal(1.0); + const rp3d::CylinderShape cylinderCollisionShape(radiusCylinder, heightCylinder); + + // Initial position and orientation of the rigid body + rp3d::Vector3 initPosition(position.x, position.y, position.z); + rp3d::decimal angleAroundX = 0;//rp3d::PI / 2; + rp3d::Quaternion initOrientation(angleAroundX, 0, 0); + rp3d::Transform transformBody(initPosition, initOrientation); + + // Initial transform of the first sphere collision shape of the dumbbell (in local-space) + rp3d::Transform transformSphereShape1(rp3d::Vector3(0, 4.0, 0), rp3d::Quaternion::identity()); + + // Initial transform of the second sphere collision shape of the dumbell (in local-space) + rp3d::Transform transformSphereShape2(rp3d::Vector3(0, -4.0, 0), rp3d::Quaternion::identity()); + + // Initial transform of the cylinder collision shape of the dumbell (in local-space) + rp3d::Transform transformCylinderShape(rp3d::Vector3(0, 0, 0), rp3d::Quaternion::identity()); + + // Create a rigid body corresponding to the dumbbell in the dynamics world + rp3d::RigidBody* body = dynamicsWorld->createRigidBody(transformBody); + + // Add the three collision shapes to the body and specify the mass and transform of the shapes + body->addCollisionShape(sphereCollisionShape, transformSphereShape1, massSphere); + body->addCollisionShape(sphereCollisionShape, transformSphereShape2, massSphere); + body->addCollisionShape(cylinderCollisionShape, transformCylinderShape, massCylinder); + + mBody = body; + + mTransformMatrix = mTransformMatrix * mScalingMatrix; +} + +// Constructor +Dumbbell::Dumbbell(const openglframework::Vector3 &position, + reactphysics3d::CollisionWorld* world, const std::string& meshFolderPath) + : openglframework::Mesh() { + + // Load the mesh from a file + openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "dumbbell.obj", *this); + + // Calculate the normals of the mesh + calculateNormals(); + + // Identity scaling matrix + mScalingMatrix.setToIdentity(); + + // Initialize the position where the sphere will be rendered + translateWorld(position); + + // Create a sphere collision shape for the two ends of the dumbbell + // ReactPhysics3D will clone this object to create an internal one. Therefore, + // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() + const rp3d::decimal radiusSphere = rp3d::decimal(1.5); + const rp3d::decimal massSphere = rp3d::decimal(2.0); + const rp3d::SphereShape sphereCollisionShape(radiusSphere); + + // Create a cylinder collision shape for the middle of the dumbbell + // ReactPhysics3D will clone this object to create an internal one. Therefore, + // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() + const rp3d::decimal radiusCylinder = rp3d::decimal(0.5); + const rp3d::decimal heightCylinder = rp3d::decimal(8.0); + const rp3d::decimal massCylinder = rp3d::decimal(1.0); + const rp3d::CylinderShape cylinderCollisionShape(radiusCylinder, heightCylinder); + + // Initial position and orientation of the rigid body + rp3d::Vector3 initPosition(position.x, position.y, position.z); + rp3d::decimal angleAroundX = 0;//rp3d::PI / 2; + rp3d::Quaternion initOrientation(angleAroundX, 0, 0); + rp3d::Transform transformBody(initPosition, initOrientation); + + // Initial transform of the first sphere collision shape of the dumbbell (in local-space) + rp3d::Transform transformSphereShape1(rp3d::Vector3(0, 4.0, 0), rp3d::Quaternion::identity()); + + // Initial transform of the second sphere collision shape of the dumbell (in local-space) + rp3d::Transform transformSphereShape2(rp3d::Vector3(0, -4.0, 0), rp3d::Quaternion::identity()); + + // Initial transform of the cylinder collision shape of the dumbell (in local-space) + rp3d::Transform transformCylinderShape(rp3d::Vector3(0, 0, 0), rp3d::Quaternion::identity()); + + // Create a rigid body corresponding to the dumbbell in the dynamics world + mBody = world->createCollisionBody(transformBody); + + // Add the three collision shapes to the body and specify the mass and transform of the shapes + mBody->addCollisionShape(sphereCollisionShape, transformSphereShape1); + mBody->addCollisionShape(sphereCollisionShape, transformSphereShape2); + mBody->addCollisionShape(cylinderCollisionShape, transformCylinderShape); + + mTransformMatrix = mTransformMatrix * mScalingMatrix; +} + +// Destructor +Dumbbell::~Dumbbell() { + + // Destroy the mesh + destroy(); +} + +// Render the sphere at the correct position and with the correct orientation +void Dumbbell::render(openglframework::Shader& shader, + const openglframework::Matrix4& worldToCameraMatrix) { + + // Bind the shader + shader.bind(); + + // Set the model to camera matrix + const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix; + shader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix); + + // Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the + // model-view matrix) + const openglframework::Matrix3 normalMatrix = + localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose(); + shader.setMatrix3x3Uniform("normalMatrix", normalMatrix); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + if (hasTexture()) { + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + } + + glVertexPointer(3, GL_FLOAT, 0, getVerticesPointer()); + glNormalPointer(GL_FLOAT, 0, getNormalsPointer()); + if(hasTexture()) { + glTexCoordPointer(2, GL_FLOAT, 0, getUVTextureCoordinatesPointer()); + } + + // For each part of the mesh + for (unsigned int i=0; igetInterpolatedTransform(); + + // Compute the transform used for rendering the sphere + rp3d::decimal matrix[16]; + transform.getOpenGLMatrix(matrix); + openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12], + matrix[1], matrix[5], matrix[9], matrix[13], + matrix[2], matrix[6], matrix[10], matrix[14], + matrix[3], matrix[7], matrix[11], matrix[15]); + + // Apply the scaling matrix to have the correct sphere dimensions + mTransformMatrix = newMatrix * mScalingMatrix; +} + diff --git a/testbed/common/Dumbbell.h b/testbed/common/Dumbbell.h new file mode 100644 index 00000000..ff673951 --- /dev/null +++ b/testbed/common/Dumbbell.h @@ -0,0 +1,91 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +#ifndef DUMBBELL_H +#define DUMBBELL_H + +// Libraries +#include "openglframework.h" +#include "reactphysics3d.h" + +// Class Sphere +class Dumbbell : public openglframework::Mesh { + + private : + + // -------------------- Attributes -------------------- // + + /// Radius of the spheres + float mRadius; + + /// Rigid body used to simulate the dynamics of the sphere + rp3d::CollisionBody* mBody; + + /// Scaling matrix (applied to a sphere to obtain the correct sphere dimensions) + openglframework::Matrix4 mScalingMatrix; + + // -------------------- Methods -------------------- // + + public : + + // -------------------- Methods -------------------- // + + /// Constructor + Dumbbell(const openglframework::Vector3& position, rp3d::DynamicsWorld* dynamicsWorld, + const std::string& meshFolderPath); + + /// Constructor + Dumbbell(const openglframework::Vector3& position, rp3d::CollisionWorld* world, + const std::string& meshFolderPath); + + + /// Destructor + ~Dumbbell(); + + /// Return a pointer to the rigid body + rp3d::RigidBody* getRigidBody(); + + /// Return a pointer to the body + rp3d::CollisionBody* getCollisionBody(); + + /// Update the transform matrix of the sphere + void updateTransform(); + + /// Render the sphere at the correct position and with the correct orientation + void render(openglframework::Shader& shader, + const openglframework::Matrix4& worldToCameraMatrix); +}; + +// Return a pointer to the rigid body of the sphere +inline rp3d::RigidBody* Dumbbell::getRigidBody() { + return dynamic_cast(mBody); +} + +// Return a pointer to the body +inline rp3d::CollisionBody* Dumbbell::getCollisionBody() { + return mBody; +} + +#endif diff --git a/testbed/common/Line.cpp b/testbed/common/Line.cpp new file mode 100644 index 00000000..9263c1d6 --- /dev/null +++ b/testbed/common/Line.cpp @@ -0,0 +1,59 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Libraries +#include "Line.h" + +// Constructor +Line::Line(const openglframework::Vector3& worldPoint1, + const openglframework::Vector3& worldPoint2) + : mWorldPoint1(worldPoint1), mWorldPoint2(worldPoint2) { + +} + +// Destructor +Line::~Line() { + + +} + +// Render the sphere at the correct position and with the correct orientation +void Line::render(openglframework::Shader& shader, + const openglframework::Matrix4& worldToCameraMatrix) { + + // Bind the shader + shader.bind(); + + // Set the model to camera matrix + shader.setMatrix4x4Uniform("localToCameraMatrix", worldToCameraMatrix); + + glBegin(GL_LINES); + glVertex3f(mWorldPoint1.x, mWorldPoint1.y, mWorldPoint1.z); + glVertex3f(mWorldPoint2.x, mWorldPoint2.y, mWorldPoint2.z); + glEnd(); + + // Unbind the shader + shader.unbind(); +} diff --git a/testbed/common/Line.h b/testbed/common/Line.h new file mode 100644 index 00000000..41de3266 --- /dev/null +++ b/testbed/common/Line.h @@ -0,0 +1,79 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +#ifndef LINE_H +#define LINE_H + +// Libraries +#include "openglframework.h" +#include "reactphysics3d.h" + +// Class Line +class Line : public openglframework::Object3D { + + private : + + // -------------------- Attributes -------------------- // + + openglframework::Vector3 mWorldPoint1, mWorldPoint2; + + // -------------------- Methods -------------------- // + + public : + + // -------------------- Methods -------------------- // + + /// Constructor + Line(const openglframework::Vector3& worldPoint1, + const openglframework::Vector3& worldPoint2); + + /// Destructor + ~Line(); + + /// Return the first point of the line + openglframework::Vector3 getPoint1() const; + + /// Return the second point of the line + openglframework::Vector3 getPoint2() const; + + /// Update the transform matrix of the sphere + void updateTransform(); + + /// Render the line at the correct position and with the correct orientation + void render(openglframework::Shader& shader, + const openglframework::Matrix4& worldToCameraMatrix); +}; + +// Return the first point of the line +inline openglframework::Vector3 Line::getPoint1() const { + return mWorldPoint1; +} + +// Return the second point of the line +inline openglframework::Vector3 Line::getPoint2() const { + return mWorldPoint2; +} + +#endif diff --git a/testbed/common/Sphere.cpp b/testbed/common/Sphere.cpp new file mode 100644 index 00000000..56882569 --- /dev/null +++ b/testbed/common/Sphere.cpp @@ -0,0 +1,179 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Libraries +#include "Sphere.h" + +// Constructor +Sphere::Sphere(float radius, const openglframework::Vector3 &position, + reactphysics3d::CollisionWorld* world, + const std::string& meshFolderPath) + : openglframework::Mesh(), mRadius(radius) { + + // Load the mesh from a file + openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "sphere.obj", *this); + + // Calculate the normals of the mesh + calculateNormals(); + + // Compute the scaling matrix + mScalingMatrix = openglframework::Matrix4(mRadius, 0, 0, 0, + 0, mRadius, 0, 0, + 0, 0, mRadius, 0, + 0, 0, 0, 1); + + // Initialize the position where the sphere will be rendered + translateWorld(position); + + // Create the collision shape for the rigid body (sphere shape) + // ReactPhysics3D will clone this object to create an internal one. Therefore, + // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() + const rp3d::SphereShape collisionShape(mRadius); + + // Initial position and orientation of the rigid body + rp3d::Vector3 initPosition(position.x, position.y, position.z); + rp3d::Quaternion initOrientation = rp3d::Quaternion::identity(); + rp3d::Transform transform(initPosition, initOrientation); + + // Create a rigid body corresponding to the sphere in the dynamics world + mRigidBody = world->createCollisionBody(transform); + + // Add a collision shape to the body and specify the mass of the shape + mRigidBody->addCollisionShape(collisionShape, rp3d::Transform::identity()); + + mTransformMatrix = mTransformMatrix * mScalingMatrix; +} + +// Constructor +Sphere::Sphere(float radius, const openglframework::Vector3 &position, + float mass, reactphysics3d::DynamicsWorld* world, + const std::string& meshFolderPath) + : openglframework::Mesh(), mRadius(radius) { + + // Load the mesh from a file + openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "sphere.obj", *this); + + // Calculate the normals of the mesh + calculateNormals(); + + // Compute the scaling matrix + mScalingMatrix = openglframework::Matrix4(mRadius, 0, 0, 0, + 0, mRadius, 0, 0, + 0, 0, mRadius, 0, + 0, 0, 0, 1); + + // Initialize the position where the sphere will be rendered + translateWorld(position); + + // Create the collision shape for the rigid body (sphere shape) + // ReactPhysics3D will clone this object to create an internal one. Therefore, + // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() + const rp3d::SphereShape collisionShape(mRadius); + + // Initial position and orientation of the rigid body + rp3d::Vector3 initPosition(position.x, position.y, position.z); + rp3d::Quaternion initOrientation = rp3d::Quaternion::identity(); + rp3d::Transform transform(initPosition, initOrientation); + + // Create a rigid body corresponding to the sphere in the dynamics world + rp3d::RigidBody* body = world->createRigidBody(transform); + + // Add a collision shape to the body and specify the mass of the shape + body->addCollisionShape(collisionShape, rp3d::Transform::identity(), mass); + + mRigidBody = body; + + mTransformMatrix = mTransformMatrix * mScalingMatrix; +} + +// Destructor +Sphere::~Sphere() { + + // Destroy the mesh + destroy(); +} + +// Render the sphere at the correct position and with the correct orientation +void Sphere::render(openglframework::Shader& shader, + const openglframework::Matrix4& worldToCameraMatrix) { + + // Bind the shader + shader.bind(); + + // Set the model to camera matrix + const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix; + shader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix); + + // Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the + // model-view matrix) + const openglframework::Matrix3 normalMatrix = + localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose(); + shader.setMatrix3x3Uniform("normalMatrix", normalMatrix); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + if (hasTexture()) { + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + } + + glVertexPointer(3, GL_FLOAT, 0, getVerticesPointer()); + glNormalPointer(GL_FLOAT, 0, getNormalsPointer()); + if(hasTexture()) { + glTexCoordPointer(2, GL_FLOAT, 0, getUVTextureCoordinatesPointer()); + } + + // For each part of the mesh + for (unsigned int i=0; igetInterpolatedTransform(); + + // Compute the transform used for rendering the sphere + rp3d::decimal matrix[16]; + transform.getOpenGLMatrix(matrix); + openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12], + matrix[1], matrix[5], matrix[9], matrix[13], + matrix[2], matrix[6], matrix[10], matrix[14], + matrix[3], matrix[7], matrix[11], matrix[15]); + + // Apply the scaling matrix to have the correct sphere dimensions + mTransformMatrix = newMatrix * mScalingMatrix; +} diff --git a/testbed/common/Sphere.h b/testbed/common/Sphere.h new file mode 100644 index 00000000..08a335f7 --- /dev/null +++ b/testbed/common/Sphere.h @@ -0,0 +1,90 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +#ifndef SPHERE_H +#define SPHERE_H + +// Libraries +#include "openglframework.h" +#include "reactphysics3d.h" + +// Class Sphere +class Sphere : public openglframework::Mesh { + + private : + + // -------------------- Attributes -------------------- // + + /// Radius of the sphere + float mRadius; + + /// Rigid body used to simulate the dynamics of the sphere + rp3d::CollisionBody* mRigidBody; + + /// Scaling matrix (applied to a sphere to obtain the correct sphere dimensions) + openglframework::Matrix4 mScalingMatrix; + + // -------------------- Methods -------------------- // + + public : + + // -------------------- Methods -------------------- // + + /// Constructor + Sphere(float radius, const openglframework::Vector3& position, + rp3d::CollisionWorld* world, const std::string& meshFolderPath); + + /// Constructor + Sphere(float radius, const openglframework::Vector3& position, + float mass, rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath); + + /// Destructor + ~Sphere(); + + /// Return a pointer to the collision body of the box + reactphysics3d::CollisionBody* getCollisionBody(); + + /// Return a pointer to the rigid body of the box + reactphysics3d::RigidBody* getRigidBody(); + + /// Update the transform matrix of the sphere + void updateTransform(); + + /// Render the sphere at the correct position and with the correct orientation + void render(openglframework::Shader& shader, + const openglframework::Matrix4& worldToCameraMatrix); +}; + +// Return a pointer to the collision body of the box +inline rp3d::CollisionBody* Sphere::getCollisionBody() { + return mRigidBody; +} + +// Return a pointer to the rigid body of the box +inline rp3d::RigidBody* Sphere::getRigidBody() { + return dynamic_cast(mRigidBody); +} + +#endif diff --git a/testbed/common/Viewer.cpp b/testbed/common/Viewer.cpp new file mode 100644 index 00000000..7383fc6c --- /dev/null +++ b/testbed/common/Viewer.cpp @@ -0,0 +1,342 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Libraries +#include "Viewer.h" +#include "openglframework.h" +#include +#include +#include + +using namespace openglframework; + +// Initialization of static variables +const float Viewer::SCROLL_SENSITIVITY = 0.02f; + +// Constructor +Viewer::Viewer() : mFPS(0), mNbFrames(0), mPreviousTime(0) { + +} + +// Destructor +Viewer::~Viewer() { + + // Destroy the window + glfwDestroyWindow(mWindow); + + // Terminate GLFW + glfwTerminate(); +} + +// Initialize the viewer +void Viewer::init(int argc, char** argv, const std::string& windowsTitle, + const Vector2& windowsSize, const Vector2& windowsPosition, + bool isMultisamplingActive) { + + mWindowTitle = windowsTitle; + + // Set the GLFW error callback method + glfwSetErrorCallback(error_callback); + + // Initialize the GLFW library + if (!glfwInit()) { + std::exit(EXIT_FAILURE); + } + + // Active the multi-sampling by default + if (isMultisamplingActive) { + glfwWindowHint(GLFW_SAMPLES, 4); + } + + // Create the GLFW window + mWindow = glfwCreateWindow(static_cast(windowsSize.x), + static_cast(windowsSize.y), mWindowTitle.c_str(), NULL, NULL); + if (!mWindow) { + glfwTerminate(); + std::exit(EXIT_FAILURE); + } + glfwMakeContextCurrent(mWindow); + + // Disable Vertical Synchronization + glfwSwapInterval(0); + + // Initialize the GLEW library + GLenum errorGLEW = glewInit(); + if (errorGLEW != GLEW_OK) { + + // Problem: glewInit failed, something is wrong + std::cerr << "GLEW Error : " << glewGetErrorString(errorGLEW) << std::endl; + assert(false); + std::exit(EXIT_FAILURE); + } + + if (isMultisamplingActive) { + glEnable(GL_MULTISAMPLE); + } +} + +// Set the dimension of the camera viewport +void Viewer::reshape() { + + // Get the framebuffer dimension + int width, height; + glfwGetFramebufferSize(mWindow, &width, &height); + + // Resize the viewport + mCamera.setDimensions(width, height); + glViewport(0, 0, width, height); +} + +// Start the main loop where rendering occur +void Viewer::startMainLoop() { + + // Loop until the user closes the window + while (!glfwWindowShouldClose(mWindow)) { + + // Reshape the viewport + reshape(); + + // Call the update function + (*mUpdateFunctionPointer)(); + + // Swap front and back buffers + glfwSwapBuffers(mWindow); + + // Poll for and process events + glfwPollEvents(); + } +} + +// Set the camera so that we can view the whole scene +void Viewer::resetCameraToViewAll() { + + // Move the camera to the origin of the scene + mCamera.translateWorld(-mCamera.getOrigin()); + + // Move the camera to the center of the scene + mCamera.translateWorld(mCenterScene); + + // Set the zoom of the camera so that the scene center is + // in negative view direction of the camera + mCamera.setZoom(1.0); +} + +// Called when a mouse button event occurs +void Viewer::mouseButtonEvent(int button, int action) { + + // Get the mouse cursor position + double x, y; + glfwGetCursorPos(mWindow, &x, &y); + + // If the mouse button is pressed + if (action == GLFW_PRESS) { + mLastMouseX = x; + mLastMouseY = y; + mIsLastPointOnSphereValid = mapMouseCoordinatesToSphere(x, y, mLastPointOnSphere); + } + else { // If the mouse button is released + mIsLastPointOnSphereValid = false; + } +} + +// Called when a mouse motion event occurs +void Viewer::mouseMotionEvent(double xMouse, double yMouse) { + + int leftButtonState = glfwGetMouseButton(mWindow, GLFW_MOUSE_BUTTON_LEFT); + int rightButtonState = glfwGetMouseButton(mWindow, GLFW_MOUSE_BUTTON_RIGHT); + int middleButtonState = glfwGetMouseButton(mWindow, GLFW_MOUSE_BUTTON_MIDDLE); + int altKeyState = glfwGetKey(mWindow, GLFW_KEY_LEFT_ALT); + + // Zoom + if (leftButtonState == GLFW_PRESS && altKeyState == GLFW_PRESS) { + + // Get the window dimension + int width, height; + glfwGetWindowSize(mWindow, &width, &height); + + float dy = static_cast(yMouse - mLastMouseY); + float h = static_cast(height); + + // Zoom the camera + zoom(-dy / h); + } + // Translation + else if (middleButtonState == GLFW_PRESS || rightButtonState == GLFW_PRESS || + (leftButtonState == GLFW_PRESS && altKeyState == GLFW_PRESS)) { + translate(xMouse, yMouse); + } + // Rotation + else if (leftButtonState == GLFW_PRESS) { + rotate(xMouse, yMouse); + } + + // Remember the mouse position + mLastMouseX = xMouse; + mLastMouseY = yMouse; + mIsLastPointOnSphereValid = mapMouseCoordinatesToSphere(xMouse, yMouse, mLastPointOnSphere); +} + +// Called when a scrolling event occurs +void Viewer::scrollingEvent(float scrollAxis) { + zoom(scrollAxis * SCROLL_SENSITIVITY); +} + +// Map the mouse x,y coordinates to a point on a sphere +bool Viewer::mapMouseCoordinatesToSphere(double xMouse, double yMouse, Vector3& spherePoint) const { + + // Get the window dimension + int width, height; + glfwGetWindowSize(mWindow, &width, &height); + + if ((xMouse >= 0) && (xMouse <= width) && (yMouse >= 0) && (yMouse <= height)) { + float x = float(xMouse - 0.5f * width) / float(width); + float y = float(0.5f * height - yMouse) / float(height); + float sinx = sin(PI * x * 0.5f); + float siny = sin(PI * y * 0.5f); + float sinx2siny2 = sinx * sinx + siny * siny; + + // Compute the point on the sphere + spherePoint.x = sinx; + spherePoint.y = siny; + spherePoint.z = (sinx2siny2 < 1.0) ? sqrt(1.0f - sinx2siny2) : 0.0f; + + return true; + } + + return false; +} + +// Zoom the camera +void Viewer::zoom(float zoomDiff) { + + // Zoom the camera + mCamera.setZoom(zoomDiff); +} + +// Translate the camera +void Viewer::translate(int xMouse, int yMouse) { + float dx = static_cast(xMouse - mLastMouseX); + float dy = static_cast(yMouse - mLastMouseY); + + // Translate the camera + mCamera.translateCamera(-dx / float(mCamera.getWidth()), + -dy / float(mCamera.getHeight()), mCenterScene); +} + +// Rotate the camera +void Viewer::rotate(int xMouse, int yMouse) { + + if (mIsLastPointOnSphereValid) { + + Vector3 newPoint3D; + bool isNewPointOK = mapMouseCoordinatesToSphere(xMouse, yMouse, newPoint3D); + + if (isNewPointOK) { + Vector3 axis = mLastPointOnSphere.cross(newPoint3D); + float cosAngle = mLastPointOnSphere.dot(newPoint3D); + + float epsilon = std::numeric_limits::epsilon(); + if (fabs(cosAngle) < 1.0f && axis.length() > epsilon) { + axis.normalize(); + float angle = 2.0f * acos(cosAngle); + + // Rotate the camera around the center of the scene + mCamera.rotateAroundLocalPoint(axis, -angle, mCenterScene); + } + } + } +} + +// Check the OpenGL errors +void Viewer::checkOpenGLErrors() { + GLenum glError; + + // Get the OpenGL errors + glError = glGetError(); + + // While there are errors + while (glError != GL_NO_ERROR) { + + // Get the error string + const GLubyte* stringError = gluErrorString(glError); + + // Display the error + if (stringError) + std::cerr << "OpenGL Error #" << glError << "(" << gluErrorString(glError) << std::endl; + else + std::cerr << "OpenGL Error #" << glError << " (no message available)" << std::endl; + + // Get the next error + glError = glGetError(); + } +} + + +// Compute the FPS +void Viewer::computeFPS() { + + mNbFrames++; + + // Get the number of milliseconds since glutInit called + mCurrentTime = glfwGetTime(); + + // Calculate time passed + double timeInterval = mCurrentTime - mPreviousTime; + + // Update the FPS counter each second + if(timeInterval > 1.0) { + + // calculate the number of frames per second + mFPS = static_cast(mNbFrames) / timeInterval; + + // Set time + mPreviousTime = mCurrentTime; + + // Reset frame count + mNbFrames = 0; + } +} + +// GLFW error callback method +void Viewer::error_callback(int error, const char* description) { + fputs(description, stderr); +} + +// Display the GUI +void Viewer::displayGUI() { + + // Display the FPS + displayFPS(); +} + +// Display the FPS +void Viewer::displayFPS() { + + std::stringstream ss; + ss << mFPS; + std::string fpsString = ss.str(); + std::string windowTitle = mWindowTitle + " | FPS : " + fpsString; + glfwSetWindowTitle(mWindow, windowTitle.c_str()); +} diff --git a/testbed/common/Viewer.h b/testbed/common/Viewer.h new file mode 100644 index 00000000..b3742509 --- /dev/null +++ b/testbed/common/Viewer.h @@ -0,0 +1,208 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +#ifndef VIEWER_H +#define VIEWER_H + +// Libraries +#include "openglframework.h" +#include + +// Class Viewer +class Viewer { + + private : + + // -------------------- Constants -------------------- // + + static const float SCROLL_SENSITIVITY; + + // -------------------- Attributes -------------------- // + + /// GLFW window + GLFWwindow* mWindow; + + /// Window title + std::string mWindowTitle; + + /// Camera + openglframework::Camera mCamera; + + /// Center of the scene + openglframework::Vector3 mCenterScene; + + /// Last mouse coordinates on the windows + double mLastMouseX, mLastMouseY; + + /// Last point computed on a sphere (for camera rotation) + openglframework::Vector3 mLastPointOnSphere; + + /// True if the last point computed on a sphere (for camera rotation) is valid + bool mIsLastPointOnSphereValid; + + /// Current number of frames per seconds + double mFPS; + + /// Number of frames during the last second + int mNbFrames; + + /// Current time for fps computation + double mCurrentTime; + + /// Previous time for fps computation + double mPreviousTime; + + /// Pointer to the update function + void (*mUpdateFunctionPointer)(); + + // -------------------- Methods -------------------- // + + bool mapMouseCoordinatesToSphere(double xMouse, double yMouse, openglframework::Vector3& spherePoint) const; + + public : + + // -------------------- Methods -------------------- // + + /// Constructor + Viewer(); + + /// Destructor + ~Viewer(); + + // -------------------- Methods -------------------- // + + /// Initialize the viewer + void init(int argc, char** argv, const std::string& windowsTitle, + const openglframework::Vector2& windowsSize, + const openglframework::Vector2& windowsPosition, + bool isMultisamplingActive = false); + + /// Start the main loop where rendering occur + void startMainLoop(); + + /// Called when the windows is reshaped + void reshape(); + + /// Set the scene position (where the camera needs to look at) + void setScenePosition(const openglframework::Vector3& position, float sceneRadius); + + /// Set the camera so that we can view the whole scene + void resetCameraToViewAll(); + + /// Zoom the camera + void zoom(float zoomDiff); + + /// Translate the camera + void translate(int xMouse, int yMouse); + + /// Rotate the camera + void rotate(int xMouse, int yMouse); + + /// Get the camera + openglframework::Camera& getCamera(); + + /// Called when a GLUT mouse button event occurs + void mouseButtonEvent(int button, int action); + + /// Called when a GLUT mouse motion event occurs + void mouseMotionEvent(double xMouse, double yMouse); + + /// Called when a scrolling event occurs + void scrollingEvent(float scrollAxis); + + /// Check the OpenGL errors + static void checkOpenGLErrors(); + + /// Display the FPS + void displayFPS(); + + /// Compute the FPS + void computeFPS(); + + /// Display the GUI + void displayGUI(); + + /// GLFW error callback method + static void error_callback(int error, const char* description); + + /// Register the update function that has to be called each frame + void registerUpdateFunction(void (*updateFunctionPointer)()); + + /// Register a keyboard callback method + void registerKeyboardCallback(GLFWkeyfun method); + + /// Register a mouse button callback method + void registerMouseButtonCallback(GLFWmousebuttonfun method); + + /// Register a mouse cursor motion callback method + void registerMouseCursorCallback(GLFWcursorposfun method); + + /// Register a scrolling cursor callback method + void registerScrollingCallback(GLFWscrollfun method); + +}; + +// Set the scene position (where the camera needs to look at) +inline void Viewer::setScenePosition(const openglframework::Vector3& position, float sceneRadius) { + + // Set the position and radius of the scene + mCenterScene = position; + mCamera.setSceneRadius(sceneRadius); + + // Reset the camera position and zoom in order to view all the scene + resetCameraToViewAll(); +} + +// Get the camera +inline openglframework::Camera& Viewer::getCamera() { + return mCamera; +} + +// Register the update function that has to be called each frame +inline void Viewer::registerUpdateFunction(void (*updateFunctionPointer)()) { + mUpdateFunctionPointer = updateFunctionPointer; +} + +// Register a keyboard callback method +inline void Viewer::registerKeyboardCallback(GLFWkeyfun method) { + glfwSetKeyCallback(mWindow, method); +} + +// Register a mouse button callback method +inline void Viewer::registerMouseButtonCallback(GLFWmousebuttonfun method) { + glfwSetMouseButtonCallback(mWindow, method); +} + +// Register a mouse cursor motion callback method +inline void Viewer::registerMouseCursorCallback(GLFWcursorposfun method) { + glfwSetCursorPosCallback(mWindow, method); +} + +// Register a scrolling cursor callback method +inline void Viewer::registerScrollingCallback(GLFWscrollfun method) { + glfwSetScrollCallback(mWindow, method); +} + +#endif diff --git a/testbed/common/VisualContactPoint.cpp b/testbed/common/VisualContactPoint.cpp new file mode 100644 index 00000000..77337192 --- /dev/null +++ b/testbed/common/VisualContactPoint.cpp @@ -0,0 +1,115 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Libraries +#include "VisualContactPoint.h" + +// Initialization of static variables +int VisualContactPoint::mNbTotalPoints = 0; +bool VisualContactPoint::mIsMeshInitialized = false; +openglframework::Mesh VisualContactPoint::mMesh; + +// Constructor +VisualContactPoint::VisualContactPoint(const openglframework::Vector3& position) { + + assert(mIsMeshInitialized); + + // Initialize the position where the sphere will be rendered + translateWorld(position); +} + +// Destructor +VisualContactPoint::~VisualContactPoint() { + +} + +// Load and initialize the mesh for all the contact points +void VisualContactPoint::createStaticData(const std::string& meshFolderPath) { + + if (!mIsMeshInitialized) { + + // Load the mesh from a file + openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "sphere.obj", mMesh); + + // Calculate the normals of the mesh + mMesh.calculateNormals(); + + mMesh.scaleVertices(VISUAL_CONTACT_POINT_RADIUS); + + mIsMeshInitialized = true; + } +} + +// Destroy the mesh for the contact points +void VisualContactPoint::destroyStaticData() { + + mMesh.destroy(); + mIsMeshInitialized = false; +} + +// Render the sphere at the correct position and with the correct orientation +void VisualContactPoint::render(openglframework::Shader& shader, + const openglframework::Matrix4& worldToCameraMatrix) { + + // Bind the shader + shader.bind(); + + // Set the model to camera matrix + const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix; + shader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix); + + // Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the + // model-view matrix) + const openglframework::Matrix3 normalMatrix = + localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose(); + shader.setMatrix3x3Uniform("normalMatrix", normalMatrix); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + if (mMesh.hasTexture()) { + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + } + + glVertexPointer(3, GL_FLOAT, 0, mMesh.getVerticesPointer()); + glNormalPointer(GL_FLOAT, 0, mMesh.getNormalsPointer()); + if(mMesh.hasTexture()) { + glTexCoordPointer(2, GL_FLOAT, 0, mMesh.getUVTextureCoordinatesPointer()); + } + + // For each part of the mesh + for (unsigned int i=0; iinit(argc, argv, "ReactPhysics3D Examples - Collision Shapes", + windowsSize, windowsPosition, true); + + // If the shaders and meshes folders are not specified as an argument + if (argc < 3) { + std::cerr << "Error : You need to specify the shaders folder as the first argument" + << " and the meshes folder as the second argument" << std::endl; + return 1; + } + + // Get the path of the shaders folder + std::string shaderFolderPath(argv[1]); + std::string meshFolderPath(argv[2]); + + // Register callback methods + viewer->registerUpdateFunction(update); + viewer->registerKeyboardCallback(keyboard); + viewer->registerMouseButtonCallback(mouseButton); + viewer->registerMouseCursorCallback(mouseMotion); + viewer->registerScrollingCallback(scroll); + + // Create the scene + scene = new Scene(viewer, shaderFolderPath, meshFolderPath); + + init(); + + viewer->startMainLoop(); + + delete viewer; + delete scene; + + return 0; +} + +// Update function that is called each frame +void update() { + + // Take a simulation step + simulate(); + + // Render + render(); +} + +// Simulate function +void simulate() { + + // Physics simulation + scene->simulate(); + + viewer->computeFPS(); +} + +// Initialization +void init() { + + // Define the background color (black) + glClearColor(0.0, 0.0, 0.0, 1.0); +} + +// Callback method to receive keyboard events +void keyboard(GLFWwindow* window, int key, int scancode, int action, int mods) { + if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) { + glfwSetWindowShouldClose(window, GL_TRUE); + } + else if (key == GLFW_KEY_SPACE && action == GLFW_PRESS) { + scene->pauseContinueSimulation(); + } +} + +// Callback method to receive scrolling events +void scroll(GLFWwindow* window, double xAxis, double yAxis) { + viewer->scrollingEvent(static_cast(yAxis)); +} + +// Called when a mouse button event occurs +void mouseButton(GLFWwindow* window, int button, int action, int mods) { + viewer->mouseButtonEvent(button, action); +} + +// Called when a mouse motion event occurs +void mouseMotion(GLFWwindow* window, double x, double y) { + viewer->mouseMotionEvent(x, y); +} + +// Display the scene +void render() { + + // Render the scene + scene->render(); + + // Display the FPS + viewer->displayGUI(); + + // Check the OpenGL errors + Viewer::checkOpenGLErrors(); +} + + diff --git a/testbed/examples/collisionshapes/Scene.cpp b/testbed/examples/collisionshapes/Scene.cpp new file mode 100644 index 00000000..740a48e6 --- /dev/null +++ b/testbed/examples/collisionshapes/Scene.cpp @@ -0,0 +1,444 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Libraries +#include "Scene.h" + +// Namespaces +using namespace openglframework; + +// Constructor +Scene::Scene(Viewer* viewer, const std::string& shaderFolderPath, const std::string& meshFolderPath) + : mViewer(viewer), mLight0(0), + mPhongShader(shaderFolderPath + "phong.vert", + shaderFolderPath +"phong.frag"), mIsRunning(false) { + + // Move the light 0 + mLight0.translateWorld(Vector3(50, 50, 50)); + + // Compute the radius and the center of the scene + float radiusScene = 30.0f; + openglframework::Vector3 center(0, 5, 0); + + // Set the center of the scene + mViewer->setScenePosition(center, radiusScene); + + // Gravity vector in the dynamics world + rp3d::Vector3 gravity(0, -9.81, 0); + + // Time step for the physics simulation + rp3d::decimal timeStep = 1.0f / 60.0f; + + // Create the dynamics world for the physics simulation + mDynamicsWorld = new rp3d::DynamicsWorld(gravity, timeStep); + + // Set the number of iterations of the constraint solver + mDynamicsWorld->setNbIterationsVelocitySolver(15); + + // Create the static data for the visual contact points + VisualContactPoint::createStaticData(meshFolderPath); + + float radius = 3.0f; + + for (int i=0; igetRigidBody()->getMaterial(); + material.setBounciness(rp3d::decimal(0.2)); + + // Add the mesh the list of dumbbells in the scene + mDumbbells.push_back(dumbbell); + } + + // Create all the boxes of the scene + for (int i=0; igetRigidBody()->getMaterial(); + material.setBounciness(rp3d::decimal(0.2)); + + // Add the sphere the list of sphere in the scene + mBoxes.push_back(box); + } + + // Create all the spheres of the scene + for (int i=0; igetRigidBody()->getMaterial(); + material.setBounciness(rp3d::decimal(0.2)); + + // Add the sphere the list of sphere in the scene + mSpheres.push_back(sphere); + } + + // Create all the cones of the scene + for (int i=0; igetRigidBody()->getMaterial(); + material.setBounciness(rp3d::decimal(0.2)); + + // Add the cone the list of sphere in the scene + mCones.push_back(cone); + } + + // Create all the cylinders of the scene + for (int i=0; igetRigidBody()->getMaterial(); + material.setBounciness(rp3d::decimal(0.2)); + + // Add the cylinder the list of sphere in the scene + mCylinders.push_back(cylinder); + } + + // Create all the capsules of the scene + for (int i=0; igetRigidBody()->getMaterial(); + material.setBounciness(rp3d::decimal(0.2)); + + // Add the cylinder the list of sphere in the scene + mCapsules.push_back(capsule); + } + + // Create all the convex meshes of the scene + for (int i=0; igetRigidBody()->getMaterial(); + material.setBounciness(rp3d::decimal(0.2)); + + // Add the mesh the list of sphere in the scene + mConvexMeshes.push_back(mesh); + } + + // Create the floor + openglframework::Vector3 floorPosition(0, 0, 0); + mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld); + + // The floor must be a static rigid body + mFloor->getRigidBody()->setType(rp3d::STATIC); + + // Change the material properties of the rigid body + rp3d::Material& material = mFloor->getRigidBody()->getMaterial(); + material.setBounciness(rp3d::decimal(0.2)); + + // Start the simulation + startSimulation(); +} + +// Destructor +Scene::~Scene() { + + // Stop the physics simulation + stopSimulation(); + + // Destroy the shader + mPhongShader.destroy(); + + // Destroy all the boxes of the scene + for (std::vector::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { + + // Destroy the corresponding rigid body from the dynamics world + mDynamicsWorld->destroyRigidBody((*it)->getRigidBody()); + + // Destroy the box + delete (*it); + } + + // Destroy all the sphere of the scene + for (std::vector::iterator it = mSpheres.begin(); it != mSpheres.end(); ++it) { + + // Destroy the corresponding rigid body from the dynamics world + mDynamicsWorld->destroyRigidBody((*it)->getRigidBody()); + + // Destroy the sphere + delete (*it); + } + + // Destroy all the cones of the scene + for (std::vector::iterator it = mCones.begin(); it != mCones.end(); ++it) { + + // Destroy the corresponding rigid body from the dynamics world + mDynamicsWorld->destroyRigidBody((*it)->getRigidBody()); + + // Destroy the sphere + delete (*it); + } + + // Destroy all the cylinders of the scene + for (std::vector::iterator it = mCylinders.begin(); it != mCylinders.end(); ++it) { + + // Destroy the corresponding rigid body from the dynamics world + mDynamicsWorld->destroyRigidBody((*it)->getRigidBody()); + + // Destroy the sphere + delete (*it); + } + + // Destroy all the capsules of the scene + for (std::vector::iterator it = mCapsules.begin(); it != mCapsules.end(); ++it) { + + // Destroy the corresponding rigid body from the dynamics world + mDynamicsWorld->destroyRigidBody((*it)->getRigidBody()); + + // Destroy the sphere + delete (*it); + } + + // Destroy all the convex meshes of the scene + for (std::vector::iterator it = mConvexMeshes.begin(); + it != mConvexMeshes.end(); ++it) { + + // Destroy the corresponding rigid body from the dynamics world + mDynamicsWorld->destroyRigidBody((*it)->getRigidBody()); + + // Destroy the convex mesh + delete (*it); + } + + // Destroy all the dumbbell of the scene + for (std::vector::iterator it = mDumbbells.begin(); + it != mDumbbells.end(); ++it) { + + // Destroy the corresponding rigid body from the dynamics world + mDynamicsWorld->destroyRigidBody((*it)->getRigidBody()); + + // Destroy the convex mesh + delete (*it); + } + + // Destroy the rigid body of the floor + mDynamicsWorld->destroyRigidBody(mFloor->getRigidBody()); + + // Destroy the floor + delete mFloor; + + // Destroy the dynamics world + delete mDynamicsWorld; +} + +// Take a step for the simulation +void Scene::simulate() { + + // If the physics simulation is running + if (mIsRunning) { + + // Take a simulation step + mDynamicsWorld->update(); + + // Update the position and orientation of the boxes + for (std::vector::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { + + // Update the transform used for the rendering + (*it)->updateTransform(); + } + + // Update the position and orientation of the sphere + for (std::vector::iterator it = mSpheres.begin(); it != mSpheres.end(); ++it) { + + // Update the transform used for the rendering + (*it)->updateTransform(); + } + + // Update the position and orientation of the cones + for (std::vector::iterator it = mCones.begin(); it != mCones.end(); ++it) { + + // Update the transform used for the rendering + (*it)->updateTransform(); + } + + // Update the position and orientation of the cylinders + for (std::vector::iterator it = mCylinders.begin(); it != mCylinders.end(); ++it) { + + // Update the transform used for the rendering + (*it)->updateTransform(); + } + + // Update the position and orientation of the capsules + for (std::vector::iterator it = mCapsules.begin(); it != mCapsules.end(); ++it) { + + // Update the transform used for the rendering + (*it)->updateTransform(); + } + + // Update the position and orientation of the convex meshes + for (std::vector::iterator it = mConvexMeshes.begin(); + it != mConvexMeshes.end(); ++it) { + + // Update the transform used for the rendering + (*it)->updateTransform(); + } + + // Update the position and orientation of the dumbbells + for (std::vector::iterator it = mDumbbells.begin(); + it != mDumbbells.end(); ++it) { + + // Update the transform used for the rendering + (*it)->updateTransform(); + } + + mFloor->updateTransform(); + } +} + +// Render the scene +void Scene::render() { + + glEnable(GL_DEPTH_TEST); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glEnable(GL_CULL_FACE); + + // Get the world-space to camera-space matrix + const Camera& camera = mViewer->getCamera(); + const openglframework::Matrix4 worldToCameraMatrix = camera.getTransformMatrix().getInverse(); + + // Bind the shader + mPhongShader.bind(); + + // Set the variables of the shader + mPhongShader.setMatrix4x4Uniform("projectionMatrix", camera.getProjectionMatrix()); + mPhongShader.setVector3Uniform("light0PosCameraSpace", worldToCameraMatrix * mLight0.getOrigin()); + mPhongShader.setVector3Uniform("lightAmbientColor", Vector3(0.3f, 0.3f, 0.3f)); + const Color& diffColLight0 = mLight0.getDiffuseColor(); + const Color& specColLight0 = mLight0.getSpecularColor(); + mPhongShader.setVector3Uniform("light0DiffuseColor", Vector3(diffColLight0.r, diffColLight0.g, diffColLight0.b)); + mPhongShader.setVector3Uniform("light0SpecularColor", Vector3(specColLight0.r, specColLight0.g, specColLight0.b)); + mPhongShader.setFloatUniform("shininess", 200.0f); + + // Render all the boxes of the scene + for (std::vector::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { + (*it)->render(mPhongShader, worldToCameraMatrix); + } + + // Render all the sphere of the scene + for (std::vector::iterator it = mSpheres.begin(); it != mSpheres.end(); ++it) { + (*it)->render(mPhongShader, worldToCameraMatrix); + } + + // Render all the cones of the scene + for (std::vector::iterator it = mCones.begin(); it != mCones.end(); ++it) { + (*it)->render(mPhongShader, worldToCameraMatrix); + } + + // Render all the cylinders of the scene + for (std::vector::iterator it = mCylinders.begin(); it != mCylinders.end(); ++it) { + (*it)->render(mPhongShader, worldToCameraMatrix); + } + + // Render all the capsules of the scene + for (std::vector::iterator it = mCapsules.begin(); it != mCapsules.end(); ++it) { + (*it)->render(mPhongShader, worldToCameraMatrix); + } + + // Render all the convex meshes of the scene + for (std::vector::iterator it = mConvexMeshes.begin(); + it != mConvexMeshes.end(); ++it) { + (*it)->render(mPhongShader, worldToCameraMatrix); + } + + // Render all the dumbbells of the scene + for (std::vector::iterator it = mDumbbells.begin(); + it != mDumbbells.end(); ++it) { + (*it)->render(mPhongShader, worldToCameraMatrix); + } + + // Render the floor + mFloor->render(mPhongShader, worldToCameraMatrix); + + // Unbind the shader + mPhongShader.unbind(); +} diff --git a/testbed/examples/collisionshapes/Scene.h b/testbed/examples/collisionshapes/Scene.h new file mode 100644 index 00000000..61a2e7a7 --- /dev/null +++ b/testbed/examples/collisionshapes/Scene.h @@ -0,0 +1,158 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +#ifndef SCENE_H +#define SCENE_H + +// Libraries +#include "openglframework.h" +#include "reactphysics3d.h" +#include "Sphere.h" +#include "Box.h" +#include "Cone.h" +#include "Cylinder.h" +#include "Capsule.h" +#include "ConvexMesh.h" +#include "Dumbbell.h" +#include "VisualContactPoint.h" +#include "../common/Viewer.h" + +// Constants +const int NB_BOXES = 2; +const int NB_CUBES = 1; +const int NB_CONES = 3; +const int NB_CYLINDERS = 2; +const int NB_CAPSULES = 1; +const int NB_MESHES = 2; +const int NB_COMPOUND_SHAPES = 2; +const openglframework::Vector3 BOX_SIZE(2, 2, 2); +const float SPHERE_RADIUS = 1.5f; +const float CONE_RADIUS = 2.0f; +const float CONE_HEIGHT = 3.0f; +const float CYLINDER_RADIUS = 1.0f; +const float CYLINDER_HEIGHT = 5.0f; +const float CAPSULE_RADIUS = 1.0f; +const float CAPSULE_HEIGHT = 1.0f; +const float DUMBBELL_HEIGHT = 1.0f; +const openglframework::Vector3 FLOOR_SIZE(20, 0.5f, 20); // Floor dimensions in meters +const float BOX_MASS = 1.0f; +const float CONE_MASS = 1.0f; +const float CYLINDER_MASS = 1.0f; +const float CAPSULE_MASS = 1.0f; +const float MESH_MASS = 1.0f; +const float FLOOR_MASS = 100.0f; // Floor mass in kilograms + +// Class Scene +class Scene { + + private : + + // -------------------- Attributes -------------------- // + + /// Pointer to the viewer + Viewer* mViewer; + + /// Light 0 + openglframework::Light mLight0; + + /// Phong shader + openglframework::Shader mPhongShader; + + /// All the spheres of the scene + std::vector mBoxes; + + std::vector mSpheres; + + std::vector mCones; + + std::vector mCylinders; + + std::vector mCapsules; + + /// All the convex meshes of the scene + std::vector mConvexMeshes; + + /// All the dumbbell of the scene + std::vector mDumbbells; + + /// Box for the floor + Box* mFloor; + + /// Dynamics world used for the physics simulation + rp3d::DynamicsWorld* mDynamicsWorld; + + /// True if the physics simulation is running + bool mIsRunning; + + public: + + // -------------------- Methods -------------------- // + + /// Constructor + Scene(Viewer* viewer, const std::string& shaderFolderPath, + const std::string& meshFolderPath); + + /// Destructor + ~Scene(); + + /// Take a step for the simulation + void simulate(); + + /// Stop the simulation + void stopSimulation(); + + /// Start the simulation + void startSimulation(); + + /// Pause or continue simulation + void pauseContinueSimulation(); + + /// Render the scene + void render(); +}; + +// Stop the simulation +inline void Scene::stopSimulation() { + mDynamicsWorld->stop(); + mIsRunning = false; +} + +// Start the simulation +inline void Scene::startSimulation() { + mDynamicsWorld->start(); + mIsRunning = true; +} + +// Pause or continue simulation +inline void Scene::pauseContinueSimulation() { + if (mIsRunning) { + stopSimulation(); + } + else { + startSimulation(); + } +} + +#endif diff --git a/testbed/examples/cubes/CMakeLists.txt b/testbed/examples/cubes/CMakeLists.txt new file mode 100644 index 00000000..5239dc56 --- /dev/null +++ b/testbed/examples/cubes/CMakeLists.txt @@ -0,0 +1,34 @@ +# Minimum cmake version required +cmake_minimum_required(VERSION 2.6) + +# Project configuration +PROJECT(Cubes) + +# Where to build the executables +SET(EXECUTABLE_OUTPUT_PATH "${OUR_EXECUTABLE_OUTPUT_PATH}/cubes") +SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}) +SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${EXECUTABLE_OUTPUT_PATH}) +SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${EXECUTABLE_OUTPUT_PATH}) + +# Copy the shaders used for the demo into the build directory +FILE(COPY "${OPENGLFRAMEWORK_DIR}/src/shaders/" DESTINATION "${EXECUTABLE_OUTPUT_PATH}/shaders/") + +# Headers +INCLUDE_DIRECTORIES("${OPENGLFRAMEWORK_DIR}/src/" "../common/glfw/include/" "../common/") + +# Source files +SET(CUBES_SOURCES + Cubes.cpp + Scene.cpp + Scene.h + "../common/Box.cpp" + "../common/Box.h" + "../common/Viewer.cpp" + "../common/Viewer.h" +) + +# Create the executable +ADD_EXECUTABLE(cubes ${CUBES_SOURCES}) + +# Link with libraries +TARGET_LINK_LIBRARIES(cubes reactphysics3d openglframework glfw ${GLFW_LIBRARIES}) diff --git a/testbed/examples/cubes/Cubes.cpp b/testbed/examples/cubes/Cubes.cpp new file mode 100644 index 00000000..f00cda72 --- /dev/null +++ b/testbed/examples/cubes/Cubes.cpp @@ -0,0 +1,148 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Libraries +#include "Scene.h" +#include "Viewer.h" + +// Declarations +void simulate(); +void render(); +void update(); +void mouseButton(GLFWwindow* window, int button, int action, int mods); +void mouseMotion(GLFWwindow* window, double x, double y); +void keyboard(GLFWwindow* window, int key, int scancode, int action, int mods); +void scroll(GLFWwindow* window, double xAxis, double yAxis); +void init(); + +// Namespaces +using namespace openglframework; + +// Global variables +Viewer* viewer; +Scene* scene; + +// Main function +int main(int argc, char** argv) { + + // Create and initialize the Viewer + viewer = new Viewer(); + Vector2 windowsSize = Vector2(800, 600); + Vector2 windowsPosition = Vector2(100, 100); + viewer->init(argc, argv, "ReactPhysics3D Examples - Cubes", windowsSize, windowsPosition, true); + + // If the shaders folder is not specified as an argument + if (argc < 2) { + std::cerr << "Error : You need to specify the shaders folder as argument !" << std::endl; + return 1; + } + + // Get the path of the shaders folder + std::string shaderFolderPath(argv[1]); + + // Register callback methods + viewer->registerUpdateFunction(update); + viewer->registerKeyboardCallback(keyboard); + viewer->registerMouseButtonCallback(mouseButton); + viewer->registerMouseCursorCallback(mouseMotion); + viewer->registerScrollingCallback(scroll); + + // Create the scene + scene = new Scene(viewer, shaderFolderPath); + + init(); + + viewer->startMainLoop(); + + delete viewer; + delete scene; + + return 0; +} + +// Update function that is called each frame +void update() { + + // Take a simulation step + simulate(); + + // Render + render(); +} + +// Simulate function +void simulate() { + + // Physics simulation + scene->simulate(); + + // Compute the current framerate + viewer->computeFPS(); +} + +// Initialization +void init() { + + // Define the background color (black) + glClearColor(0.0, 0.0, 0.0, 1.0); +} + +// Callback method to receive keyboard events +void keyboard(GLFWwindow* window, int key, int scancode, int action, int mods) { + if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) { + glfwSetWindowShouldClose(window, GL_TRUE); + } + else if (key == GLFW_KEY_SPACE && action == GLFW_PRESS) { + scene->pauseContinueSimulation(); + } +} + +// Callback method to receive scrolling events +void scroll(GLFWwindow* window, double xAxis, double yAxis) { + viewer->scrollingEvent(static_cast(yAxis)); +} + +// Called when a mouse button event occurs +void mouseButton(GLFWwindow* window, int button, int action, int mods) { + viewer->mouseButtonEvent(button, action); +} + +// Called when a mouse motion event occurs +void mouseMotion(GLFWwindow* window, double x, double y) { + viewer->mouseMotionEvent(x, y); +} + +// Display the scene +void render() { + + // Render the scene + scene->render(); + + // Display the FPS + viewer->displayGUI(); + + // Check the OpenGL errors + Viewer::checkOpenGLErrors(); +} diff --git a/testbed/examples/cubes/Scene.cpp b/testbed/examples/cubes/Scene.cpp new file mode 100644 index 00000000..073ab02b --- /dev/null +++ b/testbed/examples/cubes/Scene.cpp @@ -0,0 +1,197 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Libraries +#include "Scene.h" + +// Namespaces +using namespace openglframework; + +// Constructor +Scene::Scene(Viewer* viewer, const std::string& shaderFolderPath) + : mViewer(viewer), mLight0(0), + mPhongShader(shaderFolderPath + "phong.vert", shaderFolderPath + "phong.frag"), + mIsRunning(false) { + + // Move the light 0 + mLight0.translateWorld(Vector3(7, 15, 15)); + + // Compute the radius and the center of the scene + float radiusScene = 30.0f; + openglframework::Vector3 center(0, 5, 0); + + // Set the center of the scene + mViewer->setScenePosition(center, radiusScene); + + // Gravity vector in the dynamics world + rp3d::Vector3 gravity(0, rp3d::decimal(-5.81), 0); + + // Time step for the physics simulation + rp3d::decimal timeStep = 1.0f / 60.0f; + + // Create the dynamics world for the physics simulation + mDynamicsWorld = new rp3d::DynamicsWorld(gravity, timeStep); + + // Set the number of iterations of the constraint solver + mDynamicsWorld->setNbIterationsVelocitySolver(15); + + float radius = 2.0f; + + // Create all the cubes of the scene + for (int i=0; igetRigidBody()->getMaterial(); + material.setBounciness(rp3d::decimal(0.4)); + + // Add the box the list of box in the scene + mBoxes.push_back(cube); + } + + // Create the floor + openglframework::Vector3 floorPosition(0, 0, 0); + mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld); + + // The floor must be a static rigid body + mFloor->getRigidBody()->setType(rp3d::STATIC); + + // Change the material properties of the floor rigid body + rp3d::Material& material = mFloor->getRigidBody()->getMaterial(); + material.setBounciness(rp3d::decimal(0.3)); + + // Start the simulation + startSimulation(); + + counter=0; +} + +// Destructor +Scene::~Scene() { + + // Stop the physics simulation + stopSimulation(); + + // Destroy the shader + mPhongShader.destroy(); + + // Destroy all the cubes of the scene + for (std::vector::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { + + // Destroy the corresponding rigid body from the dynamics world + mDynamicsWorld->destroyRigidBody((*it)->getRigidBody()); + + // Destroy the cube + delete (*it); + } + + // Destroy the rigid body of the floor + mDynamicsWorld->destroyRigidBody(mFloor->getRigidBody()); + + // Destroy the floor + delete mFloor; + + // Destroy the dynamics world + delete mDynamicsWorld; +} + +// Take a step for the simulation +void Scene::simulate() { + + // If the physics simulation is running + if (mIsRunning) { + + counter++; + if (counter == 400) { + //mIsRunning = false; + } + + // Take a simulation step + mDynamicsWorld->update(); + + // Update the position and orientation of the boxes + for (std::vector::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { + + // Update the transform used for the rendering + (*it)->updateTransform(); + } + + mFloor->updateTransform(); + + // Set the color of the awake/sleeping bodies + for (uint i=0; igetRigidBody()->isSleeping()) { + mBoxes[i]->setColor(Color(1, 0, 0, 1)); + } + else { + mBoxes[i]->setColor(Color(0, 1, 0, 1)); + } + } + } +} + +// Render the scene +void Scene::render() { + + glEnable(GL_DEPTH_TEST); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glEnable(GL_CULL_FACE); + + // Get the world-space to camera-space matrix + const Camera& camera = mViewer->getCamera(); + const openglframework::Matrix4 worldToCameraMatrix = camera.getTransformMatrix().getInverse(); + + // Bind the shader + mPhongShader.bind(); + + // Set the variables of the shader + mPhongShader.setMatrix4x4Uniform("projectionMatrix", camera.getProjectionMatrix()); + mPhongShader.setVector3Uniform("light0PosCameraSpace",worldToCameraMatrix * mLight0.getOrigin()); + mPhongShader.setVector3Uniform("lightAmbientColor", Vector3(0.3f, 0.3f, 0.3f)); + const Color& diffCol = mLight0.getDiffuseColor(); + const Color& specCol = mLight0.getSpecularColor(); + mPhongShader.setVector3Uniform("light0DiffuseColor", Vector3(diffCol.r, diffCol.g, diffCol.b)); + mPhongShader.setVector3Uniform("light0SpecularColor", Vector3(specCol.r, specCol.g, specCol.b)); + mPhongShader.setFloatUniform("shininess", 60.0f); + + // Render all the cubes of the scene + for (std::vector::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { + (*it)->render(mPhongShader, worldToCameraMatrix); + } + + // Render the floor + mFloor->render(mPhongShader, worldToCameraMatrix); + + // Unbind the shader + mPhongShader.unbind(); +} diff --git a/testbed/examples/cubes/Scene.h b/testbed/examples/cubes/Scene.h new file mode 100644 index 00000000..2f79daed --- /dev/null +++ b/testbed/examples/cubes/Scene.h @@ -0,0 +1,120 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +#ifndef SCENE_H +#define SCENE_H + +// Libraries +#include "openglframework.h" +#include "reactphysics3d.h" +#include "Box.h" +#include "Viewer.h" + +// Constants +const int NB_CUBES = 200; // Number of boxes in the scene +const openglframework::Vector3 BOX_SIZE(2, 2, 2); // Box dimensions in meters +const openglframework::Vector3 FLOOR_SIZE(50, 0.5f, 50); // Floor dimensions in meters +const float BOX_MASS = 1.0f; // Box mass in kilograms +const float FLOOR_MASS = 100.0f; // Floor mass in kilograms + +// Class Scene +class Scene { + + private : + + // -------------------- Attributes -------------------- // + + int counter; + + /// Pointer to the viewer + Viewer* mViewer; + + /// Light 0 + openglframework::Light mLight0; + + /// Phong shader + openglframework::Shader mPhongShader; + + /// All the boxes of the scene + std::vector mBoxes; + + /// Box for the floor + Box* mFloor; + + /// Dynamics world used for the physics simulation + rp3d::DynamicsWorld* mDynamicsWorld; + + /// True if the physics simulation is running + bool mIsRunning; + + public: + + // -------------------- Methods -------------------- // + + /// Constructor + Scene(Viewer* viewer, const std::string& shaderFolderPath); + + /// Destructor + ~Scene(); + + /// Take a step for the simulation + void simulate(); + + /// Stop the simulation + void stopSimulation(); + + /// Start the simulation + void startSimulation(); + + /// Pause or continue simulation + void pauseContinueSimulation(); + + /// Render the scene + void render(); +}; + +// Stop the simulation +inline void Scene::stopSimulation() { + mDynamicsWorld->stop(); + mIsRunning = false; +} + +// Start the simulation +inline void Scene::startSimulation() { + mDynamicsWorld->start(); + mIsRunning = true; +} + +// Pause or continue simulation +inline void Scene::pauseContinueSimulation() { + if (mIsRunning) { + stopSimulation(); + } + else { + startSimulation(); + } +} + +#endif diff --git a/testbed/examples/joints/CMakeLists.txt b/testbed/examples/joints/CMakeLists.txt new file mode 100644 index 00000000..ba304b9d --- /dev/null +++ b/testbed/examples/joints/CMakeLists.txt @@ -0,0 +1,34 @@ +# Minimum cmake version required +cmake_minimum_required(VERSION 2.6) + +# Project configuration +PROJECT(Joints) + +# Where to build the executables +SET(EXECUTABLE_OUTPUT_PATH "${OUR_EXECUTABLE_OUTPUT_PATH}/joints") +SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}) +SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${EXECUTABLE_OUTPUT_PATH}) +SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${EXECUTABLE_OUTPUT_PATH}) + +# Copy the shaders used for the demo into the build directory +FILE(COPY "${OPENGLFRAMEWORK_DIR}/src/shaders/" DESTINATION "${EXECUTABLE_OUTPUT_PATH}/shaders/") + +# Headers +INCLUDE_DIRECTORIES("${OPENGLFRAMEWORK_DIR}/src/" "../common/glfw/include/" "../common/") + +# Source files +SET(JOINTS_SOURCES + Joints.cpp + Scene.cpp + Scene.h + "../common/Box.cpp" + "../common/Box.h" + "../common/Viewer.cpp" + "../common/Viewer.h" +) + +# Create the executable +ADD_EXECUTABLE(joints ${JOINTS_SOURCES}) + +# Link with libraries +TARGET_LINK_LIBRARIES(joints reactphysics3d openglframework glfw ${GLFW_LIBRARIES}) diff --git a/testbed/examples/joints/Joints.cpp b/testbed/examples/joints/Joints.cpp new file mode 100644 index 00000000..1b1b7e00 --- /dev/null +++ b/testbed/examples/joints/Joints.cpp @@ -0,0 +1,149 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Libraries +#include "Scene.h" +#include "../common/Viewer.h" + +// Declarations +void simulate(); +void update(); +void render(); +void mouseButton(GLFWwindow* window, int button, int action, int mods); +void mouseMotion(GLFWwindow* window, double x, double y); +void keyboard(GLFWwindow* window, int key, int scancode, int action, int mods); +void scroll(GLFWwindow* window, double xAxis, double yAxis); +void init(); + +// Namespaces +using namespace openglframework; + +// Global variables +Viewer* viewer; +Scene* scene; + +// Main function +int main(int argc, char** argv) { + + // Create and initialize the Viewer + viewer = new Viewer(); + Vector2 windowsSize = Vector2(800, 600); + Vector2 windowsPosition = Vector2(100, 100); + viewer->init(argc, argv, "ReactPhysics3D Examples - Joints", windowsSize, windowsPosition, true); + + // If the shaders folder is not specified as an argument + if (argc < 2) { + std::cerr << "Error : You need to specify the shaders folder as argument !" << std::endl; + return 1; + } + + // Get the path of the shaders folder + std::string shaderFolderPath(argv[1]); + + // Register callback methods + viewer->registerUpdateFunction(update); + viewer->registerKeyboardCallback(keyboard); + viewer->registerMouseButtonCallback(mouseButton); + viewer->registerMouseCursorCallback(mouseMotion); + viewer->registerScrollingCallback(scroll); + + // Create the scene + scene = new Scene(viewer, shaderFolderPath); + + init(); + + viewer->startMainLoop(); + + delete viewer; + delete scene; + + return 0; +} + +// Update function that is called each frame +void update() { + + // Take a simulation step + simulate(); + + // Render + render(); +} + +// Simulate function +void simulate() { + + // Physics simulation + scene->simulate(); + + viewer->computeFPS(); +} + +// Initialization +void init() { + + // Define the background color (black) + glClearColor(0.0, 0.0, 0.0, 1.0); +} + +// Callback method to receive keyboard events +void keyboard(GLFWwindow* window, int key, int scancode, int action, int mods) { + if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) { + glfwSetWindowShouldClose(window, GL_TRUE); + } + else if (key == GLFW_KEY_SPACE && action == GLFW_PRESS) { + scene->pauseContinueSimulation(); + } +} + +// Callback method to receive scrolling events +void scroll(GLFWwindow* window, double xAxis, double yAxis) { + viewer->scrollingEvent(static_cast(yAxis)); +} + +// Called when a mouse button event occurs +void mouseButton(GLFWwindow* window, int button, int action, int mods) { + viewer->mouseButtonEvent(button, action); +} + +// Called when a mouse motion event occurs +void mouseMotion(GLFWwindow* window, double x, double y) { + viewer->mouseMotionEvent(x, y); +} + +// Display the scene +void render() { + + // Render the scene + scene->render(); + + // Display the FPS + viewer->displayGUI(); + + // Check the OpenGL errors + Viewer::checkOpenGLErrors(); +} + + diff --git a/testbed/examples/joints/Scene.cpp b/testbed/examples/joints/Scene.cpp new file mode 100644 index 00000000..def294fa --- /dev/null +++ b/testbed/examples/joints/Scene.cpp @@ -0,0 +1,394 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Libraries +#include "Scene.h" +#include + +// Namespaces +using namespace openglframework; + +// Constructor +Scene::Scene(Viewer *viewer, const std::string& shaderFolderPath) + : mViewer(viewer), mLight0(0), mPhongShader(shaderFolderPath + "phong.vert", + shaderFolderPath + "phong.frag"), + mIsRunning(false) { + + // Move the light 0 + mLight0.translateWorld(Vector3(7, 15, 15)); + + // Compute the radius and the center of the scene + float radiusScene = 30.0f; + openglframework::Vector3 center(0, 5, 0); + + // Set the center of the scene + mViewer->setScenePosition(center, radiusScene); + + // Gravity vector in the dynamics world + rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0); + + // Time step for the physics simulation + rp3d::decimal timeStep = 1.0f / 60.0f; + + // Create the dynamics world for the physics simulation + mDynamicsWorld = new rp3d::DynamicsWorld(gravity, timeStep); + + // Set the number of iterations of the constraint solver + mDynamicsWorld->setNbIterationsVelocitySolver(15); + + // Create the Ball-and-Socket joint + createBallAndSocketJoints(); + + // Create the Slider joint + createSliderJoint(); + + // Create the Hinge joint + createPropellerHingeJoint(); + + // Create the Fixed joint + createFixedJoints(); + + // Create the floor + createFloor(); + + // Start the simulation + startSimulation(); +} + +// Destructor +Scene::~Scene() { + + // Stop the physics simulation + stopSimulation(); + + // Destroy the shader + mPhongShader.destroy(); + + // Destroy the joints + mDynamicsWorld->destroyJoint(mSliderJoint); + mDynamicsWorld->destroyJoint(mPropellerHingeJoint); + mDynamicsWorld->destroyJoint(mFixedJoint1); + mDynamicsWorld->destroyJoint(mFixedJoint2); + for (int i=0; idestroyJoint(mBallAndSocketJoints[i]); + } + + // Destroy all the rigid bodies of the scene + mDynamicsWorld->destroyRigidBody(mSliderJointBottomBox->getRigidBody()); + mDynamicsWorld->destroyRigidBody(mSliderJointTopBox->getRigidBody()); + mDynamicsWorld->destroyRigidBody(mPropellerBox->getRigidBody()); + mDynamicsWorld->destroyRigidBody(mFixedJointBox1->getRigidBody()); + mDynamicsWorld->destroyRigidBody(mFixedJointBox2->getRigidBody()); + for (int i=0; idestroyRigidBody(mBallAndSocketJointChainBoxes[i]->getRigidBody()); + } + + delete mSliderJointBottomBox; + delete mSliderJointTopBox; + delete mPropellerBox; + delete mFixedJointBox1; + delete mFixedJointBox2; + for (int i=0; idestroyRigidBody(mFloor->getRigidBody()); + delete mFloor; + + // Destroy the dynamics world + delete mDynamicsWorld; +} + +// Take a step for the simulation +void Scene::simulate() { + + // If the physics simulation is running + if (mIsRunning) { + + // Update the motor speed of the Slider Joint (to move up and down) + long double motorSpeed = 2 * cos(mDynamicsWorld->getPhysicsTime() * 1.5); + mSliderJoint->setMotorSpeed(rp3d::decimal(motorSpeed)); + + // Take a simulation step + mDynamicsWorld->update(); + + // Update the position and orientation of the boxes + mSliderJointBottomBox->updateTransform(); + mSliderJointTopBox->updateTransform(); + mPropellerBox->updateTransform(); + mFixedJointBox1->updateTransform(); + mFixedJointBox2->updateTransform(); + for (int i=0; iupdateTransform(); + } + + // Update the position and orientation of the floor + mFloor->updateTransform(); + } +} + +// Render the scene +void Scene::render() { + + glEnable(GL_DEPTH_TEST); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glEnable(GL_CULL_FACE); + + // Get the world-space to camera-space matrix + const Camera& camera = mViewer->getCamera(); + const openglframework::Matrix4 worldToCameraMatrix = camera.getTransformMatrix().getInverse(); + + // Bind the shader + mPhongShader.bind(); + + // Set the variables of the shader + mPhongShader.setVector3Uniform("light0PosCameraSpace",worldToCameraMatrix * mLight0.getOrigin()); + mPhongShader.setMatrix4x4Uniform("projectionMatrix", camera.getProjectionMatrix()); + mPhongShader.setVector3Uniform("lightAmbientColor", Vector3(0.3f, 0.3f, 0.3f)); + const Color& diffCol = mLight0.getDiffuseColor(); + const Color& specCol = mLight0.getSpecularColor(); + mPhongShader.setVector3Uniform("light0DiffuseColor", Vector3(diffCol.r, diffCol.g, diffCol.b)); + mPhongShader.setVector3Uniform("light0SpecularColor", Vector3(specCol.r, specCol.g, specCol.b)); + mPhongShader.setFloatUniform("shininess", 60.0f); + + // Render all the boxes + mSliderJointBottomBox->render(mPhongShader, worldToCameraMatrix); + mSliderJointTopBox->render(mPhongShader, worldToCameraMatrix); + mPropellerBox->render(mPhongShader, worldToCameraMatrix); + mFixedJointBox1->render(mPhongShader, worldToCameraMatrix); + mFixedJointBox2->render(mPhongShader, worldToCameraMatrix); + for (int i=0; irender(mPhongShader, worldToCameraMatrix); + } + + // Render the floor + mFloor->render(mPhongShader, worldToCameraMatrix); + + // Unbind the shader + mPhongShader.unbind(); +} + +// Create the boxes and joints for the Ball-and-Socket joint example +void Scene::createBallAndSocketJoints() { + + // --------------- Create the boxes --------------- // + + openglframework::Vector3 positionBox(0, 15, 5); + openglframework::Vector3 boxDimension(1, 1, 1); + const float boxMass = 0.5f; + + for (int i=0; igetRigidBody()->setType(rp3d::STATIC); + } + + // Add some angular velocity damping + mBallAndSocketJointChainBoxes[i]->getRigidBody()->setAngularDamping(rp3d::decimal(0.2)); + + // Change the material properties of the rigid body + rp3d::Material& material = mBallAndSocketJointChainBoxes[i]->getRigidBody()->getMaterial(); + material.setBounciness(rp3d::decimal(0.4)); + + positionBox.y -= boxDimension.y + 0.5f; + } + + // --------------- Create the joints --------------- // + + for (int i=0; igetRigidBody(); + rp3d::RigidBody* body2 = mBallAndSocketJointChainBoxes[i+1]->getRigidBody(); + rp3d::Vector3 body1Position = body1->getTransform().getPosition(); + rp3d::Vector3 body2Position = body2->getTransform().getPosition(); + const rp3d::Vector3 anchorPointWorldSpace = 0.5 * (body1Position + body2Position); + rp3d::BallAndSocketJointInfo jointInfo(body1, body2, anchorPointWorldSpace); + + // Create the joint in the dynamics world + mBallAndSocketJoints[i] = dynamic_cast( + mDynamicsWorld->createJoint(jointInfo)); + } +} + +/// Create the boxes and joint for the Slider joint example +void Scene::createSliderJoint() { + + // --------------- Create the first box --------------- // + + // Position of the box + openglframework::Vector3 positionBox1(0, 2.1f, 0); + + // Create a box and a corresponding rigid in the dynamics world + openglframework::Vector3 box1Dimension(2, 4, 2); + mSliderJointBottomBox = new Box(box1Dimension, positionBox1 , BOX_MASS, mDynamicsWorld); + + // The fist box cannot move + mSliderJointBottomBox->getRigidBody()->setType(rp3d::STATIC); + + // Change the material properties of the rigid body + rp3d::Material& material1 = mSliderJointBottomBox->getRigidBody()->getMaterial(); + material1.setBounciness(0.4f); + + // --------------- Create the second box --------------- // + + // Position of the box + openglframework::Vector3 positionBox2(0, 4.2f, 0); + + // Create a box and a corresponding rigid in the dynamics world + openglframework::Vector3 box2Dimension(1.5f, 4, 1.5f); + mSliderJointTopBox = new Box(box2Dimension, positionBox2 , BOX_MASS, mDynamicsWorld); + + // Change the material properties of the rigid body + rp3d::Material& material2 = mSliderJointTopBox->getRigidBody()->getMaterial(); + material2.setBounciness(0.4f); + + // --------------- Create the joint --------------- // + + // Create the joint info object + rp3d::RigidBody* body1 = mSliderJointBottomBox->getRigidBody(); + rp3d::RigidBody* body2 = mSliderJointTopBox->getRigidBody(); + const rp3d::Vector3& body1Position = body1->getTransform().getPosition(); + const rp3d::Vector3& body2Position = body2->getTransform().getPosition(); + const rp3d::Vector3 anchorPointWorldSpace = rp3d::decimal(0.5) * (body2Position + body1Position); + const rp3d::Vector3 sliderAxisWorldSpace = (body2Position - body1Position); + rp3d::SliderJointInfo jointInfo(body1, body2, anchorPointWorldSpace, sliderAxisWorldSpace, + rp3d::decimal(-1.7), rp3d::decimal(1.7)); + jointInfo.isMotorEnabled = true; + jointInfo.motorSpeed = 0.0; + jointInfo.maxMotorForce = 10000.0; + jointInfo.isCollisionEnabled = false; + + // Create the joint in the dynamics world + mSliderJoint = dynamic_cast(mDynamicsWorld->createJoint(jointInfo)); +} + +/// Create the boxes and joint for the Hinge joint example +void Scene::createPropellerHingeJoint() { + + // --------------- Create the propeller box --------------- // + + // Position of the box + openglframework::Vector3 positionBox1(0, 7, 0); + + // Create a box and a corresponding rigid in the dynamics world + openglframework::Vector3 boxDimension(10, 1, 1); + mPropellerBox = new Box(boxDimension, positionBox1 , BOX_MASS, mDynamicsWorld); + + // Change the material properties of the rigid body + rp3d::Material& material = mPropellerBox->getRigidBody()->getMaterial(); + material.setBounciness(rp3d::decimal(0.4)); + + // --------------- Create the Hinge joint --------------- // + + // Create the joint info object + rp3d::RigidBody* body1 = mPropellerBox->getRigidBody(); + rp3d::RigidBody* body2 = mSliderJointTopBox->getRigidBody(); + const rp3d::Vector3& body1Position = body1->getTransform().getPosition(); + const rp3d::Vector3& body2Position = body2->getTransform().getPosition(); + const rp3d::Vector3 anchorPointWorldSpace = 0.5 * (body2Position + body1Position); + const rp3d::Vector3 hingeAxisWorldSpace(0, 1, 0); + rp3d::HingeJointInfo jointInfo(body1, body2, anchorPointWorldSpace, hingeAxisWorldSpace); + jointInfo.isMotorEnabled = true; + jointInfo.motorSpeed = - rp3d::decimal(0.5) * PI; + jointInfo.maxMotorTorque = rp3d::decimal(60.0); + jointInfo.isCollisionEnabled = false; + + // Create the joint in the dynamics world + mPropellerHingeJoint = dynamic_cast(mDynamicsWorld->createJoint(jointInfo)); +} + +/// Create the boxes and joints for the fixed joints +void Scene::createFixedJoints() { + + // --------------- Create the first box --------------- // + + // Position of the box + openglframework::Vector3 positionBox1(5, 7, 0); + + // Create a box and a corresponding rigid in the dynamics world + openglframework::Vector3 boxDimension(1.5, 1.5, 1.5); + mFixedJointBox1 = new Box(boxDimension, positionBox1 , BOX_MASS, mDynamicsWorld); + + // Change the material properties of the rigid body + rp3d::Material& material1 = mFixedJointBox1->getRigidBody()->getMaterial(); + material1.setBounciness(rp3d::decimal(0.4)); + + // --------------- Create the second box --------------- // + + // Position of the box + openglframework::Vector3 positionBox2(-5, 7, 0); + + // Create a box and a corresponding rigid in the dynamics world + mFixedJointBox2 = new Box(boxDimension, positionBox2 , BOX_MASS, mDynamicsWorld); + + // Change the material properties of the rigid body + rp3d::Material& material2 = mFixedJointBox2->getRigidBody()->getMaterial(); + material2.setBounciness(rp3d::decimal(0.4)); + + // --------------- Create the first fixed joint --------------- // + + // Create the joint info object + rp3d::RigidBody* body1 = mFixedJointBox1->getRigidBody(); + rp3d::RigidBody* propellerBody = mPropellerBox->getRigidBody(); + const rp3d::Vector3 anchorPointWorldSpace1(5, 7, 0); + rp3d::FixedJointInfo jointInfo1(body1, propellerBody, anchorPointWorldSpace1); + jointInfo1.isCollisionEnabled = false; + + // Create the joint in the dynamics world + mFixedJoint1 = dynamic_cast(mDynamicsWorld->createJoint(jointInfo1)); + + // --------------- Create the second fixed joint --------------- // + + // Create the joint info object + rp3d::RigidBody* body2 = mFixedJointBox2->getRigidBody(); + const rp3d::Vector3 anchorPointWorldSpace2(-5, 7, 0); + rp3d::FixedJointInfo jointInfo2(body2, propellerBody, anchorPointWorldSpace2); + jointInfo2.isCollisionEnabled = false; + + // Create the joint in the dynamics world + mFixedJoint2 = dynamic_cast(mDynamicsWorld->createJoint(jointInfo2)); +} + +// Create the floor +void Scene::createFloor() { + + // Create the floor + openglframework::Vector3 floorPosition(0, 0, 0); + mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld); + + // The floor must be a static rigid body + mFloor->getRigidBody()->setType(rp3d::STATIC); + + // Change the material properties of the rigid body + rp3d::Material& material = mFloor->getRigidBody()->getMaterial(); + material.setBounciness(rp3d::decimal(0.3)); +} diff --git a/testbed/examples/joints/Scene.h b/testbed/examples/joints/Scene.h new file mode 100644 index 00000000..4467f3af --- /dev/null +++ b/testbed/examples/joints/Scene.h @@ -0,0 +1,172 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +#ifndef SCENE_H +#define SCENE_H + +// Libraries +#include "openglframework.h" +#include "reactphysics3d.h" +#include "Box.h" +#include "../common/Viewer.h" + +// Constants +const openglframework::Vector3 BOX_SIZE(2, 2, 2); // Box dimensions in meters +const openglframework::Vector3 FLOOR_SIZE(20, 0.5f, 20); // Floor dimensions in meters +const float BOX_MASS = 1.0f; // Box mass in kilograms +const float FLOOR_MASS = 100.0f; // Floor mass in kilograms +const int NB_BALLSOCKETJOINT_BOXES = 7; // Number of Ball-And-Socket chain boxes +const int NB_HINGE_BOXES = 7; // Number of Hinge chain boxes + +// Class Scene +class Scene { + + private : + + // -------------------- Attributes -------------------- // + + /// Pointer to the viewer + Viewer* mViewer; + + /// Light 0 + openglframework::Light mLight0; + + /// Phong shader + openglframework::Shader mPhongShader; + + /// Boxes of Ball-And-Socket joint chain + Box* mBallAndSocketJointChainBoxes[NB_BALLSOCKETJOINT_BOXES]; + + /// Boxes of the Hinge joint chain + Box* mHingeJointChainBoxes[NB_HINGE_BOXES]; + + /// Ball-And-Socket joints of the chain + rp3d::BallAndSocketJoint* mBallAndSocketJoints[NB_BALLSOCKETJOINT_BOXES-1]; + + /// Hinge joints of the chain + rp3d::HingeJoint* mHingeJoints[NB_HINGE_BOXES-1]; + + /// Bottom box of the Slider joint + Box* mSliderJointBottomBox; + + /// Top box of the Slider joint + Box* mSliderJointTopBox; + + /// Slider joint + rp3d::SliderJoint* mSliderJoint; + + /// Propeller box + Box* mPropellerBox; + + /// Box 1 of Fixed joint + Box* mFixedJointBox1; + + /// Box 2 of Fixed joint + Box* mFixedJointBox2; + + /// Hinge joint + rp3d::HingeJoint* mPropellerHingeJoint; + + /// First Fixed joint + rp3d::FixedJoint* mFixedJoint1; + + /// Second Fixed joint + rp3d::FixedJoint* mFixedJoint2; + + /// Box for the floor + Box* mFloor; + + /// Dynamics world used for the physics simulation + rp3d::DynamicsWorld* mDynamicsWorld; + + /// True if the physics simulation is running + bool mIsRunning; + + // -------------------- Methods -------------------- // + + /// Create the boxes and joints for the Ball-and-Socket joint example + void createBallAndSocketJoints(); + + /// Create the boxes and joint for the Slider joint example + void createSliderJoint(); + + /// Create the boxes and joint for the Hinge joint example + void createPropellerHingeJoint(); + + /// Create the boxes and joint for the Fixed joint example + void createFixedJoints(); + + /// Create the floor + void createFloor(); + + public: + + // -------------------- Methods -------------------- // + + /// Constructor + Scene(Viewer* viewer, const std::string& shaderFolderPath); + + /// Destructor + ~Scene(); + + /// Take a step for the simulation + void simulate(); + + /// Stop the simulation + void stopSimulation(); + + /// Start the simulation + void startSimulation(); + + /// Pause or continue simulation + void pauseContinueSimulation(); + + /// Render the scene + void render(); +}; + +// Stop the simulation +inline void Scene::stopSimulation() { + mDynamicsWorld->stop(); + mIsRunning = false; +} + +// Start the simulation +inline void Scene::startSimulation() { + mDynamicsWorld->start(); + mIsRunning = true; +} + +// Pause or continue simulation +inline void Scene::pauseContinueSimulation() { + if (mIsRunning) { + stopSimulation(); + } + else { + startSimulation(); + } +} + +#endif diff --git a/testbed/examples/raycast/CMakeLists.txt b/testbed/examples/raycast/CMakeLists.txt new file mode 100644 index 00000000..01440b00 --- /dev/null +++ b/testbed/examples/raycast/CMakeLists.txt @@ -0,0 +1,43 @@ +# Minimum cmake version required +cmake_minimum_required(VERSION 2.6) + +# Project configuration +PROJECT(Raycast) + +# Where to build the executables +SET(EXECUTABLE_OUTPUT_PATH "${OUR_EXECUTABLE_OUTPUT_PATH}/raycast") +SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}) +SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${EXECUTABLE_OUTPUT_PATH}) +SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${EXECUTABLE_OUTPUT_PATH}) + +# Copy the shaders used for the demo into the build directory +FILE(COPY "${OPENGLFRAMEWORK_DIR}/src/shaders/" DESTINATION "${EXECUTABLE_OUTPUT_PATH}/shaders/") + +# Copy the meshes used for the demo into the build directory +FILE(COPY "../common/meshes/" DESTINATION "${EXECUTABLE_OUTPUT_PATH}/meshes/") + +# Headers +INCLUDE_DIRECTORIES("${OPENGLFRAMEWORK_DIR}/src/" "../common/glfw/include/" "../common/") + +# Source files +SET(RAYCAST_SOURCES + Raycast.cpp + Scene.cpp + Scene.h + "../common/VisualContactPoint.cpp" + "../common/ConvexMesh.cpp" + "../common/Capsule.cpp" + "../common/Sphere.cpp" + "../common/Line.cpp" + "../common/Cylinder.cpp" + "../common/Cone.cpp" + "../common/Dumbbell.cpp" + "../common/Box.cpp" + "../common/Viewer.cpp" +) + +# Create the executable +ADD_EXECUTABLE(raycast ${RAYCAST_SOURCES}) + +# Link with libraries +TARGET_LINK_LIBRARIES(raycast reactphysics3d openglframework glfw ${GLFW_LIBRARIES}) diff --git a/testbed/examples/raycast/Raycast.cpp b/testbed/examples/raycast/Raycast.cpp new file mode 100644 index 00000000..e971069a --- /dev/null +++ b/testbed/examples/raycast/Raycast.cpp @@ -0,0 +1,155 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Libraries +#include "Scene.h" +#include "../common/Viewer.h" + +// Declarations +void simulate(); +void render(); +void update(); +void mouseButton(GLFWwindow* window, int button, int action, int mods); +void mouseMotion(GLFWwindow* window, double x, double y); +void keyboard(GLFWwindow* window, int key, int scancode, int action, int mods); +void scroll(GLFWwindow* window, double xAxis, double yAxis); +void init(); + +// Namespaces +using namespace openglframework; + +// Global variables +Viewer* viewer; +Scene* scene; + +// Main function +int main(int argc, char** argv) { + + // Create and initialize the Viewer + viewer = new Viewer(); + Vector2 windowsSize = Vector2(800, 600); + Vector2 windowsPosition = Vector2(100, 100); + viewer->init(argc, argv, "ReactPhysics3D Examples - Raycast", + windowsSize, windowsPosition, true); + + // If the shaders and meshes folders are not specified as an argument + if (argc < 3) { + std::cerr << "Error : You need to specify the shaders folder as the first argument" + << " and the meshes folder as the second argument" << std::endl; + return 1; + } + + // Get the path of the shaders folder + std::string shaderFolderPath(argv[1]); + std::string meshFolderPath(argv[2]); + + // Register callback methods + viewer->registerUpdateFunction(update); + viewer->registerKeyboardCallback(keyboard); + viewer->registerMouseButtonCallback(mouseButton); + viewer->registerMouseCursorCallback(mouseMotion); + viewer->registerScrollingCallback(scroll); + + // Create the scene + scene = new Scene(viewer, shaderFolderPath, meshFolderPath); + + init(); + + viewer->startMainLoop(); + + delete viewer; + delete scene; + + return 0; +} + +// Update function that is called each frame +void update() { + + // Take a simulation step + simulate(); + + // Render + render(); +} + +// Simulate function +void simulate() { + + // Physics simulation + scene->simulate(); + + viewer->computeFPS(); +} + +// Initialization +void init() { + + // Define the background color (black) + glClearColor(0.0, 0.0, 0.0, 1.0); +} + +// Callback method to receive keyboard events +void keyboard(GLFWwindow* window, int key, int scancode, int action, int mods) { + if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) { + glfwSetWindowShouldClose(window, GL_TRUE); + } + if (key == GLFW_KEY_SPACE && action == GLFW_PRESS) { + scene->changeBody(); + } + if (key == GLFW_KEY_N && action == GLFW_PRESS) { + scene->showHideNormals(); + } +} + +// Callback method to receive scrolling events +void scroll(GLFWwindow* window, double xAxis, double yAxis) { + viewer->scrollingEvent(static_cast(yAxis)); +} + +// Called when a mouse button event occurs +void mouseButton(GLFWwindow* window, int button, int action, int mods) { + viewer->mouseButtonEvent(button, action); +} + +// Called when a mouse motion event occurs +void mouseMotion(GLFWwindow* window, double x, double y) { + viewer->mouseMotionEvent(x, y); +} + +// Display the scene +void render() { + + // Render the scene + scene->render(); + + // Display the FPS + viewer->displayGUI(); + + // Check the OpenGL errors + Viewer::checkOpenGLErrors(); +} + + diff --git a/testbed/examples/raycast/Scene.cpp b/testbed/examples/raycast/Scene.cpp new file mode 100644 index 00000000..da6423a3 --- /dev/null +++ b/testbed/examples/raycast/Scene.cpp @@ -0,0 +1,307 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Libraries +#include "Scene.h" + +// Namespaces +using namespace openglframework; + +// Constructor +Scene::Scene(Viewer* viewer, const std::string& shaderFolderPath, const std::string& meshFolderPath) + : mViewer(viewer), mLight0(0), mCurrentBodyIndex(-1), mAreNormalsDisplayed(false), + mPhongShader(shaderFolderPath + "phong.vert", + shaderFolderPath +"phong.frag") { + + // Move the light 0 + mLight0.translateWorld(Vector3(50, 50, 50)); + + // Compute the radius and the center of the scene + float radiusScene = 30.0f; + openglframework::Vector3 center(0, 0, 0); + + // Set the center of the scene + mViewer->setScenePosition(center, radiusScene); + + // Create the dynamics world for the physics simulation + mCollisionWorld = new rp3d::CollisionWorld(); + + // Create the static data for the visual contact points + VisualContactPoint::createStaticData(meshFolderPath); + + // ---------- Dumbbell ---------- // + openglframework::Vector3 position1(0, 0, 0); + + // Create a convex mesh and a corresponding collision body in the dynamics world + mDumbbell = new Dumbbell(position1, mCollisionWorld, meshFolderPath); + + // ---------- Box ---------- // + openglframework::Vector3 position2(0, 0, 0); + + // Create a box and a corresponding collision body in the dynamics world + mBox = new Box(BOX_SIZE, position2, mCollisionWorld); + mBox->getCollisionBody()->setIsActive(false); + + // ---------- Sphere ---------- // + openglframework::Vector3 position3(0, 0, 0); + + // Create a sphere and a corresponding collision body in the dynamics world + mSphere = new Sphere(SPHERE_RADIUS, position3, mCollisionWorld, + meshFolderPath); + + // ---------- Cone ---------- // + openglframework::Vector3 position4(0, 0, 0); + + // Create a cone and a corresponding collision body in the dynamics world + mCone = new Cone(CONE_RADIUS, CONE_HEIGHT, position4, mCollisionWorld, + meshFolderPath); + + // ---------- Cylinder ---------- // + openglframework::Vector3 position5(0, 0, 0); + + // Create a cylinder and a corresponding collision body in the dynamics world + mCylinder = new Cylinder(CYLINDER_RADIUS, CYLINDER_HEIGHT, position5, + mCollisionWorld, meshFolderPath); + + // ---------- Capsule ---------- // + openglframework::Vector3 position6(0, 0, 0); + + // Create a cylinder and a corresponding collision body in the dynamics world + mCapsule = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, position6 , + mCollisionWorld, meshFolderPath); + + // ---------- Convex Mesh ---------- // + openglframework::Vector3 position7(0, 0, 0); + + // Create a convex mesh and a corresponding collision body in the dynamics world + mConvexMesh = new ConvexMesh(position7, mCollisionWorld, meshFolderPath); + + // Create the lines that will be used for raycasting + createLines(); + + changeBody(); +} + +// Create the raycast lines +void Scene::createLines() { + + int nbRaysOneDimension = std::sqrt(float(NB_RAYS)); + + for (int i=0; i= NB_BODIES) mCurrentBodyIndex = 0; + + mSphere->getCollisionBody()->setIsActive(false); + mBox->getCollisionBody()->setIsActive(false); + mCone->getCollisionBody()->setIsActive(false); + mCylinder->getCollisionBody()->setIsActive(false); + mCapsule->getCollisionBody()->setIsActive(false); + mConvexMesh->getCollisionBody()->setIsActive(false); + mDumbbell->getCollisionBody()->setIsActive(false); + + switch(mCurrentBodyIndex) { + case 0: mSphere->getCollisionBody()->setIsActive(true); + break; + case 1: mBox->getCollisionBody()->setIsActive(true); + break; + case 2: mCone->getCollisionBody()->setIsActive(true); + break; + case 3: mCylinder->getCollisionBody()->setIsActive(true); + break; + case 4: mCapsule->getCollisionBody()->setIsActive(true); + break; + case 5: mConvexMesh->getCollisionBody()->setIsActive(true); + break; + case 6: mDumbbell->getCollisionBody()->setIsActive(true); + break; + + } +} + +// Destructor +Scene::~Scene() { + + // Destroy the shader + mPhongShader.destroy(); + + // Destroy the box rigid body from the dynamics world + mCollisionWorld->destroyCollisionBody(mBox->getCollisionBody()); + delete mBox; + + // Destroy the sphere + mCollisionWorld->destroyCollisionBody(mSphere->getCollisionBody()); + delete mSphere; + + // Destroy the corresponding rigid body from the dynamics world + mCollisionWorld->destroyCollisionBody(mCone->getCollisionBody()); + delete mCone; + + // Destroy the corresponding rigid body from the dynamics world + mCollisionWorld->destroyCollisionBody(mCylinder->getCollisionBody()); + + // Destroy the sphere + delete mCylinder; + + // Destroy the corresponding rigid body from the dynamics world + mCollisionWorld->destroyCollisionBody(mCapsule->getCollisionBody()); + + // Destroy the sphere + delete mCapsule; + + // Destroy the corresponding rigid body from the dynamics world + mCollisionWorld->destroyCollisionBody(mConvexMesh->getCollisionBody()); + + // Destroy the convex mesh + delete mConvexMesh; + + // Destroy the corresponding rigid body from the dynamics world + mCollisionWorld->destroyCollisionBody(mDumbbell->getCollisionBody()); + + // Destroy the convex mesh + delete mDumbbell; + + mRaycastManager.resetPoints(); + + // Destroy the static data for the visual contact points + VisualContactPoint::destroyStaticData(); + + // Destroy the collision world + delete mCollisionWorld; + + // Destroy the lines + for (std::vector::iterator it = mLines.begin(); it != mLines.end(); + ++it) { + delete (*it); + } +} + +// Take a step for the simulation +void Scene::simulate() { + + mRaycastManager.resetPoints(); + + // For each line of the scene + for (std::vector::iterator it = mLines.begin(); it != mLines.end(); + ++it) { + + Line* line = *it; + + // Create a ray corresponding to the line + openglframework::Vector3 p1 = line->getPoint1(); + openglframework::Vector3 p2 = line->getPoint2(); + + rp3d::Vector3 point1(p1.x, p1.y, p1.z); + rp3d::Vector3 point2(p2.x, p2.y, p2.z); + rp3d::Ray ray(point1, point2); + + // Perform a raycast query on the physics world by passing a raycast + // callback class in argument. + mCollisionWorld->raycast(ray, &mRaycastManager); + } +} + +// Render the scene +void Scene::render() { + + glEnable(GL_DEPTH_TEST); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glEnable(GL_CULL_FACE); + + // Get the world-space to camera-space matrix + const Camera& camera = mViewer->getCamera(); + const openglframework::Matrix4 worldToCameraMatrix = camera.getTransformMatrix().getInverse(); + + // Bind the shader + mPhongShader.bind(); + + openglframework::Vector4 grey(0.7, 0.7, 0.7, 1); + mPhongShader.setVector4Uniform("vertexColor", grey); + + // Set the variables of the shader + mPhongShader.setMatrix4x4Uniform("projectionMatrix", camera.getProjectionMatrix()); + mPhongShader.setVector3Uniform("light0PosCameraSpace", worldToCameraMatrix * mLight0.getOrigin()); + mPhongShader.setVector3Uniform("lightAmbientColor", Vector3(0.3f, 0.3f, 0.3f)); + const Color& diffColLight0 = mLight0.getDiffuseColor(); + const Color& specColLight0 = mLight0.getSpecularColor(); + mPhongShader.setVector3Uniform("light0DiffuseColor", Vector3(diffColLight0.r, diffColLight0.g, diffColLight0.b)); + mPhongShader.setVector3Uniform("light0SpecularColor", Vector3(specColLight0.r, specColLight0.g, specColLight0.b)); + mPhongShader.setFloatUniform("shininess", 200.0f); + + if (mBox->getCollisionBody()->isActive()) mBox->render(mPhongShader, worldToCameraMatrix); + if (mSphere->getCollisionBody()->isActive()) mSphere->render(mPhongShader, worldToCameraMatrix); + if (mCone->getCollisionBody()->isActive()) mCone->render(mPhongShader, worldToCameraMatrix); + if (mCylinder->getCollisionBody()->isActive()) mCylinder->render(mPhongShader, worldToCameraMatrix); + if (mCapsule->getCollisionBody()->isActive()) mCapsule->render(mPhongShader, worldToCameraMatrix); + if (mConvexMesh->getCollisionBody()->isActive()) mConvexMesh->render(mPhongShader, worldToCameraMatrix); + if (mDumbbell->getCollisionBody()->isActive()) mDumbbell->render(mPhongShader, worldToCameraMatrix); + + mPhongShader.unbind(); + mPhongShader.bind(); + + mPhongShader.setVector3Uniform("light0SpecularColor", Vector3(0, 0, 0)); + openglframework::Vector4 redColor(1, 0, 0, 1); + mPhongShader.setVector4Uniform("vertexColor", redColor); + + // Render all the raycast hit points + mRaycastManager.render(mPhongShader, worldToCameraMatrix, mAreNormalsDisplayed); + + mPhongShader.unbind(); + mPhongShader.bind(); + + openglframework::Vector4 blueColor(0, 0.62, 0.92, 1); + mPhongShader.setVector4Uniform("vertexColor", blueColor); + + // Render the lines + for (std::vector::iterator it = mLines.begin(); it != mLines.end(); + ++it) { + (*it)->render(mPhongShader, worldToCameraMatrix); + } + + // Unbind the shader + mPhongShader.unbind(); +} diff --git a/testbed/examples/raycast/Scene.h b/testbed/examples/raycast/Scene.h new file mode 100644 index 00000000..9b044e06 --- /dev/null +++ b/testbed/examples/raycast/Scene.h @@ -0,0 +1,200 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +#ifndef SCENE_H +#define SCENE_H + +// Libraries +#define _USE_MATH_DEFINES +#include +#include "openglframework.h" +#include "reactphysics3d.h" +#include "Sphere.h" +#include "Box.h" +#include "Cone.h" +#include "Cylinder.h" +#include "Capsule.h" +#include "Line.h" +#include "ConvexMesh.h" +#include "Dumbbell.h" +#include "VisualContactPoint.h" +#include "../common/Viewer.h" + +// Constants +const openglframework::Vector3 BOX_SIZE(4, 2, 1); +const float SPHERE_RADIUS = 3.0f; +const float CONE_RADIUS = 3.0f; +const float CONE_HEIGHT = 5.0f; +const float CYLINDER_RADIUS = 3.0f; +const float CYLINDER_HEIGHT = 5.0f; +const float CAPSULE_RADIUS = 3.0f; +const float CAPSULE_HEIGHT = 5.0f; +const float DUMBBELL_HEIGHT = 5.0f; +const int NB_RAYS = 100; +const float RAY_LENGTH = 30.0f; +const int NB_BODIES = 7; + +// Raycast manager +class RaycastManager : public rp3d::RaycastCallback { + + private: + + /// All the visual contact points + std::vector mHitPoints; + + /// All the normals at hit points + std::vector mNormals; + + public: + + virtual rp3d::decimal notifyRaycastHit(const rp3d::RaycastInfo& raycastInfo) { + rp3d::Vector3 hitPos = raycastInfo.worldPoint; + openglframework::Vector3 position(hitPos.x, hitPos.y, hitPos.z); + VisualContactPoint* point = new VisualContactPoint(position); + mHitPoints.push_back(point); + + // Create a line to display the normal at hit point + rp3d::Vector3 n = raycastInfo.worldNormal; + openglframework::Vector3 normal(n.x, n.y, n.z); + Line* normalLine = new Line(position, position + normal); + mNormals.push_back(normalLine); + + return raycastInfo.hitFraction; + } + + void render(openglframework::Shader& shader, + const openglframework::Matrix4& worldToCameraMatrix, + bool showNormals) { + + // Render all the raycast hit points + for (std::vector::iterator it = mHitPoints.begin(); + it != mHitPoints.end(); ++it) { + (*it)->render(shader, worldToCameraMatrix); + } + + if (showNormals) { + + // Render all the normals at hit points + for (std::vector::iterator it = mNormals.begin(); + it != mNormals.end(); ++it) { + (*it)->render(shader, worldToCameraMatrix); + } + } + } + + void resetPoints() { + + // Destroy all the visual contact points + for (std::vector::iterator it = mHitPoints.begin(); + it != mHitPoints.end(); ++it) { + delete (*it); + } + mHitPoints.clear(); + + // Destroy all the normals + for (std::vector::iterator it = mNormals.begin(); + it != mNormals.end(); ++it) { + delete (*it); + } + mNormals.clear(); + } +}; + +// Class Scene +class Scene { + + private : + + // -------------------- Attributes -------------------- // + + /// Pointer to the viewer + Viewer* mViewer; + + /// Raycast manager + RaycastManager mRaycastManager; + + /// Light 0 + openglframework::Light mLight0; + + /// Phong shader + openglframework::Shader mPhongShader; + + /// All the raycast lines + std::vector mLines; + + /// Current body index + int mCurrentBodyIndex; + + /// True if the hit points normals are displayed + bool mAreNormalsDisplayed; + + /// Raycast manager + + /// All objects on the scene + Box* mBox; + Sphere* mSphere; + Cone* mCone; + Cylinder* mCylinder; + Capsule* mCapsule; + ConvexMesh* mConvexMesh; + Dumbbell* mDumbbell; + + /// Collision world used for the physics simulation + rp3d::CollisionWorld* mCollisionWorld; + + /// Create the raycast lines + void createLines(); + + public: + + // -------------------- Methods -------------------- // + + /// Constructor + Scene(Viewer* viewer, const std::string& shaderFolderPath, + const std::string& meshFolderPath); + + /// Destructor + ~Scene(); + + /// Take a step for the simulation + void simulate(); + + /// Render the scene + void render(); + + /// Change the body to raycast + void changeBody(); + + /// Display or not the surface normals at hit points + void showHideNormals(); +}; + +// Display or not the surface normals at hit points +inline void Scene::showHideNormals() { + mAreNormalsDisplayed = !mAreNormalsDisplayed; +} + + +#endif diff --git a/testbed/glfw/.gitignore b/testbed/glfw/.gitignore new file mode 100644 index 00000000..3ba142ef --- /dev/null +++ b/testbed/glfw/.gitignore @@ -0,0 +1,70 @@ +# External junk +.DS_Store +_ReSharper* +*.opensdf +*.sdf +*.dir +*.vcxproj* +*.sln +Win32 +Debug +Release + +# CMake files +Makefile +CMakeCache.txt +CMakeFiles +cmake_install.cmake +cmake_uninstall.cmake + +# Generated files +docs/Doxyfile +docs/html +docs/warnings.txt +src/config.h +src/glfw3.pc +src/glfwConfig.cmake +src/glfwConfigVersion.cmake + +# Compiled binaries +src/libglfw.so +src/libglfw.so.3 +src/libglfw.so.3.0 +src/libglfw.dylib +src/libglfw.dylib +src/libglfw.3.dylib +src/libglfw.3.0.dylib +src/libglfw3.a +src/glfw3.lib +src/glfw3.dll +src/glfw3dll.lib +src/glfw3dll.a +examples/*.app +examples/*.exe +examples/boing +examples/gears +examples/heightmap +examples/splitview +examples/simple +examples/wave +tests/*.app +tests/*.exe +tests/accuracy +tests/clipboard +tests/defaults +tests/events +tests/fsaa +tests/gamma +tests/glfwinfo +tests/iconify +tests/joysticks +tests/modes +tests/peter +tests/reopen +tests/sharing +tests/tearing +tests/threads +tests/title +tests/version +tests/windows + diff --git a/testbed/glfw/CMake/amd64-mingw32msvc.cmake b/testbed/glfw/CMake/amd64-mingw32msvc.cmake new file mode 100644 index 00000000..705e251d --- /dev/null +++ b/testbed/glfw/CMake/amd64-mingw32msvc.cmake @@ -0,0 +1,13 @@ +# Define the environment for cross compiling from Linux to Win64 +SET(CMAKE_SYSTEM_NAME Windows) +SET(CMAKE_SYSTEM_VERSION 1) +SET(CMAKE_C_COMPILER "amd64-mingw32msvc-gcc") +SET(CMAKE_CXX_COMPILER "amd64-mingw32msvc-g++") +SET(CMAKE_RC_COMPILER "amd64-mingw32msvc-windres") +SET(CMAKE_RANLIB "amd64-mingw32msvc-ranlib") + +# Configure the behaviour of the find commands +SET(CMAKE_FIND_ROOT_PATH "/usr/amd64-mingw32msvc") +SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/testbed/glfw/CMake/i586-mingw32msvc.cmake b/testbed/glfw/CMake/i586-mingw32msvc.cmake new file mode 100644 index 00000000..393ddbda --- /dev/null +++ b/testbed/glfw/CMake/i586-mingw32msvc.cmake @@ -0,0 +1,13 @@ +# Define the environment for cross compiling from Linux to Win32 +SET(CMAKE_SYSTEM_NAME Windows) +SET(CMAKE_SYSTEM_VERSION 1) +SET(CMAKE_C_COMPILER "i586-mingw32msvc-gcc") +SET(CMAKE_CXX_COMPILER "i586-mingw32msvc-g++") +SET(CMAKE_RC_COMPILER "i586-mingw32msvc-windres") +SET(CMAKE_RANLIB "i586-mingw32msvc-ranlib") + +# Configure the behaviour of the find commands +SET(CMAKE_FIND_ROOT_PATH "/usr/i586-mingw32msvc") +SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/testbed/glfw/CMake/i686-pc-mingw32.cmake b/testbed/glfw/CMake/i686-pc-mingw32.cmake new file mode 100644 index 00000000..9a46aef7 --- /dev/null +++ b/testbed/glfw/CMake/i686-pc-mingw32.cmake @@ -0,0 +1,13 @@ +# Define the environment for cross compiling from Linux to Win32 +SET(CMAKE_SYSTEM_NAME Windows) # Target system name +SET(CMAKE_SYSTEM_VERSION 1) +SET(CMAKE_C_COMPILER "i686-pc-mingw32-gcc") +SET(CMAKE_CXX_COMPILER "i686-pc-mingw32-g++") +SET(CMAKE_RC_COMPILER "i686-pc-mingw32-windres") +SET(CMAKE_RANLIB "i686-pc-mingw32-ranlib") + +#Configure the behaviour of the find commands +SET(CMAKE_FIND_ROOT_PATH "/opt/mingw/usr/i686-pc-mingw32") +SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/testbed/glfw/CMake/i686-w64-mingw32.cmake b/testbed/glfw/CMake/i686-w64-mingw32.cmake new file mode 100644 index 00000000..9bd60936 --- /dev/null +++ b/testbed/glfw/CMake/i686-w64-mingw32.cmake @@ -0,0 +1,13 @@ +# Define the environment for cross compiling from Linux to Win32 +SET(CMAKE_SYSTEM_NAME Windows) # Target system name +SET(CMAKE_SYSTEM_VERSION 1) +SET(CMAKE_C_COMPILER "i686-w64-mingw32-gcc") +SET(CMAKE_CXX_COMPILER "i686-w64-mingw32-g++") +SET(CMAKE_RC_COMPILER "i686-w64-mingw32-windres") +SET(CMAKE_RANLIB "i686-w64-mingw32-ranlib") + +# Configure the behaviour of the find commands +SET(CMAKE_FIND_ROOT_PATH "/usr/i686-w64-mingw32") +SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/testbed/glfw/CMake/modules/FindEGL.cmake b/testbed/glfw/CMake/modules/FindEGL.cmake new file mode 100644 index 00000000..796eef96 --- /dev/null +++ b/testbed/glfw/CMake/modules/FindEGL.cmake @@ -0,0 +1,16 @@ +# Find EGL +# +# EGL_INCLUDE_DIR +# EGL_LIBRARY +# EGL_FOUND + +find_path(EGL_INCLUDE_DIR NAMES EGL/egl.h PATHS /opt/vc/include) + +set(EGL_NAMES ${EGL_NAMES} egl EGL) +find_library(EGL_LIBRARY NAMES ${EGL_NAMES} PATHS /opt/vc/lib) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(EGL DEFAULT_MSG EGL_LIBRARY EGL_INCLUDE_DIR) + +mark_as_advanced(EGL_INCLUDE_DIR EGL_LIBRARY) + diff --git a/testbed/glfw/CMake/modules/FindGLESv1.cmake b/testbed/glfw/CMake/modules/FindGLESv1.cmake new file mode 100644 index 00000000..6ab0414c --- /dev/null +++ b/testbed/glfw/CMake/modules/FindGLESv1.cmake @@ -0,0 +1,16 @@ +# Find GLESv1 +# +# GLESv1_INCLUDE_DIR +# GLESv1_LIBRARY +# GLESv1_FOUND + +find_path(GLESv1_INCLUDE_DIR NAMES GLES/gl.h PATHS /opt/vc/include) + +set(GLESv1_NAMES ${GLESv1_NAMES} GLESv1_CM) +find_library(GLESv1_LIBRARY NAMES ${GLESv1_NAMES} PATHS /opt/vc/lib) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(GLESv1 DEFAULT_MSG GLESv1_LIBRARY GLESv1_INCLUDE_DIR) + +mark_as_advanced(GLESv1_INCLUDE_DIR GLESv1_LIBRARY) + diff --git a/testbed/glfw/CMake/modules/FindGLESv2.cmake b/testbed/glfw/CMake/modules/FindGLESv2.cmake new file mode 100644 index 00000000..12c4d063 --- /dev/null +++ b/testbed/glfw/CMake/modules/FindGLESv2.cmake @@ -0,0 +1,16 @@ +# Find GLESv2 +# +# GLESv2_INCLUDE_DIR +# GLESv2_LIBRARY +# GLESv2_FOUND + +find_path(GLESv2_INCLUDE_DIR NAMES GLES2/gl2.h PATHS /opt/vc/include) + +set(GLESv2_NAMES ${GLESv2_NAMES} GLESv2) +find_library(GLESv2_LIBRARY NAMES ${GLESv2_NAMES} PATHS /opt/vc/lib) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(GLESv2 DEFAULT_MSG GLESv2_LIBRARY GLESv2_INCLUDE_DIR) + +mark_as_advanced(GLESv2_INCLUDE_DIR GLESv2_LIBRARY) + diff --git a/testbed/glfw/CMake/modules/FindMir.cmake b/testbed/glfw/CMake/modules/FindMir.cmake new file mode 100644 index 00000000..b1a495ba --- /dev/null +++ b/testbed/glfw/CMake/modules/FindMir.cmake @@ -0,0 +1,18 @@ +# Try to find Mir on a Unix system +# +# This will define: +# +# MIR_LIBRARIES - Link these to use Wayland +# MIR_INCLUDE_DIR - Include directory for Wayland +# +# Copyright (c) 2014 Brandon Schaefer + +if (NOT WIN32) + + find_package (PkgConfig) + pkg_check_modules (PKG_MIR QUIET mirclient) + + set (MIR_INCLUDE_DIR ${PKG_MIR_INCLUDE_DIRS}) + set (MIR_LIBRARIES ${PKG_MIR_LIBRARIES}) + +endif () diff --git a/testbed/glfw/CMake/modules/FindWayland.cmake b/testbed/glfw/CMake/modules/FindWayland.cmake new file mode 100644 index 00000000..f93218b8 --- /dev/null +++ b/testbed/glfw/CMake/modules/FindWayland.cmake @@ -0,0 +1,66 @@ +# Try to find Wayland on a Unix system +# +# This will define: +# +# WAYLAND_FOUND - True if Wayland is found +# WAYLAND_LIBRARIES - Link these to use Wayland +# WAYLAND_INCLUDE_DIR - Include directory for Wayland +# WAYLAND_DEFINITIONS - Compiler flags for using Wayland +# +# In addition the following more fine grained variables will be defined: +# +# WAYLAND_CLIENT_FOUND WAYLAND_CLIENT_INCLUDE_DIR WAYLAND_CLIENT_LIBRARIES +# WAYLAND_SERVER_FOUND WAYLAND_SERVER_INCLUDE_DIR WAYLAND_SERVER_LIBRARIES +# WAYLAND_EGL_FOUND WAYLAND_EGL_INCLUDE_DIR WAYLAND_EGL_LIBRARIES +# +# Copyright (c) 2013 Martin Gräßlin +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +IF (NOT WIN32) + IF (WAYLAND_INCLUDE_DIR AND WAYLAND_LIBRARIES) + # In the cache already + SET(WAYLAND_FIND_QUIETLY TRUE) + ENDIF () + + # Use pkg-config to get the directories and then use these values + # in the FIND_PATH() and FIND_LIBRARY() calls + FIND_PACKAGE(PkgConfig) + PKG_CHECK_MODULES(PKG_WAYLAND QUIET wayland-client wayland-server wayland-egl wayland-cursor) + + SET(WAYLAND_DEFINITIONS ${PKG_WAYLAND_CFLAGS}) + + FIND_PATH(WAYLAND_CLIENT_INCLUDE_DIR NAMES wayland-client.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS}) + FIND_PATH(WAYLAND_SERVER_INCLUDE_DIR NAMES wayland-server.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS}) + FIND_PATH(WAYLAND_EGL_INCLUDE_DIR NAMES wayland-egl.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS}) + FIND_PATH(WAYLAND_CURSOR_INCLUDE_DIR NAMES wayland-cursor.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS}) + + FIND_LIBRARY(WAYLAND_CLIENT_LIBRARIES NAMES wayland-client HINTS ${PKG_WAYLAND_LIBRARY_DIRS}) + FIND_LIBRARY(WAYLAND_SERVER_LIBRARIES NAMES wayland-server HINTS ${PKG_WAYLAND_LIBRARY_DIRS}) + FIND_LIBRARY(WAYLAND_EGL_LIBRARIES NAMES wayland-egl HINTS ${PKG_WAYLAND_LIBRARY_DIRS}) + FIND_LIBRARY(WAYLAND_CURSOR_LIBRARIES NAMES wayland-cursor HINTS ${PKG_WAYLAND_LIBRARY_DIRS}) + + set(WAYLAND_INCLUDE_DIR ${WAYLAND_CLIENT_INCLUDE_DIR} ${WAYLAND_SERVER_INCLUDE_DIR} ${WAYLAND_EGL_INCLUDE_DIR} ${WAYLAND_CURSOR_INCLUDE_DIR}) + + set(WAYLAND_LIBRARIES ${WAYLAND_CLIENT_LIBRARIES} ${WAYLAND_SERVER_LIBRARIES} ${WAYLAND_EGL_LIBRARIES} ${WAYLAND_CURSOR_LIBRARIES}) + + list(REMOVE_DUPLICATES WAYLAND_INCLUDE_DIR) + + include(FindPackageHandleStandardArgs) + + FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_CLIENT DEFAULT_MSG WAYLAND_CLIENT_LIBRARIES WAYLAND_CLIENT_INCLUDE_DIR) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_SERVER DEFAULT_MSG WAYLAND_SERVER_LIBRARIES WAYLAND_SERVER_INCLUDE_DIR) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_EGL DEFAULT_MSG WAYLAND_EGL_LIBRARIES WAYLAND_EGL_INCLUDE_DIR) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_CURSOR DEFAULT_MSG WAYLAND_CURSOR_LIBRARIES WAYLAND_CURSOR_INCLUDE_DIR) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND DEFAULT_MSG WAYLAND_LIBRARIES WAYLAND_INCLUDE_DIR) + + MARK_AS_ADVANCED( + WAYLAND_INCLUDE_DIR WAYLAND_LIBRARIES + WAYLAND_CLIENT_INCLUDE_DIR WAYLAND_CLIENT_LIBRARIES + WAYLAND_SERVER_INCLUDE_DIR WAYLAND_SERVER_LIBRARIES + WAYLAND_EGL_INCLUDE_DIR WAYLAND_EGL_LIBRARIES + WAYLAND_CURSOR_INCLUDE_DIR WAYLAND_CURSOR_LIBRARIES + ) + +ENDIF () diff --git a/testbed/glfw/CMake/modules/FindXKBCommon.cmake b/testbed/glfw/CMake/modules/FindXKBCommon.cmake new file mode 100644 index 00000000..0f571eea --- /dev/null +++ b/testbed/glfw/CMake/modules/FindXKBCommon.cmake @@ -0,0 +1,34 @@ +# - Try to find XKBCommon +# Once done, this will define +# +# XKBCOMMON_FOUND - System has XKBCommon +# XKBCOMMON_INCLUDE_DIRS - The XKBCommon include directories +# XKBCOMMON_LIBRARIES - The libraries needed to use XKBCommon +# XKBCOMMON_DEFINITIONS - Compiler switches required for using XKBCommon + +find_package(PkgConfig) +pkg_check_modules(PC_XKBCOMMON QUIET xkbcommon) +set(XKBCOMMON_DEFINITIONS ${PC_XKBCOMMON_CFLAGS_OTHER}) + +find_path(XKBCOMMON_INCLUDE_DIR + NAMES xkbcommon/xkbcommon.h + HINTS ${PC_XKBCOMMON_INCLUDE_DIR} ${PC_XKBCOMMON_INCLUDE_DIRS} +) + +find_library(XKBCOMMON_LIBRARY + NAMES xkbcommon + HINTS ${PC_XKBCOMMON_LIBRARY} ${PC_XKBCOMMON_LIBRARY_DIRS} +) + +set(XKBCOMMON_LIBRARIES ${XKBCOMMON_LIBRARY}) +set(XKBCOMMON_LIBRARY_DIRS ${XKBCOMMON_LIBRARY_DIRS}) +set(XKBCOMMON_INCLUDE_DIRS ${XKBCOMMON_INCLUDE_DIR}) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(XKBCommon DEFAULT_MSG + XKBCOMMON_LIBRARY + XKBCOMMON_INCLUDE_DIR +) + +mark_as_advanced(XKBCOMMON_LIBRARY XKBCOMMON_INCLUDE_DIR) + diff --git a/testbed/glfw/CMake/x86_64-w64-mingw32.cmake b/testbed/glfw/CMake/x86_64-w64-mingw32.cmake new file mode 100644 index 00000000..84b2c701 --- /dev/null +++ b/testbed/glfw/CMake/x86_64-w64-mingw32.cmake @@ -0,0 +1,13 @@ +# Define the environment for cross compiling from Linux to Win32 +SET(CMAKE_SYSTEM_NAME Windows) # Target system name +SET(CMAKE_SYSTEM_VERSION 1) +SET(CMAKE_C_COMPILER "x86_64-w64-mingw32-gcc") +SET(CMAKE_CXX_COMPILER "x86_64-w64-mingw32-g++") +SET(CMAKE_RC_COMPILER "x86_64-w64-mingw32-windres") +SET(CMAKE_RANLIB "x86_64-w64-mingw32-ranlib") + +# Configure the behaviour of the find commands +SET(CMAKE_FIND_ROOT_PATH "/usr/x86_64-w64-mingw32") +SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/testbed/glfw/CMakeLists.txt b/testbed/glfw/CMakeLists.txt new file mode 100644 index 00000000..731f09f7 --- /dev/null +++ b/testbed/glfw/CMakeLists.txt @@ -0,0 +1,586 @@ +project(GLFW C) + +cmake_minimum_required(VERSION 2.8.9) + +if (CMAKE_VERSION VERSION_EQUAL "3.0" OR CMAKE_VERSION VERSION_GREATER "3.0") + # Until all major package systems have moved to CMake 3, + # we stick with the older INSTALL_NAME_DIR mechanism + cmake_policy(SET CMP0042 OLD) +endif() + +set(GLFW_VERSION_MAJOR "3") +set(GLFW_VERSION_MINOR "1") +set(GLFW_VERSION_PATCH "0") +set(GLFW_VERSION_EXTRA "") +set(GLFW_VERSION "${GLFW_VERSION_MAJOR}.${GLFW_VERSION_MINOR}") +set(GLFW_VERSION_FULL "${GLFW_VERSION}.${GLFW_VERSION_PATCH}${GLFW_VERSION_EXTRA}") +set(LIB_SUFFIX "" CACHE STRING "Takes an empty string or 64. Directory where lib will be installed: lib or lib64") + +set_property(GLOBAL PROPERTY USE_FOLDERS ON) + +option(BUILD_SHARED_LIBS "Build shared libraries" OFF) +option(GLFW_BUILD_EXAMPLES "Build the GLFW example programs" ON) +option(GLFW_BUILD_TESTS "Build the GLFW test programs" ON) +option(GLFW_BUILD_DOCS "Build the GLFW documentation" ON) +option(GLFW_INSTALL "Generate installation target" ON) +option(GLFW_DOCUMENT_INTERNALS "Include internals in documentation" OFF) + +if (WIN32) + option(GLFW_USE_DWM_SWAP_INTERVAL "Set swap interval even when DWM compositing is enabled" OFF) + option(GLFW_USE_OPTIMUS_HPG "Force use of high-performance GPU on Optimus systems" OFF) +endif() + +if (APPLE) + option(GLFW_BUILD_UNIVERSAL "Build GLFW as a Universal Binary" OFF) + option(GLFW_USE_CHDIR "Make glfwInit chdir to Contents/Resources" ON) + option(GLFW_USE_MENUBAR "Populate the menu bar on first window creation" ON) + option(GLFW_USE_RETINA "Use the full resolution of Retina displays" ON) +else() + option(GLFW_USE_EGL "Use EGL for context creation" OFF) +endif() + +if (UNIX AND NOT APPLE) + option(GLFW_USE_WAYLAND "Use Wayland for context creation (implies EGL as well)" OFF) + option(GLFW_USE_MIR "Use Mir for context creation (implies EGL as well)" OFF) +endif() + +if (MSVC) + option(USE_MSVC_RUNTIME_LIBRARY_DLL "Use MSVC runtime library DLL" ON) +endif() + +if (BUILD_SHARED_LIBS) + set(_GLFW_BUILD_DLL 1) +endif() + +if (GLFW_USE_WAYLAND) + set(GLFW_USE_EGL ON) +elseif (GLFW_USE_MIR) + set(GLFW_USE_EGL ON) +endif() + +if (GLFW_USE_EGL) + set(GLFW_CLIENT_LIBRARY "opengl" CACHE STRING + "The client library to use; one of opengl, glesv1 or glesv2") + + if (${GLFW_CLIENT_LIBRARY} STREQUAL "opengl") + set(_GLFW_USE_OPENGL 1) + elseif (${GLFW_CLIENT_LIBRARY} STREQUAL "glesv1") + set(_GLFW_USE_GLESV1 1) + elseif (${GLFW_CLIENT_LIBRARY} STREQUAL "glesv2") + set(_GLFW_USE_GLESV2 1) + else() + message(FATAL_ERROR "Unsupported client library") + endif() + + set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/CMake/modules") + find_package(EGL REQUIRED) + + if (NOT _GLFW_USE_OPENGL) + set(GLFW_BUILD_EXAMPLES OFF) + set(GLFW_BUILD_TESTS OFF) + message(STATUS "NOTE: Examples and tests require OpenGL") + endif() +else() + set(_GLFW_USE_OPENGL 1) +endif() + +if (_GLFW_USE_OPENGL) + find_package(OpenGL REQUIRED) +elseif (_GLFW_USE_GLESV1) + find_package(GLESv1 REQUIRED) +elseif (_GLFW_USE_GLESV2) + find_package(GLESv2 REQUIRED) +endif() + +find_package(Threads REQUIRED) + +if (GLFW_BUILD_DOCS) + set(DOXYGEN_SKIP_DOT TRUE) + find_package(Doxygen) + + if (GLFW_DOCUMENT_INTERNALS) + set(GLFW_INTERNAL_DOCS "${GLFW_SOURCE_DIR}/src/internal.h ${GLFW_SOURCE_DIR}/docs/internal.dox") + endif() +endif() + +#-------------------------------------------------------------------- +# Set compiler specific flags +#-------------------------------------------------------------------- +if (UNIX) + add_definitions(-Wall) + + if (BUILD_SHARED_LIBS) + add_definitions(-fvisibility=hidden) + endif() +endif() + +if (MSVC) + add_definitions(-D_CRT_SECURE_NO_WARNINGS) + + if (NOT USE_MSVC_RUNTIME_LIBRARY_DLL) + foreach (flag CMAKE_C_FLAGS + CMAKE_C_FLAGS_DEBUG + CMAKE_C_FLAGS_RELEASE + CMAKE_C_FLAGS_MINSIZEREL + CMAKE_C_FLAGS_RELWITHDEBINFO) + + if (${flag} MATCHES "/MD") + string(REGEX REPLACE "/MD" "/MT" ${flag} "${${flag}}") + endif() + if (${flag} MATCHES "/MDd") + string(REGEX REPLACE "/MDd" "/MTd" ${flag} "${${flag}}") + endif() + + endforeach() + endif() +endif() + +if (MINGW) + # Enable link-time exploit mitigation features enabled by default on MSVC + + include(CheckCCompilerFlag) + + # Compatibility with data execution prevention (DEP) + set(CMAKE_REQUIRED_FLAGS "-Wl,--nxcompat") + check_c_compiler_flag("" _GLFW_HAS_DEP) + if (_GLFW_HAS_DEP) + set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--nxcompat ${CMAKE_SHARED_LINKER_FLAGS}") + endif() + + # Compatibility with address space layout randomization (ASLR) + set(CMAKE_REQUIRED_FLAGS "-Wl,--dynamicbase") + check_c_compiler_flag("" _GLFW_HAS_ASLR) + if (_GLFW_HAS_ASLR) + set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--dynamicbase ${CMAKE_SHARED_LINKER_FLAGS}") + endif() + + # Compatibility with 64-bit address space layout randomization (ASLR) + set(CMAKE_REQUIRED_FLAGS "-Wl,--high-entropy-va") + check_c_compiler_flag("" _GLFW_HAS_64ASLR) + if (_GLFW_HAS_64ASLR) + set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--high-entropy-va ${CMAKE_SHARED_LINKER_FLAGS}") + endif() +endif() + +#-------------------------------------------------------------------- +# Detect and select backend APIs +#-------------------------------------------------------------------- +if (WIN32) + set(_GLFW_WIN32 1) + message(STATUS "Using Win32 for window creation") + + if (GLFW_USE_EGL) + set(_GLFW_EGL 1) + message(STATUS "Using EGL for context creation") + else() + set(_GLFW_WGL 1) + message(STATUS "Using WGL for context creation") + endif() +elseif (APPLE) + set(_GLFW_COCOA 1) + message(STATUS "Using Cocoa for window creation") + set(_GLFW_NSGL 1) + message(STATUS "Using NSGL for context creation") +elseif (UNIX) + if (GLFW_USE_WAYLAND) + set(_GLFW_WAYLAND 1) + message(STATUS "Using Wayland for window creation") + elseif (GLFW_USE_MIR) + set(_GLFW_MIR 1) + message(STATUS "Using Mir for window creation") + else() + set(_GLFW_X11 1) + message(STATUS "Using X11 for window creation") + endif() + + if (GLFW_USE_EGL) + set(_GLFW_EGL 1) + message(STATUS "Using EGL for context creation") + else() + set(_GLFW_GLX 1) + message(STATUS "Using GLX for context creation") + endif() +else() + message(FATAL_ERROR "No supported platform was detected") +endif() + +#-------------------------------------------------------------------- +# Use Win32 for window creation +#-------------------------------------------------------------------- +if (_GLFW_WIN32) + + list(APPEND glfw_PKG_LIBS "-lgdi32") + + if (GLFW_USE_DWM_SWAP_INTERVAL) + set(_GLFW_USE_DWM_SWAP_INTERVAL 1) + endif() + if (GLFW_USE_OPTIMUS_HPG) + set(_GLFW_USE_OPTIMUS_HPG 1) + endif() + + # HACK: When building on MinGW, WINVER and UNICODE need to be defined before + # the inclusion of stddef.h (by glfw3.h), which is itself included before + # win32_platform.h. We define them here until a saner solution can be found + # NOTE: MinGW-w64 and Visual C++ do /not/ need this hack. + if (${CMAKE_C_COMPILER_ID} STREQUAL "GNU") + add_definitions(-DUNICODE -DWINVER=0x0501) + endif() +endif() + +#-------------------------------------------------------------------- +# Use WGL for context creation +#-------------------------------------------------------------------- +if (_GLFW_WGL) + + list(APPEND glfw_PKG_LIBS "-lopengl32") + + list(APPEND glfw_INCLUDE_DIRS "${OPENGL_INCLUDE_DIR}") + list(APPEND glfw_LIBRARIES "${OPENGL_gl_LIBRARY}") +endif() + +#-------------------------------------------------------------------- +# Use X11 for window creation +#-------------------------------------------------------------------- +if (_GLFW_X11) + + find_package(X11 REQUIRED) + + list(APPEND glfw_PKG_DEPS "x11") + + # Set up library and include paths + list(APPEND glfw_INCLUDE_DIRS "${X11_X11_INCLUDE_PATH}") + list(APPEND glfw_LIBRARIES "${X11_X11_LIB}" "${CMAKE_THREAD_LIBS_INIT}") + if (UNIX AND NOT APPLE) + list(APPEND glfw_LIBRARIES "${RT_LIBRARY}") + endif() + + # Check for XRandR (modern resolution switching and gamma control) + if (NOT X11_Xrandr_FOUND) + message(FATAL_ERROR "The RandR library and headers were not found") + endif() + + list(APPEND glfw_INCLUDE_DIRS "${X11_Xrandr_INCLUDE_PATH}") + list(APPEND glfw_LIBRARIES "${X11_Xrandr_LIB}") + list(APPEND glfw_PKG_DEPS "xrandr") + + # Check for Xinerama (legacy multi-monitor support) + if (NOT X11_Xinerama_FOUND) + message(FATAL_ERROR "The Xinerama library and headers were not found") + endif() + + list(APPEND glfw_INCLUDE_DIRS "${X11_Xinerama_INCLUDE_PATH}") + list(APPEND glfw_LIBRARIES "${X11_Xinerama_LIB}") + list(APPEND glfw_PKG_DEPS "xinerama") + + # Check for XInput (high-resolution cursor motion) + if (NOT X11_Xinput_FOUND) + message(FATAL_ERROR "The XInput library and headers were not found") + endif() + + list(APPEND glfw_INCLUDE_DIRS "${X11_Xinput_INCLUDE_PATH}") + + if (X11_Xinput_LIB) + list(APPEND glfw_LIBRARIES "${X11_Xinput_LIB}") + else() + # Backwards compatibility (bug in CMake 2.8.7) + list(APPEND glfw_LIBRARIES Xi) + endif() + list(APPEND glfw_PKG_DEPS "xi") + + # Check for Xf86VidMode (fallback gamma control) + if (NOT X11_xf86vmode_FOUND) + message(FATAL_ERROR "The Xf86VidMode library and headers were not found") + endif() + + list(APPEND glfw_INCLUDE_DIRS "${X11_xf86vmode_INCLUDE_PATH}") + list(APPEND glfw_PKG_DEPS "xxf86vm") + + if (X11_Xxf86vm_LIB) + list(APPEND glfw_LIBRARIES "${X11_Xxf86vm_LIB}") + else() + # Backwards compatibility (see CMake bug 0006976) + list(APPEND glfw_LIBRARIES Xxf86vm) + endif() + + # Check for Xkb (X keyboard extension) + if (NOT X11_Xkb_FOUND) + message(FATAL_ERROR "The X keyboard extension headers were not found") + endif() + + list(APPEND glfw_INCLUDE_DIR "${X11_Xkb_INCLUDE_PATH}") + + find_library(RT_LIBRARY rt) + mark_as_advanced(RT_LIBRARY) + if (RT_LIBRARY) + list(APPEND glfw_LIBRARIES "${RT_LIBRARY}") + list(APPEND glfw_PKG_LIBS "-lrt") + endif() + + find_library(MATH_LIBRARY m) + mark_as_advanced(MATH_LIBRARY) + if (MATH_LIBRARY) + list(APPEND glfw_LIBRARIES "${MATH_LIBRARY}") + list(APPEND glfw_PKG_LIBS "-lm") + endif() + + # Check for Xcursor + if (NOT X11_Xcursor_FOUND) + message(FATAL_ERROR "The Xcursor libraries and headers were not found") + endif() + + list(APPEND glfw_INCLUDE_DIR "${X11_Xcursor_INCLUDE_PATH}") + list(APPEND glfw_LIBRARIES "${X11_Xcursor_LIB}") + list(APPEND glfw_PKG_DEPS "xcursor") + +endif() + +#-------------------------------------------------------------------- +# Use Wayland for window creation +#-------------------------------------------------------------------- +if (_GLFW_WAYLAND) + find_package(Wayland REQUIRED) + list(APPEND glfw_PKG_DEPS "wayland-egl") + + list(APPEND glfw_INCLUDE_DIRS "${WAYLAND_INCLUDE_DIR}") + list(APPEND glfw_LIBRARIES "${WAYLAND_LIBRARIES}" "${CMAKE_THREAD_LIBS_INIT}") + + find_package(XKBCommon REQUIRED) + list(APPEND glfw_PKG_DEPS "xkbcommon") + list(APPEND glfw_INCLUDE_DIRS "${XKBCOMMON_INCLUDE_DIRS}") + list(APPEND glfw_LIBRARIES "${XKBCOMMON_LIBRARY}") + + find_library(MATH_LIBRARY m) + mark_as_advanced(MATH_LIBRARY) + if (MATH_LIBRARY) + list(APPEND glfw_LIBRARIES "${MATH_LIBRARY}") + list(APPEND glfw_PKG_LIBS "-lm") + endif() +endif() + +#-------------------------------------------------------------------- +# Use Mir for window creation +#-------------------------------------------------------------------- +if (_GLFW_MIR) + find_package(Mir REQUIRED) + list(APPEND glfw_PKG_DEPS "mirclient") + + list(APPEND glfw_INCLUDE_DIRS "${MIR_INCLUDE_DIR}") + list(APPEND glfw_LIBRARIES "${MIR_LIBRARIES}" "${CMAKE_THREAD_LIBS_INIT}") + + find_package(XKBCommon REQUIRED) + list(APPEND glfw_PKG_DEPS "xkbcommon") + list(APPEND glfw_INCLUDE_DIRS "${XKBCOMMON_INCLUDE_DIRS}") + list(APPEND glfw_LIBRARIES "${XKBCOMMON_LIBRARY}") + + find_library(MATH_LIBRARY m) + mark_as_advanced(MATH_LIBRARY) + if (MATH_LIBRARY) + list(APPEND glfw_LIBRARIES "${MATH_LIBRARY}") + list(APPEND glfw_PKG_LIBS "-lm") + endif() +endif() + +#-------------------------------------------------------------------- +# Use GLX for context creation +#-------------------------------------------------------------------- +if (_GLFW_GLX) + + list(APPEND glfw_INCLUDE_DIRS "${OPENGL_INCLUDE_DIR}") + list(APPEND glfw_LIBRARIES "${OPENGL_gl_LIBRARY}") + + list(APPEND glfw_PKG_DEPS "gl") + + include(CheckFunctionExists) + + set(CMAKE_REQUIRED_LIBRARIES "${OPENGL_gl_LIBRARY}") + check_function_exists(glXGetProcAddress _GLFW_HAS_GLXGETPROCADDRESS) + check_function_exists(glXGetProcAddressARB _GLFW_HAS_GLXGETPROCADDRESSARB) + check_function_exists(glXGetProcAddressEXT _GLFW_HAS_GLXGETPROCADDRESSEXT) + + if (NOT _GLFW_HAS_GLXGETPROCADDRESS AND + NOT _GLFW_HAS_GLXGETPROCADDRESSARB AND + NOT _GLFW_HAS_GLXGETPROCADDRESSEXT) + message(WARNING "No glXGetProcAddressXXX variant found") + + # Check for dlopen support as a fallback + + set(CMAKE_REQUIRED_LIBRARIES "${CMAKE_DL_LIBS}") + check_function_exists(dlopen _GLFW_HAS_DLOPEN) + if (NOT _GLFW_HAS_DLOPEN) + message(FATAL_ERROR "No entry point retrieval mechanism found") + endif() + + if (CMAKE_DL_LIBS) + list(APPEND glfw_LIBRARIES "${CMAKE_DL_LIBS}") + list(APPEND glfw_PKG_LIBS "-l${CMAKE_DL_LIBS}") + endif() + endif() + +endif() + +#-------------------------------------------------------------------- +# Use EGL for context creation +#-------------------------------------------------------------------- +if (_GLFW_EGL) + + list(APPEND glfw_INCLUDE_DIRS "${EGL_INCLUDE_DIR}") + list(APPEND glfw_LIBRARIES "${EGL_LIBRARY}") + + list(APPEND glfw_PKG_DEPS "egl") + + if (_GLFW_USE_OPENGL) + list(APPEND glfw_LIBRARIES "${OPENGL_gl_LIBRARY}") + list(APPEND glfw_INCLUDE_DIRS "${OPENGL_INCLUDE_DIR}") + list(APPEND glfw_PKG_DEPS "gl") + elseif (_GLFW_USE_GLESV1) + list(APPEND glfw_LIBRARIES "${GLESv1_LIBRARY}") + list(APPEND glfw_INCLUDE_DIRS "${GLESv1_INCLUDE_DIR}") + list(APPEND glfw_PKG_DEPS "glesv1_cm") + elseif (_GLFW_USE_GLESV2) + list(APPEND glfw_LIBRARIES "${GLESv2_LIBRARY}") + list(APPEND glfw_INCLUDE_DIRS "${GLESv2_INCLUDE_DIR}") + list(APPEND glfw_PKG_DEPS "glesv2") + endif() + +endif() + +#-------------------------------------------------------------------- +# Use Cocoa for window creation and NSOpenGL for context creation +#-------------------------------------------------------------------- +if (_GLFW_COCOA AND _GLFW_NSGL) + + if (GLFW_USE_MENUBAR) + set(_GLFW_USE_MENUBAR 1) + endif() + + if (GLFW_USE_CHDIR) + set(_GLFW_USE_CHDIR 1) + endif() + + if (GLFW_USE_RETINA) + set(_GLFW_USE_RETINA 1) + endif() + + if (GLFW_BUILD_UNIVERSAL) + message(STATUS "Building GLFW as Universal Binaries") + set(CMAKE_OSX_ARCHITECTURES i386;x86_64) + else() + message(STATUS "Building GLFW only for the native architecture") + endif() + + # Set up library and include paths + find_library(COCOA_FRAMEWORK Cocoa) + find_library(IOKIT_FRAMEWORK IOKit) + find_library(CORE_FOUNDATION_FRAMEWORK CoreFoundation) + find_library(CORE_VIDEO_FRAMEWORK CoreVideo) + mark_as_advanced(COCOA_FRAMEWORK + IOKIT_FRAMEWORK + CORE_FOUNDATION_FRAMEWORK + CORE_VIDEO_FRAMEWORK) + list(APPEND glfw_LIBRARIES "${COCOA_FRAMEWORK}" + "${OPENGL_gl_LIBRARY}" + "${IOKIT_FRAMEWORK}" + "${CORE_FOUNDATION_FRAMEWORK}" + "${CORE_VIDEO_FRAMEWORK}") + + set(glfw_PKG_DEPS "") + set(glfw_PKG_LIBS "-framework Cocoa -framework OpenGL -framework IOKit -framework CoreFoundation -framework CoreVideo") +endif() + +#-------------------------------------------------------------------- +# Export GLFW library dependencies +#-------------------------------------------------------------------- +set(GLFW_LIBRARIES ${glfw_LIBRARIES} CACHE STRING "Dependencies of GLFW") +foreach(arg ${glfw_PKG_DEPS}) + set(GLFW_PKG_DEPS "${GLFW_PKG_DEPS} ${arg}") +endforeach() +foreach(arg ${glfw_PKG_LIBS}) + set(GLFW_PKG_LIBS "${GLFW_PKG_LIBS} ${arg}") +endforeach() + +#-------------------------------------------------------------------- +# Choose library output name +#-------------------------------------------------------------------- +if (BUILD_SHARED_LIBS AND UNIX) + # On Unix-like systems, shared libraries can use the soname system. + set(GLFW_LIB_NAME glfw) +else() + set(GLFW_LIB_NAME glfw3) +endif() + +#-------------------------------------------------------------------- +# Create generated files +#-------------------------------------------------------------------- +include(CMakePackageConfigHelpers) + +if (UNIX) + set(GLFW_CONFIG_PATH "${CMAKE_INSTALL_PREFIX}/lib/cmake/glfw3/") +else() + set(GLFW_CONFIG_PATH "${CMAKE_INSTALL_PREFIX}/") +endif() + +configure_package_config_file("${GLFW_SOURCE_DIR}/src/glfw3Config.cmake.in" + "${GLFW_BINARY_DIR}/src/glfw3Config.cmake" + INSTALL_DESTINATION "${GLFW_CONFIG_PATH}" + PATH_VARS CMAKE_INSTALL_PREFIX + NO_CHECK_REQUIRED_COMPONENTS_MACRO) + +write_basic_package_version_file("${GLFW_BINARY_DIR}/src/glfw3ConfigVersion.cmake" + VERSION ${GLFW_VERSION_FULL} + COMPATIBILITY SameMajorVersion) + +if (GLFW_BUILD_DOCS) + configure_file("${GLFW_SOURCE_DIR}/docs/Doxyfile.in" + "${GLFW_BINARY_DIR}/docs/Doxyfile" @ONLY) +endif() + +configure_file("${GLFW_SOURCE_DIR}/src/glfw_config.h.in" + "${GLFW_BINARY_DIR}/src/glfw_config.h" @ONLY) + +configure_file("${GLFW_SOURCE_DIR}/src/glfw3.pc.in" + "${GLFW_BINARY_DIR}/src/glfw3.pc" @ONLY) + +#-------------------------------------------------------------------- +# Add subdirectories +#-------------------------------------------------------------------- +add_subdirectory(src) + +if (GLFW_BUILD_EXAMPLES) + add_subdirectory(examples) +endif() + +if (GLFW_BUILD_TESTS) + add_subdirectory(tests) +endif() + +if (DOXYGEN_FOUND AND GLFW_BUILD_DOCS) + add_subdirectory(docs) +endif() + +#-------------------------------------------------------------------- +# Install files other than the library +# The library is installed by src/CMakeLists.txt +#-------------------------------------------------------------------- +if (GLFW_INSTALL) + install(DIRECTORY include/GLFW DESTINATION include + FILES_MATCHING PATTERN glfw3.h PATTERN glfw3native.h) + + install(FILES "${GLFW_BINARY_DIR}/src/glfw3Config.cmake" + "${GLFW_BINARY_DIR}/src/glfw3ConfigVersion.cmake" + DESTINATION lib${LIB_SUFFIX}/cmake/glfw) + + install(EXPORT glfwTargets DESTINATION lib${LIB_SUFFIX}/cmake/glfw) + install(FILES "${GLFW_BINARY_DIR}/src/glfw3.pc" + DESTINATION lib${LIB_SUFFIX}/pkgconfig) + + # Only generate this target if no higher-level project already has + if (NOT TARGET uninstall) + configure_file("${GLFW_SOURCE_DIR}/cmake_uninstall.cmake.in" + "${GLFW_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY) + + add_custom_target(uninstall + "${CMAKE_COMMAND}" -P + "${GLFW_BINARY_DIR}/cmake_uninstall.cmake") + endif() +endif() + diff --git a/testbed/glfw/COPYING.txt b/testbed/glfw/COPYING.txt new file mode 100644 index 00000000..b30c7015 --- /dev/null +++ b/testbed/glfw/COPYING.txt @@ -0,0 +1,22 @@ +Copyright (c) 2002-2006 Marcus Geelnard +Copyright (c) 2006-2010 Camilla Berglund + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would + be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and must not + be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source + distribution. + diff --git a/testbed/glfw/README.md b/testbed/glfw/README.md new file mode 100644 index 00000000..91b3ae5e --- /dev/null +++ b/testbed/glfw/README.md @@ -0,0 +1,294 @@ +# GLFW + +## Introduction + +GLFW is a free, Open Source, multi-platform library for OpenGL and OpenGL ES +application development. It provides a simple, platform-independent API for +creating windows and contexts, reading input, handling events, etc. + +Version 3.1 adds improved documentation, support for custom system cursors, file +drop events, main thread wake-up, window frame size retrieval, floating windows, +character input with modifier keys, single buffered windows, build improvements +and fixes for a large number of bugs. + +If you are new to GLFW, you may find the +[introductory tutorial](http://www.glfw.org/docs/latest/quick.html) for GLFW +3 useful. If you have used GLFW 2 in the past, there is a +[transition guide](http://www.glfw.org/docs/latest/moving.html) for moving to +the GLFW 3 API. + +Note that a number of source files have been added or renamed in 3.1, which may +require you to update any custom build files you have. + + +## Compiling GLFW + +See the [Compiling GLFW](http://www.glfw.org/docs/latest/compile.html) guide in +the GLFW documentation. + + +## Using GLFW + +See the +[Building programs that use GLFW](http://www.glfw.org/docs/latest/build.html) +guide in the GLFW documentation. + + +## Reporting bugs + +Bugs are reported to our [issue tracker](https://github.com/glfw/glfw/issues). +Please always include the name and version of the OS where the bug occurs and +the version of GLFW used. If you have cloned it, include the commit ID used. + +If it's a build issue, please also include the build log and the name and +version of your development environment. + +If it's a context creation issue, please also include the make and model of your +graphics card and the version of your driver. + +This will help both us and other people experiencing the same bug. + + +## Dependencies + +GLFW bundles a number of dependencies in the `deps/` directory. + + - [Khronos extension headers](https://www.opengl.org/registry/) for API + extension symbols used by GLFW + - [getopt\_port](https://github.com/kimgr/getopt_port/) for examples + with command-line options + - [TinyCThread](https://github.com/tinycthread/tinycthread) for threaded + examples + - An OpenGL 3.2 core loader generated by + [glad](https://github.com/Dav1dde/glad) for examples using modern OpenGL + + +## Changelog + + - Added `GLFWcursor` custom system cursor handle + - Added `glfwCreateCursor`, `glfwCreateStandardCursor`, `glfwDestroyCursor` and + `glfwSetCursor` for managing system cursor images + - Added `GLFWimage` struct for passing 32-bit RGBA images + - Added monitor and adapter identifier access to native API + - Added `glfwSetDropCallback` and `GLFWdropfun` for receiving dropped files + - Added `glfwPostEmptyEvent` for allowing secondary threads to cause + `glfwWaitEvents` to return + - Added `empty` test program for verifying posting of empty events + - Added `glfwSetCharModsCallback` for receiving character events with modifiers + - Added `glfwGetWindowFrameSize` for retrieving the size of the frame around + the client area of a window + - Added `GLFW_AUTO_ICONIFY` for controlling whether full screen windows + automatically iconify (and restore the previous video mode) on focus loss + - Added `GLFW_DONT_CARE` for indicating that any value is acceptable + - Added `GLFW_DOUBLEBUFFER` for controlling whether to use double buffering + - Added `GLFW_CONTEXT_RELEASE_BEHAVIOR` and values + `GLFW_ANY_RELEASE_BEHAVIOR`, `GLFW_RELEASE_BEHAVIOR_FLUSH` and + `GLFW_RELEASE_BEHAVIOR_NONE` for `GL_KHR_context_flush_control` support + - Added `GLFW_INCLUDE_ES31` for including the OpenGL ES 3.1 header + - Added `GLFW_FLOATING` for creating always-on-top windowed mode windows + - Added `GLFW_FOCUSED` window hint for controlling initial input focus + - Added *partial and experimental* support for Wayland + - Added *partial and experimental* support for Mir + - Changed the window state attributes (focused, iconified and visible) to query + the system directly + - Changed the default of `GLFW_REFRESH_RATE` to `GLFW_DONT_CARE` to maintain + the default behavior + - Changed static library to build as position independent code for easier use + from the Rust language + - Changed `glfwGetCursorPos` to query the system directly for all cursor modes + except captured mode + - Bugfix: The debug context attribute was set from `GL_ARB_debug_output` even + when a debug context had not been requested + - Bugfix: The particles example was not linked against the threading library + - Bugfix: The cursor was not positioned over newly created full screen windows + - Bugfix: The queried cursor position was not always up-to-date + - Bugfix: `glfwExtensionSupported` always failed for OpenGL ES 3.0 and later if + the library was compiled for OpenGL ES + - [Cocoa] Added `_GLFW_USE_RETINA` to control whether windows will use the full + resolution on Retina displays + - [Cocoa] Made content view subclass of `NSOpenGLView` + - [Cocoa] Bugfix: Using a 1x1 cursor for hidden mode caused some screen + recorders to fail + - [Cocoa] Bugfix: Some Core Foundation objects were leaked during joystick + enumeration and termination + - [Cocoa] Bugfix: One copy of each display name string was leaked + - [Cocoa] Bugfix: Monitor enumeration caused a segfault if no `NSScreen` was + found for a given `CGDisplay` + - [Cocoa] Bugfix: Modifier key events were lost if the corresponding modifier + bit field was unchanged + - [Cocoa] Bugfix: Joystick enumeration took hundreds of ms on some systems + - [Cocoa] Bugfix: The cursor was hidden when the user resized a GLFW window + - [Cocoa] Bugfix: The 10.10 Yosemite OpenGL 4.1 profile token was not used + - [Cocoa] Bugfix: The generic software OpenGL renderer could be selected under + certain conditions + - [Cocoa] Bugfix: The virtual cursor jumped unpredictably when entering + disabled cursor mode + - [Win32] Enabled generation of pkg-config file for MinGW + - [Win32] Removed option to require explicitly linking against `winmm.dll` + - [Win32] Bugfix: Failure to load winmm or its functions was not reported to + the error callback + - [Win32] Bugfix: Some keys were reported based on the current layout instead + of their physical location + - [Win32] Bugfix: Maximized hidden windows were restored by `glfwShowWindow` + - [Win32] Bugfix: Context re-creation was not triggered by sRGB hint + - [Win32] Bugfix: Full screen windows were incorrectly sized and placed on some + systems + - [Win32] Bugfix: Gamma ramp functions acted on entire desktop instead of the + specified monitor + - [Win32] Bugfix: The wrong incorrect physical size was returned for + non-primary monitors + - [Win32] Bugfix: X-axis scroll offsets were inverted + - [Win32] Bugfix: The Optimus HPG forcing variable was not correctly exported + - [Win32] Bugfix: The iconified window state attribute was not always updated + - [Win32] Bugfix: Previously focused windows with disabled cursor mode and that + had been iconified by Win+D were not visible when restored + - [Win32] Bugfix: The virtual cursor jumped unpredictably when entering + disabled cursor mode + - [X11] Added run-time support for systems lacking the XKB extension + - [X11] Made GLX 1.3 the minimum supported version + - [X11] Replaced `XRRGetScreenResources` with `XRRGetScreenResourcesCurrent` + for monitor property retrieval + - [X11] Bugfix: The case of finding no usable CRTCs was not detected + - [X11] Bugfix: Detection of broken Nvidia RandR gamma support did not verify + that at least one CRTC was present + - [X11] Bugfix: A stale `_NET_SUPPORTING_WM_CHECK` root window property would + cause an uncaught `BadWindow` error + - [X11] Bugfix: No check was made for the presence of GLX 1.3 when + `GLX_SGIX_fbconfig` was unavailable + - [X11] Bugfix: The message type of ICCCM protocol events was not checked + - [X11] Bugfix: `glfwDestroyWindow` did not flush the output buffer + - [X11] Bugfix: Window frame interactions were reported as focus events + - [X11] Bugfix: Workaround for legacy Compiz caused flickering during resize + - [X11] Bugfix: The name pointer of joysticks were not cleared on disconnection + - [X11] Bugfix: Video mode resolutions and monitor physical sizes were not + corrected for rotated CRTCs + - [X11] Bugfix: Unicode character input ignored dead keys + - [X11] Bugfix: X-axis scroll offsets were inverted + - [X11] Bugfix: Full screen override redirect windows were not always + positioned over the specified monitor + - [X11] Bugfix: Character input did not work for the default `"C"` locale + - [X11] Bugfix: Joysticks connected after `glfwInit` were not detected + (temporary inotify solution until proper libudev solution) + + +## Contact + +The official website for GLFW is [glfw.org](http://www.glfw.org/). There you +can find the latest version of GLFW, as well as news, documentation and other +information about the project. + +If you have questions related to the use of GLFW, we have a +[support forum](https://sourceforge.net/p/glfw/discussion/247562/), and the IRC +channel `#glfw` on [Freenode](http://freenode.net/). + +If you have a bug to report, a patch to submit or a feature you'd like to +request, please file it in the +[issue tracker](https://github.com/glfw/glfw/issues) on GitHub. + +Finally, if you're interested in helping out with the development of GLFW or +porting it to your favorite platform, we have an occasionally active +[developer's mailing list](https://lists.stacken.kth.se/mailman/listinfo/glfw-dev), +or you could join us on `#glfw`. + + +## Acknowledgements + +GLFW exists because people around the world donated their time and lent their +skills. + + - Bobyshev Alexander + - artblanc + - arturo + - Matt Arsenault + - Keith Bauer + - John Bartholomew + - Niklas Behrens + - Niklas Bergström + - Doug Binks + - blanco + - Martin Capitanio + - Lambert Clara + - Andrew Corrigan + - Noel Cower + - Jarrod Davis + - Olivier Delannoy + - Paul R. Deppe + - Michael Dickens + - Jonathan Dummer + - Ralph Eastwood + - Michael Fogleman + - Gerald Franz + - GeO4d + - Marcus Geelnard + - Eloi Marín Gratacós + - Stefan Gustavson + - Sylvain Hellegouarch + - Matthew Henry + - heromyth + - Lucas Hinderberger + - Paul Holden + - Toni Jovanoski + - Arseny Kapoulkine + - Osman Keskin + - Cameron King + - Peter Knut + - Robin Leffmann + - Glenn Lewis + - Shane Liesegang + - Дмитри Малышев + - Martins Mozeiko + - Tristam MacDonald + - Hans Mackowiak + - Kyle McDonald + - David Medlock + - Jonathan Mercier + - Marcel Metz + - Kenneth Miller + - Bruce Mitchener + - Jack Moffitt + - Jeff Molofee + - Jon Morton + - Pierre Moulon + - Julian Møller + - Kamil Nowakowski + - Ozzy + - Andri Pálsson + - Peoro + - Braden Pellett + - Arturo J. Pérez + - Cyril Pichard + - Pieroman + - Jorge Rodriguez + - Ed Ropple + - Riku Salminen + - Brandon Schaefer + - Sebastian Schuberth + - Matt Sealey + - SephiRok + - Steve Sexton + - Systemcluster + - Dmitri Shuralyov + - Daniel Skorupski + - Bradley Smith + - Julian Squires + - Johannes Stein + - Justin Stoecker + - Nathan Sweet + - TTK-Bandit + - Sergey Tikhomirov + - Samuli Tuomola + - urraka + - Jari Vetoniemi + - Ricardo Vieira + - Simon Voordouw + - Torsten Walluhn + - Patrick Walton + - Jay Weisskopf + - Frank Wille + - yuriks + - Santi Zupancic + - Jonas Ådahl + - Lasse Öörni + - All the unmentioned and anonymous contributors in the GLFW community, for bug + reports, patches, feedback, testing and encouragement + diff --git a/testbed/glfw/cmake_uninstall.cmake.in b/testbed/glfw/cmake_uninstall.cmake.in new file mode 100644 index 00000000..4ea57b1c --- /dev/null +++ b/testbed/glfw/cmake_uninstall.cmake.in @@ -0,0 +1,29 @@ + +if (NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + message(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"") +endif() + +file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) +string(REGEX REPLACE "\n" ";" files "${files}") + +foreach (file ${files}) + message(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"") + if (EXISTS "$ENV{DESTDIR}${file}") + exec_program("@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" + OUTPUT_VARIABLE rm_out + RETURN_VALUE rm_retval) + if (NOT "${rm_retval}" STREQUAL 0) + MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") + endif() + elseif (IS_SYMLINK "$ENV{DESTDIR}${file}") + EXEC_PROGRAM("@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" + OUTPUT_VARIABLE rm_out + RETURN_VALUE rm_retval) + if (NOT "${rm_retval}" STREQUAL 0) + message(FATAL_ERROR "Problem when removing symlink \"$ENV{DESTDIR}${file}\"") + endif() + else() + message(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.") + endif() +endforeach() + diff --git a/testbed/glfw/deps/EGL/eglext.h b/testbed/glfw/deps/EGL/eglext.h new file mode 100644 index 00000000..bd51114b --- /dev/null +++ b/testbed/glfw/deps/EGL/eglext.h @@ -0,0 +1,565 @@ +#ifndef __eglext_h_ +#define __eglext_h_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Copyright (c) 2007-2013 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE 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 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +#include + +/*************************************************************/ + +/* Header file version number */ +/* Current version at http://www.khronos.org/registry/egl/ */ +/* $Revision: 20690 $ on $Date: 2013-02-22 17:15:05 -0800 (Fri, 22 Feb 2013) $ */ +#define EGL_EGLEXT_VERSION 15 + +#ifndef EGL_KHR_config_attribs +#define EGL_KHR_config_attribs 1 +#define EGL_CONFORMANT_KHR 0x3042 /* EGLConfig attribute */ +#define EGL_VG_COLORSPACE_LINEAR_BIT_KHR 0x0020 /* EGL_SURFACE_TYPE bitfield */ +#define EGL_VG_ALPHA_FORMAT_PRE_BIT_KHR 0x0040 /* EGL_SURFACE_TYPE bitfield */ +#endif + +#ifndef EGL_KHR_lock_surface +#define EGL_KHR_lock_surface 1 +#define EGL_READ_SURFACE_BIT_KHR 0x0001 /* EGL_LOCK_USAGE_HINT_KHR bitfield */ +#define EGL_WRITE_SURFACE_BIT_KHR 0x0002 /* EGL_LOCK_USAGE_HINT_KHR bitfield */ +#define EGL_LOCK_SURFACE_BIT_KHR 0x0080 /* EGL_SURFACE_TYPE bitfield */ +#define EGL_OPTIMAL_FORMAT_BIT_KHR 0x0100 /* EGL_SURFACE_TYPE bitfield */ +#define EGL_MATCH_FORMAT_KHR 0x3043 /* EGLConfig attribute */ +#define EGL_FORMAT_RGB_565_EXACT_KHR 0x30C0 /* EGL_MATCH_FORMAT_KHR value */ +#define EGL_FORMAT_RGB_565_KHR 0x30C1 /* EGL_MATCH_FORMAT_KHR value */ +#define EGL_FORMAT_RGBA_8888_EXACT_KHR 0x30C2 /* EGL_MATCH_FORMAT_KHR value */ +#define EGL_FORMAT_RGBA_8888_KHR 0x30C3 /* EGL_MATCH_FORMAT_KHR value */ +#define EGL_MAP_PRESERVE_PIXELS_KHR 0x30C4 /* eglLockSurfaceKHR attribute */ +#define EGL_LOCK_USAGE_HINT_KHR 0x30C5 /* eglLockSurfaceKHR attribute */ +#define EGL_BITMAP_POINTER_KHR 0x30C6 /* eglQuerySurface attribute */ +#define EGL_BITMAP_PITCH_KHR 0x30C7 /* eglQuerySurface attribute */ +#define EGL_BITMAP_ORIGIN_KHR 0x30C8 /* eglQuerySurface attribute */ +#define EGL_BITMAP_PIXEL_RED_OFFSET_KHR 0x30C9 /* eglQuerySurface attribute */ +#define EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR 0x30CA /* eglQuerySurface attribute */ +#define EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR 0x30CB /* eglQuerySurface attribute */ +#define EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR 0x30CC /* eglQuerySurface attribute */ +#define EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR 0x30CD /* eglQuerySurface attribute */ +#define EGL_LOWER_LEFT_KHR 0x30CE /* EGL_BITMAP_ORIGIN_KHR value */ +#define EGL_UPPER_LEFT_KHR 0x30CF /* EGL_BITMAP_ORIGIN_KHR value */ +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglLockSurfaceKHR (EGLDisplay display, EGLSurface surface, const EGLint *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglUnlockSurfaceKHR (EGLDisplay display, EGLSurface surface); +#endif /* EGL_EGLEXT_PROTOTYPES */ +typedef EGLBoolean (EGLAPIENTRYP PFNEGLLOCKSURFACEKHRPROC) (EGLDisplay display, EGLSurface surface, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNLOCKSURFACEKHRPROC) (EGLDisplay display, EGLSurface surface); +#endif + +#ifndef EGL_KHR_image +#define EGL_KHR_image 1 +#define EGL_NATIVE_PIXMAP_KHR 0x30B0 /* eglCreateImageKHR target */ +typedef void *EGLImageKHR; +#define EGL_NO_IMAGE_KHR ((EGLImageKHR)0) +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLImageKHR EGLAPIENTRY eglCreateImageKHR (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImageKHR (EGLDisplay dpy, EGLImageKHR image); +#endif /* EGL_EGLEXT_PROTOTYPES */ +typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEIMAGEKHRPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEKHRPROC) (EGLDisplay dpy, EGLImageKHR image); +#endif + +#ifndef EGL_KHR_vg_parent_image +#define EGL_KHR_vg_parent_image 1 +#define EGL_VG_PARENT_IMAGE_KHR 0x30BA /* eglCreateImageKHR target */ +#endif + +#ifndef EGL_KHR_gl_texture_2D_image +#define EGL_KHR_gl_texture_2D_image 1 +#define EGL_GL_TEXTURE_2D_KHR 0x30B1 /* eglCreateImageKHR target */ +#define EGL_GL_TEXTURE_LEVEL_KHR 0x30BC /* eglCreateImageKHR attribute */ +#endif + +#ifndef EGL_KHR_gl_texture_cubemap_image +#define EGL_KHR_gl_texture_cubemap_image 1 +#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR 0x30B3 /* eglCreateImageKHR target */ +#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR 0x30B4 /* eglCreateImageKHR target */ +#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR 0x30B5 /* eglCreateImageKHR target */ +#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR 0x30B6 /* eglCreateImageKHR target */ +#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR 0x30B7 /* eglCreateImageKHR target */ +#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR 0x30B8 /* eglCreateImageKHR target */ +#endif + +#ifndef EGL_KHR_gl_texture_3D_image +#define EGL_KHR_gl_texture_3D_image 1 +#define EGL_GL_TEXTURE_3D_KHR 0x30B2 /* eglCreateImageKHR target */ +#define EGL_GL_TEXTURE_ZOFFSET_KHR 0x30BD /* eglCreateImageKHR attribute */ +#endif + +#ifndef EGL_KHR_gl_renderbuffer_image +#define EGL_KHR_gl_renderbuffer_image 1 +#define EGL_GL_RENDERBUFFER_KHR 0x30B9 /* eglCreateImageKHR target */ +#endif + +#if KHRONOS_SUPPORT_INT64 /* EGLTimeKHR requires 64-bit uint support */ +#ifndef EGL_KHR_reusable_sync +#define EGL_KHR_reusable_sync 1 + +typedef void* EGLSyncKHR; +typedef khronos_utime_nanoseconds_t EGLTimeKHR; + +#define EGL_SYNC_STATUS_KHR 0x30F1 +#define EGL_SIGNALED_KHR 0x30F2 +#define EGL_UNSIGNALED_KHR 0x30F3 +#define EGL_TIMEOUT_EXPIRED_KHR 0x30F5 +#define EGL_CONDITION_SATISFIED_KHR 0x30F6 +#define EGL_SYNC_TYPE_KHR 0x30F7 +#define EGL_SYNC_REUSABLE_KHR 0x30FA +#define EGL_SYNC_FLUSH_COMMANDS_BIT_KHR 0x0001 /* eglClientWaitSyncKHR bitfield */ +#define EGL_FOREVER_KHR 0xFFFFFFFFFFFFFFFFull +#define EGL_NO_SYNC_KHR ((EGLSyncKHR)0) +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync); +EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout); +EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode); +EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value); +#endif /* EGL_EGLEXT_PROTOTYPES */ +typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESYNCKHRPROC) (EGLDisplay dpy, EGLenum type, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync); +typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value); +#endif +#endif + +#ifndef EGL_KHR_image_base +#define EGL_KHR_image_base 1 +/* Most interfaces defined by EGL_KHR_image_pixmap above */ +#define EGL_IMAGE_PRESERVED_KHR 0x30D2 /* eglCreateImageKHR attribute */ +#endif + +#ifndef EGL_KHR_image_pixmap +#define EGL_KHR_image_pixmap 1 +/* Interfaces defined by EGL_KHR_image above */ +#endif + +#ifndef EGL_IMG_context_priority +#define EGL_IMG_context_priority 1 +#define EGL_CONTEXT_PRIORITY_LEVEL_IMG 0x3100 +#define EGL_CONTEXT_PRIORITY_HIGH_IMG 0x3101 +#define EGL_CONTEXT_PRIORITY_MEDIUM_IMG 0x3102 +#define EGL_CONTEXT_PRIORITY_LOW_IMG 0x3103 +#endif + +#ifndef EGL_KHR_lock_surface2 +#define EGL_KHR_lock_surface2 1 +#define EGL_BITMAP_PIXEL_SIZE_KHR 0x3110 +#endif + +#ifndef EGL_NV_coverage_sample +#define EGL_NV_coverage_sample 1 +#define EGL_COVERAGE_BUFFERS_NV 0x30E0 +#define EGL_COVERAGE_SAMPLES_NV 0x30E1 +#endif + +#ifndef EGL_NV_depth_nonlinear +#define EGL_NV_depth_nonlinear 1 +#define EGL_DEPTH_ENCODING_NV 0x30E2 +#define EGL_DEPTH_ENCODING_NONE_NV 0 +#define EGL_DEPTH_ENCODING_NONLINEAR_NV 0x30E3 +#endif + +#if KHRONOS_SUPPORT_INT64 /* EGLTimeNV requires 64-bit uint support */ +#ifndef EGL_NV_sync +#define EGL_NV_sync 1 +#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_NV 0x30E6 +#define EGL_SYNC_STATUS_NV 0x30E7 +#define EGL_SIGNALED_NV 0x30E8 +#define EGL_UNSIGNALED_NV 0x30E9 +#define EGL_SYNC_FLUSH_COMMANDS_BIT_NV 0x0001 +#define EGL_FOREVER_NV 0xFFFFFFFFFFFFFFFFull +#define EGL_ALREADY_SIGNALED_NV 0x30EA +#define EGL_TIMEOUT_EXPIRED_NV 0x30EB +#define EGL_CONDITION_SATISFIED_NV 0x30EC +#define EGL_SYNC_TYPE_NV 0x30ED +#define EGL_SYNC_CONDITION_NV 0x30EE +#define EGL_SYNC_FENCE_NV 0x30EF +#define EGL_NO_SYNC_NV ((EGLSyncNV)0) +typedef void* EGLSyncNV; +typedef khronos_utime_nanoseconds_t EGLTimeNV; +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLSyncNV EGLAPIENTRY eglCreateFenceSyncNV (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncNV (EGLSyncNV sync); +EGLAPI EGLBoolean EGLAPIENTRY eglFenceNV (EGLSyncNV sync); +EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncNV (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout); +EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncNV (EGLSyncNV sync, EGLenum mode); +EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribNV (EGLSyncNV sync, EGLint attribute, EGLint *value); +#endif /* EGL_EGLEXT_PROTOTYPES */ +typedef EGLSyncNV (EGLAPIENTRYP PFNEGLCREATEFENCESYNCNVPROC) (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCNVPROC) (EGLSyncNV sync); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLFENCENVPROC) (EGLSyncNV sync); +typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCNVPROC) (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCNVPROC) (EGLSyncNV sync, EGLenum mode); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBNVPROC) (EGLSyncNV sync, EGLint attribute, EGLint *value); +#endif +#endif + +#if KHRONOS_SUPPORT_INT64 /* Dependent on EGL_KHR_reusable_sync which requires 64-bit uint support */ +#ifndef EGL_KHR_fence_sync +#define EGL_KHR_fence_sync 1 +/* Reuses most tokens and entry points from EGL_KHR_reusable_sync */ +#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR 0x30F0 +#define EGL_SYNC_CONDITION_KHR 0x30F8 +#define EGL_SYNC_FENCE_KHR 0x30F9 +#endif +#endif + +#ifndef EGL_HI_clientpixmap +#define EGL_HI_clientpixmap 1 + +/* Surface Attribute */ +#define EGL_CLIENT_PIXMAP_POINTER_HI 0x8F74 +/* + * Structure representing a client pixmap + * (pixmap's data is in client-space memory). + */ +struct EGLClientPixmapHI +{ + void* pData; + EGLint iWidth; + EGLint iHeight; + EGLint iStride; +}; +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurfaceHI(EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI* pixmap); +#endif /* EGL_EGLEXT_PROTOTYPES */ +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPIXMAPSURFACEHIPROC) (EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI* pixmap); +#endif /* EGL_HI_clientpixmap */ + +#ifndef EGL_HI_colorformats +#define EGL_HI_colorformats 1 +/* Config Attribute */ +#define EGL_COLOR_FORMAT_HI 0x8F70 +/* Color Formats */ +#define EGL_COLOR_RGB_HI 0x8F71 +#define EGL_COLOR_RGBA_HI 0x8F72 +#define EGL_COLOR_ARGB_HI 0x8F73 +#endif /* EGL_HI_colorformats */ + +#ifndef EGL_MESA_drm_image +#define EGL_MESA_drm_image 1 +#define EGL_DRM_BUFFER_FORMAT_MESA 0x31D0 /* CreateDRMImageMESA attribute */ +#define EGL_DRM_BUFFER_USE_MESA 0x31D1 /* CreateDRMImageMESA attribute */ +#define EGL_DRM_BUFFER_FORMAT_ARGB32_MESA 0x31D2 /* EGL_IMAGE_FORMAT_MESA attribute value */ +#define EGL_DRM_BUFFER_MESA 0x31D3 /* eglCreateImageKHR target */ +#define EGL_DRM_BUFFER_STRIDE_MESA 0x31D4 +#define EGL_DRM_BUFFER_USE_SCANOUT_MESA 0x00000001 /* EGL_DRM_BUFFER_USE_MESA bits */ +#define EGL_DRM_BUFFER_USE_SHARE_MESA 0x00000002 /* EGL_DRM_BUFFER_USE_MESA bits */ +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLImageKHR EGLAPIENTRY eglCreateDRMImageMESA (EGLDisplay dpy, const EGLint *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglExportDRMImageMESA (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride); +#endif /* EGL_EGLEXT_PROTOTYPES */ +typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEDRMIMAGEMESAPROC) (EGLDisplay dpy, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDRMIMAGEMESAPROC) (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride); +#endif + +#ifndef EGL_NV_post_sub_buffer +#define EGL_NV_post_sub_buffer 1 +#define EGL_POST_SUB_BUFFER_SUPPORTED_NV 0x30BE +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglPostSubBufferNV (EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height); +#endif /* EGL_EGLEXT_PROTOTYPES */ +typedef EGLBoolean (EGLAPIENTRYP PFNEGLPOSTSUBBUFFERNVPROC) (EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height); +#endif + +#ifndef EGL_ANGLE_query_surface_pointer +#define EGL_ANGLE_query_surface_pointer 1 +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value); +#endif +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACEPOINTERANGLEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value); +#endif + +#ifndef EGL_ANGLE_surface_d3d_texture_2d_share_handle +#define EGL_ANGLE_surface_d3d_texture_2d_share_handle 1 +#define EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE 0x3200 +#endif + +#ifndef EGL_NV_coverage_sample_resolve +#define EGL_NV_coverage_sample_resolve 1 +#define EGL_COVERAGE_SAMPLE_RESOLVE_NV 0x3131 +#define EGL_COVERAGE_SAMPLE_RESOLVE_DEFAULT_NV 0x3132 +#define EGL_COVERAGE_SAMPLE_RESOLVE_NONE_NV 0x3133 +#endif + +#if KHRONOS_SUPPORT_INT64 /* EGLuint64NV requires 64-bit uint support */ +#ifndef EGL_NV_system_time +#define EGL_NV_system_time 1 +typedef khronos_utime_nanoseconds_t EGLuint64NV; +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeFrequencyNV(void); +EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeNV(void); +#endif /* EGL_EGLEXT_PROTOTYPES */ +typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC) (void); +typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMENVPROC) (void); +#endif +#endif + +#if KHRONOS_SUPPORT_INT64 /* EGLuint64KHR requires 64-bit uint support */ +#ifndef EGL_KHR_stream +#define EGL_KHR_stream 1 +typedef void* EGLStreamKHR; +typedef khronos_uint64_t EGLuint64KHR; +#define EGL_NO_STREAM_KHR ((EGLStreamKHR)0) +#define EGL_CONSUMER_LATENCY_USEC_KHR 0x3210 +#define EGL_PRODUCER_FRAME_KHR 0x3212 +#define EGL_CONSUMER_FRAME_KHR 0x3213 +#define EGL_STREAM_STATE_KHR 0x3214 +#define EGL_STREAM_STATE_CREATED_KHR 0x3215 +#define EGL_STREAM_STATE_CONNECTING_KHR 0x3216 +#define EGL_STREAM_STATE_EMPTY_KHR 0x3217 +#define EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR 0x3218 +#define EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR 0x3219 +#define EGL_STREAM_STATE_DISCONNECTED_KHR 0x321A +#define EGL_BAD_STREAM_KHR 0x321B +#define EGL_BAD_STATE_KHR 0x321C +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLStreamKHR EGLAPIENTRY eglCreateStreamKHR(EGLDisplay dpy, const EGLint *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglDestroyStreamKHR(EGLDisplay dpy, EGLStreamKHR stream); +EGLAPI EGLBoolean EGLAPIENTRY eglStreamAttribKHR(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint value); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamKHR(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint *value); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamu64KHR(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLuint64KHR *value); +#endif /* EGL_EGLEXT_PROTOTYPES */ +typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMKHRPROC)(EGLDisplay dpy, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSTREAMKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMATTRIBKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint *value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMU64KHRPROC)(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLuint64KHR *value); +#endif +#endif + +#ifdef EGL_KHR_stream /* Requires KHR_stream extension */ +#ifndef EGL_KHR_stream_consumer_gltexture +#define EGL_KHR_stream_consumer_gltexture 1 +#define EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR 0x321E +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalKHR(EGLDisplay dpy, EGLStreamKHR stream); +EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerAcquireKHR(EGLDisplay dpy, EGLStreamKHR stream); +EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerReleaseKHR(EGLDisplay dpy, EGLStreamKHR stream); +#endif /* EGL_EGLEXT_PROTOTYPES */ +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERACQUIREKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERRELEASEKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream); +#endif +#endif + +#ifdef EGL_KHR_stream /* Requires KHR_stream extension */ +#ifndef EGL_KHR_stream_producer_eglsurface +#define EGL_KHR_stream_producer_eglsurface 1 +#define EGL_STREAM_BIT_KHR 0x0800 +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLSurface EGLAPIENTRY eglCreateStreamProducerSurfaceKHR(EGLDisplay dpy, EGLConfig config, EGLStreamKHR stream, const EGLint *attrib_list); +#endif /* EGL_EGLEXT_PROTOTYPES */ +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC)(EGLDisplay dpy, EGLConfig config, EGLStreamKHR stream, const EGLint *attrib_list); +#endif +#endif + +#ifdef EGL_KHR_stream /* Requires KHR_stream extension */ +#ifndef EGL_KHR_stream_producer_aldatalocator +#define EGL_KHR_stream_producer_aldatalocator 1 +#endif +#endif + +#ifdef EGL_KHR_stream /* Requires KHR_stream extension */ +#ifndef EGL_KHR_stream_fifo +#define EGL_KHR_stream_fifo 1 +/* reuse EGLTimeKHR */ +#define EGL_STREAM_FIFO_LENGTH_KHR 0x31FC +#define EGL_STREAM_TIME_NOW_KHR 0x31FD +#define EGL_STREAM_TIME_CONSUMER_KHR 0x31FE +#define EGL_STREAM_TIME_PRODUCER_KHR 0x31FF +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamTimeKHR(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLTimeKHR *value); +#endif /* EGL_EGLEXT_PROTOTYPES */ +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMTIMEKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLTimeKHR *value); +#endif +#endif + +#ifndef EGL_EXT_create_context_robustness +#define EGL_EXT_create_context_robustness 1 +#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT 0x30BF +#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT 0x3138 +#define EGL_NO_RESET_NOTIFICATION_EXT 0x31BE +#define EGL_LOSE_CONTEXT_ON_RESET_EXT 0x31BF +#endif + +#ifndef EGL_ANGLE_d3d_share_handle_client_buffer +#define EGL_ANGLE_d3d_share_handle_client_buffer 1 +/* reuse EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE */ +#endif + +#ifndef EGL_KHR_create_context +#define EGL_KHR_create_context 1 +#define EGL_CONTEXT_MAJOR_VERSION_KHR EGL_CONTEXT_CLIENT_VERSION +#define EGL_CONTEXT_MINOR_VERSION_KHR 0x30FB +#define EGL_CONTEXT_FLAGS_KHR 0x30FC +#define EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR 0x30FD +#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR 0x31BD +#define EGL_NO_RESET_NOTIFICATION_KHR 0x31BE +#define EGL_LOSE_CONTEXT_ON_RESET_KHR 0x31BF +#define EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR 0x00000001 +#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002 +#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR 0x00000004 +#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001 +#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002 +#define EGL_OPENGL_ES3_BIT_KHR 0x00000040 +#endif + +#ifndef EGL_KHR_surfaceless_context +#define EGL_KHR_surfaceless_context 1 +/* No tokens/entry points, just relaxes an error condition */ +#endif + +#ifdef EGL_KHR_stream /* Requires KHR_stream extension */ +#ifndef EGL_KHR_stream_cross_process_fd +#define EGL_KHR_stream_cross_process_fd 1 +typedef int EGLNativeFileDescriptorKHR; +#define EGL_NO_FILE_DESCRIPTOR_KHR ((EGLNativeFileDescriptorKHR)(-1)) +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLNativeFileDescriptorKHR EGLAPIENTRY eglGetStreamFileDescriptorKHR(EGLDisplay dpy, EGLStreamKHR stream); +EGLAPI EGLStreamKHR EGLAPIENTRY eglCreateStreamFromFileDescriptorKHR(EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor); +#endif /* EGL_EGLEXT_PROTOTYPES */ +typedef EGLNativeFileDescriptorKHR (EGLAPIENTRYP PFNEGLGETSTREAMFILEDESCRIPTORKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream); +typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMFROMFILEDESCRIPTORKHRPROC)(EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor); +#endif +#endif + +#ifndef EGL_EXT_multiview_window +#define EGL_EXT_multiview_window 1 +#define EGL_MULTIVIEW_VIEW_COUNT_EXT 0x3134 +#endif + +#ifndef EGL_KHR_wait_sync +#define EGL_KHR_wait_sync 1 +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLint EGLAPIENTRY eglWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags); +#endif /* EGL_EGLEXT_PROTOTYPES */ +typedef EGLint (EGLAPIENTRYP PFNEGLWAITSYNCKHRPROC)(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags); +#endif + +#ifndef EGL_NV_post_convert_rounding +#define EGL_NV_post_convert_rounding 1 +/* No tokens or entry points, just relaxes behavior of SwapBuffers */ +#endif + +#ifndef EGL_NV_native_query +#define EGL_NV_native_query 1 +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQueryNativeDisplayNV( EGLDisplay dpy, EGLNativeDisplayType* display_id); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryNativeWindowNV( EGLDisplay dpy, EGLSurface surf, EGLNativeWindowType* window); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryNativePixmapNV( EGLDisplay dpy, EGLSurface surf, EGLNativePixmapType* pixmap); +#endif /* EGL_EGLEXT_PROTOTYPES */ +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEDISPLAYNVPROC)(EGLDisplay dpy, EGLNativeDisplayType *display_id); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEWINDOWNVPROC)(EGLDisplay dpy, EGLSurface surf, EGLNativeWindowType *window); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEPIXMAPNVPROC)(EGLDisplay dpy, EGLSurface surf, EGLNativePixmapType *pixmap); +#endif + +#ifndef EGL_NV_3dvision_surface +#define EGL_NV_3dvision_surface 1 +#define EGL_AUTO_STEREO_NV 0x3136 +#endif + +#ifndef EGL_ANDROID_framebuffer_target +#define EGL_ANDROID_framebuffer_target 1 +#define EGL_FRAMEBUFFER_TARGET_ANDROID 0x3147 +#endif + +#ifndef EGL_ANDROID_blob_cache +#define EGL_ANDROID_blob_cache 1 +typedef khronos_ssize_t EGLsizeiANDROID; +typedef void (*EGLSetBlobFuncANDROID) (const void *key, EGLsizeiANDROID keySize, const void *value, EGLsizeiANDROID valueSize); +typedef EGLsizeiANDROID (*EGLGetBlobFuncANDROID) (const void *key, EGLsizeiANDROID keySize, void *value, EGLsizeiANDROID valueSize); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI void EGLAPIENTRY eglSetBlobCacheFuncsANDROID(EGLDisplay dpy, EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get); +#endif /* EGL_EGLEXT_PROTOTYPES */ +typedef void (EGLAPIENTRYP PFNEGLSETBLOBCACHEFUNCSANDROIDPROC)(EGLDisplay dpy, EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get); +#endif + +#ifndef EGL_ANDROID_image_native_buffer +#define EGL_ANDROID_image_native_buffer 1 +#define EGL_NATIVE_BUFFER_ANDROID 0x3140 +#endif + +#ifndef EGL_ANDROID_native_fence_sync +#define EGL_ANDROID_native_fence_sync 1 +#define EGL_SYNC_NATIVE_FENCE_ANDROID 0x3144 +#define EGL_SYNC_NATIVE_FENCE_FD_ANDROID 0x3145 +#define EGL_SYNC_NATIVE_FENCE_SIGNALED_ANDROID 0x3146 +#define EGL_NO_NATIVE_FENCE_FD_ANDROID -1 +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLint EGLAPIENTRY eglDupNativeFenceFDANDROID( EGLDisplay dpy, EGLSyncKHR); +#endif /* EGL_EGLEXT_PROTOTYPES */ +typedef EGLint (EGLAPIENTRYP PFNEGLDUPNATIVEFENCEFDANDROIDPROC)(EGLDisplay dpy, EGLSyncKHR); +#endif + +#ifndef EGL_ANDROID_recordable +#define EGL_ANDROID_recordable 1 +#define EGL_RECORDABLE_ANDROID 0x3142 +#endif + +#ifndef EGL_EXT_buffer_age +#define EGL_EXT_buffer_age 1 +#define EGL_BUFFER_AGE_EXT 0x313D +#endif + +#ifndef EGL_EXT_image_dma_buf_import +#define EGL_EXT_image_dma_buf_import 1 +#define EGL_LINUX_DMA_BUF_EXT 0x3270 +#define EGL_LINUX_DRM_FOURCC_EXT 0x3271 +#define EGL_DMA_BUF_PLANE0_FD_EXT 0x3272 +#define EGL_DMA_BUF_PLANE0_OFFSET_EXT 0x3273 +#define EGL_DMA_BUF_PLANE0_PITCH_EXT 0x3274 +#define EGL_DMA_BUF_PLANE1_FD_EXT 0x3275 +#define EGL_DMA_BUF_PLANE1_OFFSET_EXT 0x3276 +#define EGL_DMA_BUF_PLANE1_PITCH_EXT 0x3277 +#define EGL_DMA_BUF_PLANE2_FD_EXT 0x3278 +#define EGL_DMA_BUF_PLANE2_OFFSET_EXT 0x3279 +#define EGL_DMA_BUF_PLANE2_PITCH_EXT 0x327A +#define EGL_YUV_COLOR_SPACE_HINT_EXT 0x327B +#define EGL_SAMPLE_RANGE_HINT_EXT 0x327C +#define EGL_YUV_CHROMA_HORIZONTAL_SITING_HINT_EXT 0x327D +#define EGL_YUV_CHROMA_VERTICAL_SITING_HINT_EXT 0x327E +#define EGL_ITU_REC601_EXT 0x327F +#define EGL_ITU_REC709_EXT 0x3280 +#define EGL_ITU_REC2020_EXT 0x3281 +#define EGL_YUV_FULL_RANGE_EXT 0x3282 +#define EGL_YUV_NARROW_RANGE_EXT 0x3283 +#define EGL_YUV_CHROMA_SITING_0_EXT 0x3284 +#define EGL_YUV_CHROMA_SITING_0_5_EXT 0x3285 +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __eglext_h_ */ diff --git a/testbed/glfw/deps/GL/glext.h b/testbed/glfw/deps/GL/glext.h new file mode 100644 index 00000000..e619fa3c --- /dev/null +++ b/testbed/glfw/deps/GL/glext.h @@ -0,0 +1,11626 @@ +#ifndef __glext_h_ +#define __glext_h_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Copyright (c) 2013-2014 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE 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 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ +/* +** This header is generated from the Khronos OpenGL / OpenGL ES XML +** API Registry. The current version of the Registry, generator scripts +** used to make the header, and the header can be found at +** http://www.opengl.org/registry/ +** +** Khronos $Revision: 27684 $ on $Date: 2014-08-11 01:21:35 -0700 (Mon, 11 Aug 2014) $ +*/ + +#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN 1 +#endif +#include +#endif + +#ifndef APIENTRY +#define APIENTRY +#endif +#ifndef APIENTRYP +#define APIENTRYP APIENTRY * +#endif +#ifndef GLAPI +#define GLAPI extern +#endif + +#define GL_GLEXT_VERSION 20140810 + +/* Generated C header for: + * API: gl + * Profile: compatibility + * Versions considered: .* + * Versions emitted: 1\.[2-9]|[234]\.[0-9] + * Default extensions included: gl + * Additional extensions included: _nomatch_^ + * Extensions removed: _nomatch_^ + */ + +#ifndef GL_VERSION_1_2 +#define GL_VERSION_1_2 1 +#define GL_UNSIGNED_BYTE_3_3_2 0x8032 +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_INT_8_8_8_8 0x8035 +#define GL_UNSIGNED_INT_10_10_10_2 0x8036 +#define GL_TEXTURE_BINDING_3D 0x806A +#define GL_PACK_SKIP_IMAGES 0x806B +#define GL_PACK_IMAGE_HEIGHT 0x806C +#define GL_UNPACK_SKIP_IMAGES 0x806D +#define GL_UNPACK_IMAGE_HEIGHT 0x806E +#define GL_TEXTURE_3D 0x806F +#define GL_PROXY_TEXTURE_3D 0x8070 +#define GL_TEXTURE_DEPTH 0x8071 +#define GL_TEXTURE_WRAP_R 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE 0x8073 +#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 +#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_BGR 0x80E0 +#define GL_BGRA 0x80E1 +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_ELEMENTS_INDICES 0x80E9 +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_TEXTURE_MIN_LOD 0x813A +#define GL_TEXTURE_MAX_LOD 0x813B +#define GL_TEXTURE_BASE_LEVEL 0x813C +#define GL_TEXTURE_MAX_LEVEL 0x813D +#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 +#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 +#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#define GL_RESCALE_NORMAL 0x803A +#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 +#define GL_SINGLE_COLOR 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR 0x81FA +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); +typedef void (APIENTRYP PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawRangeElements (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); +GLAPI void APIENTRY glTexImage3D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glCopyTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +#endif +#endif /* GL_VERSION_1_2 */ + +#ifndef GL_VERSION_1_3 +#define GL_VERSION_1_3 1 +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_ACTIVE_TEXTURE 0x84E0 +#define GL_MULTISAMPLE 0x809D +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE 0x809F +#define GL_SAMPLE_COVERAGE 0x80A0 +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C +#define GL_COMPRESSED_RGB 0x84ED +#define GL_COMPRESSED_RGBA 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT 0x84EF +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 +#define GL_TEXTURE_COMPRESSED 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 +#define GL_CLAMP_TO_BORDER 0x812D +#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 +#define GL_MAX_TEXTURE_UNITS 0x84E2 +#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 +#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 +#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 +#define GL_MULTISAMPLE_BIT 0x20000000 +#define GL_NORMAL_MAP 0x8511 +#define GL_REFLECTION_MAP 0x8512 +#define GL_COMPRESSED_ALPHA 0x84E9 +#define GL_COMPRESSED_LUMINANCE 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB +#define GL_COMPRESSED_INTENSITY 0x84EC +#define GL_COMBINE 0x8570 +#define GL_COMBINE_RGB 0x8571 +#define GL_COMBINE_ALPHA 0x8572 +#define GL_SOURCE0_RGB 0x8580 +#define GL_SOURCE1_RGB 0x8581 +#define GL_SOURCE2_RGB 0x8582 +#define GL_SOURCE0_ALPHA 0x8588 +#define GL_SOURCE1_ALPHA 0x8589 +#define GL_SOURCE2_ALPHA 0x858A +#define GL_OPERAND0_RGB 0x8590 +#define GL_OPERAND1_RGB 0x8591 +#define GL_OPERAND2_RGB 0x8592 +#define GL_OPERAND0_ALPHA 0x8598 +#define GL_OPERAND1_ALPHA 0x8599 +#define GL_OPERAND2_ALPHA 0x859A +#define GL_RGB_SCALE 0x8573 +#define GL_ADD_SIGNED 0x8574 +#define GL_INTERPOLATE 0x8575 +#define GL_SUBTRACT 0x84E7 +#define GL_CONSTANT 0x8576 +#define GL_PRIMARY_COLOR 0x8577 +#define GL_PREVIOUS 0x8578 +#define GL_DOT3_RGB 0x86AE +#define GL_DOT3_RGBA 0x86AF +typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture); +typedef void (APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLfloat value, GLboolean invert); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); +typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, void *img); +typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREPROC) (GLenum texture); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1DPROC) (GLenum target, GLdouble s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1FPROC) (GLenum target, GLfloat s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1IPROC) (GLenum target, GLint s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1SPROC) (GLenum target, GLshort s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2DPROC) (GLenum target, GLdouble s, GLdouble t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2FPROC) (GLenum target, GLfloat s, GLfloat t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2IPROC) (GLenum target, GLint s, GLint t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2SPROC) (GLenum target, GLshort s, GLshort t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3IPROC) (GLenum target, GLint s, GLint t, GLint r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3SPROC) (GLenum target, GLshort s, GLshort t, GLshort r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4IPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4SPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXFPROC) (const GLfloat *m); +typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXDPROC) (const GLdouble *m); +typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXFPROC) (const GLfloat *m); +typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXDPROC) (const GLdouble *m); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glActiveTexture (GLenum texture); +GLAPI void APIENTRY glSampleCoverage (GLfloat value, GLboolean invert); +GLAPI void APIENTRY glCompressedTexImage3D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); +GLAPI void APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); +GLAPI void APIENTRY glCompressedTexImage1D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data); +GLAPI void APIENTRY glCompressedTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); +GLAPI void APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); +GLAPI void APIENTRY glCompressedTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); +GLAPI void APIENTRY glGetCompressedTexImage (GLenum target, GLint level, void *img); +GLAPI void APIENTRY glClientActiveTexture (GLenum texture); +GLAPI void APIENTRY glMultiTexCoord1d (GLenum target, GLdouble s); +GLAPI void APIENTRY glMultiTexCoord1dv (GLenum target, const GLdouble *v); +GLAPI void APIENTRY glMultiTexCoord1f (GLenum target, GLfloat s); +GLAPI void APIENTRY glMultiTexCoord1fv (GLenum target, const GLfloat *v); +GLAPI void APIENTRY glMultiTexCoord1i (GLenum target, GLint s); +GLAPI void APIENTRY glMultiTexCoord1iv (GLenum target, const GLint *v); +GLAPI void APIENTRY glMultiTexCoord1s (GLenum target, GLshort s); +GLAPI void APIENTRY glMultiTexCoord1sv (GLenum target, const GLshort *v); +GLAPI void APIENTRY glMultiTexCoord2d (GLenum target, GLdouble s, GLdouble t); +GLAPI void APIENTRY glMultiTexCoord2dv (GLenum target, const GLdouble *v); +GLAPI void APIENTRY glMultiTexCoord2f (GLenum target, GLfloat s, GLfloat t); +GLAPI void APIENTRY glMultiTexCoord2fv (GLenum target, const GLfloat *v); +GLAPI void APIENTRY glMultiTexCoord2i (GLenum target, GLint s, GLint t); +GLAPI void APIENTRY glMultiTexCoord2iv (GLenum target, const GLint *v); +GLAPI void APIENTRY glMultiTexCoord2s (GLenum target, GLshort s, GLshort t); +GLAPI void APIENTRY glMultiTexCoord2sv (GLenum target, const GLshort *v); +GLAPI void APIENTRY glMultiTexCoord3d (GLenum target, GLdouble s, GLdouble t, GLdouble r); +GLAPI void APIENTRY glMultiTexCoord3dv (GLenum target, const GLdouble *v); +GLAPI void APIENTRY glMultiTexCoord3f (GLenum target, GLfloat s, GLfloat t, GLfloat r); +GLAPI void APIENTRY glMultiTexCoord3fv (GLenum target, const GLfloat *v); +GLAPI void APIENTRY glMultiTexCoord3i (GLenum target, GLint s, GLint t, GLint r); +GLAPI void APIENTRY glMultiTexCoord3iv (GLenum target, const GLint *v); +GLAPI void APIENTRY glMultiTexCoord3s (GLenum target, GLshort s, GLshort t, GLshort r); +GLAPI void APIENTRY glMultiTexCoord3sv (GLenum target, const GLshort *v); +GLAPI void APIENTRY glMultiTexCoord4d (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +GLAPI void APIENTRY glMultiTexCoord4dv (GLenum target, const GLdouble *v); +GLAPI void APIENTRY glMultiTexCoord4f (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +GLAPI void APIENTRY glMultiTexCoord4fv (GLenum target, const GLfloat *v); +GLAPI void APIENTRY glMultiTexCoord4i (GLenum target, GLint s, GLint t, GLint r, GLint q); +GLAPI void APIENTRY glMultiTexCoord4iv (GLenum target, const GLint *v); +GLAPI void APIENTRY glMultiTexCoord4s (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +GLAPI void APIENTRY glMultiTexCoord4sv (GLenum target, const GLshort *v); +GLAPI void APIENTRY glLoadTransposeMatrixf (const GLfloat *m); +GLAPI void APIENTRY glLoadTransposeMatrixd (const GLdouble *m); +GLAPI void APIENTRY glMultTransposeMatrixf (const GLfloat *m); +GLAPI void APIENTRY glMultTransposeMatrixd (const GLdouble *m); +#endif +#endif /* GL_VERSION_1_3 */ + +#ifndef GL_VERSION_1_4 +#define GL_VERSION_1_4 1 +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_SRC_ALPHA 0x80CB +#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_DEPTH_COMPONENT24 0x81A6 +#define GL_DEPTH_COMPONENT32 0x81A7 +#define GL_MIRRORED_REPEAT 0x8370 +#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD +#define GL_TEXTURE_LOD_BIAS 0x8501 +#define GL_INCR_WRAP 0x8507 +#define GL_DECR_WRAP 0x8508 +#define GL_TEXTURE_DEPTH_SIZE 0x884A +#define GL_TEXTURE_COMPARE_MODE 0x884C +#define GL_TEXTURE_COMPARE_FUNC 0x884D +#define GL_POINT_SIZE_MIN 0x8126 +#define GL_POINT_SIZE_MAX 0x8127 +#define GL_POINT_DISTANCE_ATTENUATION 0x8129 +#define GL_GENERATE_MIPMAP 0x8191 +#define GL_GENERATE_MIPMAP_HINT 0x8192 +#define GL_FOG_COORDINATE_SOURCE 0x8450 +#define GL_FOG_COORDINATE 0x8451 +#define GL_FRAGMENT_DEPTH 0x8452 +#define GL_CURRENT_FOG_COORDINATE 0x8453 +#define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454 +#define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455 +#define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456 +#define GL_FOG_COORDINATE_ARRAY 0x8457 +#define GL_COLOR_SUM 0x8458 +#define GL_CURRENT_SECONDARY_COLOR 0x8459 +#define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A +#define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B +#define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C +#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D +#define GL_SECONDARY_COLOR_ARRAY 0x845E +#define GL_TEXTURE_FILTER_CONTROL 0x8500 +#define GL_DEPTH_TEXTURE_MODE 0x884B +#define GL_COMPARE_R_TO_TEXTURE 0x884E +#define GL_FUNC_ADD 0x8006 +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#define GL_MIN 0x8007 +#define GL_MAX 0x8008 +#define GL_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount); +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount); +typedef void (APIENTRYP PFNGLPOINTPARAMETERFPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLPOINTPARAMETERFVPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLPOINTPARAMETERIPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLPOINTPARAMETERIVPROC) (GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLFOGCOORDFPROC) (GLfloat coord); +typedef void (APIENTRYP PFNGLFOGCOORDFVPROC) (const GLfloat *coord); +typedef void (APIENTRYP PFNGLFOGCOORDDPROC) (GLdouble coord); +typedef void (APIENTRYP PFNGLFOGCOORDDVPROC) (const GLdouble *coord); +typedef void (APIENTRYP PFNGLFOGCOORDPOINTERPROC) (GLenum type, GLsizei stride, const void *pointer); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BPROC) (GLbyte red, GLbyte green, GLbyte blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BVPROC) (const GLbyte *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DPROC) (GLdouble red, GLdouble green, GLdouble blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DVPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FPROC) (GLfloat red, GLfloat green, GLfloat blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FVPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IPROC) (GLint red, GLint green, GLint blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IVPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SPROC) (GLshort red, GLshort green, GLshort blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SVPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBPROC) (GLubyte red, GLubyte green, GLubyte blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBVPROC) (const GLubyte *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIPROC) (GLuint red, GLuint green, GLuint blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIVPROC) (const GLuint *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USPROC) (GLushort red, GLushort green, GLushort blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USVPROC) (const GLushort *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTERPROC) (GLint size, GLenum type, GLsizei stride, const void *pointer); +typedef void (APIENTRYP PFNGLWINDOWPOS2DPROC) (GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLWINDOWPOS2DVPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2FPROC) (GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLWINDOWPOS2FVPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2IPROC) (GLint x, GLint y); +typedef void (APIENTRYP PFNGLWINDOWPOS2IVPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2SPROC) (GLshort x, GLshort y); +typedef void (APIENTRYP PFNGLWINDOWPOS2SVPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3DPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLWINDOWPOS3DVPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3FPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLWINDOWPOS3FVPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3IPROC) (GLint x, GLint y, GLint z); +typedef void (APIENTRYP PFNGLWINDOWPOS3IVPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3SPROC) (GLshort x, GLshort y, GLshort z); +typedef void (APIENTRYP PFNGLWINDOWPOS3SVPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLBLENDCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +typedef void (APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendFuncSeparate (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +GLAPI void APIENTRY glMultiDrawArrays (GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount); +GLAPI void APIENTRY glMultiDrawElements (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount); +GLAPI void APIENTRY glPointParameterf (GLenum pname, GLfloat param); +GLAPI void APIENTRY glPointParameterfv (GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glPointParameteri (GLenum pname, GLint param); +GLAPI void APIENTRY glPointParameteriv (GLenum pname, const GLint *params); +GLAPI void APIENTRY glFogCoordf (GLfloat coord); +GLAPI void APIENTRY glFogCoordfv (const GLfloat *coord); +GLAPI void APIENTRY glFogCoordd (GLdouble coord); +GLAPI void APIENTRY glFogCoorddv (const GLdouble *coord); +GLAPI void APIENTRY glFogCoordPointer (GLenum type, GLsizei stride, const void *pointer); +GLAPI void APIENTRY glSecondaryColor3b (GLbyte red, GLbyte green, GLbyte blue); +GLAPI void APIENTRY glSecondaryColor3bv (const GLbyte *v); +GLAPI void APIENTRY glSecondaryColor3d (GLdouble red, GLdouble green, GLdouble blue); +GLAPI void APIENTRY glSecondaryColor3dv (const GLdouble *v); +GLAPI void APIENTRY glSecondaryColor3f (GLfloat red, GLfloat green, GLfloat blue); +GLAPI void APIENTRY glSecondaryColor3fv (const GLfloat *v); +GLAPI void APIENTRY glSecondaryColor3i (GLint red, GLint green, GLint blue); +GLAPI void APIENTRY glSecondaryColor3iv (const GLint *v); +GLAPI void APIENTRY glSecondaryColor3s (GLshort red, GLshort green, GLshort blue); +GLAPI void APIENTRY glSecondaryColor3sv (const GLshort *v); +GLAPI void APIENTRY glSecondaryColor3ub (GLubyte red, GLubyte green, GLubyte blue); +GLAPI void APIENTRY glSecondaryColor3ubv (const GLubyte *v); +GLAPI void APIENTRY glSecondaryColor3ui (GLuint red, GLuint green, GLuint blue); +GLAPI void APIENTRY glSecondaryColor3uiv (const GLuint *v); +GLAPI void APIENTRY glSecondaryColor3us (GLushort red, GLushort green, GLushort blue); +GLAPI void APIENTRY glSecondaryColor3usv (const GLushort *v); +GLAPI void APIENTRY glSecondaryColorPointer (GLint size, GLenum type, GLsizei stride, const void *pointer); +GLAPI void APIENTRY glWindowPos2d (GLdouble x, GLdouble y); +GLAPI void APIENTRY glWindowPos2dv (const GLdouble *v); +GLAPI void APIENTRY glWindowPos2f (GLfloat x, GLfloat y); +GLAPI void APIENTRY glWindowPos2fv (const GLfloat *v); +GLAPI void APIENTRY glWindowPos2i (GLint x, GLint y); +GLAPI void APIENTRY glWindowPos2iv (const GLint *v); +GLAPI void APIENTRY glWindowPos2s (GLshort x, GLshort y); +GLAPI void APIENTRY glWindowPos2sv (const GLshort *v); +GLAPI void APIENTRY glWindowPos3d (GLdouble x, GLdouble y, GLdouble z); +GLAPI void APIENTRY glWindowPos3dv (const GLdouble *v); +GLAPI void APIENTRY glWindowPos3f (GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glWindowPos3fv (const GLfloat *v); +GLAPI void APIENTRY glWindowPos3i (GLint x, GLint y, GLint z); +GLAPI void APIENTRY glWindowPos3iv (const GLint *v); +GLAPI void APIENTRY glWindowPos3s (GLshort x, GLshort y, GLshort z); +GLAPI void APIENTRY glWindowPos3sv (const GLshort *v); +GLAPI void APIENTRY glBlendColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GLAPI void APIENTRY glBlendEquation (GLenum mode); +#endif +#endif /* GL_VERSION_1_4 */ + +#ifndef GL_VERSION_1_5 +#define GL_VERSION_1_5 1 +#include +typedef ptrdiff_t GLsizeiptr; +typedef ptrdiff_t GLintptr; +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_USAGE 0x8765 +#define GL_QUERY_COUNTER_BITS 0x8864 +#define GL_CURRENT_QUERY 0x8865 +#define GL_QUERY_RESULT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE 0x8867 +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F +#define GL_READ_ONLY 0x88B8 +#define GL_WRITE_ONLY 0x88B9 +#define GL_READ_WRITE 0x88BA +#define GL_BUFFER_ACCESS 0x88BB +#define GL_BUFFER_MAPPED 0x88BC +#define GL_BUFFER_MAP_POINTER 0x88BD +#define GL_STREAM_DRAW 0x88E0 +#define GL_STREAM_READ 0x88E1 +#define GL_STREAM_COPY 0x88E2 +#define GL_STATIC_DRAW 0x88E4 +#define GL_STATIC_READ 0x88E5 +#define GL_STATIC_COPY 0x88E6 +#define GL_DYNAMIC_DRAW 0x88E8 +#define GL_DYNAMIC_READ 0x88E9 +#define GL_DYNAMIC_COPY 0x88EA +#define GL_SAMPLES_PASSED 0x8914 +#define GL_SRC1_ALPHA 0x8589 +#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 +#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897 +#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898 +#define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899 +#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A +#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B +#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C +#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D +#define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E +#define GL_FOG_COORD_SRC 0x8450 +#define GL_FOG_COORD 0x8451 +#define GL_CURRENT_FOG_COORD 0x8453 +#define GL_FOG_COORD_ARRAY_TYPE 0x8454 +#define GL_FOG_COORD_ARRAY_STRIDE 0x8455 +#define GL_FOG_COORD_ARRAY_POINTER 0x8456 +#define GL_FOG_COORD_ARRAY 0x8457 +#define GL_FOG_COORD_ARRAY_BUFFER_BINDING 0x889D +#define GL_SRC0_RGB 0x8580 +#define GL_SRC1_RGB 0x8581 +#define GL_SRC2_RGB 0x8582 +#define GL_SRC0_ALPHA 0x8588 +#define GL_SRC2_ALPHA 0x858A +typedef void (APIENTRYP PFNGLGENQUERIESPROC) (GLsizei n, GLuint *ids); +typedef void (APIENTRYP PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint *ids); +typedef GLboolean (APIENTRYP PFNGLISQUERYPROC) (GLuint id); +typedef void (APIENTRYP PFNGLBEGINQUERYPROC) (GLenum target, GLuint id); +typedef void (APIENTRYP PFNGLENDQUERYPROC) (GLenum target); +typedef void (APIENTRYP PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVPROC) (GLuint id, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint *params); +typedef void (APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer); +typedef void (APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers); +typedef void (APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers); +typedef GLboolean (APIENTRYP PFNGLISBUFFERPROC) (GLuint buffer); +typedef void (APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const void *data, GLenum usage); +typedef void (APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const void *data); +typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, void *data); +typedef void *(APIENTRYP PFNGLMAPBUFFERPROC) (GLenum target, GLenum access); +typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERPROC) (GLenum target); +typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, void **params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGenQueries (GLsizei n, GLuint *ids); +GLAPI void APIENTRY glDeleteQueries (GLsizei n, const GLuint *ids); +GLAPI GLboolean APIENTRY glIsQuery (GLuint id); +GLAPI void APIENTRY glBeginQuery (GLenum target, GLuint id); +GLAPI void APIENTRY glEndQuery (GLenum target); +GLAPI void APIENTRY glGetQueryiv (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetQueryObjectiv (GLuint id, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetQueryObjectuiv (GLuint id, GLenum pname, GLuint *params); +GLAPI void APIENTRY glBindBuffer (GLenum target, GLuint buffer); +GLAPI void APIENTRY glDeleteBuffers (GLsizei n, const GLuint *buffers); +GLAPI void APIENTRY glGenBuffers (GLsizei n, GLuint *buffers); +GLAPI GLboolean APIENTRY glIsBuffer (GLuint buffer); +GLAPI void APIENTRY glBufferData (GLenum target, GLsizeiptr size, const void *data, GLenum usage); +GLAPI void APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const void *data); +GLAPI void APIENTRY glGetBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, void *data); +GLAPI void *APIENTRY glMapBuffer (GLenum target, GLenum access); +GLAPI GLboolean APIENTRY glUnmapBuffer (GLenum target); +GLAPI void APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetBufferPointerv (GLenum target, GLenum pname, void **params); +#endif +#endif /* GL_VERSION_1_5 */ + +#ifndef GL_VERSION_2_0 +#define GL_VERSION_2_0 1 +typedef char GLchar; +#define GL_BLEND_EQUATION_RGB 0x8009 +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 +#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_STENCIL_BACK_FUNC 0x8800 +#define GL_STENCIL_BACK_FAIL 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 +#define GL_MAX_DRAW_BUFFERS 0x8824 +#define GL_DRAW_BUFFER0 0x8825 +#define GL_DRAW_BUFFER1 0x8826 +#define GL_DRAW_BUFFER2 0x8827 +#define GL_DRAW_BUFFER3 0x8828 +#define GL_DRAW_BUFFER4 0x8829 +#define GL_DRAW_BUFFER5 0x882A +#define GL_DRAW_BUFFER6 0x882B +#define GL_DRAW_BUFFER7 0x882C +#define GL_DRAW_BUFFER8 0x882D +#define GL_DRAW_BUFFER9 0x882E +#define GL_DRAW_BUFFER10 0x882F +#define GL_DRAW_BUFFER11 0x8830 +#define GL_DRAW_BUFFER12 0x8831 +#define GL_DRAW_BUFFER13 0x8832 +#define GL_DRAW_BUFFER14 0x8833 +#define GL_DRAW_BUFFER15 0x8834 +#define GL_BLEND_EQUATION_ALPHA 0x883D +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A +#define GL_MAX_VARYING_FLOATS 0x8B4B +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_SHADER_TYPE 0x8B4F +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_BOOL 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT4 0x8B5C +#define GL_SAMPLER_1D 0x8B5D +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_3D 0x8B5F +#define GL_SAMPLER_CUBE 0x8B60 +#define GL_SAMPLER_1D_SHADOW 0x8B61 +#define GL_SAMPLER_2D_SHADOW 0x8B62 +#define GL_DELETE_STATUS 0x8B80 +#define GL_COMPILE_STATUS 0x8B81 +#define GL_LINK_STATUS 0x8B82 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_CURRENT_PROGRAM 0x8B8D +#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 +#define GL_LOWER_LEFT 0x8CA1 +#define GL_UPPER_LEFT 0x8CA2 +#define GL_STENCIL_BACK_REF 0x8CA3 +#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 +#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 +#define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643 +#define GL_POINT_SPRITE 0x8861 +#define GL_COORD_REPLACE 0x8862 +#define GL_MAX_TEXTURE_COORDS 0x8871 +typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha); +typedef void (APIENTRYP PFNGLDRAWBUFFERSPROC) (GLsizei n, const GLenum *bufs); +typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC) (GLenum face, GLenum func, GLint ref, GLuint mask); +typedef void (APIENTRYP PFNGLSTENCILMASKSEPARATEPROC) (GLenum face, GLuint mask); +typedef void (APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader); +typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar *name); +typedef void (APIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader); +typedef GLuint (APIENTRYP PFNGLCREATEPROGRAMPROC) (void); +typedef GLuint (APIENTRYP PFNGLCREATESHADERPROC) (GLenum type); +typedef void (APIENTRYP PFNGLDELETEPROGRAMPROC) (GLuint program); +typedef void (APIENTRYP PFNGLDELETESHADERPROC) (GLuint shader); +typedef void (APIENTRYP PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader); +typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index); +typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index); +typedef void (APIENTRYP PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +typedef void (APIENTRYP PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders); +typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name); +typedef void (APIENTRYP PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +typedef void (APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +typedef void (APIENTRYP PFNGLGETSHADERSOURCEPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); +typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name); +typedef void (APIENTRYP PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat *params); +typedef void (APIENTRYP PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVPROC) (GLuint index, GLenum pname, GLdouble *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVPROC) (GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, void **pointer); +typedef GLboolean (APIENTRYP PFNGLISPROGRAMPROC) (GLuint program); +typedef GLboolean (APIENTRYP PFNGLISSHADERPROC) (GLuint shader); +typedef void (APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program); +typedef void (APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length); +typedef void (APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program); +typedef void (APIENTRYP PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0); +typedef void (APIENTRYP PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1); +typedef void (APIENTRYP PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (APIENTRYP PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (APIENTRYP PFNGLUNIFORM1IPROC) (GLint location, GLint v0); +typedef void (APIENTRYP PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1); +typedef void (APIENTRYP PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2); +typedef void (APIENTRYP PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (APIENTRYP PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1DPROC) (GLuint index, GLdouble x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1SPROC) (GLuint index, GLshort x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2DPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2SPROC) (GLuint index, GLshort x, GLshort y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3SPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVPROC) (GLuint index, const GLbyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVPROC) (GLuint index, const GLushort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVPROC) (GLuint index, const GLbyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4SPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVPROC) (GLuint index, const GLushort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha); +GLAPI void APIENTRY glDrawBuffers (GLsizei n, const GLenum *bufs); +GLAPI void APIENTRY glStencilOpSeparate (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +GLAPI void APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask); +GLAPI void APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask); +GLAPI void APIENTRY glAttachShader (GLuint program, GLuint shader); +GLAPI void APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar *name); +GLAPI void APIENTRY glCompileShader (GLuint shader); +GLAPI GLuint APIENTRY glCreateProgram (void); +GLAPI GLuint APIENTRY glCreateShader (GLenum type); +GLAPI void APIENTRY glDeleteProgram (GLuint program); +GLAPI void APIENTRY glDeleteShader (GLuint shader); +GLAPI void APIENTRY glDetachShader (GLuint program, GLuint shader); +GLAPI void APIENTRY glDisableVertexAttribArray (GLuint index); +GLAPI void APIENTRY glEnableVertexAttribArray (GLuint index); +GLAPI void APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +GLAPI void APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +GLAPI void APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders); +GLAPI GLint APIENTRY glGetAttribLocation (GLuint program, const GLchar *name); +GLAPI void APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +GLAPI void APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +GLAPI void APIENTRY glGetShaderSource (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); +GLAPI GLint APIENTRY glGetUniformLocation (GLuint program, const GLchar *name); +GLAPI void APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat *params); +GLAPI void APIENTRY glGetUniformiv (GLuint program, GLint location, GLint *params); +GLAPI void APIENTRY glGetVertexAttribdv (GLuint index, GLenum pname, GLdouble *params); +GLAPI void APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, void **pointer); +GLAPI GLboolean APIENTRY glIsProgram (GLuint program); +GLAPI GLboolean APIENTRY glIsShader (GLuint shader); +GLAPI void APIENTRY glLinkProgram (GLuint program); +GLAPI void APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length); +GLAPI void APIENTRY glUseProgram (GLuint program); +GLAPI void APIENTRY glUniform1f (GLint location, GLfloat v0); +GLAPI void APIENTRY glUniform2f (GLint location, GLfloat v0, GLfloat v1); +GLAPI void APIENTRY glUniform3f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +GLAPI void APIENTRY glUniform4f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +GLAPI void APIENTRY glUniform1i (GLint location, GLint v0); +GLAPI void APIENTRY glUniform2i (GLint location, GLint v0, GLint v1); +GLAPI void APIENTRY glUniform3i (GLint location, GLint v0, GLint v1, GLint v2); +GLAPI void APIENTRY glUniform4i (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +GLAPI void APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glValidateProgram (GLuint program); +GLAPI void APIENTRY glVertexAttrib1d (GLuint index, GLdouble x); +GLAPI void APIENTRY glVertexAttrib1dv (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttrib1f (GLuint index, GLfloat x); +GLAPI void APIENTRY glVertexAttrib1fv (GLuint index, const GLfloat *v); +GLAPI void APIENTRY glVertexAttrib1s (GLuint index, GLshort x); +GLAPI void APIENTRY glVertexAttrib1sv (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib2d (GLuint index, GLdouble x, GLdouble y); +GLAPI void APIENTRY glVertexAttrib2dv (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttrib2f (GLuint index, GLfloat x, GLfloat y); +GLAPI void APIENTRY glVertexAttrib2fv (GLuint index, const GLfloat *v); +GLAPI void APIENTRY glVertexAttrib2s (GLuint index, GLshort x, GLshort y); +GLAPI void APIENTRY glVertexAttrib2sv (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib3d (GLuint index, GLdouble x, GLdouble y, GLdouble z); +GLAPI void APIENTRY glVertexAttrib3dv (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttrib3f (GLuint index, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glVertexAttrib3fv (GLuint index, const GLfloat *v); +GLAPI void APIENTRY glVertexAttrib3s (GLuint index, GLshort x, GLshort y, GLshort z); +GLAPI void APIENTRY glVertexAttrib3sv (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib4Nbv (GLuint index, const GLbyte *v); +GLAPI void APIENTRY glVertexAttrib4Niv (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttrib4Nsv (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib4Nub (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +GLAPI void APIENTRY glVertexAttrib4Nubv (GLuint index, const GLubyte *v); +GLAPI void APIENTRY glVertexAttrib4Nuiv (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttrib4Nusv (GLuint index, const GLushort *v); +GLAPI void APIENTRY glVertexAttrib4bv (GLuint index, const GLbyte *v); +GLAPI void APIENTRY glVertexAttrib4d (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void APIENTRY glVertexAttrib4dv (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttrib4f (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void APIENTRY glVertexAttrib4fv (GLuint index, const GLfloat *v); +GLAPI void APIENTRY glVertexAttrib4iv (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttrib4s (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +GLAPI void APIENTRY glVertexAttrib4sv (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib4ubv (GLuint index, const GLubyte *v); +GLAPI void APIENTRY glVertexAttrib4uiv (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttrib4usv (GLuint index, const GLushort *v); +GLAPI void APIENTRY glVertexAttribPointer (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); +#endif +#endif /* GL_VERSION_2_0 */ + +#ifndef GL_VERSION_2_1 +#define GL_VERSION_2_1 1 +#define GL_PIXEL_PACK_BUFFER 0x88EB +#define GL_PIXEL_UNPACK_BUFFER 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF +#define GL_FLOAT_MAT2x3 0x8B65 +#define GL_FLOAT_MAT2x4 0x8B66 +#define GL_FLOAT_MAT3x2 0x8B67 +#define GL_FLOAT_MAT3x4 0x8B68 +#define GL_FLOAT_MAT4x2 0x8B69 +#define GL_FLOAT_MAT4x3 0x8B6A +#define GL_SRGB 0x8C40 +#define GL_SRGB8 0x8C41 +#define GL_SRGB_ALPHA 0x8C42 +#define GL_SRGB8_ALPHA8 0x8C43 +#define GL_COMPRESSED_SRGB 0x8C48 +#define GL_COMPRESSED_SRGB_ALPHA 0x8C49 +#define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F +#define GL_SLUMINANCE_ALPHA 0x8C44 +#define GL_SLUMINANCE8_ALPHA8 0x8C45 +#define GL_SLUMINANCE 0x8C46 +#define GL_SLUMINANCE8 0x8C47 +#define GL_COMPRESSED_SLUMINANCE 0x8C4A +#define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glUniformMatrix2x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glUniformMatrix3x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glUniformMatrix2x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glUniformMatrix4x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glUniformMatrix3x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glUniformMatrix4x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +#endif +#endif /* GL_VERSION_2_1 */ + +#ifndef GL_VERSION_3_0 +#define GL_VERSION_3_0 1 +typedef unsigned short GLhalf; +#define GL_COMPARE_REF_TO_TEXTURE 0x884E +#define GL_CLIP_DISTANCE0 0x3000 +#define GL_CLIP_DISTANCE1 0x3001 +#define GL_CLIP_DISTANCE2 0x3002 +#define GL_CLIP_DISTANCE3 0x3003 +#define GL_CLIP_DISTANCE4 0x3004 +#define GL_CLIP_DISTANCE5 0x3005 +#define GL_CLIP_DISTANCE6 0x3006 +#define GL_CLIP_DISTANCE7 0x3007 +#define GL_MAX_CLIP_DISTANCES 0x0D32 +#define GL_MAJOR_VERSION 0x821B +#define GL_MINOR_VERSION 0x821C +#define GL_NUM_EXTENSIONS 0x821D +#define GL_CONTEXT_FLAGS 0x821E +#define GL_COMPRESSED_RED 0x8225 +#define GL_COMPRESSED_RG 0x8226 +#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x00000001 +#define GL_RGBA32F 0x8814 +#define GL_RGB32F 0x8815 +#define GL_RGBA16F 0x881A +#define GL_RGB16F 0x881B +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD +#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF +#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 +#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 +#define GL_CLAMP_READ_COLOR 0x891C +#define GL_FIXED_ONLY 0x891D +#define GL_MAX_VARYING_COMPONENTS 0x8B4B +#define GL_TEXTURE_1D_ARRAY 0x8C18 +#define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19 +#define GL_TEXTURE_2D_ARRAY 0x8C1A +#define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B +#define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C +#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D +#define GL_R11F_G11F_B10F 0x8C3A +#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B +#define GL_RGB9_E5 0x8C3D +#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E +#define GL_TEXTURE_SHARED_SIZE 0x8C3F +#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 +#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 +#define GL_PRIMITIVES_GENERATED 0x8C87 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 +#define GL_RASTERIZER_DISCARD 0x8C89 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B +#define GL_INTERLEAVED_ATTRIBS 0x8C8C +#define GL_SEPARATE_ATTRIBS 0x8C8D +#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F +#define GL_RGBA32UI 0x8D70 +#define GL_RGB32UI 0x8D71 +#define GL_RGBA16UI 0x8D76 +#define GL_RGB16UI 0x8D77 +#define GL_RGBA8UI 0x8D7C +#define GL_RGB8UI 0x8D7D +#define GL_RGBA32I 0x8D82 +#define GL_RGB32I 0x8D83 +#define GL_RGBA16I 0x8D88 +#define GL_RGB16I 0x8D89 +#define GL_RGBA8I 0x8D8E +#define GL_RGB8I 0x8D8F +#define GL_RED_INTEGER 0x8D94 +#define GL_GREEN_INTEGER 0x8D95 +#define GL_BLUE_INTEGER 0x8D96 +#define GL_RGB_INTEGER 0x8D98 +#define GL_RGBA_INTEGER 0x8D99 +#define GL_BGR_INTEGER 0x8D9A +#define GL_BGRA_INTEGER 0x8D9B +#define GL_SAMPLER_1D_ARRAY 0x8DC0 +#define GL_SAMPLER_2D_ARRAY 0x8DC1 +#define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3 +#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 +#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 +#define GL_UNSIGNED_INT_VEC2 0x8DC6 +#define GL_UNSIGNED_INT_VEC3 0x8DC7 +#define GL_UNSIGNED_INT_VEC4 0x8DC8 +#define GL_INT_SAMPLER_1D 0x8DC9 +#define GL_INT_SAMPLER_2D 0x8DCA +#define GL_INT_SAMPLER_3D 0x8DCB +#define GL_INT_SAMPLER_CUBE 0x8DCC +#define GL_INT_SAMPLER_1D_ARRAY 0x8DCE +#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF +#define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1 +#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 +#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 +#define GL_QUERY_WAIT 0x8E13 +#define GL_QUERY_NO_WAIT 0x8E14 +#define GL_QUERY_BY_REGION_WAIT 0x8E15 +#define GL_QUERY_BY_REGION_NO_WAIT 0x8E16 +#define GL_BUFFER_ACCESS_FLAGS 0x911F +#define GL_BUFFER_MAP_LENGTH 0x9120 +#define GL_BUFFER_MAP_OFFSET 0x9121 +#define GL_DEPTH_COMPONENT32F 0x8CAC +#define GL_DEPTH32F_STENCIL8 0x8CAD +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD +#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 +#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 +#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 +#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 +#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 +#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 +#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 +#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 +#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 +#define GL_FRAMEBUFFER_DEFAULT 0x8218 +#define GL_FRAMEBUFFER_UNDEFINED 0x8219 +#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A +#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 +#define GL_DEPTH_STENCIL 0x84F9 +#define GL_UNSIGNED_INT_24_8 0x84FA +#define GL_DEPTH24_STENCIL8 0x88F0 +#define GL_TEXTURE_STENCIL_SIZE 0x88F1 +#define GL_TEXTURE_RED_TYPE 0x8C10 +#define GL_TEXTURE_GREEN_TYPE 0x8C11 +#define GL_TEXTURE_BLUE_TYPE 0x8C12 +#define GL_TEXTURE_ALPHA_TYPE 0x8C13 +#define GL_TEXTURE_DEPTH_TYPE 0x8C16 +#define GL_UNSIGNED_NORMALIZED 0x8C17 +#define GL_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_RENDERBUFFER_BINDING 0x8CA7 +#define GL_READ_FRAMEBUFFER 0x8CA8 +#define GL_DRAW_FRAMEBUFFER 0x8CA9 +#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA +#define GL_RENDERBUFFER_SAMPLES 0x8CAB +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 +#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC +#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD +#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF +#define GL_COLOR_ATTACHMENT0 0x8CE0 +#define GL_COLOR_ATTACHMENT1 0x8CE1 +#define GL_COLOR_ATTACHMENT2 0x8CE2 +#define GL_COLOR_ATTACHMENT3 0x8CE3 +#define GL_COLOR_ATTACHMENT4 0x8CE4 +#define GL_COLOR_ATTACHMENT5 0x8CE5 +#define GL_COLOR_ATTACHMENT6 0x8CE6 +#define GL_COLOR_ATTACHMENT7 0x8CE7 +#define GL_COLOR_ATTACHMENT8 0x8CE8 +#define GL_COLOR_ATTACHMENT9 0x8CE9 +#define GL_COLOR_ATTACHMENT10 0x8CEA +#define GL_COLOR_ATTACHMENT11 0x8CEB +#define GL_COLOR_ATTACHMENT12 0x8CEC +#define GL_COLOR_ATTACHMENT13 0x8CED +#define GL_COLOR_ATTACHMENT14 0x8CEE +#define GL_COLOR_ATTACHMENT15 0x8CEF +#define GL_DEPTH_ATTACHMENT 0x8D00 +#define GL_STENCIL_ATTACHMENT 0x8D20 +#define GL_FRAMEBUFFER 0x8D40 +#define GL_RENDERBUFFER 0x8D41 +#define GL_RENDERBUFFER_WIDTH 0x8D42 +#define GL_RENDERBUFFER_HEIGHT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 +#define GL_STENCIL_INDEX1 0x8D46 +#define GL_STENCIL_INDEX4 0x8D47 +#define GL_STENCIL_INDEX8 0x8D48 +#define GL_STENCIL_INDEX16 0x8D49 +#define GL_RENDERBUFFER_RED_SIZE 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 +#define GL_MAX_SAMPLES 0x8D57 +#define GL_INDEX 0x8222 +#define GL_TEXTURE_LUMINANCE_TYPE 0x8C14 +#define GL_TEXTURE_INTENSITY_TYPE 0x8C15 +#define GL_FRAMEBUFFER_SRGB 0x8DB9 +#define GL_HALF_FLOAT 0x140B +#define GL_MAP_READ_BIT 0x0001 +#define GL_MAP_WRITE_BIT 0x0002 +#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 +#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 +#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 +#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 +#define GL_COMPRESSED_RED_RGTC1 0x8DBB +#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC +#define GL_COMPRESSED_RG_RGTC2 0x8DBD +#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE +#define GL_RG 0x8227 +#define GL_RG_INTEGER 0x8228 +#define GL_R8 0x8229 +#define GL_R16 0x822A +#define GL_RG8 0x822B +#define GL_RG16 0x822C +#define GL_R16F 0x822D +#define GL_R32F 0x822E +#define GL_RG16F 0x822F +#define GL_RG32F 0x8230 +#define GL_R8I 0x8231 +#define GL_R8UI 0x8232 +#define GL_R16I 0x8233 +#define GL_R16UI 0x8234 +#define GL_R32I 0x8235 +#define GL_R32UI 0x8236 +#define GL_RG8I 0x8237 +#define GL_RG8UI 0x8238 +#define GL_RG16I 0x8239 +#define GL_RG16UI 0x823A +#define GL_RG32I 0x823B +#define GL_RG32UI 0x823C +#define GL_VERTEX_ARRAY_BINDING 0x85B5 +#define GL_CLAMP_VERTEX_COLOR 0x891A +#define GL_CLAMP_FRAGMENT_COLOR 0x891B +#define GL_ALPHA_INTEGER 0x8D97 +typedef void (APIENTRYP PFNGLCOLORMASKIPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +typedef void (APIENTRYP PFNGLGETBOOLEANI_VPROC) (GLenum target, GLuint index, GLboolean *data); +typedef void (APIENTRYP PFNGLGETINTEGERI_VPROC) (GLenum target, GLuint index, GLint *data); +typedef void (APIENTRYP PFNGLENABLEIPROC) (GLenum target, GLuint index); +typedef void (APIENTRYP PFNGLDISABLEIPROC) (GLenum target, GLuint index); +typedef GLboolean (APIENTRYP PFNGLISENABLEDIPROC) (GLenum target, GLuint index); +typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKPROC) (GLenum primitiveMode); +typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKPROC) (void); +typedef void (APIENTRYP PFNGLBINDBUFFERRANGEPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (APIENTRYP PFNGLBINDBUFFERBASEPROC) (GLenum target, GLuint index, GLuint buffer); +typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode); +typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); +typedef void (APIENTRYP PFNGLCLAMPCOLORPROC) (GLenum target, GLenum clamp); +typedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERPROC) (GLuint id, GLenum mode); +typedef void (APIENTRYP PFNGLENDCONDITIONALRENDERPROC) (void); +typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVPROC) (GLuint index, GLenum pname, GLuint *params); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IPROC) (GLuint index, GLint x); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IPROC) (GLuint index, GLint x, GLint y); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IPROC) (GLuint index, GLint x, GLint y, GLint z); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIPROC) (GLuint index, GLuint x); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIPROC) (GLuint index, GLuint x, GLuint y); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IVPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IVPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IVPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IVPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIVPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIVPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIVPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIVPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4BVPROC) (GLuint index, const GLbyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4SVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UBVPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4USVPROC) (GLuint index, const GLushort *v); +typedef void (APIENTRYP PFNGLGETUNIFORMUIVPROC) (GLuint program, GLint location, GLuint *params); +typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONPROC) (GLuint program, GLuint color, const GLchar *name); +typedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONPROC) (GLuint program, const GLchar *name); +typedef void (APIENTRYP PFNGLUNIFORM1UIPROC) (GLint location, GLuint v0); +typedef void (APIENTRYP PFNGLUNIFORM2UIPROC) (GLint location, GLuint v0, GLuint v1); +typedef void (APIENTRYP PFNGLUNIFORM3UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (APIENTRYP PFNGLUNIFORM4UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (APIENTRYP PFNGLUNIFORM1UIVPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLUNIFORM2UIVPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLUNIFORM3UIVPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLUNIFORM4UIVPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, const GLuint *params); +typedef void (APIENTRYP PFNGLGETTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, GLuint *params); +typedef void (APIENTRYP PFNGLCLEARBUFFERIVPROC) (GLenum buffer, GLint drawbuffer, const GLint *value); +typedef void (APIENTRYP PFNGLCLEARBUFFERUIVPROC) (GLenum buffer, GLint drawbuffer, const GLuint *value); +typedef void (APIENTRYP PFNGLCLEARBUFFERFVPROC) (GLenum buffer, GLint drawbuffer, const GLfloat *value); +typedef void (APIENTRYP PFNGLCLEARBUFFERFIPROC) (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); +typedef const GLubyte *(APIENTRYP PFNGLGETSTRINGIPROC) (GLenum name, GLuint index); +typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFERPROC) (GLuint renderbuffer); +typedef void (APIENTRYP PFNGLBINDRENDERBUFFERPROC) (GLenum target, GLuint renderbuffer); +typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSPROC) (GLsizei n, const GLuint *renderbuffers); +typedef void (APIENTRYP PFNGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint *renderbuffers); +typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFERPROC) (GLuint framebuffer); +typedef void (APIENTRYP PFNGLBINDFRAMEBUFFERPROC) (GLenum target, GLuint framebuffer); +typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSPROC) (GLsizei n, const GLuint *framebuffers); +typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint *framebuffers); +typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSPROC) (GLenum target); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGENERATEMIPMAPPROC) (GLenum target); +typedef void (APIENTRYP PFNGLBLITFRAMEBUFFERPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void *(APIENTRYP PFNGLMAPBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); +typedef void (APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length); +typedef void (APIENTRYP PFNGLBINDVERTEXARRAYPROC) (GLuint array); +typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint *arrays); +typedef void (APIENTRYP PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays); +typedef GLboolean (APIENTRYP PFNGLISVERTEXARRAYPROC) (GLuint array); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glColorMaski (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +GLAPI void APIENTRY glGetBooleani_v (GLenum target, GLuint index, GLboolean *data); +GLAPI void APIENTRY glGetIntegeri_v (GLenum target, GLuint index, GLint *data); +GLAPI void APIENTRY glEnablei (GLenum target, GLuint index); +GLAPI void APIENTRY glDisablei (GLenum target, GLuint index); +GLAPI GLboolean APIENTRY glIsEnabledi (GLenum target, GLuint index); +GLAPI void APIENTRY glBeginTransformFeedback (GLenum primitiveMode); +GLAPI void APIENTRY glEndTransformFeedback (void); +GLAPI void APIENTRY glBindBufferRange (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +GLAPI void APIENTRY glBindBufferBase (GLenum target, GLuint index, GLuint buffer); +GLAPI void APIENTRY glTransformFeedbackVaryings (GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode); +GLAPI void APIENTRY glGetTransformFeedbackVarying (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); +GLAPI void APIENTRY glClampColor (GLenum target, GLenum clamp); +GLAPI void APIENTRY glBeginConditionalRender (GLuint id, GLenum mode); +GLAPI void APIENTRY glEndConditionalRender (void); +GLAPI void APIENTRY glVertexAttribIPointer (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); +GLAPI void APIENTRY glGetVertexAttribIiv (GLuint index, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetVertexAttribIuiv (GLuint index, GLenum pname, GLuint *params); +GLAPI void APIENTRY glVertexAttribI1i (GLuint index, GLint x); +GLAPI void APIENTRY glVertexAttribI2i (GLuint index, GLint x, GLint y); +GLAPI void APIENTRY glVertexAttribI3i (GLuint index, GLint x, GLint y, GLint z); +GLAPI void APIENTRY glVertexAttribI4i (GLuint index, GLint x, GLint y, GLint z, GLint w); +GLAPI void APIENTRY glVertexAttribI1ui (GLuint index, GLuint x); +GLAPI void APIENTRY glVertexAttribI2ui (GLuint index, GLuint x, GLuint y); +GLAPI void APIENTRY glVertexAttribI3ui (GLuint index, GLuint x, GLuint y, GLuint z); +GLAPI void APIENTRY glVertexAttribI4ui (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +GLAPI void APIENTRY glVertexAttribI1iv (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttribI2iv (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttribI3iv (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttribI4iv (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttribI1uiv (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttribI2uiv (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttribI3uiv (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttribI4uiv (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttribI4bv (GLuint index, const GLbyte *v); +GLAPI void APIENTRY glVertexAttribI4sv (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttribI4ubv (GLuint index, const GLubyte *v); +GLAPI void APIENTRY glVertexAttribI4usv (GLuint index, const GLushort *v); +GLAPI void APIENTRY glGetUniformuiv (GLuint program, GLint location, GLuint *params); +GLAPI void APIENTRY glBindFragDataLocation (GLuint program, GLuint color, const GLchar *name); +GLAPI GLint APIENTRY glGetFragDataLocation (GLuint program, const GLchar *name); +GLAPI void APIENTRY glUniform1ui (GLint location, GLuint v0); +GLAPI void APIENTRY glUniform2ui (GLint location, GLuint v0, GLuint v1); +GLAPI void APIENTRY glUniform3ui (GLint location, GLuint v0, GLuint v1, GLuint v2); +GLAPI void APIENTRY glUniform4ui (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +GLAPI void APIENTRY glUniform1uiv (GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glUniform2uiv (GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glUniform3uiv (GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glUniform4uiv (GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glTexParameterIiv (GLenum target, GLenum pname, const GLint *params); +GLAPI void APIENTRY glTexParameterIuiv (GLenum target, GLenum pname, const GLuint *params); +GLAPI void APIENTRY glGetTexParameterIiv (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetTexParameterIuiv (GLenum target, GLenum pname, GLuint *params); +GLAPI void APIENTRY glClearBufferiv (GLenum buffer, GLint drawbuffer, const GLint *value); +GLAPI void APIENTRY glClearBufferuiv (GLenum buffer, GLint drawbuffer, const GLuint *value); +GLAPI void APIENTRY glClearBufferfv (GLenum buffer, GLint drawbuffer, const GLfloat *value); +GLAPI void APIENTRY glClearBufferfi (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); +GLAPI const GLubyte *APIENTRY glGetStringi (GLenum name, GLuint index); +GLAPI GLboolean APIENTRY glIsRenderbuffer (GLuint renderbuffer); +GLAPI void APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer); +GLAPI void APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint *renderbuffers); +GLAPI void APIENTRY glGenRenderbuffers (GLsizei n, GLuint *renderbuffers); +GLAPI void APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +GLAPI void APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint *params); +GLAPI GLboolean APIENTRY glIsFramebuffer (GLuint framebuffer); +GLAPI void APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer); +GLAPI void APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint *framebuffers); +GLAPI void APIENTRY glGenFramebuffers (GLsizei n, GLuint *framebuffers); +GLAPI GLenum APIENTRY glCheckFramebufferStatus (GLenum target); +GLAPI void APIENTRY glFramebufferTexture1D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GLAPI void APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GLAPI void APIENTRY glFramebufferTexture3D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +GLAPI void APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +GLAPI void APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint *params); +GLAPI void APIENTRY glGenerateMipmap (GLenum target); +GLAPI void APIENTRY glBlitFramebuffer (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +GLAPI void APIENTRY glRenderbufferStorageMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +GLAPI void APIENTRY glFramebufferTextureLayer (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +GLAPI void *APIENTRY glMapBufferRange (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); +GLAPI void APIENTRY glFlushMappedBufferRange (GLenum target, GLintptr offset, GLsizeiptr length); +GLAPI void APIENTRY glBindVertexArray (GLuint array); +GLAPI void APIENTRY glDeleteVertexArrays (GLsizei n, const GLuint *arrays); +GLAPI void APIENTRY glGenVertexArrays (GLsizei n, GLuint *arrays); +GLAPI GLboolean APIENTRY glIsVertexArray (GLuint array); +#endif +#endif /* GL_VERSION_3_0 */ + +#ifndef GL_VERSION_3_1 +#define GL_VERSION_3_1 1 +#define GL_SAMPLER_2D_RECT 0x8B63 +#define GL_SAMPLER_2D_RECT_SHADOW 0x8B64 +#define GL_SAMPLER_BUFFER 0x8DC2 +#define GL_INT_SAMPLER_2D_RECT 0x8DCD +#define GL_INT_SAMPLER_BUFFER 0x8DD0 +#define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8 +#define GL_TEXTURE_BUFFER 0x8C2A +#define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B +#define GL_TEXTURE_BINDING_BUFFER 0x8C2C +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D +#define GL_TEXTURE_RECTANGLE 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8 +#define GL_R8_SNORM 0x8F94 +#define GL_RG8_SNORM 0x8F95 +#define GL_RGB8_SNORM 0x8F96 +#define GL_RGBA8_SNORM 0x8F97 +#define GL_R16_SNORM 0x8F98 +#define GL_RG16_SNORM 0x8F99 +#define GL_RGB16_SNORM 0x8F9A +#define GL_RGBA16_SNORM 0x8F9B +#define GL_SIGNED_NORMALIZED 0x8F9C +#define GL_PRIMITIVE_RESTART 0x8F9D +#define GL_PRIMITIVE_RESTART_INDEX 0x8F9E +#define GL_COPY_READ_BUFFER 0x8F36 +#define GL_COPY_WRITE_BUFFER 0x8F37 +#define GL_UNIFORM_BUFFER 0x8A11 +#define GL_UNIFORM_BUFFER_BINDING 0x8A28 +#define GL_UNIFORM_BUFFER_START 0x8A29 +#define GL_UNIFORM_BUFFER_SIZE 0x8A2A +#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B +#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C +#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D +#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E +#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F +#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 +#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 +#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32 +#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 +#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34 +#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35 +#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 +#define GL_UNIFORM_TYPE 0x8A37 +#define GL_UNIFORM_SIZE 0x8A38 +#define GL_UNIFORM_NAME_LENGTH 0x8A39 +#define GL_UNIFORM_BLOCK_INDEX 0x8A3A +#define GL_UNIFORM_OFFSET 0x8A3B +#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C +#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D +#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E +#define GL_UNIFORM_BLOCK_BINDING 0x8A3F +#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 +#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 +#define GL_INVALID_INDEX 0xFFFFFFFFu +typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instancecount); +typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount); +typedef void (APIENTRYP PFNGLTEXBUFFERPROC) (GLenum target, GLenum internalformat, GLuint buffer); +typedef void (APIENTRYP PFNGLPRIMITIVERESTARTINDEXPROC) (GLuint index); +typedef void (APIENTRYP PFNGLCOPYBUFFERSUBDATAPROC) (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +typedef void (APIENTRYP PFNGLGETUNIFORMINDICESPROC) (GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices); +typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMSIVPROC) (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMNAMEPROC) (GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformName); +typedef GLuint (APIENTRYP PFNGLGETUNIFORMBLOCKINDEXPROC) (GLuint program, const GLchar *uniformBlockName); +typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKIVPROC) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName); +typedef void (APIENTRYP PFNGLUNIFORMBLOCKBINDINGPROC) (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawArraysInstanced (GLenum mode, GLint first, GLsizei count, GLsizei instancecount); +GLAPI void APIENTRY glDrawElementsInstanced (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount); +GLAPI void APIENTRY glTexBuffer (GLenum target, GLenum internalformat, GLuint buffer); +GLAPI void APIENTRY glPrimitiveRestartIndex (GLuint index); +GLAPI void APIENTRY glCopyBufferSubData (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +GLAPI void APIENTRY glGetUniformIndices (GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices); +GLAPI void APIENTRY glGetActiveUniformsiv (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetActiveUniformName (GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformName); +GLAPI GLuint APIENTRY glGetUniformBlockIndex (GLuint program, const GLchar *uniformBlockName); +GLAPI void APIENTRY glGetActiveUniformBlockiv (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetActiveUniformBlockName (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName); +GLAPI void APIENTRY glUniformBlockBinding (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); +#endif +#endif /* GL_VERSION_3_1 */ + +#ifndef GL_VERSION_3_2 +#define GL_VERSION_3_2 1 +typedef struct __GLsync *GLsync; +#ifndef GLEXT_64_TYPES_DEFINED +/* This code block is duplicated in glxext.h, so must be protected */ +#define GLEXT_64_TYPES_DEFINED +/* Define int32_t, int64_t, and uint64_t types for UST/MSC */ +/* (as used in the GL_EXT_timer_query extension). */ +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#include +#elif defined(__sun__) || defined(__digital__) +#include +#if defined(__STDC__) +#if defined(__arch64__) || defined(_LP64) +typedef long int int64_t; +typedef unsigned long int uint64_t; +#else +typedef long long int int64_t; +typedef unsigned long long int uint64_t; +#endif /* __arch64__ */ +#endif /* __STDC__ */ +#elif defined( __VMS ) || defined(__sgi) +#include +#elif defined(__SCO__) || defined(__USLC__) +#include +#elif defined(__UNIXOS2__) || defined(__SOL64__) +typedef long int int32_t; +typedef long long int int64_t; +typedef unsigned long long int uint64_t; +#elif defined(_WIN32) && defined(__GNUC__) +#include +#elif defined(_WIN32) +typedef __int32 int32_t; +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +#else +/* Fallback if nothing above works */ +#include +#endif +#endif +typedef uint64_t GLuint64; +typedef int64_t GLint64; +#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001 +#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002 +#define GL_LINES_ADJACENCY 0x000A +#define GL_LINE_STRIP_ADJACENCY 0x000B +#define GL_TRIANGLES_ADJACENCY 0x000C +#define GL_TRIANGLE_STRIP_ADJACENCY 0x000D +#define GL_PROGRAM_POINT_SIZE 0x8642 +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8 +#define GL_GEOMETRY_SHADER 0x8DD9 +#define GL_GEOMETRY_VERTICES_OUT 0x8916 +#define GL_GEOMETRY_INPUT_TYPE 0x8917 +#define GL_GEOMETRY_OUTPUT_TYPE 0x8918 +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1 +#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 +#define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123 +#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124 +#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 +#define GL_CONTEXT_PROFILE_MASK 0x9126 +#define GL_DEPTH_CLAMP 0x864F +#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C +#define GL_FIRST_VERTEX_CONVENTION 0x8E4D +#define GL_LAST_VERTEX_CONVENTION 0x8E4E +#define GL_PROVOKING_VERTEX 0x8E4F +#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F +#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111 +#define GL_OBJECT_TYPE 0x9112 +#define GL_SYNC_CONDITION 0x9113 +#define GL_SYNC_STATUS 0x9114 +#define GL_SYNC_FLAGS 0x9115 +#define GL_SYNC_FENCE 0x9116 +#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 +#define GL_UNSIGNALED 0x9118 +#define GL_SIGNALED 0x9119 +#define GL_ALREADY_SIGNALED 0x911A +#define GL_TIMEOUT_EXPIRED 0x911B +#define GL_CONDITION_SATISFIED 0x911C +#define GL_WAIT_FAILED 0x911D +#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull +#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 +#define GL_SAMPLE_POSITION 0x8E50 +#define GL_SAMPLE_MASK 0x8E51 +#define GL_SAMPLE_MASK_VALUE 0x8E52 +#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59 +#define GL_TEXTURE_2D_MULTISAMPLE 0x9100 +#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101 +#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102 +#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105 +#define GL_TEXTURE_SAMPLES 0x9106 +#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107 +#define GL_SAMPLER_2D_MULTISAMPLE 0x9108 +#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A +#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B +#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D +#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E +#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F +#define GL_MAX_INTEGER_SAMPLES 0x9110 +typedef void (APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex); +typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex); +typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex); +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount, const GLint *basevertex); +typedef void (APIENTRYP PFNGLPROVOKINGVERTEXPROC) (GLenum mode); +typedef GLsync (APIENTRYP PFNGLFENCESYNCPROC) (GLenum condition, GLbitfield flags); +typedef GLboolean (APIENTRYP PFNGLISSYNCPROC) (GLsync sync); +typedef void (APIENTRYP PFNGLDELETESYNCPROC) (GLsync sync); +typedef GLenum (APIENTRYP PFNGLCLIENTWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); +typedef void (APIENTRYP PFNGLWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); +typedef void (APIENTRYP PFNGLGETINTEGER64VPROC) (GLenum pname, GLint64 *data); +typedef void (APIENTRYP PFNGLGETSYNCIVPROC) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); +typedef void (APIENTRYP PFNGLGETINTEGER64I_VPROC) (GLenum target, GLuint index, GLint64 *data); +typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERI64VPROC) (GLenum target, GLenum pname, GLint64 *params); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLTEXIMAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +typedef void (APIENTRYP PFNGLTEXIMAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +typedef void (APIENTRYP PFNGLGETMULTISAMPLEFVPROC) (GLenum pname, GLuint index, GLfloat *val); +typedef void (APIENTRYP PFNGLSAMPLEMASKIPROC) (GLuint maskNumber, GLbitfield mask); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawElementsBaseVertex (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex); +GLAPI void APIENTRY glDrawRangeElementsBaseVertex (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex); +GLAPI void APIENTRY glDrawElementsInstancedBaseVertex (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex); +GLAPI void APIENTRY glMultiDrawElementsBaseVertex (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount, const GLint *basevertex); +GLAPI void APIENTRY glProvokingVertex (GLenum mode); +GLAPI GLsync APIENTRY glFenceSync (GLenum condition, GLbitfield flags); +GLAPI GLboolean APIENTRY glIsSync (GLsync sync); +GLAPI void APIENTRY glDeleteSync (GLsync sync); +GLAPI GLenum APIENTRY glClientWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout); +GLAPI void APIENTRY glWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout); +GLAPI void APIENTRY glGetInteger64v (GLenum pname, GLint64 *data); +GLAPI void APIENTRY glGetSynciv (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); +GLAPI void APIENTRY glGetInteger64i_v (GLenum target, GLuint index, GLint64 *data); +GLAPI void APIENTRY glGetBufferParameteri64v (GLenum target, GLenum pname, GLint64 *params); +GLAPI void APIENTRY glFramebufferTexture (GLenum target, GLenum attachment, GLuint texture, GLint level); +GLAPI void APIENTRY glTexImage2DMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +GLAPI void APIENTRY glTexImage3DMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +GLAPI void APIENTRY glGetMultisamplefv (GLenum pname, GLuint index, GLfloat *val); +GLAPI void APIENTRY glSampleMaski (GLuint maskNumber, GLbitfield mask); +#endif +#endif /* GL_VERSION_3_2 */ + +#ifndef GL_VERSION_3_3 +#define GL_VERSION_3_3 1 +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE +#define GL_SRC1_COLOR 0x88F9 +#define GL_ONE_MINUS_SRC1_COLOR 0x88FA +#define GL_ONE_MINUS_SRC1_ALPHA 0x88FB +#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS 0x88FC +#define GL_ANY_SAMPLES_PASSED 0x8C2F +#define GL_SAMPLER_BINDING 0x8919 +#define GL_RGB10_A2UI 0x906F +#define GL_TEXTURE_SWIZZLE_R 0x8E42 +#define GL_TEXTURE_SWIZZLE_G 0x8E43 +#define GL_TEXTURE_SWIZZLE_B 0x8E44 +#define GL_TEXTURE_SWIZZLE_A 0x8E45 +#define GL_TEXTURE_SWIZZLE_RGBA 0x8E46 +#define GL_TIME_ELAPSED 0x88BF +#define GL_TIMESTAMP 0x8E28 +#define GL_INT_2_10_10_10_REV 0x8D9F +typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONINDEXEDPROC) (GLuint program, GLuint colorNumber, GLuint index, const GLchar *name); +typedef GLint (APIENTRYP PFNGLGETFRAGDATAINDEXPROC) (GLuint program, const GLchar *name); +typedef void (APIENTRYP PFNGLGENSAMPLERSPROC) (GLsizei count, GLuint *samplers); +typedef void (APIENTRYP PFNGLDELETESAMPLERSPROC) (GLsizei count, const GLuint *samplers); +typedef GLboolean (APIENTRYP PFNGLISSAMPLERPROC) (GLuint sampler); +typedef void (APIENTRYP PFNGLBINDSAMPLERPROC) (GLuint unit, GLuint sampler); +typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIPROC) (GLuint sampler, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, const GLint *param); +typedef void (APIENTRYP PFNGLSAMPLERPARAMETERFPROC) (GLuint sampler, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, const GLfloat *param); +typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, const GLint *param); +typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, const GLuint *param); +typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, GLuint *params); +typedef void (APIENTRYP PFNGLQUERYCOUNTERPROC) (GLuint id, GLenum target); +typedef void (APIENTRYP PFNGLGETQUERYOBJECTI64VPROC) (GLuint id, GLenum pname, GLint64 *params); +typedef void (APIENTRYP PFNGLGETQUERYOBJECTUI64VPROC) (GLuint id, GLenum pname, GLuint64 *params); +typedef void (APIENTRYP PFNGLVERTEXATTRIBDIVISORPROC) (GLuint index, GLuint divisor); +typedef void (APIENTRYP PFNGLVERTEXATTRIBP1UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); +typedef void (APIENTRYP PFNGLVERTEXATTRIBP1UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); +typedef void (APIENTRYP PFNGLVERTEXATTRIBP2UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); +typedef void (APIENTRYP PFNGLVERTEXATTRIBP2UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); +typedef void (APIENTRYP PFNGLVERTEXATTRIBP3UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); +typedef void (APIENTRYP PFNGLVERTEXATTRIBP3UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); +typedef void (APIENTRYP PFNGLVERTEXATTRIBP4UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); +typedef void (APIENTRYP PFNGLVERTEXATTRIBP4UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); +typedef void (APIENTRYP PFNGLVERTEXP2UIPROC) (GLenum type, GLuint value); +typedef void (APIENTRYP PFNGLVERTEXP2UIVPROC) (GLenum type, const GLuint *value); +typedef void (APIENTRYP PFNGLVERTEXP3UIPROC) (GLenum type, GLuint value); +typedef void (APIENTRYP PFNGLVERTEXP3UIVPROC) (GLenum type, const GLuint *value); +typedef void (APIENTRYP PFNGLVERTEXP4UIPROC) (GLenum type, GLuint value); +typedef void (APIENTRYP PFNGLVERTEXP4UIVPROC) (GLenum type, const GLuint *value); +typedef void (APIENTRYP PFNGLTEXCOORDP1UIPROC) (GLenum type, GLuint coords); +typedef void (APIENTRYP PFNGLTEXCOORDP1UIVPROC) (GLenum type, const GLuint *coords); +typedef void (APIENTRYP PFNGLTEXCOORDP2UIPROC) (GLenum type, GLuint coords); +typedef void (APIENTRYP PFNGLTEXCOORDP2UIVPROC) (GLenum type, const GLuint *coords); +typedef void (APIENTRYP PFNGLTEXCOORDP3UIPROC) (GLenum type, GLuint coords); +typedef void (APIENTRYP PFNGLTEXCOORDP3UIVPROC) (GLenum type, const GLuint *coords); +typedef void (APIENTRYP PFNGLTEXCOORDP4UIPROC) (GLenum type, GLuint coords); +typedef void (APIENTRYP PFNGLTEXCOORDP4UIVPROC) (GLenum type, const GLuint *coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORDP1UIPROC) (GLenum texture, GLenum type, GLuint coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORDP1UIVPROC) (GLenum texture, GLenum type, const GLuint *coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORDP2UIPROC) (GLenum texture, GLenum type, GLuint coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORDP2UIVPROC) (GLenum texture, GLenum type, const GLuint *coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORDP3UIPROC) (GLenum texture, GLenum type, GLuint coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORDP3UIVPROC) (GLenum texture, GLenum type, const GLuint *coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORDP4UIPROC) (GLenum texture, GLenum type, GLuint coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORDP4UIVPROC) (GLenum texture, GLenum type, const GLuint *coords); +typedef void (APIENTRYP PFNGLNORMALP3UIPROC) (GLenum type, GLuint coords); +typedef void (APIENTRYP PFNGLNORMALP3UIVPROC) (GLenum type, const GLuint *coords); +typedef void (APIENTRYP PFNGLCOLORP3UIPROC) (GLenum type, GLuint color); +typedef void (APIENTRYP PFNGLCOLORP3UIVPROC) (GLenum type, const GLuint *color); +typedef void (APIENTRYP PFNGLCOLORP4UIPROC) (GLenum type, GLuint color); +typedef void (APIENTRYP PFNGLCOLORP4UIVPROC) (GLenum type, const GLuint *color); +typedef void (APIENTRYP PFNGLSECONDARYCOLORP3UIPROC) (GLenum type, GLuint color); +typedef void (APIENTRYP PFNGLSECONDARYCOLORP3UIVPROC) (GLenum type, const GLuint *color); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBindFragDataLocationIndexed (GLuint program, GLuint colorNumber, GLuint index, const GLchar *name); +GLAPI GLint APIENTRY glGetFragDataIndex (GLuint program, const GLchar *name); +GLAPI void APIENTRY glGenSamplers (GLsizei count, GLuint *samplers); +GLAPI void APIENTRY glDeleteSamplers (GLsizei count, const GLuint *samplers); +GLAPI GLboolean APIENTRY glIsSampler (GLuint sampler); +GLAPI void APIENTRY glBindSampler (GLuint unit, GLuint sampler); +GLAPI void APIENTRY glSamplerParameteri (GLuint sampler, GLenum pname, GLint param); +GLAPI void APIENTRY glSamplerParameteriv (GLuint sampler, GLenum pname, const GLint *param); +GLAPI void APIENTRY glSamplerParameterf (GLuint sampler, GLenum pname, GLfloat param); +GLAPI void APIENTRY glSamplerParameterfv (GLuint sampler, GLenum pname, const GLfloat *param); +GLAPI void APIENTRY glSamplerParameterIiv (GLuint sampler, GLenum pname, const GLint *param); +GLAPI void APIENTRY glSamplerParameterIuiv (GLuint sampler, GLenum pname, const GLuint *param); +GLAPI void APIENTRY glGetSamplerParameteriv (GLuint sampler, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetSamplerParameterIiv (GLuint sampler, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetSamplerParameterfv (GLuint sampler, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetSamplerParameterIuiv (GLuint sampler, GLenum pname, GLuint *params); +GLAPI void APIENTRY glQueryCounter (GLuint id, GLenum target); +GLAPI void APIENTRY glGetQueryObjecti64v (GLuint id, GLenum pname, GLint64 *params); +GLAPI void APIENTRY glGetQueryObjectui64v (GLuint id, GLenum pname, GLuint64 *params); +GLAPI void APIENTRY glVertexAttribDivisor (GLuint index, GLuint divisor); +GLAPI void APIENTRY glVertexAttribP1ui (GLuint index, GLenum type, GLboolean normalized, GLuint value); +GLAPI void APIENTRY glVertexAttribP1uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); +GLAPI void APIENTRY glVertexAttribP2ui (GLuint index, GLenum type, GLboolean normalized, GLuint value); +GLAPI void APIENTRY glVertexAttribP2uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); +GLAPI void APIENTRY glVertexAttribP3ui (GLuint index, GLenum type, GLboolean normalized, GLuint value); +GLAPI void APIENTRY glVertexAttribP3uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); +GLAPI void APIENTRY glVertexAttribP4ui (GLuint index, GLenum type, GLboolean normalized, GLuint value); +GLAPI void APIENTRY glVertexAttribP4uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); +GLAPI void APIENTRY glVertexP2ui (GLenum type, GLuint value); +GLAPI void APIENTRY glVertexP2uiv (GLenum type, const GLuint *value); +GLAPI void APIENTRY glVertexP3ui (GLenum type, GLuint value); +GLAPI void APIENTRY glVertexP3uiv (GLenum type, const GLuint *value); +GLAPI void APIENTRY glVertexP4ui (GLenum type, GLuint value); +GLAPI void APIENTRY glVertexP4uiv (GLenum type, const GLuint *value); +GLAPI void APIENTRY glTexCoordP1ui (GLenum type, GLuint coords); +GLAPI void APIENTRY glTexCoordP1uiv (GLenum type, const GLuint *coords); +GLAPI void APIENTRY glTexCoordP2ui (GLenum type, GLuint coords); +GLAPI void APIENTRY glTexCoordP2uiv (GLenum type, const GLuint *coords); +GLAPI void APIENTRY glTexCoordP3ui (GLenum type, GLuint coords); +GLAPI void APIENTRY glTexCoordP3uiv (GLenum type, const GLuint *coords); +GLAPI void APIENTRY glTexCoordP4ui (GLenum type, GLuint coords); +GLAPI void APIENTRY glTexCoordP4uiv (GLenum type, const GLuint *coords); +GLAPI void APIENTRY glMultiTexCoordP1ui (GLenum texture, GLenum type, GLuint coords); +GLAPI void APIENTRY glMultiTexCoordP1uiv (GLenum texture, GLenum type, const GLuint *coords); +GLAPI void APIENTRY glMultiTexCoordP2ui (GLenum texture, GLenum type, GLuint coords); +GLAPI void APIENTRY glMultiTexCoordP2uiv (GLenum texture, GLenum type, const GLuint *coords); +GLAPI void APIENTRY glMultiTexCoordP3ui (GLenum texture, GLenum type, GLuint coords); +GLAPI void APIENTRY glMultiTexCoordP3uiv (GLenum texture, GLenum type, const GLuint *coords); +GLAPI void APIENTRY glMultiTexCoordP4ui (GLenum texture, GLenum type, GLuint coords); +GLAPI void APIENTRY glMultiTexCoordP4uiv (GLenum texture, GLenum type, const GLuint *coords); +GLAPI void APIENTRY glNormalP3ui (GLenum type, GLuint coords); +GLAPI void APIENTRY glNormalP3uiv (GLenum type, const GLuint *coords); +GLAPI void APIENTRY glColorP3ui (GLenum type, GLuint color); +GLAPI void APIENTRY glColorP3uiv (GLenum type, const GLuint *color); +GLAPI void APIENTRY glColorP4ui (GLenum type, GLuint color); +GLAPI void APIENTRY glColorP4uiv (GLenum type, const GLuint *color); +GLAPI void APIENTRY glSecondaryColorP3ui (GLenum type, GLuint color); +GLAPI void APIENTRY glSecondaryColorP3uiv (GLenum type, const GLuint *color); +#endif +#endif /* GL_VERSION_3_3 */ + +#ifndef GL_VERSION_4_0 +#define GL_VERSION_4_0 1 +#define GL_SAMPLE_SHADING 0x8C36 +#define GL_MIN_SAMPLE_SHADING_VALUE 0x8C37 +#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E +#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F +#define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A +#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY 0x900B +#define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C +#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D +#define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E +#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F +#define GL_DRAW_INDIRECT_BUFFER 0x8F3F +#define GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43 +#define GL_GEOMETRY_SHADER_INVOCATIONS 0x887F +#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS 0x8E5A +#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET 0x8E5B +#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET 0x8E5C +#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS 0x8E5D +#define GL_MAX_VERTEX_STREAMS 0x8E71 +#define GL_DOUBLE_VEC2 0x8FFC +#define GL_DOUBLE_VEC3 0x8FFD +#define GL_DOUBLE_VEC4 0x8FFE +#define GL_DOUBLE_MAT2 0x8F46 +#define GL_DOUBLE_MAT3 0x8F47 +#define GL_DOUBLE_MAT4 0x8F48 +#define GL_DOUBLE_MAT2x3 0x8F49 +#define GL_DOUBLE_MAT2x4 0x8F4A +#define GL_DOUBLE_MAT3x2 0x8F4B +#define GL_DOUBLE_MAT3x4 0x8F4C +#define GL_DOUBLE_MAT4x2 0x8F4D +#define GL_DOUBLE_MAT4x3 0x8F4E +#define GL_ACTIVE_SUBROUTINES 0x8DE5 +#define GL_ACTIVE_SUBROUTINE_UNIFORMS 0x8DE6 +#define GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS 0x8E47 +#define GL_ACTIVE_SUBROUTINE_MAX_LENGTH 0x8E48 +#define GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH 0x8E49 +#define GL_MAX_SUBROUTINES 0x8DE7 +#define GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS 0x8DE8 +#define GL_NUM_COMPATIBLE_SUBROUTINES 0x8E4A +#define GL_COMPATIBLE_SUBROUTINES 0x8E4B +#define GL_PATCHES 0x000E +#define GL_PATCH_VERTICES 0x8E72 +#define GL_PATCH_DEFAULT_INNER_LEVEL 0x8E73 +#define GL_PATCH_DEFAULT_OUTER_LEVEL 0x8E74 +#define GL_TESS_CONTROL_OUTPUT_VERTICES 0x8E75 +#define GL_TESS_GEN_MODE 0x8E76 +#define GL_TESS_GEN_SPACING 0x8E77 +#define GL_TESS_GEN_VERTEX_ORDER 0x8E78 +#define GL_TESS_GEN_POINT_MODE 0x8E79 +#define GL_ISOLINES 0x8E7A +#define GL_FRACTIONAL_ODD 0x8E7B +#define GL_FRACTIONAL_EVEN 0x8E7C +#define GL_MAX_PATCH_VERTICES 0x8E7D +#define GL_MAX_TESS_GEN_LEVEL 0x8E7E +#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E7F +#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E80 +#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS 0x8E81 +#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS 0x8E82 +#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS 0x8E83 +#define GL_MAX_TESS_PATCH_COMPONENTS 0x8E84 +#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS 0x8E85 +#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS 0x8E86 +#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS 0x8E89 +#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS 0x8E8A +#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS 0x886C +#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS 0x886D +#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E1E +#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E1F +#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER 0x84F0 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER 0x84F1 +#define GL_TESS_EVALUATION_SHADER 0x8E87 +#define GL_TESS_CONTROL_SHADER 0x8E88 +#define GL_TRANSFORM_FEEDBACK 0x8E22 +#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED 0x8E23 +#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE 0x8E24 +#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25 +#define GL_MAX_TRANSFORM_FEEDBACK_BUFFERS 0x8E70 +typedef void (APIENTRYP PFNGLMINSAMPLESHADINGPROC) (GLfloat value); +typedef void (APIENTRYP PFNGLBLENDEQUATIONIPROC) (GLuint buf, GLenum mode); +typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEIPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); +typedef void (APIENTRYP PFNGLBLENDFUNCIPROC) (GLuint buf, GLenum src, GLenum dst); +typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEIPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +typedef void (APIENTRYP PFNGLDRAWARRAYSINDIRECTPROC) (GLenum mode, const void *indirect); +typedef void (APIENTRYP PFNGLDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const void *indirect); +typedef void (APIENTRYP PFNGLUNIFORM1DPROC) (GLint location, GLdouble x); +typedef void (APIENTRYP PFNGLUNIFORM2DPROC) (GLint location, GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLUNIFORM3DPROC) (GLint location, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLUNIFORM4DPROC) (GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLUNIFORM1DVPROC) (GLint location, GLsizei count, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORM2DVPROC) (GLint location, GLsizei count, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORM3DVPROC) (GLint location, GLsizei count, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORM4DVPROC) (GLint location, GLsizei count, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLGETUNIFORMDVPROC) (GLuint program, GLint location, GLdouble *params); +typedef GLint (APIENTRYP PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC) (GLuint program, GLenum shadertype, const GLchar *name); +typedef GLuint (APIENTRYP PFNGLGETSUBROUTINEINDEXPROC) (GLuint program, GLenum shadertype, const GLchar *name); +typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC) (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint *values); +typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); +typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINENAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); +typedef void (APIENTRYP PFNGLUNIFORMSUBROUTINESUIVPROC) (GLenum shadertype, GLsizei count, const GLuint *indices); +typedef void (APIENTRYP PFNGLGETUNIFORMSUBROUTINEUIVPROC) (GLenum shadertype, GLint location, GLuint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMSTAGEIVPROC) (GLuint program, GLenum shadertype, GLenum pname, GLint *values); +typedef void (APIENTRYP PFNGLPATCHPARAMETERIPROC) (GLenum pname, GLint value); +typedef void (APIENTRYP PFNGLPATCHPARAMETERFVPROC) (GLenum pname, const GLfloat *values); +typedef void (APIENTRYP PFNGLBINDTRANSFORMFEEDBACKPROC) (GLenum target, GLuint id); +typedef void (APIENTRYP PFNGLDELETETRANSFORMFEEDBACKSPROC) (GLsizei n, const GLuint *ids); +typedef void (APIENTRYP PFNGLGENTRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint *ids); +typedef GLboolean (APIENTRYP PFNGLISTRANSFORMFEEDBACKPROC) (GLuint id); +typedef void (APIENTRYP PFNGLPAUSETRANSFORMFEEDBACKPROC) (void); +typedef void (APIENTRYP PFNGLRESUMETRANSFORMFEEDBACKPROC) (void); +typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKPROC) (GLenum mode, GLuint id); +typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC) (GLenum mode, GLuint id, GLuint stream); +typedef void (APIENTRYP PFNGLBEGINQUERYINDEXEDPROC) (GLenum target, GLuint index, GLuint id); +typedef void (APIENTRYP PFNGLENDQUERYINDEXEDPROC) (GLenum target, GLuint index); +typedef void (APIENTRYP PFNGLGETQUERYINDEXEDIVPROC) (GLenum target, GLuint index, GLenum pname, GLint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMinSampleShading (GLfloat value); +GLAPI void APIENTRY glBlendEquationi (GLuint buf, GLenum mode); +GLAPI void APIENTRY glBlendEquationSeparatei (GLuint buf, GLenum modeRGB, GLenum modeAlpha); +GLAPI void APIENTRY glBlendFunci (GLuint buf, GLenum src, GLenum dst); +GLAPI void APIENTRY glBlendFuncSeparatei (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +GLAPI void APIENTRY glDrawArraysIndirect (GLenum mode, const void *indirect); +GLAPI void APIENTRY glDrawElementsIndirect (GLenum mode, GLenum type, const void *indirect); +GLAPI void APIENTRY glUniform1d (GLint location, GLdouble x); +GLAPI void APIENTRY glUniform2d (GLint location, GLdouble x, GLdouble y); +GLAPI void APIENTRY glUniform3d (GLint location, GLdouble x, GLdouble y, GLdouble z); +GLAPI void APIENTRY glUniform4d (GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void APIENTRY glUniform1dv (GLint location, GLsizei count, const GLdouble *value); +GLAPI void APIENTRY glUniform2dv (GLint location, GLsizei count, const GLdouble *value); +GLAPI void APIENTRY glUniform3dv (GLint location, GLsizei count, const GLdouble *value); +GLAPI void APIENTRY glUniform4dv (GLint location, GLsizei count, const GLdouble *value); +GLAPI void APIENTRY glUniformMatrix2dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glUniformMatrix3dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glUniformMatrix4dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glUniformMatrix2x3dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glUniformMatrix2x4dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glUniformMatrix3x2dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glUniformMatrix3x4dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glUniformMatrix4x2dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glUniformMatrix4x3dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glGetUniformdv (GLuint program, GLint location, GLdouble *params); +GLAPI GLint APIENTRY glGetSubroutineUniformLocation (GLuint program, GLenum shadertype, const GLchar *name); +GLAPI GLuint APIENTRY glGetSubroutineIndex (GLuint program, GLenum shadertype, const GLchar *name); +GLAPI void APIENTRY glGetActiveSubroutineUniformiv (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint *values); +GLAPI void APIENTRY glGetActiveSubroutineUniformName (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); +GLAPI void APIENTRY glGetActiveSubroutineName (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); +GLAPI void APIENTRY glUniformSubroutinesuiv (GLenum shadertype, GLsizei count, const GLuint *indices); +GLAPI void APIENTRY glGetUniformSubroutineuiv (GLenum shadertype, GLint location, GLuint *params); +GLAPI void APIENTRY glGetProgramStageiv (GLuint program, GLenum shadertype, GLenum pname, GLint *values); +GLAPI void APIENTRY glPatchParameteri (GLenum pname, GLint value); +GLAPI void APIENTRY glPatchParameterfv (GLenum pname, const GLfloat *values); +GLAPI void APIENTRY glBindTransformFeedback (GLenum target, GLuint id); +GLAPI void APIENTRY glDeleteTransformFeedbacks (GLsizei n, const GLuint *ids); +GLAPI void APIENTRY glGenTransformFeedbacks (GLsizei n, GLuint *ids); +GLAPI GLboolean APIENTRY glIsTransformFeedback (GLuint id); +GLAPI void APIENTRY glPauseTransformFeedback (void); +GLAPI void APIENTRY glResumeTransformFeedback (void); +GLAPI void APIENTRY glDrawTransformFeedback (GLenum mode, GLuint id); +GLAPI void APIENTRY glDrawTransformFeedbackStream (GLenum mode, GLuint id, GLuint stream); +GLAPI void APIENTRY glBeginQueryIndexed (GLenum target, GLuint index, GLuint id); +GLAPI void APIENTRY glEndQueryIndexed (GLenum target, GLuint index); +GLAPI void APIENTRY glGetQueryIndexediv (GLenum target, GLuint index, GLenum pname, GLint *params); +#endif +#endif /* GL_VERSION_4_0 */ + +#ifndef GL_VERSION_4_1 +#define GL_VERSION_4_1 1 +#define GL_FIXED 0x140C +#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B +#define GL_LOW_FLOAT 0x8DF0 +#define GL_MEDIUM_FLOAT 0x8DF1 +#define GL_HIGH_FLOAT 0x8DF2 +#define GL_LOW_INT 0x8DF3 +#define GL_MEDIUM_INT 0x8DF4 +#define GL_HIGH_INT 0x8DF5 +#define GL_SHADER_COMPILER 0x8DFA +#define GL_SHADER_BINARY_FORMATS 0x8DF8 +#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 +#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB +#define GL_MAX_VARYING_VECTORS 0x8DFC +#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD +#define GL_RGB565 0x8D62 +#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257 +#define GL_PROGRAM_BINARY_LENGTH 0x8741 +#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE +#define GL_PROGRAM_BINARY_FORMATS 0x87FF +#define GL_VERTEX_SHADER_BIT 0x00000001 +#define GL_FRAGMENT_SHADER_BIT 0x00000002 +#define GL_GEOMETRY_SHADER_BIT 0x00000004 +#define GL_TESS_CONTROL_SHADER_BIT 0x00000008 +#define GL_TESS_EVALUATION_SHADER_BIT 0x00000010 +#define GL_ALL_SHADER_BITS 0xFFFFFFFF +#define GL_PROGRAM_SEPARABLE 0x8258 +#define GL_ACTIVE_PROGRAM 0x8259 +#define GL_PROGRAM_PIPELINE_BINDING 0x825A +#define GL_MAX_VIEWPORTS 0x825B +#define GL_VIEWPORT_SUBPIXEL_BITS 0x825C +#define GL_VIEWPORT_BOUNDS_RANGE 0x825D +#define GL_LAYER_PROVOKING_VERTEX 0x825E +#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX 0x825F +#define GL_UNDEFINED_VERTEX 0x8260 +typedef void (APIENTRYP PFNGLRELEASESHADERCOMPILERPROC) (void); +typedef void (APIENTRYP PFNGLSHADERBINARYPROC) (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length); +typedef void (APIENTRYP PFNGLGETSHADERPRECISIONFORMATPROC) (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision); +typedef void (APIENTRYP PFNGLDEPTHRANGEFPROC) (GLfloat n, GLfloat f); +typedef void (APIENTRYP PFNGLCLEARDEPTHFPROC) (GLfloat d); +typedef void (APIENTRYP PFNGLGETPROGRAMBINARYPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary); +typedef void (APIENTRYP PFNGLPROGRAMBINARYPROC) (GLuint program, GLenum binaryFormat, const void *binary, GLsizei length); +typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIPROC) (GLuint program, GLenum pname, GLint value); +typedef void (APIENTRYP PFNGLUSEPROGRAMSTAGESPROC) (GLuint pipeline, GLbitfield stages, GLuint program); +typedef void (APIENTRYP PFNGLACTIVESHADERPROGRAMPROC) (GLuint pipeline, GLuint program); +typedef GLuint (APIENTRYP PFNGLCREATESHADERPROGRAMVPROC) (GLenum type, GLsizei count, const GLchar *const*strings); +typedef void (APIENTRYP PFNGLBINDPROGRAMPIPELINEPROC) (GLuint pipeline); +typedef void (APIENTRYP PFNGLDELETEPROGRAMPIPELINESPROC) (GLsizei n, const GLuint *pipelines); +typedef void (APIENTRYP PFNGLGENPROGRAMPIPELINESPROC) (GLsizei n, GLuint *pipelines); +typedef GLboolean (APIENTRYP PFNGLISPROGRAMPIPELINEPROC) (GLuint pipeline); +typedef void (APIENTRYP PFNGLGETPROGRAMPIPELINEIVPROC) (GLuint pipeline, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IPROC) (GLuint program, GLint location, GLint v0); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FPROC) (GLuint program, GLint location, GLfloat v0); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DPROC) (GLuint program, GLint location, GLdouble v0); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIPROC) (GLuint program, GLint location, GLuint v0); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IPROC) (GLuint program, GLint location, GLint v0, GLint v1); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPIPELINEPROC) (GLuint pipeline); +typedef void (APIENTRYP PFNGLGETPROGRAMPIPELINEINFOLOGPROC) (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DPROC) (GLuint index, GLdouble x); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBLPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLDVPROC) (GLuint index, GLenum pname, GLdouble *params); +typedef void (APIENTRYP PFNGLVIEWPORTARRAYVPROC) (GLuint first, GLsizei count, const GLfloat *v); +typedef void (APIENTRYP PFNGLVIEWPORTINDEXEDFPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); +typedef void (APIENTRYP PFNGLVIEWPORTINDEXEDFVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLSCISSORARRAYVPROC) (GLuint first, GLsizei count, const GLint *v); +typedef void (APIENTRYP PFNGLSCISSORINDEXEDPROC) (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLSCISSORINDEXEDVPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLDEPTHRANGEARRAYVPROC) (GLuint first, GLsizei count, const GLdouble *v); +typedef void (APIENTRYP PFNGLDEPTHRANGEINDEXEDPROC) (GLuint index, GLdouble n, GLdouble f); +typedef void (APIENTRYP PFNGLGETFLOATI_VPROC) (GLenum target, GLuint index, GLfloat *data); +typedef void (APIENTRYP PFNGLGETDOUBLEI_VPROC) (GLenum target, GLuint index, GLdouble *data); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glReleaseShaderCompiler (void); +GLAPI void APIENTRY glShaderBinary (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length); +GLAPI void APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision); +GLAPI void APIENTRY glDepthRangef (GLfloat n, GLfloat f); +GLAPI void APIENTRY glClearDepthf (GLfloat d); +GLAPI void APIENTRY glGetProgramBinary (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary); +GLAPI void APIENTRY glProgramBinary (GLuint program, GLenum binaryFormat, const void *binary, GLsizei length); +GLAPI void APIENTRY glProgramParameteri (GLuint program, GLenum pname, GLint value); +GLAPI void APIENTRY glUseProgramStages (GLuint pipeline, GLbitfield stages, GLuint program); +GLAPI void APIENTRY glActiveShaderProgram (GLuint pipeline, GLuint program); +GLAPI GLuint APIENTRY glCreateShaderProgramv (GLenum type, GLsizei count, const GLchar *const*strings); +GLAPI void APIENTRY glBindProgramPipeline (GLuint pipeline); +GLAPI void APIENTRY glDeleteProgramPipelines (GLsizei n, const GLuint *pipelines); +GLAPI void APIENTRY glGenProgramPipelines (GLsizei n, GLuint *pipelines); +GLAPI GLboolean APIENTRY glIsProgramPipeline (GLuint pipeline); +GLAPI void APIENTRY glGetProgramPipelineiv (GLuint pipeline, GLenum pname, GLint *params); +GLAPI void APIENTRY glProgramUniform1i (GLuint program, GLint location, GLint v0); +GLAPI void APIENTRY glProgramUniform1iv (GLuint program, GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glProgramUniform1f (GLuint program, GLint location, GLfloat v0); +GLAPI void APIENTRY glProgramUniform1fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glProgramUniform1d (GLuint program, GLint location, GLdouble v0); +GLAPI void APIENTRY glProgramUniform1dv (GLuint program, GLint location, GLsizei count, const GLdouble *value); +GLAPI void APIENTRY glProgramUniform1ui (GLuint program, GLint location, GLuint v0); +GLAPI void APIENTRY glProgramUniform1uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glProgramUniform2i (GLuint program, GLint location, GLint v0, GLint v1); +GLAPI void APIENTRY glProgramUniform2iv (GLuint program, GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glProgramUniform2f (GLuint program, GLint location, GLfloat v0, GLfloat v1); +GLAPI void APIENTRY glProgramUniform2fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glProgramUniform2d (GLuint program, GLint location, GLdouble v0, GLdouble v1); +GLAPI void APIENTRY glProgramUniform2dv (GLuint program, GLint location, GLsizei count, const GLdouble *value); +GLAPI void APIENTRY glProgramUniform2ui (GLuint program, GLint location, GLuint v0, GLuint v1); +GLAPI void APIENTRY glProgramUniform2uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glProgramUniform3i (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); +GLAPI void APIENTRY glProgramUniform3iv (GLuint program, GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glProgramUniform3f (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +GLAPI void APIENTRY glProgramUniform3fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glProgramUniform3d (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2); +GLAPI void APIENTRY glProgramUniform3dv (GLuint program, GLint location, GLsizei count, const GLdouble *value); +GLAPI void APIENTRY glProgramUniform3ui (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); +GLAPI void APIENTRY glProgramUniform3uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glProgramUniform4i (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +GLAPI void APIENTRY glProgramUniform4iv (GLuint program, GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glProgramUniform4f (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +GLAPI void APIENTRY glProgramUniform4fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glProgramUniform4d (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3); +GLAPI void APIENTRY glProgramUniform4dv (GLuint program, GLint location, GLsizei count, const GLdouble *value); +GLAPI void APIENTRY glProgramUniform4ui (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +GLAPI void APIENTRY glProgramUniform4uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glProgramUniformMatrix2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix2dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix3dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix4dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix2x3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix3x2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix2x4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix4x2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix3x4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix4x3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix2x3dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix3x2dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix2x4dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix4x2dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix3x4dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix4x3dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glValidateProgramPipeline (GLuint pipeline); +GLAPI void APIENTRY glGetProgramPipelineInfoLog (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +GLAPI void APIENTRY glVertexAttribL1d (GLuint index, GLdouble x); +GLAPI void APIENTRY glVertexAttribL2d (GLuint index, GLdouble x, GLdouble y); +GLAPI void APIENTRY glVertexAttribL3d (GLuint index, GLdouble x, GLdouble y, GLdouble z); +GLAPI void APIENTRY glVertexAttribL4d (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void APIENTRY glVertexAttribL1dv (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttribL2dv (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttribL3dv (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttribL4dv (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttribLPointer (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); +GLAPI void APIENTRY glGetVertexAttribLdv (GLuint index, GLenum pname, GLdouble *params); +GLAPI void APIENTRY glViewportArrayv (GLuint first, GLsizei count, const GLfloat *v); +GLAPI void APIENTRY glViewportIndexedf (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); +GLAPI void APIENTRY glViewportIndexedfv (GLuint index, const GLfloat *v); +GLAPI void APIENTRY glScissorArrayv (GLuint first, GLsizei count, const GLint *v); +GLAPI void APIENTRY glScissorIndexed (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); +GLAPI void APIENTRY glScissorIndexedv (GLuint index, const GLint *v); +GLAPI void APIENTRY glDepthRangeArrayv (GLuint first, GLsizei count, const GLdouble *v); +GLAPI void APIENTRY glDepthRangeIndexed (GLuint index, GLdouble n, GLdouble f); +GLAPI void APIENTRY glGetFloati_v (GLenum target, GLuint index, GLfloat *data); +GLAPI void APIENTRY glGetDoublei_v (GLenum target, GLuint index, GLdouble *data); +#endif +#endif /* GL_VERSION_4_1 */ + +#ifndef GL_VERSION_4_2 +#define GL_VERSION_4_2 1 +#define GL_UNPACK_COMPRESSED_BLOCK_WIDTH 0x9127 +#define GL_UNPACK_COMPRESSED_BLOCK_HEIGHT 0x9128 +#define GL_UNPACK_COMPRESSED_BLOCK_DEPTH 0x9129 +#define GL_UNPACK_COMPRESSED_BLOCK_SIZE 0x912A +#define GL_PACK_COMPRESSED_BLOCK_WIDTH 0x912B +#define GL_PACK_COMPRESSED_BLOCK_HEIGHT 0x912C +#define GL_PACK_COMPRESSED_BLOCK_DEPTH 0x912D +#define GL_PACK_COMPRESSED_BLOCK_SIZE 0x912E +#define GL_NUM_SAMPLE_COUNTS 0x9380 +#define GL_MIN_MAP_BUFFER_ALIGNMENT 0x90BC +#define GL_ATOMIC_COUNTER_BUFFER 0x92C0 +#define GL_ATOMIC_COUNTER_BUFFER_BINDING 0x92C1 +#define GL_ATOMIC_COUNTER_BUFFER_START 0x92C2 +#define GL_ATOMIC_COUNTER_BUFFER_SIZE 0x92C3 +#define GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE 0x92C4 +#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS 0x92C5 +#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES 0x92C6 +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER 0x92C7 +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER 0x92C8 +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER 0x92C9 +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER 0x92CA +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER 0x92CB +#define GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS 0x92CC +#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS 0x92CD +#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS 0x92CE +#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS 0x92CF +#define GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS 0x92D0 +#define GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS 0x92D1 +#define GL_MAX_VERTEX_ATOMIC_COUNTERS 0x92D2 +#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS 0x92D3 +#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS 0x92D4 +#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS 0x92D5 +#define GL_MAX_FRAGMENT_ATOMIC_COUNTERS 0x92D6 +#define GL_MAX_COMBINED_ATOMIC_COUNTERS 0x92D7 +#define GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE 0x92D8 +#define GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS 0x92DC +#define GL_ACTIVE_ATOMIC_COUNTER_BUFFERS 0x92D9 +#define GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX 0x92DA +#define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB +#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001 +#define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002 +#define GL_UNIFORM_BARRIER_BIT 0x00000004 +#define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008 +#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020 +#define GL_COMMAND_BARRIER_BIT 0x00000040 +#define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080 +#define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100 +#define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200 +#define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400 +#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800 +#define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000 +#define GL_ALL_BARRIER_BITS 0xFFFFFFFF +#define GL_MAX_IMAGE_UNITS 0x8F38 +#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS 0x8F39 +#define GL_IMAGE_BINDING_NAME 0x8F3A +#define GL_IMAGE_BINDING_LEVEL 0x8F3B +#define GL_IMAGE_BINDING_LAYERED 0x8F3C +#define GL_IMAGE_BINDING_LAYER 0x8F3D +#define GL_IMAGE_BINDING_ACCESS 0x8F3E +#define GL_IMAGE_1D 0x904C +#define GL_IMAGE_2D 0x904D +#define GL_IMAGE_3D 0x904E +#define GL_IMAGE_2D_RECT 0x904F +#define GL_IMAGE_CUBE 0x9050 +#define GL_IMAGE_BUFFER 0x9051 +#define GL_IMAGE_1D_ARRAY 0x9052 +#define GL_IMAGE_2D_ARRAY 0x9053 +#define GL_IMAGE_CUBE_MAP_ARRAY 0x9054 +#define GL_IMAGE_2D_MULTISAMPLE 0x9055 +#define GL_IMAGE_2D_MULTISAMPLE_ARRAY 0x9056 +#define GL_INT_IMAGE_1D 0x9057 +#define GL_INT_IMAGE_2D 0x9058 +#define GL_INT_IMAGE_3D 0x9059 +#define GL_INT_IMAGE_2D_RECT 0x905A +#define GL_INT_IMAGE_CUBE 0x905B +#define GL_INT_IMAGE_BUFFER 0x905C +#define GL_INT_IMAGE_1D_ARRAY 0x905D +#define GL_INT_IMAGE_2D_ARRAY 0x905E +#define GL_INT_IMAGE_CUBE_MAP_ARRAY 0x905F +#define GL_INT_IMAGE_2D_MULTISAMPLE 0x9060 +#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x9061 +#define GL_UNSIGNED_INT_IMAGE_1D 0x9062 +#define GL_UNSIGNED_INT_IMAGE_2D 0x9063 +#define GL_UNSIGNED_INT_IMAGE_3D 0x9064 +#define GL_UNSIGNED_INT_IMAGE_2D_RECT 0x9065 +#define GL_UNSIGNED_INT_IMAGE_CUBE 0x9066 +#define GL_UNSIGNED_INT_IMAGE_BUFFER 0x9067 +#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY 0x9068 +#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY 0x9069 +#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY 0x906A +#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE 0x906B +#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x906C +#define GL_MAX_IMAGE_SAMPLES 0x906D +#define GL_IMAGE_BINDING_FORMAT 0x906E +#define GL_IMAGE_FORMAT_COMPATIBILITY_TYPE 0x90C7 +#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE 0x90C8 +#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS 0x90C9 +#define GL_MAX_VERTEX_IMAGE_UNIFORMS 0x90CA +#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS 0x90CB +#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS 0x90CC +#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS 0x90CD +#define GL_MAX_FRAGMENT_IMAGE_UNIFORMS 0x90CE +#define GL_MAX_COMBINED_IMAGE_UNIFORMS 0x90CF +#define GL_COMPRESSED_RGBA_BPTC_UNORM 0x8E8C +#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM 0x8E8D +#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E +#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F +#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F +typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance); +typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance); +typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance); +typedef void (APIENTRYP PFNGLGETINTERNALFORMATIVPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params); +typedef void (APIENTRYP PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC) (GLuint program, GLuint bufferIndex, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLBINDIMAGETEXTUREPROC) (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); +typedef void (APIENTRYP PFNGLMEMORYBARRIERPROC) (GLbitfield barriers); +typedef void (APIENTRYP PFNGLTEXSTORAGE1DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +typedef void (APIENTRYP PFNGLTEXSTORAGE2DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLTEXSTORAGE3DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC) (GLenum mode, GLuint id, GLsizei instancecount); +typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC) (GLenum mode, GLuint id, GLuint stream, GLsizei instancecount); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawArraysInstancedBaseInstance (GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance); +GLAPI void APIENTRY glDrawElementsInstancedBaseInstance (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance); +GLAPI void APIENTRY glDrawElementsInstancedBaseVertexBaseInstance (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance); +GLAPI void APIENTRY glGetInternalformativ (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params); +GLAPI void APIENTRY glGetActiveAtomicCounterBufferiv (GLuint program, GLuint bufferIndex, GLenum pname, GLint *params); +GLAPI void APIENTRY glBindImageTexture (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); +GLAPI void APIENTRY glMemoryBarrier (GLbitfield barriers); +GLAPI void APIENTRY glTexStorage1D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +GLAPI void APIENTRY glTexStorage2D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +GLAPI void APIENTRY glTexStorage3D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +GLAPI void APIENTRY glDrawTransformFeedbackInstanced (GLenum mode, GLuint id, GLsizei instancecount); +GLAPI void APIENTRY glDrawTransformFeedbackStreamInstanced (GLenum mode, GLuint id, GLuint stream, GLsizei instancecount); +#endif +#endif /* GL_VERSION_4_2 */ + +#ifndef GL_VERSION_4_3 +#define GL_VERSION_4_3 1 +typedef void (APIENTRY *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); +#define GL_NUM_SHADING_LANGUAGE_VERSIONS 0x82E9 +#define GL_VERTEX_ATTRIB_ARRAY_LONG 0x874E +#define GL_COMPRESSED_RGB8_ETC2 0x9274 +#define GL_COMPRESSED_SRGB8_ETC2 0x9275 +#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276 +#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277 +#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 +#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279 +#define GL_COMPRESSED_R11_EAC 0x9270 +#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271 +#define GL_COMPRESSED_RG11_EAC 0x9272 +#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273 +#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69 +#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A +#define GL_MAX_ELEMENT_INDEX 0x8D6B +#define GL_COMPUTE_SHADER 0x91B9 +#define GL_MAX_COMPUTE_UNIFORM_BLOCKS 0x91BB +#define GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS 0x91BC +#define GL_MAX_COMPUTE_IMAGE_UNIFORMS 0x91BD +#define GL_MAX_COMPUTE_SHARED_MEMORY_SIZE 0x8262 +#define GL_MAX_COMPUTE_UNIFORM_COMPONENTS 0x8263 +#define GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS 0x8264 +#define GL_MAX_COMPUTE_ATOMIC_COUNTERS 0x8265 +#define GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS 0x8266 +#define GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS 0x90EB +#define GL_MAX_COMPUTE_WORK_GROUP_COUNT 0x91BE +#define GL_MAX_COMPUTE_WORK_GROUP_SIZE 0x91BF +#define GL_COMPUTE_WORK_GROUP_SIZE 0x8267 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER 0x90EC +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER 0x90ED +#define GL_DISPATCH_INDIRECT_BUFFER 0x90EE +#define GL_DISPATCH_INDIRECT_BUFFER_BINDING 0x90EF +#define GL_COMPUTE_SHADER_BIT 0x00000020 +#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242 +#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243 +#define GL_DEBUG_CALLBACK_FUNCTION 0x8244 +#define GL_DEBUG_CALLBACK_USER_PARAM 0x8245 +#define GL_DEBUG_SOURCE_API 0x8246 +#define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247 +#define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248 +#define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249 +#define GL_DEBUG_SOURCE_APPLICATION 0x824A +#define GL_DEBUG_SOURCE_OTHER 0x824B +#define GL_DEBUG_TYPE_ERROR 0x824C +#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D +#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E +#define GL_DEBUG_TYPE_PORTABILITY 0x824F +#define GL_DEBUG_TYPE_PERFORMANCE 0x8250 +#define GL_DEBUG_TYPE_OTHER 0x8251 +#define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143 +#define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144 +#define GL_DEBUG_LOGGED_MESSAGES 0x9145 +#define GL_DEBUG_SEVERITY_HIGH 0x9146 +#define GL_DEBUG_SEVERITY_MEDIUM 0x9147 +#define GL_DEBUG_SEVERITY_LOW 0x9148 +#define GL_DEBUG_TYPE_MARKER 0x8268 +#define GL_DEBUG_TYPE_PUSH_GROUP 0x8269 +#define GL_DEBUG_TYPE_POP_GROUP 0x826A +#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B +#define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C +#define GL_DEBUG_GROUP_STACK_DEPTH 0x826D +#define GL_BUFFER 0x82E0 +#define GL_SHADER 0x82E1 +#define GL_PROGRAM 0x82E2 +#define GL_QUERY 0x82E3 +#define GL_PROGRAM_PIPELINE 0x82E4 +#define GL_SAMPLER 0x82E6 +#define GL_MAX_LABEL_LENGTH 0x82E8 +#define GL_DEBUG_OUTPUT 0x92E0 +#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002 +#define GL_MAX_UNIFORM_LOCATIONS 0x826E +#define GL_FRAMEBUFFER_DEFAULT_WIDTH 0x9310 +#define GL_FRAMEBUFFER_DEFAULT_HEIGHT 0x9311 +#define GL_FRAMEBUFFER_DEFAULT_LAYERS 0x9312 +#define GL_FRAMEBUFFER_DEFAULT_SAMPLES 0x9313 +#define GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS 0x9314 +#define GL_MAX_FRAMEBUFFER_WIDTH 0x9315 +#define GL_MAX_FRAMEBUFFER_HEIGHT 0x9316 +#define GL_MAX_FRAMEBUFFER_LAYERS 0x9317 +#define GL_MAX_FRAMEBUFFER_SAMPLES 0x9318 +#define GL_INTERNALFORMAT_SUPPORTED 0x826F +#define GL_INTERNALFORMAT_PREFERRED 0x8270 +#define GL_INTERNALFORMAT_RED_SIZE 0x8271 +#define GL_INTERNALFORMAT_GREEN_SIZE 0x8272 +#define GL_INTERNALFORMAT_BLUE_SIZE 0x8273 +#define GL_INTERNALFORMAT_ALPHA_SIZE 0x8274 +#define GL_INTERNALFORMAT_DEPTH_SIZE 0x8275 +#define GL_INTERNALFORMAT_STENCIL_SIZE 0x8276 +#define GL_INTERNALFORMAT_SHARED_SIZE 0x8277 +#define GL_INTERNALFORMAT_RED_TYPE 0x8278 +#define GL_INTERNALFORMAT_GREEN_TYPE 0x8279 +#define GL_INTERNALFORMAT_BLUE_TYPE 0x827A +#define GL_INTERNALFORMAT_ALPHA_TYPE 0x827B +#define GL_INTERNALFORMAT_DEPTH_TYPE 0x827C +#define GL_INTERNALFORMAT_STENCIL_TYPE 0x827D +#define GL_MAX_WIDTH 0x827E +#define GL_MAX_HEIGHT 0x827F +#define GL_MAX_DEPTH 0x8280 +#define GL_MAX_LAYERS 0x8281 +#define GL_MAX_COMBINED_DIMENSIONS 0x8282 +#define GL_COLOR_COMPONENTS 0x8283 +#define GL_DEPTH_COMPONENTS 0x8284 +#define GL_STENCIL_COMPONENTS 0x8285 +#define GL_COLOR_RENDERABLE 0x8286 +#define GL_DEPTH_RENDERABLE 0x8287 +#define GL_STENCIL_RENDERABLE 0x8288 +#define GL_FRAMEBUFFER_RENDERABLE 0x8289 +#define GL_FRAMEBUFFER_RENDERABLE_LAYERED 0x828A +#define GL_FRAMEBUFFER_BLEND 0x828B +#define GL_READ_PIXELS 0x828C +#define GL_READ_PIXELS_FORMAT 0x828D +#define GL_READ_PIXELS_TYPE 0x828E +#define GL_TEXTURE_IMAGE_FORMAT 0x828F +#define GL_TEXTURE_IMAGE_TYPE 0x8290 +#define GL_GET_TEXTURE_IMAGE_FORMAT 0x8291 +#define GL_GET_TEXTURE_IMAGE_TYPE 0x8292 +#define GL_MIPMAP 0x8293 +#define GL_MANUAL_GENERATE_MIPMAP 0x8294 +#define GL_AUTO_GENERATE_MIPMAP 0x8295 +#define GL_COLOR_ENCODING 0x8296 +#define GL_SRGB_READ 0x8297 +#define GL_SRGB_WRITE 0x8298 +#define GL_FILTER 0x829A +#define GL_VERTEX_TEXTURE 0x829B +#define GL_TESS_CONTROL_TEXTURE 0x829C +#define GL_TESS_EVALUATION_TEXTURE 0x829D +#define GL_GEOMETRY_TEXTURE 0x829E +#define GL_FRAGMENT_TEXTURE 0x829F +#define GL_COMPUTE_TEXTURE 0x82A0 +#define GL_TEXTURE_SHADOW 0x82A1 +#define GL_TEXTURE_GATHER 0x82A2 +#define GL_TEXTURE_GATHER_SHADOW 0x82A3 +#define GL_SHADER_IMAGE_LOAD 0x82A4 +#define GL_SHADER_IMAGE_STORE 0x82A5 +#define GL_SHADER_IMAGE_ATOMIC 0x82A6 +#define GL_IMAGE_TEXEL_SIZE 0x82A7 +#define GL_IMAGE_COMPATIBILITY_CLASS 0x82A8 +#define GL_IMAGE_PIXEL_FORMAT 0x82A9 +#define GL_IMAGE_PIXEL_TYPE 0x82AA +#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST 0x82AC +#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST 0x82AD +#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE 0x82AE +#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE 0x82AF +#define GL_TEXTURE_COMPRESSED_BLOCK_WIDTH 0x82B1 +#define GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT 0x82B2 +#define GL_TEXTURE_COMPRESSED_BLOCK_SIZE 0x82B3 +#define GL_CLEAR_BUFFER 0x82B4 +#define GL_TEXTURE_VIEW 0x82B5 +#define GL_VIEW_COMPATIBILITY_CLASS 0x82B6 +#define GL_FULL_SUPPORT 0x82B7 +#define GL_CAVEAT_SUPPORT 0x82B8 +#define GL_IMAGE_CLASS_4_X_32 0x82B9 +#define GL_IMAGE_CLASS_2_X_32 0x82BA +#define GL_IMAGE_CLASS_1_X_32 0x82BB +#define GL_IMAGE_CLASS_4_X_16 0x82BC +#define GL_IMAGE_CLASS_2_X_16 0x82BD +#define GL_IMAGE_CLASS_1_X_16 0x82BE +#define GL_IMAGE_CLASS_4_X_8 0x82BF +#define GL_IMAGE_CLASS_2_X_8 0x82C0 +#define GL_IMAGE_CLASS_1_X_8 0x82C1 +#define GL_IMAGE_CLASS_11_11_10 0x82C2 +#define GL_IMAGE_CLASS_10_10_10_2 0x82C3 +#define GL_VIEW_CLASS_128_BITS 0x82C4 +#define GL_VIEW_CLASS_96_BITS 0x82C5 +#define GL_VIEW_CLASS_64_BITS 0x82C6 +#define GL_VIEW_CLASS_48_BITS 0x82C7 +#define GL_VIEW_CLASS_32_BITS 0x82C8 +#define GL_VIEW_CLASS_24_BITS 0x82C9 +#define GL_VIEW_CLASS_16_BITS 0x82CA +#define GL_VIEW_CLASS_8_BITS 0x82CB +#define GL_VIEW_CLASS_S3TC_DXT1_RGB 0x82CC +#define GL_VIEW_CLASS_S3TC_DXT1_RGBA 0x82CD +#define GL_VIEW_CLASS_S3TC_DXT3_RGBA 0x82CE +#define GL_VIEW_CLASS_S3TC_DXT5_RGBA 0x82CF +#define GL_VIEW_CLASS_RGTC1_RED 0x82D0 +#define GL_VIEW_CLASS_RGTC2_RG 0x82D1 +#define GL_VIEW_CLASS_BPTC_UNORM 0x82D2 +#define GL_VIEW_CLASS_BPTC_FLOAT 0x82D3 +#define GL_UNIFORM 0x92E1 +#define GL_UNIFORM_BLOCK 0x92E2 +#define GL_PROGRAM_INPUT 0x92E3 +#define GL_PROGRAM_OUTPUT 0x92E4 +#define GL_BUFFER_VARIABLE 0x92E5 +#define GL_SHADER_STORAGE_BLOCK 0x92E6 +#define GL_VERTEX_SUBROUTINE 0x92E8 +#define GL_TESS_CONTROL_SUBROUTINE 0x92E9 +#define GL_TESS_EVALUATION_SUBROUTINE 0x92EA +#define GL_GEOMETRY_SUBROUTINE 0x92EB +#define GL_FRAGMENT_SUBROUTINE 0x92EC +#define GL_COMPUTE_SUBROUTINE 0x92ED +#define GL_VERTEX_SUBROUTINE_UNIFORM 0x92EE +#define GL_TESS_CONTROL_SUBROUTINE_UNIFORM 0x92EF +#define GL_TESS_EVALUATION_SUBROUTINE_UNIFORM 0x92F0 +#define GL_GEOMETRY_SUBROUTINE_UNIFORM 0x92F1 +#define GL_FRAGMENT_SUBROUTINE_UNIFORM 0x92F2 +#define GL_COMPUTE_SUBROUTINE_UNIFORM 0x92F3 +#define GL_TRANSFORM_FEEDBACK_VARYING 0x92F4 +#define GL_ACTIVE_RESOURCES 0x92F5 +#define GL_MAX_NAME_LENGTH 0x92F6 +#define GL_MAX_NUM_ACTIVE_VARIABLES 0x92F7 +#define GL_MAX_NUM_COMPATIBLE_SUBROUTINES 0x92F8 +#define GL_NAME_LENGTH 0x92F9 +#define GL_TYPE 0x92FA +#define GL_ARRAY_SIZE 0x92FB +#define GL_OFFSET 0x92FC +#define GL_BLOCK_INDEX 0x92FD +#define GL_ARRAY_STRIDE 0x92FE +#define GL_MATRIX_STRIDE 0x92FF +#define GL_IS_ROW_MAJOR 0x9300 +#define GL_ATOMIC_COUNTER_BUFFER_INDEX 0x9301 +#define GL_BUFFER_BINDING 0x9302 +#define GL_BUFFER_DATA_SIZE 0x9303 +#define GL_NUM_ACTIVE_VARIABLES 0x9304 +#define GL_ACTIVE_VARIABLES 0x9305 +#define GL_REFERENCED_BY_VERTEX_SHADER 0x9306 +#define GL_REFERENCED_BY_TESS_CONTROL_SHADER 0x9307 +#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER 0x9308 +#define GL_REFERENCED_BY_GEOMETRY_SHADER 0x9309 +#define GL_REFERENCED_BY_FRAGMENT_SHADER 0x930A +#define GL_REFERENCED_BY_COMPUTE_SHADER 0x930B +#define GL_TOP_LEVEL_ARRAY_SIZE 0x930C +#define GL_TOP_LEVEL_ARRAY_STRIDE 0x930D +#define GL_LOCATION 0x930E +#define GL_LOCATION_INDEX 0x930F +#define GL_IS_PER_PATCH 0x92E7 +#define GL_SHADER_STORAGE_BUFFER 0x90D2 +#define GL_SHADER_STORAGE_BUFFER_BINDING 0x90D3 +#define GL_SHADER_STORAGE_BUFFER_START 0x90D4 +#define GL_SHADER_STORAGE_BUFFER_SIZE 0x90D5 +#define GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS 0x90D6 +#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS 0x90D7 +#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS 0x90D8 +#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS 0x90D9 +#define GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS 0x90DA +#define GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS 0x90DB +#define GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS 0x90DC +#define GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS 0x90DD +#define GL_MAX_SHADER_STORAGE_BLOCK_SIZE 0x90DE +#define GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT 0x90DF +#define GL_SHADER_STORAGE_BARRIER_BIT 0x00002000 +#define GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES 0x8F39 +#define GL_DEPTH_STENCIL_TEXTURE_MODE 0x90EA +#define GL_TEXTURE_BUFFER_OFFSET 0x919D +#define GL_TEXTURE_BUFFER_SIZE 0x919E +#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT 0x919F +#define GL_TEXTURE_VIEW_MIN_LEVEL 0x82DB +#define GL_TEXTURE_VIEW_NUM_LEVELS 0x82DC +#define GL_TEXTURE_VIEW_MIN_LAYER 0x82DD +#define GL_TEXTURE_VIEW_NUM_LAYERS 0x82DE +#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF +#define GL_VERTEX_ATTRIB_BINDING 0x82D4 +#define GL_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D5 +#define GL_VERTEX_BINDING_DIVISOR 0x82D6 +#define GL_VERTEX_BINDING_OFFSET 0x82D7 +#define GL_VERTEX_BINDING_STRIDE 0x82D8 +#define GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D9 +#define GL_MAX_VERTEX_ATTRIB_BINDINGS 0x82DA +#define GL_VERTEX_BINDING_BUFFER 0x8F4F +#define GL_DISPLAY_LIST 0x82E7 +typedef void (APIENTRYP PFNGLCLEARBUFFERDATAPROC) (GLenum target, GLenum internalformat, GLenum format, GLenum type, const void *data); +typedef void (APIENTRYP PFNGLCLEARBUFFERSUBDATAPROC) (GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); +typedef void (APIENTRYP PFNGLDISPATCHCOMPUTEPROC) (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); +typedef void (APIENTRYP PFNGLDISPATCHCOMPUTEINDIRECTPROC) (GLintptr indirect); +typedef void (APIENTRYP PFNGLCOPYIMAGESUBDATAPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); +typedef void (APIENTRYP PFNGLFRAMEBUFFERPARAMETERIPROC) (GLenum target, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETINTERNALFORMATI64VPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint64 *params); +typedef void (APIENTRYP PFNGLINVALIDATETEXSUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); +typedef void (APIENTRYP PFNGLINVALIDATETEXIMAGEPROC) (GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLINVALIDATEBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length); +typedef void (APIENTRYP PFNGLINVALIDATEBUFFERDATAPROC) (GLuint buffer); +typedef void (APIENTRYP PFNGLINVALIDATEFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments); +typedef void (APIENTRYP PFNGLINVALIDATESUBFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTPROC) (GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride); +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride); +typedef void (APIENTRYP PFNGLGETPROGRAMINTERFACEIVPROC) (GLuint program, GLenum programInterface, GLenum pname, GLint *params); +typedef GLuint (APIENTRYP PFNGLGETPROGRAMRESOURCEINDEXPROC) (GLuint program, GLenum programInterface, const GLchar *name); +typedef void (APIENTRYP PFNGLGETPROGRAMRESOURCENAMEPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name); +typedef void (APIENTRYP PFNGLGETPROGRAMRESOURCEIVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params); +typedef GLint (APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONPROC) (GLuint program, GLenum programInterface, const GLchar *name); +typedef GLint (APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC) (GLuint program, GLenum programInterface, const GLchar *name); +typedef void (APIENTRYP PFNGLSHADERSTORAGEBLOCKBINDINGPROC) (GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding); +typedef void (APIENTRYP PFNGLTEXBUFFERRANGEPROC) (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (APIENTRYP PFNGLTEXSTORAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +typedef void (APIENTRYP PFNGLTEXSTORAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +typedef void (APIENTRYP PFNGLTEXTUREVIEWPROC) (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers); +typedef void (APIENTRYP PFNGLBINDVERTEXBUFFERPROC) (GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); +typedef void (APIENTRYP PFNGLVERTEXATTRIBFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); +typedef void (APIENTRYP PFNGLVERTEXATTRIBIFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +typedef void (APIENTRYP PFNGLVERTEXATTRIBLFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +typedef void (APIENTRYP PFNGLVERTEXATTRIBBINDINGPROC) (GLuint attribindex, GLuint bindingindex); +typedef void (APIENTRYP PFNGLVERTEXBINDINGDIVISORPROC) (GLuint bindingindex, GLuint divisor); +typedef void (APIENTRYP PFNGLDEBUGMESSAGECONTROLPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); +typedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); +typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKPROC) (GLDEBUGPROC callback, const void *userParam); +typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGPROC) (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); +typedef void (APIENTRYP PFNGLPUSHDEBUGGROUPPROC) (GLenum source, GLuint id, GLsizei length, const GLchar *message); +typedef void (APIENTRYP PFNGLPOPDEBUGGROUPPROC) (void); +typedef void (APIENTRYP PFNGLOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei length, const GLchar *label); +typedef void (APIENTRYP PFNGLGETOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label); +typedef void (APIENTRYP PFNGLOBJECTPTRLABELPROC) (const void *ptr, GLsizei length, const GLchar *label); +typedef void (APIENTRYP PFNGLGETOBJECTPTRLABELPROC) (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glClearBufferData (GLenum target, GLenum internalformat, GLenum format, GLenum type, const void *data); +GLAPI void APIENTRY glClearBufferSubData (GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); +GLAPI void APIENTRY glDispatchCompute (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); +GLAPI void APIENTRY glDispatchComputeIndirect (GLintptr indirect); +GLAPI void APIENTRY glCopyImageSubData (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); +GLAPI void APIENTRY glFramebufferParameteri (GLenum target, GLenum pname, GLint param); +GLAPI void APIENTRY glGetFramebufferParameteriv (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetInternalformati64v (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint64 *params); +GLAPI void APIENTRY glInvalidateTexSubImage (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); +GLAPI void APIENTRY glInvalidateTexImage (GLuint texture, GLint level); +GLAPI void APIENTRY glInvalidateBufferSubData (GLuint buffer, GLintptr offset, GLsizeiptr length); +GLAPI void APIENTRY glInvalidateBufferData (GLuint buffer); +GLAPI void APIENTRY glInvalidateFramebuffer (GLenum target, GLsizei numAttachments, const GLenum *attachments); +GLAPI void APIENTRY glInvalidateSubFramebuffer (GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void APIENTRY glMultiDrawArraysIndirect (GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride); +GLAPI void APIENTRY glMultiDrawElementsIndirect (GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride); +GLAPI void APIENTRY glGetProgramInterfaceiv (GLuint program, GLenum programInterface, GLenum pname, GLint *params); +GLAPI GLuint APIENTRY glGetProgramResourceIndex (GLuint program, GLenum programInterface, const GLchar *name); +GLAPI void APIENTRY glGetProgramResourceName (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name); +GLAPI void APIENTRY glGetProgramResourceiv (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params); +GLAPI GLint APIENTRY glGetProgramResourceLocation (GLuint program, GLenum programInterface, const GLchar *name); +GLAPI GLint APIENTRY glGetProgramResourceLocationIndex (GLuint program, GLenum programInterface, const GLchar *name); +GLAPI void APIENTRY glShaderStorageBlockBinding (GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding); +GLAPI void APIENTRY glTexBufferRange (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); +GLAPI void APIENTRY glTexStorage2DMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +GLAPI void APIENTRY glTexStorage3DMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +GLAPI void APIENTRY glTextureView (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers); +GLAPI void APIENTRY glBindVertexBuffer (GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); +GLAPI void APIENTRY glVertexAttribFormat (GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); +GLAPI void APIENTRY glVertexAttribIFormat (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +GLAPI void APIENTRY glVertexAttribLFormat (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +GLAPI void APIENTRY glVertexAttribBinding (GLuint attribindex, GLuint bindingindex); +GLAPI void APIENTRY glVertexBindingDivisor (GLuint bindingindex, GLuint divisor); +GLAPI void APIENTRY glDebugMessageControl (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); +GLAPI void APIENTRY glDebugMessageInsert (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); +GLAPI void APIENTRY glDebugMessageCallback (GLDEBUGPROC callback, const void *userParam); +GLAPI GLuint APIENTRY glGetDebugMessageLog (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); +GLAPI void APIENTRY glPushDebugGroup (GLenum source, GLuint id, GLsizei length, const GLchar *message); +GLAPI void APIENTRY glPopDebugGroup (void); +GLAPI void APIENTRY glObjectLabel (GLenum identifier, GLuint name, GLsizei length, const GLchar *label); +GLAPI void APIENTRY glGetObjectLabel (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label); +GLAPI void APIENTRY glObjectPtrLabel (const void *ptr, GLsizei length, const GLchar *label); +GLAPI void APIENTRY glGetObjectPtrLabel (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label); +#endif +#endif /* GL_VERSION_4_3 */ + +#ifndef GL_VERSION_4_4 +#define GL_VERSION_4_4 1 +#define GL_MAX_VERTEX_ATTRIB_STRIDE 0x82E5 +#define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED 0x8221 +#define GL_TEXTURE_BUFFER_BINDING 0x8C2A +#define GL_MAP_PERSISTENT_BIT 0x0040 +#define GL_MAP_COHERENT_BIT 0x0080 +#define GL_DYNAMIC_STORAGE_BIT 0x0100 +#define GL_CLIENT_STORAGE_BIT 0x0200 +#define GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT 0x00004000 +#define GL_BUFFER_IMMUTABLE_STORAGE 0x821F +#define GL_BUFFER_STORAGE_FLAGS 0x8220 +#define GL_CLEAR_TEXTURE 0x9365 +#define GL_LOCATION_COMPONENT 0x934A +#define GL_TRANSFORM_FEEDBACK_BUFFER_INDEX 0x934B +#define GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE 0x934C +#define GL_QUERY_BUFFER 0x9192 +#define GL_QUERY_BUFFER_BARRIER_BIT 0x00008000 +#define GL_QUERY_BUFFER_BINDING 0x9193 +#define GL_QUERY_RESULT_NO_WAIT 0x9194 +#define GL_MIRROR_CLAMP_TO_EDGE 0x8743 +typedef void (APIENTRYP PFNGLBUFFERSTORAGEPROC) (GLenum target, GLsizeiptr size, const void *data, GLbitfield flags); +typedef void (APIENTRYP PFNGLCLEARTEXIMAGEPROC) (GLuint texture, GLint level, GLenum format, GLenum type, const void *data); +typedef void (APIENTRYP PFNGLCLEARTEXSUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data); +typedef void (APIENTRYP PFNGLBINDBUFFERSBASEPROC) (GLenum target, GLuint first, GLsizei count, const GLuint *buffers); +typedef void (APIENTRYP PFNGLBINDBUFFERSRANGEPROC) (GLenum target, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizeiptr *sizes); +typedef void (APIENTRYP PFNGLBINDTEXTURESPROC) (GLuint first, GLsizei count, const GLuint *textures); +typedef void (APIENTRYP PFNGLBINDSAMPLERSPROC) (GLuint first, GLsizei count, const GLuint *samplers); +typedef void (APIENTRYP PFNGLBINDIMAGETEXTURESPROC) (GLuint first, GLsizei count, const GLuint *textures); +typedef void (APIENTRYP PFNGLBINDVERTEXBUFFERSPROC) (GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizei *strides); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBufferStorage (GLenum target, GLsizeiptr size, const void *data, GLbitfield flags); +GLAPI void APIENTRY glClearTexImage (GLuint texture, GLint level, GLenum format, GLenum type, const void *data); +GLAPI void APIENTRY glClearTexSubImage (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data); +GLAPI void APIENTRY glBindBuffersBase (GLenum target, GLuint first, GLsizei count, const GLuint *buffers); +GLAPI void APIENTRY glBindBuffersRange (GLenum target, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizeiptr *sizes); +GLAPI void APIENTRY glBindTextures (GLuint first, GLsizei count, const GLuint *textures); +GLAPI void APIENTRY glBindSamplers (GLuint first, GLsizei count, const GLuint *samplers); +GLAPI void APIENTRY glBindImageTextures (GLuint first, GLsizei count, const GLuint *textures); +GLAPI void APIENTRY glBindVertexBuffers (GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizei *strides); +#endif +#endif /* GL_VERSION_4_4 */ + +#ifndef GL_VERSION_4_5 +#define GL_VERSION_4_5 1 +#define GL_CONTEXT_LOST 0x0507 +#define GL_NEGATIVE_ONE_TO_ONE 0x935E +#define GL_ZERO_TO_ONE 0x935F +#define GL_CLIP_ORIGIN 0x935C +#define GL_CLIP_DEPTH_MODE 0x935D +#define GL_QUERY_WAIT_INVERTED 0x8E17 +#define GL_QUERY_NO_WAIT_INVERTED 0x8E18 +#define GL_QUERY_BY_REGION_WAIT_INVERTED 0x8E19 +#define GL_QUERY_BY_REGION_NO_WAIT_INVERTED 0x8E1A +#define GL_MAX_CULL_DISTANCES 0x82F9 +#define GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES 0x82FA +#define GL_TEXTURE_TARGET 0x1006 +#define GL_QUERY_TARGET 0x82EA +#define GL_TEXTURE_BINDING 0x82EB +#define GL_GUILTY_CONTEXT_RESET 0x8253 +#define GL_INNOCENT_CONTEXT_RESET 0x8254 +#define GL_UNKNOWN_CONTEXT_RESET 0x8255 +#define GL_RESET_NOTIFICATION_STRATEGY 0x8256 +#define GL_LOSE_CONTEXT_ON_RESET 0x8252 +#define GL_NO_RESET_NOTIFICATION 0x8261 +#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT 0x00000004 +#define GL_CONTEXT_RELEASE_BEHAVIOR 0x82FB +#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH 0x82FC +typedef void (APIENTRYP PFNGLCLIPCONTROLPROC) (GLenum origin, GLenum depth); +typedef void (APIENTRYP PFNGLCREATETRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint *ids); +typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC) (GLuint xfb, GLuint index, GLuint buffer); +typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC) (GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizei size); +typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKIVPROC) (GLuint xfb, GLenum pname, GLint *param); +typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKI_VPROC) (GLuint xfb, GLenum pname, GLuint index, GLint *param); +typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKI64_VPROC) (GLuint xfb, GLenum pname, GLuint index, GLint64 *param); +typedef void (APIENTRYP PFNGLCREATEBUFFERSPROC) (GLsizei n, GLuint *buffers); +typedef void (APIENTRYP PFNGLNAMEDBUFFERSTORAGEPROC) (GLuint buffer, GLsizei size, const void *data, GLbitfield flags); +typedef void (APIENTRYP PFNGLNAMEDBUFFERDATAPROC) (GLuint buffer, GLsizei size, const void *data, GLenum usage); +typedef void (APIENTRYP PFNGLNAMEDBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizei size, const void *data); +typedef void (APIENTRYP PFNGLCOPYNAMEDBUFFERSUBDATAPROC) (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizei size); +typedef void (APIENTRYP PFNGLCLEARNAMEDBUFFERDATAPROC) (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data); +typedef void (APIENTRYP PFNGLCLEARNAMEDBUFFERSUBDATAPROC) (GLuint buffer, GLenum internalformat, GLintptr offset, GLsizei size, GLenum format, GLenum type, const void *data); +typedef void *(APIENTRYP PFNGLMAPNAMEDBUFFERPROC) (GLuint buffer, GLenum access); +typedef void *(APIENTRYP PFNGLMAPNAMEDBUFFERRANGEPROC) (GLuint buffer, GLintptr offset, GLsizei length, GLbitfield access); +typedef GLboolean (APIENTRYP PFNGLUNMAPNAMEDBUFFERPROC) (GLuint buffer); +typedef void (APIENTRYP PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC) (GLuint buffer, GLintptr offset, GLsizei length); +typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPARAMETERIVPROC) (GLuint buffer, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPARAMETERI64VPROC) (GLuint buffer, GLenum pname, GLint64 *params); +typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPOINTERVPROC) (GLuint buffer, GLenum pname, void **params); +typedef void (APIENTRYP PFNGLGETNAMEDBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizei size, void *data); +typedef void (APIENTRYP PFNGLCREATEFRAMEBUFFERSPROC) (GLsizei n, GLuint *framebuffers); +typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC) (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC) (GLuint framebuffer, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTUREPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC) (GLuint framebuffer, GLenum buf); +typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC) (GLuint framebuffer, GLsizei n, const GLenum *bufs); +typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC) (GLuint framebuffer, GLenum src); +typedef void (APIENTRYP PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC) (GLuint framebuffer, GLsizei numAttachments, const GLenum *attachments); +typedef void (APIENTRYP PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC) (GLuint framebuffer, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLCLEARNAMEDFRAMEBUFFERIVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint *value); +typedef void (APIENTRYP PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint *value); +typedef void (APIENTRYP PFNGLCLEARNAMEDFRAMEBUFFERFVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat *value); +typedef void (APIENTRYP PFNGLCLEARNAMEDFRAMEBUFFERFIPROC) (GLuint framebuffer, GLenum buffer, const GLfloat depth, GLint stencil); +typedef void (APIENTRYP PFNGLBLITNAMEDFRAMEBUFFERPROC) (GLuint readFramebuffer, GLuint drawFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +typedef GLenum (APIENTRYP PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC) (GLuint framebuffer, GLenum target); +typedef void (APIENTRYP PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC) (GLuint framebuffer, GLenum pname, GLint *param); +typedef void (APIENTRYP PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLCREATERENDERBUFFERSPROC) (GLsizei n, GLuint *renderbuffers); +typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEPROC) (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC) (GLuint renderbuffer, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLCREATETEXTURESPROC) (GLenum target, GLsizei n, GLuint *textures); +typedef void (APIENTRYP PFNGLTEXTUREBUFFERPROC) (GLuint texture, GLenum internalformat, GLuint buffer); +typedef void (APIENTRYP PFNGLTEXTUREBUFFERRANGEPROC) (GLuint texture, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizei size); +typedef void (APIENTRYP PFNGLTEXTURESTORAGE1DPROC) (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width); +typedef void (APIENTRYP PFNGLTEXTURESTORAGE2DPROC) (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLTEXTURESTORAGE3DPROC) (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +typedef void (APIENTRYP PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC) (GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +typedef void (APIENTRYP PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC) (GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE1DPROC) (GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE2DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE3DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC) (GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); +typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE1DPROC) (GLuint texture, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE2DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE3DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLTEXTUREPARAMETERFPROC) (GLuint texture, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLTEXTUREPARAMETERFVPROC) (GLuint texture, GLenum pname, const GLfloat *param); +typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIPROC) (GLuint texture, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIIVPROC) (GLuint texture, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIUIVPROC) (GLuint texture, GLenum pname, const GLuint *params); +typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIVPROC) (GLuint texture, GLenum pname, const GLint *param); +typedef void (APIENTRYP PFNGLGENERATETEXTUREMIPMAPPROC) (GLuint texture); +typedef void (APIENTRYP PFNGLBINDTEXTUREUNITPROC) (GLuint unit, GLuint texture); +typedef void (APIENTRYP PFNGLGETTEXTUREIMAGEPROC) (GLuint texture, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels); +typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC) (GLuint texture, GLint level, GLsizei bufSize, void *pixels); +typedef void (APIENTRYP PFNGLGETTEXTURELEVELPARAMETERFVPROC) (GLuint texture, GLint level, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETTEXTURELEVELPARAMETERIVPROC) (GLuint texture, GLint level, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERFVPROC) (GLuint texture, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIIVPROC) (GLuint texture, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIUIVPROC) (GLuint texture, GLenum pname, GLuint *params); +typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIVPROC) (GLuint texture, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLCREATEVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays); +typedef void (APIENTRYP PFNGLDISABLEVERTEXARRAYATTRIBPROC) (GLuint vaobj, GLuint index); +typedef void (APIENTRYP PFNGLENABLEVERTEXARRAYATTRIBPROC) (GLuint vaobj, GLuint index); +typedef void (APIENTRYP PFNGLVERTEXARRAYELEMENTBUFFERPROC) (GLuint vaobj, GLuint buffer); +typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXBUFFERPROC) (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); +typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXBUFFERSPROC) (GLuint vaobj, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizei *strides); +typedef void (APIENTRYP PFNGLVERTEXARRAYATTRIBBINDINGPROC) (GLuint vaobj, GLuint attribindex, GLuint bindingindex); +typedef void (APIENTRYP PFNGLVERTEXARRAYATTRIBFORMATPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); +typedef void (APIENTRYP PFNGLVERTEXARRAYATTRIBIFORMATPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +typedef void (APIENTRYP PFNGLVERTEXARRAYATTRIBLFORMATPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +typedef void (APIENTRYP PFNGLVERTEXARRAYBINDINGDIVISORPROC) (GLuint vaobj, GLuint bindingindex, GLuint divisor); +typedef void (APIENTRYP PFNGLGETVERTEXARRAYIVPROC) (GLuint vaobj, GLenum pname, GLint *param); +typedef void (APIENTRYP PFNGLGETVERTEXARRAYINDEXEDIVPROC) (GLuint vaobj, GLuint index, GLenum pname, GLint *param); +typedef void (APIENTRYP PFNGLGETVERTEXARRAYINDEXED64IVPROC) (GLuint vaobj, GLuint index, GLenum pname, GLint64 *param); +typedef void (APIENTRYP PFNGLCREATESAMPLERSPROC) (GLsizei n, GLuint *samplers); +typedef void (APIENTRYP PFNGLCREATEPROGRAMPIPELINESPROC) (GLsizei n, GLuint *pipelines); +typedef void (APIENTRYP PFNGLCREATEQUERIESPROC) (GLenum target, GLsizei n, GLuint *ids); +typedef void (APIENTRYP PFNGLMEMORYBARRIERBYREGIONPROC) (GLbitfield barriers); +typedef void (APIENTRYP PFNGLGETTEXTURESUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLsizei bufSize, void *pixels); +typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei bufSize, void *pixels); +typedef GLenum (APIENTRYP PFNGLGETGRAPHICSRESETSTATUSPROC) (void); +typedef void (APIENTRYP PFNGLGETNCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint lod, GLsizei bufSize, void *pixels); +typedef void (APIENTRYP PFNGLGETNTEXIMAGEPROC) (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels); +typedef void (APIENTRYP PFNGLGETNUNIFORMDVPROC) (GLuint program, GLint location, GLsizei bufSize, GLdouble *params); +typedef void (APIENTRYP PFNGLGETNUNIFORMFVPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); +typedef void (APIENTRYP PFNGLGETNUNIFORMIVPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params); +typedef void (APIENTRYP PFNGLGETNUNIFORMUIVPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint *params); +typedef void (APIENTRYP PFNGLREADNPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); +typedef void (APIENTRYP PFNGLGETNMAPDVPROC) (GLenum target, GLenum query, GLsizei bufSize, GLdouble *v); +typedef void (APIENTRYP PFNGLGETNMAPFVPROC) (GLenum target, GLenum query, GLsizei bufSize, GLfloat *v); +typedef void (APIENTRYP PFNGLGETNMAPIVPROC) (GLenum target, GLenum query, GLsizei bufSize, GLint *v); +typedef void (APIENTRYP PFNGLGETNPIXELMAPFVPROC) (GLenum map, GLsizei bufSize, GLfloat *values); +typedef void (APIENTRYP PFNGLGETNPIXELMAPUIVPROC) (GLenum map, GLsizei bufSize, GLuint *values); +typedef void (APIENTRYP PFNGLGETNPIXELMAPUSVPROC) (GLenum map, GLsizei bufSize, GLushort *values); +typedef void (APIENTRYP PFNGLGETNPOLYGONSTIPPLEPROC) (GLsizei bufSize, GLubyte *pattern); +typedef void (APIENTRYP PFNGLGETNCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *table); +typedef void (APIENTRYP PFNGLGETNCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *image); +typedef void (APIENTRYP PFNGLGETNSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, void *row, GLsizei columnBufSize, void *column, void *span); +typedef void (APIENTRYP PFNGLGETNHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void *values); +typedef void (APIENTRYP PFNGLGETNMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void *values); +typedef void (APIENTRYP PFNGLTEXTUREBARRIERPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glClipControl (GLenum origin, GLenum depth); +GLAPI void APIENTRY glCreateTransformFeedbacks (GLsizei n, GLuint *ids); +GLAPI void APIENTRY glTransformFeedbackBufferBase (GLuint xfb, GLuint index, GLuint buffer); +GLAPI void APIENTRY glTransformFeedbackBufferRange (GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizei size); +GLAPI void APIENTRY glGetTransformFeedbackiv (GLuint xfb, GLenum pname, GLint *param); +GLAPI void APIENTRY glGetTransformFeedbacki_v (GLuint xfb, GLenum pname, GLuint index, GLint *param); +GLAPI void APIENTRY glGetTransformFeedbacki64_v (GLuint xfb, GLenum pname, GLuint index, GLint64 *param); +GLAPI void APIENTRY glCreateBuffers (GLsizei n, GLuint *buffers); +GLAPI void APIENTRY glNamedBufferStorage (GLuint buffer, GLsizei size, const void *data, GLbitfield flags); +GLAPI void APIENTRY glNamedBufferData (GLuint buffer, GLsizei size, const void *data, GLenum usage); +GLAPI void APIENTRY glNamedBufferSubData (GLuint buffer, GLintptr offset, GLsizei size, const void *data); +GLAPI void APIENTRY glCopyNamedBufferSubData (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizei size); +GLAPI void APIENTRY glClearNamedBufferData (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data); +GLAPI void APIENTRY glClearNamedBufferSubData (GLuint buffer, GLenum internalformat, GLintptr offset, GLsizei size, GLenum format, GLenum type, const void *data); +GLAPI void *APIENTRY glMapNamedBuffer (GLuint buffer, GLenum access); +GLAPI void *APIENTRY glMapNamedBufferRange (GLuint buffer, GLintptr offset, GLsizei length, GLbitfield access); +GLAPI GLboolean APIENTRY glUnmapNamedBuffer (GLuint buffer); +GLAPI void APIENTRY glFlushMappedNamedBufferRange (GLuint buffer, GLintptr offset, GLsizei length); +GLAPI void APIENTRY glGetNamedBufferParameteriv (GLuint buffer, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetNamedBufferParameteri64v (GLuint buffer, GLenum pname, GLint64 *params); +GLAPI void APIENTRY glGetNamedBufferPointerv (GLuint buffer, GLenum pname, void **params); +GLAPI void APIENTRY glGetNamedBufferSubData (GLuint buffer, GLintptr offset, GLsizei size, void *data); +GLAPI void APIENTRY glCreateFramebuffers (GLsizei n, GLuint *framebuffers); +GLAPI void APIENTRY glNamedFramebufferRenderbuffer (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +GLAPI void APIENTRY glNamedFramebufferParameteri (GLuint framebuffer, GLenum pname, GLint param); +GLAPI void APIENTRY glNamedFramebufferTexture (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); +GLAPI void APIENTRY glNamedFramebufferTextureLayer (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); +GLAPI void APIENTRY glNamedFramebufferDrawBuffer (GLuint framebuffer, GLenum buf); +GLAPI void APIENTRY glNamedFramebufferDrawBuffers (GLuint framebuffer, GLsizei n, const GLenum *bufs); +GLAPI void APIENTRY glNamedFramebufferReadBuffer (GLuint framebuffer, GLenum src); +GLAPI void APIENTRY glInvalidateNamedFramebufferData (GLuint framebuffer, GLsizei numAttachments, const GLenum *attachments); +GLAPI void APIENTRY glInvalidateNamedFramebufferSubData (GLuint framebuffer, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void APIENTRY glClearNamedFramebufferiv (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint *value); +GLAPI void APIENTRY glClearNamedFramebufferuiv (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint *value); +GLAPI void APIENTRY glClearNamedFramebufferfv (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat *value); +GLAPI void APIENTRY glClearNamedFramebufferfi (GLuint framebuffer, GLenum buffer, const GLfloat depth, GLint stencil); +GLAPI void APIENTRY glBlitNamedFramebuffer (GLuint readFramebuffer, GLuint drawFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +GLAPI GLenum APIENTRY glCheckNamedFramebufferStatus (GLuint framebuffer, GLenum target); +GLAPI void APIENTRY glGetNamedFramebufferParameteriv (GLuint framebuffer, GLenum pname, GLint *param); +GLAPI void APIENTRY glGetNamedFramebufferAttachmentParameteriv (GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params); +GLAPI void APIENTRY glCreateRenderbuffers (GLsizei n, GLuint *renderbuffers); +GLAPI void APIENTRY glNamedRenderbufferStorage (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); +GLAPI void APIENTRY glNamedRenderbufferStorageMultisample (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +GLAPI void APIENTRY glGetNamedRenderbufferParameteriv (GLuint renderbuffer, GLenum pname, GLint *params); +GLAPI void APIENTRY glCreateTextures (GLenum target, GLsizei n, GLuint *textures); +GLAPI void APIENTRY glTextureBuffer (GLuint texture, GLenum internalformat, GLuint buffer); +GLAPI void APIENTRY glTextureBufferRange (GLuint texture, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizei size); +GLAPI void APIENTRY glTextureStorage1D (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width); +GLAPI void APIENTRY glTextureStorage2D (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +GLAPI void APIENTRY glTextureStorage3D (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +GLAPI void APIENTRY glTextureStorage2DMultisample (GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +GLAPI void APIENTRY glTextureStorage3DMultisample (GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +GLAPI void APIENTRY glTextureSubImage1D (GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glTextureSubImage2D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glTextureSubImage3D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glCompressedTextureSubImage1D (GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); +GLAPI void APIENTRY glCompressedTextureSubImage2D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); +GLAPI void APIENTRY glCompressedTextureSubImage3D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); +GLAPI void APIENTRY glCopyTextureSubImage1D (GLuint texture, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +GLAPI void APIENTRY glCopyTextureSubImage2D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void APIENTRY glCopyTextureSubImage3D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void APIENTRY glTextureParameterf (GLuint texture, GLenum pname, GLfloat param); +GLAPI void APIENTRY glTextureParameterfv (GLuint texture, GLenum pname, const GLfloat *param); +GLAPI void APIENTRY glTextureParameteri (GLuint texture, GLenum pname, GLint param); +GLAPI void APIENTRY glTextureParameterIiv (GLuint texture, GLenum pname, const GLint *params); +GLAPI void APIENTRY glTextureParameterIuiv (GLuint texture, GLenum pname, const GLuint *params); +GLAPI void APIENTRY glTextureParameteriv (GLuint texture, GLenum pname, const GLint *param); +GLAPI void APIENTRY glGenerateTextureMipmap (GLuint texture); +GLAPI void APIENTRY glBindTextureUnit (GLuint unit, GLuint texture); +GLAPI void APIENTRY glGetTextureImage (GLuint texture, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels); +GLAPI void APIENTRY glGetCompressedTextureImage (GLuint texture, GLint level, GLsizei bufSize, void *pixels); +GLAPI void APIENTRY glGetTextureLevelParameterfv (GLuint texture, GLint level, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetTextureLevelParameteriv (GLuint texture, GLint level, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetTextureParameterfv (GLuint texture, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetTextureParameterIiv (GLuint texture, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetTextureParameterIuiv (GLuint texture, GLenum pname, GLuint *params); +GLAPI void APIENTRY glGetTextureParameteriv (GLuint texture, GLenum pname, GLint *params); +GLAPI void APIENTRY glCreateVertexArrays (GLsizei n, GLuint *arrays); +GLAPI void APIENTRY glDisableVertexArrayAttrib (GLuint vaobj, GLuint index); +GLAPI void APIENTRY glEnableVertexArrayAttrib (GLuint vaobj, GLuint index); +GLAPI void APIENTRY glVertexArrayElementBuffer (GLuint vaobj, GLuint buffer); +GLAPI void APIENTRY glVertexArrayVertexBuffer (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); +GLAPI void APIENTRY glVertexArrayVertexBuffers (GLuint vaobj, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizei *strides); +GLAPI void APIENTRY glVertexArrayAttribBinding (GLuint vaobj, GLuint attribindex, GLuint bindingindex); +GLAPI void APIENTRY glVertexArrayAttribFormat (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); +GLAPI void APIENTRY glVertexArrayAttribIFormat (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +GLAPI void APIENTRY glVertexArrayAttribLFormat (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +GLAPI void APIENTRY glVertexArrayBindingDivisor (GLuint vaobj, GLuint bindingindex, GLuint divisor); +GLAPI void APIENTRY glGetVertexArrayiv (GLuint vaobj, GLenum pname, GLint *param); +GLAPI void APIENTRY glGetVertexArrayIndexediv (GLuint vaobj, GLuint index, GLenum pname, GLint *param); +GLAPI void APIENTRY glGetVertexArrayIndexed64iv (GLuint vaobj, GLuint index, GLenum pname, GLint64 *param); +GLAPI void APIENTRY glCreateSamplers (GLsizei n, GLuint *samplers); +GLAPI void APIENTRY glCreateProgramPipelines (GLsizei n, GLuint *pipelines); +GLAPI void APIENTRY glCreateQueries (GLenum target, GLsizei n, GLuint *ids); +GLAPI void APIENTRY glMemoryBarrierByRegion (GLbitfield barriers); +GLAPI void APIENTRY glGetTextureSubImage (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLsizei bufSize, void *pixels); +GLAPI void APIENTRY glGetCompressedTextureSubImage (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei bufSize, void *pixels); +GLAPI GLenum APIENTRY glGetGraphicsResetStatus (void); +GLAPI void APIENTRY glGetnCompressedTexImage (GLenum target, GLint lod, GLsizei bufSize, void *pixels); +GLAPI void APIENTRY glGetnTexImage (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels); +GLAPI void APIENTRY glGetnUniformdv (GLuint program, GLint location, GLsizei bufSize, GLdouble *params); +GLAPI void APIENTRY glGetnUniformfv (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); +GLAPI void APIENTRY glGetnUniformiv (GLuint program, GLint location, GLsizei bufSize, GLint *params); +GLAPI void APIENTRY glGetnUniformuiv (GLuint program, GLint location, GLsizei bufSize, GLuint *params); +GLAPI void APIENTRY glReadnPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); +GLAPI void APIENTRY glGetnMapdv (GLenum target, GLenum query, GLsizei bufSize, GLdouble *v); +GLAPI void APIENTRY glGetnMapfv (GLenum target, GLenum query, GLsizei bufSize, GLfloat *v); +GLAPI void APIENTRY glGetnMapiv (GLenum target, GLenum query, GLsizei bufSize, GLint *v); +GLAPI void APIENTRY glGetnPixelMapfv (GLenum map, GLsizei bufSize, GLfloat *values); +GLAPI void APIENTRY glGetnPixelMapuiv (GLenum map, GLsizei bufSize, GLuint *values); +GLAPI void APIENTRY glGetnPixelMapusv (GLenum map, GLsizei bufSize, GLushort *values); +GLAPI void APIENTRY glGetnPolygonStipple (GLsizei bufSize, GLubyte *pattern); +GLAPI void APIENTRY glGetnColorTable (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *table); +GLAPI void APIENTRY glGetnConvolutionFilter (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *image); +GLAPI void APIENTRY glGetnSeparableFilter (GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, void *row, GLsizei columnBufSize, void *column, void *span); +GLAPI void APIENTRY glGetnHistogram (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void *values); +GLAPI void APIENTRY glGetnMinmax (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void *values); +GLAPI void APIENTRY glTextureBarrier (void); +#endif +#endif /* GL_VERSION_4_5 */ + +#ifndef GL_ARB_ES2_compatibility +#define GL_ARB_ES2_compatibility 1 +#endif /* GL_ARB_ES2_compatibility */ + +#ifndef GL_ARB_ES3_1_compatibility +#define GL_ARB_ES3_1_compatibility 1 +#endif /* GL_ARB_ES3_1_compatibility */ + +#ifndef GL_ARB_ES3_compatibility +#define GL_ARB_ES3_compatibility 1 +#endif /* GL_ARB_ES3_compatibility */ + +#ifndef GL_ARB_arrays_of_arrays +#define GL_ARB_arrays_of_arrays 1 +#endif /* GL_ARB_arrays_of_arrays */ + +#ifndef GL_ARB_base_instance +#define GL_ARB_base_instance 1 +#endif /* GL_ARB_base_instance */ + +#ifndef GL_ARB_bindless_texture +#define GL_ARB_bindless_texture 1 +typedef uint64_t GLuint64EXT; +#define GL_UNSIGNED_INT64_ARB 0x140F +typedef GLuint64 (APIENTRYP PFNGLGETTEXTUREHANDLEARBPROC) (GLuint texture); +typedef GLuint64 (APIENTRYP PFNGLGETTEXTURESAMPLERHANDLEARBPROC) (GLuint texture, GLuint sampler); +typedef void (APIENTRYP PFNGLMAKETEXTUREHANDLERESIDENTARBPROC) (GLuint64 handle); +typedef void (APIENTRYP PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC) (GLuint64 handle); +typedef GLuint64 (APIENTRYP PFNGLGETIMAGEHANDLEARBPROC) (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format); +typedef void (APIENTRYP PFNGLMAKEIMAGEHANDLERESIDENTARBPROC) (GLuint64 handle, GLenum access); +typedef void (APIENTRYP PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC) (GLuint64 handle); +typedef void (APIENTRYP PFNGLUNIFORMHANDLEUI64ARBPROC) (GLint location, GLuint64 value); +typedef void (APIENTRYP PFNGLUNIFORMHANDLEUI64VARBPROC) (GLint location, GLsizei count, const GLuint64 *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC) (GLuint program, GLint location, GLuint64 value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLuint64 *values); +typedef GLboolean (APIENTRYP PFNGLISTEXTUREHANDLERESIDENTARBPROC) (GLuint64 handle); +typedef GLboolean (APIENTRYP PFNGLISIMAGEHANDLERESIDENTARBPROC) (GLuint64 handle); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL1UI64ARBPROC) (GLuint index, GLuint64EXT x); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL1UI64VARBPROC) (GLuint index, const GLuint64EXT *v); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLUI64VARBPROC) (GLuint index, GLenum pname, GLuint64EXT *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLuint64 APIENTRY glGetTextureHandleARB (GLuint texture); +GLAPI GLuint64 APIENTRY glGetTextureSamplerHandleARB (GLuint texture, GLuint sampler); +GLAPI void APIENTRY glMakeTextureHandleResidentARB (GLuint64 handle); +GLAPI void APIENTRY glMakeTextureHandleNonResidentARB (GLuint64 handle); +GLAPI GLuint64 APIENTRY glGetImageHandleARB (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format); +GLAPI void APIENTRY glMakeImageHandleResidentARB (GLuint64 handle, GLenum access); +GLAPI void APIENTRY glMakeImageHandleNonResidentARB (GLuint64 handle); +GLAPI void APIENTRY glUniformHandleui64ARB (GLint location, GLuint64 value); +GLAPI void APIENTRY glUniformHandleui64vARB (GLint location, GLsizei count, const GLuint64 *value); +GLAPI void APIENTRY glProgramUniformHandleui64ARB (GLuint program, GLint location, GLuint64 value); +GLAPI void APIENTRY glProgramUniformHandleui64vARB (GLuint program, GLint location, GLsizei count, const GLuint64 *values); +GLAPI GLboolean APIENTRY glIsTextureHandleResidentARB (GLuint64 handle); +GLAPI GLboolean APIENTRY glIsImageHandleResidentARB (GLuint64 handle); +GLAPI void APIENTRY glVertexAttribL1ui64ARB (GLuint index, GLuint64EXT x); +GLAPI void APIENTRY glVertexAttribL1ui64vARB (GLuint index, const GLuint64EXT *v); +GLAPI void APIENTRY glGetVertexAttribLui64vARB (GLuint index, GLenum pname, GLuint64EXT *params); +#endif +#endif /* GL_ARB_bindless_texture */ + +#ifndef GL_ARB_blend_func_extended +#define GL_ARB_blend_func_extended 1 +#endif /* GL_ARB_blend_func_extended */ + +#ifndef GL_ARB_buffer_storage +#define GL_ARB_buffer_storage 1 +#endif /* GL_ARB_buffer_storage */ + +#ifndef GL_ARB_cl_event +#define GL_ARB_cl_event 1 +struct _cl_context; +struct _cl_event; +#define GL_SYNC_CL_EVENT_ARB 0x8240 +#define GL_SYNC_CL_EVENT_COMPLETE_ARB 0x8241 +typedef GLsync (APIENTRYP PFNGLCREATESYNCFROMCLEVENTARBPROC) (struct _cl_context *context, struct _cl_event *event, GLbitfield flags); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLsync APIENTRY glCreateSyncFromCLeventARB (struct _cl_context *context, struct _cl_event *event, GLbitfield flags); +#endif +#endif /* GL_ARB_cl_event */ + +#ifndef GL_ARB_clear_buffer_object +#define GL_ARB_clear_buffer_object 1 +#endif /* GL_ARB_clear_buffer_object */ + +#ifndef GL_ARB_clear_texture +#define GL_ARB_clear_texture 1 +#endif /* GL_ARB_clear_texture */ + +#ifndef GL_ARB_clip_control +#define GL_ARB_clip_control 1 +#endif /* GL_ARB_clip_control */ + +#ifndef GL_ARB_color_buffer_float +#define GL_ARB_color_buffer_float 1 +#define GL_RGBA_FLOAT_MODE_ARB 0x8820 +#define GL_CLAMP_VERTEX_COLOR_ARB 0x891A +#define GL_CLAMP_FRAGMENT_COLOR_ARB 0x891B +#define GL_CLAMP_READ_COLOR_ARB 0x891C +#define GL_FIXED_ONLY_ARB 0x891D +typedef void (APIENTRYP PFNGLCLAMPCOLORARBPROC) (GLenum target, GLenum clamp); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glClampColorARB (GLenum target, GLenum clamp); +#endif +#endif /* GL_ARB_color_buffer_float */ + +#ifndef GL_ARB_compatibility +#define GL_ARB_compatibility 1 +#endif /* GL_ARB_compatibility */ + +#ifndef GL_ARB_compressed_texture_pixel_storage +#define GL_ARB_compressed_texture_pixel_storage 1 +#endif /* GL_ARB_compressed_texture_pixel_storage */ + +#ifndef GL_ARB_compute_shader +#define GL_ARB_compute_shader 1 +#endif /* GL_ARB_compute_shader */ + +#ifndef GL_ARB_compute_variable_group_size +#define GL_ARB_compute_variable_group_size 1 +#define GL_MAX_COMPUTE_VARIABLE_GROUP_INVOCATIONS_ARB 0x9344 +#define GL_MAX_COMPUTE_FIXED_GROUP_INVOCATIONS_ARB 0x90EB +#define GL_MAX_COMPUTE_VARIABLE_GROUP_SIZE_ARB 0x9345 +#define GL_MAX_COMPUTE_FIXED_GROUP_SIZE_ARB 0x91BF +typedef void (APIENTRYP PFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC) (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z, GLuint group_size_x, GLuint group_size_y, GLuint group_size_z); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDispatchComputeGroupSizeARB (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z, GLuint group_size_x, GLuint group_size_y, GLuint group_size_z); +#endif +#endif /* GL_ARB_compute_variable_group_size */ + +#ifndef GL_ARB_conditional_render_inverted +#define GL_ARB_conditional_render_inverted 1 +#endif /* GL_ARB_conditional_render_inverted */ + +#ifndef GL_ARB_conservative_depth +#define GL_ARB_conservative_depth 1 +#endif /* GL_ARB_conservative_depth */ + +#ifndef GL_ARB_copy_buffer +#define GL_ARB_copy_buffer 1 +#define GL_COPY_READ_BUFFER_BINDING 0x8F36 +#define GL_COPY_WRITE_BUFFER_BINDING 0x8F37 +#endif /* GL_ARB_copy_buffer */ + +#ifndef GL_ARB_copy_image +#define GL_ARB_copy_image 1 +#endif /* GL_ARB_copy_image */ + +#ifndef GL_ARB_cull_distance +#define GL_ARB_cull_distance 1 +#endif /* GL_ARB_cull_distance */ + +#ifndef GL_ARB_debug_output +#define GL_ARB_debug_output 1 +typedef void (APIENTRY *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); +#define GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB 0x8242 +#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB 0x8243 +#define GL_DEBUG_CALLBACK_FUNCTION_ARB 0x8244 +#define GL_DEBUG_CALLBACK_USER_PARAM_ARB 0x8245 +#define GL_DEBUG_SOURCE_API_ARB 0x8246 +#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB 0x8247 +#define GL_DEBUG_SOURCE_SHADER_COMPILER_ARB 0x8248 +#define GL_DEBUG_SOURCE_THIRD_PARTY_ARB 0x8249 +#define GL_DEBUG_SOURCE_APPLICATION_ARB 0x824A +#define GL_DEBUG_SOURCE_OTHER_ARB 0x824B +#define GL_DEBUG_TYPE_ERROR_ARB 0x824C +#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB 0x824D +#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB 0x824E +#define GL_DEBUG_TYPE_PORTABILITY_ARB 0x824F +#define GL_DEBUG_TYPE_PERFORMANCE_ARB 0x8250 +#define GL_DEBUG_TYPE_OTHER_ARB 0x8251 +#define GL_MAX_DEBUG_MESSAGE_LENGTH_ARB 0x9143 +#define GL_MAX_DEBUG_LOGGED_MESSAGES_ARB 0x9144 +#define GL_DEBUG_LOGGED_MESSAGES_ARB 0x9145 +#define GL_DEBUG_SEVERITY_HIGH_ARB 0x9146 +#define GL_DEBUG_SEVERITY_MEDIUM_ARB 0x9147 +#define GL_DEBUG_SEVERITY_LOW_ARB 0x9148 +typedef void (APIENTRYP PFNGLDEBUGMESSAGECONTROLARBPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); +typedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTARBPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); +typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKARBPROC) (GLDEBUGPROCARB callback, const void *userParam); +typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGARBPROC) (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDebugMessageControlARB (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); +GLAPI void APIENTRY glDebugMessageInsertARB (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); +GLAPI void APIENTRY glDebugMessageCallbackARB (GLDEBUGPROCARB callback, const void *userParam); +GLAPI GLuint APIENTRY glGetDebugMessageLogARB (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); +#endif +#endif /* GL_ARB_debug_output */ + +#ifndef GL_ARB_depth_buffer_float +#define GL_ARB_depth_buffer_float 1 +#endif /* GL_ARB_depth_buffer_float */ + +#ifndef GL_ARB_depth_clamp +#define GL_ARB_depth_clamp 1 +#endif /* GL_ARB_depth_clamp */ + +#ifndef GL_ARB_depth_texture +#define GL_ARB_depth_texture 1 +#define GL_DEPTH_COMPONENT16_ARB 0x81A5 +#define GL_DEPTH_COMPONENT24_ARB 0x81A6 +#define GL_DEPTH_COMPONENT32_ARB 0x81A7 +#define GL_TEXTURE_DEPTH_SIZE_ARB 0x884A +#define GL_DEPTH_TEXTURE_MODE_ARB 0x884B +#endif /* GL_ARB_depth_texture */ + +#ifndef GL_ARB_derivative_control +#define GL_ARB_derivative_control 1 +#endif /* GL_ARB_derivative_control */ + +#ifndef GL_ARB_direct_state_access +#define GL_ARB_direct_state_access 1 +#endif /* GL_ARB_direct_state_access */ + +#ifndef GL_ARB_draw_buffers +#define GL_ARB_draw_buffers 1 +#define GL_MAX_DRAW_BUFFERS_ARB 0x8824 +#define GL_DRAW_BUFFER0_ARB 0x8825 +#define GL_DRAW_BUFFER1_ARB 0x8826 +#define GL_DRAW_BUFFER2_ARB 0x8827 +#define GL_DRAW_BUFFER3_ARB 0x8828 +#define GL_DRAW_BUFFER4_ARB 0x8829 +#define GL_DRAW_BUFFER5_ARB 0x882A +#define GL_DRAW_BUFFER6_ARB 0x882B +#define GL_DRAW_BUFFER7_ARB 0x882C +#define GL_DRAW_BUFFER8_ARB 0x882D +#define GL_DRAW_BUFFER9_ARB 0x882E +#define GL_DRAW_BUFFER10_ARB 0x882F +#define GL_DRAW_BUFFER11_ARB 0x8830 +#define GL_DRAW_BUFFER12_ARB 0x8831 +#define GL_DRAW_BUFFER13_ARB 0x8832 +#define GL_DRAW_BUFFER14_ARB 0x8833 +#define GL_DRAW_BUFFER15_ARB 0x8834 +typedef void (APIENTRYP PFNGLDRAWBUFFERSARBPROC) (GLsizei n, const GLenum *bufs); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawBuffersARB (GLsizei n, const GLenum *bufs); +#endif +#endif /* GL_ARB_draw_buffers */ + +#ifndef GL_ARB_draw_buffers_blend +#define GL_ARB_draw_buffers_blend 1 +typedef void (APIENTRYP PFNGLBLENDEQUATIONIARBPROC) (GLuint buf, GLenum mode); +typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEIARBPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); +typedef void (APIENTRYP PFNGLBLENDFUNCIARBPROC) (GLuint buf, GLenum src, GLenum dst); +typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEIARBPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendEquationiARB (GLuint buf, GLenum mode); +GLAPI void APIENTRY glBlendEquationSeparateiARB (GLuint buf, GLenum modeRGB, GLenum modeAlpha); +GLAPI void APIENTRY glBlendFunciARB (GLuint buf, GLenum src, GLenum dst); +GLAPI void APIENTRY glBlendFuncSeparateiARB (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +#endif +#endif /* GL_ARB_draw_buffers_blend */ + +#ifndef GL_ARB_draw_elements_base_vertex +#define GL_ARB_draw_elements_base_vertex 1 +#endif /* GL_ARB_draw_elements_base_vertex */ + +#ifndef GL_ARB_draw_indirect +#define GL_ARB_draw_indirect 1 +#endif /* GL_ARB_draw_indirect */ + +#ifndef GL_ARB_draw_instanced +#define GL_ARB_draw_instanced 1 +typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDARBPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); +typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDARBPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawArraysInstancedARB (GLenum mode, GLint first, GLsizei count, GLsizei primcount); +GLAPI void APIENTRY glDrawElementsInstancedARB (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); +#endif +#endif /* GL_ARB_draw_instanced */ + +#ifndef GL_ARB_enhanced_layouts +#define GL_ARB_enhanced_layouts 1 +#endif /* GL_ARB_enhanced_layouts */ + +#ifndef GL_ARB_explicit_attrib_location +#define GL_ARB_explicit_attrib_location 1 +#endif /* GL_ARB_explicit_attrib_location */ + +#ifndef GL_ARB_explicit_uniform_location +#define GL_ARB_explicit_uniform_location 1 +#endif /* GL_ARB_explicit_uniform_location */ + +#ifndef GL_ARB_fragment_coord_conventions +#define GL_ARB_fragment_coord_conventions 1 +#endif /* GL_ARB_fragment_coord_conventions */ + +#ifndef GL_ARB_fragment_layer_viewport +#define GL_ARB_fragment_layer_viewport 1 +#endif /* GL_ARB_fragment_layer_viewport */ + +#ifndef GL_ARB_fragment_program +#define GL_ARB_fragment_program 1 +#define GL_FRAGMENT_PROGRAM_ARB 0x8804 +#define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875 +#define GL_PROGRAM_LENGTH_ARB 0x8627 +#define GL_PROGRAM_FORMAT_ARB 0x8876 +#define GL_PROGRAM_BINDING_ARB 0x8677 +#define GL_PROGRAM_INSTRUCTIONS_ARB 0x88A0 +#define GL_MAX_PROGRAM_INSTRUCTIONS_ARB 0x88A1 +#define GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2 +#define GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3 +#define GL_PROGRAM_TEMPORARIES_ARB 0x88A4 +#define GL_MAX_PROGRAM_TEMPORARIES_ARB 0x88A5 +#define GL_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6 +#define GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7 +#define GL_PROGRAM_PARAMETERS_ARB 0x88A8 +#define GL_MAX_PROGRAM_PARAMETERS_ARB 0x88A9 +#define GL_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AA +#define GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB +#define GL_PROGRAM_ATTRIBS_ARB 0x88AC +#define GL_MAX_PROGRAM_ATTRIBS_ARB 0x88AD +#define GL_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AE +#define GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF +#define GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4 +#define GL_MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5 +#define GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6 +#define GL_PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805 +#define GL_PROGRAM_TEX_INSTRUCTIONS_ARB 0x8806 +#define GL_PROGRAM_TEX_INDIRECTIONS_ARB 0x8807 +#define GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808 +#define GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809 +#define GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A +#define GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B +#define GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C +#define GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D +#define GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E +#define GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F +#define GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810 +#define GL_PROGRAM_STRING_ARB 0x8628 +#define GL_PROGRAM_ERROR_POSITION_ARB 0x864B +#define GL_CURRENT_MATRIX_ARB 0x8641 +#define GL_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7 +#define GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640 +#define GL_MAX_PROGRAM_MATRICES_ARB 0x862F +#define GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E +#define GL_MAX_TEXTURE_COORDS_ARB 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872 +#define GL_PROGRAM_ERROR_STRING_ARB 0x8874 +#define GL_MATRIX0_ARB 0x88C0 +#define GL_MATRIX1_ARB 0x88C1 +#define GL_MATRIX2_ARB 0x88C2 +#define GL_MATRIX3_ARB 0x88C3 +#define GL_MATRIX4_ARB 0x88C4 +#define GL_MATRIX5_ARB 0x88C5 +#define GL_MATRIX6_ARB 0x88C6 +#define GL_MATRIX7_ARB 0x88C7 +#define GL_MATRIX8_ARB 0x88C8 +#define GL_MATRIX9_ARB 0x88C9 +#define GL_MATRIX10_ARB 0x88CA +#define GL_MATRIX11_ARB 0x88CB +#define GL_MATRIX12_ARB 0x88CC +#define GL_MATRIX13_ARB 0x88CD +#define GL_MATRIX14_ARB 0x88CE +#define GL_MATRIX15_ARB 0x88CF +#define GL_MATRIX16_ARB 0x88D0 +#define GL_MATRIX17_ARB 0x88D1 +#define GL_MATRIX18_ARB 0x88D2 +#define GL_MATRIX19_ARB 0x88D3 +#define GL_MATRIX20_ARB 0x88D4 +#define GL_MATRIX21_ARB 0x88D5 +#define GL_MATRIX22_ARB 0x88D6 +#define GL_MATRIX23_ARB 0x88D7 +#define GL_MATRIX24_ARB 0x88D8 +#define GL_MATRIX25_ARB 0x88D9 +#define GL_MATRIX26_ARB 0x88DA +#define GL_MATRIX27_ARB 0x88DB +#define GL_MATRIX28_ARB 0x88DC +#define GL_MATRIX29_ARB 0x88DD +#define GL_MATRIX30_ARB 0x88DE +#define GL_MATRIX31_ARB 0x88DF +typedef void (APIENTRYP PFNGLPROGRAMSTRINGARBPROC) (GLenum target, GLenum format, GLsizei len, const void *string); +typedef void (APIENTRYP PFNGLBINDPROGRAMARBPROC) (GLenum target, GLuint program); +typedef void (APIENTRYP PFNGLDELETEPROGRAMSARBPROC) (GLsizei n, const GLuint *programs); +typedef void (APIENTRYP PFNGLGENPROGRAMSARBPROC) (GLsizei n, GLuint *programs); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params); +typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params); +typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params); +typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params); +typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params); +typedef void (APIENTRYP PFNGLGETPROGRAMIVARBPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMSTRINGARBPROC) (GLenum target, GLenum pname, void *string); +typedef GLboolean (APIENTRYP PFNGLISPROGRAMARBPROC) (GLuint program); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glProgramStringARB (GLenum target, GLenum format, GLsizei len, const void *string); +GLAPI void APIENTRY glBindProgramARB (GLenum target, GLuint program); +GLAPI void APIENTRY glDeleteProgramsARB (GLsizei n, const GLuint *programs); +GLAPI void APIENTRY glGenProgramsARB (GLsizei n, GLuint *programs); +GLAPI void APIENTRY glProgramEnvParameter4dARB (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void APIENTRY glProgramEnvParameter4dvARB (GLenum target, GLuint index, const GLdouble *params); +GLAPI void APIENTRY glProgramEnvParameter4fARB (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void APIENTRY glProgramEnvParameter4fvARB (GLenum target, GLuint index, const GLfloat *params); +GLAPI void APIENTRY glProgramLocalParameter4dARB (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void APIENTRY glProgramLocalParameter4dvARB (GLenum target, GLuint index, const GLdouble *params); +GLAPI void APIENTRY glProgramLocalParameter4fARB (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void APIENTRY glProgramLocalParameter4fvARB (GLenum target, GLuint index, const GLfloat *params); +GLAPI void APIENTRY glGetProgramEnvParameterdvARB (GLenum target, GLuint index, GLdouble *params); +GLAPI void APIENTRY glGetProgramEnvParameterfvARB (GLenum target, GLuint index, GLfloat *params); +GLAPI void APIENTRY glGetProgramLocalParameterdvARB (GLenum target, GLuint index, GLdouble *params); +GLAPI void APIENTRY glGetProgramLocalParameterfvARB (GLenum target, GLuint index, GLfloat *params); +GLAPI void APIENTRY glGetProgramivARB (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetProgramStringARB (GLenum target, GLenum pname, void *string); +GLAPI GLboolean APIENTRY glIsProgramARB (GLuint program); +#endif +#endif /* GL_ARB_fragment_program */ + +#ifndef GL_ARB_fragment_program_shadow +#define GL_ARB_fragment_program_shadow 1 +#endif /* GL_ARB_fragment_program_shadow */ + +#ifndef GL_ARB_fragment_shader +#define GL_ARB_fragment_shader 1 +#define GL_FRAGMENT_SHADER_ARB 0x8B30 +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49 +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB 0x8B8B +#endif /* GL_ARB_fragment_shader */ + +#ifndef GL_ARB_framebuffer_no_attachments +#define GL_ARB_framebuffer_no_attachments 1 +#endif /* GL_ARB_framebuffer_no_attachments */ + +#ifndef GL_ARB_framebuffer_object +#define GL_ARB_framebuffer_object 1 +#endif /* GL_ARB_framebuffer_object */ + +#ifndef GL_ARB_framebuffer_sRGB +#define GL_ARB_framebuffer_sRGB 1 +#endif /* GL_ARB_framebuffer_sRGB */ + +#ifndef GL_ARB_geometry_shader4 +#define GL_ARB_geometry_shader4 1 +#define GL_LINES_ADJACENCY_ARB 0x000A +#define GL_LINE_STRIP_ADJACENCY_ARB 0x000B +#define GL_TRIANGLES_ADJACENCY_ARB 0x000C +#define GL_TRIANGLE_STRIP_ADJACENCY_ARB 0x000D +#define GL_PROGRAM_POINT_SIZE_ARB 0x8642 +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB 0x8C29 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_ARB 0x8DA7 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB 0x8DA8 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB 0x8DA9 +#define GL_GEOMETRY_SHADER_ARB 0x8DD9 +#define GL_GEOMETRY_VERTICES_OUT_ARB 0x8DDA +#define GL_GEOMETRY_INPUT_TYPE_ARB 0x8DDB +#define GL_GEOMETRY_OUTPUT_TYPE_ARB 0x8DDC +#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB 0x8DDD +#define GL_MAX_VERTEX_VARYING_COMPONENTS_ARB 0x8DDE +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB 0x8DDF +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB 0x8DE0 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB 0x8DE1 +typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIARBPROC) (GLuint program, GLenum pname, GLint value); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREFACEARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glProgramParameteriARB (GLuint program, GLenum pname, GLint value); +GLAPI void APIENTRY glFramebufferTextureARB (GLenum target, GLenum attachment, GLuint texture, GLint level); +GLAPI void APIENTRY glFramebufferTextureLayerARB (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +GLAPI void APIENTRY glFramebufferTextureFaceARB (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); +#endif +#endif /* GL_ARB_geometry_shader4 */ + +#ifndef GL_ARB_get_program_binary +#define GL_ARB_get_program_binary 1 +#endif /* GL_ARB_get_program_binary */ + +#ifndef GL_ARB_get_texture_sub_image +#define GL_ARB_get_texture_sub_image 1 +#endif /* GL_ARB_get_texture_sub_image */ + +#ifndef GL_ARB_gpu_shader5 +#define GL_ARB_gpu_shader5 1 +#endif /* GL_ARB_gpu_shader5 */ + +#ifndef GL_ARB_gpu_shader_fp64 +#define GL_ARB_gpu_shader_fp64 1 +#endif /* GL_ARB_gpu_shader_fp64 */ + +#ifndef GL_ARB_half_float_pixel +#define GL_ARB_half_float_pixel 1 +typedef unsigned short GLhalfARB; +#define GL_HALF_FLOAT_ARB 0x140B +#endif /* GL_ARB_half_float_pixel */ + +#ifndef GL_ARB_half_float_vertex +#define GL_ARB_half_float_vertex 1 +#endif /* GL_ARB_half_float_vertex */ + +#ifndef GL_ARB_imaging +#define GL_ARB_imaging 1 +#define GL_BLEND_COLOR 0x8005 +#define GL_BLEND_EQUATION 0x8009 +#define GL_CONVOLUTION_1D 0x8010 +#define GL_CONVOLUTION_2D 0x8011 +#define GL_SEPARABLE_2D 0x8012 +#define GL_CONVOLUTION_BORDER_MODE 0x8013 +#define GL_CONVOLUTION_FILTER_SCALE 0x8014 +#define GL_CONVOLUTION_FILTER_BIAS 0x8015 +#define GL_REDUCE 0x8016 +#define GL_CONVOLUTION_FORMAT 0x8017 +#define GL_CONVOLUTION_WIDTH 0x8018 +#define GL_CONVOLUTION_HEIGHT 0x8019 +#define GL_MAX_CONVOLUTION_WIDTH 0x801A +#define GL_MAX_CONVOLUTION_HEIGHT 0x801B +#define GL_POST_CONVOLUTION_RED_SCALE 0x801C +#define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D +#define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E +#define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F +#define GL_POST_CONVOLUTION_RED_BIAS 0x8020 +#define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021 +#define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022 +#define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023 +#define GL_HISTOGRAM 0x8024 +#define GL_PROXY_HISTOGRAM 0x8025 +#define GL_HISTOGRAM_WIDTH 0x8026 +#define GL_HISTOGRAM_FORMAT 0x8027 +#define GL_HISTOGRAM_RED_SIZE 0x8028 +#define GL_HISTOGRAM_GREEN_SIZE 0x8029 +#define GL_HISTOGRAM_BLUE_SIZE 0x802A +#define GL_HISTOGRAM_ALPHA_SIZE 0x802B +#define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C +#define GL_HISTOGRAM_SINK 0x802D +#define GL_MINMAX 0x802E +#define GL_MINMAX_FORMAT 0x802F +#define GL_MINMAX_SINK 0x8030 +#define GL_TABLE_TOO_LARGE 0x8031 +#define GL_COLOR_MATRIX 0x80B1 +#define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2 +#define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3 +#define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4 +#define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5 +#define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6 +#define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7 +#define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8 +#define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9 +#define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA +#define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB +#define GL_COLOR_TABLE 0x80D0 +#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2 +#define GL_PROXY_COLOR_TABLE 0x80D3 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5 +#define GL_COLOR_TABLE_SCALE 0x80D6 +#define GL_COLOR_TABLE_BIAS 0x80D7 +#define GL_COLOR_TABLE_FORMAT 0x80D8 +#define GL_COLOR_TABLE_WIDTH 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF +#define GL_CONSTANT_BORDER 0x8151 +#define GL_REPLICATE_BORDER 0x8153 +#define GL_CONVOLUTION_BORDER_COLOR 0x8154 +typedef void (APIENTRYP PFNGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *table); +typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLCOPYCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (APIENTRYP PFNGLGETCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, void *table); +typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const void *data); +typedef void (APIENTRYP PFNGLCOPYCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); +typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *image); +typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *image); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat params); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIPROC) (GLenum target, GLenum pname, GLint params); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLGETCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, void *image); +typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, void *row, void *column, void *span); +typedef void (APIENTRYP PFNGLSEPARABLEFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *row, const void *column); +typedef void (APIENTRYP PFNGLGETHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); +typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); +typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLHISTOGRAMPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); +typedef void (APIENTRYP PFNGLMINMAXPROC) (GLenum target, GLenum internalformat, GLboolean sink); +typedef void (APIENTRYP PFNGLRESETHISTOGRAMPROC) (GLenum target); +typedef void (APIENTRYP PFNGLRESETMINMAXPROC) (GLenum target); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glColorTable (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *table); +GLAPI void APIENTRY glColorTableParameterfv (GLenum target, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glColorTableParameteriv (GLenum target, GLenum pname, const GLint *params); +GLAPI void APIENTRY glCopyColorTable (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +GLAPI void APIENTRY glGetColorTable (GLenum target, GLenum format, GLenum type, void *table); +GLAPI void APIENTRY glGetColorTableParameterfv (GLenum target, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetColorTableParameteriv (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glColorSubTable (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const void *data); +GLAPI void APIENTRY glCopyColorSubTable (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); +GLAPI void APIENTRY glConvolutionFilter1D (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *image); +GLAPI void APIENTRY glConvolutionFilter2D (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *image); +GLAPI void APIENTRY glConvolutionParameterf (GLenum target, GLenum pname, GLfloat params); +GLAPI void APIENTRY glConvolutionParameterfv (GLenum target, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glConvolutionParameteri (GLenum target, GLenum pname, GLint params); +GLAPI void APIENTRY glConvolutionParameteriv (GLenum target, GLenum pname, const GLint *params); +GLAPI void APIENTRY glCopyConvolutionFilter1D (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +GLAPI void APIENTRY glCopyConvolutionFilter2D (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void APIENTRY glGetConvolutionFilter (GLenum target, GLenum format, GLenum type, void *image); +GLAPI void APIENTRY glGetConvolutionParameterfv (GLenum target, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetConvolutionParameteriv (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetSeparableFilter (GLenum target, GLenum format, GLenum type, void *row, void *column, void *span); +GLAPI void APIENTRY glSeparableFilter2D (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *row, const void *column); +GLAPI void APIENTRY glGetHistogram (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); +GLAPI void APIENTRY glGetHistogramParameterfv (GLenum target, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetHistogramParameteriv (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetMinmax (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); +GLAPI void APIENTRY glGetMinmaxParameterfv (GLenum target, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetMinmaxParameteriv (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glHistogram (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); +GLAPI void APIENTRY glMinmax (GLenum target, GLenum internalformat, GLboolean sink); +GLAPI void APIENTRY glResetHistogram (GLenum target); +GLAPI void APIENTRY glResetMinmax (GLenum target); +#endif +#endif /* GL_ARB_imaging */ + +#ifndef GL_ARB_indirect_parameters +#define GL_ARB_indirect_parameters 1 +#define GL_PARAMETER_BUFFER_ARB 0x80EE +#define GL_PARAMETER_BUFFER_BINDING_ARB 0x80EF +typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC) (GLenum mode, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC) (GLenum mode, GLenum type, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMultiDrawArraysIndirectCountARB (GLenum mode, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +GLAPI void APIENTRY glMultiDrawElementsIndirectCountARB (GLenum mode, GLenum type, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +#endif +#endif /* GL_ARB_indirect_parameters */ + +#ifndef GL_ARB_instanced_arrays +#define GL_ARB_instanced_arrays 1 +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB 0x88FE +typedef void (APIENTRYP PFNGLVERTEXATTRIBDIVISORARBPROC) (GLuint index, GLuint divisor); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexAttribDivisorARB (GLuint index, GLuint divisor); +#endif +#endif /* GL_ARB_instanced_arrays */ + +#ifndef GL_ARB_internalformat_query +#define GL_ARB_internalformat_query 1 +#endif /* GL_ARB_internalformat_query */ + +#ifndef GL_ARB_internalformat_query2 +#define GL_ARB_internalformat_query2 1 +#define GL_SRGB_DECODE_ARB 0x8299 +#endif /* GL_ARB_internalformat_query2 */ + +#ifndef GL_ARB_invalidate_subdata +#define GL_ARB_invalidate_subdata 1 +#endif /* GL_ARB_invalidate_subdata */ + +#ifndef GL_ARB_map_buffer_alignment +#define GL_ARB_map_buffer_alignment 1 +#endif /* GL_ARB_map_buffer_alignment */ + +#ifndef GL_ARB_map_buffer_range +#define GL_ARB_map_buffer_range 1 +#endif /* GL_ARB_map_buffer_range */ + +#ifndef GL_ARB_matrix_palette +#define GL_ARB_matrix_palette 1 +#define GL_MATRIX_PALETTE_ARB 0x8840 +#define GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB 0x8841 +#define GL_MAX_PALETTE_MATRICES_ARB 0x8842 +#define GL_CURRENT_PALETTE_MATRIX_ARB 0x8843 +#define GL_MATRIX_INDEX_ARRAY_ARB 0x8844 +#define GL_CURRENT_MATRIX_INDEX_ARB 0x8845 +#define GL_MATRIX_INDEX_ARRAY_SIZE_ARB 0x8846 +#define GL_MATRIX_INDEX_ARRAY_TYPE_ARB 0x8847 +#define GL_MATRIX_INDEX_ARRAY_STRIDE_ARB 0x8848 +#define GL_MATRIX_INDEX_ARRAY_POINTER_ARB 0x8849 +typedef void (APIENTRYP PFNGLCURRENTPALETTEMATRIXARBPROC) (GLint index); +typedef void (APIENTRYP PFNGLMATRIXINDEXUBVARBPROC) (GLint size, const GLubyte *indices); +typedef void (APIENTRYP PFNGLMATRIXINDEXUSVARBPROC) (GLint size, const GLushort *indices); +typedef void (APIENTRYP PFNGLMATRIXINDEXUIVARBPROC) (GLint size, const GLuint *indices); +typedef void (APIENTRYP PFNGLMATRIXINDEXPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const void *pointer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glCurrentPaletteMatrixARB (GLint index); +GLAPI void APIENTRY glMatrixIndexubvARB (GLint size, const GLubyte *indices); +GLAPI void APIENTRY glMatrixIndexusvARB (GLint size, const GLushort *indices); +GLAPI void APIENTRY glMatrixIndexuivARB (GLint size, const GLuint *indices); +GLAPI void APIENTRY glMatrixIndexPointerARB (GLint size, GLenum type, GLsizei stride, const void *pointer); +#endif +#endif /* GL_ARB_matrix_palette */ + +#ifndef GL_ARB_multi_bind +#define GL_ARB_multi_bind 1 +#endif /* GL_ARB_multi_bind */ + +#ifndef GL_ARB_multi_draw_indirect +#define GL_ARB_multi_draw_indirect 1 +#endif /* GL_ARB_multi_draw_indirect */ + +#ifndef GL_ARB_multisample +#define GL_ARB_multisample 1 +#define GL_MULTISAMPLE_ARB 0x809D +#define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F +#define GL_SAMPLE_COVERAGE_ARB 0x80A0 +#define GL_SAMPLE_BUFFERS_ARB 0x80A8 +#define GL_SAMPLES_ARB 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB +#define GL_MULTISAMPLE_BIT_ARB 0x20000000 +typedef void (APIENTRYP PFNGLSAMPLECOVERAGEARBPROC) (GLfloat value, GLboolean invert); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSampleCoverageARB (GLfloat value, GLboolean invert); +#endif +#endif /* GL_ARB_multisample */ + +#ifndef GL_ARB_multitexture +#define GL_ARB_multitexture 1 +#define GL_TEXTURE0_ARB 0x84C0 +#define GL_TEXTURE1_ARB 0x84C1 +#define GL_TEXTURE2_ARB 0x84C2 +#define GL_TEXTURE3_ARB 0x84C3 +#define GL_TEXTURE4_ARB 0x84C4 +#define GL_TEXTURE5_ARB 0x84C5 +#define GL_TEXTURE6_ARB 0x84C6 +#define GL_TEXTURE7_ARB 0x84C7 +#define GL_TEXTURE8_ARB 0x84C8 +#define GL_TEXTURE9_ARB 0x84C9 +#define GL_TEXTURE10_ARB 0x84CA +#define GL_TEXTURE11_ARB 0x84CB +#define GL_TEXTURE12_ARB 0x84CC +#define GL_TEXTURE13_ARB 0x84CD +#define GL_TEXTURE14_ARB 0x84CE +#define GL_TEXTURE15_ARB 0x84CF +#define GL_TEXTURE16_ARB 0x84D0 +#define GL_TEXTURE17_ARB 0x84D1 +#define GL_TEXTURE18_ARB 0x84D2 +#define GL_TEXTURE19_ARB 0x84D3 +#define GL_TEXTURE20_ARB 0x84D4 +#define GL_TEXTURE21_ARB 0x84D5 +#define GL_TEXTURE22_ARB 0x84D6 +#define GL_TEXTURE23_ARB 0x84D7 +#define GL_TEXTURE24_ARB 0x84D8 +#define GL_TEXTURE25_ARB 0x84D9 +#define GL_TEXTURE26_ARB 0x84DA +#define GL_TEXTURE27_ARB 0x84DB +#define GL_TEXTURE28_ARB 0x84DC +#define GL_TEXTURE29_ARB 0x84DD +#define GL_TEXTURE30_ARB 0x84DE +#define GL_TEXTURE31_ARB 0x84DF +#define GL_ACTIVE_TEXTURE_ARB 0x84E0 +#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 +#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 +typedef void (APIENTRYP PFNGLACTIVETEXTUREARBPROC) (GLenum texture); +typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort *v); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glActiveTextureARB (GLenum texture); +GLAPI void APIENTRY glClientActiveTextureARB (GLenum texture); +GLAPI void APIENTRY glMultiTexCoord1dARB (GLenum target, GLdouble s); +GLAPI void APIENTRY glMultiTexCoord1dvARB (GLenum target, const GLdouble *v); +GLAPI void APIENTRY glMultiTexCoord1fARB (GLenum target, GLfloat s); +GLAPI void APIENTRY glMultiTexCoord1fvARB (GLenum target, const GLfloat *v); +GLAPI void APIENTRY glMultiTexCoord1iARB (GLenum target, GLint s); +GLAPI void APIENTRY glMultiTexCoord1ivARB (GLenum target, const GLint *v); +GLAPI void APIENTRY glMultiTexCoord1sARB (GLenum target, GLshort s); +GLAPI void APIENTRY glMultiTexCoord1svARB (GLenum target, const GLshort *v); +GLAPI void APIENTRY glMultiTexCoord2dARB (GLenum target, GLdouble s, GLdouble t); +GLAPI void APIENTRY glMultiTexCoord2dvARB (GLenum target, const GLdouble *v); +GLAPI void APIENTRY glMultiTexCoord2fARB (GLenum target, GLfloat s, GLfloat t); +GLAPI void APIENTRY glMultiTexCoord2fvARB (GLenum target, const GLfloat *v); +GLAPI void APIENTRY glMultiTexCoord2iARB (GLenum target, GLint s, GLint t); +GLAPI void APIENTRY glMultiTexCoord2ivARB (GLenum target, const GLint *v); +GLAPI void APIENTRY glMultiTexCoord2sARB (GLenum target, GLshort s, GLshort t); +GLAPI void APIENTRY glMultiTexCoord2svARB (GLenum target, const GLshort *v); +GLAPI void APIENTRY glMultiTexCoord3dARB (GLenum target, GLdouble s, GLdouble t, GLdouble r); +GLAPI void APIENTRY glMultiTexCoord3dvARB (GLenum target, const GLdouble *v); +GLAPI void APIENTRY glMultiTexCoord3fARB (GLenum target, GLfloat s, GLfloat t, GLfloat r); +GLAPI void APIENTRY glMultiTexCoord3fvARB (GLenum target, const GLfloat *v); +GLAPI void APIENTRY glMultiTexCoord3iARB (GLenum target, GLint s, GLint t, GLint r); +GLAPI void APIENTRY glMultiTexCoord3ivARB (GLenum target, const GLint *v); +GLAPI void APIENTRY glMultiTexCoord3sARB (GLenum target, GLshort s, GLshort t, GLshort r); +GLAPI void APIENTRY glMultiTexCoord3svARB (GLenum target, const GLshort *v); +GLAPI void APIENTRY glMultiTexCoord4dARB (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +GLAPI void APIENTRY glMultiTexCoord4dvARB (GLenum target, const GLdouble *v); +GLAPI void APIENTRY glMultiTexCoord4fARB (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +GLAPI void APIENTRY glMultiTexCoord4fvARB (GLenum target, const GLfloat *v); +GLAPI void APIENTRY glMultiTexCoord4iARB (GLenum target, GLint s, GLint t, GLint r, GLint q); +GLAPI void APIENTRY glMultiTexCoord4ivARB (GLenum target, const GLint *v); +GLAPI void APIENTRY glMultiTexCoord4sARB (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +GLAPI void APIENTRY glMultiTexCoord4svARB (GLenum target, const GLshort *v); +#endif +#endif /* GL_ARB_multitexture */ + +#ifndef GL_ARB_occlusion_query +#define GL_ARB_occlusion_query 1 +#define GL_QUERY_COUNTER_BITS_ARB 0x8864 +#define GL_CURRENT_QUERY_ARB 0x8865 +#define GL_QUERY_RESULT_ARB 0x8866 +#define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867 +#define GL_SAMPLES_PASSED_ARB 0x8914 +typedef void (APIENTRYP PFNGLGENQUERIESARBPROC) (GLsizei n, GLuint *ids); +typedef void (APIENTRYP PFNGLDELETEQUERIESARBPROC) (GLsizei n, const GLuint *ids); +typedef GLboolean (APIENTRYP PFNGLISQUERYARBPROC) (GLuint id); +typedef void (APIENTRYP PFNGLBEGINQUERYARBPROC) (GLenum target, GLuint id); +typedef void (APIENTRYP PFNGLENDQUERYARBPROC) (GLenum target); +typedef void (APIENTRYP PFNGLGETQUERYIVARBPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVARBPROC) (GLuint id, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVARBPROC) (GLuint id, GLenum pname, GLuint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGenQueriesARB (GLsizei n, GLuint *ids); +GLAPI void APIENTRY glDeleteQueriesARB (GLsizei n, const GLuint *ids); +GLAPI GLboolean APIENTRY glIsQueryARB (GLuint id); +GLAPI void APIENTRY glBeginQueryARB (GLenum target, GLuint id); +GLAPI void APIENTRY glEndQueryARB (GLenum target); +GLAPI void APIENTRY glGetQueryivARB (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetQueryObjectivARB (GLuint id, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetQueryObjectuivARB (GLuint id, GLenum pname, GLuint *params); +#endif +#endif /* GL_ARB_occlusion_query */ + +#ifndef GL_ARB_occlusion_query2 +#define GL_ARB_occlusion_query2 1 +#endif /* GL_ARB_occlusion_query2 */ + +#ifndef GL_ARB_pipeline_statistics_query +#define GL_ARB_pipeline_statistics_query 1 +#define GL_VERTICES_SUBMITTED_ARB 0x82EE +#define GL_PRIMITIVES_SUBMITTED_ARB 0x82EF +#define GL_VERTEX_SHADER_INVOCATIONS_ARB 0x82F0 +#define GL_TESS_CONTROL_SHADER_PATCHES_ARB 0x82F1 +#define GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB 0x82F2 +#define GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB 0x82F3 +#define GL_FRAGMENT_SHADER_INVOCATIONS_ARB 0x82F4 +#define GL_COMPUTE_SHADER_INVOCATIONS_ARB 0x82F5 +#define GL_CLIPPING_INPUT_PRIMITIVES_ARB 0x82F6 +#define GL_CLIPPING_OUTPUT_PRIMITIVES_ARB 0x82F7 +#endif /* GL_ARB_pipeline_statistics_query */ + +#ifndef GL_ARB_pixel_buffer_object +#define GL_ARB_pixel_buffer_object 1 +#define GL_PIXEL_PACK_BUFFER_ARB 0x88EB +#define GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF +#endif /* GL_ARB_pixel_buffer_object */ + +#ifndef GL_ARB_point_parameters +#define GL_ARB_point_parameters 1 +#define GL_POINT_SIZE_MIN_ARB 0x8126 +#define GL_POINT_SIZE_MAX_ARB 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_ARB 0x8128 +#define GL_POINT_DISTANCE_ATTENUATION_ARB 0x8129 +typedef void (APIENTRYP PFNGLPOINTPARAMETERFARBPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLPOINTPARAMETERFVARBPROC) (GLenum pname, const GLfloat *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPointParameterfARB (GLenum pname, GLfloat param); +GLAPI void APIENTRY glPointParameterfvARB (GLenum pname, const GLfloat *params); +#endif +#endif /* GL_ARB_point_parameters */ + +#ifndef GL_ARB_point_sprite +#define GL_ARB_point_sprite 1 +#define GL_POINT_SPRITE_ARB 0x8861 +#define GL_COORD_REPLACE_ARB 0x8862 +#endif /* GL_ARB_point_sprite */ + +#ifndef GL_ARB_program_interface_query +#define GL_ARB_program_interface_query 1 +#endif /* GL_ARB_program_interface_query */ + +#ifndef GL_ARB_provoking_vertex +#define GL_ARB_provoking_vertex 1 +#endif /* GL_ARB_provoking_vertex */ + +#ifndef GL_ARB_query_buffer_object +#define GL_ARB_query_buffer_object 1 +#endif /* GL_ARB_query_buffer_object */ + +#ifndef GL_ARB_robust_buffer_access_behavior +#define GL_ARB_robust_buffer_access_behavior 1 +#endif /* GL_ARB_robust_buffer_access_behavior */ + +#ifndef GL_ARB_robustness +#define GL_ARB_robustness 1 +#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB 0x00000004 +#define GL_LOSE_CONTEXT_ON_RESET_ARB 0x8252 +#define GL_GUILTY_CONTEXT_RESET_ARB 0x8253 +#define GL_INNOCENT_CONTEXT_RESET_ARB 0x8254 +#define GL_UNKNOWN_CONTEXT_RESET_ARB 0x8255 +#define GL_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 +#define GL_NO_RESET_NOTIFICATION_ARB 0x8261 +typedef GLenum (APIENTRYP PFNGLGETGRAPHICSRESETSTATUSARBPROC) (void); +typedef void (APIENTRYP PFNGLGETNTEXIMAGEARBPROC) (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *img); +typedef void (APIENTRYP PFNGLREADNPIXELSARBPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); +typedef void (APIENTRYP PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint lod, GLsizei bufSize, void *img); +typedef void (APIENTRYP PFNGLGETNUNIFORMFVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); +typedef void (APIENTRYP PFNGLGETNUNIFORMIVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params); +typedef void (APIENTRYP PFNGLGETNUNIFORMUIVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint *params); +typedef void (APIENTRYP PFNGLGETNUNIFORMDVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLdouble *params); +typedef void (APIENTRYP PFNGLGETNMAPDVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLdouble *v); +typedef void (APIENTRYP PFNGLGETNMAPFVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLfloat *v); +typedef void (APIENTRYP PFNGLGETNMAPIVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLint *v); +typedef void (APIENTRYP PFNGLGETNPIXELMAPFVARBPROC) (GLenum map, GLsizei bufSize, GLfloat *values); +typedef void (APIENTRYP PFNGLGETNPIXELMAPUIVARBPROC) (GLenum map, GLsizei bufSize, GLuint *values); +typedef void (APIENTRYP PFNGLGETNPIXELMAPUSVARBPROC) (GLenum map, GLsizei bufSize, GLushort *values); +typedef void (APIENTRYP PFNGLGETNPOLYGONSTIPPLEARBPROC) (GLsizei bufSize, GLubyte *pattern); +typedef void (APIENTRYP PFNGLGETNCOLORTABLEARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *table); +typedef void (APIENTRYP PFNGLGETNCONVOLUTIONFILTERARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *image); +typedef void (APIENTRYP PFNGLGETNSEPARABLEFILTERARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, void *row, GLsizei columnBufSize, void *column, void *span); +typedef void (APIENTRYP PFNGLGETNHISTOGRAMARBPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void *values); +typedef void (APIENTRYP PFNGLGETNMINMAXARBPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void *values); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLenum APIENTRY glGetGraphicsResetStatusARB (void); +GLAPI void APIENTRY glGetnTexImageARB (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *img); +GLAPI void APIENTRY glReadnPixelsARB (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); +GLAPI void APIENTRY glGetnCompressedTexImageARB (GLenum target, GLint lod, GLsizei bufSize, void *img); +GLAPI void APIENTRY glGetnUniformfvARB (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); +GLAPI void APIENTRY glGetnUniformivARB (GLuint program, GLint location, GLsizei bufSize, GLint *params); +GLAPI void APIENTRY glGetnUniformuivARB (GLuint program, GLint location, GLsizei bufSize, GLuint *params); +GLAPI void APIENTRY glGetnUniformdvARB (GLuint program, GLint location, GLsizei bufSize, GLdouble *params); +GLAPI void APIENTRY glGetnMapdvARB (GLenum target, GLenum query, GLsizei bufSize, GLdouble *v); +GLAPI void APIENTRY glGetnMapfvARB (GLenum target, GLenum query, GLsizei bufSize, GLfloat *v); +GLAPI void APIENTRY glGetnMapivARB (GLenum target, GLenum query, GLsizei bufSize, GLint *v); +GLAPI void APIENTRY glGetnPixelMapfvARB (GLenum map, GLsizei bufSize, GLfloat *values); +GLAPI void APIENTRY glGetnPixelMapuivARB (GLenum map, GLsizei bufSize, GLuint *values); +GLAPI void APIENTRY glGetnPixelMapusvARB (GLenum map, GLsizei bufSize, GLushort *values); +GLAPI void APIENTRY glGetnPolygonStippleARB (GLsizei bufSize, GLubyte *pattern); +GLAPI void APIENTRY glGetnColorTableARB (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *table); +GLAPI void APIENTRY glGetnConvolutionFilterARB (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *image); +GLAPI void APIENTRY glGetnSeparableFilterARB (GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, void *row, GLsizei columnBufSize, void *column, void *span); +GLAPI void APIENTRY glGetnHistogramARB (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void *values); +GLAPI void APIENTRY glGetnMinmaxARB (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void *values); +#endif +#endif /* GL_ARB_robustness */ + +#ifndef GL_ARB_robustness_isolation +#define GL_ARB_robustness_isolation 1 +#endif /* GL_ARB_robustness_isolation */ + +#ifndef GL_ARB_sample_shading +#define GL_ARB_sample_shading 1 +#define GL_SAMPLE_SHADING_ARB 0x8C36 +#define GL_MIN_SAMPLE_SHADING_VALUE_ARB 0x8C37 +typedef void (APIENTRYP PFNGLMINSAMPLESHADINGARBPROC) (GLfloat value); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMinSampleShadingARB (GLfloat value); +#endif +#endif /* GL_ARB_sample_shading */ + +#ifndef GL_ARB_sampler_objects +#define GL_ARB_sampler_objects 1 +#endif /* GL_ARB_sampler_objects */ + +#ifndef GL_ARB_seamless_cube_map +#define GL_ARB_seamless_cube_map 1 +#endif /* GL_ARB_seamless_cube_map */ + +#ifndef GL_ARB_seamless_cubemap_per_texture +#define GL_ARB_seamless_cubemap_per_texture 1 +#endif /* GL_ARB_seamless_cubemap_per_texture */ + +#ifndef GL_ARB_separate_shader_objects +#define GL_ARB_separate_shader_objects 1 +#endif /* GL_ARB_separate_shader_objects */ + +#ifndef GL_ARB_shader_atomic_counters +#define GL_ARB_shader_atomic_counters 1 +#endif /* GL_ARB_shader_atomic_counters */ + +#ifndef GL_ARB_shader_bit_encoding +#define GL_ARB_shader_bit_encoding 1 +#endif /* GL_ARB_shader_bit_encoding */ + +#ifndef GL_ARB_shader_draw_parameters +#define GL_ARB_shader_draw_parameters 1 +#endif /* GL_ARB_shader_draw_parameters */ + +#ifndef GL_ARB_shader_group_vote +#define GL_ARB_shader_group_vote 1 +#endif /* GL_ARB_shader_group_vote */ + +#ifndef GL_ARB_shader_image_load_store +#define GL_ARB_shader_image_load_store 1 +#endif /* GL_ARB_shader_image_load_store */ + +#ifndef GL_ARB_shader_image_size +#define GL_ARB_shader_image_size 1 +#endif /* GL_ARB_shader_image_size */ + +#ifndef GL_ARB_shader_objects +#define GL_ARB_shader_objects 1 +#ifdef __APPLE__ +typedef void *GLhandleARB; +#else +typedef unsigned int GLhandleARB; +#endif +typedef char GLcharARB; +#define GL_PROGRAM_OBJECT_ARB 0x8B40 +#define GL_SHADER_OBJECT_ARB 0x8B48 +#define GL_OBJECT_TYPE_ARB 0x8B4E +#define GL_OBJECT_SUBTYPE_ARB 0x8B4F +#define GL_FLOAT_VEC2_ARB 0x8B50 +#define GL_FLOAT_VEC3_ARB 0x8B51 +#define GL_FLOAT_VEC4_ARB 0x8B52 +#define GL_INT_VEC2_ARB 0x8B53 +#define GL_INT_VEC3_ARB 0x8B54 +#define GL_INT_VEC4_ARB 0x8B55 +#define GL_BOOL_ARB 0x8B56 +#define GL_BOOL_VEC2_ARB 0x8B57 +#define GL_BOOL_VEC3_ARB 0x8B58 +#define GL_BOOL_VEC4_ARB 0x8B59 +#define GL_FLOAT_MAT2_ARB 0x8B5A +#define GL_FLOAT_MAT3_ARB 0x8B5B +#define GL_FLOAT_MAT4_ARB 0x8B5C +#define GL_SAMPLER_1D_ARB 0x8B5D +#define GL_SAMPLER_2D_ARB 0x8B5E +#define GL_SAMPLER_3D_ARB 0x8B5F +#define GL_SAMPLER_CUBE_ARB 0x8B60 +#define GL_SAMPLER_1D_SHADOW_ARB 0x8B61 +#define GL_SAMPLER_2D_SHADOW_ARB 0x8B62 +#define GL_SAMPLER_2D_RECT_ARB 0x8B63 +#define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64 +#define GL_OBJECT_DELETE_STATUS_ARB 0x8B80 +#define GL_OBJECT_COMPILE_STATUS_ARB 0x8B81 +#define GL_OBJECT_LINK_STATUS_ARB 0x8B82 +#define GL_OBJECT_VALIDATE_STATUS_ARB 0x8B83 +#define GL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84 +#define GL_OBJECT_ATTACHED_OBJECTS_ARB 0x8B85 +#define GL_OBJECT_ACTIVE_UNIFORMS_ARB 0x8B86 +#define GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB 0x8B87 +#define GL_OBJECT_SHADER_SOURCE_LENGTH_ARB 0x8B88 +typedef void (APIENTRYP PFNGLDELETEOBJECTARBPROC) (GLhandleARB obj); +typedef GLhandleARB (APIENTRYP PFNGLGETHANDLEARBPROC) (GLenum pname); +typedef void (APIENTRYP PFNGLDETACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB attachedObj); +typedef GLhandleARB (APIENTRYP PFNGLCREATESHADEROBJECTARBPROC) (GLenum shaderType); +typedef void (APIENTRYP PFNGLSHADERSOURCEARBPROC) (GLhandleARB shaderObj, GLsizei count, const GLcharARB **string, const GLint *length); +typedef void (APIENTRYP PFNGLCOMPILESHADERARBPROC) (GLhandleARB shaderObj); +typedef GLhandleARB (APIENTRYP PFNGLCREATEPROGRAMOBJECTARBPROC) (void); +typedef void (APIENTRYP PFNGLATTACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB obj); +typedef void (APIENTRYP PFNGLLINKPROGRAMARBPROC) (GLhandleARB programObj); +typedef void (APIENTRYP PFNGLUSEPROGRAMOBJECTARBPROC) (GLhandleARB programObj); +typedef void (APIENTRYP PFNGLVALIDATEPROGRAMARBPROC) (GLhandleARB programObj); +typedef void (APIENTRYP PFNGLUNIFORM1FARBPROC) (GLint location, GLfloat v0); +typedef void (APIENTRYP PFNGLUNIFORM2FARBPROC) (GLint location, GLfloat v0, GLfloat v1); +typedef void (APIENTRYP PFNGLUNIFORM3FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (APIENTRYP PFNGLUNIFORM4FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (APIENTRYP PFNGLUNIFORM1IARBPROC) (GLint location, GLint v0); +typedef void (APIENTRYP PFNGLUNIFORM2IARBPROC) (GLint location, GLint v0, GLint v1); +typedef void (APIENTRYP PFNGLUNIFORM3IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2); +typedef void (APIENTRYP PFNGLUNIFORM4IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (APIENTRYP PFNGLUNIFORM1FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM2FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM3FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM4FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM1IVARBPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORM2IVARBPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORM3IVARBPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORM4IVARBPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERFVARBPROC) (GLhandleARB obj, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERIVARBPROC) (GLhandleARB obj, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETINFOLOGARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog); +typedef void (APIENTRYP PFNGLGETATTACHEDOBJECTSARBPROC) (GLhandleARB containerObj, GLsizei maxCount, GLsizei *count, GLhandleARB *obj); +typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name); +typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); +typedef void (APIENTRYP PFNGLGETUNIFORMFVARBPROC) (GLhandleARB programObj, GLint location, GLfloat *params); +typedef void (APIENTRYP PFNGLGETUNIFORMIVARBPROC) (GLhandleARB programObj, GLint location, GLint *params); +typedef void (APIENTRYP PFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDeleteObjectARB (GLhandleARB obj); +GLAPI GLhandleARB APIENTRY glGetHandleARB (GLenum pname); +GLAPI void APIENTRY glDetachObjectARB (GLhandleARB containerObj, GLhandleARB attachedObj); +GLAPI GLhandleARB APIENTRY glCreateShaderObjectARB (GLenum shaderType); +GLAPI void APIENTRY glShaderSourceARB (GLhandleARB shaderObj, GLsizei count, const GLcharARB **string, const GLint *length); +GLAPI void APIENTRY glCompileShaderARB (GLhandleARB shaderObj); +GLAPI GLhandleARB APIENTRY glCreateProgramObjectARB (void); +GLAPI void APIENTRY glAttachObjectARB (GLhandleARB containerObj, GLhandleARB obj); +GLAPI void APIENTRY glLinkProgramARB (GLhandleARB programObj); +GLAPI void APIENTRY glUseProgramObjectARB (GLhandleARB programObj); +GLAPI void APIENTRY glValidateProgramARB (GLhandleARB programObj); +GLAPI void APIENTRY glUniform1fARB (GLint location, GLfloat v0); +GLAPI void APIENTRY glUniform2fARB (GLint location, GLfloat v0, GLfloat v1); +GLAPI void APIENTRY glUniform3fARB (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +GLAPI void APIENTRY glUniform4fARB (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +GLAPI void APIENTRY glUniform1iARB (GLint location, GLint v0); +GLAPI void APIENTRY glUniform2iARB (GLint location, GLint v0, GLint v1); +GLAPI void APIENTRY glUniform3iARB (GLint location, GLint v0, GLint v1, GLint v2); +GLAPI void APIENTRY glUniform4iARB (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +GLAPI void APIENTRY glUniform1fvARB (GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glUniform2fvARB (GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glUniform3fvARB (GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glUniform4fvARB (GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glUniform1ivARB (GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glUniform2ivARB (GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glUniform3ivARB (GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glUniform4ivARB (GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glUniformMatrix2fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glUniformMatrix3fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glUniformMatrix4fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glGetObjectParameterfvARB (GLhandleARB obj, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetObjectParameterivARB (GLhandleARB obj, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetInfoLogARB (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog); +GLAPI void APIENTRY glGetAttachedObjectsARB (GLhandleARB containerObj, GLsizei maxCount, GLsizei *count, GLhandleARB *obj); +GLAPI GLint APIENTRY glGetUniformLocationARB (GLhandleARB programObj, const GLcharARB *name); +GLAPI void APIENTRY glGetActiveUniformARB (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); +GLAPI void APIENTRY glGetUniformfvARB (GLhandleARB programObj, GLint location, GLfloat *params); +GLAPI void APIENTRY glGetUniformivARB (GLhandleARB programObj, GLint location, GLint *params); +GLAPI void APIENTRY glGetShaderSourceARB (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source); +#endif +#endif /* GL_ARB_shader_objects */ + +#ifndef GL_ARB_shader_precision +#define GL_ARB_shader_precision 1 +#endif /* GL_ARB_shader_precision */ + +#ifndef GL_ARB_shader_stencil_export +#define GL_ARB_shader_stencil_export 1 +#endif /* GL_ARB_shader_stencil_export */ + +#ifndef GL_ARB_shader_storage_buffer_object +#define GL_ARB_shader_storage_buffer_object 1 +#endif /* GL_ARB_shader_storage_buffer_object */ + +#ifndef GL_ARB_shader_subroutine +#define GL_ARB_shader_subroutine 1 +#endif /* GL_ARB_shader_subroutine */ + +#ifndef GL_ARB_shader_texture_image_samples +#define GL_ARB_shader_texture_image_samples 1 +#endif /* GL_ARB_shader_texture_image_samples */ + +#ifndef GL_ARB_shader_texture_lod +#define GL_ARB_shader_texture_lod 1 +#endif /* GL_ARB_shader_texture_lod */ + +#ifndef GL_ARB_shading_language_100 +#define GL_ARB_shading_language_100 1 +#define GL_SHADING_LANGUAGE_VERSION_ARB 0x8B8C +#endif /* GL_ARB_shading_language_100 */ + +#ifndef GL_ARB_shading_language_420pack +#define GL_ARB_shading_language_420pack 1 +#endif /* GL_ARB_shading_language_420pack */ + +#ifndef GL_ARB_shading_language_include +#define GL_ARB_shading_language_include 1 +#define GL_SHADER_INCLUDE_ARB 0x8DAE +#define GL_NAMED_STRING_LENGTH_ARB 0x8DE9 +#define GL_NAMED_STRING_TYPE_ARB 0x8DEA +typedef void (APIENTRYP PFNGLNAMEDSTRINGARBPROC) (GLenum type, GLint namelen, const GLchar *name, GLint stringlen, const GLchar *string); +typedef void (APIENTRYP PFNGLDELETENAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name); +typedef void (APIENTRYP PFNGLCOMPILESHADERINCLUDEARBPROC) (GLuint shader, GLsizei count, const GLchar *const*path, const GLint *length); +typedef GLboolean (APIENTRYP PFNGLISNAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name); +typedef void (APIENTRYP PFNGLGETNAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name, GLsizei bufSize, GLint *stringlen, GLchar *string); +typedef void (APIENTRYP PFNGLGETNAMEDSTRINGIVARBPROC) (GLint namelen, const GLchar *name, GLenum pname, GLint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glNamedStringARB (GLenum type, GLint namelen, const GLchar *name, GLint stringlen, const GLchar *string); +GLAPI void APIENTRY glDeleteNamedStringARB (GLint namelen, const GLchar *name); +GLAPI void APIENTRY glCompileShaderIncludeARB (GLuint shader, GLsizei count, const GLchar *const*path, const GLint *length); +GLAPI GLboolean APIENTRY glIsNamedStringARB (GLint namelen, const GLchar *name); +GLAPI void APIENTRY glGetNamedStringARB (GLint namelen, const GLchar *name, GLsizei bufSize, GLint *stringlen, GLchar *string); +GLAPI void APIENTRY glGetNamedStringivARB (GLint namelen, const GLchar *name, GLenum pname, GLint *params); +#endif +#endif /* GL_ARB_shading_language_include */ + +#ifndef GL_ARB_shading_language_packing +#define GL_ARB_shading_language_packing 1 +#endif /* GL_ARB_shading_language_packing */ + +#ifndef GL_ARB_shadow +#define GL_ARB_shadow 1 +#define GL_TEXTURE_COMPARE_MODE_ARB 0x884C +#define GL_TEXTURE_COMPARE_FUNC_ARB 0x884D +#define GL_COMPARE_R_TO_TEXTURE_ARB 0x884E +#endif /* GL_ARB_shadow */ + +#ifndef GL_ARB_shadow_ambient +#define GL_ARB_shadow_ambient 1 +#define GL_TEXTURE_COMPARE_FAIL_VALUE_ARB 0x80BF +#endif /* GL_ARB_shadow_ambient */ + +#ifndef GL_ARB_sparse_buffer +#define GL_ARB_sparse_buffer 1 +#define GL_SPARSE_STORAGE_BIT_ARB 0x0400 +#define GL_SPARSE_BUFFER_PAGE_SIZE_ARB 0x82F8 +typedef void (APIENTRYP PFNGLBUFFERPAGECOMMITMENTARBPROC) (GLenum target, GLintptr offset, GLsizei size, GLboolean commit); +typedef void (APIENTRYP PFNGLNAMEDBUFFERPAGECOMMITMENTEXTPROC) (GLuint buffer, GLintptr offset, GLsizei size, GLboolean commit); +typedef void (APIENTRYP PFNGLNAMEDBUFFERPAGECOMMITMENTARBPROC) (GLuint buffer, GLintptr offset, GLsizei size, GLboolean commit); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBufferPageCommitmentARB (GLenum target, GLintptr offset, GLsizei size, GLboolean commit); +GLAPI void APIENTRY glNamedBufferPageCommitmentEXT (GLuint buffer, GLintptr offset, GLsizei size, GLboolean commit); +GLAPI void APIENTRY glNamedBufferPageCommitmentARB (GLuint buffer, GLintptr offset, GLsizei size, GLboolean commit); +#endif +#endif /* GL_ARB_sparse_buffer */ + +#ifndef GL_ARB_sparse_texture +#define GL_ARB_sparse_texture 1 +#define GL_TEXTURE_SPARSE_ARB 0x91A6 +#define GL_VIRTUAL_PAGE_SIZE_INDEX_ARB 0x91A7 +#define GL_MIN_SPARSE_LEVEL_ARB 0x919B +#define GL_NUM_VIRTUAL_PAGE_SIZES_ARB 0x91A8 +#define GL_VIRTUAL_PAGE_SIZE_X_ARB 0x9195 +#define GL_VIRTUAL_PAGE_SIZE_Y_ARB 0x9196 +#define GL_VIRTUAL_PAGE_SIZE_Z_ARB 0x9197 +#define GL_MAX_SPARSE_TEXTURE_SIZE_ARB 0x9198 +#define GL_MAX_SPARSE_3D_TEXTURE_SIZE_ARB 0x9199 +#define GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_ARB 0x919A +#define GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_ARB 0x91A9 +typedef void (APIENTRYP PFNGLTEXPAGECOMMITMENTARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean resident); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexPageCommitmentARB (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean resident); +#endif +#endif /* GL_ARB_sparse_texture */ + +#ifndef GL_ARB_stencil_texturing +#define GL_ARB_stencil_texturing 1 +#endif /* GL_ARB_stencil_texturing */ + +#ifndef GL_ARB_sync +#define GL_ARB_sync 1 +#endif /* GL_ARB_sync */ + +#ifndef GL_ARB_tessellation_shader +#define GL_ARB_tessellation_shader 1 +#endif /* GL_ARB_tessellation_shader */ + +#ifndef GL_ARB_texture_barrier +#define GL_ARB_texture_barrier 1 +#endif /* GL_ARB_texture_barrier */ + +#ifndef GL_ARB_texture_border_clamp +#define GL_ARB_texture_border_clamp 1 +#define GL_CLAMP_TO_BORDER_ARB 0x812D +#endif /* GL_ARB_texture_border_clamp */ + +#ifndef GL_ARB_texture_buffer_object +#define GL_ARB_texture_buffer_object 1 +#define GL_TEXTURE_BUFFER_ARB 0x8C2A +#define GL_MAX_TEXTURE_BUFFER_SIZE_ARB 0x8C2B +#define GL_TEXTURE_BINDING_BUFFER_ARB 0x8C2C +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_ARB 0x8C2D +#define GL_TEXTURE_BUFFER_FORMAT_ARB 0x8C2E +typedef void (APIENTRYP PFNGLTEXBUFFERARBPROC) (GLenum target, GLenum internalformat, GLuint buffer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexBufferARB (GLenum target, GLenum internalformat, GLuint buffer); +#endif +#endif /* GL_ARB_texture_buffer_object */ + +#ifndef GL_ARB_texture_buffer_object_rgb32 +#define GL_ARB_texture_buffer_object_rgb32 1 +#endif /* GL_ARB_texture_buffer_object_rgb32 */ + +#ifndef GL_ARB_texture_buffer_range +#define GL_ARB_texture_buffer_range 1 +#endif /* GL_ARB_texture_buffer_range */ + +#ifndef GL_ARB_texture_compression +#define GL_ARB_texture_compression 1 +#define GL_COMPRESSED_ALPHA_ARB 0x84E9 +#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB +#define GL_COMPRESSED_INTENSITY_ARB 0x84EC +#define GL_COMPRESSED_RGB_ARB 0x84ED +#define GL_COMPRESSED_RGBA_ARB 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0 +#define GL_TEXTURE_COMPRESSED_ARB 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3 +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); +typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint level, void *img); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glCompressedTexImage3DARB (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); +GLAPI void APIENTRY glCompressedTexImage2DARB (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); +GLAPI void APIENTRY glCompressedTexImage1DARB (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data); +GLAPI void APIENTRY glCompressedTexSubImage3DARB (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); +GLAPI void APIENTRY glCompressedTexSubImage2DARB (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); +GLAPI void APIENTRY glCompressedTexSubImage1DARB (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); +GLAPI void APIENTRY glGetCompressedTexImageARB (GLenum target, GLint level, void *img); +#endif +#endif /* GL_ARB_texture_compression */ + +#ifndef GL_ARB_texture_compression_bptc +#define GL_ARB_texture_compression_bptc 1 +#define GL_COMPRESSED_RGBA_BPTC_UNORM_ARB 0x8E8C +#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D +#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E +#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F +#endif /* GL_ARB_texture_compression_bptc */ + +#ifndef GL_ARB_texture_compression_rgtc +#define GL_ARB_texture_compression_rgtc 1 +#endif /* GL_ARB_texture_compression_rgtc */ + +#ifndef GL_ARB_texture_cube_map +#define GL_ARB_texture_cube_map 1 +#define GL_NORMAL_MAP_ARB 0x8511 +#define GL_REFLECTION_MAP_ARB 0x8512 +#define GL_TEXTURE_CUBE_MAP_ARB 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C +#endif /* GL_ARB_texture_cube_map */ + +#ifndef GL_ARB_texture_cube_map_array +#define GL_ARB_texture_cube_map_array 1 +#define GL_TEXTURE_CUBE_MAP_ARRAY_ARB 0x9009 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_ARB 0x900A +#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB 0x900B +#define GL_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900C +#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB 0x900D +#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900E +#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900F +#endif /* GL_ARB_texture_cube_map_array */ + +#ifndef GL_ARB_texture_env_add +#define GL_ARB_texture_env_add 1 +#endif /* GL_ARB_texture_env_add */ + +#ifndef GL_ARB_texture_env_combine +#define GL_ARB_texture_env_combine 1 +#define GL_COMBINE_ARB 0x8570 +#define GL_COMBINE_RGB_ARB 0x8571 +#define GL_COMBINE_ALPHA_ARB 0x8572 +#define GL_SOURCE0_RGB_ARB 0x8580 +#define GL_SOURCE1_RGB_ARB 0x8581 +#define GL_SOURCE2_RGB_ARB 0x8582 +#define GL_SOURCE0_ALPHA_ARB 0x8588 +#define GL_SOURCE1_ALPHA_ARB 0x8589 +#define GL_SOURCE2_ALPHA_ARB 0x858A +#define GL_OPERAND0_RGB_ARB 0x8590 +#define GL_OPERAND1_RGB_ARB 0x8591 +#define GL_OPERAND2_RGB_ARB 0x8592 +#define GL_OPERAND0_ALPHA_ARB 0x8598 +#define GL_OPERAND1_ALPHA_ARB 0x8599 +#define GL_OPERAND2_ALPHA_ARB 0x859A +#define GL_RGB_SCALE_ARB 0x8573 +#define GL_ADD_SIGNED_ARB 0x8574 +#define GL_INTERPOLATE_ARB 0x8575 +#define GL_SUBTRACT_ARB 0x84E7 +#define GL_CONSTANT_ARB 0x8576 +#define GL_PRIMARY_COLOR_ARB 0x8577 +#define GL_PREVIOUS_ARB 0x8578 +#endif /* GL_ARB_texture_env_combine */ + +#ifndef GL_ARB_texture_env_crossbar +#define GL_ARB_texture_env_crossbar 1 +#endif /* GL_ARB_texture_env_crossbar */ + +#ifndef GL_ARB_texture_env_dot3 +#define GL_ARB_texture_env_dot3 1 +#define GL_DOT3_RGB_ARB 0x86AE +#define GL_DOT3_RGBA_ARB 0x86AF +#endif /* GL_ARB_texture_env_dot3 */ + +#ifndef GL_ARB_texture_float +#define GL_ARB_texture_float 1 +#define GL_TEXTURE_RED_TYPE_ARB 0x8C10 +#define GL_TEXTURE_GREEN_TYPE_ARB 0x8C11 +#define GL_TEXTURE_BLUE_TYPE_ARB 0x8C12 +#define GL_TEXTURE_ALPHA_TYPE_ARB 0x8C13 +#define GL_TEXTURE_LUMINANCE_TYPE_ARB 0x8C14 +#define GL_TEXTURE_INTENSITY_TYPE_ARB 0x8C15 +#define GL_TEXTURE_DEPTH_TYPE_ARB 0x8C16 +#define GL_UNSIGNED_NORMALIZED_ARB 0x8C17 +#define GL_RGBA32F_ARB 0x8814 +#define GL_RGB32F_ARB 0x8815 +#define GL_ALPHA32F_ARB 0x8816 +#define GL_INTENSITY32F_ARB 0x8817 +#define GL_LUMINANCE32F_ARB 0x8818 +#define GL_LUMINANCE_ALPHA32F_ARB 0x8819 +#define GL_RGBA16F_ARB 0x881A +#define GL_RGB16F_ARB 0x881B +#define GL_ALPHA16F_ARB 0x881C +#define GL_INTENSITY16F_ARB 0x881D +#define GL_LUMINANCE16F_ARB 0x881E +#define GL_LUMINANCE_ALPHA16F_ARB 0x881F +#endif /* GL_ARB_texture_float */ + +#ifndef GL_ARB_texture_gather +#define GL_ARB_texture_gather 1 +#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5E +#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5F +#define GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS_ARB 0x8F9F +#endif /* GL_ARB_texture_gather */ + +#ifndef GL_ARB_texture_mirror_clamp_to_edge +#define GL_ARB_texture_mirror_clamp_to_edge 1 +#endif /* GL_ARB_texture_mirror_clamp_to_edge */ + +#ifndef GL_ARB_texture_mirrored_repeat +#define GL_ARB_texture_mirrored_repeat 1 +#define GL_MIRRORED_REPEAT_ARB 0x8370 +#endif /* GL_ARB_texture_mirrored_repeat */ + +#ifndef GL_ARB_texture_multisample +#define GL_ARB_texture_multisample 1 +#endif /* GL_ARB_texture_multisample */ + +#ifndef GL_ARB_texture_non_power_of_two +#define GL_ARB_texture_non_power_of_two 1 +#endif /* GL_ARB_texture_non_power_of_two */ + +#ifndef GL_ARB_texture_query_levels +#define GL_ARB_texture_query_levels 1 +#endif /* GL_ARB_texture_query_levels */ + +#ifndef GL_ARB_texture_query_lod +#define GL_ARB_texture_query_lod 1 +#endif /* GL_ARB_texture_query_lod */ + +#ifndef GL_ARB_texture_rectangle +#define GL_ARB_texture_rectangle 1 +#define GL_TEXTURE_RECTANGLE_ARB 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE_ARB 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8 +#endif /* GL_ARB_texture_rectangle */ + +#ifndef GL_ARB_texture_rg +#define GL_ARB_texture_rg 1 +#endif /* GL_ARB_texture_rg */ + +#ifndef GL_ARB_texture_rgb10_a2ui +#define GL_ARB_texture_rgb10_a2ui 1 +#endif /* GL_ARB_texture_rgb10_a2ui */ + +#ifndef GL_ARB_texture_stencil8 +#define GL_ARB_texture_stencil8 1 +#endif /* GL_ARB_texture_stencil8 */ + +#ifndef GL_ARB_texture_storage +#define GL_ARB_texture_storage 1 +#endif /* GL_ARB_texture_storage */ + +#ifndef GL_ARB_texture_storage_multisample +#define GL_ARB_texture_storage_multisample 1 +#endif /* GL_ARB_texture_storage_multisample */ + +#ifndef GL_ARB_texture_swizzle +#define GL_ARB_texture_swizzle 1 +#endif /* GL_ARB_texture_swizzle */ + +#ifndef GL_ARB_texture_view +#define GL_ARB_texture_view 1 +#endif /* GL_ARB_texture_view */ + +#ifndef GL_ARB_timer_query +#define GL_ARB_timer_query 1 +#endif /* GL_ARB_timer_query */ + +#ifndef GL_ARB_transform_feedback2 +#define GL_ARB_transform_feedback2 1 +#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23 +#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24 +#endif /* GL_ARB_transform_feedback2 */ + +#ifndef GL_ARB_transform_feedback3 +#define GL_ARB_transform_feedback3 1 +#endif /* GL_ARB_transform_feedback3 */ + +#ifndef GL_ARB_transform_feedback_instanced +#define GL_ARB_transform_feedback_instanced 1 +#endif /* GL_ARB_transform_feedback_instanced */ + +#ifndef GL_ARB_transform_feedback_overflow_query +#define GL_ARB_transform_feedback_overflow_query 1 +#define GL_TRANSFORM_FEEDBACK_OVERFLOW_ARB 0x82EC +#define GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW_ARB 0x82ED +#endif /* GL_ARB_transform_feedback_overflow_query */ + +#ifndef GL_ARB_transpose_matrix +#define GL_ARB_transpose_matrix 1 +#define GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3 +#define GL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX_ARB 0x84E5 +#define GL_TRANSPOSE_COLOR_MATRIX_ARB 0x84E6 +typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXFARBPROC) (const GLfloat *m); +typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXDARBPROC) (const GLdouble *m); +typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXFARBPROC) (const GLfloat *m); +typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXDARBPROC) (const GLdouble *m); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glLoadTransposeMatrixfARB (const GLfloat *m); +GLAPI void APIENTRY glLoadTransposeMatrixdARB (const GLdouble *m); +GLAPI void APIENTRY glMultTransposeMatrixfARB (const GLfloat *m); +GLAPI void APIENTRY glMultTransposeMatrixdARB (const GLdouble *m); +#endif +#endif /* GL_ARB_transpose_matrix */ + +#ifndef GL_ARB_uniform_buffer_object +#define GL_ARB_uniform_buffer_object 1 +#endif /* GL_ARB_uniform_buffer_object */ + +#ifndef GL_ARB_vertex_array_bgra +#define GL_ARB_vertex_array_bgra 1 +#endif /* GL_ARB_vertex_array_bgra */ + +#ifndef GL_ARB_vertex_array_object +#define GL_ARB_vertex_array_object 1 +#endif /* GL_ARB_vertex_array_object */ + +#ifndef GL_ARB_vertex_attrib_64bit +#define GL_ARB_vertex_attrib_64bit 1 +#endif /* GL_ARB_vertex_attrib_64bit */ + +#ifndef GL_ARB_vertex_attrib_binding +#define GL_ARB_vertex_attrib_binding 1 +#endif /* GL_ARB_vertex_attrib_binding */ + +#ifndef GL_ARB_vertex_blend +#define GL_ARB_vertex_blend 1 +#define GL_MAX_VERTEX_UNITS_ARB 0x86A4 +#define GL_ACTIVE_VERTEX_UNITS_ARB 0x86A5 +#define GL_WEIGHT_SUM_UNITY_ARB 0x86A6 +#define GL_VERTEX_BLEND_ARB 0x86A7 +#define GL_CURRENT_WEIGHT_ARB 0x86A8 +#define GL_WEIGHT_ARRAY_TYPE_ARB 0x86A9 +#define GL_WEIGHT_ARRAY_STRIDE_ARB 0x86AA +#define GL_WEIGHT_ARRAY_SIZE_ARB 0x86AB +#define GL_WEIGHT_ARRAY_POINTER_ARB 0x86AC +#define GL_WEIGHT_ARRAY_ARB 0x86AD +#define GL_MODELVIEW0_ARB 0x1700 +#define GL_MODELVIEW1_ARB 0x850A +#define GL_MODELVIEW2_ARB 0x8722 +#define GL_MODELVIEW3_ARB 0x8723 +#define GL_MODELVIEW4_ARB 0x8724 +#define GL_MODELVIEW5_ARB 0x8725 +#define GL_MODELVIEW6_ARB 0x8726 +#define GL_MODELVIEW7_ARB 0x8727 +#define GL_MODELVIEW8_ARB 0x8728 +#define GL_MODELVIEW9_ARB 0x8729 +#define GL_MODELVIEW10_ARB 0x872A +#define GL_MODELVIEW11_ARB 0x872B +#define GL_MODELVIEW12_ARB 0x872C +#define GL_MODELVIEW13_ARB 0x872D +#define GL_MODELVIEW14_ARB 0x872E +#define GL_MODELVIEW15_ARB 0x872F +#define GL_MODELVIEW16_ARB 0x8730 +#define GL_MODELVIEW17_ARB 0x8731 +#define GL_MODELVIEW18_ARB 0x8732 +#define GL_MODELVIEW19_ARB 0x8733 +#define GL_MODELVIEW20_ARB 0x8734 +#define GL_MODELVIEW21_ARB 0x8735 +#define GL_MODELVIEW22_ARB 0x8736 +#define GL_MODELVIEW23_ARB 0x8737 +#define GL_MODELVIEW24_ARB 0x8738 +#define GL_MODELVIEW25_ARB 0x8739 +#define GL_MODELVIEW26_ARB 0x873A +#define GL_MODELVIEW27_ARB 0x873B +#define GL_MODELVIEW28_ARB 0x873C +#define GL_MODELVIEW29_ARB 0x873D +#define GL_MODELVIEW30_ARB 0x873E +#define GL_MODELVIEW31_ARB 0x873F +typedef void (APIENTRYP PFNGLWEIGHTBVARBPROC) (GLint size, const GLbyte *weights); +typedef void (APIENTRYP PFNGLWEIGHTSVARBPROC) (GLint size, const GLshort *weights); +typedef void (APIENTRYP PFNGLWEIGHTIVARBPROC) (GLint size, const GLint *weights); +typedef void (APIENTRYP PFNGLWEIGHTFVARBPROC) (GLint size, const GLfloat *weights); +typedef void (APIENTRYP PFNGLWEIGHTDVARBPROC) (GLint size, const GLdouble *weights); +typedef void (APIENTRYP PFNGLWEIGHTUBVARBPROC) (GLint size, const GLubyte *weights); +typedef void (APIENTRYP PFNGLWEIGHTUSVARBPROC) (GLint size, const GLushort *weights); +typedef void (APIENTRYP PFNGLWEIGHTUIVARBPROC) (GLint size, const GLuint *weights); +typedef void (APIENTRYP PFNGLWEIGHTPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const void *pointer); +typedef void (APIENTRYP PFNGLVERTEXBLENDARBPROC) (GLint count); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glWeightbvARB (GLint size, const GLbyte *weights); +GLAPI void APIENTRY glWeightsvARB (GLint size, const GLshort *weights); +GLAPI void APIENTRY glWeightivARB (GLint size, const GLint *weights); +GLAPI void APIENTRY glWeightfvARB (GLint size, const GLfloat *weights); +GLAPI void APIENTRY glWeightdvARB (GLint size, const GLdouble *weights); +GLAPI void APIENTRY glWeightubvARB (GLint size, const GLubyte *weights); +GLAPI void APIENTRY glWeightusvARB (GLint size, const GLushort *weights); +GLAPI void APIENTRY glWeightuivARB (GLint size, const GLuint *weights); +GLAPI void APIENTRY glWeightPointerARB (GLint size, GLenum type, GLsizei stride, const void *pointer); +GLAPI void APIENTRY glVertexBlendARB (GLint count); +#endif +#endif /* GL_ARB_vertex_blend */ + +#ifndef GL_ARB_vertex_buffer_object +#define GL_ARB_vertex_buffer_object 1 +/* HACK: This is a workaround for gltypes.h on OS X 10.9 defining these types as + * long instead of ptrdiff_t + */ +#if defined(__APPLE__) +typedef long GLsizeiptrARB; +typedef long GLintptrARB; +#else +typedef ptrdiff_t GLsizeiptrARB; +typedef ptrdiff_t GLintptrARB; +#endif +#define GL_BUFFER_SIZE_ARB 0x8764 +#define GL_BUFFER_USAGE_ARB 0x8765 +#define GL_ARRAY_BUFFER_ARB 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893 +#define GL_ARRAY_BUFFER_BINDING_ARB 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895 +#define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896 +#define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897 +#define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898 +#define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899 +#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A +#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B +#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C +#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D +#define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F +#define GL_READ_ONLY_ARB 0x88B8 +#define GL_WRITE_ONLY_ARB 0x88B9 +#define GL_READ_WRITE_ARB 0x88BA +#define GL_BUFFER_ACCESS_ARB 0x88BB +#define GL_BUFFER_MAPPED_ARB 0x88BC +#define GL_BUFFER_MAP_POINTER_ARB 0x88BD +#define GL_STREAM_DRAW_ARB 0x88E0 +#define GL_STREAM_READ_ARB 0x88E1 +#define GL_STREAM_COPY_ARB 0x88E2 +#define GL_STATIC_DRAW_ARB 0x88E4 +#define GL_STATIC_READ_ARB 0x88E5 +#define GL_STATIC_COPY_ARB 0x88E6 +#define GL_DYNAMIC_DRAW_ARB 0x88E8 +#define GL_DYNAMIC_READ_ARB 0x88E9 +#define GL_DYNAMIC_COPY_ARB 0x88EA +typedef void (APIENTRYP PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer); +typedef void (APIENTRYP PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers); +typedef void (APIENTRYP PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers); +typedef GLboolean (APIENTRYP PFNGLISBUFFERARBPROC) (GLuint buffer); +typedef void (APIENTRYP PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const void *data, GLenum usage); +typedef void (APIENTRYP PFNGLBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const void *data); +typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, void *data); +typedef void *(APIENTRYP PFNGLMAPBUFFERARBPROC) (GLenum target, GLenum access); +typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERARBPROC) (GLenum target); +typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVARBPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVARBPROC) (GLenum target, GLenum pname, void **params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBindBufferARB (GLenum target, GLuint buffer); +GLAPI void APIENTRY glDeleteBuffersARB (GLsizei n, const GLuint *buffers); +GLAPI void APIENTRY glGenBuffersARB (GLsizei n, GLuint *buffers); +GLAPI GLboolean APIENTRY glIsBufferARB (GLuint buffer); +GLAPI void APIENTRY glBufferDataARB (GLenum target, GLsizeiptrARB size, const void *data, GLenum usage); +GLAPI void APIENTRY glBufferSubDataARB (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const void *data); +GLAPI void APIENTRY glGetBufferSubDataARB (GLenum target, GLintptrARB offset, GLsizeiptrARB size, void *data); +GLAPI void *APIENTRY glMapBufferARB (GLenum target, GLenum access); +GLAPI GLboolean APIENTRY glUnmapBufferARB (GLenum target); +GLAPI void APIENTRY glGetBufferParameterivARB (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetBufferPointervARB (GLenum target, GLenum pname, void **params); +#endif +#endif /* GL_ARB_vertex_buffer_object */ + +#ifndef GL_ARB_vertex_program +#define GL_ARB_vertex_program 1 +#define GL_COLOR_SUM_ARB 0x8458 +#define GL_VERTEX_PROGRAM_ARB 0x8620 +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625 +#define GL_CURRENT_VERTEX_ATTRIB_ARB 0x8626 +#define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643 +#define GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645 +#define GL_MAX_VERTEX_ATTRIBS_ARB 0x8869 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A +#define GL_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B0 +#define GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B1 +#define GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B2 +#define GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B3 +typedef void (APIENTRYP PFNGLVERTEXATTRIB1DARBPROC) (GLuint index, GLdouble x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVARBPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1FARBPROC) (GLuint index, GLfloat x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVARBPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1SARBPROC) (GLuint index, GLshort x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVARBPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2DARBPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVARBPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2FARBPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVARBPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2SARBPROC) (GLuint index, GLshort x, GLshort y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVARBPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVARBPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVARBPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVARBPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVARBPROC) (GLuint index, const GLbyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVARBPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVARBPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBARBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVARBPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVARBPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVARBPROC) (GLuint index, const GLushort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVARBPROC) (GLuint index, const GLbyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVARBPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVARBPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVARBPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVARBPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVARBPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVARBPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVARBPROC) (GLuint index, const GLushort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERARBPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); +typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); +typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVARBPROC) (GLuint index, GLenum pname, GLdouble *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVARBPROC) (GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVARBPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVARBPROC) (GLuint index, GLenum pname, void **pointer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexAttrib1dARB (GLuint index, GLdouble x); +GLAPI void APIENTRY glVertexAttrib1dvARB (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttrib1fARB (GLuint index, GLfloat x); +GLAPI void APIENTRY glVertexAttrib1fvARB (GLuint index, const GLfloat *v); +GLAPI void APIENTRY glVertexAttrib1sARB (GLuint index, GLshort x); +GLAPI void APIENTRY glVertexAttrib1svARB (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib2dARB (GLuint index, GLdouble x, GLdouble y); +GLAPI void APIENTRY glVertexAttrib2dvARB (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttrib2fARB (GLuint index, GLfloat x, GLfloat y); +GLAPI void APIENTRY glVertexAttrib2fvARB (GLuint index, const GLfloat *v); +GLAPI void APIENTRY glVertexAttrib2sARB (GLuint index, GLshort x, GLshort y); +GLAPI void APIENTRY glVertexAttrib2svARB (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib3dARB (GLuint index, GLdouble x, GLdouble y, GLdouble z); +GLAPI void APIENTRY glVertexAttrib3dvARB (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttrib3fARB (GLuint index, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glVertexAttrib3fvARB (GLuint index, const GLfloat *v); +GLAPI void APIENTRY glVertexAttrib3sARB (GLuint index, GLshort x, GLshort y, GLshort z); +GLAPI void APIENTRY glVertexAttrib3svARB (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib4NbvARB (GLuint index, const GLbyte *v); +GLAPI void APIENTRY glVertexAttrib4NivARB (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttrib4NsvARB (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib4NubARB (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +GLAPI void APIENTRY glVertexAttrib4NubvARB (GLuint index, const GLubyte *v); +GLAPI void APIENTRY glVertexAttrib4NuivARB (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttrib4NusvARB (GLuint index, const GLushort *v); +GLAPI void APIENTRY glVertexAttrib4bvARB (GLuint index, const GLbyte *v); +GLAPI void APIENTRY glVertexAttrib4dARB (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void APIENTRY glVertexAttrib4dvARB (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttrib4fARB (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void APIENTRY glVertexAttrib4fvARB (GLuint index, const GLfloat *v); +GLAPI void APIENTRY glVertexAttrib4ivARB (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttrib4sARB (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +GLAPI void APIENTRY glVertexAttrib4svARB (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib4ubvARB (GLuint index, const GLubyte *v); +GLAPI void APIENTRY glVertexAttrib4uivARB (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttrib4usvARB (GLuint index, const GLushort *v); +GLAPI void APIENTRY glVertexAttribPointerARB (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); +GLAPI void APIENTRY glEnableVertexAttribArrayARB (GLuint index); +GLAPI void APIENTRY glDisableVertexAttribArrayARB (GLuint index); +GLAPI void APIENTRY glGetVertexAttribdvARB (GLuint index, GLenum pname, GLdouble *params); +GLAPI void APIENTRY glGetVertexAttribfvARB (GLuint index, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetVertexAttribivARB (GLuint index, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetVertexAttribPointervARB (GLuint index, GLenum pname, void **pointer); +#endif +#endif /* GL_ARB_vertex_program */ + +#ifndef GL_ARB_vertex_shader +#define GL_ARB_vertex_shader 1 +#define GL_VERTEX_SHADER_ARB 0x8B31 +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB 0x8B4A +#define GL_MAX_VARYING_FLOATS_ARB 0x8B4B +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB 0x8B4D +#define GL_OBJECT_ACTIVE_ATTRIBUTES_ARB 0x8B89 +#define GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A +typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONARBPROC) (GLhandleARB programObj, GLuint index, const GLcharARB *name); +typedef void (APIENTRYP PFNGLGETACTIVEATTRIBARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); +typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBindAttribLocationARB (GLhandleARB programObj, GLuint index, const GLcharARB *name); +GLAPI void APIENTRY glGetActiveAttribARB (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); +GLAPI GLint APIENTRY glGetAttribLocationARB (GLhandleARB programObj, const GLcharARB *name); +#endif +#endif /* GL_ARB_vertex_shader */ + +#ifndef GL_ARB_vertex_type_10f_11f_11f_rev +#define GL_ARB_vertex_type_10f_11f_11f_rev 1 +#endif /* GL_ARB_vertex_type_10f_11f_11f_rev */ + +#ifndef GL_ARB_vertex_type_2_10_10_10_rev +#define GL_ARB_vertex_type_2_10_10_10_rev 1 +#endif /* GL_ARB_vertex_type_2_10_10_10_rev */ + +#ifndef GL_ARB_viewport_array +#define GL_ARB_viewport_array 1 +#endif /* GL_ARB_viewport_array */ + +#ifndef GL_ARB_window_pos +#define GL_ARB_window_pos 1 +typedef void (APIENTRYP PFNGLWINDOWPOS2DARBPROC) (GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLWINDOWPOS2DVARBPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2FARBPROC) (GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLWINDOWPOS2FVARBPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2IARBPROC) (GLint x, GLint y); +typedef void (APIENTRYP PFNGLWINDOWPOS2IVARBPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2SARBPROC) (GLshort x, GLshort y); +typedef void (APIENTRYP PFNGLWINDOWPOS2SVARBPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3DARBPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLWINDOWPOS3DVARBPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3FARBPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLWINDOWPOS3FVARBPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3IARBPROC) (GLint x, GLint y, GLint z); +typedef void (APIENTRYP PFNGLWINDOWPOS3IVARBPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3SARBPROC) (GLshort x, GLshort y, GLshort z); +typedef void (APIENTRYP PFNGLWINDOWPOS3SVARBPROC) (const GLshort *v); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glWindowPos2dARB (GLdouble x, GLdouble y); +GLAPI void APIENTRY glWindowPos2dvARB (const GLdouble *v); +GLAPI void APIENTRY glWindowPos2fARB (GLfloat x, GLfloat y); +GLAPI void APIENTRY glWindowPos2fvARB (const GLfloat *v); +GLAPI void APIENTRY glWindowPos2iARB (GLint x, GLint y); +GLAPI void APIENTRY glWindowPos2ivARB (const GLint *v); +GLAPI void APIENTRY glWindowPos2sARB (GLshort x, GLshort y); +GLAPI void APIENTRY glWindowPos2svARB (const GLshort *v); +GLAPI void APIENTRY glWindowPos3dARB (GLdouble x, GLdouble y, GLdouble z); +GLAPI void APIENTRY glWindowPos3dvARB (const GLdouble *v); +GLAPI void APIENTRY glWindowPos3fARB (GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glWindowPos3fvARB (const GLfloat *v); +GLAPI void APIENTRY glWindowPos3iARB (GLint x, GLint y, GLint z); +GLAPI void APIENTRY glWindowPos3ivARB (const GLint *v); +GLAPI void APIENTRY glWindowPos3sARB (GLshort x, GLshort y, GLshort z); +GLAPI void APIENTRY glWindowPos3svARB (const GLshort *v); +#endif +#endif /* GL_ARB_window_pos */ + +#ifndef GL_KHR_blend_equation_advanced +#define GL_KHR_blend_equation_advanced 1 +#define GL_MULTIPLY_KHR 0x9294 +#define GL_SCREEN_KHR 0x9295 +#define GL_OVERLAY_KHR 0x9296 +#define GL_DARKEN_KHR 0x9297 +#define GL_LIGHTEN_KHR 0x9298 +#define GL_COLORDODGE_KHR 0x9299 +#define GL_COLORBURN_KHR 0x929A +#define GL_HARDLIGHT_KHR 0x929B +#define GL_SOFTLIGHT_KHR 0x929C +#define GL_DIFFERENCE_KHR 0x929E +#define GL_EXCLUSION_KHR 0x92A0 +#define GL_HSL_HUE_KHR 0x92AD +#define GL_HSL_SATURATION_KHR 0x92AE +#define GL_HSL_COLOR_KHR 0x92AF +#define GL_HSL_LUMINOSITY_KHR 0x92B0 +typedef void (APIENTRYP PFNGLBLENDBARRIERKHRPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendBarrierKHR (void); +#endif +#endif /* GL_KHR_blend_equation_advanced */ + +#ifndef GL_KHR_blend_equation_advanced_coherent +#define GL_KHR_blend_equation_advanced_coherent 1 +#define GL_BLEND_ADVANCED_COHERENT_KHR 0x9285 +#endif /* GL_KHR_blend_equation_advanced_coherent */ + +#ifndef GL_KHR_context_flush_control +#define GL_KHR_context_flush_control 1 +#endif /* GL_KHR_context_flush_control */ + +#ifndef GL_KHR_debug +#define GL_KHR_debug 1 +#endif /* GL_KHR_debug */ + +#ifndef GL_KHR_robust_buffer_access_behavior +#define GL_KHR_robust_buffer_access_behavior 1 +#endif /* GL_KHR_robust_buffer_access_behavior */ + +#ifndef GL_KHR_robustness +#define GL_KHR_robustness 1 +#define GL_CONTEXT_ROBUST_ACCESS 0x90F3 +#endif /* GL_KHR_robustness */ + +#ifndef GL_KHR_texture_compression_astc_hdr +#define GL_KHR_texture_compression_astc_hdr 1 +#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0 +#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1 +#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2 +#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3 +#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4 +#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5 +#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6 +#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7 +#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8 +#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9 +#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA +#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB +#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC +#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD +#endif /* GL_KHR_texture_compression_astc_hdr */ + +#ifndef GL_KHR_texture_compression_astc_ldr +#define GL_KHR_texture_compression_astc_ldr 1 +#endif /* GL_KHR_texture_compression_astc_ldr */ + +#ifndef GL_OES_byte_coordinates +#define GL_OES_byte_coordinates 1 +typedef void (APIENTRYP PFNGLMULTITEXCOORD1BOESPROC) (GLenum texture, GLbyte s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1BVOESPROC) (GLenum texture, const GLbyte *coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2BOESPROC) (GLenum texture, GLbyte s, GLbyte t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2BVOESPROC) (GLenum texture, const GLbyte *coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3BOESPROC) (GLenum texture, GLbyte s, GLbyte t, GLbyte r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3BVOESPROC) (GLenum texture, const GLbyte *coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4BOESPROC) (GLenum texture, GLbyte s, GLbyte t, GLbyte r, GLbyte q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4BVOESPROC) (GLenum texture, const GLbyte *coords); +typedef void (APIENTRYP PFNGLTEXCOORD1BOESPROC) (GLbyte s); +typedef void (APIENTRYP PFNGLTEXCOORD1BVOESPROC) (const GLbyte *coords); +typedef void (APIENTRYP PFNGLTEXCOORD2BOESPROC) (GLbyte s, GLbyte t); +typedef void (APIENTRYP PFNGLTEXCOORD2BVOESPROC) (const GLbyte *coords); +typedef void (APIENTRYP PFNGLTEXCOORD3BOESPROC) (GLbyte s, GLbyte t, GLbyte r); +typedef void (APIENTRYP PFNGLTEXCOORD3BVOESPROC) (const GLbyte *coords); +typedef void (APIENTRYP PFNGLTEXCOORD4BOESPROC) (GLbyte s, GLbyte t, GLbyte r, GLbyte q); +typedef void (APIENTRYP PFNGLTEXCOORD4BVOESPROC) (const GLbyte *coords); +typedef void (APIENTRYP PFNGLVERTEX2BOESPROC) (GLbyte x, GLbyte y); +typedef void (APIENTRYP PFNGLVERTEX2BVOESPROC) (const GLbyte *coords); +typedef void (APIENTRYP PFNGLVERTEX3BOESPROC) (GLbyte x, GLbyte y, GLbyte z); +typedef void (APIENTRYP PFNGLVERTEX3BVOESPROC) (const GLbyte *coords); +typedef void (APIENTRYP PFNGLVERTEX4BOESPROC) (GLbyte x, GLbyte y, GLbyte z, GLbyte w); +typedef void (APIENTRYP PFNGLVERTEX4BVOESPROC) (const GLbyte *coords); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMultiTexCoord1bOES (GLenum texture, GLbyte s); +GLAPI void APIENTRY glMultiTexCoord1bvOES (GLenum texture, const GLbyte *coords); +GLAPI void APIENTRY glMultiTexCoord2bOES (GLenum texture, GLbyte s, GLbyte t); +GLAPI void APIENTRY glMultiTexCoord2bvOES (GLenum texture, const GLbyte *coords); +GLAPI void APIENTRY glMultiTexCoord3bOES (GLenum texture, GLbyte s, GLbyte t, GLbyte r); +GLAPI void APIENTRY glMultiTexCoord3bvOES (GLenum texture, const GLbyte *coords); +GLAPI void APIENTRY glMultiTexCoord4bOES (GLenum texture, GLbyte s, GLbyte t, GLbyte r, GLbyte q); +GLAPI void APIENTRY glMultiTexCoord4bvOES (GLenum texture, const GLbyte *coords); +GLAPI void APIENTRY glTexCoord1bOES (GLbyte s); +GLAPI void APIENTRY glTexCoord1bvOES (const GLbyte *coords); +GLAPI void APIENTRY glTexCoord2bOES (GLbyte s, GLbyte t); +GLAPI void APIENTRY glTexCoord2bvOES (const GLbyte *coords); +GLAPI void APIENTRY glTexCoord3bOES (GLbyte s, GLbyte t, GLbyte r); +GLAPI void APIENTRY glTexCoord3bvOES (const GLbyte *coords); +GLAPI void APIENTRY glTexCoord4bOES (GLbyte s, GLbyte t, GLbyte r, GLbyte q); +GLAPI void APIENTRY glTexCoord4bvOES (const GLbyte *coords); +GLAPI void APIENTRY glVertex2bOES (GLbyte x, GLbyte y); +GLAPI void APIENTRY glVertex2bvOES (const GLbyte *coords); +GLAPI void APIENTRY glVertex3bOES (GLbyte x, GLbyte y, GLbyte z); +GLAPI void APIENTRY glVertex3bvOES (const GLbyte *coords); +GLAPI void APIENTRY glVertex4bOES (GLbyte x, GLbyte y, GLbyte z, GLbyte w); +GLAPI void APIENTRY glVertex4bvOES (const GLbyte *coords); +#endif +#endif /* GL_OES_byte_coordinates */ + +#ifndef GL_OES_compressed_paletted_texture +#define GL_OES_compressed_paletted_texture 1 +#define GL_PALETTE4_RGB8_OES 0x8B90 +#define GL_PALETTE4_RGBA8_OES 0x8B91 +#define GL_PALETTE4_R5_G6_B5_OES 0x8B92 +#define GL_PALETTE4_RGBA4_OES 0x8B93 +#define GL_PALETTE4_RGB5_A1_OES 0x8B94 +#define GL_PALETTE8_RGB8_OES 0x8B95 +#define GL_PALETTE8_RGBA8_OES 0x8B96 +#define GL_PALETTE8_R5_G6_B5_OES 0x8B97 +#define GL_PALETTE8_RGBA4_OES 0x8B98 +#define GL_PALETTE8_RGB5_A1_OES 0x8B99 +#endif /* GL_OES_compressed_paletted_texture */ + +#ifndef GL_OES_fixed_point +#define GL_OES_fixed_point 1 +typedef GLint GLfixed; +#define GL_FIXED_OES 0x140C +typedef void (APIENTRYP PFNGLALPHAFUNCXOESPROC) (GLenum func, GLfixed ref); +typedef void (APIENTRYP PFNGLCLEARCOLORXOESPROC) (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); +typedef void (APIENTRYP PFNGLCLEARDEPTHXOESPROC) (GLfixed depth); +typedef void (APIENTRYP PFNGLCLIPPLANEXOESPROC) (GLenum plane, const GLfixed *equation); +typedef void (APIENTRYP PFNGLCOLOR4XOESPROC) (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); +typedef void (APIENTRYP PFNGLDEPTHRANGEXOESPROC) (GLfixed n, GLfixed f); +typedef void (APIENTRYP PFNGLFOGXOESPROC) (GLenum pname, GLfixed param); +typedef void (APIENTRYP PFNGLFOGXVOESPROC) (GLenum pname, const GLfixed *param); +typedef void (APIENTRYP PFNGLFRUSTUMXOESPROC) (GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f); +typedef void (APIENTRYP PFNGLGETCLIPPLANEXOESPROC) (GLenum plane, GLfixed *equation); +typedef void (APIENTRYP PFNGLGETFIXEDVOESPROC) (GLenum pname, GLfixed *params); +typedef void (APIENTRYP PFNGLGETTEXENVXVOESPROC) (GLenum target, GLenum pname, GLfixed *params); +typedef void (APIENTRYP PFNGLGETTEXPARAMETERXVOESPROC) (GLenum target, GLenum pname, GLfixed *params); +typedef void (APIENTRYP PFNGLLIGHTMODELXOESPROC) (GLenum pname, GLfixed param); +typedef void (APIENTRYP PFNGLLIGHTMODELXVOESPROC) (GLenum pname, const GLfixed *param); +typedef void (APIENTRYP PFNGLLIGHTXOESPROC) (GLenum light, GLenum pname, GLfixed param); +typedef void (APIENTRYP PFNGLLIGHTXVOESPROC) (GLenum light, GLenum pname, const GLfixed *params); +typedef void (APIENTRYP PFNGLLINEWIDTHXOESPROC) (GLfixed width); +typedef void (APIENTRYP PFNGLLOADMATRIXXOESPROC) (const GLfixed *m); +typedef void (APIENTRYP PFNGLMATERIALXOESPROC) (GLenum face, GLenum pname, GLfixed param); +typedef void (APIENTRYP PFNGLMATERIALXVOESPROC) (GLenum face, GLenum pname, const GLfixed *param); +typedef void (APIENTRYP PFNGLMULTMATRIXXOESPROC) (const GLfixed *m); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4XOESPROC) (GLenum texture, GLfixed s, GLfixed t, GLfixed r, GLfixed q); +typedef void (APIENTRYP PFNGLNORMAL3XOESPROC) (GLfixed nx, GLfixed ny, GLfixed nz); +typedef void (APIENTRYP PFNGLORTHOXOESPROC) (GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f); +typedef void (APIENTRYP PFNGLPOINTPARAMETERXVOESPROC) (GLenum pname, const GLfixed *params); +typedef void (APIENTRYP PFNGLPOINTSIZEXOESPROC) (GLfixed size); +typedef void (APIENTRYP PFNGLPOLYGONOFFSETXOESPROC) (GLfixed factor, GLfixed units); +typedef void (APIENTRYP PFNGLROTATEXOESPROC) (GLfixed angle, GLfixed x, GLfixed y, GLfixed z); +typedef void (APIENTRYP PFNGLSAMPLECOVERAGEOESPROC) (GLfixed value, GLboolean invert); +typedef void (APIENTRYP PFNGLSCALEXOESPROC) (GLfixed x, GLfixed y, GLfixed z); +typedef void (APIENTRYP PFNGLTEXENVXOESPROC) (GLenum target, GLenum pname, GLfixed param); +typedef void (APIENTRYP PFNGLTEXENVXVOESPROC) (GLenum target, GLenum pname, const GLfixed *params); +typedef void (APIENTRYP PFNGLTEXPARAMETERXOESPROC) (GLenum target, GLenum pname, GLfixed param); +typedef void (APIENTRYP PFNGLTEXPARAMETERXVOESPROC) (GLenum target, GLenum pname, const GLfixed *params); +typedef void (APIENTRYP PFNGLTRANSLATEXOESPROC) (GLfixed x, GLfixed y, GLfixed z); +typedef void (APIENTRYP PFNGLACCUMXOESPROC) (GLenum op, GLfixed value); +typedef void (APIENTRYP PFNGLBITMAPXOESPROC) (GLsizei width, GLsizei height, GLfixed xorig, GLfixed yorig, GLfixed xmove, GLfixed ymove, const GLubyte *bitmap); +typedef void (APIENTRYP PFNGLBLENDCOLORXOESPROC) (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); +typedef void (APIENTRYP PFNGLCLEARACCUMXOESPROC) (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); +typedef void (APIENTRYP PFNGLCOLOR3XOESPROC) (GLfixed red, GLfixed green, GLfixed blue); +typedef void (APIENTRYP PFNGLCOLOR3XVOESPROC) (const GLfixed *components); +typedef void (APIENTRYP PFNGLCOLOR4XVOESPROC) (const GLfixed *components); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERXOESPROC) (GLenum target, GLenum pname, GLfixed param); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERXVOESPROC) (GLenum target, GLenum pname, const GLfixed *params); +typedef void (APIENTRYP PFNGLEVALCOORD1XOESPROC) (GLfixed u); +typedef void (APIENTRYP PFNGLEVALCOORD1XVOESPROC) (const GLfixed *coords); +typedef void (APIENTRYP PFNGLEVALCOORD2XOESPROC) (GLfixed u, GLfixed v); +typedef void (APIENTRYP PFNGLEVALCOORD2XVOESPROC) (const GLfixed *coords); +typedef void (APIENTRYP PFNGLFEEDBACKBUFFERXOESPROC) (GLsizei n, GLenum type, const GLfixed *buffer); +typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERXVOESPROC) (GLenum target, GLenum pname, GLfixed *params); +typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERXVOESPROC) (GLenum target, GLenum pname, GLfixed *params); +typedef void (APIENTRYP PFNGLGETLIGHTXOESPROC) (GLenum light, GLenum pname, GLfixed *params); +typedef void (APIENTRYP PFNGLGETMAPXVOESPROC) (GLenum target, GLenum query, GLfixed *v); +typedef void (APIENTRYP PFNGLGETMATERIALXOESPROC) (GLenum face, GLenum pname, GLfixed param); +typedef void (APIENTRYP PFNGLGETPIXELMAPXVPROC) (GLenum map, GLint size, GLfixed *values); +typedef void (APIENTRYP PFNGLGETTEXGENXVOESPROC) (GLenum coord, GLenum pname, GLfixed *params); +typedef void (APIENTRYP PFNGLGETTEXLEVELPARAMETERXVOESPROC) (GLenum target, GLint level, GLenum pname, GLfixed *params); +typedef void (APIENTRYP PFNGLINDEXXOESPROC) (GLfixed component); +typedef void (APIENTRYP PFNGLINDEXXVOESPROC) (const GLfixed *component); +typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXXOESPROC) (const GLfixed *m); +typedef void (APIENTRYP PFNGLMAP1XOESPROC) (GLenum target, GLfixed u1, GLfixed u2, GLint stride, GLint order, GLfixed points); +typedef void (APIENTRYP PFNGLMAP2XOESPROC) (GLenum target, GLfixed u1, GLfixed u2, GLint ustride, GLint uorder, GLfixed v1, GLfixed v2, GLint vstride, GLint vorder, GLfixed points); +typedef void (APIENTRYP PFNGLMAPGRID1XOESPROC) (GLint n, GLfixed u1, GLfixed u2); +typedef void (APIENTRYP PFNGLMAPGRID2XOESPROC) (GLint n, GLfixed u1, GLfixed u2, GLfixed v1, GLfixed v2); +typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXXOESPROC) (const GLfixed *m); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1XOESPROC) (GLenum texture, GLfixed s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1XVOESPROC) (GLenum texture, const GLfixed *coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2XOESPROC) (GLenum texture, GLfixed s, GLfixed t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2XVOESPROC) (GLenum texture, const GLfixed *coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3XOESPROC) (GLenum texture, GLfixed s, GLfixed t, GLfixed r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3XVOESPROC) (GLenum texture, const GLfixed *coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4XVOESPROC) (GLenum texture, const GLfixed *coords); +typedef void (APIENTRYP PFNGLNORMAL3XVOESPROC) (const GLfixed *coords); +typedef void (APIENTRYP PFNGLPASSTHROUGHXOESPROC) (GLfixed token); +typedef void (APIENTRYP PFNGLPIXELMAPXPROC) (GLenum map, GLint size, const GLfixed *values); +typedef void (APIENTRYP PFNGLPIXELSTOREXPROC) (GLenum pname, GLfixed param); +typedef void (APIENTRYP PFNGLPIXELTRANSFERXOESPROC) (GLenum pname, GLfixed param); +typedef void (APIENTRYP PFNGLPIXELZOOMXOESPROC) (GLfixed xfactor, GLfixed yfactor); +typedef void (APIENTRYP PFNGLPRIORITIZETEXTURESXOESPROC) (GLsizei n, const GLuint *textures, const GLfixed *priorities); +typedef void (APIENTRYP PFNGLRASTERPOS2XOESPROC) (GLfixed x, GLfixed y); +typedef void (APIENTRYP PFNGLRASTERPOS2XVOESPROC) (const GLfixed *coords); +typedef void (APIENTRYP PFNGLRASTERPOS3XOESPROC) (GLfixed x, GLfixed y, GLfixed z); +typedef void (APIENTRYP PFNGLRASTERPOS3XVOESPROC) (const GLfixed *coords); +typedef void (APIENTRYP PFNGLRASTERPOS4XOESPROC) (GLfixed x, GLfixed y, GLfixed z, GLfixed w); +typedef void (APIENTRYP PFNGLRASTERPOS4XVOESPROC) (const GLfixed *coords); +typedef void (APIENTRYP PFNGLRECTXOESPROC) (GLfixed x1, GLfixed y1, GLfixed x2, GLfixed y2); +typedef void (APIENTRYP PFNGLRECTXVOESPROC) (const GLfixed *v1, const GLfixed *v2); +typedef void (APIENTRYP PFNGLTEXCOORD1XOESPROC) (GLfixed s); +typedef void (APIENTRYP PFNGLTEXCOORD1XVOESPROC) (const GLfixed *coords); +typedef void (APIENTRYP PFNGLTEXCOORD2XOESPROC) (GLfixed s, GLfixed t); +typedef void (APIENTRYP PFNGLTEXCOORD2XVOESPROC) (const GLfixed *coords); +typedef void (APIENTRYP PFNGLTEXCOORD3XOESPROC) (GLfixed s, GLfixed t, GLfixed r); +typedef void (APIENTRYP PFNGLTEXCOORD3XVOESPROC) (const GLfixed *coords); +typedef void (APIENTRYP PFNGLTEXCOORD4XOESPROC) (GLfixed s, GLfixed t, GLfixed r, GLfixed q); +typedef void (APIENTRYP PFNGLTEXCOORD4XVOESPROC) (const GLfixed *coords); +typedef void (APIENTRYP PFNGLTEXGENXOESPROC) (GLenum coord, GLenum pname, GLfixed param); +typedef void (APIENTRYP PFNGLTEXGENXVOESPROC) (GLenum coord, GLenum pname, const GLfixed *params); +typedef void (APIENTRYP PFNGLVERTEX2XOESPROC) (GLfixed x); +typedef void (APIENTRYP PFNGLVERTEX2XVOESPROC) (const GLfixed *coords); +typedef void (APIENTRYP PFNGLVERTEX3XOESPROC) (GLfixed x, GLfixed y); +typedef void (APIENTRYP PFNGLVERTEX3XVOESPROC) (const GLfixed *coords); +typedef void (APIENTRYP PFNGLVERTEX4XOESPROC) (GLfixed x, GLfixed y, GLfixed z); +typedef void (APIENTRYP PFNGLVERTEX4XVOESPROC) (const GLfixed *coords); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glAlphaFuncxOES (GLenum func, GLfixed ref); +GLAPI void APIENTRY glClearColorxOES (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); +GLAPI void APIENTRY glClearDepthxOES (GLfixed depth); +GLAPI void APIENTRY glClipPlanexOES (GLenum plane, const GLfixed *equation); +GLAPI void APIENTRY glColor4xOES (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); +GLAPI void APIENTRY glDepthRangexOES (GLfixed n, GLfixed f); +GLAPI void APIENTRY glFogxOES (GLenum pname, GLfixed param); +GLAPI void APIENTRY glFogxvOES (GLenum pname, const GLfixed *param); +GLAPI void APIENTRY glFrustumxOES (GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f); +GLAPI void APIENTRY glGetClipPlanexOES (GLenum plane, GLfixed *equation); +GLAPI void APIENTRY glGetFixedvOES (GLenum pname, GLfixed *params); +GLAPI void APIENTRY glGetTexEnvxvOES (GLenum target, GLenum pname, GLfixed *params); +GLAPI void APIENTRY glGetTexParameterxvOES (GLenum target, GLenum pname, GLfixed *params); +GLAPI void APIENTRY glLightModelxOES (GLenum pname, GLfixed param); +GLAPI void APIENTRY glLightModelxvOES (GLenum pname, const GLfixed *param); +GLAPI void APIENTRY glLightxOES (GLenum light, GLenum pname, GLfixed param); +GLAPI void APIENTRY glLightxvOES (GLenum light, GLenum pname, const GLfixed *params); +GLAPI void APIENTRY glLineWidthxOES (GLfixed width); +GLAPI void APIENTRY glLoadMatrixxOES (const GLfixed *m); +GLAPI void APIENTRY glMaterialxOES (GLenum face, GLenum pname, GLfixed param); +GLAPI void APIENTRY glMaterialxvOES (GLenum face, GLenum pname, const GLfixed *param); +GLAPI void APIENTRY glMultMatrixxOES (const GLfixed *m); +GLAPI void APIENTRY glMultiTexCoord4xOES (GLenum texture, GLfixed s, GLfixed t, GLfixed r, GLfixed q); +GLAPI void APIENTRY glNormal3xOES (GLfixed nx, GLfixed ny, GLfixed nz); +GLAPI void APIENTRY glOrthoxOES (GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f); +GLAPI void APIENTRY glPointParameterxvOES (GLenum pname, const GLfixed *params); +GLAPI void APIENTRY glPointSizexOES (GLfixed size); +GLAPI void APIENTRY glPolygonOffsetxOES (GLfixed factor, GLfixed units); +GLAPI void APIENTRY glRotatexOES (GLfixed angle, GLfixed x, GLfixed y, GLfixed z); +GLAPI void APIENTRY glSampleCoverageOES (GLfixed value, GLboolean invert); +GLAPI void APIENTRY glScalexOES (GLfixed x, GLfixed y, GLfixed z); +GLAPI void APIENTRY glTexEnvxOES (GLenum target, GLenum pname, GLfixed param); +GLAPI void APIENTRY glTexEnvxvOES (GLenum target, GLenum pname, const GLfixed *params); +GLAPI void APIENTRY glTexParameterxOES (GLenum target, GLenum pname, GLfixed param); +GLAPI void APIENTRY glTexParameterxvOES (GLenum target, GLenum pname, const GLfixed *params); +GLAPI void APIENTRY glTranslatexOES (GLfixed x, GLfixed y, GLfixed z); +GLAPI void APIENTRY glAccumxOES (GLenum op, GLfixed value); +GLAPI void APIENTRY glBitmapxOES (GLsizei width, GLsizei height, GLfixed xorig, GLfixed yorig, GLfixed xmove, GLfixed ymove, const GLubyte *bitmap); +GLAPI void APIENTRY glBlendColorxOES (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); +GLAPI void APIENTRY glClearAccumxOES (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); +GLAPI void APIENTRY glColor3xOES (GLfixed red, GLfixed green, GLfixed blue); +GLAPI void APIENTRY glColor3xvOES (const GLfixed *components); +GLAPI void APIENTRY glColor4xvOES (const GLfixed *components); +GLAPI void APIENTRY glConvolutionParameterxOES (GLenum target, GLenum pname, GLfixed param); +GLAPI void APIENTRY glConvolutionParameterxvOES (GLenum target, GLenum pname, const GLfixed *params); +GLAPI void APIENTRY glEvalCoord1xOES (GLfixed u); +GLAPI void APIENTRY glEvalCoord1xvOES (const GLfixed *coords); +GLAPI void APIENTRY glEvalCoord2xOES (GLfixed u, GLfixed v); +GLAPI void APIENTRY glEvalCoord2xvOES (const GLfixed *coords); +GLAPI void APIENTRY glFeedbackBufferxOES (GLsizei n, GLenum type, const GLfixed *buffer); +GLAPI void APIENTRY glGetConvolutionParameterxvOES (GLenum target, GLenum pname, GLfixed *params); +GLAPI void APIENTRY glGetHistogramParameterxvOES (GLenum target, GLenum pname, GLfixed *params); +GLAPI void APIENTRY glGetLightxOES (GLenum light, GLenum pname, GLfixed *params); +GLAPI void APIENTRY glGetMapxvOES (GLenum target, GLenum query, GLfixed *v); +GLAPI void APIENTRY glGetMaterialxOES (GLenum face, GLenum pname, GLfixed param); +GLAPI void APIENTRY glGetPixelMapxv (GLenum map, GLint size, GLfixed *values); +GLAPI void APIENTRY glGetTexGenxvOES (GLenum coord, GLenum pname, GLfixed *params); +GLAPI void APIENTRY glGetTexLevelParameterxvOES (GLenum target, GLint level, GLenum pname, GLfixed *params); +GLAPI void APIENTRY glIndexxOES (GLfixed component); +GLAPI void APIENTRY glIndexxvOES (const GLfixed *component); +GLAPI void APIENTRY glLoadTransposeMatrixxOES (const GLfixed *m); +GLAPI void APIENTRY glMap1xOES (GLenum target, GLfixed u1, GLfixed u2, GLint stride, GLint order, GLfixed points); +GLAPI void APIENTRY glMap2xOES (GLenum target, GLfixed u1, GLfixed u2, GLint ustride, GLint uorder, GLfixed v1, GLfixed v2, GLint vstride, GLint vorder, GLfixed points); +GLAPI void APIENTRY glMapGrid1xOES (GLint n, GLfixed u1, GLfixed u2); +GLAPI void APIENTRY glMapGrid2xOES (GLint n, GLfixed u1, GLfixed u2, GLfixed v1, GLfixed v2); +GLAPI void APIENTRY glMultTransposeMatrixxOES (const GLfixed *m); +GLAPI void APIENTRY glMultiTexCoord1xOES (GLenum texture, GLfixed s); +GLAPI void APIENTRY glMultiTexCoord1xvOES (GLenum texture, const GLfixed *coords); +GLAPI void APIENTRY glMultiTexCoord2xOES (GLenum texture, GLfixed s, GLfixed t); +GLAPI void APIENTRY glMultiTexCoord2xvOES (GLenum texture, const GLfixed *coords); +GLAPI void APIENTRY glMultiTexCoord3xOES (GLenum texture, GLfixed s, GLfixed t, GLfixed r); +GLAPI void APIENTRY glMultiTexCoord3xvOES (GLenum texture, const GLfixed *coords); +GLAPI void APIENTRY glMultiTexCoord4xvOES (GLenum texture, const GLfixed *coords); +GLAPI void APIENTRY glNormal3xvOES (const GLfixed *coords); +GLAPI void APIENTRY glPassThroughxOES (GLfixed token); +GLAPI void APIENTRY glPixelMapx (GLenum map, GLint size, const GLfixed *values); +GLAPI void APIENTRY glPixelStorex (GLenum pname, GLfixed param); +GLAPI void APIENTRY glPixelTransferxOES (GLenum pname, GLfixed param); +GLAPI void APIENTRY glPixelZoomxOES (GLfixed xfactor, GLfixed yfactor); +GLAPI void APIENTRY glPrioritizeTexturesxOES (GLsizei n, const GLuint *textures, const GLfixed *priorities); +GLAPI void APIENTRY glRasterPos2xOES (GLfixed x, GLfixed y); +GLAPI void APIENTRY glRasterPos2xvOES (const GLfixed *coords); +GLAPI void APIENTRY glRasterPos3xOES (GLfixed x, GLfixed y, GLfixed z); +GLAPI void APIENTRY glRasterPos3xvOES (const GLfixed *coords); +GLAPI void APIENTRY glRasterPos4xOES (GLfixed x, GLfixed y, GLfixed z, GLfixed w); +GLAPI void APIENTRY glRasterPos4xvOES (const GLfixed *coords); +GLAPI void APIENTRY glRectxOES (GLfixed x1, GLfixed y1, GLfixed x2, GLfixed y2); +GLAPI void APIENTRY glRectxvOES (const GLfixed *v1, const GLfixed *v2); +GLAPI void APIENTRY glTexCoord1xOES (GLfixed s); +GLAPI void APIENTRY glTexCoord1xvOES (const GLfixed *coords); +GLAPI void APIENTRY glTexCoord2xOES (GLfixed s, GLfixed t); +GLAPI void APIENTRY glTexCoord2xvOES (const GLfixed *coords); +GLAPI void APIENTRY glTexCoord3xOES (GLfixed s, GLfixed t, GLfixed r); +GLAPI void APIENTRY glTexCoord3xvOES (const GLfixed *coords); +GLAPI void APIENTRY glTexCoord4xOES (GLfixed s, GLfixed t, GLfixed r, GLfixed q); +GLAPI void APIENTRY glTexCoord4xvOES (const GLfixed *coords); +GLAPI void APIENTRY glTexGenxOES (GLenum coord, GLenum pname, GLfixed param); +GLAPI void APIENTRY glTexGenxvOES (GLenum coord, GLenum pname, const GLfixed *params); +GLAPI void APIENTRY glVertex2xOES (GLfixed x); +GLAPI void APIENTRY glVertex2xvOES (const GLfixed *coords); +GLAPI void APIENTRY glVertex3xOES (GLfixed x, GLfixed y); +GLAPI void APIENTRY glVertex3xvOES (const GLfixed *coords); +GLAPI void APIENTRY glVertex4xOES (GLfixed x, GLfixed y, GLfixed z); +GLAPI void APIENTRY glVertex4xvOES (const GLfixed *coords); +#endif +#endif /* GL_OES_fixed_point */ + +#ifndef GL_OES_query_matrix +#define GL_OES_query_matrix 1 +typedef GLbitfield (APIENTRYP PFNGLQUERYMATRIXXOESPROC) (GLfixed *mantissa, GLint *exponent); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLbitfield APIENTRY glQueryMatrixxOES (GLfixed *mantissa, GLint *exponent); +#endif +#endif /* GL_OES_query_matrix */ + +#ifndef GL_OES_read_format +#define GL_OES_read_format 1 +#define GL_IMPLEMENTATION_COLOR_READ_TYPE_OES 0x8B9A +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES 0x8B9B +#endif /* GL_OES_read_format */ + +#ifndef GL_OES_single_precision +#define GL_OES_single_precision 1 +typedef void (APIENTRYP PFNGLCLEARDEPTHFOESPROC) (GLclampf depth); +typedef void (APIENTRYP PFNGLCLIPPLANEFOESPROC) (GLenum plane, const GLfloat *equation); +typedef void (APIENTRYP PFNGLDEPTHRANGEFOESPROC) (GLclampf n, GLclampf f); +typedef void (APIENTRYP PFNGLFRUSTUMFOESPROC) (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); +typedef void (APIENTRYP PFNGLGETCLIPPLANEFOESPROC) (GLenum plane, GLfloat *equation); +typedef void (APIENTRYP PFNGLORTHOFOESPROC) (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glClearDepthfOES (GLclampf depth); +GLAPI void APIENTRY glClipPlanefOES (GLenum plane, const GLfloat *equation); +GLAPI void APIENTRY glDepthRangefOES (GLclampf n, GLclampf f); +GLAPI void APIENTRY glFrustumfOES (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); +GLAPI void APIENTRY glGetClipPlanefOES (GLenum plane, GLfloat *equation); +GLAPI void APIENTRY glOrthofOES (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); +#endif +#endif /* GL_OES_single_precision */ + +#ifndef GL_3DFX_multisample +#define GL_3DFX_multisample 1 +#define GL_MULTISAMPLE_3DFX 0x86B2 +#define GL_SAMPLE_BUFFERS_3DFX 0x86B3 +#define GL_SAMPLES_3DFX 0x86B4 +#define GL_MULTISAMPLE_BIT_3DFX 0x20000000 +#endif /* GL_3DFX_multisample */ + +#ifndef GL_3DFX_tbuffer +#define GL_3DFX_tbuffer 1 +typedef void (APIENTRYP PFNGLTBUFFERMASK3DFXPROC) (GLuint mask); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTbufferMask3DFX (GLuint mask); +#endif +#endif /* GL_3DFX_tbuffer */ + +#ifndef GL_3DFX_texture_compression_FXT1 +#define GL_3DFX_texture_compression_FXT1 1 +#define GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0 +#define GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1 +#endif /* GL_3DFX_texture_compression_FXT1 */ + +#ifndef GL_AMD_blend_minmax_factor +#define GL_AMD_blend_minmax_factor 1 +#define GL_FACTOR_MIN_AMD 0x901C +#define GL_FACTOR_MAX_AMD 0x901D +#endif /* GL_AMD_blend_minmax_factor */ + +#ifndef GL_AMD_conservative_depth +#define GL_AMD_conservative_depth 1 +#endif /* GL_AMD_conservative_depth */ + +#ifndef GL_AMD_debug_output +#define GL_AMD_debug_output 1 +typedef void (APIENTRY *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,void *userParam); +#define GL_MAX_DEBUG_MESSAGE_LENGTH_AMD 0x9143 +#define GL_MAX_DEBUG_LOGGED_MESSAGES_AMD 0x9144 +#define GL_DEBUG_LOGGED_MESSAGES_AMD 0x9145 +#define GL_DEBUG_SEVERITY_HIGH_AMD 0x9146 +#define GL_DEBUG_SEVERITY_MEDIUM_AMD 0x9147 +#define GL_DEBUG_SEVERITY_LOW_AMD 0x9148 +#define GL_DEBUG_CATEGORY_API_ERROR_AMD 0x9149 +#define GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD 0x914A +#define GL_DEBUG_CATEGORY_DEPRECATION_AMD 0x914B +#define GL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD 0x914C +#define GL_DEBUG_CATEGORY_PERFORMANCE_AMD 0x914D +#define GL_DEBUG_CATEGORY_SHADER_COMPILER_AMD 0x914E +#define GL_DEBUG_CATEGORY_APPLICATION_AMD 0x914F +#define GL_DEBUG_CATEGORY_OTHER_AMD 0x9150 +typedef void (APIENTRYP PFNGLDEBUGMESSAGEENABLEAMDPROC) (GLenum category, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); +typedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTAMDPROC) (GLenum category, GLenum severity, GLuint id, GLsizei length, const GLchar *buf); +typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKAMDPROC) (GLDEBUGPROCAMD callback, void *userParam); +typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGAMDPROC) (GLuint count, GLsizei bufsize, GLenum *categories, GLuint *severities, GLuint *ids, GLsizei *lengths, GLchar *message); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDebugMessageEnableAMD (GLenum category, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); +GLAPI void APIENTRY glDebugMessageInsertAMD (GLenum category, GLenum severity, GLuint id, GLsizei length, const GLchar *buf); +GLAPI void APIENTRY glDebugMessageCallbackAMD (GLDEBUGPROCAMD callback, void *userParam); +GLAPI GLuint APIENTRY glGetDebugMessageLogAMD (GLuint count, GLsizei bufsize, GLenum *categories, GLuint *severities, GLuint *ids, GLsizei *lengths, GLchar *message); +#endif +#endif /* GL_AMD_debug_output */ + +#ifndef GL_AMD_depth_clamp_separate +#define GL_AMD_depth_clamp_separate 1 +#define GL_DEPTH_CLAMP_NEAR_AMD 0x901E +#define GL_DEPTH_CLAMP_FAR_AMD 0x901F +#endif /* GL_AMD_depth_clamp_separate */ + +#ifndef GL_AMD_draw_buffers_blend +#define GL_AMD_draw_buffers_blend 1 +typedef void (APIENTRYP PFNGLBLENDFUNCINDEXEDAMDPROC) (GLuint buf, GLenum src, GLenum dst); +typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +typedef void (APIENTRYP PFNGLBLENDEQUATIONINDEXEDAMDPROC) (GLuint buf, GLenum mode); +typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendFuncIndexedAMD (GLuint buf, GLenum src, GLenum dst); +GLAPI void APIENTRY glBlendFuncSeparateIndexedAMD (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +GLAPI void APIENTRY glBlendEquationIndexedAMD (GLuint buf, GLenum mode); +GLAPI void APIENTRY glBlendEquationSeparateIndexedAMD (GLuint buf, GLenum modeRGB, GLenum modeAlpha); +#endif +#endif /* GL_AMD_draw_buffers_blend */ + +#ifndef GL_AMD_gcn_shader +#define GL_AMD_gcn_shader 1 +#endif /* GL_AMD_gcn_shader */ + +#ifndef GL_AMD_gpu_shader_int64 +#define GL_AMD_gpu_shader_int64 1 +typedef int64_t GLint64EXT; +#define GL_INT64_NV 0x140E +#define GL_UNSIGNED_INT64_NV 0x140F +#define GL_INT8_NV 0x8FE0 +#define GL_INT8_VEC2_NV 0x8FE1 +#define GL_INT8_VEC3_NV 0x8FE2 +#define GL_INT8_VEC4_NV 0x8FE3 +#define GL_INT16_NV 0x8FE4 +#define GL_INT16_VEC2_NV 0x8FE5 +#define GL_INT16_VEC3_NV 0x8FE6 +#define GL_INT16_VEC4_NV 0x8FE7 +#define GL_INT64_VEC2_NV 0x8FE9 +#define GL_INT64_VEC3_NV 0x8FEA +#define GL_INT64_VEC4_NV 0x8FEB +#define GL_UNSIGNED_INT8_NV 0x8FEC +#define GL_UNSIGNED_INT8_VEC2_NV 0x8FED +#define GL_UNSIGNED_INT8_VEC3_NV 0x8FEE +#define GL_UNSIGNED_INT8_VEC4_NV 0x8FEF +#define GL_UNSIGNED_INT16_NV 0x8FF0 +#define GL_UNSIGNED_INT16_VEC2_NV 0x8FF1 +#define GL_UNSIGNED_INT16_VEC3_NV 0x8FF2 +#define GL_UNSIGNED_INT16_VEC4_NV 0x8FF3 +#define GL_UNSIGNED_INT64_VEC2_NV 0x8FF5 +#define GL_UNSIGNED_INT64_VEC3_NV 0x8FF6 +#define GL_UNSIGNED_INT64_VEC4_NV 0x8FF7 +#define GL_FLOAT16_NV 0x8FF8 +#define GL_FLOAT16_VEC2_NV 0x8FF9 +#define GL_FLOAT16_VEC3_NV 0x8FFA +#define GL_FLOAT16_VEC4_NV 0x8FFB +typedef void (APIENTRYP PFNGLUNIFORM1I64NVPROC) (GLint location, GLint64EXT x); +typedef void (APIENTRYP PFNGLUNIFORM2I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y); +typedef void (APIENTRYP PFNGLUNIFORM3I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); +typedef void (APIENTRYP PFNGLUNIFORM4I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); +typedef void (APIENTRYP PFNGLUNIFORM1I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value); +typedef void (APIENTRYP PFNGLUNIFORM2I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value); +typedef void (APIENTRYP PFNGLUNIFORM3I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value); +typedef void (APIENTRYP PFNGLUNIFORM4I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value); +typedef void (APIENTRYP PFNGLUNIFORM1UI64NVPROC) (GLint location, GLuint64EXT x); +typedef void (APIENTRYP PFNGLUNIFORM2UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y); +typedef void (APIENTRYP PFNGLUNIFORM3UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); +typedef void (APIENTRYP PFNGLUNIFORM4UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); +typedef void (APIENTRYP PFNGLUNIFORM1UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value); +typedef void (APIENTRYP PFNGLUNIFORM2UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value); +typedef void (APIENTRYP PFNGLUNIFORM3UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value); +typedef void (APIENTRYP PFNGLUNIFORM4UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value); +typedef void (APIENTRYP PFNGLGETUNIFORMI64VNVPROC) (GLuint program, GLint location, GLint64EXT *params); +typedef void (APIENTRYP PFNGLGETUNIFORMUI64VNVPROC) (GLuint program, GLint location, GLuint64EXT *params); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1I64NVPROC) (GLuint program, GLint location, GLint64EXT x); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glUniform1i64NV (GLint location, GLint64EXT x); +GLAPI void APIENTRY glUniform2i64NV (GLint location, GLint64EXT x, GLint64EXT y); +GLAPI void APIENTRY glUniform3i64NV (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); +GLAPI void APIENTRY glUniform4i64NV (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); +GLAPI void APIENTRY glUniform1i64vNV (GLint location, GLsizei count, const GLint64EXT *value); +GLAPI void APIENTRY glUniform2i64vNV (GLint location, GLsizei count, const GLint64EXT *value); +GLAPI void APIENTRY glUniform3i64vNV (GLint location, GLsizei count, const GLint64EXT *value); +GLAPI void APIENTRY glUniform4i64vNV (GLint location, GLsizei count, const GLint64EXT *value); +GLAPI void APIENTRY glUniform1ui64NV (GLint location, GLuint64EXT x); +GLAPI void APIENTRY glUniform2ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y); +GLAPI void APIENTRY glUniform3ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); +GLAPI void APIENTRY glUniform4ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); +GLAPI void APIENTRY glUniform1ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value); +GLAPI void APIENTRY glUniform2ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value); +GLAPI void APIENTRY glUniform3ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value); +GLAPI void APIENTRY glUniform4ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value); +GLAPI void APIENTRY glGetUniformi64vNV (GLuint program, GLint location, GLint64EXT *params); +GLAPI void APIENTRY glGetUniformui64vNV (GLuint program, GLint location, GLuint64EXT *params); +GLAPI void APIENTRY glProgramUniform1i64NV (GLuint program, GLint location, GLint64EXT x); +GLAPI void APIENTRY glProgramUniform2i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y); +GLAPI void APIENTRY glProgramUniform3i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); +GLAPI void APIENTRY glProgramUniform4i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); +GLAPI void APIENTRY glProgramUniform1i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); +GLAPI void APIENTRY glProgramUniform2i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); +GLAPI void APIENTRY glProgramUniform3i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); +GLAPI void APIENTRY glProgramUniform4i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); +GLAPI void APIENTRY glProgramUniform1ui64NV (GLuint program, GLint location, GLuint64EXT x); +GLAPI void APIENTRY glProgramUniform2ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y); +GLAPI void APIENTRY glProgramUniform3ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); +GLAPI void APIENTRY glProgramUniform4ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); +GLAPI void APIENTRY glProgramUniform1ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +GLAPI void APIENTRY glProgramUniform2ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +GLAPI void APIENTRY glProgramUniform3ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +GLAPI void APIENTRY glProgramUniform4ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +#endif +#endif /* GL_AMD_gpu_shader_int64 */ + +#ifndef GL_AMD_interleaved_elements +#define GL_AMD_interleaved_elements 1 +#define GL_VERTEX_ELEMENT_SWIZZLE_AMD 0x91A4 +#define GL_VERTEX_ID_SWIZZLE_AMD 0x91A5 +typedef void (APIENTRYP PFNGLVERTEXATTRIBPARAMETERIAMDPROC) (GLuint index, GLenum pname, GLint param); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexAttribParameteriAMD (GLuint index, GLenum pname, GLint param); +#endif +#endif /* GL_AMD_interleaved_elements */ + +#ifndef GL_AMD_multi_draw_indirect +#define GL_AMD_multi_draw_indirect 1 +typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTAMDPROC) (GLenum mode, const void *indirect, GLsizei primcount, GLsizei stride); +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTAMDPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei primcount, GLsizei stride); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMultiDrawArraysIndirectAMD (GLenum mode, const void *indirect, GLsizei primcount, GLsizei stride); +GLAPI void APIENTRY glMultiDrawElementsIndirectAMD (GLenum mode, GLenum type, const void *indirect, GLsizei primcount, GLsizei stride); +#endif +#endif /* GL_AMD_multi_draw_indirect */ + +#ifndef GL_AMD_name_gen_delete +#define GL_AMD_name_gen_delete 1 +#define GL_DATA_BUFFER_AMD 0x9151 +#define GL_PERFORMANCE_MONITOR_AMD 0x9152 +#define GL_QUERY_OBJECT_AMD 0x9153 +#define GL_VERTEX_ARRAY_OBJECT_AMD 0x9154 +#define GL_SAMPLER_OBJECT_AMD 0x9155 +typedef void (APIENTRYP PFNGLGENNAMESAMDPROC) (GLenum identifier, GLuint num, GLuint *names); +typedef void (APIENTRYP PFNGLDELETENAMESAMDPROC) (GLenum identifier, GLuint num, const GLuint *names); +typedef GLboolean (APIENTRYP PFNGLISNAMEAMDPROC) (GLenum identifier, GLuint name); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGenNamesAMD (GLenum identifier, GLuint num, GLuint *names); +GLAPI void APIENTRY glDeleteNamesAMD (GLenum identifier, GLuint num, const GLuint *names); +GLAPI GLboolean APIENTRY glIsNameAMD (GLenum identifier, GLuint name); +#endif +#endif /* GL_AMD_name_gen_delete */ + +#ifndef GL_AMD_occlusion_query_event +#define GL_AMD_occlusion_query_event 1 +#define GL_OCCLUSION_QUERY_EVENT_MASK_AMD 0x874F +#define GL_QUERY_DEPTH_PASS_EVENT_BIT_AMD 0x00000001 +#define GL_QUERY_DEPTH_FAIL_EVENT_BIT_AMD 0x00000002 +#define GL_QUERY_STENCIL_FAIL_EVENT_BIT_AMD 0x00000004 +#define GL_QUERY_DEPTH_BOUNDS_FAIL_EVENT_BIT_AMD 0x00000008 +#define GL_QUERY_ALL_EVENT_BITS_AMD 0xFFFFFFFF +typedef void (APIENTRYP PFNGLQUERYOBJECTPARAMETERUIAMDPROC) (GLenum target, GLuint id, GLenum pname, GLuint param); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glQueryObjectParameteruiAMD (GLenum target, GLuint id, GLenum pname, GLuint param); +#endif +#endif /* GL_AMD_occlusion_query_event */ + +#ifndef GL_AMD_performance_monitor +#define GL_AMD_performance_monitor 1 +#define GL_COUNTER_TYPE_AMD 0x8BC0 +#define GL_COUNTER_RANGE_AMD 0x8BC1 +#define GL_UNSIGNED_INT64_AMD 0x8BC2 +#define GL_PERCENTAGE_AMD 0x8BC3 +#define GL_PERFMON_RESULT_AVAILABLE_AMD 0x8BC4 +#define GL_PERFMON_RESULT_SIZE_AMD 0x8BC5 +#define GL_PERFMON_RESULT_AMD 0x8BC6 +typedef void (APIENTRYP PFNGLGETPERFMONITORGROUPSAMDPROC) (GLint *numGroups, GLsizei groupsSize, GLuint *groups); +typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERSAMDPROC) (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters); +typedef void (APIENTRYP PFNGLGETPERFMONITORGROUPSTRINGAMDPROC) (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString); +typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC) (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString); +typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERINFOAMDPROC) (GLuint group, GLuint counter, GLenum pname, void *data); +typedef void (APIENTRYP PFNGLGENPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors); +typedef void (APIENTRYP PFNGLDELETEPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors); +typedef void (APIENTRYP PFNGLSELECTPERFMONITORCOUNTERSAMDPROC) (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *counterList); +typedef void (APIENTRYP PFNGLBEGINPERFMONITORAMDPROC) (GLuint monitor); +typedef void (APIENTRYP PFNGLENDPERFMONITORAMDPROC) (GLuint monitor); +typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGetPerfMonitorGroupsAMD (GLint *numGroups, GLsizei groupsSize, GLuint *groups); +GLAPI void APIENTRY glGetPerfMonitorCountersAMD (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters); +GLAPI void APIENTRY glGetPerfMonitorGroupStringAMD (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString); +GLAPI void APIENTRY glGetPerfMonitorCounterStringAMD (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString); +GLAPI void APIENTRY glGetPerfMonitorCounterInfoAMD (GLuint group, GLuint counter, GLenum pname, void *data); +GLAPI void APIENTRY glGenPerfMonitorsAMD (GLsizei n, GLuint *monitors); +GLAPI void APIENTRY glDeletePerfMonitorsAMD (GLsizei n, GLuint *monitors); +GLAPI void APIENTRY glSelectPerfMonitorCountersAMD (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *counterList); +GLAPI void APIENTRY glBeginPerfMonitorAMD (GLuint monitor); +GLAPI void APIENTRY glEndPerfMonitorAMD (GLuint monitor); +GLAPI void APIENTRY glGetPerfMonitorCounterDataAMD (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten); +#endif +#endif /* GL_AMD_performance_monitor */ + +#ifndef GL_AMD_pinned_memory +#define GL_AMD_pinned_memory 1 +#define GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD 0x9160 +#endif /* GL_AMD_pinned_memory */ + +#ifndef GL_AMD_query_buffer_object +#define GL_AMD_query_buffer_object 1 +#define GL_QUERY_BUFFER_AMD 0x9192 +#define GL_QUERY_BUFFER_BINDING_AMD 0x9193 +#define GL_QUERY_RESULT_NO_WAIT_AMD 0x9194 +#endif /* GL_AMD_query_buffer_object */ + +#ifndef GL_AMD_sample_positions +#define GL_AMD_sample_positions 1 +#define GL_SUBSAMPLE_DISTANCE_AMD 0x883F +typedef void (APIENTRYP PFNGLSETMULTISAMPLEFVAMDPROC) (GLenum pname, GLuint index, const GLfloat *val); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSetMultisamplefvAMD (GLenum pname, GLuint index, const GLfloat *val); +#endif +#endif /* GL_AMD_sample_positions */ + +#ifndef GL_AMD_seamless_cubemap_per_texture +#define GL_AMD_seamless_cubemap_per_texture 1 +#endif /* GL_AMD_seamless_cubemap_per_texture */ + +#ifndef GL_AMD_shader_atomic_counter_ops +#define GL_AMD_shader_atomic_counter_ops 1 +#endif /* GL_AMD_shader_atomic_counter_ops */ + +#ifndef GL_AMD_shader_stencil_export +#define GL_AMD_shader_stencil_export 1 +#endif /* GL_AMD_shader_stencil_export */ + +#ifndef GL_AMD_shader_trinary_minmax +#define GL_AMD_shader_trinary_minmax 1 +#endif /* GL_AMD_shader_trinary_minmax */ + +#ifndef GL_AMD_sparse_texture +#define GL_AMD_sparse_texture 1 +#define GL_VIRTUAL_PAGE_SIZE_X_AMD 0x9195 +#define GL_VIRTUAL_PAGE_SIZE_Y_AMD 0x9196 +#define GL_VIRTUAL_PAGE_SIZE_Z_AMD 0x9197 +#define GL_MAX_SPARSE_TEXTURE_SIZE_AMD 0x9198 +#define GL_MAX_SPARSE_3D_TEXTURE_SIZE_AMD 0x9199 +#define GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS 0x919A +#define GL_MIN_SPARSE_LEVEL_AMD 0x919B +#define GL_MIN_LOD_WARNING_AMD 0x919C +#define GL_TEXTURE_STORAGE_SPARSE_BIT_AMD 0x00000001 +typedef void (APIENTRYP PFNGLTEXSTORAGESPARSEAMDPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei layers, GLbitfield flags); +typedef void (APIENTRYP PFNGLTEXTURESTORAGESPARSEAMDPROC) (GLuint texture, GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei layers, GLbitfield flags); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexStorageSparseAMD (GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei layers, GLbitfield flags); +GLAPI void APIENTRY glTextureStorageSparseAMD (GLuint texture, GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei layers, GLbitfield flags); +#endif +#endif /* GL_AMD_sparse_texture */ + +#ifndef GL_AMD_stencil_operation_extended +#define GL_AMD_stencil_operation_extended 1 +#define GL_SET_AMD 0x874A +#define GL_REPLACE_VALUE_AMD 0x874B +#define GL_STENCIL_OP_VALUE_AMD 0x874C +#define GL_STENCIL_BACK_OP_VALUE_AMD 0x874D +typedef void (APIENTRYP PFNGLSTENCILOPVALUEAMDPROC) (GLenum face, GLuint value); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glStencilOpValueAMD (GLenum face, GLuint value); +#endif +#endif /* GL_AMD_stencil_operation_extended */ + +#ifndef GL_AMD_texture_texture4 +#define GL_AMD_texture_texture4 1 +#endif /* GL_AMD_texture_texture4 */ + +#ifndef GL_AMD_transform_feedback3_lines_triangles +#define GL_AMD_transform_feedback3_lines_triangles 1 +#endif /* GL_AMD_transform_feedback3_lines_triangles */ + +#ifndef GL_AMD_transform_feedback4 +#define GL_AMD_transform_feedback4 1 +#define GL_STREAM_RASTERIZATION_AMD 0x91A0 +#endif /* GL_AMD_transform_feedback4 */ + +#ifndef GL_AMD_vertex_shader_layer +#define GL_AMD_vertex_shader_layer 1 +#endif /* GL_AMD_vertex_shader_layer */ + +#ifndef GL_AMD_vertex_shader_tessellator +#define GL_AMD_vertex_shader_tessellator 1 +#define GL_SAMPLER_BUFFER_AMD 0x9001 +#define GL_INT_SAMPLER_BUFFER_AMD 0x9002 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER_AMD 0x9003 +#define GL_TESSELLATION_MODE_AMD 0x9004 +#define GL_TESSELLATION_FACTOR_AMD 0x9005 +#define GL_DISCRETE_AMD 0x9006 +#define GL_CONTINUOUS_AMD 0x9007 +typedef void (APIENTRYP PFNGLTESSELLATIONFACTORAMDPROC) (GLfloat factor); +typedef void (APIENTRYP PFNGLTESSELLATIONMODEAMDPROC) (GLenum mode); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTessellationFactorAMD (GLfloat factor); +GLAPI void APIENTRY glTessellationModeAMD (GLenum mode); +#endif +#endif /* GL_AMD_vertex_shader_tessellator */ + +#ifndef GL_AMD_vertex_shader_viewport_index +#define GL_AMD_vertex_shader_viewport_index 1 +#endif /* GL_AMD_vertex_shader_viewport_index */ + +#ifndef GL_APPLE_aux_depth_stencil +#define GL_APPLE_aux_depth_stencil 1 +#define GL_AUX_DEPTH_STENCIL_APPLE 0x8A14 +#endif /* GL_APPLE_aux_depth_stencil */ + +#ifndef GL_APPLE_client_storage +#define GL_APPLE_client_storage 1 +#define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2 +#endif /* GL_APPLE_client_storage */ + +#ifndef GL_APPLE_element_array +#define GL_APPLE_element_array 1 +#define GL_ELEMENT_ARRAY_APPLE 0x8A0C +#define GL_ELEMENT_ARRAY_TYPE_APPLE 0x8A0D +#define GL_ELEMENT_ARRAY_POINTER_APPLE 0x8A0E +typedef void (APIENTRYP PFNGLELEMENTPOINTERAPPLEPROC) (GLenum type, const void *pointer); +typedef void (APIENTRYP PFNGLDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, GLint first, GLsizei count); +typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count); +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); +typedef void (APIENTRYP PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, const GLint *first, const GLsizei *count, GLsizei primcount); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glElementPointerAPPLE (GLenum type, const void *pointer); +GLAPI void APIENTRY glDrawElementArrayAPPLE (GLenum mode, GLint first, GLsizei count); +GLAPI void APIENTRY glDrawRangeElementArrayAPPLE (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count); +GLAPI void APIENTRY glMultiDrawElementArrayAPPLE (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); +GLAPI void APIENTRY glMultiDrawRangeElementArrayAPPLE (GLenum mode, GLuint start, GLuint end, const GLint *first, const GLsizei *count, GLsizei primcount); +#endif +#endif /* GL_APPLE_element_array */ + +#ifndef GL_APPLE_fence +#define GL_APPLE_fence 1 +#define GL_DRAW_PIXELS_APPLE 0x8A0A +#define GL_FENCE_APPLE 0x8A0B +typedef void (APIENTRYP PFNGLGENFENCESAPPLEPROC) (GLsizei n, GLuint *fences); +typedef void (APIENTRYP PFNGLDELETEFENCESAPPLEPROC) (GLsizei n, const GLuint *fences); +typedef void (APIENTRYP PFNGLSETFENCEAPPLEPROC) (GLuint fence); +typedef GLboolean (APIENTRYP PFNGLISFENCEAPPLEPROC) (GLuint fence); +typedef GLboolean (APIENTRYP PFNGLTESTFENCEAPPLEPROC) (GLuint fence); +typedef void (APIENTRYP PFNGLFINISHFENCEAPPLEPROC) (GLuint fence); +typedef GLboolean (APIENTRYP PFNGLTESTOBJECTAPPLEPROC) (GLenum object, GLuint name); +typedef void (APIENTRYP PFNGLFINISHOBJECTAPPLEPROC) (GLenum object, GLint name); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGenFencesAPPLE (GLsizei n, GLuint *fences); +GLAPI void APIENTRY glDeleteFencesAPPLE (GLsizei n, const GLuint *fences); +GLAPI void APIENTRY glSetFenceAPPLE (GLuint fence); +GLAPI GLboolean APIENTRY glIsFenceAPPLE (GLuint fence); +GLAPI GLboolean APIENTRY glTestFenceAPPLE (GLuint fence); +GLAPI void APIENTRY glFinishFenceAPPLE (GLuint fence); +GLAPI GLboolean APIENTRY glTestObjectAPPLE (GLenum object, GLuint name); +GLAPI void APIENTRY glFinishObjectAPPLE (GLenum object, GLint name); +#endif +#endif /* GL_APPLE_fence */ + +#ifndef GL_APPLE_float_pixels +#define GL_APPLE_float_pixels 1 +#define GL_HALF_APPLE 0x140B +#define GL_RGBA_FLOAT32_APPLE 0x8814 +#define GL_RGB_FLOAT32_APPLE 0x8815 +#define GL_ALPHA_FLOAT32_APPLE 0x8816 +#define GL_INTENSITY_FLOAT32_APPLE 0x8817 +#define GL_LUMINANCE_FLOAT32_APPLE 0x8818 +#define GL_LUMINANCE_ALPHA_FLOAT32_APPLE 0x8819 +#define GL_RGBA_FLOAT16_APPLE 0x881A +#define GL_RGB_FLOAT16_APPLE 0x881B +#define GL_ALPHA_FLOAT16_APPLE 0x881C +#define GL_INTENSITY_FLOAT16_APPLE 0x881D +#define GL_LUMINANCE_FLOAT16_APPLE 0x881E +#define GL_LUMINANCE_ALPHA_FLOAT16_APPLE 0x881F +#define GL_COLOR_FLOAT_APPLE 0x8A0F +#endif /* GL_APPLE_float_pixels */ + +#ifndef GL_APPLE_flush_buffer_range +#define GL_APPLE_flush_buffer_range 1 +#define GL_BUFFER_SERIALIZED_MODIFY_APPLE 0x8A12 +#define GL_BUFFER_FLUSHING_UNMAP_APPLE 0x8A13 +typedef void (APIENTRYP PFNGLBUFFERPARAMETERIAPPLEPROC) (GLenum target, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC) (GLenum target, GLintptr offset, GLsizeiptr size); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBufferParameteriAPPLE (GLenum target, GLenum pname, GLint param); +GLAPI void APIENTRY glFlushMappedBufferRangeAPPLE (GLenum target, GLintptr offset, GLsizeiptr size); +#endif +#endif /* GL_APPLE_flush_buffer_range */ + +#ifndef GL_APPLE_object_purgeable +#define GL_APPLE_object_purgeable 1 +#define GL_BUFFER_OBJECT_APPLE 0x85B3 +#define GL_RELEASED_APPLE 0x8A19 +#define GL_VOLATILE_APPLE 0x8A1A +#define GL_RETAINED_APPLE 0x8A1B +#define GL_UNDEFINED_APPLE 0x8A1C +#define GL_PURGEABLE_APPLE 0x8A1D +typedef GLenum (APIENTRYP PFNGLOBJECTPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option); +typedef GLenum (APIENTRYP PFNGLOBJECTUNPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option); +typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERIVAPPLEPROC) (GLenum objectType, GLuint name, GLenum pname, GLint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLenum APIENTRY glObjectPurgeableAPPLE (GLenum objectType, GLuint name, GLenum option); +GLAPI GLenum APIENTRY glObjectUnpurgeableAPPLE (GLenum objectType, GLuint name, GLenum option); +GLAPI void APIENTRY glGetObjectParameterivAPPLE (GLenum objectType, GLuint name, GLenum pname, GLint *params); +#endif +#endif /* GL_APPLE_object_purgeable */ + +#ifndef GL_APPLE_rgb_422 +#define GL_APPLE_rgb_422 1 +#define GL_RGB_422_APPLE 0x8A1F +#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB +#define GL_RGB_RAW_422_APPLE 0x8A51 +#endif /* GL_APPLE_rgb_422 */ + +#ifndef GL_APPLE_row_bytes +#define GL_APPLE_row_bytes 1 +#define GL_PACK_ROW_BYTES_APPLE 0x8A15 +#define GL_UNPACK_ROW_BYTES_APPLE 0x8A16 +#endif /* GL_APPLE_row_bytes */ + +#ifndef GL_APPLE_specular_vector +#define GL_APPLE_specular_vector 1 +#define GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0 +#endif /* GL_APPLE_specular_vector */ + +#ifndef GL_APPLE_texture_range +#define GL_APPLE_texture_range 1 +#define GL_TEXTURE_RANGE_LENGTH_APPLE 0x85B7 +#define GL_TEXTURE_RANGE_POINTER_APPLE 0x85B8 +#define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC +#define GL_STORAGE_PRIVATE_APPLE 0x85BD +#define GL_STORAGE_CACHED_APPLE 0x85BE +#define GL_STORAGE_SHARED_APPLE 0x85BF +typedef void (APIENTRYP PFNGLTEXTURERANGEAPPLEPROC) (GLenum target, GLsizei length, const void *pointer); +typedef void (APIENTRYP PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC) (GLenum target, GLenum pname, void **params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTextureRangeAPPLE (GLenum target, GLsizei length, const void *pointer); +GLAPI void APIENTRY glGetTexParameterPointervAPPLE (GLenum target, GLenum pname, void **params); +#endif +#endif /* GL_APPLE_texture_range */ + +#ifndef GL_APPLE_transform_hint +#define GL_APPLE_transform_hint 1 +#define GL_TRANSFORM_HINT_APPLE 0x85B1 +#endif /* GL_APPLE_transform_hint */ + +#ifndef GL_APPLE_vertex_array_object +#define GL_APPLE_vertex_array_object 1 +#define GL_VERTEX_ARRAY_BINDING_APPLE 0x85B5 +typedef void (APIENTRYP PFNGLBINDVERTEXARRAYAPPLEPROC) (GLuint array); +typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint *arrays); +typedef void (APIENTRYP PFNGLGENVERTEXARRAYSAPPLEPROC) (GLsizei n, GLuint *arrays); +typedef GLboolean (APIENTRYP PFNGLISVERTEXARRAYAPPLEPROC) (GLuint array); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBindVertexArrayAPPLE (GLuint array); +GLAPI void APIENTRY glDeleteVertexArraysAPPLE (GLsizei n, const GLuint *arrays); +GLAPI void APIENTRY glGenVertexArraysAPPLE (GLsizei n, GLuint *arrays); +GLAPI GLboolean APIENTRY glIsVertexArrayAPPLE (GLuint array); +#endif +#endif /* GL_APPLE_vertex_array_object */ + +#ifndef GL_APPLE_vertex_array_range +#define GL_APPLE_vertex_array_range 1 +#define GL_VERTEX_ARRAY_RANGE_APPLE 0x851D +#define GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE 0x851E +#define GL_VERTEX_ARRAY_STORAGE_HINT_APPLE 0x851F +#define GL_VERTEX_ARRAY_RANGE_POINTER_APPLE 0x8521 +#define GL_STORAGE_CLIENT_APPLE 0x85B4 +typedef void (APIENTRYP PFNGLVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, void *pointer); +typedef void (APIENTRYP PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, void *pointer); +typedef void (APIENTRYP PFNGLVERTEXARRAYPARAMETERIAPPLEPROC) (GLenum pname, GLint param); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexArrayRangeAPPLE (GLsizei length, void *pointer); +GLAPI void APIENTRY glFlushVertexArrayRangeAPPLE (GLsizei length, void *pointer); +GLAPI void APIENTRY glVertexArrayParameteriAPPLE (GLenum pname, GLint param); +#endif +#endif /* GL_APPLE_vertex_array_range */ + +#ifndef GL_APPLE_vertex_program_evaluators +#define GL_APPLE_vertex_program_evaluators 1 +#define GL_VERTEX_ATTRIB_MAP1_APPLE 0x8A00 +#define GL_VERTEX_ATTRIB_MAP2_APPLE 0x8A01 +#define GL_VERTEX_ATTRIB_MAP1_SIZE_APPLE 0x8A02 +#define GL_VERTEX_ATTRIB_MAP1_COEFF_APPLE 0x8A03 +#define GL_VERTEX_ATTRIB_MAP1_ORDER_APPLE 0x8A04 +#define GL_VERTEX_ATTRIB_MAP1_DOMAIN_APPLE 0x8A05 +#define GL_VERTEX_ATTRIB_MAP2_SIZE_APPLE 0x8A06 +#define GL_VERTEX_ATTRIB_MAP2_COEFF_APPLE 0x8A07 +#define GL_VERTEX_ATTRIB_MAP2_ORDER_APPLE 0x8A08 +#define GL_VERTEX_ATTRIB_MAP2_DOMAIN_APPLE 0x8A09 +typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname); +typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname); +typedef GLboolean (APIENTRYP PFNGLISVERTEXATTRIBENABLEDAPPLEPROC) (GLuint index, GLenum pname); +typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB1DAPPLEPROC) (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); +typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB1FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); +typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB2DAPPLEPROC) (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); +typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB2FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glEnableVertexAttribAPPLE (GLuint index, GLenum pname); +GLAPI void APIENTRY glDisableVertexAttribAPPLE (GLuint index, GLenum pname); +GLAPI GLboolean APIENTRY glIsVertexAttribEnabledAPPLE (GLuint index, GLenum pname); +GLAPI void APIENTRY glMapVertexAttrib1dAPPLE (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); +GLAPI void APIENTRY glMapVertexAttrib1fAPPLE (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); +GLAPI void APIENTRY glMapVertexAttrib2dAPPLE (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); +GLAPI void APIENTRY glMapVertexAttrib2fAPPLE (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); +#endif +#endif /* GL_APPLE_vertex_program_evaluators */ + +#ifndef GL_APPLE_ycbcr_422 +#define GL_APPLE_ycbcr_422 1 +#define GL_YCBCR_422_APPLE 0x85B9 +#endif /* GL_APPLE_ycbcr_422 */ + +#ifndef GL_ATI_draw_buffers +#define GL_ATI_draw_buffers 1 +#define GL_MAX_DRAW_BUFFERS_ATI 0x8824 +#define GL_DRAW_BUFFER0_ATI 0x8825 +#define GL_DRAW_BUFFER1_ATI 0x8826 +#define GL_DRAW_BUFFER2_ATI 0x8827 +#define GL_DRAW_BUFFER3_ATI 0x8828 +#define GL_DRAW_BUFFER4_ATI 0x8829 +#define GL_DRAW_BUFFER5_ATI 0x882A +#define GL_DRAW_BUFFER6_ATI 0x882B +#define GL_DRAW_BUFFER7_ATI 0x882C +#define GL_DRAW_BUFFER8_ATI 0x882D +#define GL_DRAW_BUFFER9_ATI 0x882E +#define GL_DRAW_BUFFER10_ATI 0x882F +#define GL_DRAW_BUFFER11_ATI 0x8830 +#define GL_DRAW_BUFFER12_ATI 0x8831 +#define GL_DRAW_BUFFER13_ATI 0x8832 +#define GL_DRAW_BUFFER14_ATI 0x8833 +#define GL_DRAW_BUFFER15_ATI 0x8834 +typedef void (APIENTRYP PFNGLDRAWBUFFERSATIPROC) (GLsizei n, const GLenum *bufs); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawBuffersATI (GLsizei n, const GLenum *bufs); +#endif +#endif /* GL_ATI_draw_buffers */ + +#ifndef GL_ATI_element_array +#define GL_ATI_element_array 1 +#define GL_ELEMENT_ARRAY_ATI 0x8768 +#define GL_ELEMENT_ARRAY_TYPE_ATI 0x8769 +#define GL_ELEMENT_ARRAY_POINTER_ATI 0x876A +typedef void (APIENTRYP PFNGLELEMENTPOINTERATIPROC) (GLenum type, const void *pointer); +typedef void (APIENTRYP PFNGLDRAWELEMENTARRAYATIPROC) (GLenum mode, GLsizei count); +typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTARRAYATIPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glElementPointerATI (GLenum type, const void *pointer); +GLAPI void APIENTRY glDrawElementArrayATI (GLenum mode, GLsizei count); +GLAPI void APIENTRY glDrawRangeElementArrayATI (GLenum mode, GLuint start, GLuint end, GLsizei count); +#endif +#endif /* GL_ATI_element_array */ + +#ifndef GL_ATI_envmap_bumpmap +#define GL_ATI_envmap_bumpmap 1 +#define GL_BUMP_ROT_MATRIX_ATI 0x8775 +#define GL_BUMP_ROT_MATRIX_SIZE_ATI 0x8776 +#define GL_BUMP_NUM_TEX_UNITS_ATI 0x8777 +#define GL_BUMP_TEX_UNITS_ATI 0x8778 +#define GL_DUDV_ATI 0x8779 +#define GL_DU8DV8_ATI 0x877A +#define GL_BUMP_ENVMAP_ATI 0x877B +#define GL_BUMP_TARGET_ATI 0x877C +typedef void (APIENTRYP PFNGLTEXBUMPPARAMETERIVATIPROC) (GLenum pname, const GLint *param); +typedef void (APIENTRYP PFNGLTEXBUMPPARAMETERFVATIPROC) (GLenum pname, const GLfloat *param); +typedef void (APIENTRYP PFNGLGETTEXBUMPPARAMETERIVATIPROC) (GLenum pname, GLint *param); +typedef void (APIENTRYP PFNGLGETTEXBUMPPARAMETERFVATIPROC) (GLenum pname, GLfloat *param); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexBumpParameterivATI (GLenum pname, const GLint *param); +GLAPI void APIENTRY glTexBumpParameterfvATI (GLenum pname, const GLfloat *param); +GLAPI void APIENTRY glGetTexBumpParameterivATI (GLenum pname, GLint *param); +GLAPI void APIENTRY glGetTexBumpParameterfvATI (GLenum pname, GLfloat *param); +#endif +#endif /* GL_ATI_envmap_bumpmap */ + +#ifndef GL_ATI_fragment_shader +#define GL_ATI_fragment_shader 1 +#define GL_FRAGMENT_SHADER_ATI 0x8920 +#define GL_REG_0_ATI 0x8921 +#define GL_REG_1_ATI 0x8922 +#define GL_REG_2_ATI 0x8923 +#define GL_REG_3_ATI 0x8924 +#define GL_REG_4_ATI 0x8925 +#define GL_REG_5_ATI 0x8926 +#define GL_REG_6_ATI 0x8927 +#define GL_REG_7_ATI 0x8928 +#define GL_REG_8_ATI 0x8929 +#define GL_REG_9_ATI 0x892A +#define GL_REG_10_ATI 0x892B +#define GL_REG_11_ATI 0x892C +#define GL_REG_12_ATI 0x892D +#define GL_REG_13_ATI 0x892E +#define GL_REG_14_ATI 0x892F +#define GL_REG_15_ATI 0x8930 +#define GL_REG_16_ATI 0x8931 +#define GL_REG_17_ATI 0x8932 +#define GL_REG_18_ATI 0x8933 +#define GL_REG_19_ATI 0x8934 +#define GL_REG_20_ATI 0x8935 +#define GL_REG_21_ATI 0x8936 +#define GL_REG_22_ATI 0x8937 +#define GL_REG_23_ATI 0x8938 +#define GL_REG_24_ATI 0x8939 +#define GL_REG_25_ATI 0x893A +#define GL_REG_26_ATI 0x893B +#define GL_REG_27_ATI 0x893C +#define GL_REG_28_ATI 0x893D +#define GL_REG_29_ATI 0x893E +#define GL_REG_30_ATI 0x893F +#define GL_REG_31_ATI 0x8940 +#define GL_CON_0_ATI 0x8941 +#define GL_CON_1_ATI 0x8942 +#define GL_CON_2_ATI 0x8943 +#define GL_CON_3_ATI 0x8944 +#define GL_CON_4_ATI 0x8945 +#define GL_CON_5_ATI 0x8946 +#define GL_CON_6_ATI 0x8947 +#define GL_CON_7_ATI 0x8948 +#define GL_CON_8_ATI 0x8949 +#define GL_CON_9_ATI 0x894A +#define GL_CON_10_ATI 0x894B +#define GL_CON_11_ATI 0x894C +#define GL_CON_12_ATI 0x894D +#define GL_CON_13_ATI 0x894E +#define GL_CON_14_ATI 0x894F +#define GL_CON_15_ATI 0x8950 +#define GL_CON_16_ATI 0x8951 +#define GL_CON_17_ATI 0x8952 +#define GL_CON_18_ATI 0x8953 +#define GL_CON_19_ATI 0x8954 +#define GL_CON_20_ATI 0x8955 +#define GL_CON_21_ATI 0x8956 +#define GL_CON_22_ATI 0x8957 +#define GL_CON_23_ATI 0x8958 +#define GL_CON_24_ATI 0x8959 +#define GL_CON_25_ATI 0x895A +#define GL_CON_26_ATI 0x895B +#define GL_CON_27_ATI 0x895C +#define GL_CON_28_ATI 0x895D +#define GL_CON_29_ATI 0x895E +#define GL_CON_30_ATI 0x895F +#define GL_CON_31_ATI 0x8960 +#define GL_MOV_ATI 0x8961 +#define GL_ADD_ATI 0x8963 +#define GL_MUL_ATI 0x8964 +#define GL_SUB_ATI 0x8965 +#define GL_DOT3_ATI 0x8966 +#define GL_DOT4_ATI 0x8967 +#define GL_MAD_ATI 0x8968 +#define GL_LERP_ATI 0x8969 +#define GL_CND_ATI 0x896A +#define GL_CND0_ATI 0x896B +#define GL_DOT2_ADD_ATI 0x896C +#define GL_SECONDARY_INTERPOLATOR_ATI 0x896D +#define GL_NUM_FRAGMENT_REGISTERS_ATI 0x896E +#define GL_NUM_FRAGMENT_CONSTANTS_ATI 0x896F +#define GL_NUM_PASSES_ATI 0x8970 +#define GL_NUM_INSTRUCTIONS_PER_PASS_ATI 0x8971 +#define GL_NUM_INSTRUCTIONS_TOTAL_ATI 0x8972 +#define GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI 0x8973 +#define GL_NUM_LOOPBACK_COMPONENTS_ATI 0x8974 +#define GL_COLOR_ALPHA_PAIRING_ATI 0x8975 +#define GL_SWIZZLE_STR_ATI 0x8976 +#define GL_SWIZZLE_STQ_ATI 0x8977 +#define GL_SWIZZLE_STR_DR_ATI 0x8978 +#define GL_SWIZZLE_STQ_DQ_ATI 0x8979 +#define GL_SWIZZLE_STRQ_ATI 0x897A +#define GL_SWIZZLE_STRQ_DQ_ATI 0x897B +#define GL_RED_BIT_ATI 0x00000001 +#define GL_GREEN_BIT_ATI 0x00000002 +#define GL_BLUE_BIT_ATI 0x00000004 +#define GL_2X_BIT_ATI 0x00000001 +#define GL_4X_BIT_ATI 0x00000002 +#define GL_8X_BIT_ATI 0x00000004 +#define GL_HALF_BIT_ATI 0x00000008 +#define GL_QUARTER_BIT_ATI 0x00000010 +#define GL_EIGHTH_BIT_ATI 0x00000020 +#define GL_SATURATE_BIT_ATI 0x00000040 +#define GL_COMP_BIT_ATI 0x00000002 +#define GL_NEGATE_BIT_ATI 0x00000004 +#define GL_BIAS_BIT_ATI 0x00000008 +typedef GLuint (APIENTRYP PFNGLGENFRAGMENTSHADERSATIPROC) (GLuint range); +typedef void (APIENTRYP PFNGLBINDFRAGMENTSHADERATIPROC) (GLuint id); +typedef void (APIENTRYP PFNGLDELETEFRAGMENTSHADERATIPROC) (GLuint id); +typedef void (APIENTRYP PFNGLBEGINFRAGMENTSHADERATIPROC) (void); +typedef void (APIENTRYP PFNGLENDFRAGMENTSHADERATIPROC) (void); +typedef void (APIENTRYP PFNGLPASSTEXCOORDATIPROC) (GLuint dst, GLuint coord, GLenum swizzle); +typedef void (APIENTRYP PFNGLSAMPLEMAPATIPROC) (GLuint dst, GLuint interp, GLenum swizzle); +typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); +typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); +typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); +typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); +typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); +typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); +typedef void (APIENTRYP PFNGLSETFRAGMENTSHADERCONSTANTATIPROC) (GLuint dst, const GLfloat *value); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLuint APIENTRY glGenFragmentShadersATI (GLuint range); +GLAPI void APIENTRY glBindFragmentShaderATI (GLuint id); +GLAPI void APIENTRY glDeleteFragmentShaderATI (GLuint id); +GLAPI void APIENTRY glBeginFragmentShaderATI (void); +GLAPI void APIENTRY glEndFragmentShaderATI (void); +GLAPI void APIENTRY glPassTexCoordATI (GLuint dst, GLuint coord, GLenum swizzle); +GLAPI void APIENTRY glSampleMapATI (GLuint dst, GLuint interp, GLenum swizzle); +GLAPI void APIENTRY glColorFragmentOp1ATI (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); +GLAPI void APIENTRY glColorFragmentOp2ATI (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); +GLAPI void APIENTRY glColorFragmentOp3ATI (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); +GLAPI void APIENTRY glAlphaFragmentOp1ATI (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); +GLAPI void APIENTRY glAlphaFragmentOp2ATI (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); +GLAPI void APIENTRY glAlphaFragmentOp3ATI (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); +GLAPI void APIENTRY glSetFragmentShaderConstantATI (GLuint dst, const GLfloat *value); +#endif +#endif /* GL_ATI_fragment_shader */ + +#ifndef GL_ATI_map_object_buffer +#define GL_ATI_map_object_buffer 1 +typedef void *(APIENTRYP PFNGLMAPOBJECTBUFFERATIPROC) (GLuint buffer); +typedef void (APIENTRYP PFNGLUNMAPOBJECTBUFFERATIPROC) (GLuint buffer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void *APIENTRY glMapObjectBufferATI (GLuint buffer); +GLAPI void APIENTRY glUnmapObjectBufferATI (GLuint buffer); +#endif +#endif /* GL_ATI_map_object_buffer */ + +#ifndef GL_ATI_meminfo +#define GL_ATI_meminfo 1 +#define GL_VBO_FREE_MEMORY_ATI 0x87FB +#define GL_TEXTURE_FREE_MEMORY_ATI 0x87FC +#define GL_RENDERBUFFER_FREE_MEMORY_ATI 0x87FD +#endif /* GL_ATI_meminfo */ + +#ifndef GL_ATI_pixel_format_float +#define GL_ATI_pixel_format_float 1 +#define GL_RGBA_FLOAT_MODE_ATI 0x8820 +#define GL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI 0x8835 +#endif /* GL_ATI_pixel_format_float */ + +#ifndef GL_ATI_pn_triangles +#define GL_ATI_pn_triangles 1 +#define GL_PN_TRIANGLES_ATI 0x87F0 +#define GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F1 +#define GL_PN_TRIANGLES_POINT_MODE_ATI 0x87F2 +#define GL_PN_TRIANGLES_NORMAL_MODE_ATI 0x87F3 +#define GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F4 +#define GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI 0x87F5 +#define GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI 0x87F6 +#define GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7 +#define GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8 +typedef void (APIENTRYP PFNGLPNTRIANGLESIATIPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLPNTRIANGLESFATIPROC) (GLenum pname, GLfloat param); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPNTrianglesiATI (GLenum pname, GLint param); +GLAPI void APIENTRY glPNTrianglesfATI (GLenum pname, GLfloat param); +#endif +#endif /* GL_ATI_pn_triangles */ + +#ifndef GL_ATI_separate_stencil +#define GL_ATI_separate_stencil 1 +#define GL_STENCIL_BACK_FUNC_ATI 0x8800 +#define GL_STENCIL_BACK_FAIL_ATI 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI 0x8803 +typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEATIPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEATIPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glStencilOpSeparateATI (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +GLAPI void APIENTRY glStencilFuncSeparateATI (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); +#endif +#endif /* GL_ATI_separate_stencil */ + +#ifndef GL_ATI_text_fragment_shader +#define GL_ATI_text_fragment_shader 1 +#define GL_TEXT_FRAGMENT_SHADER_ATI 0x8200 +#endif /* GL_ATI_text_fragment_shader */ + +#ifndef GL_ATI_texture_env_combine3 +#define GL_ATI_texture_env_combine3 1 +#define GL_MODULATE_ADD_ATI 0x8744 +#define GL_MODULATE_SIGNED_ADD_ATI 0x8745 +#define GL_MODULATE_SUBTRACT_ATI 0x8746 +#endif /* GL_ATI_texture_env_combine3 */ + +#ifndef GL_ATI_texture_float +#define GL_ATI_texture_float 1 +#define GL_RGBA_FLOAT32_ATI 0x8814 +#define GL_RGB_FLOAT32_ATI 0x8815 +#define GL_ALPHA_FLOAT32_ATI 0x8816 +#define GL_INTENSITY_FLOAT32_ATI 0x8817 +#define GL_LUMINANCE_FLOAT32_ATI 0x8818 +#define GL_LUMINANCE_ALPHA_FLOAT32_ATI 0x8819 +#define GL_RGBA_FLOAT16_ATI 0x881A +#define GL_RGB_FLOAT16_ATI 0x881B +#define GL_ALPHA_FLOAT16_ATI 0x881C +#define GL_INTENSITY_FLOAT16_ATI 0x881D +#define GL_LUMINANCE_FLOAT16_ATI 0x881E +#define GL_LUMINANCE_ALPHA_FLOAT16_ATI 0x881F +#endif /* GL_ATI_texture_float */ + +#ifndef GL_ATI_texture_mirror_once +#define GL_ATI_texture_mirror_once 1 +#define GL_MIRROR_CLAMP_ATI 0x8742 +#define GL_MIRROR_CLAMP_TO_EDGE_ATI 0x8743 +#endif /* GL_ATI_texture_mirror_once */ + +#ifndef GL_ATI_vertex_array_object +#define GL_ATI_vertex_array_object 1 +#define GL_STATIC_ATI 0x8760 +#define GL_DYNAMIC_ATI 0x8761 +#define GL_PRESERVE_ATI 0x8762 +#define GL_DISCARD_ATI 0x8763 +#define GL_OBJECT_BUFFER_SIZE_ATI 0x8764 +#define GL_OBJECT_BUFFER_USAGE_ATI 0x8765 +#define GL_ARRAY_OBJECT_BUFFER_ATI 0x8766 +#define GL_ARRAY_OBJECT_OFFSET_ATI 0x8767 +typedef GLuint (APIENTRYP PFNGLNEWOBJECTBUFFERATIPROC) (GLsizei size, const void *pointer, GLenum usage); +typedef GLboolean (APIENTRYP PFNGLISOBJECTBUFFERATIPROC) (GLuint buffer); +typedef void (APIENTRYP PFNGLUPDATEOBJECTBUFFERATIPROC) (GLuint buffer, GLuint offset, GLsizei size, const void *pointer, GLenum preserve); +typedef void (APIENTRYP PFNGLGETOBJECTBUFFERFVATIPROC) (GLuint buffer, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETOBJECTBUFFERIVATIPROC) (GLuint buffer, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLFREEOBJECTBUFFERATIPROC) (GLuint buffer); +typedef void (APIENTRYP PFNGLARRAYOBJECTATIPROC) (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); +typedef void (APIENTRYP PFNGLGETARRAYOBJECTFVATIPROC) (GLenum array, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETARRAYOBJECTIVATIPROC) (GLenum array, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLVARIANTARRAYOBJECTATIPROC) (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); +typedef void (APIENTRYP PFNGLGETVARIANTARRAYOBJECTFVATIPROC) (GLuint id, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETVARIANTARRAYOBJECTIVATIPROC) (GLuint id, GLenum pname, GLint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLuint APIENTRY glNewObjectBufferATI (GLsizei size, const void *pointer, GLenum usage); +GLAPI GLboolean APIENTRY glIsObjectBufferATI (GLuint buffer); +GLAPI void APIENTRY glUpdateObjectBufferATI (GLuint buffer, GLuint offset, GLsizei size, const void *pointer, GLenum preserve); +GLAPI void APIENTRY glGetObjectBufferfvATI (GLuint buffer, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetObjectBufferivATI (GLuint buffer, GLenum pname, GLint *params); +GLAPI void APIENTRY glFreeObjectBufferATI (GLuint buffer); +GLAPI void APIENTRY glArrayObjectATI (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); +GLAPI void APIENTRY glGetArrayObjectfvATI (GLenum array, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetArrayObjectivATI (GLenum array, GLenum pname, GLint *params); +GLAPI void APIENTRY glVariantArrayObjectATI (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); +GLAPI void APIENTRY glGetVariantArrayObjectfvATI (GLuint id, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetVariantArrayObjectivATI (GLuint id, GLenum pname, GLint *params); +#endif +#endif /* GL_ATI_vertex_array_object */ + +#ifndef GL_ATI_vertex_attrib_array_object +#define GL_ATI_vertex_attrib_array_object 1 +typedef void (APIENTRYP PFNGLVERTEXATTRIBARRAYOBJECTATIPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC) (GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC) (GLuint index, GLenum pname, GLint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexAttribArrayObjectATI (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset); +GLAPI void APIENTRY glGetVertexAttribArrayObjectfvATI (GLuint index, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetVertexAttribArrayObjectivATI (GLuint index, GLenum pname, GLint *params); +#endif +#endif /* GL_ATI_vertex_attrib_array_object */ + +#ifndef GL_ATI_vertex_streams +#define GL_ATI_vertex_streams 1 +#define GL_MAX_VERTEX_STREAMS_ATI 0x876B +#define GL_VERTEX_STREAM0_ATI 0x876C +#define GL_VERTEX_STREAM1_ATI 0x876D +#define GL_VERTEX_STREAM2_ATI 0x876E +#define GL_VERTEX_STREAM3_ATI 0x876F +#define GL_VERTEX_STREAM4_ATI 0x8770 +#define GL_VERTEX_STREAM5_ATI 0x8771 +#define GL_VERTEX_STREAM6_ATI 0x8772 +#define GL_VERTEX_STREAM7_ATI 0x8773 +#define GL_VERTEX_SOURCE_ATI 0x8774 +typedef void (APIENTRYP PFNGLVERTEXSTREAM1SATIPROC) (GLenum stream, GLshort x); +typedef void (APIENTRYP PFNGLVERTEXSTREAM1SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM1IATIPROC) (GLenum stream, GLint x); +typedef void (APIENTRYP PFNGLVERTEXSTREAM1IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM1FATIPROC) (GLenum stream, GLfloat x); +typedef void (APIENTRYP PFNGLVERTEXSTREAM1FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM1DATIPROC) (GLenum stream, GLdouble x); +typedef void (APIENTRYP PFNGLVERTEXSTREAM1DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2SATIPROC) (GLenum stream, GLshort x, GLshort y); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2IATIPROC) (GLenum stream, GLint x, GLint y); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2FATIPROC) (GLenum stream, GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2DATIPROC) (GLenum stream, GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3IATIPROC) (GLenum stream, GLint x, GLint y, GLint z); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4IATIPROC) (GLenum stream, GLint x, GLint y, GLint z, GLint w); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (APIENTRYP PFNGLNORMALSTREAM3BATIPROC) (GLenum stream, GLbyte nx, GLbyte ny, GLbyte nz); +typedef void (APIENTRYP PFNGLNORMALSTREAM3BVATIPROC) (GLenum stream, const GLbyte *coords); +typedef void (APIENTRYP PFNGLNORMALSTREAM3SATIPROC) (GLenum stream, GLshort nx, GLshort ny, GLshort nz); +typedef void (APIENTRYP PFNGLNORMALSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (APIENTRYP PFNGLNORMALSTREAM3IATIPROC) (GLenum stream, GLint nx, GLint ny, GLint nz); +typedef void (APIENTRYP PFNGLNORMALSTREAM3IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (APIENTRYP PFNGLNORMALSTREAM3FATIPROC) (GLenum stream, GLfloat nx, GLfloat ny, GLfloat nz); +typedef void (APIENTRYP PFNGLNORMALSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (APIENTRYP PFNGLNORMALSTREAM3DATIPROC) (GLenum stream, GLdouble nx, GLdouble ny, GLdouble nz); +typedef void (APIENTRYP PFNGLNORMALSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (APIENTRYP PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC) (GLenum stream); +typedef void (APIENTRYP PFNGLVERTEXBLENDENVIATIPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLVERTEXBLENDENVFATIPROC) (GLenum pname, GLfloat param); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexStream1sATI (GLenum stream, GLshort x); +GLAPI void APIENTRY glVertexStream1svATI (GLenum stream, const GLshort *coords); +GLAPI void APIENTRY glVertexStream1iATI (GLenum stream, GLint x); +GLAPI void APIENTRY glVertexStream1ivATI (GLenum stream, const GLint *coords); +GLAPI void APIENTRY glVertexStream1fATI (GLenum stream, GLfloat x); +GLAPI void APIENTRY glVertexStream1fvATI (GLenum stream, const GLfloat *coords); +GLAPI void APIENTRY glVertexStream1dATI (GLenum stream, GLdouble x); +GLAPI void APIENTRY glVertexStream1dvATI (GLenum stream, const GLdouble *coords); +GLAPI void APIENTRY glVertexStream2sATI (GLenum stream, GLshort x, GLshort y); +GLAPI void APIENTRY glVertexStream2svATI (GLenum stream, const GLshort *coords); +GLAPI void APIENTRY glVertexStream2iATI (GLenum stream, GLint x, GLint y); +GLAPI void APIENTRY glVertexStream2ivATI (GLenum stream, const GLint *coords); +GLAPI void APIENTRY glVertexStream2fATI (GLenum stream, GLfloat x, GLfloat y); +GLAPI void APIENTRY glVertexStream2fvATI (GLenum stream, const GLfloat *coords); +GLAPI void APIENTRY glVertexStream2dATI (GLenum stream, GLdouble x, GLdouble y); +GLAPI void APIENTRY glVertexStream2dvATI (GLenum stream, const GLdouble *coords); +GLAPI void APIENTRY glVertexStream3sATI (GLenum stream, GLshort x, GLshort y, GLshort z); +GLAPI void APIENTRY glVertexStream3svATI (GLenum stream, const GLshort *coords); +GLAPI void APIENTRY glVertexStream3iATI (GLenum stream, GLint x, GLint y, GLint z); +GLAPI void APIENTRY glVertexStream3ivATI (GLenum stream, const GLint *coords); +GLAPI void APIENTRY glVertexStream3fATI (GLenum stream, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glVertexStream3fvATI (GLenum stream, const GLfloat *coords); +GLAPI void APIENTRY glVertexStream3dATI (GLenum stream, GLdouble x, GLdouble y, GLdouble z); +GLAPI void APIENTRY glVertexStream3dvATI (GLenum stream, const GLdouble *coords); +GLAPI void APIENTRY glVertexStream4sATI (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w); +GLAPI void APIENTRY glVertexStream4svATI (GLenum stream, const GLshort *coords); +GLAPI void APIENTRY glVertexStream4iATI (GLenum stream, GLint x, GLint y, GLint z, GLint w); +GLAPI void APIENTRY glVertexStream4ivATI (GLenum stream, const GLint *coords); +GLAPI void APIENTRY glVertexStream4fATI (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void APIENTRY glVertexStream4fvATI (GLenum stream, const GLfloat *coords); +GLAPI void APIENTRY glVertexStream4dATI (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void APIENTRY glVertexStream4dvATI (GLenum stream, const GLdouble *coords); +GLAPI void APIENTRY glNormalStream3bATI (GLenum stream, GLbyte nx, GLbyte ny, GLbyte nz); +GLAPI void APIENTRY glNormalStream3bvATI (GLenum stream, const GLbyte *coords); +GLAPI void APIENTRY glNormalStream3sATI (GLenum stream, GLshort nx, GLshort ny, GLshort nz); +GLAPI void APIENTRY glNormalStream3svATI (GLenum stream, const GLshort *coords); +GLAPI void APIENTRY glNormalStream3iATI (GLenum stream, GLint nx, GLint ny, GLint nz); +GLAPI void APIENTRY glNormalStream3ivATI (GLenum stream, const GLint *coords); +GLAPI void APIENTRY glNormalStream3fATI (GLenum stream, GLfloat nx, GLfloat ny, GLfloat nz); +GLAPI void APIENTRY glNormalStream3fvATI (GLenum stream, const GLfloat *coords); +GLAPI void APIENTRY glNormalStream3dATI (GLenum stream, GLdouble nx, GLdouble ny, GLdouble nz); +GLAPI void APIENTRY glNormalStream3dvATI (GLenum stream, const GLdouble *coords); +GLAPI void APIENTRY glClientActiveVertexStreamATI (GLenum stream); +GLAPI void APIENTRY glVertexBlendEnviATI (GLenum pname, GLint param); +GLAPI void APIENTRY glVertexBlendEnvfATI (GLenum pname, GLfloat param); +#endif +#endif /* GL_ATI_vertex_streams */ + +#ifndef GL_EXT_422_pixels +#define GL_EXT_422_pixels 1 +#define GL_422_EXT 0x80CC +#define GL_422_REV_EXT 0x80CD +#define GL_422_AVERAGE_EXT 0x80CE +#define GL_422_REV_AVERAGE_EXT 0x80CF +#endif /* GL_EXT_422_pixels */ + +#ifndef GL_EXT_abgr +#define GL_EXT_abgr 1 +#define GL_ABGR_EXT 0x8000 +#endif /* GL_EXT_abgr */ + +#ifndef GL_EXT_bgra +#define GL_EXT_bgra 1 +#define GL_BGR_EXT 0x80E0 +#define GL_BGRA_EXT 0x80E1 +#endif /* GL_EXT_bgra */ + +#ifndef GL_EXT_bindable_uniform +#define GL_EXT_bindable_uniform 1 +#define GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT 0x8DE2 +#define GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT 0x8DE3 +#define GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT 0x8DE4 +#define GL_MAX_BINDABLE_UNIFORM_SIZE_EXT 0x8DED +#define GL_UNIFORM_BUFFER_EXT 0x8DEE +#define GL_UNIFORM_BUFFER_BINDING_EXT 0x8DEF +typedef void (APIENTRYP PFNGLUNIFORMBUFFEREXTPROC) (GLuint program, GLint location, GLuint buffer); +typedef GLint (APIENTRYP PFNGLGETUNIFORMBUFFERSIZEEXTPROC) (GLuint program, GLint location); +typedef GLintptr (APIENTRYP PFNGLGETUNIFORMOFFSETEXTPROC) (GLuint program, GLint location); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glUniformBufferEXT (GLuint program, GLint location, GLuint buffer); +GLAPI GLint APIENTRY glGetUniformBufferSizeEXT (GLuint program, GLint location); +GLAPI GLintptr APIENTRY glGetUniformOffsetEXT (GLuint program, GLint location); +#endif +#endif /* GL_EXT_bindable_uniform */ + +#ifndef GL_EXT_blend_color +#define GL_EXT_blend_color 1 +#define GL_CONSTANT_COLOR_EXT 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR_EXT 0x8002 +#define GL_CONSTANT_ALPHA_EXT 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA_EXT 0x8004 +#define GL_BLEND_COLOR_EXT 0x8005 +typedef void (APIENTRYP PFNGLBLENDCOLOREXTPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendColorEXT (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +#endif +#endif /* GL_EXT_blend_color */ + +#ifndef GL_EXT_blend_equation_separate +#define GL_EXT_blend_equation_separate 1 +#define GL_BLEND_EQUATION_RGB_EXT 0x8009 +#define GL_BLEND_EQUATION_ALPHA_EXT 0x883D +typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEEXTPROC) (GLenum modeRGB, GLenum modeAlpha); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendEquationSeparateEXT (GLenum modeRGB, GLenum modeAlpha); +#endif +#endif /* GL_EXT_blend_equation_separate */ + +#ifndef GL_EXT_blend_func_separate +#define GL_EXT_blend_func_separate 1 +#define GL_BLEND_DST_RGB_EXT 0x80C8 +#define GL_BLEND_SRC_RGB_EXT 0x80C9 +#define GL_BLEND_DST_ALPHA_EXT 0x80CA +#define GL_BLEND_SRC_ALPHA_EXT 0x80CB +typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEEXTPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendFuncSeparateEXT (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +#endif +#endif /* GL_EXT_blend_func_separate */ + +#ifndef GL_EXT_blend_logic_op +#define GL_EXT_blend_logic_op 1 +#endif /* GL_EXT_blend_logic_op */ + +#ifndef GL_EXT_blend_minmax +#define GL_EXT_blend_minmax 1 +#define GL_MIN_EXT 0x8007 +#define GL_MAX_EXT 0x8008 +#define GL_FUNC_ADD_EXT 0x8006 +#define GL_BLEND_EQUATION_EXT 0x8009 +typedef void (APIENTRYP PFNGLBLENDEQUATIONEXTPROC) (GLenum mode); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendEquationEXT (GLenum mode); +#endif +#endif /* GL_EXT_blend_minmax */ + +#ifndef GL_EXT_blend_subtract +#define GL_EXT_blend_subtract 1 +#define GL_FUNC_SUBTRACT_EXT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT_EXT 0x800B +#endif /* GL_EXT_blend_subtract */ + +#ifndef GL_EXT_clip_volume_hint +#define GL_EXT_clip_volume_hint 1 +#define GL_CLIP_VOLUME_CLIPPING_HINT_EXT 0x80F0 +#endif /* GL_EXT_clip_volume_hint */ + +#ifndef GL_EXT_cmyka +#define GL_EXT_cmyka 1 +#define GL_CMYK_EXT 0x800C +#define GL_CMYKA_EXT 0x800D +#define GL_PACK_CMYK_HINT_EXT 0x800E +#define GL_UNPACK_CMYK_HINT_EXT 0x800F +#endif /* GL_EXT_cmyka */ + +#ifndef GL_EXT_color_subtable +#define GL_EXT_color_subtable 1 +typedef void (APIENTRYP PFNGLCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const void *data); +typedef void (APIENTRYP PFNGLCOPYCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glColorSubTableEXT (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const void *data); +GLAPI void APIENTRY glCopyColorSubTableEXT (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); +#endif +#endif /* GL_EXT_color_subtable */ + +#ifndef GL_EXT_compiled_vertex_array +#define GL_EXT_compiled_vertex_array 1 +#define GL_ARRAY_ELEMENT_LOCK_FIRST_EXT 0x81A8 +#define GL_ARRAY_ELEMENT_LOCK_COUNT_EXT 0x81A9 +typedef void (APIENTRYP PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count); +typedef void (APIENTRYP PFNGLUNLOCKARRAYSEXTPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glLockArraysEXT (GLint first, GLsizei count); +GLAPI void APIENTRY glUnlockArraysEXT (void); +#endif +#endif /* GL_EXT_compiled_vertex_array */ + +#ifndef GL_EXT_convolution +#define GL_EXT_convolution 1 +#define GL_CONVOLUTION_1D_EXT 0x8010 +#define GL_CONVOLUTION_2D_EXT 0x8011 +#define GL_SEPARABLE_2D_EXT 0x8012 +#define GL_CONVOLUTION_BORDER_MODE_EXT 0x8013 +#define GL_CONVOLUTION_FILTER_SCALE_EXT 0x8014 +#define GL_CONVOLUTION_FILTER_BIAS_EXT 0x8015 +#define GL_REDUCE_EXT 0x8016 +#define GL_CONVOLUTION_FORMAT_EXT 0x8017 +#define GL_CONVOLUTION_WIDTH_EXT 0x8018 +#define GL_CONVOLUTION_HEIGHT_EXT 0x8019 +#define GL_MAX_CONVOLUTION_WIDTH_EXT 0x801A +#define GL_MAX_CONVOLUTION_HEIGHT_EXT 0x801B +#define GL_POST_CONVOLUTION_RED_SCALE_EXT 0x801C +#define GL_POST_CONVOLUTION_GREEN_SCALE_EXT 0x801D +#define GL_POST_CONVOLUTION_BLUE_SCALE_EXT 0x801E +#define GL_POST_CONVOLUTION_ALPHA_SCALE_EXT 0x801F +#define GL_POST_CONVOLUTION_RED_BIAS_EXT 0x8020 +#define GL_POST_CONVOLUTION_GREEN_BIAS_EXT 0x8021 +#define GL_POST_CONVOLUTION_BLUE_BIAS_EXT 0x8022 +#define GL_POST_CONVOLUTION_ALPHA_BIAS_EXT 0x8023 +typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *image); +typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *image); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat params); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint params); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLGETCONVOLUTIONFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, void *image); +typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETSEPARABLEFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, void *row, void *column, void *span); +typedef void (APIENTRYP PFNGLSEPARABLEFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *row, const void *column); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glConvolutionFilter1DEXT (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *image); +GLAPI void APIENTRY glConvolutionFilter2DEXT (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *image); +GLAPI void APIENTRY glConvolutionParameterfEXT (GLenum target, GLenum pname, GLfloat params); +GLAPI void APIENTRY glConvolutionParameterfvEXT (GLenum target, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glConvolutionParameteriEXT (GLenum target, GLenum pname, GLint params); +GLAPI void APIENTRY glConvolutionParameterivEXT (GLenum target, GLenum pname, const GLint *params); +GLAPI void APIENTRY glCopyConvolutionFilter1DEXT (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +GLAPI void APIENTRY glCopyConvolutionFilter2DEXT (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void APIENTRY glGetConvolutionFilterEXT (GLenum target, GLenum format, GLenum type, void *image); +GLAPI void APIENTRY glGetConvolutionParameterfvEXT (GLenum target, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetConvolutionParameterivEXT (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetSeparableFilterEXT (GLenum target, GLenum format, GLenum type, void *row, void *column, void *span); +GLAPI void APIENTRY glSeparableFilter2DEXT (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *row, const void *column); +#endif +#endif /* GL_EXT_convolution */ + +#ifndef GL_EXT_coordinate_frame +#define GL_EXT_coordinate_frame 1 +#define GL_TANGENT_ARRAY_EXT 0x8439 +#define GL_BINORMAL_ARRAY_EXT 0x843A +#define GL_CURRENT_TANGENT_EXT 0x843B +#define GL_CURRENT_BINORMAL_EXT 0x843C +#define GL_TANGENT_ARRAY_TYPE_EXT 0x843E +#define GL_TANGENT_ARRAY_STRIDE_EXT 0x843F +#define GL_BINORMAL_ARRAY_TYPE_EXT 0x8440 +#define GL_BINORMAL_ARRAY_STRIDE_EXT 0x8441 +#define GL_TANGENT_ARRAY_POINTER_EXT 0x8442 +#define GL_BINORMAL_ARRAY_POINTER_EXT 0x8443 +#define GL_MAP1_TANGENT_EXT 0x8444 +#define GL_MAP2_TANGENT_EXT 0x8445 +#define GL_MAP1_BINORMAL_EXT 0x8446 +#define GL_MAP2_BINORMAL_EXT 0x8447 +typedef void (APIENTRYP PFNGLTANGENT3BEXTPROC) (GLbyte tx, GLbyte ty, GLbyte tz); +typedef void (APIENTRYP PFNGLTANGENT3BVEXTPROC) (const GLbyte *v); +typedef void (APIENTRYP PFNGLTANGENT3DEXTPROC) (GLdouble tx, GLdouble ty, GLdouble tz); +typedef void (APIENTRYP PFNGLTANGENT3DVEXTPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLTANGENT3FEXTPROC) (GLfloat tx, GLfloat ty, GLfloat tz); +typedef void (APIENTRYP PFNGLTANGENT3FVEXTPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLTANGENT3IEXTPROC) (GLint tx, GLint ty, GLint tz); +typedef void (APIENTRYP PFNGLTANGENT3IVEXTPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLTANGENT3SEXTPROC) (GLshort tx, GLshort ty, GLshort tz); +typedef void (APIENTRYP PFNGLTANGENT3SVEXTPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLBINORMAL3BEXTPROC) (GLbyte bx, GLbyte by, GLbyte bz); +typedef void (APIENTRYP PFNGLBINORMAL3BVEXTPROC) (const GLbyte *v); +typedef void (APIENTRYP PFNGLBINORMAL3DEXTPROC) (GLdouble bx, GLdouble by, GLdouble bz); +typedef void (APIENTRYP PFNGLBINORMAL3DVEXTPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLBINORMAL3FEXTPROC) (GLfloat bx, GLfloat by, GLfloat bz); +typedef void (APIENTRYP PFNGLBINORMAL3FVEXTPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLBINORMAL3IEXTPROC) (GLint bx, GLint by, GLint bz); +typedef void (APIENTRYP PFNGLBINORMAL3IVEXTPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLBINORMAL3SEXTPROC) (GLshort bx, GLshort by, GLshort bz); +typedef void (APIENTRYP PFNGLBINORMAL3SVEXTPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLTANGENTPOINTEREXTPROC) (GLenum type, GLsizei stride, const void *pointer); +typedef void (APIENTRYP PFNGLBINORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, const void *pointer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTangent3bEXT (GLbyte tx, GLbyte ty, GLbyte tz); +GLAPI void APIENTRY glTangent3bvEXT (const GLbyte *v); +GLAPI void APIENTRY glTangent3dEXT (GLdouble tx, GLdouble ty, GLdouble tz); +GLAPI void APIENTRY glTangent3dvEXT (const GLdouble *v); +GLAPI void APIENTRY glTangent3fEXT (GLfloat tx, GLfloat ty, GLfloat tz); +GLAPI void APIENTRY glTangent3fvEXT (const GLfloat *v); +GLAPI void APIENTRY glTangent3iEXT (GLint tx, GLint ty, GLint tz); +GLAPI void APIENTRY glTangent3ivEXT (const GLint *v); +GLAPI void APIENTRY glTangent3sEXT (GLshort tx, GLshort ty, GLshort tz); +GLAPI void APIENTRY glTangent3svEXT (const GLshort *v); +GLAPI void APIENTRY glBinormal3bEXT (GLbyte bx, GLbyte by, GLbyte bz); +GLAPI void APIENTRY glBinormal3bvEXT (const GLbyte *v); +GLAPI void APIENTRY glBinormal3dEXT (GLdouble bx, GLdouble by, GLdouble bz); +GLAPI void APIENTRY glBinormal3dvEXT (const GLdouble *v); +GLAPI void APIENTRY glBinormal3fEXT (GLfloat bx, GLfloat by, GLfloat bz); +GLAPI void APIENTRY glBinormal3fvEXT (const GLfloat *v); +GLAPI void APIENTRY glBinormal3iEXT (GLint bx, GLint by, GLint bz); +GLAPI void APIENTRY glBinormal3ivEXT (const GLint *v); +GLAPI void APIENTRY glBinormal3sEXT (GLshort bx, GLshort by, GLshort bz); +GLAPI void APIENTRY glBinormal3svEXT (const GLshort *v); +GLAPI void APIENTRY glTangentPointerEXT (GLenum type, GLsizei stride, const void *pointer); +GLAPI void APIENTRY glBinormalPointerEXT (GLenum type, GLsizei stride, const void *pointer); +#endif +#endif /* GL_EXT_coordinate_frame */ + +#ifndef GL_EXT_copy_texture +#define GL_EXT_copy_texture 1 +typedef void (APIENTRYP PFNGLCOPYTEXIMAGE1DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +typedef void (APIENTRYP PFNGLCOPYTEXIMAGE2DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glCopyTexImage1DEXT (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +GLAPI void APIENTRY glCopyTexImage2DEXT (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +GLAPI void APIENTRY glCopyTexSubImage1DEXT (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +GLAPI void APIENTRY glCopyTexSubImage2DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void APIENTRY glCopyTexSubImage3DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +#endif +#endif /* GL_EXT_copy_texture */ + +#ifndef GL_EXT_cull_vertex +#define GL_EXT_cull_vertex 1 +#define GL_CULL_VERTEX_EXT 0x81AA +#define GL_CULL_VERTEX_EYE_POSITION_EXT 0x81AB +#define GL_CULL_VERTEX_OBJECT_POSITION_EXT 0x81AC +typedef void (APIENTRYP PFNGLCULLPARAMETERDVEXTPROC) (GLenum pname, GLdouble *params); +typedef void (APIENTRYP PFNGLCULLPARAMETERFVEXTPROC) (GLenum pname, GLfloat *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glCullParameterdvEXT (GLenum pname, GLdouble *params); +GLAPI void APIENTRY glCullParameterfvEXT (GLenum pname, GLfloat *params); +#endif +#endif /* GL_EXT_cull_vertex */ + +#ifndef GL_EXT_debug_label +#define GL_EXT_debug_label 1 +#define GL_PROGRAM_PIPELINE_OBJECT_EXT 0x8A4F +#define GL_PROGRAM_OBJECT_EXT 0x8B40 +#define GL_SHADER_OBJECT_EXT 0x8B48 +#define GL_BUFFER_OBJECT_EXT 0x9151 +#define GL_QUERY_OBJECT_EXT 0x9153 +#define GL_VERTEX_ARRAY_OBJECT_EXT 0x9154 +typedef void (APIENTRYP PFNGLLABELOBJECTEXTPROC) (GLenum type, GLuint object, GLsizei length, const GLchar *label); +typedef void (APIENTRYP PFNGLGETOBJECTLABELEXTPROC) (GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glLabelObjectEXT (GLenum type, GLuint object, GLsizei length, const GLchar *label); +GLAPI void APIENTRY glGetObjectLabelEXT (GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label); +#endif +#endif /* GL_EXT_debug_label */ + +#ifndef GL_EXT_debug_marker +#define GL_EXT_debug_marker 1 +typedef void (APIENTRYP PFNGLINSERTEVENTMARKEREXTPROC) (GLsizei length, const GLchar *marker); +typedef void (APIENTRYP PFNGLPUSHGROUPMARKEREXTPROC) (GLsizei length, const GLchar *marker); +typedef void (APIENTRYP PFNGLPOPGROUPMARKEREXTPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glInsertEventMarkerEXT (GLsizei length, const GLchar *marker); +GLAPI void APIENTRY glPushGroupMarkerEXT (GLsizei length, const GLchar *marker); +GLAPI void APIENTRY glPopGroupMarkerEXT (void); +#endif +#endif /* GL_EXT_debug_marker */ + +#ifndef GL_EXT_depth_bounds_test +#define GL_EXT_depth_bounds_test 1 +#define GL_DEPTH_BOUNDS_TEST_EXT 0x8890 +#define GL_DEPTH_BOUNDS_EXT 0x8891 +typedef void (APIENTRYP PFNGLDEPTHBOUNDSEXTPROC) (GLclampd zmin, GLclampd zmax); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDepthBoundsEXT (GLclampd zmin, GLclampd zmax); +#endif +#endif /* GL_EXT_depth_bounds_test */ + +#ifndef GL_EXT_direct_state_access +#define GL_EXT_direct_state_access 1 +#define GL_PROGRAM_MATRIX_EXT 0x8E2D +#define GL_TRANSPOSE_PROGRAM_MATRIX_EXT 0x8E2E +#define GL_PROGRAM_MATRIX_STACK_DEPTH_EXT 0x8E2F +typedef void (APIENTRYP PFNGLMATRIXLOADFEXTPROC) (GLenum mode, const GLfloat *m); +typedef void (APIENTRYP PFNGLMATRIXLOADDEXTPROC) (GLenum mode, const GLdouble *m); +typedef void (APIENTRYP PFNGLMATRIXMULTFEXTPROC) (GLenum mode, const GLfloat *m); +typedef void (APIENTRYP PFNGLMATRIXMULTDEXTPROC) (GLenum mode, const GLdouble *m); +typedef void (APIENTRYP PFNGLMATRIXLOADIDENTITYEXTPROC) (GLenum mode); +typedef void (APIENTRYP PFNGLMATRIXROTATEFEXTPROC) (GLenum mode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLMATRIXROTATEDEXTPROC) (GLenum mode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLMATRIXSCALEFEXTPROC) (GLenum mode, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLMATRIXSCALEDEXTPROC) (GLenum mode, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLMATRIXTRANSLATEFEXTPROC) (GLenum mode, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLMATRIXTRANSLATEDEXTPROC) (GLenum mode, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLMATRIXFRUSTUMEXTPROC) (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +typedef void (APIENTRYP PFNGLMATRIXORTHOEXTPROC) (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +typedef void (APIENTRYP PFNGLMATRIXPOPEXTPROC) (GLenum mode); +typedef void (APIENTRYP PFNGLMATRIXPUSHEXTPROC) (GLenum mode); +typedef void (APIENTRYP PFNGLCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask); +typedef void (APIENTRYP PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask); +typedef void (APIENTRYP PFNGLTEXTUREPARAMETERFEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLCOPYTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +typedef void (APIENTRYP PFNGLCOPYTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLGETTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, void *pixels); +typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLBINDMULTITEXTUREEXTPROC) (GLenum texunit, GLenum target, GLuint texture); +typedef void (APIENTRYP PFNGLMULTITEXCOORDPOINTEREXTPROC) (GLenum texunit, GLint size, GLenum type, GLsizei stride, const void *pointer); +typedef void (APIENTRYP PFNGLMULTITEXENVFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLMULTITEXENVIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLMULTITEXGENDEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble param); +typedef void (APIENTRYP PFNGLMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLdouble *params); +typedef void (APIENTRYP PFNGLMULTITEXGENFEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLMULTITEXGENIEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLGETMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble *params); +typedef void (APIENTRYP PFNGLGETMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLMULTITEXPARAMETERFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLCOPYMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +typedef void (APIENTRYP PFNGLCOPYMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (APIENTRYP PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (APIENTRYP PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLGETMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, void *pixels); +typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLENABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index); +typedef void (APIENTRYP PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index); +typedef void (APIENTRYP PFNGLGETFLOATINDEXEDVEXTPROC) (GLenum target, GLuint index, GLfloat *data); +typedef void (APIENTRYP PFNGLGETDOUBLEINDEXEDVEXTPROC) (GLenum target, GLuint index, GLdouble *data); +typedef void (APIENTRYP PFNGLGETPOINTERINDEXEDVEXTPROC) (GLenum target, GLuint index, void **data); +typedef void (APIENTRYP PFNGLENABLEINDEXEDEXTPROC) (GLenum target, GLuint index); +typedef void (APIENTRYP PFNGLDISABLEINDEXEDEXTPROC) (GLenum target, GLuint index); +typedef GLboolean (APIENTRYP PFNGLISENABLEDINDEXEDEXTPROC) (GLenum target, GLuint index); +typedef void (APIENTRYP PFNGLGETINTEGERINDEXEDVEXTPROC) (GLenum target, GLuint index, GLint *data); +typedef void (APIENTRYP PFNGLGETBOOLEANINDEXEDVEXTPROC) (GLenum target, GLuint index, GLboolean *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *bits); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *bits); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *bits); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *bits); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *bits); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *bits); +typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint lod, void *img); +typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *bits); +typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *bits); +typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *bits); +typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *bits); +typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *bits); +typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *bits); +typedef void (APIENTRYP PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint lod, void *img); +typedef void (APIENTRYP PFNGLMATRIXLOADTRANSPOSEFEXTPROC) (GLenum mode, const GLfloat *m); +typedef void (APIENTRYP PFNGLMATRIXLOADTRANSPOSEDEXTPROC) (GLenum mode, const GLdouble *m); +typedef void (APIENTRYP PFNGLMATRIXMULTTRANSPOSEFEXTPROC) (GLenum mode, const GLfloat *m); +typedef void (APIENTRYP PFNGLMATRIXMULTTRANSPOSEDEXTPROC) (GLenum mode, const GLdouble *m); +typedef void (APIENTRYP PFNGLNAMEDBUFFERDATAEXTPROC) (GLuint buffer, GLsizeiptr size, const void *data, GLenum usage); +typedef void (APIENTRYP PFNGLNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data); +typedef void *(APIENTRYP PFNGLMAPNAMEDBUFFEREXTPROC) (GLuint buffer, GLenum access); +typedef GLboolean (APIENTRYP PFNGLUNMAPNAMEDBUFFEREXTPROC) (GLuint buffer); +typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC) (GLuint buffer, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPOINTERVEXTPROC) (GLuint buffer, GLenum pname, void **params); +typedef void (APIENTRYP PFNGLGETNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, void *data); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FEXTPROC) (GLuint program, GLint location, GLfloat v0); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IEXTPROC) (GLuint program, GLint location, GLint v0); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLTEXTUREBUFFEREXTPROC) (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer); +typedef void (APIENTRYP PFNGLMULTITEXBUFFEREXTPROC) (GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer); +typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLuint *params); +typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLuint *params); +typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLuint *params); +typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLuint *params); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIEXTPROC) (GLuint program, GLint location, GLuint v0); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLfloat *params); +typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC) (GLuint program, GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLint *params); +typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLint *params); +typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLuint *params); +typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLuint *params); +typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLint *params); +typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint *params); +typedef void (APIENTRYP PFNGLENABLECLIENTSTATEIEXTPROC) (GLenum array, GLuint index); +typedef void (APIENTRYP PFNGLDISABLECLIENTSTATEIEXTPROC) (GLenum array, GLuint index); +typedef void (APIENTRYP PFNGLGETFLOATI_VEXTPROC) (GLenum pname, GLuint index, GLfloat *params); +typedef void (APIENTRYP PFNGLGETDOUBLEI_VEXTPROC) (GLenum pname, GLuint index, GLdouble *params); +typedef void (APIENTRYP PFNGLGETPOINTERI_VEXTPROC) (GLenum pname, GLuint index, void **params); +typedef void (APIENTRYP PFNGLNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum format, GLsizei len, const void *string); +typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLdouble *params); +typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLfloat *params); +typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble *params); +typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat *params); +typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMIVEXTPROC) (GLuint program, GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum pname, void *string); +typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC) (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC) (GLuint renderbuffer, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC) (GLuint renderbuffer, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); +typedef GLenum (APIENTRYP PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC) (GLuint framebuffer, GLenum target); +typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC) (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (APIENTRYP PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGENERATETEXTUREMIPMAPEXTPROC) (GLuint texture, GLenum target); +typedef void (APIENTRYP PFNGLGENERATEMULTITEXMIPMAPEXTPROC) (GLenum texunit, GLenum target); +typedef void (APIENTRYP PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC) (GLuint framebuffer, GLenum mode); +typedef void (APIENTRYP PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC) (GLuint framebuffer, GLsizei n, const GLenum *bufs); +typedef void (APIENTRYP PFNGLFRAMEBUFFERREADBUFFEREXTPROC) (GLuint framebuffer, GLenum mode); +typedef void (APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC) (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLenum face); +typedef void (APIENTRYP PFNGLTEXTURERENDERBUFFEREXTPROC) (GLuint texture, GLenum target, GLuint renderbuffer); +typedef void (APIENTRYP PFNGLMULTITEXRENDERBUFFEREXTPROC) (GLenum texunit, GLenum target, GLuint renderbuffer); +typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (APIENTRYP PFNGLVERTEXARRAYCOLOROFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (APIENTRYP PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLsizei stride, GLintptr offset); +typedef void (APIENTRYP PFNGLVERTEXARRAYINDEXOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); +typedef void (APIENTRYP PFNGLVERTEXARRAYNORMALOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); +typedef void (APIENTRYP PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (APIENTRYP PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum texunit, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (APIENTRYP PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); +typedef void (APIENTRYP PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLintptr offset); +typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (APIENTRYP PFNGLENABLEVERTEXARRAYEXTPROC) (GLuint vaobj, GLenum array); +typedef void (APIENTRYP PFNGLDISABLEVERTEXARRAYEXTPROC) (GLuint vaobj, GLenum array); +typedef void (APIENTRYP PFNGLENABLEVERTEXARRAYATTRIBEXTPROC) (GLuint vaobj, GLuint index); +typedef void (APIENTRYP PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC) (GLuint vaobj, GLuint index); +typedef void (APIENTRYP PFNGLGETVERTEXARRAYINTEGERVEXTPROC) (GLuint vaobj, GLenum pname, GLint *param); +typedef void (APIENTRYP PFNGLGETVERTEXARRAYPOINTERVEXTPROC) (GLuint vaobj, GLenum pname, void **param); +typedef void (APIENTRYP PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC) (GLuint vaobj, GLuint index, GLenum pname, GLint *param); +typedef void (APIENTRYP PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC) (GLuint vaobj, GLuint index, GLenum pname, void **param); +typedef void *(APIENTRYP PFNGLMAPNAMEDBUFFERRANGEEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access); +typedef void (APIENTRYP PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length); +typedef void (APIENTRYP PFNGLNAMEDBUFFERSTORAGEEXTPROC) (GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags); +typedef void (APIENTRYP PFNGLCLEARNAMEDBUFFERDATAEXTPROC) (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data); +typedef void (APIENTRYP PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLenum internalformat, GLsizeiptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); +typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC) (GLuint framebuffer, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DEXTPROC) (GLuint program, GLint location, GLdouble x); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DEXTPROC) (GLuint program, GLint location, GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DEXTPROC) (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DEXTPROC) (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLTEXTUREBUFFERRANGEEXTPROC) (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (APIENTRYP PFNGLTEXTURESTORAGE1DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +typedef void (APIENTRYP PFNGLTEXTURESTORAGE2DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLTEXTURESTORAGE3DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +typedef void (APIENTRYP PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC) (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +typedef void (APIENTRYP PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC) (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +typedef void (APIENTRYP PFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC) (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); +typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); +typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC) (GLuint vaobj, GLuint attribindex, GLuint bindingindex); +typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC) (GLuint vaobj, GLuint bindingindex, GLuint divisor); +typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (APIENTRYP PFNGLTEXTUREPAGECOMMITMENTEXTPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean resident); +typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBDIVISOREXTPROC) (GLuint vaobj, GLuint index, GLuint divisor); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMatrixLoadfEXT (GLenum mode, const GLfloat *m); +GLAPI void APIENTRY glMatrixLoaddEXT (GLenum mode, const GLdouble *m); +GLAPI void APIENTRY glMatrixMultfEXT (GLenum mode, const GLfloat *m); +GLAPI void APIENTRY glMatrixMultdEXT (GLenum mode, const GLdouble *m); +GLAPI void APIENTRY glMatrixLoadIdentityEXT (GLenum mode); +GLAPI void APIENTRY glMatrixRotatefEXT (GLenum mode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glMatrixRotatedEXT (GLenum mode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z); +GLAPI void APIENTRY glMatrixScalefEXT (GLenum mode, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glMatrixScaledEXT (GLenum mode, GLdouble x, GLdouble y, GLdouble z); +GLAPI void APIENTRY glMatrixTranslatefEXT (GLenum mode, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glMatrixTranslatedEXT (GLenum mode, GLdouble x, GLdouble y, GLdouble z); +GLAPI void APIENTRY glMatrixFrustumEXT (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +GLAPI void APIENTRY glMatrixOrthoEXT (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +GLAPI void APIENTRY glMatrixPopEXT (GLenum mode); +GLAPI void APIENTRY glMatrixPushEXT (GLenum mode); +GLAPI void APIENTRY glClientAttribDefaultEXT (GLbitfield mask); +GLAPI void APIENTRY glPushClientAttribDefaultEXT (GLbitfield mask); +GLAPI void APIENTRY glTextureParameterfEXT (GLuint texture, GLenum target, GLenum pname, GLfloat param); +GLAPI void APIENTRY glTextureParameterfvEXT (GLuint texture, GLenum target, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glTextureParameteriEXT (GLuint texture, GLenum target, GLenum pname, GLint param); +GLAPI void APIENTRY glTextureParameterivEXT (GLuint texture, GLenum target, GLenum pname, const GLint *params); +GLAPI void APIENTRY glTextureImage1DEXT (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glTextureImage2DEXT (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glTextureSubImage1DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glTextureSubImage2DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glCopyTextureImage1DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +GLAPI void APIENTRY glCopyTextureImage2DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +GLAPI void APIENTRY glCopyTextureSubImage1DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +GLAPI void APIENTRY glCopyTextureSubImage2DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void APIENTRY glGetTextureImageEXT (GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, void *pixels); +GLAPI void APIENTRY glGetTextureParameterfvEXT (GLuint texture, GLenum target, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetTextureParameterivEXT (GLuint texture, GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetTextureLevelParameterfvEXT (GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetTextureLevelParameterivEXT (GLuint texture, GLenum target, GLint level, GLenum pname, GLint *params); +GLAPI void APIENTRY glTextureImage3DEXT (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glTextureSubImage3DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glCopyTextureSubImage3DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void APIENTRY glBindMultiTextureEXT (GLenum texunit, GLenum target, GLuint texture); +GLAPI void APIENTRY glMultiTexCoordPointerEXT (GLenum texunit, GLint size, GLenum type, GLsizei stride, const void *pointer); +GLAPI void APIENTRY glMultiTexEnvfEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat param); +GLAPI void APIENTRY glMultiTexEnvfvEXT (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glMultiTexEnviEXT (GLenum texunit, GLenum target, GLenum pname, GLint param); +GLAPI void APIENTRY glMultiTexEnvivEXT (GLenum texunit, GLenum target, GLenum pname, const GLint *params); +GLAPI void APIENTRY glMultiTexGendEXT (GLenum texunit, GLenum coord, GLenum pname, GLdouble param); +GLAPI void APIENTRY glMultiTexGendvEXT (GLenum texunit, GLenum coord, GLenum pname, const GLdouble *params); +GLAPI void APIENTRY glMultiTexGenfEXT (GLenum texunit, GLenum coord, GLenum pname, GLfloat param); +GLAPI void APIENTRY glMultiTexGenfvEXT (GLenum texunit, GLenum coord, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glMultiTexGeniEXT (GLenum texunit, GLenum coord, GLenum pname, GLint param); +GLAPI void APIENTRY glMultiTexGenivEXT (GLenum texunit, GLenum coord, GLenum pname, const GLint *params); +GLAPI void APIENTRY glGetMultiTexEnvfvEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetMultiTexEnvivEXT (GLenum texunit, GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetMultiTexGendvEXT (GLenum texunit, GLenum coord, GLenum pname, GLdouble *params); +GLAPI void APIENTRY glGetMultiTexGenfvEXT (GLenum texunit, GLenum coord, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetMultiTexGenivEXT (GLenum texunit, GLenum coord, GLenum pname, GLint *params); +GLAPI void APIENTRY glMultiTexParameteriEXT (GLenum texunit, GLenum target, GLenum pname, GLint param); +GLAPI void APIENTRY glMultiTexParameterivEXT (GLenum texunit, GLenum target, GLenum pname, const GLint *params); +GLAPI void APIENTRY glMultiTexParameterfEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat param); +GLAPI void APIENTRY glMultiTexParameterfvEXT (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glMultiTexImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glMultiTexImage2DEXT (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glMultiTexSubImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glMultiTexSubImage2DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glCopyMultiTexImage1DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +GLAPI void APIENTRY glCopyMultiTexImage2DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +GLAPI void APIENTRY glCopyMultiTexSubImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +GLAPI void APIENTRY glCopyMultiTexSubImage2DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void APIENTRY glGetMultiTexImageEXT (GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, void *pixels); +GLAPI void APIENTRY glGetMultiTexParameterfvEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetMultiTexParameterivEXT (GLenum texunit, GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetMultiTexLevelParameterfvEXT (GLenum texunit, GLenum target, GLint level, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetMultiTexLevelParameterivEXT (GLenum texunit, GLenum target, GLint level, GLenum pname, GLint *params); +GLAPI void APIENTRY glMultiTexImage3DEXT (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glMultiTexSubImage3DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glCopyMultiTexSubImage3DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void APIENTRY glEnableClientStateIndexedEXT (GLenum array, GLuint index); +GLAPI void APIENTRY glDisableClientStateIndexedEXT (GLenum array, GLuint index); +GLAPI void APIENTRY glGetFloatIndexedvEXT (GLenum target, GLuint index, GLfloat *data); +GLAPI void APIENTRY glGetDoubleIndexedvEXT (GLenum target, GLuint index, GLdouble *data); +GLAPI void APIENTRY glGetPointerIndexedvEXT (GLenum target, GLuint index, void **data); +GLAPI void APIENTRY glEnableIndexedEXT (GLenum target, GLuint index); +GLAPI void APIENTRY glDisableIndexedEXT (GLenum target, GLuint index); +GLAPI GLboolean APIENTRY glIsEnabledIndexedEXT (GLenum target, GLuint index); +GLAPI void APIENTRY glGetIntegerIndexedvEXT (GLenum target, GLuint index, GLint *data); +GLAPI void APIENTRY glGetBooleanIndexedvEXT (GLenum target, GLuint index, GLboolean *data); +GLAPI void APIENTRY glCompressedTextureImage3DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *bits); +GLAPI void APIENTRY glCompressedTextureImage2DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *bits); +GLAPI void APIENTRY glCompressedTextureImage1DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *bits); +GLAPI void APIENTRY glCompressedTextureSubImage3DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *bits); +GLAPI void APIENTRY glCompressedTextureSubImage2DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *bits); +GLAPI void APIENTRY glCompressedTextureSubImage1DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *bits); +GLAPI void APIENTRY glGetCompressedTextureImageEXT (GLuint texture, GLenum target, GLint lod, void *img); +GLAPI void APIENTRY glCompressedMultiTexImage3DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *bits); +GLAPI void APIENTRY glCompressedMultiTexImage2DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *bits); +GLAPI void APIENTRY glCompressedMultiTexImage1DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *bits); +GLAPI void APIENTRY glCompressedMultiTexSubImage3DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *bits); +GLAPI void APIENTRY glCompressedMultiTexSubImage2DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *bits); +GLAPI void APIENTRY glCompressedMultiTexSubImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *bits); +GLAPI void APIENTRY glGetCompressedMultiTexImageEXT (GLenum texunit, GLenum target, GLint lod, void *img); +GLAPI void APIENTRY glMatrixLoadTransposefEXT (GLenum mode, const GLfloat *m); +GLAPI void APIENTRY glMatrixLoadTransposedEXT (GLenum mode, const GLdouble *m); +GLAPI void APIENTRY glMatrixMultTransposefEXT (GLenum mode, const GLfloat *m); +GLAPI void APIENTRY glMatrixMultTransposedEXT (GLenum mode, const GLdouble *m); +GLAPI void APIENTRY glNamedBufferDataEXT (GLuint buffer, GLsizeiptr size, const void *data, GLenum usage); +GLAPI void APIENTRY glNamedBufferSubDataEXT (GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data); +GLAPI void *APIENTRY glMapNamedBufferEXT (GLuint buffer, GLenum access); +GLAPI GLboolean APIENTRY glUnmapNamedBufferEXT (GLuint buffer); +GLAPI void APIENTRY glGetNamedBufferParameterivEXT (GLuint buffer, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetNamedBufferPointervEXT (GLuint buffer, GLenum pname, void **params); +GLAPI void APIENTRY glGetNamedBufferSubDataEXT (GLuint buffer, GLintptr offset, GLsizeiptr size, void *data); +GLAPI void APIENTRY glProgramUniform1fEXT (GLuint program, GLint location, GLfloat v0); +GLAPI void APIENTRY glProgramUniform2fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1); +GLAPI void APIENTRY glProgramUniform3fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +GLAPI void APIENTRY glProgramUniform4fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +GLAPI void APIENTRY glProgramUniform1iEXT (GLuint program, GLint location, GLint v0); +GLAPI void APIENTRY glProgramUniform2iEXT (GLuint program, GLint location, GLint v0, GLint v1); +GLAPI void APIENTRY glProgramUniform3iEXT (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); +GLAPI void APIENTRY glProgramUniform4iEXT (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +GLAPI void APIENTRY glProgramUniform1fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glProgramUniform2fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glProgramUniform3fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glProgramUniform4fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glProgramUniform1ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glProgramUniform2ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glProgramUniform3ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glProgramUniform4ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glProgramUniformMatrix2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix2x3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix3x2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix2x4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix4x2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix3x4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix4x3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glTextureBufferEXT (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer); +GLAPI void APIENTRY glMultiTexBufferEXT (GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer); +GLAPI void APIENTRY glTextureParameterIivEXT (GLuint texture, GLenum target, GLenum pname, const GLint *params); +GLAPI void APIENTRY glTextureParameterIuivEXT (GLuint texture, GLenum target, GLenum pname, const GLuint *params); +GLAPI void APIENTRY glGetTextureParameterIivEXT (GLuint texture, GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetTextureParameterIuivEXT (GLuint texture, GLenum target, GLenum pname, GLuint *params); +GLAPI void APIENTRY glMultiTexParameterIivEXT (GLenum texunit, GLenum target, GLenum pname, const GLint *params); +GLAPI void APIENTRY glMultiTexParameterIuivEXT (GLenum texunit, GLenum target, GLenum pname, const GLuint *params); +GLAPI void APIENTRY glGetMultiTexParameterIivEXT (GLenum texunit, GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetMultiTexParameterIuivEXT (GLenum texunit, GLenum target, GLenum pname, GLuint *params); +GLAPI void APIENTRY glProgramUniform1uiEXT (GLuint program, GLint location, GLuint v0); +GLAPI void APIENTRY glProgramUniform2uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1); +GLAPI void APIENTRY glProgramUniform3uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); +GLAPI void APIENTRY glProgramUniform4uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +GLAPI void APIENTRY glProgramUniform1uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glProgramUniform2uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glProgramUniform3uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glProgramUniform4uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glNamedProgramLocalParameters4fvEXT (GLuint program, GLenum target, GLuint index, GLsizei count, const GLfloat *params); +GLAPI void APIENTRY glNamedProgramLocalParameterI4iEXT (GLuint program, GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +GLAPI void APIENTRY glNamedProgramLocalParameterI4ivEXT (GLuint program, GLenum target, GLuint index, const GLint *params); +GLAPI void APIENTRY glNamedProgramLocalParametersI4ivEXT (GLuint program, GLenum target, GLuint index, GLsizei count, const GLint *params); +GLAPI void APIENTRY glNamedProgramLocalParameterI4uiEXT (GLuint program, GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +GLAPI void APIENTRY glNamedProgramLocalParameterI4uivEXT (GLuint program, GLenum target, GLuint index, const GLuint *params); +GLAPI void APIENTRY glNamedProgramLocalParametersI4uivEXT (GLuint program, GLenum target, GLuint index, GLsizei count, const GLuint *params); +GLAPI void APIENTRY glGetNamedProgramLocalParameterIivEXT (GLuint program, GLenum target, GLuint index, GLint *params); +GLAPI void APIENTRY glGetNamedProgramLocalParameterIuivEXT (GLuint program, GLenum target, GLuint index, GLuint *params); +GLAPI void APIENTRY glEnableClientStateiEXT (GLenum array, GLuint index); +GLAPI void APIENTRY glDisableClientStateiEXT (GLenum array, GLuint index); +GLAPI void APIENTRY glGetFloati_vEXT (GLenum pname, GLuint index, GLfloat *params); +GLAPI void APIENTRY glGetDoublei_vEXT (GLenum pname, GLuint index, GLdouble *params); +GLAPI void APIENTRY glGetPointeri_vEXT (GLenum pname, GLuint index, void **params); +GLAPI void APIENTRY glNamedProgramStringEXT (GLuint program, GLenum target, GLenum format, GLsizei len, const void *string); +GLAPI void APIENTRY glNamedProgramLocalParameter4dEXT (GLuint program, GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void APIENTRY glNamedProgramLocalParameter4dvEXT (GLuint program, GLenum target, GLuint index, const GLdouble *params); +GLAPI void APIENTRY glNamedProgramLocalParameter4fEXT (GLuint program, GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void APIENTRY glNamedProgramLocalParameter4fvEXT (GLuint program, GLenum target, GLuint index, const GLfloat *params); +GLAPI void APIENTRY glGetNamedProgramLocalParameterdvEXT (GLuint program, GLenum target, GLuint index, GLdouble *params); +GLAPI void APIENTRY glGetNamedProgramLocalParameterfvEXT (GLuint program, GLenum target, GLuint index, GLfloat *params); +GLAPI void APIENTRY glGetNamedProgramivEXT (GLuint program, GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetNamedProgramStringEXT (GLuint program, GLenum target, GLenum pname, void *string); +GLAPI void APIENTRY glNamedRenderbufferStorageEXT (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); +GLAPI void APIENTRY glGetNamedRenderbufferParameterivEXT (GLuint renderbuffer, GLenum pname, GLint *params); +GLAPI void APIENTRY glNamedRenderbufferStorageMultisampleEXT (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +GLAPI void APIENTRY glNamedRenderbufferStorageMultisampleCoverageEXT (GLuint renderbuffer, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); +GLAPI GLenum APIENTRY glCheckNamedFramebufferStatusEXT (GLuint framebuffer, GLenum target); +GLAPI void APIENTRY glNamedFramebufferTexture1DEXT (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GLAPI void APIENTRY glNamedFramebufferTexture2DEXT (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GLAPI void APIENTRY glNamedFramebufferTexture3DEXT (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +GLAPI void APIENTRY glNamedFramebufferRenderbufferEXT (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +GLAPI void APIENTRY glGetNamedFramebufferAttachmentParameterivEXT (GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params); +GLAPI void APIENTRY glGenerateTextureMipmapEXT (GLuint texture, GLenum target); +GLAPI void APIENTRY glGenerateMultiTexMipmapEXT (GLenum texunit, GLenum target); +GLAPI void APIENTRY glFramebufferDrawBufferEXT (GLuint framebuffer, GLenum mode); +GLAPI void APIENTRY glFramebufferDrawBuffersEXT (GLuint framebuffer, GLsizei n, const GLenum *bufs); +GLAPI void APIENTRY glFramebufferReadBufferEXT (GLuint framebuffer, GLenum mode); +GLAPI void APIENTRY glGetFramebufferParameterivEXT (GLuint framebuffer, GLenum pname, GLint *params); +GLAPI void APIENTRY glNamedCopyBufferSubDataEXT (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +GLAPI void APIENTRY glNamedFramebufferTextureEXT (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); +GLAPI void APIENTRY glNamedFramebufferTextureLayerEXT (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); +GLAPI void APIENTRY glNamedFramebufferTextureFaceEXT (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLenum face); +GLAPI void APIENTRY glTextureRenderbufferEXT (GLuint texture, GLenum target, GLuint renderbuffer); +GLAPI void APIENTRY glMultiTexRenderbufferEXT (GLenum texunit, GLenum target, GLuint renderbuffer); +GLAPI void APIENTRY glVertexArrayVertexOffsetEXT (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); +GLAPI void APIENTRY glVertexArrayColorOffsetEXT (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); +GLAPI void APIENTRY glVertexArrayEdgeFlagOffsetEXT (GLuint vaobj, GLuint buffer, GLsizei stride, GLintptr offset); +GLAPI void APIENTRY glVertexArrayIndexOffsetEXT (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); +GLAPI void APIENTRY glVertexArrayNormalOffsetEXT (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); +GLAPI void APIENTRY glVertexArrayTexCoordOffsetEXT (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); +GLAPI void APIENTRY glVertexArrayMultiTexCoordOffsetEXT (GLuint vaobj, GLuint buffer, GLenum texunit, GLint size, GLenum type, GLsizei stride, GLintptr offset); +GLAPI void APIENTRY glVertexArrayFogCoordOffsetEXT (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); +GLAPI void APIENTRY glVertexArraySecondaryColorOffsetEXT (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); +GLAPI void APIENTRY glVertexArrayVertexAttribOffsetEXT (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLintptr offset); +GLAPI void APIENTRY glVertexArrayVertexAttribIOffsetEXT (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset); +GLAPI void APIENTRY glEnableVertexArrayEXT (GLuint vaobj, GLenum array); +GLAPI void APIENTRY glDisableVertexArrayEXT (GLuint vaobj, GLenum array); +GLAPI void APIENTRY glEnableVertexArrayAttribEXT (GLuint vaobj, GLuint index); +GLAPI void APIENTRY glDisableVertexArrayAttribEXT (GLuint vaobj, GLuint index); +GLAPI void APIENTRY glGetVertexArrayIntegervEXT (GLuint vaobj, GLenum pname, GLint *param); +GLAPI void APIENTRY glGetVertexArrayPointervEXT (GLuint vaobj, GLenum pname, void **param); +GLAPI void APIENTRY glGetVertexArrayIntegeri_vEXT (GLuint vaobj, GLuint index, GLenum pname, GLint *param); +GLAPI void APIENTRY glGetVertexArrayPointeri_vEXT (GLuint vaobj, GLuint index, GLenum pname, void **param); +GLAPI void *APIENTRY glMapNamedBufferRangeEXT (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access); +GLAPI void APIENTRY glFlushMappedNamedBufferRangeEXT (GLuint buffer, GLintptr offset, GLsizeiptr length); +GLAPI void APIENTRY glNamedBufferStorageEXT (GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags); +GLAPI void APIENTRY glClearNamedBufferDataEXT (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data); +GLAPI void APIENTRY glClearNamedBufferSubDataEXT (GLuint buffer, GLenum internalformat, GLsizeiptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); +GLAPI void APIENTRY glNamedFramebufferParameteriEXT (GLuint framebuffer, GLenum pname, GLint param); +GLAPI void APIENTRY glGetNamedFramebufferParameterivEXT (GLuint framebuffer, GLenum pname, GLint *params); +GLAPI void APIENTRY glProgramUniform1dEXT (GLuint program, GLint location, GLdouble x); +GLAPI void APIENTRY glProgramUniform2dEXT (GLuint program, GLint location, GLdouble x, GLdouble y); +GLAPI void APIENTRY glProgramUniform3dEXT (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z); +GLAPI void APIENTRY glProgramUniform4dEXT (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void APIENTRY glProgramUniform1dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value); +GLAPI void APIENTRY glProgramUniform2dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value); +GLAPI void APIENTRY glProgramUniform3dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value); +GLAPI void APIENTRY glProgramUniform4dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix2dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix3dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix4dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix2x3dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix2x4dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix3x2dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix3x4dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix4x2dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix4x3dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glTextureBufferRangeEXT (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); +GLAPI void APIENTRY glTextureStorage1DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +GLAPI void APIENTRY glTextureStorage2DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +GLAPI void APIENTRY glTextureStorage3DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +GLAPI void APIENTRY glTextureStorage2DMultisampleEXT (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +GLAPI void APIENTRY glTextureStorage3DMultisampleEXT (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +GLAPI void APIENTRY glVertexArrayBindVertexBufferEXT (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); +GLAPI void APIENTRY glVertexArrayVertexAttribFormatEXT (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); +GLAPI void APIENTRY glVertexArrayVertexAttribIFormatEXT (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +GLAPI void APIENTRY glVertexArrayVertexAttribLFormatEXT (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +GLAPI void APIENTRY glVertexArrayVertexAttribBindingEXT (GLuint vaobj, GLuint attribindex, GLuint bindingindex); +GLAPI void APIENTRY glVertexArrayVertexBindingDivisorEXT (GLuint vaobj, GLuint bindingindex, GLuint divisor); +GLAPI void APIENTRY glVertexArrayVertexAttribLOffsetEXT (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset); +GLAPI void APIENTRY glTexturePageCommitmentEXT (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean resident); +GLAPI void APIENTRY glVertexArrayVertexAttribDivisorEXT (GLuint vaobj, GLuint index, GLuint divisor); +#endif +#endif /* GL_EXT_direct_state_access */ + +#ifndef GL_EXT_draw_buffers2 +#define GL_EXT_draw_buffers2 1 +typedef void (APIENTRYP PFNGLCOLORMASKINDEXEDEXTPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glColorMaskIndexedEXT (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +#endif +#endif /* GL_EXT_draw_buffers2 */ + +#ifndef GL_EXT_draw_instanced +#define GL_EXT_draw_instanced 1 +typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount); +typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawArraysInstancedEXT (GLenum mode, GLint start, GLsizei count, GLsizei primcount); +GLAPI void APIENTRY glDrawElementsInstancedEXT (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); +#endif +#endif /* GL_EXT_draw_instanced */ + +#ifndef GL_EXT_draw_range_elements +#define GL_EXT_draw_range_elements 1 +#define GL_MAX_ELEMENTS_VERTICES_EXT 0x80E8 +#define GL_MAX_ELEMENTS_INDICES_EXT 0x80E9 +typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawRangeElementsEXT (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); +#endif +#endif /* GL_EXT_draw_range_elements */ + +#ifndef GL_EXT_fog_coord +#define GL_EXT_fog_coord 1 +#define GL_FOG_COORDINATE_SOURCE_EXT 0x8450 +#define GL_FOG_COORDINATE_EXT 0x8451 +#define GL_FRAGMENT_DEPTH_EXT 0x8452 +#define GL_CURRENT_FOG_COORDINATE_EXT 0x8453 +#define GL_FOG_COORDINATE_ARRAY_TYPE_EXT 0x8454 +#define GL_FOG_COORDINATE_ARRAY_STRIDE_EXT 0x8455 +#define GL_FOG_COORDINATE_ARRAY_POINTER_EXT 0x8456 +#define GL_FOG_COORDINATE_ARRAY_EXT 0x8457 +typedef void (APIENTRYP PFNGLFOGCOORDFEXTPROC) (GLfloat coord); +typedef void (APIENTRYP PFNGLFOGCOORDFVEXTPROC) (const GLfloat *coord); +typedef void (APIENTRYP PFNGLFOGCOORDDEXTPROC) (GLdouble coord); +typedef void (APIENTRYP PFNGLFOGCOORDDVEXTPROC) (const GLdouble *coord); +typedef void (APIENTRYP PFNGLFOGCOORDPOINTEREXTPROC) (GLenum type, GLsizei stride, const void *pointer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFogCoordfEXT (GLfloat coord); +GLAPI void APIENTRY glFogCoordfvEXT (const GLfloat *coord); +GLAPI void APIENTRY glFogCoorddEXT (GLdouble coord); +GLAPI void APIENTRY glFogCoorddvEXT (const GLdouble *coord); +GLAPI void APIENTRY glFogCoordPointerEXT (GLenum type, GLsizei stride, const void *pointer); +#endif +#endif /* GL_EXT_fog_coord */ + +#ifndef GL_EXT_framebuffer_blit +#define GL_EXT_framebuffer_blit 1 +#define GL_READ_FRAMEBUFFER_EXT 0x8CA8 +#define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9 +#define GL_DRAW_FRAMEBUFFER_BINDING_EXT 0x8CA6 +#define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA +typedef void (APIENTRYP PFNGLBLITFRAMEBUFFEREXTPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlitFramebufferEXT (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +#endif +#endif /* GL_EXT_framebuffer_blit */ + +#ifndef GL_EXT_framebuffer_multisample +#define GL_EXT_framebuffer_multisample 1 +#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 +#define GL_MAX_SAMPLES_EXT 0x8D57 +typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glRenderbufferStorageMultisampleEXT (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +#endif +#endif /* GL_EXT_framebuffer_multisample */ + +#ifndef GL_EXT_framebuffer_multisample_blit_scaled +#define GL_EXT_framebuffer_multisample_blit_scaled 1 +#define GL_SCALED_RESOLVE_FASTEST_EXT 0x90BA +#define GL_SCALED_RESOLVE_NICEST_EXT 0x90BB +#endif /* GL_EXT_framebuffer_multisample_blit_scaled */ + +#ifndef GL_EXT_framebuffer_object +#define GL_EXT_framebuffer_object 1 +#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506 +#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8 +#define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6 +#define GL_RENDERBUFFER_BINDING_EXT 0x8CA7 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4 +#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9 +#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC +#define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD +#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF +#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 +#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1 +#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2 +#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3 +#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4 +#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5 +#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6 +#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7 +#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8 +#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9 +#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA +#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB +#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC +#define GL_COLOR_ATTACHMENT13_EXT 0x8CED +#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE +#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF +#define GL_DEPTH_ATTACHMENT_EXT 0x8D00 +#define GL_STENCIL_ATTACHMENT_EXT 0x8D20 +#define GL_FRAMEBUFFER_EXT 0x8D40 +#define GL_RENDERBUFFER_EXT 0x8D41 +#define GL_RENDERBUFFER_WIDTH_EXT 0x8D42 +#define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44 +#define GL_STENCIL_INDEX1_EXT 0x8D46 +#define GL_STENCIL_INDEX4_EXT 0x8D47 +#define GL_STENCIL_INDEX8_EXT 0x8D48 +#define GL_STENCIL_INDEX16_EXT 0x8D49 +#define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55 +typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFEREXTPROC) (GLuint renderbuffer); +typedef void (APIENTRYP PFNGLBINDRENDERBUFFEREXTPROC) (GLenum target, GLuint renderbuffer); +typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint *renderbuffers); +typedef void (APIENTRYP PFNGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint *renderbuffers); +typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFEREXTPROC) (GLuint framebuffer); +typedef void (APIENTRYP PFNGLBINDFRAMEBUFFEREXTPROC) (GLenum target, GLuint framebuffer); +typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint *framebuffers); +typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint *framebuffers); +typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGENERATEMIPMAPEXTPROC) (GLenum target); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLboolean APIENTRY glIsRenderbufferEXT (GLuint renderbuffer); +GLAPI void APIENTRY glBindRenderbufferEXT (GLenum target, GLuint renderbuffer); +GLAPI void APIENTRY glDeleteRenderbuffersEXT (GLsizei n, const GLuint *renderbuffers); +GLAPI void APIENTRY glGenRenderbuffersEXT (GLsizei n, GLuint *renderbuffers); +GLAPI void APIENTRY glRenderbufferStorageEXT (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +GLAPI void APIENTRY glGetRenderbufferParameterivEXT (GLenum target, GLenum pname, GLint *params); +GLAPI GLboolean APIENTRY glIsFramebufferEXT (GLuint framebuffer); +GLAPI void APIENTRY glBindFramebufferEXT (GLenum target, GLuint framebuffer); +GLAPI void APIENTRY glDeleteFramebuffersEXT (GLsizei n, const GLuint *framebuffers); +GLAPI void APIENTRY glGenFramebuffersEXT (GLsizei n, GLuint *framebuffers); +GLAPI GLenum APIENTRY glCheckFramebufferStatusEXT (GLenum target); +GLAPI void APIENTRY glFramebufferTexture1DEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GLAPI void APIENTRY glFramebufferTexture2DEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GLAPI void APIENTRY glFramebufferTexture3DEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +GLAPI void APIENTRY glFramebufferRenderbufferEXT (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +GLAPI void APIENTRY glGetFramebufferAttachmentParameterivEXT (GLenum target, GLenum attachment, GLenum pname, GLint *params); +GLAPI void APIENTRY glGenerateMipmapEXT (GLenum target); +#endif +#endif /* GL_EXT_framebuffer_object */ + +#ifndef GL_EXT_framebuffer_sRGB +#define GL_EXT_framebuffer_sRGB 1 +#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9 +#define GL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x8DBA +#endif /* GL_EXT_framebuffer_sRGB */ + +#ifndef GL_EXT_geometry_shader4 +#define GL_EXT_geometry_shader4 1 +#define GL_GEOMETRY_SHADER_EXT 0x8DD9 +#define GL_GEOMETRY_VERTICES_OUT_EXT 0x8DDA +#define GL_GEOMETRY_INPUT_TYPE_EXT 0x8DDB +#define GL_GEOMETRY_OUTPUT_TYPE_EXT 0x8DDC +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29 +#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT 0x8DDD +#define GL_MAX_VERTEX_VARYING_COMPONENTS_EXT 0x8DDE +#define GL_MAX_VARYING_COMPONENTS_EXT 0x8B4B +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1 +#define GL_LINES_ADJACENCY_EXT 0x000A +#define GL_LINE_STRIP_ADJACENCY_EXT 0x000B +#define GL_TRIANGLES_ADJACENCY_EXT 0x000C +#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0x000D +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4 +#define GL_PROGRAM_POINT_SIZE_EXT 0x8642 +typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glProgramParameteriEXT (GLuint program, GLenum pname, GLint value); +#endif +#endif /* GL_EXT_geometry_shader4 */ + +#ifndef GL_EXT_gpu_program_parameters +#define GL_EXT_gpu_program_parameters 1 +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat *params); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glProgramEnvParameters4fvEXT (GLenum target, GLuint index, GLsizei count, const GLfloat *params); +GLAPI void APIENTRY glProgramLocalParameters4fvEXT (GLenum target, GLuint index, GLsizei count, const GLfloat *params); +#endif +#endif /* GL_EXT_gpu_program_parameters */ + +#ifndef GL_EXT_gpu_shader4 +#define GL_EXT_gpu_shader4 1 +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_EXT 0x88FD +#define GL_SAMPLER_1D_ARRAY_EXT 0x8DC0 +#define GL_SAMPLER_2D_ARRAY_EXT 0x8DC1 +#define GL_SAMPLER_BUFFER_EXT 0x8DC2 +#define GL_SAMPLER_1D_ARRAY_SHADOW_EXT 0x8DC3 +#define GL_SAMPLER_2D_ARRAY_SHADOW_EXT 0x8DC4 +#define GL_SAMPLER_CUBE_SHADOW_EXT 0x8DC5 +#define GL_UNSIGNED_INT_VEC2_EXT 0x8DC6 +#define GL_UNSIGNED_INT_VEC3_EXT 0x8DC7 +#define GL_UNSIGNED_INT_VEC4_EXT 0x8DC8 +#define GL_INT_SAMPLER_1D_EXT 0x8DC9 +#define GL_INT_SAMPLER_2D_EXT 0x8DCA +#define GL_INT_SAMPLER_3D_EXT 0x8DCB +#define GL_INT_SAMPLER_CUBE_EXT 0x8DCC +#define GL_INT_SAMPLER_2D_RECT_EXT 0x8DCD +#define GL_INT_SAMPLER_1D_ARRAY_EXT 0x8DCE +#define GL_INT_SAMPLER_2D_ARRAY_EXT 0x8DCF +#define GL_INT_SAMPLER_BUFFER_EXT 0x8DD0 +#define GL_UNSIGNED_INT_SAMPLER_1D_EXT 0x8DD1 +#define GL_UNSIGNED_INT_SAMPLER_2D_EXT 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_3D_EXT 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_CUBE_EXT 0x8DD4 +#define GL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT 0x8DD5 +#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT 0x8DD6 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT 0x8DD7 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT 0x8DD8 +#define GL_MIN_PROGRAM_TEXEL_OFFSET_EXT 0x8904 +#define GL_MAX_PROGRAM_TEXEL_OFFSET_EXT 0x8905 +typedef void (APIENTRYP PFNGLGETUNIFORMUIVEXTPROC) (GLuint program, GLint location, GLuint *params); +typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONEXTPROC) (GLuint program, GLuint color, const GLchar *name); +typedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONEXTPROC) (GLuint program, const GLchar *name); +typedef void (APIENTRYP PFNGLUNIFORM1UIEXTPROC) (GLint location, GLuint v0); +typedef void (APIENTRYP PFNGLUNIFORM2UIEXTPROC) (GLint location, GLuint v0, GLuint v1); +typedef void (APIENTRYP PFNGLUNIFORM3UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (APIENTRYP PFNGLUNIFORM4UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (APIENTRYP PFNGLUNIFORM1UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLUNIFORM2UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLUNIFORM3UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLUNIFORM4UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGetUniformuivEXT (GLuint program, GLint location, GLuint *params); +GLAPI void APIENTRY glBindFragDataLocationEXT (GLuint program, GLuint color, const GLchar *name); +GLAPI GLint APIENTRY glGetFragDataLocationEXT (GLuint program, const GLchar *name); +GLAPI void APIENTRY glUniform1uiEXT (GLint location, GLuint v0); +GLAPI void APIENTRY glUniform2uiEXT (GLint location, GLuint v0, GLuint v1); +GLAPI void APIENTRY glUniform3uiEXT (GLint location, GLuint v0, GLuint v1, GLuint v2); +GLAPI void APIENTRY glUniform4uiEXT (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +GLAPI void APIENTRY glUniform1uivEXT (GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glUniform2uivEXT (GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glUniform3uivEXT (GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glUniform4uivEXT (GLint location, GLsizei count, const GLuint *value); +#endif +#endif /* GL_EXT_gpu_shader4 */ + +#ifndef GL_EXT_histogram +#define GL_EXT_histogram 1 +#define GL_HISTOGRAM_EXT 0x8024 +#define GL_PROXY_HISTOGRAM_EXT 0x8025 +#define GL_HISTOGRAM_WIDTH_EXT 0x8026 +#define GL_HISTOGRAM_FORMAT_EXT 0x8027 +#define GL_HISTOGRAM_RED_SIZE_EXT 0x8028 +#define GL_HISTOGRAM_GREEN_SIZE_EXT 0x8029 +#define GL_HISTOGRAM_BLUE_SIZE_EXT 0x802A +#define GL_HISTOGRAM_ALPHA_SIZE_EXT 0x802B +#define GL_HISTOGRAM_LUMINANCE_SIZE_EXT 0x802C +#define GL_HISTOGRAM_SINK_EXT 0x802D +#define GL_MINMAX_EXT 0x802E +#define GL_MINMAX_FORMAT_EXT 0x802F +#define GL_MINMAX_SINK_EXT 0x8030 +#define GL_TABLE_TOO_LARGE_EXT 0x8031 +typedef void (APIENTRYP PFNGLGETHISTOGRAMEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); +typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETMINMAXEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); +typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLHISTOGRAMEXTPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); +typedef void (APIENTRYP PFNGLMINMAXEXTPROC) (GLenum target, GLenum internalformat, GLboolean sink); +typedef void (APIENTRYP PFNGLRESETHISTOGRAMEXTPROC) (GLenum target); +typedef void (APIENTRYP PFNGLRESETMINMAXEXTPROC) (GLenum target); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGetHistogramEXT (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); +GLAPI void APIENTRY glGetHistogramParameterfvEXT (GLenum target, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetHistogramParameterivEXT (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetMinmaxEXT (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); +GLAPI void APIENTRY glGetMinmaxParameterfvEXT (GLenum target, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetMinmaxParameterivEXT (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glHistogramEXT (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); +GLAPI void APIENTRY glMinmaxEXT (GLenum target, GLenum internalformat, GLboolean sink); +GLAPI void APIENTRY glResetHistogramEXT (GLenum target); +GLAPI void APIENTRY glResetMinmaxEXT (GLenum target); +#endif +#endif /* GL_EXT_histogram */ + +#ifndef GL_EXT_index_array_formats +#define GL_EXT_index_array_formats 1 +#define GL_IUI_V2F_EXT 0x81AD +#define GL_IUI_V3F_EXT 0x81AE +#define GL_IUI_N3F_V2F_EXT 0x81AF +#define GL_IUI_N3F_V3F_EXT 0x81B0 +#define GL_T2F_IUI_V2F_EXT 0x81B1 +#define GL_T2F_IUI_V3F_EXT 0x81B2 +#define GL_T2F_IUI_N3F_V2F_EXT 0x81B3 +#define GL_T2F_IUI_N3F_V3F_EXT 0x81B4 +#endif /* GL_EXT_index_array_formats */ + +#ifndef GL_EXT_index_func +#define GL_EXT_index_func 1 +#define GL_INDEX_TEST_EXT 0x81B5 +#define GL_INDEX_TEST_FUNC_EXT 0x81B6 +#define GL_INDEX_TEST_REF_EXT 0x81B7 +typedef void (APIENTRYP PFNGLINDEXFUNCEXTPROC) (GLenum func, GLclampf ref); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glIndexFuncEXT (GLenum func, GLclampf ref); +#endif +#endif /* GL_EXT_index_func */ + +#ifndef GL_EXT_index_material +#define GL_EXT_index_material 1 +#define GL_INDEX_MATERIAL_EXT 0x81B8 +#define GL_INDEX_MATERIAL_PARAMETER_EXT 0x81B9 +#define GL_INDEX_MATERIAL_FACE_EXT 0x81BA +typedef void (APIENTRYP PFNGLINDEXMATERIALEXTPROC) (GLenum face, GLenum mode); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glIndexMaterialEXT (GLenum face, GLenum mode); +#endif +#endif /* GL_EXT_index_material */ + +#ifndef GL_EXT_index_texture +#define GL_EXT_index_texture 1 +#endif /* GL_EXT_index_texture */ + +#ifndef GL_EXT_light_texture +#define GL_EXT_light_texture 1 +#define GL_FRAGMENT_MATERIAL_EXT 0x8349 +#define GL_FRAGMENT_NORMAL_EXT 0x834A +#define GL_FRAGMENT_COLOR_EXT 0x834C +#define GL_ATTENUATION_EXT 0x834D +#define GL_SHADOW_ATTENUATION_EXT 0x834E +#define GL_TEXTURE_APPLICATION_MODE_EXT 0x834F +#define GL_TEXTURE_LIGHT_EXT 0x8350 +#define GL_TEXTURE_MATERIAL_FACE_EXT 0x8351 +#define GL_TEXTURE_MATERIAL_PARAMETER_EXT 0x8352 +typedef void (APIENTRYP PFNGLAPPLYTEXTUREEXTPROC) (GLenum mode); +typedef void (APIENTRYP PFNGLTEXTURELIGHTEXTPROC) (GLenum pname); +typedef void (APIENTRYP PFNGLTEXTUREMATERIALEXTPROC) (GLenum face, GLenum mode); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glApplyTextureEXT (GLenum mode); +GLAPI void APIENTRY glTextureLightEXT (GLenum pname); +GLAPI void APIENTRY glTextureMaterialEXT (GLenum face, GLenum mode); +#endif +#endif /* GL_EXT_light_texture */ + +#ifndef GL_EXT_misc_attribute +#define GL_EXT_misc_attribute 1 +#endif /* GL_EXT_misc_attribute */ + +#ifndef GL_EXT_multi_draw_arrays +#define GL_EXT_multi_draw_arrays 1 +typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMultiDrawArraysEXT (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); +GLAPI void APIENTRY glMultiDrawElementsEXT (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount); +#endif +#endif /* GL_EXT_multi_draw_arrays */ + +#ifndef GL_EXT_multisample +#define GL_EXT_multisample 1 +#define GL_MULTISAMPLE_EXT 0x809D +#define GL_SAMPLE_ALPHA_TO_MASK_EXT 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F +#define GL_SAMPLE_MASK_EXT 0x80A0 +#define GL_1PASS_EXT 0x80A1 +#define GL_2PASS_0_EXT 0x80A2 +#define GL_2PASS_1_EXT 0x80A3 +#define GL_4PASS_0_EXT 0x80A4 +#define GL_4PASS_1_EXT 0x80A5 +#define GL_4PASS_2_EXT 0x80A6 +#define GL_4PASS_3_EXT 0x80A7 +#define GL_SAMPLE_BUFFERS_EXT 0x80A8 +#define GL_SAMPLES_EXT 0x80A9 +#define GL_SAMPLE_MASK_VALUE_EXT 0x80AA +#define GL_SAMPLE_MASK_INVERT_EXT 0x80AB +#define GL_SAMPLE_PATTERN_EXT 0x80AC +#define GL_MULTISAMPLE_BIT_EXT 0x20000000 +typedef void (APIENTRYP PFNGLSAMPLEMASKEXTPROC) (GLclampf value, GLboolean invert); +typedef void (APIENTRYP PFNGLSAMPLEPATTERNEXTPROC) (GLenum pattern); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSampleMaskEXT (GLclampf value, GLboolean invert); +GLAPI void APIENTRY glSamplePatternEXT (GLenum pattern); +#endif +#endif /* GL_EXT_multisample */ + +#ifndef GL_EXT_packed_depth_stencil +#define GL_EXT_packed_depth_stencil 1 +#define GL_DEPTH_STENCIL_EXT 0x84F9 +#define GL_UNSIGNED_INT_24_8_EXT 0x84FA +#define GL_DEPTH24_STENCIL8_EXT 0x88F0 +#define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1 +#endif /* GL_EXT_packed_depth_stencil */ + +#ifndef GL_EXT_packed_float +#define GL_EXT_packed_float 1 +#define GL_R11F_G11F_B10F_EXT 0x8C3A +#define GL_UNSIGNED_INT_10F_11F_11F_REV_EXT 0x8C3B +#define GL_RGBA_SIGNED_COMPONENTS_EXT 0x8C3C +#endif /* GL_EXT_packed_float */ + +#ifndef GL_EXT_packed_pixels +#define GL_EXT_packed_pixels 1 +#define GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032 +#define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034 +#define GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035 +#define GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036 +#endif /* GL_EXT_packed_pixels */ + +#ifndef GL_EXT_paletted_texture +#define GL_EXT_paletted_texture 1 +#define GL_COLOR_INDEX1_EXT 0x80E2 +#define GL_COLOR_INDEX2_EXT 0x80E3 +#define GL_COLOR_INDEX4_EXT 0x80E4 +#define GL_COLOR_INDEX8_EXT 0x80E5 +#define GL_COLOR_INDEX12_EXT 0x80E6 +#define GL_COLOR_INDEX16_EXT 0x80E7 +#define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED +typedef void (APIENTRYP PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const void *table); +typedef void (APIENTRYP PFNGLGETCOLORTABLEEXTPROC) (GLenum target, GLenum format, GLenum type, void *data); +typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glColorTableEXT (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const void *table); +GLAPI void APIENTRY glGetColorTableEXT (GLenum target, GLenum format, GLenum type, void *data); +GLAPI void APIENTRY glGetColorTableParameterivEXT (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetColorTableParameterfvEXT (GLenum target, GLenum pname, GLfloat *params); +#endif +#endif /* GL_EXT_paletted_texture */ + +#ifndef GL_EXT_pixel_buffer_object +#define GL_EXT_pixel_buffer_object 1 +#define GL_PIXEL_PACK_BUFFER_EXT 0x88EB +#define GL_PIXEL_UNPACK_BUFFER_EXT 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING_EXT 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING_EXT 0x88EF +#endif /* GL_EXT_pixel_buffer_object */ + +#ifndef GL_EXT_pixel_transform +#define GL_EXT_pixel_transform 1 +#define GL_PIXEL_TRANSFORM_2D_EXT 0x8330 +#define GL_PIXEL_MAG_FILTER_EXT 0x8331 +#define GL_PIXEL_MIN_FILTER_EXT 0x8332 +#define GL_PIXEL_CUBIC_WEIGHT_EXT 0x8333 +#define GL_CUBIC_EXT 0x8334 +#define GL_AVERAGE_EXT 0x8335 +#define GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8336 +#define GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8337 +#define GL_PIXEL_TRANSFORM_2D_MATRIX_EXT 0x8338 +typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPixelTransformParameteriEXT (GLenum target, GLenum pname, GLint param); +GLAPI void APIENTRY glPixelTransformParameterfEXT (GLenum target, GLenum pname, GLfloat param); +GLAPI void APIENTRY glPixelTransformParameterivEXT (GLenum target, GLenum pname, const GLint *params); +GLAPI void APIENTRY glPixelTransformParameterfvEXT (GLenum target, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glGetPixelTransformParameterivEXT (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetPixelTransformParameterfvEXT (GLenum target, GLenum pname, GLfloat *params); +#endif +#endif /* GL_EXT_pixel_transform */ + +#ifndef GL_EXT_pixel_transform_color_table +#define GL_EXT_pixel_transform_color_table 1 +#endif /* GL_EXT_pixel_transform_color_table */ + +#ifndef GL_EXT_point_parameters +#define GL_EXT_point_parameters 1 +#define GL_POINT_SIZE_MIN_EXT 0x8126 +#define GL_POINT_SIZE_MAX_EXT 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128 +#define GL_DISTANCE_ATTENUATION_EXT 0x8129 +typedef void (APIENTRYP PFNGLPOINTPARAMETERFEXTPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLPOINTPARAMETERFVEXTPROC) (GLenum pname, const GLfloat *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPointParameterfEXT (GLenum pname, GLfloat param); +GLAPI void APIENTRY glPointParameterfvEXT (GLenum pname, const GLfloat *params); +#endif +#endif /* GL_EXT_point_parameters */ + +#ifndef GL_EXT_polygon_offset +#define GL_EXT_polygon_offset 1 +#define GL_POLYGON_OFFSET_EXT 0x8037 +#define GL_POLYGON_OFFSET_FACTOR_EXT 0x8038 +#define GL_POLYGON_OFFSET_BIAS_EXT 0x8039 +typedef void (APIENTRYP PFNGLPOLYGONOFFSETEXTPROC) (GLfloat factor, GLfloat bias); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPolygonOffsetEXT (GLfloat factor, GLfloat bias); +#endif +#endif /* GL_EXT_polygon_offset */ + +#ifndef GL_EXT_provoking_vertex +#define GL_EXT_provoking_vertex 1 +#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT 0x8E4C +#define GL_FIRST_VERTEX_CONVENTION_EXT 0x8E4D +#define GL_LAST_VERTEX_CONVENTION_EXT 0x8E4E +#define GL_PROVOKING_VERTEX_EXT 0x8E4F +typedef void (APIENTRYP PFNGLPROVOKINGVERTEXEXTPROC) (GLenum mode); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glProvokingVertexEXT (GLenum mode); +#endif +#endif /* GL_EXT_provoking_vertex */ + +#ifndef GL_EXT_rescale_normal +#define GL_EXT_rescale_normal 1 +#define GL_RESCALE_NORMAL_EXT 0x803A +#endif /* GL_EXT_rescale_normal */ + +#ifndef GL_EXT_secondary_color +#define GL_EXT_secondary_color 1 +#define GL_COLOR_SUM_EXT 0x8458 +#define GL_CURRENT_SECONDARY_COLOR_EXT 0x8459 +#define GL_SECONDARY_COLOR_ARRAY_SIZE_EXT 0x845A +#define GL_SECONDARY_COLOR_ARRAY_TYPE_EXT 0x845B +#define GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT 0x845C +#define GL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D +#define GL_SECONDARY_COLOR_ARRAY_EXT 0x845E +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BEXTPROC) (GLbyte red, GLbyte green, GLbyte blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BVEXTPROC) (const GLbyte *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DEXTPROC) (GLdouble red, GLdouble green, GLdouble blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DVEXTPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FEXTPROC) (GLfloat red, GLfloat green, GLfloat blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FVEXTPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IEXTPROC) (GLint red, GLint green, GLint blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IVEXTPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SEXTPROC) (GLshort red, GLshort green, GLshort blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SVEXTPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBEXTPROC) (GLubyte red, GLubyte green, GLubyte blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBVEXTPROC) (const GLubyte *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIEXTPROC) (GLuint red, GLuint green, GLuint blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIVEXTPROC) (const GLuint *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USEXTPROC) (GLushort red, GLushort green, GLushort blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USVEXTPROC) (const GLushort *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, const void *pointer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSecondaryColor3bEXT (GLbyte red, GLbyte green, GLbyte blue); +GLAPI void APIENTRY glSecondaryColor3bvEXT (const GLbyte *v); +GLAPI void APIENTRY glSecondaryColor3dEXT (GLdouble red, GLdouble green, GLdouble blue); +GLAPI void APIENTRY glSecondaryColor3dvEXT (const GLdouble *v); +GLAPI void APIENTRY glSecondaryColor3fEXT (GLfloat red, GLfloat green, GLfloat blue); +GLAPI void APIENTRY glSecondaryColor3fvEXT (const GLfloat *v); +GLAPI void APIENTRY glSecondaryColor3iEXT (GLint red, GLint green, GLint blue); +GLAPI void APIENTRY glSecondaryColor3ivEXT (const GLint *v); +GLAPI void APIENTRY glSecondaryColor3sEXT (GLshort red, GLshort green, GLshort blue); +GLAPI void APIENTRY glSecondaryColor3svEXT (const GLshort *v); +GLAPI void APIENTRY glSecondaryColor3ubEXT (GLubyte red, GLubyte green, GLubyte blue); +GLAPI void APIENTRY glSecondaryColor3ubvEXT (const GLubyte *v); +GLAPI void APIENTRY glSecondaryColor3uiEXT (GLuint red, GLuint green, GLuint blue); +GLAPI void APIENTRY glSecondaryColor3uivEXT (const GLuint *v); +GLAPI void APIENTRY glSecondaryColor3usEXT (GLushort red, GLushort green, GLushort blue); +GLAPI void APIENTRY glSecondaryColor3usvEXT (const GLushort *v); +GLAPI void APIENTRY glSecondaryColorPointerEXT (GLint size, GLenum type, GLsizei stride, const void *pointer); +#endif +#endif /* GL_EXT_secondary_color */ + +#ifndef GL_EXT_separate_shader_objects +#define GL_EXT_separate_shader_objects 1 +#define GL_ACTIVE_PROGRAM_EXT 0x8B8D +typedef void (APIENTRYP PFNGLUSESHADERPROGRAMEXTPROC) (GLenum type, GLuint program); +typedef void (APIENTRYP PFNGLACTIVEPROGRAMEXTPROC) (GLuint program); +typedef GLuint (APIENTRYP PFNGLCREATESHADERPROGRAMEXTPROC) (GLenum type, const GLchar *string); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glUseShaderProgramEXT (GLenum type, GLuint program); +GLAPI void APIENTRY glActiveProgramEXT (GLuint program); +GLAPI GLuint APIENTRY glCreateShaderProgramEXT (GLenum type, const GLchar *string); +#endif +#endif /* GL_EXT_separate_shader_objects */ + +#ifndef GL_EXT_separate_specular_color +#define GL_EXT_separate_specular_color 1 +#define GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8 +#define GL_SINGLE_COLOR_EXT 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA +#endif /* GL_EXT_separate_specular_color */ + +#ifndef GL_EXT_shader_image_load_formatted +#define GL_EXT_shader_image_load_formatted 1 +#endif /* GL_EXT_shader_image_load_formatted */ + +#ifndef GL_EXT_shader_image_load_store +#define GL_EXT_shader_image_load_store 1 +#define GL_MAX_IMAGE_UNITS_EXT 0x8F38 +#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS_EXT 0x8F39 +#define GL_IMAGE_BINDING_NAME_EXT 0x8F3A +#define GL_IMAGE_BINDING_LEVEL_EXT 0x8F3B +#define GL_IMAGE_BINDING_LAYERED_EXT 0x8F3C +#define GL_IMAGE_BINDING_LAYER_EXT 0x8F3D +#define GL_IMAGE_BINDING_ACCESS_EXT 0x8F3E +#define GL_IMAGE_1D_EXT 0x904C +#define GL_IMAGE_2D_EXT 0x904D +#define GL_IMAGE_3D_EXT 0x904E +#define GL_IMAGE_2D_RECT_EXT 0x904F +#define GL_IMAGE_CUBE_EXT 0x9050 +#define GL_IMAGE_BUFFER_EXT 0x9051 +#define GL_IMAGE_1D_ARRAY_EXT 0x9052 +#define GL_IMAGE_2D_ARRAY_EXT 0x9053 +#define GL_IMAGE_CUBE_MAP_ARRAY_EXT 0x9054 +#define GL_IMAGE_2D_MULTISAMPLE_EXT 0x9055 +#define GL_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9056 +#define GL_INT_IMAGE_1D_EXT 0x9057 +#define GL_INT_IMAGE_2D_EXT 0x9058 +#define GL_INT_IMAGE_3D_EXT 0x9059 +#define GL_INT_IMAGE_2D_RECT_EXT 0x905A +#define GL_INT_IMAGE_CUBE_EXT 0x905B +#define GL_INT_IMAGE_BUFFER_EXT 0x905C +#define GL_INT_IMAGE_1D_ARRAY_EXT 0x905D +#define GL_INT_IMAGE_2D_ARRAY_EXT 0x905E +#define GL_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x905F +#define GL_INT_IMAGE_2D_MULTISAMPLE_EXT 0x9060 +#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9061 +#define GL_UNSIGNED_INT_IMAGE_1D_EXT 0x9062 +#define GL_UNSIGNED_INT_IMAGE_2D_EXT 0x9063 +#define GL_UNSIGNED_INT_IMAGE_3D_EXT 0x9064 +#define GL_UNSIGNED_INT_IMAGE_2D_RECT_EXT 0x9065 +#define GL_UNSIGNED_INT_IMAGE_CUBE_EXT 0x9066 +#define GL_UNSIGNED_INT_IMAGE_BUFFER_EXT 0x9067 +#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY_EXT 0x9068 +#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY_EXT 0x9069 +#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x906A +#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_EXT 0x906B +#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x906C +#define GL_MAX_IMAGE_SAMPLES_EXT 0x906D +#define GL_IMAGE_BINDING_FORMAT_EXT 0x906E +#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT_EXT 0x00000001 +#define GL_ELEMENT_ARRAY_BARRIER_BIT_EXT 0x00000002 +#define GL_UNIFORM_BARRIER_BIT_EXT 0x00000004 +#define GL_TEXTURE_FETCH_BARRIER_BIT_EXT 0x00000008 +#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT_EXT 0x00000020 +#define GL_COMMAND_BARRIER_BIT_EXT 0x00000040 +#define GL_PIXEL_BUFFER_BARRIER_BIT_EXT 0x00000080 +#define GL_TEXTURE_UPDATE_BARRIER_BIT_EXT 0x00000100 +#define GL_BUFFER_UPDATE_BARRIER_BIT_EXT 0x00000200 +#define GL_FRAMEBUFFER_BARRIER_BIT_EXT 0x00000400 +#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT_EXT 0x00000800 +#define GL_ATOMIC_COUNTER_BARRIER_BIT_EXT 0x00001000 +#define GL_ALL_BARRIER_BITS_EXT 0xFFFFFFFF +typedef void (APIENTRYP PFNGLBINDIMAGETEXTUREEXTPROC) (GLuint index, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLint format); +typedef void (APIENTRYP PFNGLMEMORYBARRIEREXTPROC) (GLbitfield barriers); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBindImageTextureEXT (GLuint index, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLint format); +GLAPI void APIENTRY glMemoryBarrierEXT (GLbitfield barriers); +#endif +#endif /* GL_EXT_shader_image_load_store */ + +#ifndef GL_EXT_shader_integer_mix +#define GL_EXT_shader_integer_mix 1 +#endif /* GL_EXT_shader_integer_mix */ + +#ifndef GL_EXT_shadow_funcs +#define GL_EXT_shadow_funcs 1 +#endif /* GL_EXT_shadow_funcs */ + +#ifndef GL_EXT_shared_texture_palette +#define GL_EXT_shared_texture_palette 1 +#define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB +#endif /* GL_EXT_shared_texture_palette */ + +#ifndef GL_EXT_stencil_clear_tag +#define GL_EXT_stencil_clear_tag 1 +#define GL_STENCIL_TAG_BITS_EXT 0x88F2 +#define GL_STENCIL_CLEAR_TAG_VALUE_EXT 0x88F3 +typedef void (APIENTRYP PFNGLSTENCILCLEARTAGEXTPROC) (GLsizei stencilTagBits, GLuint stencilClearTag); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glStencilClearTagEXT (GLsizei stencilTagBits, GLuint stencilClearTag); +#endif +#endif /* GL_EXT_stencil_clear_tag */ + +#ifndef GL_EXT_stencil_two_side +#define GL_EXT_stencil_two_side 1 +#define GL_STENCIL_TEST_TWO_SIDE_EXT 0x8910 +#define GL_ACTIVE_STENCIL_FACE_EXT 0x8911 +typedef void (APIENTRYP PFNGLACTIVESTENCILFACEEXTPROC) (GLenum face); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glActiveStencilFaceEXT (GLenum face); +#endif +#endif /* GL_EXT_stencil_two_side */ + +#ifndef GL_EXT_stencil_wrap +#define GL_EXT_stencil_wrap 1 +#define GL_INCR_WRAP_EXT 0x8507 +#define GL_DECR_WRAP_EXT 0x8508 +#endif /* GL_EXT_stencil_wrap */ + +#ifndef GL_EXT_subtexture +#define GL_EXT_subtexture 1 +typedef void (APIENTRYP PFNGLTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexSubImage1DEXT (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glTexSubImage2DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +#endif +#endif /* GL_EXT_subtexture */ + +#ifndef GL_EXT_texture +#define GL_EXT_texture 1 +#define GL_ALPHA4_EXT 0x803B +#define GL_ALPHA8_EXT 0x803C +#define GL_ALPHA12_EXT 0x803D +#define GL_ALPHA16_EXT 0x803E +#define GL_LUMINANCE4_EXT 0x803F +#define GL_LUMINANCE8_EXT 0x8040 +#define GL_LUMINANCE12_EXT 0x8041 +#define GL_LUMINANCE16_EXT 0x8042 +#define GL_LUMINANCE4_ALPHA4_EXT 0x8043 +#define GL_LUMINANCE6_ALPHA2_EXT 0x8044 +#define GL_LUMINANCE8_ALPHA8_EXT 0x8045 +#define GL_LUMINANCE12_ALPHA4_EXT 0x8046 +#define GL_LUMINANCE12_ALPHA12_EXT 0x8047 +#define GL_LUMINANCE16_ALPHA16_EXT 0x8048 +#define GL_INTENSITY_EXT 0x8049 +#define GL_INTENSITY4_EXT 0x804A +#define GL_INTENSITY8_EXT 0x804B +#define GL_INTENSITY12_EXT 0x804C +#define GL_INTENSITY16_EXT 0x804D +#define GL_RGB2_EXT 0x804E +#define GL_RGB4_EXT 0x804F +#define GL_RGB5_EXT 0x8050 +#define GL_RGB8_EXT 0x8051 +#define GL_RGB10_EXT 0x8052 +#define GL_RGB12_EXT 0x8053 +#define GL_RGB16_EXT 0x8054 +#define GL_RGBA2_EXT 0x8055 +#define GL_RGBA4_EXT 0x8056 +#define GL_RGB5_A1_EXT 0x8057 +#define GL_RGBA8_EXT 0x8058 +#define GL_RGB10_A2_EXT 0x8059 +#define GL_RGBA12_EXT 0x805A +#define GL_RGBA16_EXT 0x805B +#define GL_TEXTURE_RED_SIZE_EXT 0x805C +#define GL_TEXTURE_GREEN_SIZE_EXT 0x805D +#define GL_TEXTURE_BLUE_SIZE_EXT 0x805E +#define GL_TEXTURE_ALPHA_SIZE_EXT 0x805F +#define GL_TEXTURE_LUMINANCE_SIZE_EXT 0x8060 +#define GL_TEXTURE_INTENSITY_SIZE_EXT 0x8061 +#define GL_REPLACE_EXT 0x8062 +#define GL_PROXY_TEXTURE_1D_EXT 0x8063 +#define GL_PROXY_TEXTURE_2D_EXT 0x8064 +#define GL_TEXTURE_TOO_LARGE_EXT 0x8065 +#endif /* GL_EXT_texture */ + +#ifndef GL_EXT_texture3D +#define GL_EXT_texture3D 1 +#define GL_PACK_SKIP_IMAGES_EXT 0x806B +#define GL_PACK_IMAGE_HEIGHT_EXT 0x806C +#define GL_UNPACK_SKIP_IMAGES_EXT 0x806D +#define GL_UNPACK_IMAGE_HEIGHT_EXT 0x806E +#define GL_TEXTURE_3D_EXT 0x806F +#define GL_PROXY_TEXTURE_3D_EXT 0x8070 +#define GL_TEXTURE_DEPTH_EXT 0x8071 +#define GL_TEXTURE_WRAP_R_EXT 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE_EXT 0x8073 +typedef void (APIENTRYP PFNGLTEXIMAGE3DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexImage3DEXT (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glTexSubImage3DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); +#endif +#endif /* GL_EXT_texture3D */ + +#ifndef GL_EXT_texture_array +#define GL_EXT_texture_array 1 +#define GL_TEXTURE_1D_ARRAY_EXT 0x8C18 +#define GL_PROXY_TEXTURE_1D_ARRAY_EXT 0x8C19 +#define GL_TEXTURE_2D_ARRAY_EXT 0x8C1A +#define GL_PROXY_TEXTURE_2D_ARRAY_EXT 0x8C1B +#define GL_TEXTURE_BINDING_1D_ARRAY_EXT 0x8C1C +#define GL_TEXTURE_BINDING_2D_ARRAY_EXT 0x8C1D +#define GL_MAX_ARRAY_TEXTURE_LAYERS_EXT 0x88FF +#define GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT 0x884E +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFramebufferTextureLayerEXT (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +#endif +#endif /* GL_EXT_texture_array */ + +#ifndef GL_EXT_texture_buffer_object +#define GL_EXT_texture_buffer_object 1 +#define GL_TEXTURE_BUFFER_EXT 0x8C2A +#define GL_MAX_TEXTURE_BUFFER_SIZE_EXT 0x8C2B +#define GL_TEXTURE_BINDING_BUFFER_EXT 0x8C2C +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT 0x8C2D +#define GL_TEXTURE_BUFFER_FORMAT_EXT 0x8C2E +typedef void (APIENTRYP PFNGLTEXBUFFEREXTPROC) (GLenum target, GLenum internalformat, GLuint buffer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexBufferEXT (GLenum target, GLenum internalformat, GLuint buffer); +#endif +#endif /* GL_EXT_texture_buffer_object */ + +#ifndef GL_EXT_texture_compression_latc +#define GL_EXT_texture_compression_latc 1 +#define GL_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70 +#define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT 0x8C71 +#define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72 +#define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73 +#endif /* GL_EXT_texture_compression_latc */ + +#ifndef GL_EXT_texture_compression_rgtc +#define GL_EXT_texture_compression_rgtc 1 +#define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB +#define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC +#define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD +#define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE +#endif /* GL_EXT_texture_compression_rgtc */ + +#ifndef GL_EXT_texture_compression_s3tc +#define GL_EXT_texture_compression_s3tc 1 +#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 +#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 +#endif /* GL_EXT_texture_compression_s3tc */ + +#ifndef GL_EXT_texture_cube_map +#define GL_EXT_texture_cube_map 1 +#define GL_NORMAL_MAP_EXT 0x8511 +#define GL_REFLECTION_MAP_EXT 0x8512 +#define GL_TEXTURE_CUBE_MAP_EXT 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP_EXT 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP_EXT 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT 0x851C +#endif /* GL_EXT_texture_cube_map */ + +#ifndef GL_EXT_texture_env_add +#define GL_EXT_texture_env_add 1 +#endif /* GL_EXT_texture_env_add */ + +#ifndef GL_EXT_texture_env_combine +#define GL_EXT_texture_env_combine 1 +#define GL_COMBINE_EXT 0x8570 +#define GL_COMBINE_RGB_EXT 0x8571 +#define GL_COMBINE_ALPHA_EXT 0x8572 +#define GL_RGB_SCALE_EXT 0x8573 +#define GL_ADD_SIGNED_EXT 0x8574 +#define GL_INTERPOLATE_EXT 0x8575 +#define GL_CONSTANT_EXT 0x8576 +#define GL_PRIMARY_COLOR_EXT 0x8577 +#define GL_PREVIOUS_EXT 0x8578 +#define GL_SOURCE0_RGB_EXT 0x8580 +#define GL_SOURCE1_RGB_EXT 0x8581 +#define GL_SOURCE2_RGB_EXT 0x8582 +#define GL_SOURCE0_ALPHA_EXT 0x8588 +#define GL_SOURCE1_ALPHA_EXT 0x8589 +#define GL_SOURCE2_ALPHA_EXT 0x858A +#define GL_OPERAND0_RGB_EXT 0x8590 +#define GL_OPERAND1_RGB_EXT 0x8591 +#define GL_OPERAND2_RGB_EXT 0x8592 +#define GL_OPERAND0_ALPHA_EXT 0x8598 +#define GL_OPERAND1_ALPHA_EXT 0x8599 +#define GL_OPERAND2_ALPHA_EXT 0x859A +#endif /* GL_EXT_texture_env_combine */ + +#ifndef GL_EXT_texture_env_dot3 +#define GL_EXT_texture_env_dot3 1 +#define GL_DOT3_RGB_EXT 0x8740 +#define GL_DOT3_RGBA_EXT 0x8741 +#endif /* GL_EXT_texture_env_dot3 */ + +#ifndef GL_EXT_texture_filter_anisotropic +#define GL_EXT_texture_filter_anisotropic 1 +#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE +#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF +#endif /* GL_EXT_texture_filter_anisotropic */ + +#ifndef GL_EXT_texture_integer +#define GL_EXT_texture_integer 1 +#define GL_RGBA32UI_EXT 0x8D70 +#define GL_RGB32UI_EXT 0x8D71 +#define GL_ALPHA32UI_EXT 0x8D72 +#define GL_INTENSITY32UI_EXT 0x8D73 +#define GL_LUMINANCE32UI_EXT 0x8D74 +#define GL_LUMINANCE_ALPHA32UI_EXT 0x8D75 +#define GL_RGBA16UI_EXT 0x8D76 +#define GL_RGB16UI_EXT 0x8D77 +#define GL_ALPHA16UI_EXT 0x8D78 +#define GL_INTENSITY16UI_EXT 0x8D79 +#define GL_LUMINANCE16UI_EXT 0x8D7A +#define GL_LUMINANCE_ALPHA16UI_EXT 0x8D7B +#define GL_RGBA8UI_EXT 0x8D7C +#define GL_RGB8UI_EXT 0x8D7D +#define GL_ALPHA8UI_EXT 0x8D7E +#define GL_INTENSITY8UI_EXT 0x8D7F +#define GL_LUMINANCE8UI_EXT 0x8D80 +#define GL_LUMINANCE_ALPHA8UI_EXT 0x8D81 +#define GL_RGBA32I_EXT 0x8D82 +#define GL_RGB32I_EXT 0x8D83 +#define GL_ALPHA32I_EXT 0x8D84 +#define GL_INTENSITY32I_EXT 0x8D85 +#define GL_LUMINANCE32I_EXT 0x8D86 +#define GL_LUMINANCE_ALPHA32I_EXT 0x8D87 +#define GL_RGBA16I_EXT 0x8D88 +#define GL_RGB16I_EXT 0x8D89 +#define GL_ALPHA16I_EXT 0x8D8A +#define GL_INTENSITY16I_EXT 0x8D8B +#define GL_LUMINANCE16I_EXT 0x8D8C +#define GL_LUMINANCE_ALPHA16I_EXT 0x8D8D +#define GL_RGBA8I_EXT 0x8D8E +#define GL_RGB8I_EXT 0x8D8F +#define GL_ALPHA8I_EXT 0x8D90 +#define GL_INTENSITY8I_EXT 0x8D91 +#define GL_LUMINANCE8I_EXT 0x8D92 +#define GL_LUMINANCE_ALPHA8I_EXT 0x8D93 +#define GL_RED_INTEGER_EXT 0x8D94 +#define GL_GREEN_INTEGER_EXT 0x8D95 +#define GL_BLUE_INTEGER_EXT 0x8D96 +#define GL_ALPHA_INTEGER_EXT 0x8D97 +#define GL_RGB_INTEGER_EXT 0x8D98 +#define GL_RGBA_INTEGER_EXT 0x8D99 +#define GL_BGR_INTEGER_EXT 0x8D9A +#define GL_BGRA_INTEGER_EXT 0x8D9B +#define GL_LUMINANCE_INTEGER_EXT 0x8D9C +#define GL_LUMINANCE_ALPHA_INTEGER_EXT 0x8D9D +#define GL_RGBA_INTEGER_MODE_EXT 0x8D9E +typedef void (APIENTRYP PFNGLTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, const GLuint *params); +typedef void (APIENTRYP PFNGLGETTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, GLuint *params); +typedef void (APIENTRYP PFNGLCLEARCOLORIIEXTPROC) (GLint red, GLint green, GLint blue, GLint alpha); +typedef void (APIENTRYP PFNGLCLEARCOLORIUIEXTPROC) (GLuint red, GLuint green, GLuint blue, GLuint alpha); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexParameterIivEXT (GLenum target, GLenum pname, const GLint *params); +GLAPI void APIENTRY glTexParameterIuivEXT (GLenum target, GLenum pname, const GLuint *params); +GLAPI void APIENTRY glGetTexParameterIivEXT (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetTexParameterIuivEXT (GLenum target, GLenum pname, GLuint *params); +GLAPI void APIENTRY glClearColorIiEXT (GLint red, GLint green, GLint blue, GLint alpha); +GLAPI void APIENTRY glClearColorIuiEXT (GLuint red, GLuint green, GLuint blue, GLuint alpha); +#endif +#endif /* GL_EXT_texture_integer */ + +#ifndef GL_EXT_texture_lod_bias +#define GL_EXT_texture_lod_bias 1 +#define GL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD +#define GL_TEXTURE_FILTER_CONTROL_EXT 0x8500 +#define GL_TEXTURE_LOD_BIAS_EXT 0x8501 +#endif /* GL_EXT_texture_lod_bias */ + +#ifndef GL_EXT_texture_mirror_clamp +#define GL_EXT_texture_mirror_clamp 1 +#define GL_MIRROR_CLAMP_EXT 0x8742 +#define GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743 +#define GL_MIRROR_CLAMP_TO_BORDER_EXT 0x8912 +#endif /* GL_EXT_texture_mirror_clamp */ + +#ifndef GL_EXT_texture_object +#define GL_EXT_texture_object 1 +#define GL_TEXTURE_PRIORITY_EXT 0x8066 +#define GL_TEXTURE_RESIDENT_EXT 0x8067 +#define GL_TEXTURE_1D_BINDING_EXT 0x8068 +#define GL_TEXTURE_2D_BINDING_EXT 0x8069 +#define GL_TEXTURE_3D_BINDING_EXT 0x806A +typedef GLboolean (APIENTRYP PFNGLARETEXTURESRESIDENTEXTPROC) (GLsizei n, const GLuint *textures, GLboolean *residences); +typedef void (APIENTRYP PFNGLBINDTEXTUREEXTPROC) (GLenum target, GLuint texture); +typedef void (APIENTRYP PFNGLDELETETEXTURESEXTPROC) (GLsizei n, const GLuint *textures); +typedef void (APIENTRYP PFNGLGENTEXTURESEXTPROC) (GLsizei n, GLuint *textures); +typedef GLboolean (APIENTRYP PFNGLISTEXTUREEXTPROC) (GLuint texture); +typedef void (APIENTRYP PFNGLPRIORITIZETEXTURESEXTPROC) (GLsizei n, const GLuint *textures, const GLclampf *priorities); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLboolean APIENTRY glAreTexturesResidentEXT (GLsizei n, const GLuint *textures, GLboolean *residences); +GLAPI void APIENTRY glBindTextureEXT (GLenum target, GLuint texture); +GLAPI void APIENTRY glDeleteTexturesEXT (GLsizei n, const GLuint *textures); +GLAPI void APIENTRY glGenTexturesEXT (GLsizei n, GLuint *textures); +GLAPI GLboolean APIENTRY glIsTextureEXT (GLuint texture); +GLAPI void APIENTRY glPrioritizeTexturesEXT (GLsizei n, const GLuint *textures, const GLclampf *priorities); +#endif +#endif /* GL_EXT_texture_object */ + +#ifndef GL_EXT_texture_perturb_normal +#define GL_EXT_texture_perturb_normal 1 +#define GL_PERTURB_EXT 0x85AE +#define GL_TEXTURE_NORMAL_EXT 0x85AF +typedef void (APIENTRYP PFNGLTEXTURENORMALEXTPROC) (GLenum mode); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTextureNormalEXT (GLenum mode); +#endif +#endif /* GL_EXT_texture_perturb_normal */ + +#ifndef GL_EXT_texture_sRGB +#define GL_EXT_texture_sRGB 1 +#define GL_SRGB_EXT 0x8C40 +#define GL_SRGB8_EXT 0x8C41 +#define GL_SRGB_ALPHA_EXT 0x8C42 +#define GL_SRGB8_ALPHA8_EXT 0x8C43 +#define GL_SLUMINANCE_ALPHA_EXT 0x8C44 +#define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45 +#define GL_SLUMINANCE_EXT 0x8C46 +#define GL_SLUMINANCE8_EXT 0x8C47 +#define GL_COMPRESSED_SRGB_EXT 0x8C48 +#define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49 +#define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A +#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B +#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F +#endif /* GL_EXT_texture_sRGB */ + +#ifndef GL_EXT_texture_sRGB_decode +#define GL_EXT_texture_sRGB_decode 1 +#define GL_TEXTURE_SRGB_DECODE_EXT 0x8A48 +#define GL_DECODE_EXT 0x8A49 +#define GL_SKIP_DECODE_EXT 0x8A4A +#endif /* GL_EXT_texture_sRGB_decode */ + +#ifndef GL_EXT_texture_shared_exponent +#define GL_EXT_texture_shared_exponent 1 +#define GL_RGB9_E5_EXT 0x8C3D +#define GL_UNSIGNED_INT_5_9_9_9_REV_EXT 0x8C3E +#define GL_TEXTURE_SHARED_SIZE_EXT 0x8C3F +#endif /* GL_EXT_texture_shared_exponent */ + +#ifndef GL_EXT_texture_snorm +#define GL_EXT_texture_snorm 1 +#define GL_ALPHA_SNORM 0x9010 +#define GL_LUMINANCE_SNORM 0x9011 +#define GL_LUMINANCE_ALPHA_SNORM 0x9012 +#define GL_INTENSITY_SNORM 0x9013 +#define GL_ALPHA8_SNORM 0x9014 +#define GL_LUMINANCE8_SNORM 0x9015 +#define GL_LUMINANCE8_ALPHA8_SNORM 0x9016 +#define GL_INTENSITY8_SNORM 0x9017 +#define GL_ALPHA16_SNORM 0x9018 +#define GL_LUMINANCE16_SNORM 0x9019 +#define GL_LUMINANCE16_ALPHA16_SNORM 0x901A +#define GL_INTENSITY16_SNORM 0x901B +#define GL_RED_SNORM 0x8F90 +#define GL_RG_SNORM 0x8F91 +#define GL_RGB_SNORM 0x8F92 +#define GL_RGBA_SNORM 0x8F93 +#endif /* GL_EXT_texture_snorm */ + +#ifndef GL_EXT_texture_swizzle +#define GL_EXT_texture_swizzle 1 +#define GL_TEXTURE_SWIZZLE_R_EXT 0x8E42 +#define GL_TEXTURE_SWIZZLE_G_EXT 0x8E43 +#define GL_TEXTURE_SWIZZLE_B_EXT 0x8E44 +#define GL_TEXTURE_SWIZZLE_A_EXT 0x8E45 +#define GL_TEXTURE_SWIZZLE_RGBA_EXT 0x8E46 +#endif /* GL_EXT_texture_swizzle */ + +#ifndef GL_EXT_timer_query +#define GL_EXT_timer_query 1 +#define GL_TIME_ELAPSED_EXT 0x88BF +typedef void (APIENTRYP PFNGLGETQUERYOBJECTI64VEXTPROC) (GLuint id, GLenum pname, GLint64 *params); +typedef void (APIENTRYP PFNGLGETQUERYOBJECTUI64VEXTPROC) (GLuint id, GLenum pname, GLuint64 *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGetQueryObjecti64vEXT (GLuint id, GLenum pname, GLint64 *params); +GLAPI void APIENTRY glGetQueryObjectui64vEXT (GLuint id, GLenum pname, GLuint64 *params); +#endif +#endif /* GL_EXT_timer_query */ + +#ifndef GL_EXT_transform_feedback +#define GL_EXT_transform_feedback 1 +#define GL_TRANSFORM_FEEDBACK_BUFFER_EXT 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_START_EXT 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_EXT 0x8C85 +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_EXT 0x8C8F +#define GL_INTERLEAVED_ATTRIBS_EXT 0x8C8C +#define GL_SEPARATE_ATTRIBS_EXT 0x8C8D +#define GL_PRIMITIVES_GENERATED_EXT 0x8C87 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT 0x8C88 +#define GL_RASTERIZER_DISCARD_EXT 0x8C89 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT 0x8C8B +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT 0x8C80 +#define GL_TRANSFORM_FEEDBACK_VARYINGS_EXT 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_EXT 0x8C7F +#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH_EXT 0x8C76 +typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKEXTPROC) (GLenum primitiveMode); +typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKEXTPROC) (void); +typedef void (APIENTRYP PFNGLBINDBUFFERRANGEEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (APIENTRYP PFNGLBINDBUFFEROFFSETEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset); +typedef void (APIENTRYP PFNGLBINDBUFFERBASEEXTPROC) (GLenum target, GLuint index, GLuint buffer); +typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC) (GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode); +typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBeginTransformFeedbackEXT (GLenum primitiveMode); +GLAPI void APIENTRY glEndTransformFeedbackEXT (void); +GLAPI void APIENTRY glBindBufferRangeEXT (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +GLAPI void APIENTRY glBindBufferOffsetEXT (GLenum target, GLuint index, GLuint buffer, GLintptr offset); +GLAPI void APIENTRY glBindBufferBaseEXT (GLenum target, GLuint index, GLuint buffer); +GLAPI void APIENTRY glTransformFeedbackVaryingsEXT (GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode); +GLAPI void APIENTRY glGetTransformFeedbackVaryingEXT (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); +#endif +#endif /* GL_EXT_transform_feedback */ + +#ifndef GL_EXT_vertex_array +#define GL_EXT_vertex_array 1 +#define GL_VERTEX_ARRAY_EXT 0x8074 +#define GL_NORMAL_ARRAY_EXT 0x8075 +#define GL_COLOR_ARRAY_EXT 0x8076 +#define GL_INDEX_ARRAY_EXT 0x8077 +#define GL_TEXTURE_COORD_ARRAY_EXT 0x8078 +#define GL_EDGE_FLAG_ARRAY_EXT 0x8079 +#define GL_VERTEX_ARRAY_SIZE_EXT 0x807A +#define GL_VERTEX_ARRAY_TYPE_EXT 0x807B +#define GL_VERTEX_ARRAY_STRIDE_EXT 0x807C +#define GL_VERTEX_ARRAY_COUNT_EXT 0x807D +#define GL_NORMAL_ARRAY_TYPE_EXT 0x807E +#define GL_NORMAL_ARRAY_STRIDE_EXT 0x807F +#define GL_NORMAL_ARRAY_COUNT_EXT 0x8080 +#define GL_COLOR_ARRAY_SIZE_EXT 0x8081 +#define GL_COLOR_ARRAY_TYPE_EXT 0x8082 +#define GL_COLOR_ARRAY_STRIDE_EXT 0x8083 +#define GL_COLOR_ARRAY_COUNT_EXT 0x8084 +#define GL_INDEX_ARRAY_TYPE_EXT 0x8085 +#define GL_INDEX_ARRAY_STRIDE_EXT 0x8086 +#define GL_INDEX_ARRAY_COUNT_EXT 0x8087 +#define GL_TEXTURE_COORD_ARRAY_SIZE_EXT 0x8088 +#define GL_TEXTURE_COORD_ARRAY_TYPE_EXT 0x8089 +#define GL_TEXTURE_COORD_ARRAY_STRIDE_EXT 0x808A +#define GL_TEXTURE_COORD_ARRAY_COUNT_EXT 0x808B +#define GL_EDGE_FLAG_ARRAY_STRIDE_EXT 0x808C +#define GL_EDGE_FLAG_ARRAY_COUNT_EXT 0x808D +#define GL_VERTEX_ARRAY_POINTER_EXT 0x808E +#define GL_NORMAL_ARRAY_POINTER_EXT 0x808F +#define GL_COLOR_ARRAY_POINTER_EXT 0x8090 +#define GL_INDEX_ARRAY_POINTER_EXT 0x8091 +#define GL_TEXTURE_COORD_ARRAY_POINTER_EXT 0x8092 +#define GL_EDGE_FLAG_ARRAY_POINTER_EXT 0x8093 +typedef void (APIENTRYP PFNGLARRAYELEMENTEXTPROC) (GLint i); +typedef void (APIENTRYP PFNGLCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const void *pointer); +typedef void (APIENTRYP PFNGLDRAWARRAYSEXTPROC) (GLenum mode, GLint first, GLsizei count); +typedef void (APIENTRYP PFNGLEDGEFLAGPOINTEREXTPROC) (GLsizei stride, GLsizei count, const GLboolean *pointer); +typedef void (APIENTRYP PFNGLGETPOINTERVEXTPROC) (GLenum pname, void **params); +typedef void (APIENTRYP PFNGLINDEXPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const void *pointer); +typedef void (APIENTRYP PFNGLNORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const void *pointer); +typedef void (APIENTRYP PFNGLTEXCOORDPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const void *pointer); +typedef void (APIENTRYP PFNGLVERTEXPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const void *pointer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glArrayElementEXT (GLint i); +GLAPI void APIENTRY glColorPointerEXT (GLint size, GLenum type, GLsizei stride, GLsizei count, const void *pointer); +GLAPI void APIENTRY glDrawArraysEXT (GLenum mode, GLint first, GLsizei count); +GLAPI void APIENTRY glEdgeFlagPointerEXT (GLsizei stride, GLsizei count, const GLboolean *pointer); +GLAPI void APIENTRY glGetPointervEXT (GLenum pname, void **params); +GLAPI void APIENTRY glIndexPointerEXT (GLenum type, GLsizei stride, GLsizei count, const void *pointer); +GLAPI void APIENTRY glNormalPointerEXT (GLenum type, GLsizei stride, GLsizei count, const void *pointer); +GLAPI void APIENTRY glTexCoordPointerEXT (GLint size, GLenum type, GLsizei stride, GLsizei count, const void *pointer); +GLAPI void APIENTRY glVertexPointerEXT (GLint size, GLenum type, GLsizei stride, GLsizei count, const void *pointer); +#endif +#endif /* GL_EXT_vertex_array */ + +#ifndef GL_EXT_vertex_array_bgra +#define GL_EXT_vertex_array_bgra 1 +#endif /* GL_EXT_vertex_array_bgra */ + +#ifndef GL_EXT_vertex_attrib_64bit +#define GL_EXT_vertex_attrib_64bit 1 +#define GL_DOUBLE_VEC2_EXT 0x8FFC +#define GL_DOUBLE_VEC3_EXT 0x8FFD +#define GL_DOUBLE_VEC4_EXT 0x8FFE +#define GL_DOUBLE_MAT2_EXT 0x8F46 +#define GL_DOUBLE_MAT3_EXT 0x8F47 +#define GL_DOUBLE_MAT4_EXT 0x8F48 +#define GL_DOUBLE_MAT2x3_EXT 0x8F49 +#define GL_DOUBLE_MAT2x4_EXT 0x8F4A +#define GL_DOUBLE_MAT3x2_EXT 0x8F4B +#define GL_DOUBLE_MAT3x4_EXT 0x8F4C +#define GL_DOUBLE_MAT4x2_EXT 0x8F4D +#define GL_DOUBLE_MAT4x3_EXT 0x8F4E +typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DEXTPROC) (GLuint index, GLdouble x); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DEXTPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DEXTPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DEXTPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DVEXTPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DVEXTPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DVEXTPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DVEXTPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBLPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLDVEXTPROC) (GLuint index, GLenum pname, GLdouble *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexAttribL1dEXT (GLuint index, GLdouble x); +GLAPI void APIENTRY glVertexAttribL2dEXT (GLuint index, GLdouble x, GLdouble y); +GLAPI void APIENTRY glVertexAttribL3dEXT (GLuint index, GLdouble x, GLdouble y, GLdouble z); +GLAPI void APIENTRY glVertexAttribL4dEXT (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void APIENTRY glVertexAttribL1dvEXT (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttribL2dvEXT (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttribL3dvEXT (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttribL4dvEXT (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttribLPointerEXT (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); +GLAPI void APIENTRY glGetVertexAttribLdvEXT (GLuint index, GLenum pname, GLdouble *params); +#endif +#endif /* GL_EXT_vertex_attrib_64bit */ + +#ifndef GL_EXT_vertex_shader +#define GL_EXT_vertex_shader 1 +#define GL_VERTEX_SHADER_EXT 0x8780 +#define GL_VERTEX_SHADER_BINDING_EXT 0x8781 +#define GL_OP_INDEX_EXT 0x8782 +#define GL_OP_NEGATE_EXT 0x8783 +#define GL_OP_DOT3_EXT 0x8784 +#define GL_OP_DOT4_EXT 0x8785 +#define GL_OP_MUL_EXT 0x8786 +#define GL_OP_ADD_EXT 0x8787 +#define GL_OP_MADD_EXT 0x8788 +#define GL_OP_FRAC_EXT 0x8789 +#define GL_OP_MAX_EXT 0x878A +#define GL_OP_MIN_EXT 0x878B +#define GL_OP_SET_GE_EXT 0x878C +#define GL_OP_SET_LT_EXT 0x878D +#define GL_OP_CLAMP_EXT 0x878E +#define GL_OP_FLOOR_EXT 0x878F +#define GL_OP_ROUND_EXT 0x8790 +#define GL_OP_EXP_BASE_2_EXT 0x8791 +#define GL_OP_LOG_BASE_2_EXT 0x8792 +#define GL_OP_POWER_EXT 0x8793 +#define GL_OP_RECIP_EXT 0x8794 +#define GL_OP_RECIP_SQRT_EXT 0x8795 +#define GL_OP_SUB_EXT 0x8796 +#define GL_OP_CROSS_PRODUCT_EXT 0x8797 +#define GL_OP_MULTIPLY_MATRIX_EXT 0x8798 +#define GL_OP_MOV_EXT 0x8799 +#define GL_OUTPUT_VERTEX_EXT 0x879A +#define GL_OUTPUT_COLOR0_EXT 0x879B +#define GL_OUTPUT_COLOR1_EXT 0x879C +#define GL_OUTPUT_TEXTURE_COORD0_EXT 0x879D +#define GL_OUTPUT_TEXTURE_COORD1_EXT 0x879E +#define GL_OUTPUT_TEXTURE_COORD2_EXT 0x879F +#define GL_OUTPUT_TEXTURE_COORD3_EXT 0x87A0 +#define GL_OUTPUT_TEXTURE_COORD4_EXT 0x87A1 +#define GL_OUTPUT_TEXTURE_COORD5_EXT 0x87A2 +#define GL_OUTPUT_TEXTURE_COORD6_EXT 0x87A3 +#define GL_OUTPUT_TEXTURE_COORD7_EXT 0x87A4 +#define GL_OUTPUT_TEXTURE_COORD8_EXT 0x87A5 +#define GL_OUTPUT_TEXTURE_COORD9_EXT 0x87A6 +#define GL_OUTPUT_TEXTURE_COORD10_EXT 0x87A7 +#define GL_OUTPUT_TEXTURE_COORD11_EXT 0x87A8 +#define GL_OUTPUT_TEXTURE_COORD12_EXT 0x87A9 +#define GL_OUTPUT_TEXTURE_COORD13_EXT 0x87AA +#define GL_OUTPUT_TEXTURE_COORD14_EXT 0x87AB +#define GL_OUTPUT_TEXTURE_COORD15_EXT 0x87AC +#define GL_OUTPUT_TEXTURE_COORD16_EXT 0x87AD +#define GL_OUTPUT_TEXTURE_COORD17_EXT 0x87AE +#define GL_OUTPUT_TEXTURE_COORD18_EXT 0x87AF +#define GL_OUTPUT_TEXTURE_COORD19_EXT 0x87B0 +#define GL_OUTPUT_TEXTURE_COORD20_EXT 0x87B1 +#define GL_OUTPUT_TEXTURE_COORD21_EXT 0x87B2 +#define GL_OUTPUT_TEXTURE_COORD22_EXT 0x87B3 +#define GL_OUTPUT_TEXTURE_COORD23_EXT 0x87B4 +#define GL_OUTPUT_TEXTURE_COORD24_EXT 0x87B5 +#define GL_OUTPUT_TEXTURE_COORD25_EXT 0x87B6 +#define GL_OUTPUT_TEXTURE_COORD26_EXT 0x87B7 +#define GL_OUTPUT_TEXTURE_COORD27_EXT 0x87B8 +#define GL_OUTPUT_TEXTURE_COORD28_EXT 0x87B9 +#define GL_OUTPUT_TEXTURE_COORD29_EXT 0x87BA +#define GL_OUTPUT_TEXTURE_COORD30_EXT 0x87BB +#define GL_OUTPUT_TEXTURE_COORD31_EXT 0x87BC +#define GL_OUTPUT_FOG_EXT 0x87BD +#define GL_SCALAR_EXT 0x87BE +#define GL_VECTOR_EXT 0x87BF +#define GL_MATRIX_EXT 0x87C0 +#define GL_VARIANT_EXT 0x87C1 +#define GL_INVARIANT_EXT 0x87C2 +#define GL_LOCAL_CONSTANT_EXT 0x87C3 +#define GL_LOCAL_EXT 0x87C4 +#define GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87C5 +#define GL_MAX_VERTEX_SHADER_VARIANTS_EXT 0x87C6 +#define GL_MAX_VERTEX_SHADER_INVARIANTS_EXT 0x87C7 +#define GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87C8 +#define GL_MAX_VERTEX_SHADER_LOCALS_EXT 0x87C9 +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CA +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT 0x87CB +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87CC +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT 0x87CD +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT 0x87CE +#define GL_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CF +#define GL_VERTEX_SHADER_VARIANTS_EXT 0x87D0 +#define GL_VERTEX_SHADER_INVARIANTS_EXT 0x87D1 +#define GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87D2 +#define GL_VERTEX_SHADER_LOCALS_EXT 0x87D3 +#define GL_VERTEX_SHADER_OPTIMIZED_EXT 0x87D4 +#define GL_X_EXT 0x87D5 +#define GL_Y_EXT 0x87D6 +#define GL_Z_EXT 0x87D7 +#define GL_W_EXT 0x87D8 +#define GL_NEGATIVE_X_EXT 0x87D9 +#define GL_NEGATIVE_Y_EXT 0x87DA +#define GL_NEGATIVE_Z_EXT 0x87DB +#define GL_NEGATIVE_W_EXT 0x87DC +#define GL_ZERO_EXT 0x87DD +#define GL_ONE_EXT 0x87DE +#define GL_NEGATIVE_ONE_EXT 0x87DF +#define GL_NORMALIZED_RANGE_EXT 0x87E0 +#define GL_FULL_RANGE_EXT 0x87E1 +#define GL_CURRENT_VERTEX_EXT 0x87E2 +#define GL_MVP_MATRIX_EXT 0x87E3 +#define GL_VARIANT_VALUE_EXT 0x87E4 +#define GL_VARIANT_DATATYPE_EXT 0x87E5 +#define GL_VARIANT_ARRAY_STRIDE_EXT 0x87E6 +#define GL_VARIANT_ARRAY_TYPE_EXT 0x87E7 +#define GL_VARIANT_ARRAY_EXT 0x87E8 +#define GL_VARIANT_ARRAY_POINTER_EXT 0x87E9 +#define GL_INVARIANT_VALUE_EXT 0x87EA +#define GL_INVARIANT_DATATYPE_EXT 0x87EB +#define GL_LOCAL_CONSTANT_VALUE_EXT 0x87EC +#define GL_LOCAL_CONSTANT_DATATYPE_EXT 0x87ED +typedef void (APIENTRYP PFNGLBEGINVERTEXSHADEREXTPROC) (void); +typedef void (APIENTRYP PFNGLENDVERTEXSHADEREXTPROC) (void); +typedef void (APIENTRYP PFNGLBINDVERTEXSHADEREXTPROC) (GLuint id); +typedef GLuint (APIENTRYP PFNGLGENVERTEXSHADERSEXTPROC) (GLuint range); +typedef void (APIENTRYP PFNGLDELETEVERTEXSHADEREXTPROC) (GLuint id); +typedef void (APIENTRYP PFNGLSHADEROP1EXTPROC) (GLenum op, GLuint res, GLuint arg1); +typedef void (APIENTRYP PFNGLSHADEROP2EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2); +typedef void (APIENTRYP PFNGLSHADEROP3EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3); +typedef void (APIENTRYP PFNGLSWIZZLEEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); +typedef void (APIENTRYP PFNGLWRITEMASKEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); +typedef void (APIENTRYP PFNGLINSERTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); +typedef void (APIENTRYP PFNGLEXTRACTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); +typedef GLuint (APIENTRYP PFNGLGENSYMBOLSEXTPROC) (GLenum datatype, GLenum storagetype, GLenum range, GLuint components); +typedef void (APIENTRYP PFNGLSETINVARIANTEXTPROC) (GLuint id, GLenum type, const void *addr); +typedef void (APIENTRYP PFNGLSETLOCALCONSTANTEXTPROC) (GLuint id, GLenum type, const void *addr); +typedef void (APIENTRYP PFNGLVARIANTBVEXTPROC) (GLuint id, const GLbyte *addr); +typedef void (APIENTRYP PFNGLVARIANTSVEXTPROC) (GLuint id, const GLshort *addr); +typedef void (APIENTRYP PFNGLVARIANTIVEXTPROC) (GLuint id, const GLint *addr); +typedef void (APIENTRYP PFNGLVARIANTFVEXTPROC) (GLuint id, const GLfloat *addr); +typedef void (APIENTRYP PFNGLVARIANTDVEXTPROC) (GLuint id, const GLdouble *addr); +typedef void (APIENTRYP PFNGLVARIANTUBVEXTPROC) (GLuint id, const GLubyte *addr); +typedef void (APIENTRYP PFNGLVARIANTUSVEXTPROC) (GLuint id, const GLushort *addr); +typedef void (APIENTRYP PFNGLVARIANTUIVEXTPROC) (GLuint id, const GLuint *addr); +typedef void (APIENTRYP PFNGLVARIANTPOINTEREXTPROC) (GLuint id, GLenum type, GLuint stride, const void *addr); +typedef void (APIENTRYP PFNGLENABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); +typedef void (APIENTRYP PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); +typedef GLuint (APIENTRYP PFNGLBINDLIGHTPARAMETEREXTPROC) (GLenum light, GLenum value); +typedef GLuint (APIENTRYP PFNGLBINDMATERIALPARAMETEREXTPROC) (GLenum face, GLenum value); +typedef GLuint (APIENTRYP PFNGLBINDTEXGENPARAMETEREXTPROC) (GLenum unit, GLenum coord, GLenum value); +typedef GLuint (APIENTRYP PFNGLBINDTEXTUREUNITPARAMETEREXTPROC) (GLenum unit, GLenum value); +typedef GLuint (APIENTRYP PFNGLBINDPARAMETEREXTPROC) (GLenum value); +typedef GLboolean (APIENTRYP PFNGLISVARIANTENABLEDEXTPROC) (GLuint id, GLenum cap); +typedef void (APIENTRYP PFNGLGETVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); +typedef void (APIENTRYP PFNGLGETVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); +typedef void (APIENTRYP PFNGLGETVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); +typedef void (APIENTRYP PFNGLGETVARIANTPOINTERVEXTPROC) (GLuint id, GLenum value, void **data); +typedef void (APIENTRYP PFNGLGETINVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); +typedef void (APIENTRYP PFNGLGETINVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); +typedef void (APIENTRYP PFNGLGETINVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); +typedef void (APIENTRYP PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); +typedef void (APIENTRYP PFNGLGETLOCALCONSTANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); +typedef void (APIENTRYP PFNGLGETLOCALCONSTANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBeginVertexShaderEXT (void); +GLAPI void APIENTRY glEndVertexShaderEXT (void); +GLAPI void APIENTRY glBindVertexShaderEXT (GLuint id); +GLAPI GLuint APIENTRY glGenVertexShadersEXT (GLuint range); +GLAPI void APIENTRY glDeleteVertexShaderEXT (GLuint id); +GLAPI void APIENTRY glShaderOp1EXT (GLenum op, GLuint res, GLuint arg1); +GLAPI void APIENTRY glShaderOp2EXT (GLenum op, GLuint res, GLuint arg1, GLuint arg2); +GLAPI void APIENTRY glShaderOp3EXT (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3); +GLAPI void APIENTRY glSwizzleEXT (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); +GLAPI void APIENTRY glWriteMaskEXT (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); +GLAPI void APIENTRY glInsertComponentEXT (GLuint res, GLuint src, GLuint num); +GLAPI void APIENTRY glExtractComponentEXT (GLuint res, GLuint src, GLuint num); +GLAPI GLuint APIENTRY glGenSymbolsEXT (GLenum datatype, GLenum storagetype, GLenum range, GLuint components); +GLAPI void APIENTRY glSetInvariantEXT (GLuint id, GLenum type, const void *addr); +GLAPI void APIENTRY glSetLocalConstantEXT (GLuint id, GLenum type, const void *addr); +GLAPI void APIENTRY glVariantbvEXT (GLuint id, const GLbyte *addr); +GLAPI void APIENTRY glVariantsvEXT (GLuint id, const GLshort *addr); +GLAPI void APIENTRY glVariantivEXT (GLuint id, const GLint *addr); +GLAPI void APIENTRY glVariantfvEXT (GLuint id, const GLfloat *addr); +GLAPI void APIENTRY glVariantdvEXT (GLuint id, const GLdouble *addr); +GLAPI void APIENTRY glVariantubvEXT (GLuint id, const GLubyte *addr); +GLAPI void APIENTRY glVariantusvEXT (GLuint id, const GLushort *addr); +GLAPI void APIENTRY glVariantuivEXT (GLuint id, const GLuint *addr); +GLAPI void APIENTRY glVariantPointerEXT (GLuint id, GLenum type, GLuint stride, const void *addr); +GLAPI void APIENTRY glEnableVariantClientStateEXT (GLuint id); +GLAPI void APIENTRY glDisableVariantClientStateEXT (GLuint id); +GLAPI GLuint APIENTRY glBindLightParameterEXT (GLenum light, GLenum value); +GLAPI GLuint APIENTRY glBindMaterialParameterEXT (GLenum face, GLenum value); +GLAPI GLuint APIENTRY glBindTexGenParameterEXT (GLenum unit, GLenum coord, GLenum value); +GLAPI GLuint APIENTRY glBindTextureUnitParameterEXT (GLenum unit, GLenum value); +GLAPI GLuint APIENTRY glBindParameterEXT (GLenum value); +GLAPI GLboolean APIENTRY glIsVariantEnabledEXT (GLuint id, GLenum cap); +GLAPI void APIENTRY glGetVariantBooleanvEXT (GLuint id, GLenum value, GLboolean *data); +GLAPI void APIENTRY glGetVariantIntegervEXT (GLuint id, GLenum value, GLint *data); +GLAPI void APIENTRY glGetVariantFloatvEXT (GLuint id, GLenum value, GLfloat *data); +GLAPI void APIENTRY glGetVariantPointervEXT (GLuint id, GLenum value, void **data); +GLAPI void APIENTRY glGetInvariantBooleanvEXT (GLuint id, GLenum value, GLboolean *data); +GLAPI void APIENTRY glGetInvariantIntegervEXT (GLuint id, GLenum value, GLint *data); +GLAPI void APIENTRY glGetInvariantFloatvEXT (GLuint id, GLenum value, GLfloat *data); +GLAPI void APIENTRY glGetLocalConstantBooleanvEXT (GLuint id, GLenum value, GLboolean *data); +GLAPI void APIENTRY glGetLocalConstantIntegervEXT (GLuint id, GLenum value, GLint *data); +GLAPI void APIENTRY glGetLocalConstantFloatvEXT (GLuint id, GLenum value, GLfloat *data); +#endif +#endif /* GL_EXT_vertex_shader */ + +#ifndef GL_EXT_vertex_weighting +#define GL_EXT_vertex_weighting 1 +#define GL_MODELVIEW0_STACK_DEPTH_EXT 0x0BA3 +#define GL_MODELVIEW1_STACK_DEPTH_EXT 0x8502 +#define GL_MODELVIEW0_MATRIX_EXT 0x0BA6 +#define GL_MODELVIEW1_MATRIX_EXT 0x8506 +#define GL_VERTEX_WEIGHTING_EXT 0x8509 +#define GL_MODELVIEW0_EXT 0x1700 +#define GL_MODELVIEW1_EXT 0x850A +#define GL_CURRENT_VERTEX_WEIGHT_EXT 0x850B +#define GL_VERTEX_WEIGHT_ARRAY_EXT 0x850C +#define GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT 0x850D +#define GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT 0x850E +#define GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT 0x850F +#define GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT 0x8510 +typedef void (APIENTRYP PFNGLVERTEXWEIGHTFEXTPROC) (GLfloat weight); +typedef void (APIENTRYP PFNGLVERTEXWEIGHTFVEXTPROC) (const GLfloat *weight); +typedef void (APIENTRYP PFNGLVERTEXWEIGHTPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, const void *pointer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexWeightfEXT (GLfloat weight); +GLAPI void APIENTRY glVertexWeightfvEXT (const GLfloat *weight); +GLAPI void APIENTRY glVertexWeightPointerEXT (GLint size, GLenum type, GLsizei stride, const void *pointer); +#endif +#endif /* GL_EXT_vertex_weighting */ + +#ifndef GL_EXT_x11_sync_object +#define GL_EXT_x11_sync_object 1 +#define GL_SYNC_X11_FENCE_EXT 0x90E1 +typedef GLsync (APIENTRYP PFNGLIMPORTSYNCEXTPROC) (GLenum external_sync_type, GLintptr external_sync, GLbitfield flags); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLsync APIENTRY glImportSyncEXT (GLenum external_sync_type, GLintptr external_sync, GLbitfield flags); +#endif +#endif /* GL_EXT_x11_sync_object */ + +#ifndef GL_GREMEDY_frame_terminator +#define GL_GREMEDY_frame_terminator 1 +typedef void (APIENTRYP PFNGLFRAMETERMINATORGREMEDYPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFrameTerminatorGREMEDY (void); +#endif +#endif /* GL_GREMEDY_frame_terminator */ + +#ifndef GL_GREMEDY_string_marker +#define GL_GREMEDY_string_marker 1 +typedef void (APIENTRYP PFNGLSTRINGMARKERGREMEDYPROC) (GLsizei len, const void *string); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glStringMarkerGREMEDY (GLsizei len, const void *string); +#endif +#endif /* GL_GREMEDY_string_marker */ + +#ifndef GL_HP_convolution_border_modes +#define GL_HP_convolution_border_modes 1 +#define GL_IGNORE_BORDER_HP 0x8150 +#define GL_CONSTANT_BORDER_HP 0x8151 +#define GL_REPLICATE_BORDER_HP 0x8153 +#define GL_CONVOLUTION_BORDER_COLOR_HP 0x8154 +#endif /* GL_HP_convolution_border_modes */ + +#ifndef GL_HP_image_transform +#define GL_HP_image_transform 1 +#define GL_IMAGE_SCALE_X_HP 0x8155 +#define GL_IMAGE_SCALE_Y_HP 0x8156 +#define GL_IMAGE_TRANSLATE_X_HP 0x8157 +#define GL_IMAGE_TRANSLATE_Y_HP 0x8158 +#define GL_IMAGE_ROTATE_ANGLE_HP 0x8159 +#define GL_IMAGE_ROTATE_ORIGIN_X_HP 0x815A +#define GL_IMAGE_ROTATE_ORIGIN_Y_HP 0x815B +#define GL_IMAGE_MAG_FILTER_HP 0x815C +#define GL_IMAGE_MIN_FILTER_HP 0x815D +#define GL_IMAGE_CUBIC_WEIGHT_HP 0x815E +#define GL_CUBIC_HP 0x815F +#define GL_AVERAGE_HP 0x8160 +#define GL_IMAGE_TRANSFORM_2D_HP 0x8161 +#define GL_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8162 +#define GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8163 +typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERIHPPROC) (GLenum target, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERFHPPROC) (GLenum target, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, GLfloat *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glImageTransformParameteriHP (GLenum target, GLenum pname, GLint param); +GLAPI void APIENTRY glImageTransformParameterfHP (GLenum target, GLenum pname, GLfloat param); +GLAPI void APIENTRY glImageTransformParameterivHP (GLenum target, GLenum pname, const GLint *params); +GLAPI void APIENTRY glImageTransformParameterfvHP (GLenum target, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glGetImageTransformParameterivHP (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetImageTransformParameterfvHP (GLenum target, GLenum pname, GLfloat *params); +#endif +#endif /* GL_HP_image_transform */ + +#ifndef GL_HP_occlusion_test +#define GL_HP_occlusion_test 1 +#define GL_OCCLUSION_TEST_HP 0x8165 +#define GL_OCCLUSION_TEST_RESULT_HP 0x8166 +#endif /* GL_HP_occlusion_test */ + +#ifndef GL_HP_texture_lighting +#define GL_HP_texture_lighting 1 +#define GL_TEXTURE_LIGHTING_MODE_HP 0x8167 +#define GL_TEXTURE_POST_SPECULAR_HP 0x8168 +#define GL_TEXTURE_PRE_SPECULAR_HP 0x8169 +#endif /* GL_HP_texture_lighting */ + +#ifndef GL_IBM_cull_vertex +#define GL_IBM_cull_vertex 1 +#define GL_CULL_VERTEX_IBM 103050 +#endif /* GL_IBM_cull_vertex */ + +#ifndef GL_IBM_multimode_draw_arrays +#define GL_IBM_multimode_draw_arrays 1 +typedef void (APIENTRYP PFNGLMULTIMODEDRAWARRAYSIBMPROC) (const GLenum *mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride); +typedef void (APIENTRYP PFNGLMULTIMODEDRAWELEMENTSIBMPROC) (const GLenum *mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount, GLint modestride); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMultiModeDrawArraysIBM (const GLenum *mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride); +GLAPI void APIENTRY glMultiModeDrawElementsIBM (const GLenum *mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount, GLint modestride); +#endif +#endif /* GL_IBM_multimode_draw_arrays */ + +#ifndef GL_IBM_rasterpos_clip +#define GL_IBM_rasterpos_clip 1 +#define GL_RASTER_POSITION_UNCLIPPED_IBM 0x19262 +#endif /* GL_IBM_rasterpos_clip */ + +#ifndef GL_IBM_static_data +#define GL_IBM_static_data 1 +#define GL_ALL_STATIC_DATA_IBM 103060 +#define GL_STATIC_VERTEX_ARRAY_IBM 103061 +typedef void (APIENTRYP PFNGLFLUSHSTATICDATAIBMPROC) (GLenum target); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFlushStaticDataIBM (GLenum target); +#endif +#endif /* GL_IBM_static_data */ + +#ifndef GL_IBM_texture_mirrored_repeat +#define GL_IBM_texture_mirrored_repeat 1 +#define GL_MIRRORED_REPEAT_IBM 0x8370 +#endif /* GL_IBM_texture_mirrored_repeat */ + +#ifndef GL_IBM_vertex_array_lists +#define GL_IBM_vertex_array_lists 1 +#define GL_VERTEX_ARRAY_LIST_IBM 103070 +#define GL_NORMAL_ARRAY_LIST_IBM 103071 +#define GL_COLOR_ARRAY_LIST_IBM 103072 +#define GL_INDEX_ARRAY_LIST_IBM 103073 +#define GL_TEXTURE_COORD_ARRAY_LIST_IBM 103074 +#define GL_EDGE_FLAG_ARRAY_LIST_IBM 103075 +#define GL_FOG_COORDINATE_ARRAY_LIST_IBM 103076 +#define GL_SECONDARY_COLOR_ARRAY_LIST_IBM 103077 +#define GL_VERTEX_ARRAY_LIST_STRIDE_IBM 103080 +#define GL_NORMAL_ARRAY_LIST_STRIDE_IBM 103081 +#define GL_COLOR_ARRAY_LIST_STRIDE_IBM 103082 +#define GL_INDEX_ARRAY_LIST_STRIDE_IBM 103083 +#define GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM 103084 +#define GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM 103085 +#define GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM 103086 +#define GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM 103087 +typedef void (APIENTRYP PFNGLCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const void **pointer, GLint ptrstride); +typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const void **pointer, GLint ptrstride); +typedef void (APIENTRYP PFNGLEDGEFLAGPOINTERLISTIBMPROC) (GLint stride, const GLboolean **pointer, GLint ptrstride); +typedef void (APIENTRYP PFNGLFOGCOORDPOINTERLISTIBMPROC) (GLenum type, GLint stride, const void **pointer, GLint ptrstride); +typedef void (APIENTRYP PFNGLINDEXPOINTERLISTIBMPROC) (GLenum type, GLint stride, const void **pointer, GLint ptrstride); +typedef void (APIENTRYP PFNGLNORMALPOINTERLISTIBMPROC) (GLenum type, GLint stride, const void **pointer, GLint ptrstride); +typedef void (APIENTRYP PFNGLTEXCOORDPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const void **pointer, GLint ptrstride); +typedef void (APIENTRYP PFNGLVERTEXPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const void **pointer, GLint ptrstride); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glColorPointerListIBM (GLint size, GLenum type, GLint stride, const void **pointer, GLint ptrstride); +GLAPI void APIENTRY glSecondaryColorPointerListIBM (GLint size, GLenum type, GLint stride, const void **pointer, GLint ptrstride); +GLAPI void APIENTRY glEdgeFlagPointerListIBM (GLint stride, const GLboolean **pointer, GLint ptrstride); +GLAPI void APIENTRY glFogCoordPointerListIBM (GLenum type, GLint stride, const void **pointer, GLint ptrstride); +GLAPI void APIENTRY glIndexPointerListIBM (GLenum type, GLint stride, const void **pointer, GLint ptrstride); +GLAPI void APIENTRY glNormalPointerListIBM (GLenum type, GLint stride, const void **pointer, GLint ptrstride); +GLAPI void APIENTRY glTexCoordPointerListIBM (GLint size, GLenum type, GLint stride, const void **pointer, GLint ptrstride); +GLAPI void APIENTRY glVertexPointerListIBM (GLint size, GLenum type, GLint stride, const void **pointer, GLint ptrstride); +#endif +#endif /* GL_IBM_vertex_array_lists */ + +#ifndef GL_INGR_blend_func_separate +#define GL_INGR_blend_func_separate 1 +typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEINGRPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendFuncSeparateINGR (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +#endif +#endif /* GL_INGR_blend_func_separate */ + +#ifndef GL_INGR_color_clamp +#define GL_INGR_color_clamp 1 +#define GL_RED_MIN_CLAMP_INGR 0x8560 +#define GL_GREEN_MIN_CLAMP_INGR 0x8561 +#define GL_BLUE_MIN_CLAMP_INGR 0x8562 +#define GL_ALPHA_MIN_CLAMP_INGR 0x8563 +#define GL_RED_MAX_CLAMP_INGR 0x8564 +#define GL_GREEN_MAX_CLAMP_INGR 0x8565 +#define GL_BLUE_MAX_CLAMP_INGR 0x8566 +#define GL_ALPHA_MAX_CLAMP_INGR 0x8567 +#endif /* GL_INGR_color_clamp */ + +#ifndef GL_INGR_interlace_read +#define GL_INGR_interlace_read 1 +#define GL_INTERLACE_READ_INGR 0x8568 +#endif /* GL_INGR_interlace_read */ + +#ifndef GL_INTEL_fragment_shader_ordering +#define GL_INTEL_fragment_shader_ordering 1 +#endif /* GL_INTEL_fragment_shader_ordering */ + +#ifndef GL_INTEL_map_texture +#define GL_INTEL_map_texture 1 +#define GL_TEXTURE_MEMORY_LAYOUT_INTEL 0x83FF +#define GL_LAYOUT_DEFAULT_INTEL 0 +#define GL_LAYOUT_LINEAR_INTEL 1 +#define GL_LAYOUT_LINEAR_CPU_CACHED_INTEL 2 +typedef void (APIENTRYP PFNGLSYNCTEXTUREINTELPROC) (GLuint texture); +typedef void (APIENTRYP PFNGLUNMAPTEXTURE2DINTELPROC) (GLuint texture, GLint level); +typedef void *(APIENTRYP PFNGLMAPTEXTURE2DINTELPROC) (GLuint texture, GLint level, GLbitfield access, GLint *stride, GLenum *layout); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSyncTextureINTEL (GLuint texture); +GLAPI void APIENTRY glUnmapTexture2DINTEL (GLuint texture, GLint level); +GLAPI void *APIENTRY glMapTexture2DINTEL (GLuint texture, GLint level, GLbitfield access, GLint *stride, GLenum *layout); +#endif +#endif /* GL_INTEL_map_texture */ + +#ifndef GL_INTEL_parallel_arrays +#define GL_INTEL_parallel_arrays 1 +#define GL_PARALLEL_ARRAYS_INTEL 0x83F4 +#define GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL 0x83F5 +#define GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL 0x83F6 +#define GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL 0x83F7 +#define GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL 0x83F8 +typedef void (APIENTRYP PFNGLVERTEXPOINTERVINTELPROC) (GLint size, GLenum type, const void **pointer); +typedef void (APIENTRYP PFNGLNORMALPOINTERVINTELPROC) (GLenum type, const void **pointer); +typedef void (APIENTRYP PFNGLCOLORPOINTERVINTELPROC) (GLint size, GLenum type, const void **pointer); +typedef void (APIENTRYP PFNGLTEXCOORDPOINTERVINTELPROC) (GLint size, GLenum type, const void **pointer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexPointervINTEL (GLint size, GLenum type, const void **pointer); +GLAPI void APIENTRY glNormalPointervINTEL (GLenum type, const void **pointer); +GLAPI void APIENTRY glColorPointervINTEL (GLint size, GLenum type, const void **pointer); +GLAPI void APIENTRY glTexCoordPointervINTEL (GLint size, GLenum type, const void **pointer); +#endif +#endif /* GL_INTEL_parallel_arrays */ + +#ifndef GL_INTEL_performance_query +#define GL_INTEL_performance_query 1 +#define GL_PERFQUERY_SINGLE_CONTEXT_INTEL 0x00000000 +#define GL_PERFQUERY_GLOBAL_CONTEXT_INTEL 0x00000001 +#define GL_PERFQUERY_WAIT_INTEL 0x83FB +#define GL_PERFQUERY_FLUSH_INTEL 0x83FA +#define GL_PERFQUERY_DONOT_FLUSH_INTEL 0x83F9 +#define GL_PERFQUERY_COUNTER_EVENT_INTEL 0x94F0 +#define GL_PERFQUERY_COUNTER_DURATION_NORM_INTEL 0x94F1 +#define GL_PERFQUERY_COUNTER_DURATION_RAW_INTEL 0x94F2 +#define GL_PERFQUERY_COUNTER_THROUGHPUT_INTEL 0x94F3 +#define GL_PERFQUERY_COUNTER_RAW_INTEL 0x94F4 +#define GL_PERFQUERY_COUNTER_TIMESTAMP_INTEL 0x94F5 +#define GL_PERFQUERY_COUNTER_DATA_UINT32_INTEL 0x94F8 +#define GL_PERFQUERY_COUNTER_DATA_UINT64_INTEL 0x94F9 +#define GL_PERFQUERY_COUNTER_DATA_FLOAT_INTEL 0x94FA +#define GL_PERFQUERY_COUNTER_DATA_DOUBLE_INTEL 0x94FB +#define GL_PERFQUERY_COUNTER_DATA_BOOL32_INTEL 0x94FC +#define GL_PERFQUERY_QUERY_NAME_LENGTH_MAX_INTEL 0x94FD +#define GL_PERFQUERY_COUNTER_NAME_LENGTH_MAX_INTEL 0x94FE +#define GL_PERFQUERY_COUNTER_DESC_LENGTH_MAX_INTEL 0x94FF +#define GL_PERFQUERY_GPA_EXTENDED_COUNTERS_INTEL 0x9500 +typedef void (APIENTRYP PFNGLBEGINPERFQUERYINTELPROC) (GLuint queryHandle); +typedef void (APIENTRYP PFNGLCREATEPERFQUERYINTELPROC) (GLuint queryId, GLuint *queryHandle); +typedef void (APIENTRYP PFNGLDELETEPERFQUERYINTELPROC) (GLuint queryHandle); +typedef void (APIENTRYP PFNGLENDPERFQUERYINTELPROC) (GLuint queryHandle); +typedef void (APIENTRYP PFNGLGETFIRSTPERFQUERYIDINTELPROC) (GLuint *queryId); +typedef void (APIENTRYP PFNGLGETNEXTPERFQUERYIDINTELPROC) (GLuint queryId, GLuint *nextQueryId); +typedef void (APIENTRYP PFNGLGETPERFCOUNTERINFOINTELPROC) (GLuint queryId, GLuint counterId, GLuint counterNameLength, GLchar *counterName, GLuint counterDescLength, GLchar *counterDesc, GLuint *counterOffset, GLuint *counterDataSize, GLuint *counterTypeEnum, GLuint *counterDataTypeEnum, GLuint64 *rawCounterMaxValue); +typedef void (APIENTRYP PFNGLGETPERFQUERYDATAINTELPROC) (GLuint queryHandle, GLuint flags, GLsizei dataSize, GLvoid *data, GLuint *bytesWritten); +typedef void (APIENTRYP PFNGLGETPERFQUERYIDBYNAMEINTELPROC) (GLchar *queryName, GLuint *queryId); +typedef void (APIENTRYP PFNGLGETPERFQUERYINFOINTELPROC) (GLuint queryId, GLuint queryNameLength, GLchar *queryName, GLuint *dataSize, GLuint *noCounters, GLuint *noInstances, GLuint *capsMask); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBeginPerfQueryINTEL (GLuint queryHandle); +GLAPI void APIENTRY glCreatePerfQueryINTEL (GLuint queryId, GLuint *queryHandle); +GLAPI void APIENTRY glDeletePerfQueryINTEL (GLuint queryHandle); +GLAPI void APIENTRY glEndPerfQueryINTEL (GLuint queryHandle); +GLAPI void APIENTRY glGetFirstPerfQueryIdINTEL (GLuint *queryId); +GLAPI void APIENTRY glGetNextPerfQueryIdINTEL (GLuint queryId, GLuint *nextQueryId); +GLAPI void APIENTRY glGetPerfCounterInfoINTEL (GLuint queryId, GLuint counterId, GLuint counterNameLength, GLchar *counterName, GLuint counterDescLength, GLchar *counterDesc, GLuint *counterOffset, GLuint *counterDataSize, GLuint *counterTypeEnum, GLuint *counterDataTypeEnum, GLuint64 *rawCounterMaxValue); +GLAPI void APIENTRY glGetPerfQueryDataINTEL (GLuint queryHandle, GLuint flags, GLsizei dataSize, GLvoid *data, GLuint *bytesWritten); +GLAPI void APIENTRY glGetPerfQueryIdByNameINTEL (GLchar *queryName, GLuint *queryId); +GLAPI void APIENTRY glGetPerfQueryInfoINTEL (GLuint queryId, GLuint queryNameLength, GLchar *queryName, GLuint *dataSize, GLuint *noCounters, GLuint *noInstances, GLuint *capsMask); +#endif +#endif /* GL_INTEL_performance_query */ + +#ifndef GL_MESAX_texture_stack +#define GL_MESAX_texture_stack 1 +#define GL_TEXTURE_1D_STACK_MESAX 0x8759 +#define GL_TEXTURE_2D_STACK_MESAX 0x875A +#define GL_PROXY_TEXTURE_1D_STACK_MESAX 0x875B +#define GL_PROXY_TEXTURE_2D_STACK_MESAX 0x875C +#define GL_TEXTURE_1D_STACK_BINDING_MESAX 0x875D +#define GL_TEXTURE_2D_STACK_BINDING_MESAX 0x875E +#endif /* GL_MESAX_texture_stack */ + +#ifndef GL_MESA_pack_invert +#define GL_MESA_pack_invert 1 +#define GL_PACK_INVERT_MESA 0x8758 +#endif /* GL_MESA_pack_invert */ + +#ifndef GL_MESA_resize_buffers +#define GL_MESA_resize_buffers 1 +typedef void (APIENTRYP PFNGLRESIZEBUFFERSMESAPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glResizeBuffersMESA (void); +#endif +#endif /* GL_MESA_resize_buffers */ + +#ifndef GL_MESA_window_pos +#define GL_MESA_window_pos 1 +typedef void (APIENTRYP PFNGLWINDOWPOS2DMESAPROC) (GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLWINDOWPOS2DVMESAPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2FMESAPROC) (GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLWINDOWPOS2FVMESAPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2IMESAPROC) (GLint x, GLint y); +typedef void (APIENTRYP PFNGLWINDOWPOS2IVMESAPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2SMESAPROC) (GLshort x, GLshort y); +typedef void (APIENTRYP PFNGLWINDOWPOS2SVMESAPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3DMESAPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLWINDOWPOS3DVMESAPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3FMESAPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLWINDOWPOS3FVMESAPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3IMESAPROC) (GLint x, GLint y, GLint z); +typedef void (APIENTRYP PFNGLWINDOWPOS3IVMESAPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3SMESAPROC) (GLshort x, GLshort y, GLshort z); +typedef void (APIENTRYP PFNGLWINDOWPOS3SVMESAPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLWINDOWPOS4DMESAPROC) (GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLWINDOWPOS4DVMESAPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLWINDOWPOS4FMESAPROC) (GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLWINDOWPOS4FVMESAPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLWINDOWPOS4IMESAPROC) (GLint x, GLint y, GLint z, GLint w); +typedef void (APIENTRYP PFNGLWINDOWPOS4IVMESAPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLWINDOWPOS4SMESAPROC) (GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (APIENTRYP PFNGLWINDOWPOS4SVMESAPROC) (const GLshort *v); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glWindowPos2dMESA (GLdouble x, GLdouble y); +GLAPI void APIENTRY glWindowPos2dvMESA (const GLdouble *v); +GLAPI void APIENTRY glWindowPos2fMESA (GLfloat x, GLfloat y); +GLAPI void APIENTRY glWindowPos2fvMESA (const GLfloat *v); +GLAPI void APIENTRY glWindowPos2iMESA (GLint x, GLint y); +GLAPI void APIENTRY glWindowPos2ivMESA (const GLint *v); +GLAPI void APIENTRY glWindowPos2sMESA (GLshort x, GLshort y); +GLAPI void APIENTRY glWindowPos2svMESA (const GLshort *v); +GLAPI void APIENTRY glWindowPos3dMESA (GLdouble x, GLdouble y, GLdouble z); +GLAPI void APIENTRY glWindowPos3dvMESA (const GLdouble *v); +GLAPI void APIENTRY glWindowPos3fMESA (GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glWindowPos3fvMESA (const GLfloat *v); +GLAPI void APIENTRY glWindowPos3iMESA (GLint x, GLint y, GLint z); +GLAPI void APIENTRY glWindowPos3ivMESA (const GLint *v); +GLAPI void APIENTRY glWindowPos3sMESA (GLshort x, GLshort y, GLshort z); +GLAPI void APIENTRY glWindowPos3svMESA (const GLshort *v); +GLAPI void APIENTRY glWindowPos4dMESA (GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void APIENTRY glWindowPos4dvMESA (const GLdouble *v); +GLAPI void APIENTRY glWindowPos4fMESA (GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void APIENTRY glWindowPos4fvMESA (const GLfloat *v); +GLAPI void APIENTRY glWindowPos4iMESA (GLint x, GLint y, GLint z, GLint w); +GLAPI void APIENTRY glWindowPos4ivMESA (const GLint *v); +GLAPI void APIENTRY glWindowPos4sMESA (GLshort x, GLshort y, GLshort z, GLshort w); +GLAPI void APIENTRY glWindowPos4svMESA (const GLshort *v); +#endif +#endif /* GL_MESA_window_pos */ + +#ifndef GL_MESA_ycbcr_texture +#define GL_MESA_ycbcr_texture 1 +#define GL_UNSIGNED_SHORT_8_8_MESA 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_MESA 0x85BB +#define GL_YCBCR_MESA 0x8757 +#endif /* GL_MESA_ycbcr_texture */ + +#ifndef GL_NVX_conditional_render +#define GL_NVX_conditional_render 1 +typedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERNVXPROC) (GLuint id); +typedef void (APIENTRYP PFNGLENDCONDITIONALRENDERNVXPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBeginConditionalRenderNVX (GLuint id); +GLAPI void APIENTRY glEndConditionalRenderNVX (void); +#endif +#endif /* GL_NVX_conditional_render */ + +#ifndef GL_NVX_gpu_memory_info +#define GL_NVX_gpu_memory_info 1 +#define GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX 0x9047 +#define GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX 0x9048 +#define GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX 0x9049 +#define GL_GPU_MEMORY_INFO_EVICTION_COUNT_NVX 0x904A +#define GL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX 0x904B +#endif /* GL_NVX_gpu_memory_info */ + +#ifndef GL_NV_bindless_multi_draw_indirect +#define GL_NV_bindless_multi_draw_indirect 1 +typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSNVPROC) (GLenum mode, const void *indirect, GLsizei drawCount, GLsizei stride, GLint vertexBufferCount); +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSNVPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei drawCount, GLsizei stride, GLint vertexBufferCount); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMultiDrawArraysIndirectBindlessNV (GLenum mode, const void *indirect, GLsizei drawCount, GLsizei stride, GLint vertexBufferCount); +GLAPI void APIENTRY glMultiDrawElementsIndirectBindlessNV (GLenum mode, GLenum type, const void *indirect, GLsizei drawCount, GLsizei stride, GLint vertexBufferCount); +#endif +#endif /* GL_NV_bindless_multi_draw_indirect */ + +#ifndef GL_NV_bindless_multi_draw_indirect_count +#define GL_NV_bindless_multi_draw_indirect_count 1 +typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSCOUNTNVPROC) (GLenum mode, const void *indirect, GLsizei drawCount, GLsizei maxDrawCount, GLsizei stride, GLint vertexBufferCount); +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSCOUNTNVPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei drawCount, GLsizei maxDrawCount, GLsizei stride, GLint vertexBufferCount); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMultiDrawArraysIndirectBindlessCountNV (GLenum mode, const void *indirect, GLsizei drawCount, GLsizei maxDrawCount, GLsizei stride, GLint vertexBufferCount); +GLAPI void APIENTRY glMultiDrawElementsIndirectBindlessCountNV (GLenum mode, GLenum type, const void *indirect, GLsizei drawCount, GLsizei maxDrawCount, GLsizei stride, GLint vertexBufferCount); +#endif +#endif /* GL_NV_bindless_multi_draw_indirect_count */ + +#ifndef GL_NV_bindless_texture +#define GL_NV_bindless_texture 1 +typedef GLuint64 (APIENTRYP PFNGLGETTEXTUREHANDLENVPROC) (GLuint texture); +typedef GLuint64 (APIENTRYP PFNGLGETTEXTURESAMPLERHANDLENVPROC) (GLuint texture, GLuint sampler); +typedef void (APIENTRYP PFNGLMAKETEXTUREHANDLERESIDENTNVPROC) (GLuint64 handle); +typedef void (APIENTRYP PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC) (GLuint64 handle); +typedef GLuint64 (APIENTRYP PFNGLGETIMAGEHANDLENVPROC) (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format); +typedef void (APIENTRYP PFNGLMAKEIMAGEHANDLERESIDENTNVPROC) (GLuint64 handle, GLenum access); +typedef void (APIENTRYP PFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC) (GLuint64 handle); +typedef void (APIENTRYP PFNGLUNIFORMHANDLEUI64NVPROC) (GLint location, GLuint64 value); +typedef void (APIENTRYP PFNGLUNIFORMHANDLEUI64VNVPROC) (GLint location, GLsizei count, const GLuint64 *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64NVPROC) (GLuint program, GLint location, GLuint64 value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64 *values); +typedef GLboolean (APIENTRYP PFNGLISTEXTUREHANDLERESIDENTNVPROC) (GLuint64 handle); +typedef GLboolean (APIENTRYP PFNGLISIMAGEHANDLERESIDENTNVPROC) (GLuint64 handle); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLuint64 APIENTRY glGetTextureHandleNV (GLuint texture); +GLAPI GLuint64 APIENTRY glGetTextureSamplerHandleNV (GLuint texture, GLuint sampler); +GLAPI void APIENTRY glMakeTextureHandleResidentNV (GLuint64 handle); +GLAPI void APIENTRY glMakeTextureHandleNonResidentNV (GLuint64 handle); +GLAPI GLuint64 APIENTRY glGetImageHandleNV (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format); +GLAPI void APIENTRY glMakeImageHandleResidentNV (GLuint64 handle, GLenum access); +GLAPI void APIENTRY glMakeImageHandleNonResidentNV (GLuint64 handle); +GLAPI void APIENTRY glUniformHandleui64NV (GLint location, GLuint64 value); +GLAPI void APIENTRY glUniformHandleui64vNV (GLint location, GLsizei count, const GLuint64 *value); +GLAPI void APIENTRY glProgramUniformHandleui64NV (GLuint program, GLint location, GLuint64 value); +GLAPI void APIENTRY glProgramUniformHandleui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64 *values); +GLAPI GLboolean APIENTRY glIsTextureHandleResidentNV (GLuint64 handle); +GLAPI GLboolean APIENTRY glIsImageHandleResidentNV (GLuint64 handle); +#endif +#endif /* GL_NV_bindless_texture */ + +#ifndef GL_NV_blend_equation_advanced +#define GL_NV_blend_equation_advanced 1 +#define GL_BLEND_OVERLAP_NV 0x9281 +#define GL_BLEND_PREMULTIPLIED_SRC_NV 0x9280 +#define GL_BLUE_NV 0x1905 +#define GL_COLORBURN_NV 0x929A +#define GL_COLORDODGE_NV 0x9299 +#define GL_CONJOINT_NV 0x9284 +#define GL_CONTRAST_NV 0x92A1 +#define GL_DARKEN_NV 0x9297 +#define GL_DIFFERENCE_NV 0x929E +#define GL_DISJOINT_NV 0x9283 +#define GL_DST_ATOP_NV 0x928F +#define GL_DST_IN_NV 0x928B +#define GL_DST_NV 0x9287 +#define GL_DST_OUT_NV 0x928D +#define GL_DST_OVER_NV 0x9289 +#define GL_EXCLUSION_NV 0x92A0 +#define GL_GREEN_NV 0x1904 +#define GL_HARDLIGHT_NV 0x929B +#define GL_HARDMIX_NV 0x92A9 +#define GL_HSL_COLOR_NV 0x92AF +#define GL_HSL_HUE_NV 0x92AD +#define GL_HSL_LUMINOSITY_NV 0x92B0 +#define GL_HSL_SATURATION_NV 0x92AE +#define GL_INVERT_OVG_NV 0x92B4 +#define GL_INVERT_RGB_NV 0x92A3 +#define GL_LIGHTEN_NV 0x9298 +#define GL_LINEARBURN_NV 0x92A5 +#define GL_LINEARDODGE_NV 0x92A4 +#define GL_LINEARLIGHT_NV 0x92A7 +#define GL_MINUS_CLAMPED_NV 0x92B3 +#define GL_MINUS_NV 0x929F +#define GL_MULTIPLY_NV 0x9294 +#define GL_OVERLAY_NV 0x9296 +#define GL_PINLIGHT_NV 0x92A8 +#define GL_PLUS_CLAMPED_ALPHA_NV 0x92B2 +#define GL_PLUS_CLAMPED_NV 0x92B1 +#define GL_PLUS_DARKER_NV 0x9292 +#define GL_PLUS_NV 0x9291 +#define GL_RED_NV 0x1903 +#define GL_SCREEN_NV 0x9295 +#define GL_SOFTLIGHT_NV 0x929C +#define GL_SRC_ATOP_NV 0x928E +#define GL_SRC_IN_NV 0x928A +#define GL_SRC_NV 0x9286 +#define GL_SRC_OUT_NV 0x928C +#define GL_SRC_OVER_NV 0x9288 +#define GL_UNCORRELATED_NV 0x9282 +#define GL_VIVIDLIGHT_NV 0x92A6 +#define GL_XOR_NV 0x1506 +typedef void (APIENTRYP PFNGLBLENDPARAMETERINVPROC) (GLenum pname, GLint value); +typedef void (APIENTRYP PFNGLBLENDBARRIERNVPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendParameteriNV (GLenum pname, GLint value); +GLAPI void APIENTRY glBlendBarrierNV (void); +#endif +#endif /* GL_NV_blend_equation_advanced */ + +#ifndef GL_NV_blend_equation_advanced_coherent +#define GL_NV_blend_equation_advanced_coherent 1 +#define GL_BLEND_ADVANCED_COHERENT_NV 0x9285 +#endif /* GL_NV_blend_equation_advanced_coherent */ + +#ifndef GL_NV_blend_square +#define GL_NV_blend_square 1 +#endif /* GL_NV_blend_square */ + +#ifndef GL_NV_compute_program5 +#define GL_NV_compute_program5 1 +#define GL_COMPUTE_PROGRAM_NV 0x90FB +#define GL_COMPUTE_PROGRAM_PARAMETER_BUFFER_NV 0x90FC +#endif /* GL_NV_compute_program5 */ + +#ifndef GL_NV_conditional_render +#define GL_NV_conditional_render 1 +#define GL_QUERY_WAIT_NV 0x8E13 +#define GL_QUERY_NO_WAIT_NV 0x8E14 +#define GL_QUERY_BY_REGION_WAIT_NV 0x8E15 +#define GL_QUERY_BY_REGION_NO_WAIT_NV 0x8E16 +typedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERNVPROC) (GLuint id, GLenum mode); +typedef void (APIENTRYP PFNGLENDCONDITIONALRENDERNVPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBeginConditionalRenderNV (GLuint id, GLenum mode); +GLAPI void APIENTRY glEndConditionalRenderNV (void); +#endif +#endif /* GL_NV_conditional_render */ + +#ifndef GL_NV_copy_depth_to_color +#define GL_NV_copy_depth_to_color 1 +#define GL_DEPTH_STENCIL_TO_RGBA_NV 0x886E +#define GL_DEPTH_STENCIL_TO_BGRA_NV 0x886F +#endif /* GL_NV_copy_depth_to_color */ + +#ifndef GL_NV_copy_image +#define GL_NV_copy_image 1 +typedef void (APIENTRYP PFNGLCOPYIMAGESUBDATANVPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glCopyImageSubDataNV (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); +#endif +#endif /* GL_NV_copy_image */ + +#ifndef GL_NV_deep_texture3D +#define GL_NV_deep_texture3D 1 +#define GL_MAX_DEEP_3D_TEXTURE_WIDTH_HEIGHT_NV 0x90D0 +#define GL_MAX_DEEP_3D_TEXTURE_DEPTH_NV 0x90D1 +#endif /* GL_NV_deep_texture3D */ + +#ifndef GL_NV_depth_buffer_float +#define GL_NV_depth_buffer_float 1 +#define GL_DEPTH_COMPONENT32F_NV 0x8DAB +#define GL_DEPTH32F_STENCIL8_NV 0x8DAC +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV_NV 0x8DAD +#define GL_DEPTH_BUFFER_FLOAT_MODE_NV 0x8DAF +typedef void (APIENTRYP PFNGLDEPTHRANGEDNVPROC) (GLdouble zNear, GLdouble zFar); +typedef void (APIENTRYP PFNGLCLEARDEPTHDNVPROC) (GLdouble depth); +typedef void (APIENTRYP PFNGLDEPTHBOUNDSDNVPROC) (GLdouble zmin, GLdouble zmax); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDepthRangedNV (GLdouble zNear, GLdouble zFar); +GLAPI void APIENTRY glClearDepthdNV (GLdouble depth); +GLAPI void APIENTRY glDepthBoundsdNV (GLdouble zmin, GLdouble zmax); +#endif +#endif /* GL_NV_depth_buffer_float */ + +#ifndef GL_NV_depth_clamp +#define GL_NV_depth_clamp 1 +#define GL_DEPTH_CLAMP_NV 0x864F +#endif /* GL_NV_depth_clamp */ + +#ifndef GL_NV_draw_texture +#define GL_NV_draw_texture 1 +typedef void (APIENTRYP PFNGLDRAWTEXTURENVPROC) (GLuint texture, GLuint sampler, GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1, GLfloat z, GLfloat s0, GLfloat t0, GLfloat s1, GLfloat t1); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawTextureNV (GLuint texture, GLuint sampler, GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1, GLfloat z, GLfloat s0, GLfloat t0, GLfloat s1, GLfloat t1); +#endif +#endif /* GL_NV_draw_texture */ + +#ifndef GL_NV_evaluators +#define GL_NV_evaluators 1 +#define GL_EVAL_2D_NV 0x86C0 +#define GL_EVAL_TRIANGULAR_2D_NV 0x86C1 +#define GL_MAP_TESSELLATION_NV 0x86C2 +#define GL_MAP_ATTRIB_U_ORDER_NV 0x86C3 +#define GL_MAP_ATTRIB_V_ORDER_NV 0x86C4 +#define GL_EVAL_FRACTIONAL_TESSELLATION_NV 0x86C5 +#define GL_EVAL_VERTEX_ATTRIB0_NV 0x86C6 +#define GL_EVAL_VERTEX_ATTRIB1_NV 0x86C7 +#define GL_EVAL_VERTEX_ATTRIB2_NV 0x86C8 +#define GL_EVAL_VERTEX_ATTRIB3_NV 0x86C9 +#define GL_EVAL_VERTEX_ATTRIB4_NV 0x86CA +#define GL_EVAL_VERTEX_ATTRIB5_NV 0x86CB +#define GL_EVAL_VERTEX_ATTRIB6_NV 0x86CC +#define GL_EVAL_VERTEX_ATTRIB7_NV 0x86CD +#define GL_EVAL_VERTEX_ATTRIB8_NV 0x86CE +#define GL_EVAL_VERTEX_ATTRIB9_NV 0x86CF +#define GL_EVAL_VERTEX_ATTRIB10_NV 0x86D0 +#define GL_EVAL_VERTEX_ATTRIB11_NV 0x86D1 +#define GL_EVAL_VERTEX_ATTRIB12_NV 0x86D2 +#define GL_EVAL_VERTEX_ATTRIB13_NV 0x86D3 +#define GL_EVAL_VERTEX_ATTRIB14_NV 0x86D4 +#define GL_EVAL_VERTEX_ATTRIB15_NV 0x86D5 +#define GL_MAX_MAP_TESSELLATION_NV 0x86D6 +#define GL_MAX_RATIONAL_EVAL_ORDER_NV 0x86D7 +typedef void (APIENTRYP PFNGLMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const void *points); +typedef void (APIENTRYP PFNGLMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLGETMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, void *points); +typedef void (APIENTRYP PFNGLGETMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETMAPATTRIBPARAMETERIVNVPROC) (GLenum target, GLuint index, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETMAPATTRIBPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLEVALMAPSNVPROC) (GLenum target, GLenum mode); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMapControlPointsNV (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const void *points); +GLAPI void APIENTRY glMapParameterivNV (GLenum target, GLenum pname, const GLint *params); +GLAPI void APIENTRY glMapParameterfvNV (GLenum target, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glGetMapControlPointsNV (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, void *points); +GLAPI void APIENTRY glGetMapParameterivNV (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetMapParameterfvNV (GLenum target, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetMapAttribParameterivNV (GLenum target, GLuint index, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetMapAttribParameterfvNV (GLenum target, GLuint index, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glEvalMapsNV (GLenum target, GLenum mode); +#endif +#endif /* GL_NV_evaluators */ + +#ifndef GL_NV_explicit_multisample +#define GL_NV_explicit_multisample 1 +#define GL_SAMPLE_POSITION_NV 0x8E50 +#define GL_SAMPLE_MASK_NV 0x8E51 +#define GL_SAMPLE_MASK_VALUE_NV 0x8E52 +#define GL_TEXTURE_BINDING_RENDERBUFFER_NV 0x8E53 +#define GL_TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV 0x8E54 +#define GL_TEXTURE_RENDERBUFFER_NV 0x8E55 +#define GL_SAMPLER_RENDERBUFFER_NV 0x8E56 +#define GL_INT_SAMPLER_RENDERBUFFER_NV 0x8E57 +#define GL_UNSIGNED_INT_SAMPLER_RENDERBUFFER_NV 0x8E58 +#define GL_MAX_SAMPLE_MASK_WORDS_NV 0x8E59 +typedef void (APIENTRYP PFNGLGETMULTISAMPLEFVNVPROC) (GLenum pname, GLuint index, GLfloat *val); +typedef void (APIENTRYP PFNGLSAMPLEMASKINDEXEDNVPROC) (GLuint index, GLbitfield mask); +typedef void (APIENTRYP PFNGLTEXRENDERBUFFERNVPROC) (GLenum target, GLuint renderbuffer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGetMultisamplefvNV (GLenum pname, GLuint index, GLfloat *val); +GLAPI void APIENTRY glSampleMaskIndexedNV (GLuint index, GLbitfield mask); +GLAPI void APIENTRY glTexRenderbufferNV (GLenum target, GLuint renderbuffer); +#endif +#endif /* GL_NV_explicit_multisample */ + +#ifndef GL_NV_fence +#define GL_NV_fence 1 +#define GL_ALL_COMPLETED_NV 0x84F2 +#define GL_FENCE_STATUS_NV 0x84F3 +#define GL_FENCE_CONDITION_NV 0x84F4 +typedef void (APIENTRYP PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint *fences); +typedef void (APIENTRYP PFNGLGENFENCESNVPROC) (GLsizei n, GLuint *fences); +typedef GLboolean (APIENTRYP PFNGLISFENCENVPROC) (GLuint fence); +typedef GLboolean (APIENTRYP PFNGLTESTFENCENVPROC) (GLuint fence); +typedef void (APIENTRYP PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLFINISHFENCENVPROC) (GLuint fence); +typedef void (APIENTRYP PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDeleteFencesNV (GLsizei n, const GLuint *fences); +GLAPI void APIENTRY glGenFencesNV (GLsizei n, GLuint *fences); +GLAPI GLboolean APIENTRY glIsFenceNV (GLuint fence); +GLAPI GLboolean APIENTRY glTestFenceNV (GLuint fence); +GLAPI void APIENTRY glGetFenceivNV (GLuint fence, GLenum pname, GLint *params); +GLAPI void APIENTRY glFinishFenceNV (GLuint fence); +GLAPI void APIENTRY glSetFenceNV (GLuint fence, GLenum condition); +#endif +#endif /* GL_NV_fence */ + +#ifndef GL_NV_float_buffer +#define GL_NV_float_buffer 1 +#define GL_FLOAT_R_NV 0x8880 +#define GL_FLOAT_RG_NV 0x8881 +#define GL_FLOAT_RGB_NV 0x8882 +#define GL_FLOAT_RGBA_NV 0x8883 +#define GL_FLOAT_R16_NV 0x8884 +#define GL_FLOAT_R32_NV 0x8885 +#define GL_FLOAT_RG16_NV 0x8886 +#define GL_FLOAT_RG32_NV 0x8887 +#define GL_FLOAT_RGB16_NV 0x8888 +#define GL_FLOAT_RGB32_NV 0x8889 +#define GL_FLOAT_RGBA16_NV 0x888A +#define GL_FLOAT_RGBA32_NV 0x888B +#define GL_TEXTURE_FLOAT_COMPONENTS_NV 0x888C +#define GL_FLOAT_CLEAR_COLOR_VALUE_NV 0x888D +#define GL_FLOAT_RGBA_MODE_NV 0x888E +#endif /* GL_NV_float_buffer */ + +#ifndef GL_NV_fog_distance +#define GL_NV_fog_distance 1 +#define GL_FOG_DISTANCE_MODE_NV 0x855A +#define GL_EYE_RADIAL_NV 0x855B +#define GL_EYE_PLANE_ABSOLUTE_NV 0x855C +#endif /* GL_NV_fog_distance */ + +#ifndef GL_NV_fragment_program +#define GL_NV_fragment_program 1 +#define GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV 0x8868 +#define GL_FRAGMENT_PROGRAM_NV 0x8870 +#define GL_MAX_TEXTURE_COORDS_NV 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS_NV 0x8872 +#define GL_FRAGMENT_PROGRAM_BINDING_NV 0x8873 +#define GL_PROGRAM_ERROR_STRING_NV 0x8874 +typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4FNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, const GLfloat *v); +typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4DNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, const GLdouble *v); +typedef void (APIENTRYP PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLfloat *params); +typedef void (APIENTRYP PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLdouble *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glProgramNamedParameter4fNV (GLuint id, GLsizei len, const GLubyte *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void APIENTRY glProgramNamedParameter4fvNV (GLuint id, GLsizei len, const GLubyte *name, const GLfloat *v); +GLAPI void APIENTRY glProgramNamedParameter4dNV (GLuint id, GLsizei len, const GLubyte *name, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void APIENTRY glProgramNamedParameter4dvNV (GLuint id, GLsizei len, const GLubyte *name, const GLdouble *v); +GLAPI void APIENTRY glGetProgramNamedParameterfvNV (GLuint id, GLsizei len, const GLubyte *name, GLfloat *params); +GLAPI void APIENTRY glGetProgramNamedParameterdvNV (GLuint id, GLsizei len, const GLubyte *name, GLdouble *params); +#endif +#endif /* GL_NV_fragment_program */ + +#ifndef GL_NV_fragment_program2 +#define GL_NV_fragment_program2 1 +#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4 +#define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5 +#define GL_MAX_PROGRAM_IF_DEPTH_NV 0x88F6 +#define GL_MAX_PROGRAM_LOOP_DEPTH_NV 0x88F7 +#define GL_MAX_PROGRAM_LOOP_COUNT_NV 0x88F8 +#endif /* GL_NV_fragment_program2 */ + +#ifndef GL_NV_fragment_program4 +#define GL_NV_fragment_program4 1 +#endif /* GL_NV_fragment_program4 */ + +#ifndef GL_NV_fragment_program_option +#define GL_NV_fragment_program_option 1 +#endif /* GL_NV_fragment_program_option */ + +#ifndef GL_NV_framebuffer_multisample_coverage +#define GL_NV_framebuffer_multisample_coverage 1 +#define GL_RENDERBUFFER_COVERAGE_SAMPLES_NV 0x8CAB +#define GL_RENDERBUFFER_COLOR_SAMPLES_NV 0x8E10 +#define GL_MAX_MULTISAMPLE_COVERAGE_MODES_NV 0x8E11 +#define GL_MULTISAMPLE_COVERAGE_MODES_NV 0x8E12 +typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glRenderbufferStorageMultisampleCoverageNV (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); +#endif +#endif /* GL_NV_framebuffer_multisample_coverage */ + +#ifndef GL_NV_geometry_program4 +#define GL_NV_geometry_program4 1 +#define GL_GEOMETRY_PROGRAM_NV 0x8C26 +#define GL_MAX_PROGRAM_OUTPUT_VERTICES_NV 0x8C27 +#define GL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV 0x8C28 +typedef void (APIENTRYP PFNGLPROGRAMVERTEXLIMITNVPROC) (GLenum target, GLint limit); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glProgramVertexLimitNV (GLenum target, GLint limit); +GLAPI void APIENTRY glFramebufferTextureEXT (GLenum target, GLenum attachment, GLuint texture, GLint level); +GLAPI void APIENTRY glFramebufferTextureFaceEXT (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); +#endif +#endif /* GL_NV_geometry_program4 */ + +#ifndef GL_NV_geometry_shader4 +#define GL_NV_geometry_shader4 1 +#endif /* GL_NV_geometry_shader4 */ + +#ifndef GL_NV_gpu_program4 +#define GL_NV_gpu_program4 1 +#define GL_MIN_PROGRAM_TEXEL_OFFSET_NV 0x8904 +#define GL_MAX_PROGRAM_TEXEL_OFFSET_NV 0x8905 +#define GL_PROGRAM_ATTRIB_COMPONENTS_NV 0x8906 +#define GL_PROGRAM_RESULT_COMPONENTS_NV 0x8907 +#define GL_MAX_PROGRAM_ATTRIB_COMPONENTS_NV 0x8908 +#define GL_MAX_PROGRAM_RESULT_COMPONENTS_NV 0x8909 +#define GL_MAX_PROGRAM_GENERIC_ATTRIBS_NV 0x8DA5 +#define GL_MAX_PROGRAM_GENERIC_RESULTS_NV 0x8DA6 +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERIIVNVPROC) (GLenum target, GLuint index, GLint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERIUIVNVPROC) (GLenum target, GLuint index, GLuint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERIIVNVPROC) (GLenum target, GLuint index, GLint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERIUIVNVPROC) (GLenum target, GLuint index, GLuint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glProgramLocalParameterI4iNV (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +GLAPI void APIENTRY glProgramLocalParameterI4ivNV (GLenum target, GLuint index, const GLint *params); +GLAPI void APIENTRY glProgramLocalParametersI4ivNV (GLenum target, GLuint index, GLsizei count, const GLint *params); +GLAPI void APIENTRY glProgramLocalParameterI4uiNV (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +GLAPI void APIENTRY glProgramLocalParameterI4uivNV (GLenum target, GLuint index, const GLuint *params); +GLAPI void APIENTRY glProgramLocalParametersI4uivNV (GLenum target, GLuint index, GLsizei count, const GLuint *params); +GLAPI void APIENTRY glProgramEnvParameterI4iNV (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +GLAPI void APIENTRY glProgramEnvParameterI4ivNV (GLenum target, GLuint index, const GLint *params); +GLAPI void APIENTRY glProgramEnvParametersI4ivNV (GLenum target, GLuint index, GLsizei count, const GLint *params); +GLAPI void APIENTRY glProgramEnvParameterI4uiNV (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +GLAPI void APIENTRY glProgramEnvParameterI4uivNV (GLenum target, GLuint index, const GLuint *params); +GLAPI void APIENTRY glProgramEnvParametersI4uivNV (GLenum target, GLuint index, GLsizei count, const GLuint *params); +GLAPI void APIENTRY glGetProgramLocalParameterIivNV (GLenum target, GLuint index, GLint *params); +GLAPI void APIENTRY glGetProgramLocalParameterIuivNV (GLenum target, GLuint index, GLuint *params); +GLAPI void APIENTRY glGetProgramEnvParameterIivNV (GLenum target, GLuint index, GLint *params); +GLAPI void APIENTRY glGetProgramEnvParameterIuivNV (GLenum target, GLuint index, GLuint *params); +#endif +#endif /* GL_NV_gpu_program4 */ + +#ifndef GL_NV_gpu_program5 +#define GL_NV_gpu_program5 1 +#define GL_MAX_GEOMETRY_PROGRAM_INVOCATIONS_NV 0x8E5A +#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_NV 0x8E5B +#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_NV 0x8E5C +#define GL_FRAGMENT_PROGRAM_INTERPOLATION_OFFSET_BITS_NV 0x8E5D +#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_NV 0x8E5E +#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_NV 0x8E5F +#define GL_MAX_PROGRAM_SUBROUTINE_PARAMETERS_NV 0x8F44 +#define GL_MAX_PROGRAM_SUBROUTINE_NUM_NV 0x8F45 +typedef void (APIENTRYP PFNGLPROGRAMSUBROUTINEPARAMETERSUIVNVPROC) (GLenum target, GLsizei count, const GLuint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMSUBROUTINEPARAMETERUIVNVPROC) (GLenum target, GLuint index, GLuint *param); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glProgramSubroutineParametersuivNV (GLenum target, GLsizei count, const GLuint *params); +GLAPI void APIENTRY glGetProgramSubroutineParameteruivNV (GLenum target, GLuint index, GLuint *param); +#endif +#endif /* GL_NV_gpu_program5 */ + +#ifndef GL_NV_gpu_program5_mem_extended +#define GL_NV_gpu_program5_mem_extended 1 +#endif /* GL_NV_gpu_program5_mem_extended */ + +#ifndef GL_NV_gpu_shader5 +#define GL_NV_gpu_shader5 1 +#endif /* GL_NV_gpu_shader5 */ + +#ifndef GL_NV_half_float +#define GL_NV_half_float 1 +typedef unsigned short GLhalfNV; +#define GL_HALF_FLOAT_NV 0x140B +typedef void (APIENTRYP PFNGLVERTEX2HNVPROC) (GLhalfNV x, GLhalfNV y); +typedef void (APIENTRYP PFNGLVERTEX2HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEX3HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z); +typedef void (APIENTRYP PFNGLVERTEX3HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEX4HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); +typedef void (APIENTRYP PFNGLVERTEX4HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLNORMAL3HNVPROC) (GLhalfNV nx, GLhalfNV ny, GLhalfNV nz); +typedef void (APIENTRYP PFNGLNORMAL3HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue); +typedef void (APIENTRYP PFNGLCOLOR3HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLCOLOR4HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue, GLhalfNV alpha); +typedef void (APIENTRYP PFNGLCOLOR4HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLTEXCOORD1HNVPROC) (GLhalfNV s); +typedef void (APIENTRYP PFNGLTEXCOORD1HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLTEXCOORD2HNVPROC) (GLhalfNV s, GLhalfNV t); +typedef void (APIENTRYP PFNGLTEXCOORD2HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLTEXCOORD3HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r); +typedef void (APIENTRYP PFNGLTEXCOORD3HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLTEXCOORD4HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); +typedef void (APIENTRYP PFNGLTEXCOORD4HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1HNVPROC) (GLenum target, GLhalfNV s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1HVNVPROC) (GLenum target, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2HVNVPROC) (GLenum target, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3HVNVPROC) (GLenum target, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4HVNVPROC) (GLenum target, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLFOGCOORDHNVPROC) (GLhalfNV fog); +typedef void (APIENTRYP PFNGLFOGCOORDHVNVPROC) (const GLhalfNV *fog); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXWEIGHTHNVPROC) (GLhalfNV weight); +typedef void (APIENTRYP PFNGLVERTEXWEIGHTHVNVPROC) (const GLhalfNV *weight); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1HNVPROC) (GLuint index, GLhalfNV x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1HVNVPROC) (GLuint index, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2HVNVPROC) (GLuint index, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3HVNVPROC) (GLuint index, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4HVNVPROC) (GLuint index, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS1HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS2HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS3HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS4HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertex2hNV (GLhalfNV x, GLhalfNV y); +GLAPI void APIENTRY glVertex2hvNV (const GLhalfNV *v); +GLAPI void APIENTRY glVertex3hNV (GLhalfNV x, GLhalfNV y, GLhalfNV z); +GLAPI void APIENTRY glVertex3hvNV (const GLhalfNV *v); +GLAPI void APIENTRY glVertex4hNV (GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); +GLAPI void APIENTRY glVertex4hvNV (const GLhalfNV *v); +GLAPI void APIENTRY glNormal3hNV (GLhalfNV nx, GLhalfNV ny, GLhalfNV nz); +GLAPI void APIENTRY glNormal3hvNV (const GLhalfNV *v); +GLAPI void APIENTRY glColor3hNV (GLhalfNV red, GLhalfNV green, GLhalfNV blue); +GLAPI void APIENTRY glColor3hvNV (const GLhalfNV *v); +GLAPI void APIENTRY glColor4hNV (GLhalfNV red, GLhalfNV green, GLhalfNV blue, GLhalfNV alpha); +GLAPI void APIENTRY glColor4hvNV (const GLhalfNV *v); +GLAPI void APIENTRY glTexCoord1hNV (GLhalfNV s); +GLAPI void APIENTRY glTexCoord1hvNV (const GLhalfNV *v); +GLAPI void APIENTRY glTexCoord2hNV (GLhalfNV s, GLhalfNV t); +GLAPI void APIENTRY glTexCoord2hvNV (const GLhalfNV *v); +GLAPI void APIENTRY glTexCoord3hNV (GLhalfNV s, GLhalfNV t, GLhalfNV r); +GLAPI void APIENTRY glTexCoord3hvNV (const GLhalfNV *v); +GLAPI void APIENTRY glTexCoord4hNV (GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); +GLAPI void APIENTRY glTexCoord4hvNV (const GLhalfNV *v); +GLAPI void APIENTRY glMultiTexCoord1hNV (GLenum target, GLhalfNV s); +GLAPI void APIENTRY glMultiTexCoord1hvNV (GLenum target, const GLhalfNV *v); +GLAPI void APIENTRY glMultiTexCoord2hNV (GLenum target, GLhalfNV s, GLhalfNV t); +GLAPI void APIENTRY glMultiTexCoord2hvNV (GLenum target, const GLhalfNV *v); +GLAPI void APIENTRY glMultiTexCoord3hNV (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r); +GLAPI void APIENTRY glMultiTexCoord3hvNV (GLenum target, const GLhalfNV *v); +GLAPI void APIENTRY glMultiTexCoord4hNV (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); +GLAPI void APIENTRY glMultiTexCoord4hvNV (GLenum target, const GLhalfNV *v); +GLAPI void APIENTRY glFogCoordhNV (GLhalfNV fog); +GLAPI void APIENTRY glFogCoordhvNV (const GLhalfNV *fog); +GLAPI void APIENTRY glSecondaryColor3hNV (GLhalfNV red, GLhalfNV green, GLhalfNV blue); +GLAPI void APIENTRY glSecondaryColor3hvNV (const GLhalfNV *v); +GLAPI void APIENTRY glVertexWeighthNV (GLhalfNV weight); +GLAPI void APIENTRY glVertexWeighthvNV (const GLhalfNV *weight); +GLAPI void APIENTRY glVertexAttrib1hNV (GLuint index, GLhalfNV x); +GLAPI void APIENTRY glVertexAttrib1hvNV (GLuint index, const GLhalfNV *v); +GLAPI void APIENTRY glVertexAttrib2hNV (GLuint index, GLhalfNV x, GLhalfNV y); +GLAPI void APIENTRY glVertexAttrib2hvNV (GLuint index, const GLhalfNV *v); +GLAPI void APIENTRY glVertexAttrib3hNV (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z); +GLAPI void APIENTRY glVertexAttrib3hvNV (GLuint index, const GLhalfNV *v); +GLAPI void APIENTRY glVertexAttrib4hNV (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); +GLAPI void APIENTRY glVertexAttrib4hvNV (GLuint index, const GLhalfNV *v); +GLAPI void APIENTRY glVertexAttribs1hvNV (GLuint index, GLsizei n, const GLhalfNV *v); +GLAPI void APIENTRY glVertexAttribs2hvNV (GLuint index, GLsizei n, const GLhalfNV *v); +GLAPI void APIENTRY glVertexAttribs3hvNV (GLuint index, GLsizei n, const GLhalfNV *v); +GLAPI void APIENTRY glVertexAttribs4hvNV (GLuint index, GLsizei n, const GLhalfNV *v); +#endif +#endif /* GL_NV_half_float */ + +#ifndef GL_NV_light_max_exponent +#define GL_NV_light_max_exponent 1 +#define GL_MAX_SHININESS_NV 0x8504 +#define GL_MAX_SPOT_EXPONENT_NV 0x8505 +#endif /* GL_NV_light_max_exponent */ + +#ifndef GL_NV_multisample_coverage +#define GL_NV_multisample_coverage 1 +#define GL_COLOR_SAMPLES_NV 0x8E20 +#endif /* GL_NV_multisample_coverage */ + +#ifndef GL_NV_multisample_filter_hint +#define GL_NV_multisample_filter_hint 1 +#define GL_MULTISAMPLE_FILTER_HINT_NV 0x8534 +#endif /* GL_NV_multisample_filter_hint */ + +#ifndef GL_NV_occlusion_query +#define GL_NV_occlusion_query 1 +#define GL_PIXEL_COUNTER_BITS_NV 0x8864 +#define GL_CURRENT_OCCLUSION_QUERY_ID_NV 0x8865 +#define GL_PIXEL_COUNT_NV 0x8866 +#define GL_PIXEL_COUNT_AVAILABLE_NV 0x8867 +typedef void (APIENTRYP PFNGLGENOCCLUSIONQUERIESNVPROC) (GLsizei n, GLuint *ids); +typedef void (APIENTRYP PFNGLDELETEOCCLUSIONQUERIESNVPROC) (GLsizei n, const GLuint *ids); +typedef GLboolean (APIENTRYP PFNGLISOCCLUSIONQUERYNVPROC) (GLuint id); +typedef void (APIENTRYP PFNGLBEGINOCCLUSIONQUERYNVPROC) (GLuint id); +typedef void (APIENTRYP PFNGLENDOCCLUSIONQUERYNVPROC) (void); +typedef void (APIENTRYP PFNGLGETOCCLUSIONQUERYIVNVPROC) (GLuint id, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETOCCLUSIONQUERYUIVNVPROC) (GLuint id, GLenum pname, GLuint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGenOcclusionQueriesNV (GLsizei n, GLuint *ids); +GLAPI void APIENTRY glDeleteOcclusionQueriesNV (GLsizei n, const GLuint *ids); +GLAPI GLboolean APIENTRY glIsOcclusionQueryNV (GLuint id); +GLAPI void APIENTRY glBeginOcclusionQueryNV (GLuint id); +GLAPI void APIENTRY glEndOcclusionQueryNV (void); +GLAPI void APIENTRY glGetOcclusionQueryivNV (GLuint id, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetOcclusionQueryuivNV (GLuint id, GLenum pname, GLuint *params); +#endif +#endif /* GL_NV_occlusion_query */ + +#ifndef GL_NV_packed_depth_stencil +#define GL_NV_packed_depth_stencil 1 +#define GL_DEPTH_STENCIL_NV 0x84F9 +#define GL_UNSIGNED_INT_24_8_NV 0x84FA +#endif /* GL_NV_packed_depth_stencil */ + +#ifndef GL_NV_parameter_buffer_object +#define GL_NV_parameter_buffer_object 1 +#define GL_MAX_PROGRAM_PARAMETER_BUFFER_BINDINGS_NV 0x8DA0 +#define GL_MAX_PROGRAM_PARAMETER_BUFFER_SIZE_NV 0x8DA1 +#define GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV 0x8DA2 +#define GL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV 0x8DA3 +#define GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV 0x8DA4 +typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC) (GLenum target, GLuint bindingIndex, GLuint wordIndex, GLsizei count, const GLfloat *params); +typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC) (GLenum target, GLuint bindingIndex, GLuint wordIndex, GLsizei count, const GLint *params); +typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC) (GLenum target, GLuint bindingIndex, GLuint wordIndex, GLsizei count, const GLuint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glProgramBufferParametersfvNV (GLenum target, GLuint bindingIndex, GLuint wordIndex, GLsizei count, const GLfloat *params); +GLAPI void APIENTRY glProgramBufferParametersIivNV (GLenum target, GLuint bindingIndex, GLuint wordIndex, GLsizei count, const GLint *params); +GLAPI void APIENTRY glProgramBufferParametersIuivNV (GLenum target, GLuint bindingIndex, GLuint wordIndex, GLsizei count, const GLuint *params); +#endif +#endif /* GL_NV_parameter_buffer_object */ + +#ifndef GL_NV_parameter_buffer_object2 +#define GL_NV_parameter_buffer_object2 1 +#endif /* GL_NV_parameter_buffer_object2 */ + +#ifndef GL_NV_path_rendering +#define GL_NV_path_rendering 1 +#define GL_PATH_FORMAT_SVG_NV 0x9070 +#define GL_PATH_FORMAT_PS_NV 0x9071 +#define GL_STANDARD_FONT_NAME_NV 0x9072 +#define GL_SYSTEM_FONT_NAME_NV 0x9073 +#define GL_FILE_NAME_NV 0x9074 +#define GL_PATH_STROKE_WIDTH_NV 0x9075 +#define GL_PATH_END_CAPS_NV 0x9076 +#define GL_PATH_INITIAL_END_CAP_NV 0x9077 +#define GL_PATH_TERMINAL_END_CAP_NV 0x9078 +#define GL_PATH_JOIN_STYLE_NV 0x9079 +#define GL_PATH_MITER_LIMIT_NV 0x907A +#define GL_PATH_DASH_CAPS_NV 0x907B +#define GL_PATH_INITIAL_DASH_CAP_NV 0x907C +#define GL_PATH_TERMINAL_DASH_CAP_NV 0x907D +#define GL_PATH_DASH_OFFSET_NV 0x907E +#define GL_PATH_CLIENT_LENGTH_NV 0x907F +#define GL_PATH_FILL_MODE_NV 0x9080 +#define GL_PATH_FILL_MASK_NV 0x9081 +#define GL_PATH_FILL_COVER_MODE_NV 0x9082 +#define GL_PATH_STROKE_COVER_MODE_NV 0x9083 +#define GL_PATH_STROKE_MASK_NV 0x9084 +#define GL_COUNT_UP_NV 0x9088 +#define GL_COUNT_DOWN_NV 0x9089 +#define GL_PATH_OBJECT_BOUNDING_BOX_NV 0x908A +#define GL_CONVEX_HULL_NV 0x908B +#define GL_BOUNDING_BOX_NV 0x908D +#define GL_TRANSLATE_X_NV 0x908E +#define GL_TRANSLATE_Y_NV 0x908F +#define GL_TRANSLATE_2D_NV 0x9090 +#define GL_TRANSLATE_3D_NV 0x9091 +#define GL_AFFINE_2D_NV 0x9092 +#define GL_AFFINE_3D_NV 0x9094 +#define GL_TRANSPOSE_AFFINE_2D_NV 0x9096 +#define GL_TRANSPOSE_AFFINE_3D_NV 0x9098 +#define GL_UTF8_NV 0x909A +#define GL_UTF16_NV 0x909B +#define GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV 0x909C +#define GL_PATH_COMMAND_COUNT_NV 0x909D +#define GL_PATH_COORD_COUNT_NV 0x909E +#define GL_PATH_DASH_ARRAY_COUNT_NV 0x909F +#define GL_PATH_COMPUTED_LENGTH_NV 0x90A0 +#define GL_PATH_FILL_BOUNDING_BOX_NV 0x90A1 +#define GL_PATH_STROKE_BOUNDING_BOX_NV 0x90A2 +#define GL_SQUARE_NV 0x90A3 +#define GL_ROUND_NV 0x90A4 +#define GL_TRIANGULAR_NV 0x90A5 +#define GL_BEVEL_NV 0x90A6 +#define GL_MITER_REVERT_NV 0x90A7 +#define GL_MITER_TRUNCATE_NV 0x90A8 +#define GL_SKIP_MISSING_GLYPH_NV 0x90A9 +#define GL_USE_MISSING_GLYPH_NV 0x90AA +#define GL_PATH_ERROR_POSITION_NV 0x90AB +#define GL_PATH_FOG_GEN_MODE_NV 0x90AC +#define GL_ACCUM_ADJACENT_PAIRS_NV 0x90AD +#define GL_ADJACENT_PAIRS_NV 0x90AE +#define GL_FIRST_TO_REST_NV 0x90AF +#define GL_PATH_GEN_MODE_NV 0x90B0 +#define GL_PATH_GEN_COEFF_NV 0x90B1 +#define GL_PATH_GEN_COLOR_FORMAT_NV 0x90B2 +#define GL_PATH_GEN_COMPONENTS_NV 0x90B3 +#define GL_PATH_STENCIL_FUNC_NV 0x90B7 +#define GL_PATH_STENCIL_REF_NV 0x90B8 +#define GL_PATH_STENCIL_VALUE_MASK_NV 0x90B9 +#define GL_PATH_STENCIL_DEPTH_OFFSET_FACTOR_NV 0x90BD +#define GL_PATH_STENCIL_DEPTH_OFFSET_UNITS_NV 0x90BE +#define GL_PATH_COVER_DEPTH_FUNC_NV 0x90BF +#define GL_PATH_DASH_OFFSET_RESET_NV 0x90B4 +#define GL_MOVE_TO_RESETS_NV 0x90B5 +#define GL_MOVE_TO_CONTINUES_NV 0x90B6 +#define GL_CLOSE_PATH_NV 0x00 +#define GL_MOVE_TO_NV 0x02 +#define GL_RELATIVE_MOVE_TO_NV 0x03 +#define GL_LINE_TO_NV 0x04 +#define GL_RELATIVE_LINE_TO_NV 0x05 +#define GL_HORIZONTAL_LINE_TO_NV 0x06 +#define GL_RELATIVE_HORIZONTAL_LINE_TO_NV 0x07 +#define GL_VERTICAL_LINE_TO_NV 0x08 +#define GL_RELATIVE_VERTICAL_LINE_TO_NV 0x09 +#define GL_QUADRATIC_CURVE_TO_NV 0x0A +#define GL_RELATIVE_QUADRATIC_CURVE_TO_NV 0x0B +#define GL_CUBIC_CURVE_TO_NV 0x0C +#define GL_RELATIVE_CUBIC_CURVE_TO_NV 0x0D +#define GL_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0E +#define GL_RELATIVE_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0F +#define GL_SMOOTH_CUBIC_CURVE_TO_NV 0x10 +#define GL_RELATIVE_SMOOTH_CUBIC_CURVE_TO_NV 0x11 +#define GL_SMALL_CCW_ARC_TO_NV 0x12 +#define GL_RELATIVE_SMALL_CCW_ARC_TO_NV 0x13 +#define GL_SMALL_CW_ARC_TO_NV 0x14 +#define GL_RELATIVE_SMALL_CW_ARC_TO_NV 0x15 +#define GL_LARGE_CCW_ARC_TO_NV 0x16 +#define GL_RELATIVE_LARGE_CCW_ARC_TO_NV 0x17 +#define GL_LARGE_CW_ARC_TO_NV 0x18 +#define GL_RELATIVE_LARGE_CW_ARC_TO_NV 0x19 +#define GL_RESTART_PATH_NV 0xF0 +#define GL_DUP_FIRST_CUBIC_CURVE_TO_NV 0xF2 +#define GL_DUP_LAST_CUBIC_CURVE_TO_NV 0xF4 +#define GL_RECT_NV 0xF6 +#define GL_CIRCULAR_CCW_ARC_TO_NV 0xF8 +#define GL_CIRCULAR_CW_ARC_TO_NV 0xFA +#define GL_CIRCULAR_TANGENT_ARC_TO_NV 0xFC +#define GL_ARC_TO_NV 0xFE +#define GL_RELATIVE_ARC_TO_NV 0xFF +#define GL_BOLD_BIT_NV 0x01 +#define GL_ITALIC_BIT_NV 0x02 +#define GL_GLYPH_WIDTH_BIT_NV 0x01 +#define GL_GLYPH_HEIGHT_BIT_NV 0x02 +#define GL_GLYPH_HORIZONTAL_BEARING_X_BIT_NV 0x04 +#define GL_GLYPH_HORIZONTAL_BEARING_Y_BIT_NV 0x08 +#define GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV 0x10 +#define GL_GLYPH_VERTICAL_BEARING_X_BIT_NV 0x20 +#define GL_GLYPH_VERTICAL_BEARING_Y_BIT_NV 0x40 +#define GL_GLYPH_VERTICAL_BEARING_ADVANCE_BIT_NV 0x80 +#define GL_GLYPH_HAS_KERNING_BIT_NV 0x100 +#define GL_FONT_X_MIN_BOUNDS_BIT_NV 0x00010000 +#define GL_FONT_Y_MIN_BOUNDS_BIT_NV 0x00020000 +#define GL_FONT_X_MAX_BOUNDS_BIT_NV 0x00040000 +#define GL_FONT_Y_MAX_BOUNDS_BIT_NV 0x00080000 +#define GL_FONT_UNITS_PER_EM_BIT_NV 0x00100000 +#define GL_FONT_ASCENDER_BIT_NV 0x00200000 +#define GL_FONT_DESCENDER_BIT_NV 0x00400000 +#define GL_FONT_HEIGHT_BIT_NV 0x00800000 +#define GL_FONT_MAX_ADVANCE_WIDTH_BIT_NV 0x01000000 +#define GL_FONT_MAX_ADVANCE_HEIGHT_BIT_NV 0x02000000 +#define GL_FONT_UNDERLINE_POSITION_BIT_NV 0x04000000 +#define GL_FONT_UNDERLINE_THICKNESS_BIT_NV 0x08000000 +#define GL_FONT_HAS_KERNING_BIT_NV 0x10000000 +#define GL_PRIMARY_COLOR_NV 0x852C +#define GL_SECONDARY_COLOR_NV 0x852D +#define GL_ROUNDED_RECT_NV 0xE8 +#define GL_RELATIVE_ROUNDED_RECT_NV 0xE9 +#define GL_ROUNDED_RECT2_NV 0xEA +#define GL_RELATIVE_ROUNDED_RECT2_NV 0xEB +#define GL_ROUNDED_RECT4_NV 0xEC +#define GL_RELATIVE_ROUNDED_RECT4_NV 0xED +#define GL_ROUNDED_RECT8_NV 0xEE +#define GL_RELATIVE_ROUNDED_RECT8_NV 0xEF +#define GL_RELATIVE_RECT_NV 0xF7 +#define GL_FONT_GLYPHS_AVAILABLE_NV 0x9368 +#define GL_FONT_TARGET_UNAVAILABLE_NV 0x9369 +#define GL_FONT_UNAVAILABLE_NV 0x936A +#define GL_FONT_UNINTELLIGIBLE_NV 0x936B +#define GL_CONIC_CURVE_TO_NV 0x1A +#define GL_RELATIVE_CONIC_CURVE_TO_NV 0x1B +#define GL_FONT_NUM_GLYPH_INDICES_BIT_NV 0x20000000 +#define GL_STANDARD_FONT_FORMAT_NV 0x936C +#define GL_2_BYTES_NV 0x1407 +#define GL_3_BYTES_NV 0x1408 +#define GL_4_BYTES_NV 0x1409 +#define GL_EYE_LINEAR_NV 0x2400 +#define GL_OBJECT_LINEAR_NV 0x2401 +#define GL_CONSTANT_NV 0x8576 +#define GL_PATH_PROJECTION_NV 0x1701 +#define GL_PATH_MODELVIEW_NV 0x1700 +#define GL_PATH_MODELVIEW_STACK_DEPTH_NV 0x0BA3 +#define GL_PATH_MODELVIEW_MATRIX_NV 0x0BA6 +#define GL_PATH_MAX_MODELVIEW_STACK_DEPTH_NV 0x0D36 +#define GL_PATH_TRANSPOSE_MODELVIEW_MATRIX_NV 0x84E3 +#define GL_PATH_PROJECTION_STACK_DEPTH_NV 0x0BA4 +#define GL_PATH_PROJECTION_MATRIX_NV 0x0BA7 +#define GL_PATH_MAX_PROJECTION_STACK_DEPTH_NV 0x0D38 +#define GL_PATH_TRANSPOSE_PROJECTION_MATRIX_NV 0x84E4 +#define GL_FRAGMENT_INPUT_NV 0x936D +typedef GLuint (APIENTRYP PFNGLGENPATHSNVPROC) (GLsizei range); +typedef void (APIENTRYP PFNGLDELETEPATHSNVPROC) (GLuint path, GLsizei range); +typedef GLboolean (APIENTRYP PFNGLISPATHNVPROC) (GLuint path); +typedef void (APIENTRYP PFNGLPATHCOMMANDSNVPROC) (GLuint path, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords); +typedef void (APIENTRYP PFNGLPATHCOORDSNVPROC) (GLuint path, GLsizei numCoords, GLenum coordType, const void *coords); +typedef void (APIENTRYP PFNGLPATHSUBCOMMANDSNVPROC) (GLuint path, GLsizei commandStart, GLsizei commandsToDelete, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords); +typedef void (APIENTRYP PFNGLPATHSUBCOORDSNVPROC) (GLuint path, GLsizei coordStart, GLsizei numCoords, GLenum coordType, const void *coords); +typedef void (APIENTRYP PFNGLPATHSTRINGNVPROC) (GLuint path, GLenum format, GLsizei length, const void *pathString); +typedef void (APIENTRYP PFNGLPATHGLYPHSNVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLsizei numGlyphs, GLenum type, const void *charcodes, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +typedef void (APIENTRYP PFNGLPATHGLYPHRANGENVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyph, GLsizei numGlyphs, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +typedef void (APIENTRYP PFNGLWEIGHTPATHSNVPROC) (GLuint resultPath, GLsizei numPaths, const GLuint *paths, const GLfloat *weights); +typedef void (APIENTRYP PFNGLCOPYPATHNVPROC) (GLuint resultPath, GLuint srcPath); +typedef void (APIENTRYP PFNGLINTERPOLATEPATHSNVPROC) (GLuint resultPath, GLuint pathA, GLuint pathB, GLfloat weight); +typedef void (APIENTRYP PFNGLTRANSFORMPATHNVPROC) (GLuint resultPath, GLuint srcPath, GLenum transformType, const GLfloat *transformValues); +typedef void (APIENTRYP PFNGLPATHPARAMETERIVNVPROC) (GLuint path, GLenum pname, const GLint *value); +typedef void (APIENTRYP PFNGLPATHPARAMETERINVPROC) (GLuint path, GLenum pname, GLint value); +typedef void (APIENTRYP PFNGLPATHPARAMETERFVNVPROC) (GLuint path, GLenum pname, const GLfloat *value); +typedef void (APIENTRYP PFNGLPATHPARAMETERFNVPROC) (GLuint path, GLenum pname, GLfloat value); +typedef void (APIENTRYP PFNGLPATHDASHARRAYNVPROC) (GLuint path, GLsizei dashCount, const GLfloat *dashArray); +typedef void (APIENTRYP PFNGLPATHSTENCILFUNCNVPROC) (GLenum func, GLint ref, GLuint mask); +typedef void (APIENTRYP PFNGLPATHSTENCILDEPTHOFFSETNVPROC) (GLfloat factor, GLfloat units); +typedef void (APIENTRYP PFNGLSTENCILFILLPATHNVPROC) (GLuint path, GLenum fillMode, GLuint mask); +typedef void (APIENTRYP PFNGLSTENCILSTROKEPATHNVPROC) (GLuint path, GLint reference, GLuint mask); +typedef void (APIENTRYP PFNGLSTENCILFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum transformType, const GLfloat *transformValues); +typedef void (APIENTRYP PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum transformType, const GLfloat *transformValues); +typedef void (APIENTRYP PFNGLPATHCOVERDEPTHFUNCNVPROC) (GLenum func); +typedef void (APIENTRYP PFNGLPATHCOLORGENNVPROC) (GLenum color, GLenum genMode, GLenum colorFormat, const GLfloat *coeffs); +typedef void (APIENTRYP PFNGLPATHTEXGENNVPROC) (GLenum texCoordSet, GLenum genMode, GLint components, const GLfloat *coeffs); +typedef void (APIENTRYP PFNGLPATHFOGGENNVPROC) (GLenum genMode); +typedef void (APIENTRYP PFNGLCOVERFILLPATHNVPROC) (GLuint path, GLenum coverMode); +typedef void (APIENTRYP PFNGLCOVERSTROKEPATHNVPROC) (GLuint path, GLenum coverMode); +typedef void (APIENTRYP PFNGLCOVERFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); +typedef void (APIENTRYP PFNGLCOVERSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); +typedef void (APIENTRYP PFNGLGETPATHPARAMETERIVNVPROC) (GLuint path, GLenum pname, GLint *value); +typedef void (APIENTRYP PFNGLGETPATHPARAMETERFVNVPROC) (GLuint path, GLenum pname, GLfloat *value); +typedef void (APIENTRYP PFNGLGETPATHCOMMANDSNVPROC) (GLuint path, GLubyte *commands); +typedef void (APIENTRYP PFNGLGETPATHCOORDSNVPROC) (GLuint path, GLfloat *coords); +typedef void (APIENTRYP PFNGLGETPATHDASHARRAYNVPROC) (GLuint path, GLfloat *dashArray); +typedef void (APIENTRYP PFNGLGETPATHMETRICSNVPROC) (GLbitfield metricQueryMask, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLsizei stride, GLfloat *metrics); +typedef void (APIENTRYP PFNGLGETPATHMETRICRANGENVPROC) (GLbitfield metricQueryMask, GLuint firstPathName, GLsizei numPaths, GLsizei stride, GLfloat *metrics); +typedef void (APIENTRYP PFNGLGETPATHSPACINGNVPROC) (GLenum pathListMode, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, GLfloat *returnedSpacing); +typedef void (APIENTRYP PFNGLGETPATHCOLORGENIVNVPROC) (GLenum color, GLenum pname, GLint *value); +typedef void (APIENTRYP PFNGLGETPATHCOLORGENFVNVPROC) (GLenum color, GLenum pname, GLfloat *value); +typedef void (APIENTRYP PFNGLGETPATHTEXGENIVNVPROC) (GLenum texCoordSet, GLenum pname, GLint *value); +typedef void (APIENTRYP PFNGLGETPATHTEXGENFVNVPROC) (GLenum texCoordSet, GLenum pname, GLfloat *value); +typedef GLboolean (APIENTRYP PFNGLISPOINTINFILLPATHNVPROC) (GLuint path, GLuint mask, GLfloat x, GLfloat y); +typedef GLboolean (APIENTRYP PFNGLISPOINTINSTROKEPATHNVPROC) (GLuint path, GLfloat x, GLfloat y); +typedef GLfloat (APIENTRYP PFNGLGETPATHLENGTHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments); +typedef GLboolean (APIENTRYP PFNGLPOINTALONGPATHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments, GLfloat distance, GLfloat *x, GLfloat *y, GLfloat *tangentX, GLfloat *tangentY); +typedef void (APIENTRYP PFNGLMATRIXLOAD3X2FNVPROC) (GLenum matrixMode, const GLfloat *m); +typedef void (APIENTRYP PFNGLMATRIXLOAD3X3FNVPROC) (GLenum matrixMode, const GLfloat *m); +typedef void (APIENTRYP PFNGLMATRIXLOADTRANSPOSE3X3FNVPROC) (GLenum matrixMode, const GLfloat *m); +typedef void (APIENTRYP PFNGLMATRIXMULT3X2FNVPROC) (GLenum matrixMode, const GLfloat *m); +typedef void (APIENTRYP PFNGLMATRIXMULT3X3FNVPROC) (GLenum matrixMode, const GLfloat *m); +typedef void (APIENTRYP PFNGLMATRIXMULTTRANSPOSE3X3FNVPROC) (GLenum matrixMode, const GLfloat *m); +typedef void (APIENTRYP PFNGLSTENCILTHENCOVERFILLPATHNVPROC) (GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode); +typedef void (APIENTRYP PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC) (GLuint path, GLint reference, GLuint mask, GLenum coverMode); +typedef void (APIENTRYP PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); +typedef void (APIENTRYP PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); +typedef GLenum (APIENTRYP PFNGLPATHGLYPHINDEXRANGENVPROC) (GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint pathParameterTemplate, GLfloat emScale, GLuint baseAndCount[2]); +typedef GLenum (APIENTRYP PFNGLPATHGLYPHINDEXARRAYNVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +typedef GLenum (APIENTRYP PFNGLPATHMEMORYGLYPHINDEXARRAYNVPROC) (GLuint firstPathName, GLenum fontTarget, GLsizeiptr fontSize, const void *fontData, GLsizei faceIndex, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +typedef void (APIENTRYP PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC) (GLuint program, GLint location, GLenum genMode, GLint components, const GLfloat *coeffs); +typedef void (APIENTRYP PFNGLGETPROGRAMRESOURCEFVNVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLfloat *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLuint APIENTRY glGenPathsNV (GLsizei range); +GLAPI void APIENTRY glDeletePathsNV (GLuint path, GLsizei range); +GLAPI GLboolean APIENTRY glIsPathNV (GLuint path); +GLAPI void APIENTRY glPathCommandsNV (GLuint path, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords); +GLAPI void APIENTRY glPathCoordsNV (GLuint path, GLsizei numCoords, GLenum coordType, const void *coords); +GLAPI void APIENTRY glPathSubCommandsNV (GLuint path, GLsizei commandStart, GLsizei commandsToDelete, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords); +GLAPI void APIENTRY glPathSubCoordsNV (GLuint path, GLsizei coordStart, GLsizei numCoords, GLenum coordType, const void *coords); +GLAPI void APIENTRY glPathStringNV (GLuint path, GLenum format, GLsizei length, const void *pathString); +GLAPI void APIENTRY glPathGlyphsNV (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLsizei numGlyphs, GLenum type, const void *charcodes, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +GLAPI void APIENTRY glPathGlyphRangeNV (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyph, GLsizei numGlyphs, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +GLAPI void APIENTRY glWeightPathsNV (GLuint resultPath, GLsizei numPaths, const GLuint *paths, const GLfloat *weights); +GLAPI void APIENTRY glCopyPathNV (GLuint resultPath, GLuint srcPath); +GLAPI void APIENTRY glInterpolatePathsNV (GLuint resultPath, GLuint pathA, GLuint pathB, GLfloat weight); +GLAPI void APIENTRY glTransformPathNV (GLuint resultPath, GLuint srcPath, GLenum transformType, const GLfloat *transformValues); +GLAPI void APIENTRY glPathParameterivNV (GLuint path, GLenum pname, const GLint *value); +GLAPI void APIENTRY glPathParameteriNV (GLuint path, GLenum pname, GLint value); +GLAPI void APIENTRY glPathParameterfvNV (GLuint path, GLenum pname, const GLfloat *value); +GLAPI void APIENTRY glPathParameterfNV (GLuint path, GLenum pname, GLfloat value); +GLAPI void APIENTRY glPathDashArrayNV (GLuint path, GLsizei dashCount, const GLfloat *dashArray); +GLAPI void APIENTRY glPathStencilFuncNV (GLenum func, GLint ref, GLuint mask); +GLAPI void APIENTRY glPathStencilDepthOffsetNV (GLfloat factor, GLfloat units); +GLAPI void APIENTRY glStencilFillPathNV (GLuint path, GLenum fillMode, GLuint mask); +GLAPI void APIENTRY glStencilStrokePathNV (GLuint path, GLint reference, GLuint mask); +GLAPI void APIENTRY glStencilFillPathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum transformType, const GLfloat *transformValues); +GLAPI void APIENTRY glStencilStrokePathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum transformType, const GLfloat *transformValues); +GLAPI void APIENTRY glPathCoverDepthFuncNV (GLenum func); +GLAPI void APIENTRY glPathColorGenNV (GLenum color, GLenum genMode, GLenum colorFormat, const GLfloat *coeffs); +GLAPI void APIENTRY glPathTexGenNV (GLenum texCoordSet, GLenum genMode, GLint components, const GLfloat *coeffs); +GLAPI void APIENTRY glPathFogGenNV (GLenum genMode); +GLAPI void APIENTRY glCoverFillPathNV (GLuint path, GLenum coverMode); +GLAPI void APIENTRY glCoverStrokePathNV (GLuint path, GLenum coverMode); +GLAPI void APIENTRY glCoverFillPathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); +GLAPI void APIENTRY glCoverStrokePathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); +GLAPI void APIENTRY glGetPathParameterivNV (GLuint path, GLenum pname, GLint *value); +GLAPI void APIENTRY glGetPathParameterfvNV (GLuint path, GLenum pname, GLfloat *value); +GLAPI void APIENTRY glGetPathCommandsNV (GLuint path, GLubyte *commands); +GLAPI void APIENTRY glGetPathCoordsNV (GLuint path, GLfloat *coords); +GLAPI void APIENTRY glGetPathDashArrayNV (GLuint path, GLfloat *dashArray); +GLAPI void APIENTRY glGetPathMetricsNV (GLbitfield metricQueryMask, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLsizei stride, GLfloat *metrics); +GLAPI void APIENTRY glGetPathMetricRangeNV (GLbitfield metricQueryMask, GLuint firstPathName, GLsizei numPaths, GLsizei stride, GLfloat *metrics); +GLAPI void APIENTRY glGetPathSpacingNV (GLenum pathListMode, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, GLfloat *returnedSpacing); +GLAPI void APIENTRY glGetPathColorGenivNV (GLenum color, GLenum pname, GLint *value); +GLAPI void APIENTRY glGetPathColorGenfvNV (GLenum color, GLenum pname, GLfloat *value); +GLAPI void APIENTRY glGetPathTexGenivNV (GLenum texCoordSet, GLenum pname, GLint *value); +GLAPI void APIENTRY glGetPathTexGenfvNV (GLenum texCoordSet, GLenum pname, GLfloat *value); +GLAPI GLboolean APIENTRY glIsPointInFillPathNV (GLuint path, GLuint mask, GLfloat x, GLfloat y); +GLAPI GLboolean APIENTRY glIsPointInStrokePathNV (GLuint path, GLfloat x, GLfloat y); +GLAPI GLfloat APIENTRY glGetPathLengthNV (GLuint path, GLsizei startSegment, GLsizei numSegments); +GLAPI GLboolean APIENTRY glPointAlongPathNV (GLuint path, GLsizei startSegment, GLsizei numSegments, GLfloat distance, GLfloat *x, GLfloat *y, GLfloat *tangentX, GLfloat *tangentY); +GLAPI void APIENTRY glMatrixLoad3x2fNV (GLenum matrixMode, const GLfloat *m); +GLAPI void APIENTRY glMatrixLoad3x3fNV (GLenum matrixMode, const GLfloat *m); +GLAPI void APIENTRY glMatrixLoadTranspose3x3fNV (GLenum matrixMode, const GLfloat *m); +GLAPI void APIENTRY glMatrixMult3x2fNV (GLenum matrixMode, const GLfloat *m); +GLAPI void APIENTRY glMatrixMult3x3fNV (GLenum matrixMode, const GLfloat *m); +GLAPI void APIENTRY glMatrixMultTranspose3x3fNV (GLenum matrixMode, const GLfloat *m); +GLAPI void APIENTRY glStencilThenCoverFillPathNV (GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode); +GLAPI void APIENTRY glStencilThenCoverStrokePathNV (GLuint path, GLint reference, GLuint mask, GLenum coverMode); +GLAPI void APIENTRY glStencilThenCoverFillPathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); +GLAPI void APIENTRY glStencilThenCoverStrokePathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); +GLAPI GLenum APIENTRY glPathGlyphIndexRangeNV (GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint pathParameterTemplate, GLfloat emScale, GLuint baseAndCount[2]); +GLAPI GLenum APIENTRY glPathGlyphIndexArrayNV (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +GLAPI GLenum APIENTRY glPathMemoryGlyphIndexArrayNV (GLuint firstPathName, GLenum fontTarget, GLsizeiptr fontSize, const void *fontData, GLsizei faceIndex, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +GLAPI void APIENTRY glProgramPathFragmentInputGenNV (GLuint program, GLint location, GLenum genMode, GLint components, const GLfloat *coeffs); +GLAPI void APIENTRY glGetProgramResourcefvNV (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLfloat *params); +#endif +#endif /* GL_NV_path_rendering */ + +#ifndef GL_NV_pixel_data_range +#define GL_NV_pixel_data_range 1 +#define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878 +#define GL_READ_PIXEL_DATA_RANGE_NV 0x8879 +#define GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV 0x887A +#define GL_READ_PIXEL_DATA_RANGE_LENGTH_NV 0x887B +#define GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV 0x887C +#define GL_READ_PIXEL_DATA_RANGE_POINTER_NV 0x887D +typedef void (APIENTRYP PFNGLPIXELDATARANGENVPROC) (GLenum target, GLsizei length, const void *pointer); +typedef void (APIENTRYP PFNGLFLUSHPIXELDATARANGENVPROC) (GLenum target); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPixelDataRangeNV (GLenum target, GLsizei length, const void *pointer); +GLAPI void APIENTRY glFlushPixelDataRangeNV (GLenum target); +#endif +#endif /* GL_NV_pixel_data_range */ + +#ifndef GL_NV_point_sprite +#define GL_NV_point_sprite 1 +#define GL_POINT_SPRITE_NV 0x8861 +#define GL_COORD_REPLACE_NV 0x8862 +#define GL_POINT_SPRITE_R_MODE_NV 0x8863 +typedef void (APIENTRYP PFNGLPOINTPARAMETERINVPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLPOINTPARAMETERIVNVPROC) (GLenum pname, const GLint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPointParameteriNV (GLenum pname, GLint param); +GLAPI void APIENTRY glPointParameterivNV (GLenum pname, const GLint *params); +#endif +#endif /* GL_NV_point_sprite */ + +#ifndef GL_NV_present_video +#define GL_NV_present_video 1 +#define GL_FRAME_NV 0x8E26 +#define GL_FIELDS_NV 0x8E27 +#define GL_CURRENT_TIME_NV 0x8E28 +#define GL_NUM_FILL_STREAMS_NV 0x8E29 +#define GL_PRESENT_TIME_NV 0x8E2A +#define GL_PRESENT_DURATION_NV 0x8E2B +typedef void (APIENTRYP PFNGLPRESENTFRAMEKEYEDNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLuint key0, GLenum target1, GLuint fill1, GLuint key1); +typedef void (APIENTRYP PFNGLPRESENTFRAMEDUALFILLNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLenum target1, GLuint fill1, GLenum target2, GLuint fill2, GLenum target3, GLuint fill3); +typedef void (APIENTRYP PFNGLGETVIDEOIVNVPROC) (GLuint video_slot, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETVIDEOUIVNVPROC) (GLuint video_slot, GLenum pname, GLuint *params); +typedef void (APIENTRYP PFNGLGETVIDEOI64VNVPROC) (GLuint video_slot, GLenum pname, GLint64EXT *params); +typedef void (APIENTRYP PFNGLGETVIDEOUI64VNVPROC) (GLuint video_slot, GLenum pname, GLuint64EXT *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPresentFrameKeyedNV (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLuint key0, GLenum target1, GLuint fill1, GLuint key1); +GLAPI void APIENTRY glPresentFrameDualFillNV (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLenum target1, GLuint fill1, GLenum target2, GLuint fill2, GLenum target3, GLuint fill3); +GLAPI void APIENTRY glGetVideoivNV (GLuint video_slot, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetVideouivNV (GLuint video_slot, GLenum pname, GLuint *params); +GLAPI void APIENTRY glGetVideoi64vNV (GLuint video_slot, GLenum pname, GLint64EXT *params); +GLAPI void APIENTRY glGetVideoui64vNV (GLuint video_slot, GLenum pname, GLuint64EXT *params); +#endif +#endif /* GL_NV_present_video */ + +#ifndef GL_NV_primitive_restart +#define GL_NV_primitive_restart 1 +#define GL_PRIMITIVE_RESTART_NV 0x8558 +#define GL_PRIMITIVE_RESTART_INDEX_NV 0x8559 +typedef void (APIENTRYP PFNGLPRIMITIVERESTARTNVPROC) (void); +typedef void (APIENTRYP PFNGLPRIMITIVERESTARTINDEXNVPROC) (GLuint index); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPrimitiveRestartNV (void); +GLAPI void APIENTRY glPrimitiveRestartIndexNV (GLuint index); +#endif +#endif /* GL_NV_primitive_restart */ + +#ifndef GL_NV_register_combiners +#define GL_NV_register_combiners 1 +#define GL_REGISTER_COMBINERS_NV 0x8522 +#define GL_VARIABLE_A_NV 0x8523 +#define GL_VARIABLE_B_NV 0x8524 +#define GL_VARIABLE_C_NV 0x8525 +#define GL_VARIABLE_D_NV 0x8526 +#define GL_VARIABLE_E_NV 0x8527 +#define GL_VARIABLE_F_NV 0x8528 +#define GL_VARIABLE_G_NV 0x8529 +#define GL_CONSTANT_COLOR0_NV 0x852A +#define GL_CONSTANT_COLOR1_NV 0x852B +#define GL_SPARE0_NV 0x852E +#define GL_SPARE1_NV 0x852F +#define GL_DISCARD_NV 0x8530 +#define GL_E_TIMES_F_NV 0x8531 +#define GL_SPARE0_PLUS_SECONDARY_COLOR_NV 0x8532 +#define GL_UNSIGNED_IDENTITY_NV 0x8536 +#define GL_UNSIGNED_INVERT_NV 0x8537 +#define GL_EXPAND_NORMAL_NV 0x8538 +#define GL_EXPAND_NEGATE_NV 0x8539 +#define GL_HALF_BIAS_NORMAL_NV 0x853A +#define GL_HALF_BIAS_NEGATE_NV 0x853B +#define GL_SIGNED_IDENTITY_NV 0x853C +#define GL_SIGNED_NEGATE_NV 0x853D +#define GL_SCALE_BY_TWO_NV 0x853E +#define GL_SCALE_BY_FOUR_NV 0x853F +#define GL_SCALE_BY_ONE_HALF_NV 0x8540 +#define GL_BIAS_BY_NEGATIVE_ONE_HALF_NV 0x8541 +#define GL_COMBINER_INPUT_NV 0x8542 +#define GL_COMBINER_MAPPING_NV 0x8543 +#define GL_COMBINER_COMPONENT_USAGE_NV 0x8544 +#define GL_COMBINER_AB_DOT_PRODUCT_NV 0x8545 +#define GL_COMBINER_CD_DOT_PRODUCT_NV 0x8546 +#define GL_COMBINER_MUX_SUM_NV 0x8547 +#define GL_COMBINER_SCALE_NV 0x8548 +#define GL_COMBINER_BIAS_NV 0x8549 +#define GL_COMBINER_AB_OUTPUT_NV 0x854A +#define GL_COMBINER_CD_OUTPUT_NV 0x854B +#define GL_COMBINER_SUM_OUTPUT_NV 0x854C +#define GL_MAX_GENERAL_COMBINERS_NV 0x854D +#define GL_NUM_GENERAL_COMBINERS_NV 0x854E +#define GL_COLOR_SUM_CLAMP_NV 0x854F +#define GL_COMBINER0_NV 0x8550 +#define GL_COMBINER1_NV 0x8551 +#define GL_COMBINER2_NV 0x8552 +#define GL_COMBINER3_NV 0x8553 +#define GL_COMBINER4_NV 0x8554 +#define GL_COMBINER5_NV 0x8555 +#define GL_COMBINER6_NV 0x8556 +#define GL_COMBINER7_NV 0x8557 +typedef void (APIENTRYP PFNGLCOMBINERPARAMETERFVNVPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLCOMBINERPARAMETERFNVPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLCOMBINERPARAMETERIVNVPROC) (GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLCOMBINERPARAMETERINVPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLCOMBINERINPUTNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); +typedef void (APIENTRYP PFNGLCOMBINEROUTPUTNVPROC) (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum); +typedef void (APIENTRYP PFNGLFINALCOMBINERINPUTNVPROC) (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); +typedef void (APIENTRYP PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC) (GLenum variable, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC) (GLenum variable, GLenum pname, GLint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glCombinerParameterfvNV (GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glCombinerParameterfNV (GLenum pname, GLfloat param); +GLAPI void APIENTRY glCombinerParameterivNV (GLenum pname, const GLint *params); +GLAPI void APIENTRY glCombinerParameteriNV (GLenum pname, GLint param); +GLAPI void APIENTRY glCombinerInputNV (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); +GLAPI void APIENTRY glCombinerOutputNV (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum); +GLAPI void APIENTRY glFinalCombinerInputNV (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); +GLAPI void APIENTRY glGetCombinerInputParameterfvNV (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetCombinerInputParameterivNV (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetCombinerOutputParameterfvNV (GLenum stage, GLenum portion, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetCombinerOutputParameterivNV (GLenum stage, GLenum portion, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetFinalCombinerInputParameterfvNV (GLenum variable, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetFinalCombinerInputParameterivNV (GLenum variable, GLenum pname, GLint *params); +#endif +#endif /* GL_NV_register_combiners */ + +#ifndef GL_NV_register_combiners2 +#define GL_NV_register_combiners2 1 +#define GL_PER_STAGE_CONSTANTS_NV 0x8535 +typedef void (APIENTRYP PFNGLCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, GLfloat *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glCombinerStageParameterfvNV (GLenum stage, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glGetCombinerStageParameterfvNV (GLenum stage, GLenum pname, GLfloat *params); +#endif +#endif /* GL_NV_register_combiners2 */ + +#ifndef GL_NV_shader_atomic_counters +#define GL_NV_shader_atomic_counters 1 +#endif /* GL_NV_shader_atomic_counters */ + +#ifndef GL_NV_shader_atomic_float +#define GL_NV_shader_atomic_float 1 +#endif /* GL_NV_shader_atomic_float */ + +#ifndef GL_NV_shader_atomic_int64 +#define GL_NV_shader_atomic_int64 1 +#endif /* GL_NV_shader_atomic_int64 */ + +#ifndef GL_NV_shader_buffer_load +#define GL_NV_shader_buffer_load 1 +#define GL_BUFFER_GPU_ADDRESS_NV 0x8F1D +#define GL_GPU_ADDRESS_NV 0x8F34 +#define GL_MAX_SHADER_BUFFER_ADDRESS_NV 0x8F35 +typedef void (APIENTRYP PFNGLMAKEBUFFERRESIDENTNVPROC) (GLenum target, GLenum access); +typedef void (APIENTRYP PFNGLMAKEBUFFERNONRESIDENTNVPROC) (GLenum target); +typedef GLboolean (APIENTRYP PFNGLISBUFFERRESIDENTNVPROC) (GLenum target); +typedef void (APIENTRYP PFNGLMAKENAMEDBUFFERRESIDENTNVPROC) (GLuint buffer, GLenum access); +typedef void (APIENTRYP PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC) (GLuint buffer); +typedef GLboolean (APIENTRYP PFNGLISNAMEDBUFFERRESIDENTNVPROC) (GLuint buffer); +typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERUI64VNVPROC) (GLenum target, GLenum pname, GLuint64EXT *params); +typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC) (GLuint buffer, GLenum pname, GLuint64EXT *params); +typedef void (APIENTRYP PFNGLGETINTEGERUI64VNVPROC) (GLenum value, GLuint64EXT *result); +typedef void (APIENTRYP PFNGLUNIFORMUI64NVPROC) (GLint location, GLuint64EXT value); +typedef void (APIENTRYP PFNGLUNIFORMUI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMUI64NVPROC) (GLuint program, GLint location, GLuint64EXT value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMUI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMakeBufferResidentNV (GLenum target, GLenum access); +GLAPI void APIENTRY glMakeBufferNonResidentNV (GLenum target); +GLAPI GLboolean APIENTRY glIsBufferResidentNV (GLenum target); +GLAPI void APIENTRY glMakeNamedBufferResidentNV (GLuint buffer, GLenum access); +GLAPI void APIENTRY glMakeNamedBufferNonResidentNV (GLuint buffer); +GLAPI GLboolean APIENTRY glIsNamedBufferResidentNV (GLuint buffer); +GLAPI void APIENTRY glGetBufferParameterui64vNV (GLenum target, GLenum pname, GLuint64EXT *params); +GLAPI void APIENTRY glGetNamedBufferParameterui64vNV (GLuint buffer, GLenum pname, GLuint64EXT *params); +GLAPI void APIENTRY glGetIntegerui64vNV (GLenum value, GLuint64EXT *result); +GLAPI void APIENTRY glUniformui64NV (GLint location, GLuint64EXT value); +GLAPI void APIENTRY glUniformui64vNV (GLint location, GLsizei count, const GLuint64EXT *value); +GLAPI void APIENTRY glProgramUniformui64NV (GLuint program, GLint location, GLuint64EXT value); +GLAPI void APIENTRY glProgramUniformui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +#endif +#endif /* GL_NV_shader_buffer_load */ + +#ifndef GL_NV_shader_buffer_store +#define GL_NV_shader_buffer_store 1 +#define GL_SHADER_GLOBAL_ACCESS_BARRIER_BIT_NV 0x00000010 +#endif /* GL_NV_shader_buffer_store */ + +#ifndef GL_NV_shader_storage_buffer_object +#define GL_NV_shader_storage_buffer_object 1 +#endif /* GL_NV_shader_storage_buffer_object */ + +#ifndef GL_NV_shader_thread_group +#define GL_NV_shader_thread_group 1 +#define GL_WARP_SIZE_NV 0x9339 +#define GL_WARPS_PER_SM_NV 0x933A +#define GL_SM_COUNT_NV 0x933B +#endif /* GL_NV_shader_thread_group */ + +#ifndef GL_NV_shader_thread_shuffle +#define GL_NV_shader_thread_shuffle 1 +#endif /* GL_NV_shader_thread_shuffle */ + +#ifndef GL_NV_tessellation_program5 +#define GL_NV_tessellation_program5 1 +#define GL_MAX_PROGRAM_PATCH_ATTRIBS_NV 0x86D8 +#define GL_TESS_CONTROL_PROGRAM_NV 0x891E +#define GL_TESS_EVALUATION_PROGRAM_NV 0x891F +#define GL_TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV 0x8C74 +#define GL_TESS_EVALUATION_PROGRAM_PARAMETER_BUFFER_NV 0x8C75 +#endif /* GL_NV_tessellation_program5 */ + +#ifndef GL_NV_texgen_emboss +#define GL_NV_texgen_emboss 1 +#define GL_EMBOSS_LIGHT_NV 0x855D +#define GL_EMBOSS_CONSTANT_NV 0x855E +#define GL_EMBOSS_MAP_NV 0x855F +#endif /* GL_NV_texgen_emboss */ + +#ifndef GL_NV_texgen_reflection +#define GL_NV_texgen_reflection 1 +#define GL_NORMAL_MAP_NV 0x8511 +#define GL_REFLECTION_MAP_NV 0x8512 +#endif /* GL_NV_texgen_reflection */ + +#ifndef GL_NV_texture_barrier +#define GL_NV_texture_barrier 1 +typedef void (APIENTRYP PFNGLTEXTUREBARRIERNVPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTextureBarrierNV (void); +#endif +#endif /* GL_NV_texture_barrier */ + +#ifndef GL_NV_texture_compression_vtc +#define GL_NV_texture_compression_vtc 1 +#endif /* GL_NV_texture_compression_vtc */ + +#ifndef GL_NV_texture_env_combine4 +#define GL_NV_texture_env_combine4 1 +#define GL_COMBINE4_NV 0x8503 +#define GL_SOURCE3_RGB_NV 0x8583 +#define GL_SOURCE3_ALPHA_NV 0x858B +#define GL_OPERAND3_RGB_NV 0x8593 +#define GL_OPERAND3_ALPHA_NV 0x859B +#endif /* GL_NV_texture_env_combine4 */ + +#ifndef GL_NV_texture_expand_normal +#define GL_NV_texture_expand_normal 1 +#define GL_TEXTURE_UNSIGNED_REMAP_MODE_NV 0x888F +#endif /* GL_NV_texture_expand_normal */ + +#ifndef GL_NV_texture_multisample +#define GL_NV_texture_multisample 1 +#define GL_TEXTURE_COVERAGE_SAMPLES_NV 0x9045 +#define GL_TEXTURE_COLOR_SAMPLES_NV 0x9046 +typedef void (APIENTRYP PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); +typedef void (APIENTRYP PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); +typedef void (APIENTRYP PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC) (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); +typedef void (APIENTRYP PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC) (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); +typedef void (APIENTRYP PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC) (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); +typedef void (APIENTRYP PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC) (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexImage2DMultisampleCoverageNV (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); +GLAPI void APIENTRY glTexImage3DMultisampleCoverageNV (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); +GLAPI void APIENTRY glTextureImage2DMultisampleNV (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); +GLAPI void APIENTRY glTextureImage3DMultisampleNV (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); +GLAPI void APIENTRY glTextureImage2DMultisampleCoverageNV (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); +GLAPI void APIENTRY glTextureImage3DMultisampleCoverageNV (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); +#endif +#endif /* GL_NV_texture_multisample */ + +#ifndef GL_NV_texture_rectangle +#define GL_NV_texture_rectangle 1 +#define GL_TEXTURE_RECTANGLE_NV 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE_NV 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE_NV 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_NV 0x84F8 +#endif /* GL_NV_texture_rectangle */ + +#ifndef GL_NV_texture_shader +#define GL_NV_texture_shader 1 +#define GL_OFFSET_TEXTURE_RECTANGLE_NV 0x864C +#define GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV 0x864D +#define GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV 0x864E +#define GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV 0x86D9 +#define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA +#define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB +#define GL_DSDT_MAG_INTENSITY_NV 0x86DC +#define GL_SHADER_CONSISTENT_NV 0x86DD +#define GL_TEXTURE_SHADER_NV 0x86DE +#define GL_SHADER_OPERATION_NV 0x86DF +#define GL_CULL_MODES_NV 0x86E0 +#define GL_OFFSET_TEXTURE_MATRIX_NV 0x86E1 +#define GL_OFFSET_TEXTURE_SCALE_NV 0x86E2 +#define GL_OFFSET_TEXTURE_BIAS_NV 0x86E3 +#define GL_OFFSET_TEXTURE_2D_MATRIX_NV 0x86E1 +#define GL_OFFSET_TEXTURE_2D_SCALE_NV 0x86E2 +#define GL_OFFSET_TEXTURE_2D_BIAS_NV 0x86E3 +#define GL_PREVIOUS_TEXTURE_INPUT_NV 0x86E4 +#define GL_CONST_EYE_NV 0x86E5 +#define GL_PASS_THROUGH_NV 0x86E6 +#define GL_CULL_FRAGMENT_NV 0x86E7 +#define GL_OFFSET_TEXTURE_2D_NV 0x86E8 +#define GL_DEPENDENT_AR_TEXTURE_2D_NV 0x86E9 +#define GL_DEPENDENT_GB_TEXTURE_2D_NV 0x86EA +#define GL_DOT_PRODUCT_NV 0x86EC +#define GL_DOT_PRODUCT_DEPTH_REPLACE_NV 0x86ED +#define GL_DOT_PRODUCT_TEXTURE_2D_NV 0x86EE +#define GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV 0x86F0 +#define GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV 0x86F1 +#define GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV 0x86F2 +#define GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV 0x86F3 +#define GL_HILO_NV 0x86F4 +#define GL_DSDT_NV 0x86F5 +#define GL_DSDT_MAG_NV 0x86F6 +#define GL_DSDT_MAG_VIB_NV 0x86F7 +#define GL_HILO16_NV 0x86F8 +#define GL_SIGNED_HILO_NV 0x86F9 +#define GL_SIGNED_HILO16_NV 0x86FA +#define GL_SIGNED_RGBA_NV 0x86FB +#define GL_SIGNED_RGBA8_NV 0x86FC +#define GL_SIGNED_RGB_NV 0x86FE +#define GL_SIGNED_RGB8_NV 0x86FF +#define GL_SIGNED_LUMINANCE_NV 0x8701 +#define GL_SIGNED_LUMINANCE8_NV 0x8702 +#define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703 +#define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704 +#define GL_SIGNED_ALPHA_NV 0x8705 +#define GL_SIGNED_ALPHA8_NV 0x8706 +#define GL_SIGNED_INTENSITY_NV 0x8707 +#define GL_SIGNED_INTENSITY8_NV 0x8708 +#define GL_DSDT8_NV 0x8709 +#define GL_DSDT8_MAG8_NV 0x870A +#define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B +#define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C +#define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D +#define GL_HI_SCALE_NV 0x870E +#define GL_LO_SCALE_NV 0x870F +#define GL_DS_SCALE_NV 0x8710 +#define GL_DT_SCALE_NV 0x8711 +#define GL_MAGNITUDE_SCALE_NV 0x8712 +#define GL_VIBRANCE_SCALE_NV 0x8713 +#define GL_HI_BIAS_NV 0x8714 +#define GL_LO_BIAS_NV 0x8715 +#define GL_DS_BIAS_NV 0x8716 +#define GL_DT_BIAS_NV 0x8717 +#define GL_MAGNITUDE_BIAS_NV 0x8718 +#define GL_VIBRANCE_BIAS_NV 0x8719 +#define GL_TEXTURE_BORDER_VALUES_NV 0x871A +#define GL_TEXTURE_HI_SIZE_NV 0x871B +#define GL_TEXTURE_LO_SIZE_NV 0x871C +#define GL_TEXTURE_DS_SIZE_NV 0x871D +#define GL_TEXTURE_DT_SIZE_NV 0x871E +#define GL_TEXTURE_MAG_SIZE_NV 0x871F +#endif /* GL_NV_texture_shader */ + +#ifndef GL_NV_texture_shader2 +#define GL_NV_texture_shader2 1 +#define GL_DOT_PRODUCT_TEXTURE_3D_NV 0x86EF +#endif /* GL_NV_texture_shader2 */ + +#ifndef GL_NV_texture_shader3 +#define GL_NV_texture_shader3 1 +#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV 0x8850 +#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV 0x8851 +#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8852 +#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV 0x8853 +#define GL_OFFSET_HILO_TEXTURE_2D_NV 0x8854 +#define GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV 0x8855 +#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV 0x8856 +#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8857 +#define GL_DEPENDENT_HILO_TEXTURE_2D_NV 0x8858 +#define GL_DEPENDENT_RGB_TEXTURE_3D_NV 0x8859 +#define GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV 0x885A +#define GL_DOT_PRODUCT_PASS_THROUGH_NV 0x885B +#define GL_DOT_PRODUCT_TEXTURE_1D_NV 0x885C +#define GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV 0x885D +#define GL_HILO8_NV 0x885E +#define GL_SIGNED_HILO8_NV 0x885F +#define GL_FORCE_BLUE_TO_ONE_NV 0x8860 +#endif /* GL_NV_texture_shader3 */ + +#ifndef GL_NV_transform_feedback +#define GL_NV_transform_feedback 1 +#define GL_BACK_PRIMARY_COLOR_NV 0x8C77 +#define GL_BACK_SECONDARY_COLOR_NV 0x8C78 +#define GL_TEXTURE_COORD_NV 0x8C79 +#define GL_CLIP_DISTANCE_NV 0x8C7A +#define GL_VERTEX_ID_NV 0x8C7B +#define GL_PRIMITIVE_ID_NV 0x8C7C +#define GL_GENERIC_ATTRIB_NV 0x8C7D +#define GL_TRANSFORM_FEEDBACK_ATTRIBS_NV 0x8C7E +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_NV 0x8C7F +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV 0x8C80 +#define GL_ACTIVE_VARYINGS_NV 0x8C81 +#define GL_ACTIVE_VARYING_MAX_LENGTH_NV 0x8C82 +#define GL_TRANSFORM_FEEDBACK_VARYINGS_NV 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START_NV 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_NV 0x8C85 +#define GL_TRANSFORM_FEEDBACK_RECORD_NV 0x8C86 +#define GL_PRIMITIVES_GENERATED_NV 0x8C87 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV 0x8C88 +#define GL_RASTERIZER_DISCARD_NV 0x8C89 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_NV 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV 0x8C8B +#define GL_INTERLEAVED_ATTRIBS_NV 0x8C8C +#define GL_SEPARATE_ATTRIBS_NV 0x8C8D +#define GL_TRANSFORM_FEEDBACK_BUFFER_NV 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_NV 0x8C8F +#define GL_LAYER_NV 0x8DAA +#define GL_NEXT_BUFFER_NV -2 +#define GL_SKIP_COMPONENTS4_NV -3 +#define GL_SKIP_COMPONENTS3_NV -4 +#define GL_SKIP_COMPONENTS2_NV -5 +#define GL_SKIP_COMPONENTS1_NV -6 +typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKNVPROC) (GLenum primitiveMode); +typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKNVPROC) (void); +typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC) (GLsizei count, const GLint *attribs, GLenum bufferMode); +typedef void (APIENTRYP PFNGLBINDBUFFERRANGENVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (APIENTRYP PFNGLBINDBUFFEROFFSETNVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset); +typedef void (APIENTRYP PFNGLBINDBUFFERBASENVPROC) (GLenum target, GLuint index, GLuint buffer); +typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC) (GLuint program, GLsizei count, const GLint *locations, GLenum bufferMode); +typedef void (APIENTRYP PFNGLACTIVEVARYINGNVPROC) (GLuint program, const GLchar *name); +typedef GLint (APIENTRYP PFNGLGETVARYINGLOCATIONNVPROC) (GLuint program, const GLchar *name); +typedef void (APIENTRYP PFNGLGETACTIVEVARYINGNVPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); +typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC) (GLuint program, GLuint index, GLint *location); +typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKSTREAMATTRIBSNVPROC) (GLsizei count, const GLint *attribs, GLsizei nbuffers, const GLint *bufstreams, GLenum bufferMode); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBeginTransformFeedbackNV (GLenum primitiveMode); +GLAPI void APIENTRY glEndTransformFeedbackNV (void); +GLAPI void APIENTRY glTransformFeedbackAttribsNV (GLsizei count, const GLint *attribs, GLenum bufferMode); +GLAPI void APIENTRY glBindBufferRangeNV (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +GLAPI void APIENTRY glBindBufferOffsetNV (GLenum target, GLuint index, GLuint buffer, GLintptr offset); +GLAPI void APIENTRY glBindBufferBaseNV (GLenum target, GLuint index, GLuint buffer); +GLAPI void APIENTRY glTransformFeedbackVaryingsNV (GLuint program, GLsizei count, const GLint *locations, GLenum bufferMode); +GLAPI void APIENTRY glActiveVaryingNV (GLuint program, const GLchar *name); +GLAPI GLint APIENTRY glGetVaryingLocationNV (GLuint program, const GLchar *name); +GLAPI void APIENTRY glGetActiveVaryingNV (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); +GLAPI void APIENTRY glGetTransformFeedbackVaryingNV (GLuint program, GLuint index, GLint *location); +GLAPI void APIENTRY glTransformFeedbackStreamAttribsNV (GLsizei count, const GLint *attribs, GLsizei nbuffers, const GLint *bufstreams, GLenum bufferMode); +#endif +#endif /* GL_NV_transform_feedback */ + +#ifndef GL_NV_transform_feedback2 +#define GL_NV_transform_feedback2 1 +#define GL_TRANSFORM_FEEDBACK_NV 0x8E22 +#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED_NV 0x8E23 +#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE_NV 0x8E24 +#define GL_TRANSFORM_FEEDBACK_BINDING_NV 0x8E25 +typedef void (APIENTRYP PFNGLBINDTRANSFORMFEEDBACKNVPROC) (GLenum target, GLuint id); +typedef void (APIENTRYP PFNGLDELETETRANSFORMFEEDBACKSNVPROC) (GLsizei n, const GLuint *ids); +typedef void (APIENTRYP PFNGLGENTRANSFORMFEEDBACKSNVPROC) (GLsizei n, GLuint *ids); +typedef GLboolean (APIENTRYP PFNGLISTRANSFORMFEEDBACKNVPROC) (GLuint id); +typedef void (APIENTRYP PFNGLPAUSETRANSFORMFEEDBACKNVPROC) (void); +typedef void (APIENTRYP PFNGLRESUMETRANSFORMFEEDBACKNVPROC) (void); +typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKNVPROC) (GLenum mode, GLuint id); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBindTransformFeedbackNV (GLenum target, GLuint id); +GLAPI void APIENTRY glDeleteTransformFeedbacksNV (GLsizei n, const GLuint *ids); +GLAPI void APIENTRY glGenTransformFeedbacksNV (GLsizei n, GLuint *ids); +GLAPI GLboolean APIENTRY glIsTransformFeedbackNV (GLuint id); +GLAPI void APIENTRY glPauseTransformFeedbackNV (void); +GLAPI void APIENTRY glResumeTransformFeedbackNV (void); +GLAPI void APIENTRY glDrawTransformFeedbackNV (GLenum mode, GLuint id); +#endif +#endif /* GL_NV_transform_feedback2 */ + +#ifndef GL_NV_vdpau_interop +#define GL_NV_vdpau_interop 1 +typedef GLintptr GLvdpauSurfaceNV; +#define GL_SURFACE_STATE_NV 0x86EB +#define GL_SURFACE_REGISTERED_NV 0x86FD +#define GL_SURFACE_MAPPED_NV 0x8700 +#define GL_WRITE_DISCARD_NV 0x88BE +typedef void (APIENTRYP PFNGLVDPAUINITNVPROC) (const void *vdpDevice, const void *getProcAddress); +typedef void (APIENTRYP PFNGLVDPAUFININVPROC) (void); +typedef GLvdpauSurfaceNV (APIENTRYP PFNGLVDPAUREGISTERVIDEOSURFACENVPROC) (const void *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames); +typedef GLvdpauSurfaceNV (APIENTRYP PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC) (const void *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames); +typedef GLboolean (APIENTRYP PFNGLVDPAUISSURFACENVPROC) (GLvdpauSurfaceNV surface); +typedef void (APIENTRYP PFNGLVDPAUUNREGISTERSURFACENVPROC) (GLvdpauSurfaceNV surface); +typedef void (APIENTRYP PFNGLVDPAUGETSURFACEIVNVPROC) (GLvdpauSurfaceNV surface, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); +typedef void (APIENTRYP PFNGLVDPAUSURFACEACCESSNVPROC) (GLvdpauSurfaceNV surface, GLenum access); +typedef void (APIENTRYP PFNGLVDPAUMAPSURFACESNVPROC) (GLsizei numSurfaces, const GLvdpauSurfaceNV *surfaces); +typedef void (APIENTRYP PFNGLVDPAUUNMAPSURFACESNVPROC) (GLsizei numSurface, const GLvdpauSurfaceNV *surfaces); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVDPAUInitNV (const void *vdpDevice, const void *getProcAddress); +GLAPI void APIENTRY glVDPAUFiniNV (void); +GLAPI GLvdpauSurfaceNV APIENTRY glVDPAURegisterVideoSurfaceNV (const void *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames); +GLAPI GLvdpauSurfaceNV APIENTRY glVDPAURegisterOutputSurfaceNV (const void *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames); +GLAPI GLboolean APIENTRY glVDPAUIsSurfaceNV (GLvdpauSurfaceNV surface); +GLAPI void APIENTRY glVDPAUUnregisterSurfaceNV (GLvdpauSurfaceNV surface); +GLAPI void APIENTRY glVDPAUGetSurfaceivNV (GLvdpauSurfaceNV surface, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); +GLAPI void APIENTRY glVDPAUSurfaceAccessNV (GLvdpauSurfaceNV surface, GLenum access); +GLAPI void APIENTRY glVDPAUMapSurfacesNV (GLsizei numSurfaces, const GLvdpauSurfaceNV *surfaces); +GLAPI void APIENTRY glVDPAUUnmapSurfacesNV (GLsizei numSurface, const GLvdpauSurfaceNV *surfaces); +#endif +#endif /* GL_NV_vdpau_interop */ + +#ifndef GL_NV_vertex_array_range +#define GL_NV_vertex_array_range 1 +#define GL_VERTEX_ARRAY_RANGE_NV 0x851D +#define GL_VERTEX_ARRAY_RANGE_LENGTH_NV 0x851E +#define GL_VERTEX_ARRAY_RANGE_VALID_NV 0x851F +#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV 0x8520 +#define GL_VERTEX_ARRAY_RANGE_POINTER_NV 0x8521 +typedef void (APIENTRYP PFNGLFLUSHVERTEXARRAYRANGENVPROC) (void); +typedef void (APIENTRYP PFNGLVERTEXARRAYRANGENVPROC) (GLsizei length, const void *pointer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFlushVertexArrayRangeNV (void); +GLAPI void APIENTRY glVertexArrayRangeNV (GLsizei length, const void *pointer); +#endif +#endif /* GL_NV_vertex_array_range */ + +#ifndef GL_NV_vertex_array_range2 +#define GL_NV_vertex_array_range2 1 +#define GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV 0x8533 +#endif /* GL_NV_vertex_array_range2 */ + +#ifndef GL_NV_vertex_attrib_integer_64bit +#define GL_NV_vertex_attrib_integer_64bit 1 +typedef void (APIENTRYP PFNGLVERTEXATTRIBL1I64NVPROC) (GLuint index, GLint64EXT x); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL2I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL3I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL4I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL1I64VNVPROC) (GLuint index, const GLint64EXT *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL2I64VNVPROC) (GLuint index, const GLint64EXT *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL3I64VNVPROC) (GLuint index, const GLint64EXT *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL4I64VNVPROC) (GLuint index, const GLint64EXT *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL1UI64NVPROC) (GLuint index, GLuint64EXT x); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL2UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL3UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL4UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL1UI64VNVPROC) (GLuint index, const GLuint64EXT *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL2UI64VNVPROC) (GLuint index, const GLuint64EXT *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL3UI64VNVPROC) (GLuint index, const GLuint64EXT *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL4UI64VNVPROC) (GLuint index, const GLuint64EXT *v); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLI64VNVPROC) (GLuint index, GLenum pname, GLint64EXT *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLUI64VNVPROC) (GLuint index, GLenum pname, GLuint64EXT *params); +typedef void (APIENTRYP PFNGLVERTEXATTRIBLFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexAttribL1i64NV (GLuint index, GLint64EXT x); +GLAPI void APIENTRY glVertexAttribL2i64NV (GLuint index, GLint64EXT x, GLint64EXT y); +GLAPI void APIENTRY glVertexAttribL3i64NV (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z); +GLAPI void APIENTRY glVertexAttribL4i64NV (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); +GLAPI void APIENTRY glVertexAttribL1i64vNV (GLuint index, const GLint64EXT *v); +GLAPI void APIENTRY glVertexAttribL2i64vNV (GLuint index, const GLint64EXT *v); +GLAPI void APIENTRY glVertexAttribL3i64vNV (GLuint index, const GLint64EXT *v); +GLAPI void APIENTRY glVertexAttribL4i64vNV (GLuint index, const GLint64EXT *v); +GLAPI void APIENTRY glVertexAttribL1ui64NV (GLuint index, GLuint64EXT x); +GLAPI void APIENTRY glVertexAttribL2ui64NV (GLuint index, GLuint64EXT x, GLuint64EXT y); +GLAPI void APIENTRY glVertexAttribL3ui64NV (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); +GLAPI void APIENTRY glVertexAttribL4ui64NV (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); +GLAPI void APIENTRY glVertexAttribL1ui64vNV (GLuint index, const GLuint64EXT *v); +GLAPI void APIENTRY glVertexAttribL2ui64vNV (GLuint index, const GLuint64EXT *v); +GLAPI void APIENTRY glVertexAttribL3ui64vNV (GLuint index, const GLuint64EXT *v); +GLAPI void APIENTRY glVertexAttribL4ui64vNV (GLuint index, const GLuint64EXT *v); +GLAPI void APIENTRY glGetVertexAttribLi64vNV (GLuint index, GLenum pname, GLint64EXT *params); +GLAPI void APIENTRY glGetVertexAttribLui64vNV (GLuint index, GLenum pname, GLuint64EXT *params); +GLAPI void APIENTRY glVertexAttribLFormatNV (GLuint index, GLint size, GLenum type, GLsizei stride); +#endif +#endif /* GL_NV_vertex_attrib_integer_64bit */ + +#ifndef GL_NV_vertex_buffer_unified_memory +#define GL_NV_vertex_buffer_unified_memory 1 +#define GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV 0x8F1E +#define GL_ELEMENT_ARRAY_UNIFIED_NV 0x8F1F +#define GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV 0x8F20 +#define GL_VERTEX_ARRAY_ADDRESS_NV 0x8F21 +#define GL_NORMAL_ARRAY_ADDRESS_NV 0x8F22 +#define GL_COLOR_ARRAY_ADDRESS_NV 0x8F23 +#define GL_INDEX_ARRAY_ADDRESS_NV 0x8F24 +#define GL_TEXTURE_COORD_ARRAY_ADDRESS_NV 0x8F25 +#define GL_EDGE_FLAG_ARRAY_ADDRESS_NV 0x8F26 +#define GL_SECONDARY_COLOR_ARRAY_ADDRESS_NV 0x8F27 +#define GL_FOG_COORD_ARRAY_ADDRESS_NV 0x8F28 +#define GL_ELEMENT_ARRAY_ADDRESS_NV 0x8F29 +#define GL_VERTEX_ATTRIB_ARRAY_LENGTH_NV 0x8F2A +#define GL_VERTEX_ARRAY_LENGTH_NV 0x8F2B +#define GL_NORMAL_ARRAY_LENGTH_NV 0x8F2C +#define GL_COLOR_ARRAY_LENGTH_NV 0x8F2D +#define GL_INDEX_ARRAY_LENGTH_NV 0x8F2E +#define GL_TEXTURE_COORD_ARRAY_LENGTH_NV 0x8F2F +#define GL_EDGE_FLAG_ARRAY_LENGTH_NV 0x8F30 +#define GL_SECONDARY_COLOR_ARRAY_LENGTH_NV 0x8F31 +#define GL_FOG_COORD_ARRAY_LENGTH_NV 0x8F32 +#define GL_ELEMENT_ARRAY_LENGTH_NV 0x8F33 +#define GL_DRAW_INDIRECT_UNIFIED_NV 0x8F40 +#define GL_DRAW_INDIRECT_ADDRESS_NV 0x8F41 +#define GL_DRAW_INDIRECT_LENGTH_NV 0x8F42 +typedef void (APIENTRYP PFNGLBUFFERADDRESSRANGENVPROC) (GLenum pname, GLuint index, GLuint64EXT address, GLsizeiptr length); +typedef void (APIENTRYP PFNGLVERTEXFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); +typedef void (APIENTRYP PFNGLNORMALFORMATNVPROC) (GLenum type, GLsizei stride); +typedef void (APIENTRYP PFNGLCOLORFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); +typedef void (APIENTRYP PFNGLINDEXFORMATNVPROC) (GLenum type, GLsizei stride); +typedef void (APIENTRYP PFNGLTEXCOORDFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); +typedef void (APIENTRYP PFNGLEDGEFLAGFORMATNVPROC) (GLsizei stride); +typedef void (APIENTRYP PFNGLSECONDARYCOLORFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); +typedef void (APIENTRYP PFNGLFOGCOORDFORMATNVPROC) (GLenum type, GLsizei stride); +typedef void (APIENTRYP PFNGLVERTEXATTRIBFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride); +typedef void (APIENTRYP PFNGLVERTEXATTRIBIFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride); +typedef void (APIENTRYP PFNGLGETINTEGERUI64I_VNVPROC) (GLenum value, GLuint index, GLuint64EXT *result); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBufferAddressRangeNV (GLenum pname, GLuint index, GLuint64EXT address, GLsizeiptr length); +GLAPI void APIENTRY glVertexFormatNV (GLint size, GLenum type, GLsizei stride); +GLAPI void APIENTRY glNormalFormatNV (GLenum type, GLsizei stride); +GLAPI void APIENTRY glColorFormatNV (GLint size, GLenum type, GLsizei stride); +GLAPI void APIENTRY glIndexFormatNV (GLenum type, GLsizei stride); +GLAPI void APIENTRY glTexCoordFormatNV (GLint size, GLenum type, GLsizei stride); +GLAPI void APIENTRY glEdgeFlagFormatNV (GLsizei stride); +GLAPI void APIENTRY glSecondaryColorFormatNV (GLint size, GLenum type, GLsizei stride); +GLAPI void APIENTRY glFogCoordFormatNV (GLenum type, GLsizei stride); +GLAPI void APIENTRY glVertexAttribFormatNV (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride); +GLAPI void APIENTRY glVertexAttribIFormatNV (GLuint index, GLint size, GLenum type, GLsizei stride); +GLAPI void APIENTRY glGetIntegerui64i_vNV (GLenum value, GLuint index, GLuint64EXT *result); +#endif +#endif /* GL_NV_vertex_buffer_unified_memory */ + +#ifndef GL_NV_vertex_program +#define GL_NV_vertex_program 1 +#define GL_VERTEX_PROGRAM_NV 0x8620 +#define GL_VERTEX_STATE_PROGRAM_NV 0x8621 +#define GL_ATTRIB_ARRAY_SIZE_NV 0x8623 +#define GL_ATTRIB_ARRAY_STRIDE_NV 0x8624 +#define GL_ATTRIB_ARRAY_TYPE_NV 0x8625 +#define GL_CURRENT_ATTRIB_NV 0x8626 +#define GL_PROGRAM_LENGTH_NV 0x8627 +#define GL_PROGRAM_STRING_NV 0x8628 +#define GL_MODELVIEW_PROJECTION_NV 0x8629 +#define GL_IDENTITY_NV 0x862A +#define GL_INVERSE_NV 0x862B +#define GL_TRANSPOSE_NV 0x862C +#define GL_INVERSE_TRANSPOSE_NV 0x862D +#define GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV 0x862E +#define GL_MAX_TRACK_MATRICES_NV 0x862F +#define GL_MATRIX0_NV 0x8630 +#define GL_MATRIX1_NV 0x8631 +#define GL_MATRIX2_NV 0x8632 +#define GL_MATRIX3_NV 0x8633 +#define GL_MATRIX4_NV 0x8634 +#define GL_MATRIX5_NV 0x8635 +#define GL_MATRIX6_NV 0x8636 +#define GL_MATRIX7_NV 0x8637 +#define GL_CURRENT_MATRIX_STACK_DEPTH_NV 0x8640 +#define GL_CURRENT_MATRIX_NV 0x8641 +#define GL_VERTEX_PROGRAM_POINT_SIZE_NV 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE_NV 0x8643 +#define GL_PROGRAM_PARAMETER_NV 0x8644 +#define GL_ATTRIB_ARRAY_POINTER_NV 0x8645 +#define GL_PROGRAM_TARGET_NV 0x8646 +#define GL_PROGRAM_RESIDENT_NV 0x8647 +#define GL_TRACK_MATRIX_NV 0x8648 +#define GL_TRACK_MATRIX_TRANSFORM_NV 0x8649 +#define GL_VERTEX_PROGRAM_BINDING_NV 0x864A +#define GL_PROGRAM_ERROR_POSITION_NV 0x864B +#define GL_VERTEX_ATTRIB_ARRAY0_NV 0x8650 +#define GL_VERTEX_ATTRIB_ARRAY1_NV 0x8651 +#define GL_VERTEX_ATTRIB_ARRAY2_NV 0x8652 +#define GL_VERTEX_ATTRIB_ARRAY3_NV 0x8653 +#define GL_VERTEX_ATTRIB_ARRAY4_NV 0x8654 +#define GL_VERTEX_ATTRIB_ARRAY5_NV 0x8655 +#define GL_VERTEX_ATTRIB_ARRAY6_NV 0x8656 +#define GL_VERTEX_ATTRIB_ARRAY7_NV 0x8657 +#define GL_VERTEX_ATTRIB_ARRAY8_NV 0x8658 +#define GL_VERTEX_ATTRIB_ARRAY9_NV 0x8659 +#define GL_VERTEX_ATTRIB_ARRAY10_NV 0x865A +#define GL_VERTEX_ATTRIB_ARRAY11_NV 0x865B +#define GL_VERTEX_ATTRIB_ARRAY12_NV 0x865C +#define GL_VERTEX_ATTRIB_ARRAY13_NV 0x865D +#define GL_VERTEX_ATTRIB_ARRAY14_NV 0x865E +#define GL_VERTEX_ATTRIB_ARRAY15_NV 0x865F +#define GL_MAP1_VERTEX_ATTRIB0_4_NV 0x8660 +#define GL_MAP1_VERTEX_ATTRIB1_4_NV 0x8661 +#define GL_MAP1_VERTEX_ATTRIB2_4_NV 0x8662 +#define GL_MAP1_VERTEX_ATTRIB3_4_NV 0x8663 +#define GL_MAP1_VERTEX_ATTRIB4_4_NV 0x8664 +#define GL_MAP1_VERTEX_ATTRIB5_4_NV 0x8665 +#define GL_MAP1_VERTEX_ATTRIB6_4_NV 0x8666 +#define GL_MAP1_VERTEX_ATTRIB7_4_NV 0x8667 +#define GL_MAP1_VERTEX_ATTRIB8_4_NV 0x8668 +#define GL_MAP1_VERTEX_ATTRIB9_4_NV 0x8669 +#define GL_MAP1_VERTEX_ATTRIB10_4_NV 0x866A +#define GL_MAP1_VERTEX_ATTRIB11_4_NV 0x866B +#define GL_MAP1_VERTEX_ATTRIB12_4_NV 0x866C +#define GL_MAP1_VERTEX_ATTRIB13_4_NV 0x866D +#define GL_MAP1_VERTEX_ATTRIB14_4_NV 0x866E +#define GL_MAP1_VERTEX_ATTRIB15_4_NV 0x866F +#define GL_MAP2_VERTEX_ATTRIB0_4_NV 0x8670 +#define GL_MAP2_VERTEX_ATTRIB1_4_NV 0x8671 +#define GL_MAP2_VERTEX_ATTRIB2_4_NV 0x8672 +#define GL_MAP2_VERTEX_ATTRIB3_4_NV 0x8673 +#define GL_MAP2_VERTEX_ATTRIB4_4_NV 0x8674 +#define GL_MAP2_VERTEX_ATTRIB5_4_NV 0x8675 +#define GL_MAP2_VERTEX_ATTRIB6_4_NV 0x8676 +#define GL_MAP2_VERTEX_ATTRIB7_4_NV 0x8677 +#define GL_MAP2_VERTEX_ATTRIB8_4_NV 0x8678 +#define GL_MAP2_VERTEX_ATTRIB9_4_NV 0x8679 +#define GL_MAP2_VERTEX_ATTRIB10_4_NV 0x867A +#define GL_MAP2_VERTEX_ATTRIB11_4_NV 0x867B +#define GL_MAP2_VERTEX_ATTRIB12_4_NV 0x867C +#define GL_MAP2_VERTEX_ATTRIB13_4_NV 0x867D +#define GL_MAP2_VERTEX_ATTRIB14_4_NV 0x867E +#define GL_MAP2_VERTEX_ATTRIB15_4_NV 0x867F +typedef GLboolean (APIENTRYP PFNGLAREPROGRAMSRESIDENTNVPROC) (GLsizei n, const GLuint *programs, GLboolean *residences); +typedef void (APIENTRYP PFNGLBINDPROGRAMNVPROC) (GLenum target, GLuint id); +typedef void (APIENTRYP PFNGLDELETEPROGRAMSNVPROC) (GLsizei n, const GLuint *programs); +typedef void (APIENTRYP PFNGLEXECUTEPROGRAMNVPROC) (GLenum target, GLuint id, const GLfloat *params); +typedef void (APIENTRYP PFNGLGENPROGRAMSNVPROC) (GLsizei n, GLuint *programs); +typedef void (APIENTRYP PFNGLGETPROGRAMPARAMETERDVNVPROC) (GLenum target, GLuint index, GLenum pname, GLdouble *params); +typedef void (APIENTRYP PFNGLGETPROGRAMPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETPROGRAMIVNVPROC) (GLuint id, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMSTRINGNVPROC) (GLuint id, GLenum pname, GLubyte *program); +typedef void (APIENTRYP PFNGLGETTRACKMATRIXIVNVPROC) (GLenum target, GLuint address, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVNVPROC) (GLuint index, GLenum pname, GLdouble *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVNVPROC) (GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVNVPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVNVPROC) (GLuint index, GLenum pname, void **pointer); +typedef GLboolean (APIENTRYP PFNGLISPROGRAMNVPROC) (GLuint id); +typedef void (APIENTRYP PFNGLLOADPROGRAMNVPROC) (GLenum target, GLuint id, GLsizei len, const GLubyte *program); +typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4DNVPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4DVNVPROC) (GLenum target, GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4FNVPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4FVNVPROC) (GLenum target, GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLPROGRAMPARAMETERS4DVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLdouble *v); +typedef void (APIENTRYP PFNGLPROGRAMPARAMETERS4FVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat *v); +typedef void (APIENTRYP PFNGLREQUESTRESIDENTPROGRAMSNVPROC) (GLsizei n, const GLuint *programs); +typedef void (APIENTRYP PFNGLTRACKMATRIXNVPROC) (GLenum target, GLuint address, GLenum matrix, GLenum transform); +typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERNVPROC) (GLuint index, GLint fsize, GLenum type, GLsizei stride, const void *pointer); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1DNVPROC) (GLuint index, GLdouble x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVNVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1FNVPROC) (GLuint index, GLfloat x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVNVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1SNVPROC) (GLuint index, GLshort x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVNVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2DNVPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVNVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2FNVPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVNVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2SNVPROC) (GLuint index, GLshort x, GLshort y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVNVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVNVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVNVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVNVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVNVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVNVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVNVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBNVPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVNVPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS1DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS1FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS1SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS2DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS2FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS2SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS3DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS3FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS3SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS4DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS4FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS4SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS4UBVNVPROC) (GLuint index, GLsizei count, const GLubyte *v); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLboolean APIENTRY glAreProgramsResidentNV (GLsizei n, const GLuint *programs, GLboolean *residences); +GLAPI void APIENTRY glBindProgramNV (GLenum target, GLuint id); +GLAPI void APIENTRY glDeleteProgramsNV (GLsizei n, const GLuint *programs); +GLAPI void APIENTRY glExecuteProgramNV (GLenum target, GLuint id, const GLfloat *params); +GLAPI void APIENTRY glGenProgramsNV (GLsizei n, GLuint *programs); +GLAPI void APIENTRY glGetProgramParameterdvNV (GLenum target, GLuint index, GLenum pname, GLdouble *params); +GLAPI void APIENTRY glGetProgramParameterfvNV (GLenum target, GLuint index, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetProgramivNV (GLuint id, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetProgramStringNV (GLuint id, GLenum pname, GLubyte *program); +GLAPI void APIENTRY glGetTrackMatrixivNV (GLenum target, GLuint address, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetVertexAttribdvNV (GLuint index, GLenum pname, GLdouble *params); +GLAPI void APIENTRY glGetVertexAttribfvNV (GLuint index, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetVertexAttribivNV (GLuint index, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetVertexAttribPointervNV (GLuint index, GLenum pname, void **pointer); +GLAPI GLboolean APIENTRY glIsProgramNV (GLuint id); +GLAPI void APIENTRY glLoadProgramNV (GLenum target, GLuint id, GLsizei len, const GLubyte *program); +GLAPI void APIENTRY glProgramParameter4dNV (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void APIENTRY glProgramParameter4dvNV (GLenum target, GLuint index, const GLdouble *v); +GLAPI void APIENTRY glProgramParameter4fNV (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void APIENTRY glProgramParameter4fvNV (GLenum target, GLuint index, const GLfloat *v); +GLAPI void APIENTRY glProgramParameters4dvNV (GLenum target, GLuint index, GLsizei count, const GLdouble *v); +GLAPI void APIENTRY glProgramParameters4fvNV (GLenum target, GLuint index, GLsizei count, const GLfloat *v); +GLAPI void APIENTRY glRequestResidentProgramsNV (GLsizei n, const GLuint *programs); +GLAPI void APIENTRY glTrackMatrixNV (GLenum target, GLuint address, GLenum matrix, GLenum transform); +GLAPI void APIENTRY glVertexAttribPointerNV (GLuint index, GLint fsize, GLenum type, GLsizei stride, const void *pointer); +GLAPI void APIENTRY glVertexAttrib1dNV (GLuint index, GLdouble x); +GLAPI void APIENTRY glVertexAttrib1dvNV (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttrib1fNV (GLuint index, GLfloat x); +GLAPI void APIENTRY glVertexAttrib1fvNV (GLuint index, const GLfloat *v); +GLAPI void APIENTRY glVertexAttrib1sNV (GLuint index, GLshort x); +GLAPI void APIENTRY glVertexAttrib1svNV (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib2dNV (GLuint index, GLdouble x, GLdouble y); +GLAPI void APIENTRY glVertexAttrib2dvNV (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttrib2fNV (GLuint index, GLfloat x, GLfloat y); +GLAPI void APIENTRY glVertexAttrib2fvNV (GLuint index, const GLfloat *v); +GLAPI void APIENTRY glVertexAttrib2sNV (GLuint index, GLshort x, GLshort y); +GLAPI void APIENTRY glVertexAttrib2svNV (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib3dNV (GLuint index, GLdouble x, GLdouble y, GLdouble z); +GLAPI void APIENTRY glVertexAttrib3dvNV (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttrib3fNV (GLuint index, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glVertexAttrib3fvNV (GLuint index, const GLfloat *v); +GLAPI void APIENTRY glVertexAttrib3sNV (GLuint index, GLshort x, GLshort y, GLshort z); +GLAPI void APIENTRY glVertexAttrib3svNV (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib4dNV (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void APIENTRY glVertexAttrib4dvNV (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttrib4fNV (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void APIENTRY glVertexAttrib4fvNV (GLuint index, const GLfloat *v); +GLAPI void APIENTRY glVertexAttrib4sNV (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +GLAPI void APIENTRY glVertexAttrib4svNV (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib4ubNV (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +GLAPI void APIENTRY glVertexAttrib4ubvNV (GLuint index, const GLubyte *v); +GLAPI void APIENTRY glVertexAttribs1dvNV (GLuint index, GLsizei count, const GLdouble *v); +GLAPI void APIENTRY glVertexAttribs1fvNV (GLuint index, GLsizei count, const GLfloat *v); +GLAPI void APIENTRY glVertexAttribs1svNV (GLuint index, GLsizei count, const GLshort *v); +GLAPI void APIENTRY glVertexAttribs2dvNV (GLuint index, GLsizei count, const GLdouble *v); +GLAPI void APIENTRY glVertexAttribs2fvNV (GLuint index, GLsizei count, const GLfloat *v); +GLAPI void APIENTRY glVertexAttribs2svNV (GLuint index, GLsizei count, const GLshort *v); +GLAPI void APIENTRY glVertexAttribs3dvNV (GLuint index, GLsizei count, const GLdouble *v); +GLAPI void APIENTRY glVertexAttribs3fvNV (GLuint index, GLsizei count, const GLfloat *v); +GLAPI void APIENTRY glVertexAttribs3svNV (GLuint index, GLsizei count, const GLshort *v); +GLAPI void APIENTRY glVertexAttribs4dvNV (GLuint index, GLsizei count, const GLdouble *v); +GLAPI void APIENTRY glVertexAttribs4fvNV (GLuint index, GLsizei count, const GLfloat *v); +GLAPI void APIENTRY glVertexAttribs4svNV (GLuint index, GLsizei count, const GLshort *v); +GLAPI void APIENTRY glVertexAttribs4ubvNV (GLuint index, GLsizei count, const GLubyte *v); +#endif +#endif /* GL_NV_vertex_program */ + +#ifndef GL_NV_vertex_program1_1 +#define GL_NV_vertex_program1_1 1 +#endif /* GL_NV_vertex_program1_1 */ + +#ifndef GL_NV_vertex_program2 +#define GL_NV_vertex_program2 1 +#endif /* GL_NV_vertex_program2 */ + +#ifndef GL_NV_vertex_program2_option +#define GL_NV_vertex_program2_option 1 +#endif /* GL_NV_vertex_program2_option */ + +#ifndef GL_NV_vertex_program3 +#define GL_NV_vertex_program3 1 +#endif /* GL_NV_vertex_program3 */ + +#ifndef GL_NV_vertex_program4 +#define GL_NV_vertex_program4 1 +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_NV 0x88FD +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IEXTPROC) (GLuint index, GLint x); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IEXTPROC) (GLuint index, GLint x, GLint y); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IEXTPROC) (GLuint index, GLint x, GLint y, GLint z); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IEXTPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIEXTPROC) (GLuint index, GLuint x); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIEXTPROC) (GLuint index, GLuint x, GLuint y); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IVEXTPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IVEXTPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IVEXTPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IVEXTPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4BVEXTPROC) (GLuint index, const GLbyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4SVEXTPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UBVEXTPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4USVEXTPROC) (GLuint index, const GLushort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVEXTPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVEXTPROC) (GLuint index, GLenum pname, GLuint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexAttribI1iEXT (GLuint index, GLint x); +GLAPI void APIENTRY glVertexAttribI2iEXT (GLuint index, GLint x, GLint y); +GLAPI void APIENTRY glVertexAttribI3iEXT (GLuint index, GLint x, GLint y, GLint z); +GLAPI void APIENTRY glVertexAttribI4iEXT (GLuint index, GLint x, GLint y, GLint z, GLint w); +GLAPI void APIENTRY glVertexAttribI1uiEXT (GLuint index, GLuint x); +GLAPI void APIENTRY glVertexAttribI2uiEXT (GLuint index, GLuint x, GLuint y); +GLAPI void APIENTRY glVertexAttribI3uiEXT (GLuint index, GLuint x, GLuint y, GLuint z); +GLAPI void APIENTRY glVertexAttribI4uiEXT (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +GLAPI void APIENTRY glVertexAttribI1ivEXT (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttribI2ivEXT (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttribI3ivEXT (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttribI4ivEXT (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttribI1uivEXT (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttribI2uivEXT (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttribI3uivEXT (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttribI4uivEXT (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttribI4bvEXT (GLuint index, const GLbyte *v); +GLAPI void APIENTRY glVertexAttribI4svEXT (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttribI4ubvEXT (GLuint index, const GLubyte *v); +GLAPI void APIENTRY glVertexAttribI4usvEXT (GLuint index, const GLushort *v); +GLAPI void APIENTRY glVertexAttribIPointerEXT (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); +GLAPI void APIENTRY glGetVertexAttribIivEXT (GLuint index, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetVertexAttribIuivEXT (GLuint index, GLenum pname, GLuint *params); +#endif +#endif /* GL_NV_vertex_program4 */ + +#ifndef GL_NV_video_capture +#define GL_NV_video_capture 1 +#define GL_VIDEO_BUFFER_NV 0x9020 +#define GL_VIDEO_BUFFER_BINDING_NV 0x9021 +#define GL_FIELD_UPPER_NV 0x9022 +#define GL_FIELD_LOWER_NV 0x9023 +#define GL_NUM_VIDEO_CAPTURE_STREAMS_NV 0x9024 +#define GL_NEXT_VIDEO_CAPTURE_BUFFER_STATUS_NV 0x9025 +#define GL_VIDEO_CAPTURE_TO_422_SUPPORTED_NV 0x9026 +#define GL_LAST_VIDEO_CAPTURE_STATUS_NV 0x9027 +#define GL_VIDEO_BUFFER_PITCH_NV 0x9028 +#define GL_VIDEO_COLOR_CONVERSION_MATRIX_NV 0x9029 +#define GL_VIDEO_COLOR_CONVERSION_MAX_NV 0x902A +#define GL_VIDEO_COLOR_CONVERSION_MIN_NV 0x902B +#define GL_VIDEO_COLOR_CONVERSION_OFFSET_NV 0x902C +#define GL_VIDEO_BUFFER_INTERNAL_FORMAT_NV 0x902D +#define GL_PARTIAL_SUCCESS_NV 0x902E +#define GL_SUCCESS_NV 0x902F +#define GL_FAILURE_NV 0x9030 +#define GL_YCBYCR8_422_NV 0x9031 +#define GL_YCBAYCR8A_4224_NV 0x9032 +#define GL_Z6Y10Z6CB10Z6Y10Z6CR10_422_NV 0x9033 +#define GL_Z6Y10Z6CB10Z6A10Z6Y10Z6CR10Z6A10_4224_NV 0x9034 +#define GL_Z4Y12Z4CB12Z4Y12Z4CR12_422_NV 0x9035 +#define GL_Z4Y12Z4CB12Z4A12Z4Y12Z4CR12Z4A12_4224_NV 0x9036 +#define GL_Z4Y12Z4CB12Z4CR12_444_NV 0x9037 +#define GL_VIDEO_CAPTURE_FRAME_WIDTH_NV 0x9038 +#define GL_VIDEO_CAPTURE_FRAME_HEIGHT_NV 0x9039 +#define GL_VIDEO_CAPTURE_FIELD_UPPER_HEIGHT_NV 0x903A +#define GL_VIDEO_CAPTURE_FIELD_LOWER_HEIGHT_NV 0x903B +#define GL_VIDEO_CAPTURE_SURFACE_ORIGIN_NV 0x903C +typedef void (APIENTRYP PFNGLBEGINVIDEOCAPTURENVPROC) (GLuint video_capture_slot); +typedef void (APIENTRYP PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLintptrARB offset); +typedef void (APIENTRYP PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC) (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLenum target, GLuint texture); +typedef void (APIENTRYP PFNGLENDVIDEOCAPTURENVPROC) (GLuint video_capture_slot); +typedef void (APIENTRYP PFNGLGETVIDEOCAPTUREIVNVPROC) (GLuint video_capture_slot, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETVIDEOCAPTURESTREAMIVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETVIDEOCAPTURESTREAMFVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETVIDEOCAPTURESTREAMDVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLdouble *params); +typedef GLenum (APIENTRYP PFNGLVIDEOCAPTURENVPROC) (GLuint video_capture_slot, GLuint *sequence_num, GLuint64EXT *capture_time); +typedef void (APIENTRYP PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLdouble *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBeginVideoCaptureNV (GLuint video_capture_slot); +GLAPI void APIENTRY glBindVideoCaptureStreamBufferNV (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLintptrARB offset); +GLAPI void APIENTRY glBindVideoCaptureStreamTextureNV (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLenum target, GLuint texture); +GLAPI void APIENTRY glEndVideoCaptureNV (GLuint video_capture_slot); +GLAPI void APIENTRY glGetVideoCaptureivNV (GLuint video_capture_slot, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetVideoCaptureStreamivNV (GLuint video_capture_slot, GLuint stream, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetVideoCaptureStreamfvNV (GLuint video_capture_slot, GLuint stream, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetVideoCaptureStreamdvNV (GLuint video_capture_slot, GLuint stream, GLenum pname, GLdouble *params); +GLAPI GLenum APIENTRY glVideoCaptureNV (GLuint video_capture_slot, GLuint *sequence_num, GLuint64EXT *capture_time); +GLAPI void APIENTRY glVideoCaptureStreamParameterivNV (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLint *params); +GLAPI void APIENTRY glVideoCaptureStreamParameterfvNV (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glVideoCaptureStreamParameterdvNV (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLdouble *params); +#endif +#endif /* GL_NV_video_capture */ + +#ifndef GL_OML_interlace +#define GL_OML_interlace 1 +#define GL_INTERLACE_OML 0x8980 +#define GL_INTERLACE_READ_OML 0x8981 +#endif /* GL_OML_interlace */ + +#ifndef GL_OML_resample +#define GL_OML_resample 1 +#define GL_PACK_RESAMPLE_OML 0x8984 +#define GL_UNPACK_RESAMPLE_OML 0x8985 +#define GL_RESAMPLE_REPLICATE_OML 0x8986 +#define GL_RESAMPLE_ZERO_FILL_OML 0x8987 +#define GL_RESAMPLE_AVERAGE_OML 0x8988 +#define GL_RESAMPLE_DECIMATE_OML 0x8989 +#endif /* GL_OML_resample */ + +#ifndef GL_OML_subsample +#define GL_OML_subsample 1 +#define GL_FORMAT_SUBSAMPLE_24_24_OML 0x8982 +#define GL_FORMAT_SUBSAMPLE_244_244_OML 0x8983 +#endif /* GL_OML_subsample */ + +#ifndef GL_PGI_misc_hints +#define GL_PGI_misc_hints 1 +#define GL_PREFER_DOUBLEBUFFER_HINT_PGI 0x1A1F8 +#define GL_CONSERVE_MEMORY_HINT_PGI 0x1A1FD +#define GL_RECLAIM_MEMORY_HINT_PGI 0x1A1FE +#define GL_NATIVE_GRAPHICS_HANDLE_PGI 0x1A202 +#define GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI 0x1A203 +#define GL_NATIVE_GRAPHICS_END_HINT_PGI 0x1A204 +#define GL_ALWAYS_FAST_HINT_PGI 0x1A20C +#define GL_ALWAYS_SOFT_HINT_PGI 0x1A20D +#define GL_ALLOW_DRAW_OBJ_HINT_PGI 0x1A20E +#define GL_ALLOW_DRAW_WIN_HINT_PGI 0x1A20F +#define GL_ALLOW_DRAW_FRG_HINT_PGI 0x1A210 +#define GL_ALLOW_DRAW_MEM_HINT_PGI 0x1A211 +#define GL_STRICT_DEPTHFUNC_HINT_PGI 0x1A216 +#define GL_STRICT_LIGHTING_HINT_PGI 0x1A217 +#define GL_STRICT_SCISSOR_HINT_PGI 0x1A218 +#define GL_FULL_STIPPLE_HINT_PGI 0x1A219 +#define GL_CLIP_NEAR_HINT_PGI 0x1A220 +#define GL_CLIP_FAR_HINT_PGI 0x1A221 +#define GL_WIDE_LINE_HINT_PGI 0x1A222 +#define GL_BACK_NORMALS_HINT_PGI 0x1A223 +typedef void (APIENTRYP PFNGLHINTPGIPROC) (GLenum target, GLint mode); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glHintPGI (GLenum target, GLint mode); +#endif +#endif /* GL_PGI_misc_hints */ + +#ifndef GL_PGI_vertex_hints +#define GL_PGI_vertex_hints 1 +#define GL_VERTEX_DATA_HINT_PGI 0x1A22A +#define GL_VERTEX_CONSISTENT_HINT_PGI 0x1A22B +#define GL_MATERIAL_SIDE_HINT_PGI 0x1A22C +#define GL_MAX_VERTEX_HINT_PGI 0x1A22D +#define GL_COLOR3_BIT_PGI 0x00010000 +#define GL_COLOR4_BIT_PGI 0x00020000 +#define GL_EDGEFLAG_BIT_PGI 0x00040000 +#define GL_INDEX_BIT_PGI 0x00080000 +#define GL_MAT_AMBIENT_BIT_PGI 0x00100000 +#define GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI 0x00200000 +#define GL_MAT_DIFFUSE_BIT_PGI 0x00400000 +#define GL_MAT_EMISSION_BIT_PGI 0x00800000 +#define GL_MAT_COLOR_INDEXES_BIT_PGI 0x01000000 +#define GL_MAT_SHININESS_BIT_PGI 0x02000000 +#define GL_MAT_SPECULAR_BIT_PGI 0x04000000 +#define GL_NORMAL_BIT_PGI 0x08000000 +#define GL_TEXCOORD1_BIT_PGI 0x10000000 +#define GL_TEXCOORD2_BIT_PGI 0x20000000 +#define GL_TEXCOORD3_BIT_PGI 0x40000000 +#define GL_TEXCOORD4_BIT_PGI 0x80000000 +#define GL_VERTEX23_BIT_PGI 0x00000004 +#define GL_VERTEX4_BIT_PGI 0x00000008 +#endif /* GL_PGI_vertex_hints */ + +#ifndef GL_REND_screen_coordinates +#define GL_REND_screen_coordinates 1 +#define GL_SCREEN_COORDINATES_REND 0x8490 +#define GL_INVERTED_SCREEN_W_REND 0x8491 +#endif /* GL_REND_screen_coordinates */ + +#ifndef GL_S3_s3tc +#define GL_S3_s3tc 1 +#define GL_RGB_S3TC 0x83A0 +#define GL_RGB4_S3TC 0x83A1 +#define GL_RGBA_S3TC 0x83A2 +#define GL_RGBA4_S3TC 0x83A3 +#define GL_RGBA_DXT5_S3TC 0x83A4 +#define GL_RGBA4_DXT5_S3TC 0x83A5 +#endif /* GL_S3_s3tc */ + +#ifndef GL_SGIS_detail_texture +#define GL_SGIS_detail_texture 1 +#define GL_DETAIL_TEXTURE_2D_SGIS 0x8095 +#define GL_DETAIL_TEXTURE_2D_BINDING_SGIS 0x8096 +#define GL_LINEAR_DETAIL_SGIS 0x8097 +#define GL_LINEAR_DETAIL_ALPHA_SGIS 0x8098 +#define GL_LINEAR_DETAIL_COLOR_SGIS 0x8099 +#define GL_DETAIL_TEXTURE_LEVEL_SGIS 0x809A +#define GL_DETAIL_TEXTURE_MODE_SGIS 0x809B +#define GL_DETAIL_TEXTURE_FUNC_POINTS_SGIS 0x809C +typedef void (APIENTRYP PFNGLDETAILTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points); +typedef void (APIENTRYP PFNGLGETDETAILTEXFUNCSGISPROC) (GLenum target, GLfloat *points); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDetailTexFuncSGIS (GLenum target, GLsizei n, const GLfloat *points); +GLAPI void APIENTRY glGetDetailTexFuncSGIS (GLenum target, GLfloat *points); +#endif +#endif /* GL_SGIS_detail_texture */ + +#ifndef GL_SGIS_fog_function +#define GL_SGIS_fog_function 1 +#define GL_FOG_FUNC_SGIS 0x812A +#define GL_FOG_FUNC_POINTS_SGIS 0x812B +#define GL_MAX_FOG_FUNC_POINTS_SGIS 0x812C +typedef void (APIENTRYP PFNGLFOGFUNCSGISPROC) (GLsizei n, const GLfloat *points); +typedef void (APIENTRYP PFNGLGETFOGFUNCSGISPROC) (GLfloat *points); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFogFuncSGIS (GLsizei n, const GLfloat *points); +GLAPI void APIENTRY glGetFogFuncSGIS (GLfloat *points); +#endif +#endif /* GL_SGIS_fog_function */ + +#ifndef GL_SGIS_generate_mipmap +#define GL_SGIS_generate_mipmap 1 +#define GL_GENERATE_MIPMAP_SGIS 0x8191 +#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192 +#endif /* GL_SGIS_generate_mipmap */ + +#ifndef GL_SGIS_multisample +#define GL_SGIS_multisample 1 +#define GL_MULTISAMPLE_SGIS 0x809D +#define GL_SAMPLE_ALPHA_TO_MASK_SGIS 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_SGIS 0x809F +#define GL_SAMPLE_MASK_SGIS 0x80A0 +#define GL_1PASS_SGIS 0x80A1 +#define GL_2PASS_0_SGIS 0x80A2 +#define GL_2PASS_1_SGIS 0x80A3 +#define GL_4PASS_0_SGIS 0x80A4 +#define GL_4PASS_1_SGIS 0x80A5 +#define GL_4PASS_2_SGIS 0x80A6 +#define GL_4PASS_3_SGIS 0x80A7 +#define GL_SAMPLE_BUFFERS_SGIS 0x80A8 +#define GL_SAMPLES_SGIS 0x80A9 +#define GL_SAMPLE_MASK_VALUE_SGIS 0x80AA +#define GL_SAMPLE_MASK_INVERT_SGIS 0x80AB +#define GL_SAMPLE_PATTERN_SGIS 0x80AC +typedef void (APIENTRYP PFNGLSAMPLEMASKSGISPROC) (GLclampf value, GLboolean invert); +typedef void (APIENTRYP PFNGLSAMPLEPATTERNSGISPROC) (GLenum pattern); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSampleMaskSGIS (GLclampf value, GLboolean invert); +GLAPI void APIENTRY glSamplePatternSGIS (GLenum pattern); +#endif +#endif /* GL_SGIS_multisample */ + +#ifndef GL_SGIS_pixel_texture +#define GL_SGIS_pixel_texture 1 +#define GL_PIXEL_TEXTURE_SGIS 0x8353 +#define GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS 0x8354 +#define GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS 0x8355 +#define GL_PIXEL_GROUP_COLOR_SGIS 0x8356 +typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERISGISPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERFSGISPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLGETPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, GLfloat *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPixelTexGenParameteriSGIS (GLenum pname, GLint param); +GLAPI void APIENTRY glPixelTexGenParameterivSGIS (GLenum pname, const GLint *params); +GLAPI void APIENTRY glPixelTexGenParameterfSGIS (GLenum pname, GLfloat param); +GLAPI void APIENTRY glPixelTexGenParameterfvSGIS (GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glGetPixelTexGenParameterivSGIS (GLenum pname, GLint *params); +GLAPI void APIENTRY glGetPixelTexGenParameterfvSGIS (GLenum pname, GLfloat *params); +#endif +#endif /* GL_SGIS_pixel_texture */ + +#ifndef GL_SGIS_point_line_texgen +#define GL_SGIS_point_line_texgen 1 +#define GL_EYE_DISTANCE_TO_POINT_SGIS 0x81F0 +#define GL_OBJECT_DISTANCE_TO_POINT_SGIS 0x81F1 +#define GL_EYE_DISTANCE_TO_LINE_SGIS 0x81F2 +#define GL_OBJECT_DISTANCE_TO_LINE_SGIS 0x81F3 +#define GL_EYE_POINT_SGIS 0x81F4 +#define GL_OBJECT_POINT_SGIS 0x81F5 +#define GL_EYE_LINE_SGIS 0x81F6 +#define GL_OBJECT_LINE_SGIS 0x81F7 +#endif /* GL_SGIS_point_line_texgen */ + +#ifndef GL_SGIS_point_parameters +#define GL_SGIS_point_parameters 1 +#define GL_POINT_SIZE_MIN_SGIS 0x8126 +#define GL_POINT_SIZE_MAX_SGIS 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_SGIS 0x8128 +#define GL_DISTANCE_ATTENUATION_SGIS 0x8129 +typedef void (APIENTRYP PFNGLPOINTPARAMETERFSGISPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLPOINTPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPointParameterfSGIS (GLenum pname, GLfloat param); +GLAPI void APIENTRY glPointParameterfvSGIS (GLenum pname, const GLfloat *params); +#endif +#endif /* GL_SGIS_point_parameters */ + +#ifndef GL_SGIS_sharpen_texture +#define GL_SGIS_sharpen_texture 1 +#define GL_LINEAR_SHARPEN_SGIS 0x80AD +#define GL_LINEAR_SHARPEN_ALPHA_SGIS 0x80AE +#define GL_LINEAR_SHARPEN_COLOR_SGIS 0x80AF +#define GL_SHARPEN_TEXTURE_FUNC_POINTS_SGIS 0x80B0 +typedef void (APIENTRYP PFNGLSHARPENTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points); +typedef void (APIENTRYP PFNGLGETSHARPENTEXFUNCSGISPROC) (GLenum target, GLfloat *points); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSharpenTexFuncSGIS (GLenum target, GLsizei n, const GLfloat *points); +GLAPI void APIENTRY glGetSharpenTexFuncSGIS (GLenum target, GLfloat *points); +#endif +#endif /* GL_SGIS_sharpen_texture */ + +#ifndef GL_SGIS_texture4D +#define GL_SGIS_texture4D 1 +#define GL_PACK_SKIP_VOLUMES_SGIS 0x8130 +#define GL_PACK_IMAGE_DEPTH_SGIS 0x8131 +#define GL_UNPACK_SKIP_VOLUMES_SGIS 0x8132 +#define GL_UNPACK_IMAGE_DEPTH_SGIS 0x8133 +#define GL_TEXTURE_4D_SGIS 0x8134 +#define GL_PROXY_TEXTURE_4D_SGIS 0x8135 +#define GL_TEXTURE_4DSIZE_SGIS 0x8136 +#define GL_TEXTURE_WRAP_Q_SGIS 0x8137 +#define GL_MAX_4D_TEXTURE_SIZE_SGIS 0x8138 +#define GL_TEXTURE_4D_BINDING_SGIS 0x814F +typedef void (APIENTRYP PFNGLTEXIMAGE4DSGISPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLTEXSUBIMAGE4DSGISPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLenum format, GLenum type, const void *pixels); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexImage4DSGIS (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLint border, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glTexSubImage4DSGIS (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLenum format, GLenum type, const void *pixels); +#endif +#endif /* GL_SGIS_texture4D */ + +#ifndef GL_SGIS_texture_border_clamp +#define GL_SGIS_texture_border_clamp 1 +#define GL_CLAMP_TO_BORDER_SGIS 0x812D +#endif /* GL_SGIS_texture_border_clamp */ + +#ifndef GL_SGIS_texture_color_mask +#define GL_SGIS_texture_color_mask 1 +#define GL_TEXTURE_COLOR_WRITEMASK_SGIS 0x81EF +typedef void (APIENTRYP PFNGLTEXTURECOLORMASKSGISPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTextureColorMaskSGIS (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +#endif +#endif /* GL_SGIS_texture_color_mask */ + +#ifndef GL_SGIS_texture_edge_clamp +#define GL_SGIS_texture_edge_clamp 1 +#define GL_CLAMP_TO_EDGE_SGIS 0x812F +#endif /* GL_SGIS_texture_edge_clamp */ + +#ifndef GL_SGIS_texture_filter4 +#define GL_SGIS_texture_filter4 1 +#define GL_FILTER4_SGIS 0x8146 +#define GL_TEXTURE_FILTER4_SIZE_SGIS 0x8147 +typedef void (APIENTRYP PFNGLGETTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLfloat *weights); +typedef void (APIENTRYP PFNGLTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLsizei n, const GLfloat *weights); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGetTexFilterFuncSGIS (GLenum target, GLenum filter, GLfloat *weights); +GLAPI void APIENTRY glTexFilterFuncSGIS (GLenum target, GLenum filter, GLsizei n, const GLfloat *weights); +#endif +#endif /* GL_SGIS_texture_filter4 */ + +#ifndef GL_SGIS_texture_lod +#define GL_SGIS_texture_lod 1 +#define GL_TEXTURE_MIN_LOD_SGIS 0x813A +#define GL_TEXTURE_MAX_LOD_SGIS 0x813B +#define GL_TEXTURE_BASE_LEVEL_SGIS 0x813C +#define GL_TEXTURE_MAX_LEVEL_SGIS 0x813D +#endif /* GL_SGIS_texture_lod */ + +#ifndef GL_SGIS_texture_select +#define GL_SGIS_texture_select 1 +#define GL_DUAL_ALPHA4_SGIS 0x8110 +#define GL_DUAL_ALPHA8_SGIS 0x8111 +#define GL_DUAL_ALPHA12_SGIS 0x8112 +#define GL_DUAL_ALPHA16_SGIS 0x8113 +#define GL_DUAL_LUMINANCE4_SGIS 0x8114 +#define GL_DUAL_LUMINANCE8_SGIS 0x8115 +#define GL_DUAL_LUMINANCE12_SGIS 0x8116 +#define GL_DUAL_LUMINANCE16_SGIS 0x8117 +#define GL_DUAL_INTENSITY4_SGIS 0x8118 +#define GL_DUAL_INTENSITY8_SGIS 0x8119 +#define GL_DUAL_INTENSITY12_SGIS 0x811A +#define GL_DUAL_INTENSITY16_SGIS 0x811B +#define GL_DUAL_LUMINANCE_ALPHA4_SGIS 0x811C +#define GL_DUAL_LUMINANCE_ALPHA8_SGIS 0x811D +#define GL_QUAD_ALPHA4_SGIS 0x811E +#define GL_QUAD_ALPHA8_SGIS 0x811F +#define GL_QUAD_LUMINANCE4_SGIS 0x8120 +#define GL_QUAD_LUMINANCE8_SGIS 0x8121 +#define GL_QUAD_INTENSITY4_SGIS 0x8122 +#define GL_QUAD_INTENSITY8_SGIS 0x8123 +#define GL_DUAL_TEXTURE_SELECT_SGIS 0x8124 +#define GL_QUAD_TEXTURE_SELECT_SGIS 0x8125 +#endif /* GL_SGIS_texture_select */ + +#ifndef GL_SGIX_async +#define GL_SGIX_async 1 +#define GL_ASYNC_MARKER_SGIX 0x8329 +typedef void (APIENTRYP PFNGLASYNCMARKERSGIXPROC) (GLuint marker); +typedef GLint (APIENTRYP PFNGLFINISHASYNCSGIXPROC) (GLuint *markerp); +typedef GLint (APIENTRYP PFNGLPOLLASYNCSGIXPROC) (GLuint *markerp); +typedef GLuint (APIENTRYP PFNGLGENASYNCMARKERSSGIXPROC) (GLsizei range); +typedef void (APIENTRYP PFNGLDELETEASYNCMARKERSSGIXPROC) (GLuint marker, GLsizei range); +typedef GLboolean (APIENTRYP PFNGLISASYNCMARKERSGIXPROC) (GLuint marker); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glAsyncMarkerSGIX (GLuint marker); +GLAPI GLint APIENTRY glFinishAsyncSGIX (GLuint *markerp); +GLAPI GLint APIENTRY glPollAsyncSGIX (GLuint *markerp); +GLAPI GLuint APIENTRY glGenAsyncMarkersSGIX (GLsizei range); +GLAPI void APIENTRY glDeleteAsyncMarkersSGIX (GLuint marker, GLsizei range); +GLAPI GLboolean APIENTRY glIsAsyncMarkerSGIX (GLuint marker); +#endif +#endif /* GL_SGIX_async */ + +#ifndef GL_SGIX_async_histogram +#define GL_SGIX_async_histogram 1 +#define GL_ASYNC_HISTOGRAM_SGIX 0x832C +#define GL_MAX_ASYNC_HISTOGRAM_SGIX 0x832D +#endif /* GL_SGIX_async_histogram */ + +#ifndef GL_SGIX_async_pixel +#define GL_SGIX_async_pixel 1 +#define GL_ASYNC_TEX_IMAGE_SGIX 0x835C +#define GL_ASYNC_DRAW_PIXELS_SGIX 0x835D +#define GL_ASYNC_READ_PIXELS_SGIX 0x835E +#define GL_MAX_ASYNC_TEX_IMAGE_SGIX 0x835F +#define GL_MAX_ASYNC_DRAW_PIXELS_SGIX 0x8360 +#define GL_MAX_ASYNC_READ_PIXELS_SGIX 0x8361 +#endif /* GL_SGIX_async_pixel */ + +#ifndef GL_SGIX_blend_alpha_minmax +#define GL_SGIX_blend_alpha_minmax 1 +#define GL_ALPHA_MIN_SGIX 0x8320 +#define GL_ALPHA_MAX_SGIX 0x8321 +#endif /* GL_SGIX_blend_alpha_minmax */ + +#ifndef GL_SGIX_calligraphic_fragment +#define GL_SGIX_calligraphic_fragment 1 +#define GL_CALLIGRAPHIC_FRAGMENT_SGIX 0x8183 +#endif /* GL_SGIX_calligraphic_fragment */ + +#ifndef GL_SGIX_clipmap +#define GL_SGIX_clipmap 1 +#define GL_LINEAR_CLIPMAP_LINEAR_SGIX 0x8170 +#define GL_TEXTURE_CLIPMAP_CENTER_SGIX 0x8171 +#define GL_TEXTURE_CLIPMAP_FRAME_SGIX 0x8172 +#define GL_TEXTURE_CLIPMAP_OFFSET_SGIX 0x8173 +#define GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8174 +#define GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX 0x8175 +#define GL_TEXTURE_CLIPMAP_DEPTH_SGIX 0x8176 +#define GL_MAX_CLIPMAP_DEPTH_SGIX 0x8177 +#define GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8178 +#define GL_NEAREST_CLIPMAP_NEAREST_SGIX 0x844D +#define GL_NEAREST_CLIPMAP_LINEAR_SGIX 0x844E +#define GL_LINEAR_CLIPMAP_NEAREST_SGIX 0x844F +#endif /* GL_SGIX_clipmap */ + +#ifndef GL_SGIX_convolution_accuracy +#define GL_SGIX_convolution_accuracy 1 +#define GL_CONVOLUTION_HINT_SGIX 0x8316 +#endif /* GL_SGIX_convolution_accuracy */ + +#ifndef GL_SGIX_depth_pass_instrument +#define GL_SGIX_depth_pass_instrument 1 +#endif /* GL_SGIX_depth_pass_instrument */ + +#ifndef GL_SGIX_depth_texture +#define GL_SGIX_depth_texture 1 +#define GL_DEPTH_COMPONENT16_SGIX 0x81A5 +#define GL_DEPTH_COMPONENT24_SGIX 0x81A6 +#define GL_DEPTH_COMPONENT32_SGIX 0x81A7 +#endif /* GL_SGIX_depth_texture */ + +#ifndef GL_SGIX_flush_raster +#define GL_SGIX_flush_raster 1 +typedef void (APIENTRYP PFNGLFLUSHRASTERSGIXPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFlushRasterSGIX (void); +#endif +#endif /* GL_SGIX_flush_raster */ + +#ifndef GL_SGIX_fog_offset +#define GL_SGIX_fog_offset 1 +#define GL_FOG_OFFSET_SGIX 0x8198 +#define GL_FOG_OFFSET_VALUE_SGIX 0x8199 +#endif /* GL_SGIX_fog_offset */ + +#ifndef GL_SGIX_fragment_lighting +#define GL_SGIX_fragment_lighting 1 +#define GL_FRAGMENT_LIGHTING_SGIX 0x8400 +#define GL_FRAGMENT_COLOR_MATERIAL_SGIX 0x8401 +#define GL_FRAGMENT_COLOR_MATERIAL_FACE_SGIX 0x8402 +#define GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_SGIX 0x8403 +#define GL_MAX_FRAGMENT_LIGHTS_SGIX 0x8404 +#define GL_MAX_ACTIVE_LIGHTS_SGIX 0x8405 +#define GL_CURRENT_RASTER_NORMAL_SGIX 0x8406 +#define GL_LIGHT_ENV_MODE_SGIX 0x8407 +#define GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_SGIX 0x8408 +#define GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_SGIX 0x8409 +#define GL_FRAGMENT_LIGHT_MODEL_AMBIENT_SGIX 0x840A +#define GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_SGIX 0x840B +#define GL_FRAGMENT_LIGHT0_SGIX 0x840C +#define GL_FRAGMENT_LIGHT1_SGIX 0x840D +#define GL_FRAGMENT_LIGHT2_SGIX 0x840E +#define GL_FRAGMENT_LIGHT3_SGIX 0x840F +#define GL_FRAGMENT_LIGHT4_SGIX 0x8410 +#define GL_FRAGMENT_LIGHT5_SGIX 0x8411 +#define GL_FRAGMENT_LIGHT6_SGIX 0x8412 +#define GL_FRAGMENT_LIGHT7_SGIX 0x8413 +typedef void (APIENTRYP PFNGLFRAGMENTCOLORMATERIALSGIXPROC) (GLenum face, GLenum mode); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTFSGIXPROC) (GLenum light, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTISGIXPROC) (GLenum light, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELFSGIXPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELFVSGIXPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELISGIXPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELIVSGIXPROC) (GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLFRAGMENTMATERIALFSGIXPROC) (GLenum face, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLFRAGMENTMATERIALISGIXPROC) (GLenum face, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLGETFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLLIGHTENVISGIXPROC) (GLenum pname, GLint param); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFragmentColorMaterialSGIX (GLenum face, GLenum mode); +GLAPI void APIENTRY glFragmentLightfSGIX (GLenum light, GLenum pname, GLfloat param); +GLAPI void APIENTRY glFragmentLightfvSGIX (GLenum light, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glFragmentLightiSGIX (GLenum light, GLenum pname, GLint param); +GLAPI void APIENTRY glFragmentLightivSGIX (GLenum light, GLenum pname, const GLint *params); +GLAPI void APIENTRY glFragmentLightModelfSGIX (GLenum pname, GLfloat param); +GLAPI void APIENTRY glFragmentLightModelfvSGIX (GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glFragmentLightModeliSGIX (GLenum pname, GLint param); +GLAPI void APIENTRY glFragmentLightModelivSGIX (GLenum pname, const GLint *params); +GLAPI void APIENTRY glFragmentMaterialfSGIX (GLenum face, GLenum pname, GLfloat param); +GLAPI void APIENTRY glFragmentMaterialfvSGIX (GLenum face, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glFragmentMaterialiSGIX (GLenum face, GLenum pname, GLint param); +GLAPI void APIENTRY glFragmentMaterialivSGIX (GLenum face, GLenum pname, const GLint *params); +GLAPI void APIENTRY glGetFragmentLightfvSGIX (GLenum light, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetFragmentLightivSGIX (GLenum light, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetFragmentMaterialfvSGIX (GLenum face, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetFragmentMaterialivSGIX (GLenum face, GLenum pname, GLint *params); +GLAPI void APIENTRY glLightEnviSGIX (GLenum pname, GLint param); +#endif +#endif /* GL_SGIX_fragment_lighting */ + +#ifndef GL_SGIX_framezoom +#define GL_SGIX_framezoom 1 +#define GL_FRAMEZOOM_SGIX 0x818B +#define GL_FRAMEZOOM_FACTOR_SGIX 0x818C +#define GL_MAX_FRAMEZOOM_FACTOR_SGIX 0x818D +typedef void (APIENTRYP PFNGLFRAMEZOOMSGIXPROC) (GLint factor); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFrameZoomSGIX (GLint factor); +#endif +#endif /* GL_SGIX_framezoom */ + +#ifndef GL_SGIX_igloo_interface +#define GL_SGIX_igloo_interface 1 +typedef void (APIENTRYP PFNGLIGLOOINTERFACESGIXPROC) (GLenum pname, const void *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glIglooInterfaceSGIX (GLenum pname, const void *params); +#endif +#endif /* GL_SGIX_igloo_interface */ + +#ifndef GL_SGIX_instruments +#define GL_SGIX_instruments 1 +#define GL_INSTRUMENT_BUFFER_POINTER_SGIX 0x8180 +#define GL_INSTRUMENT_MEASUREMENTS_SGIX 0x8181 +typedef GLint (APIENTRYP PFNGLGETINSTRUMENTSSGIXPROC) (void); +typedef void (APIENTRYP PFNGLINSTRUMENTSBUFFERSGIXPROC) (GLsizei size, GLint *buffer); +typedef GLint (APIENTRYP PFNGLPOLLINSTRUMENTSSGIXPROC) (GLint *marker_p); +typedef void (APIENTRYP PFNGLREADINSTRUMENTSSGIXPROC) (GLint marker); +typedef void (APIENTRYP PFNGLSTARTINSTRUMENTSSGIXPROC) (void); +typedef void (APIENTRYP PFNGLSTOPINSTRUMENTSSGIXPROC) (GLint marker); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLint APIENTRY glGetInstrumentsSGIX (void); +GLAPI void APIENTRY glInstrumentsBufferSGIX (GLsizei size, GLint *buffer); +GLAPI GLint APIENTRY glPollInstrumentsSGIX (GLint *marker_p); +GLAPI void APIENTRY glReadInstrumentsSGIX (GLint marker); +GLAPI void APIENTRY glStartInstrumentsSGIX (void); +GLAPI void APIENTRY glStopInstrumentsSGIX (GLint marker); +#endif +#endif /* GL_SGIX_instruments */ + +#ifndef GL_SGIX_interlace +#define GL_SGIX_interlace 1 +#define GL_INTERLACE_SGIX 0x8094 +#endif /* GL_SGIX_interlace */ + +#ifndef GL_SGIX_ir_instrument1 +#define GL_SGIX_ir_instrument1 1 +#define GL_IR_INSTRUMENT1_SGIX 0x817F +#endif /* GL_SGIX_ir_instrument1 */ + +#ifndef GL_SGIX_list_priority +#define GL_SGIX_list_priority 1 +#define GL_LIST_PRIORITY_SGIX 0x8182 +typedef void (APIENTRYP PFNGLGETLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLLISTPARAMETERFSGIXPROC) (GLuint list, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLLISTPARAMETERISGIXPROC) (GLuint list, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, const GLint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGetListParameterfvSGIX (GLuint list, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetListParameterivSGIX (GLuint list, GLenum pname, GLint *params); +GLAPI void APIENTRY glListParameterfSGIX (GLuint list, GLenum pname, GLfloat param); +GLAPI void APIENTRY glListParameterfvSGIX (GLuint list, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glListParameteriSGIX (GLuint list, GLenum pname, GLint param); +GLAPI void APIENTRY glListParameterivSGIX (GLuint list, GLenum pname, const GLint *params); +#endif +#endif /* GL_SGIX_list_priority */ + +#ifndef GL_SGIX_pixel_texture +#define GL_SGIX_pixel_texture 1 +#define GL_PIXEL_TEX_GEN_SGIX 0x8139 +#define GL_PIXEL_TEX_GEN_MODE_SGIX 0x832B +typedef void (APIENTRYP PFNGLPIXELTEXGENSGIXPROC) (GLenum mode); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPixelTexGenSGIX (GLenum mode); +#endif +#endif /* GL_SGIX_pixel_texture */ + +#ifndef GL_SGIX_pixel_tiles +#define GL_SGIX_pixel_tiles 1 +#define GL_PIXEL_TILE_BEST_ALIGNMENT_SGIX 0x813E +#define GL_PIXEL_TILE_CACHE_INCREMENT_SGIX 0x813F +#define GL_PIXEL_TILE_WIDTH_SGIX 0x8140 +#define GL_PIXEL_TILE_HEIGHT_SGIX 0x8141 +#define GL_PIXEL_TILE_GRID_WIDTH_SGIX 0x8142 +#define GL_PIXEL_TILE_GRID_HEIGHT_SGIX 0x8143 +#define GL_PIXEL_TILE_GRID_DEPTH_SGIX 0x8144 +#define GL_PIXEL_TILE_CACHE_SIZE_SGIX 0x8145 +#endif /* GL_SGIX_pixel_tiles */ + +#ifndef GL_SGIX_polynomial_ffd +#define GL_SGIX_polynomial_ffd 1 +#define GL_TEXTURE_DEFORMATION_BIT_SGIX 0x00000001 +#define GL_GEOMETRY_DEFORMATION_BIT_SGIX 0x00000002 +#define GL_GEOMETRY_DEFORMATION_SGIX 0x8194 +#define GL_TEXTURE_DEFORMATION_SGIX 0x8195 +#define GL_DEFORMATIONS_MASK_SGIX 0x8196 +#define GL_MAX_DEFORMATION_ORDER_SGIX 0x8197 +typedef void (APIENTRYP PFNGLDEFORMATIONMAP3DSGIXPROC) (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, GLdouble w1, GLdouble w2, GLint wstride, GLint worder, const GLdouble *points); +typedef void (APIENTRYP PFNGLDEFORMATIONMAP3FSGIXPROC) (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat w1, GLfloat w2, GLint wstride, GLint worder, const GLfloat *points); +typedef void (APIENTRYP PFNGLDEFORMSGIXPROC) (GLbitfield mask); +typedef void (APIENTRYP PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC) (GLbitfield mask); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDeformationMap3dSGIX (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, GLdouble w1, GLdouble w2, GLint wstride, GLint worder, const GLdouble *points); +GLAPI void APIENTRY glDeformationMap3fSGIX (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat w1, GLfloat w2, GLint wstride, GLint worder, const GLfloat *points); +GLAPI void APIENTRY glDeformSGIX (GLbitfield mask); +GLAPI void APIENTRY glLoadIdentityDeformationMapSGIX (GLbitfield mask); +#endif +#endif /* GL_SGIX_polynomial_ffd */ + +#ifndef GL_SGIX_reference_plane +#define GL_SGIX_reference_plane 1 +#define GL_REFERENCE_PLANE_SGIX 0x817D +#define GL_REFERENCE_PLANE_EQUATION_SGIX 0x817E +typedef void (APIENTRYP PFNGLREFERENCEPLANESGIXPROC) (const GLdouble *equation); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glReferencePlaneSGIX (const GLdouble *equation); +#endif +#endif /* GL_SGIX_reference_plane */ + +#ifndef GL_SGIX_resample +#define GL_SGIX_resample 1 +#define GL_PACK_RESAMPLE_SGIX 0x842C +#define GL_UNPACK_RESAMPLE_SGIX 0x842D +#define GL_RESAMPLE_REPLICATE_SGIX 0x842E +#define GL_RESAMPLE_ZERO_FILL_SGIX 0x842F +#define GL_RESAMPLE_DECIMATE_SGIX 0x8430 +#endif /* GL_SGIX_resample */ + +#ifndef GL_SGIX_scalebias_hint +#define GL_SGIX_scalebias_hint 1 +#define GL_SCALEBIAS_HINT_SGIX 0x8322 +#endif /* GL_SGIX_scalebias_hint */ + +#ifndef GL_SGIX_shadow +#define GL_SGIX_shadow 1 +#define GL_TEXTURE_COMPARE_SGIX 0x819A +#define GL_TEXTURE_COMPARE_OPERATOR_SGIX 0x819B +#define GL_TEXTURE_LEQUAL_R_SGIX 0x819C +#define GL_TEXTURE_GEQUAL_R_SGIX 0x819D +#endif /* GL_SGIX_shadow */ + +#ifndef GL_SGIX_shadow_ambient +#define GL_SGIX_shadow_ambient 1 +#define GL_SHADOW_AMBIENT_SGIX 0x80BF +#endif /* GL_SGIX_shadow_ambient */ + +#ifndef GL_SGIX_sprite +#define GL_SGIX_sprite 1 +#define GL_SPRITE_SGIX 0x8148 +#define GL_SPRITE_MODE_SGIX 0x8149 +#define GL_SPRITE_AXIS_SGIX 0x814A +#define GL_SPRITE_TRANSLATION_SGIX 0x814B +#define GL_SPRITE_AXIAL_SGIX 0x814C +#define GL_SPRITE_OBJECT_ALIGNED_SGIX 0x814D +#define GL_SPRITE_EYE_ALIGNED_SGIX 0x814E +typedef void (APIENTRYP PFNGLSPRITEPARAMETERFSGIXPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLSPRITEPARAMETERFVSGIXPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLSPRITEPARAMETERISGIXPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLSPRITEPARAMETERIVSGIXPROC) (GLenum pname, const GLint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSpriteParameterfSGIX (GLenum pname, GLfloat param); +GLAPI void APIENTRY glSpriteParameterfvSGIX (GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glSpriteParameteriSGIX (GLenum pname, GLint param); +GLAPI void APIENTRY glSpriteParameterivSGIX (GLenum pname, const GLint *params); +#endif +#endif /* GL_SGIX_sprite */ + +#ifndef GL_SGIX_subsample +#define GL_SGIX_subsample 1 +#define GL_PACK_SUBSAMPLE_RATE_SGIX 0x85A0 +#define GL_UNPACK_SUBSAMPLE_RATE_SGIX 0x85A1 +#define GL_PIXEL_SUBSAMPLE_4444_SGIX 0x85A2 +#define GL_PIXEL_SUBSAMPLE_2424_SGIX 0x85A3 +#define GL_PIXEL_SUBSAMPLE_4242_SGIX 0x85A4 +#endif /* GL_SGIX_subsample */ + +#ifndef GL_SGIX_tag_sample_buffer +#define GL_SGIX_tag_sample_buffer 1 +typedef void (APIENTRYP PFNGLTAGSAMPLEBUFFERSGIXPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTagSampleBufferSGIX (void); +#endif +#endif /* GL_SGIX_tag_sample_buffer */ + +#ifndef GL_SGIX_texture_add_env +#define GL_SGIX_texture_add_env 1 +#define GL_TEXTURE_ENV_BIAS_SGIX 0x80BE +#endif /* GL_SGIX_texture_add_env */ + +#ifndef GL_SGIX_texture_coordinate_clamp +#define GL_SGIX_texture_coordinate_clamp 1 +#define GL_TEXTURE_MAX_CLAMP_S_SGIX 0x8369 +#define GL_TEXTURE_MAX_CLAMP_T_SGIX 0x836A +#define GL_TEXTURE_MAX_CLAMP_R_SGIX 0x836B +#endif /* GL_SGIX_texture_coordinate_clamp */ + +#ifndef GL_SGIX_texture_lod_bias +#define GL_SGIX_texture_lod_bias 1 +#define GL_TEXTURE_LOD_BIAS_S_SGIX 0x818E +#define GL_TEXTURE_LOD_BIAS_T_SGIX 0x818F +#define GL_TEXTURE_LOD_BIAS_R_SGIX 0x8190 +#endif /* GL_SGIX_texture_lod_bias */ + +#ifndef GL_SGIX_texture_multi_buffer +#define GL_SGIX_texture_multi_buffer 1 +#define GL_TEXTURE_MULTI_BUFFER_HINT_SGIX 0x812E +#endif /* GL_SGIX_texture_multi_buffer */ + +#ifndef GL_SGIX_texture_scale_bias +#define GL_SGIX_texture_scale_bias 1 +#define GL_POST_TEXTURE_FILTER_BIAS_SGIX 0x8179 +#define GL_POST_TEXTURE_FILTER_SCALE_SGIX 0x817A +#define GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX 0x817B +#define GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX 0x817C +#endif /* GL_SGIX_texture_scale_bias */ + +#ifndef GL_SGIX_vertex_preclip +#define GL_SGIX_vertex_preclip 1 +#define GL_VERTEX_PRECLIP_SGIX 0x83EE +#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF +#endif /* GL_SGIX_vertex_preclip */ + +#ifndef GL_SGIX_ycrcb +#define GL_SGIX_ycrcb 1 +#define GL_YCRCB_422_SGIX 0x81BB +#define GL_YCRCB_444_SGIX 0x81BC +#endif /* GL_SGIX_ycrcb */ + +#ifndef GL_SGIX_ycrcb_subsample +#define GL_SGIX_ycrcb_subsample 1 +#endif /* GL_SGIX_ycrcb_subsample */ + +#ifndef GL_SGIX_ycrcba +#define GL_SGIX_ycrcba 1 +#define GL_YCRCB_SGIX 0x8318 +#define GL_YCRCBA_SGIX 0x8319 +#endif /* GL_SGIX_ycrcba */ + +#ifndef GL_SGI_color_matrix +#define GL_SGI_color_matrix 1 +#define GL_COLOR_MATRIX_SGI 0x80B1 +#define GL_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B2 +#define GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B3 +#define GL_POST_COLOR_MATRIX_RED_SCALE_SGI 0x80B4 +#define GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI 0x80B5 +#define GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI 0x80B6 +#define GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI 0x80B7 +#define GL_POST_COLOR_MATRIX_RED_BIAS_SGI 0x80B8 +#define GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI 0x80B9 +#define GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI 0x80BA +#define GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI 0x80BB +#endif /* GL_SGI_color_matrix */ + +#ifndef GL_SGI_color_table +#define GL_SGI_color_table 1 +#define GL_COLOR_TABLE_SGI 0x80D0 +#define GL_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D1 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D2 +#define GL_PROXY_COLOR_TABLE_SGI 0x80D3 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D4 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D5 +#define GL_COLOR_TABLE_SCALE_SGI 0x80D6 +#define GL_COLOR_TABLE_BIAS_SGI 0x80D7 +#define GL_COLOR_TABLE_FORMAT_SGI 0x80D8 +#define GL_COLOR_TABLE_WIDTH_SGI 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE_SGI 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE_SGI 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE_SGI 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE_SGI 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE_SGI 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE_SGI 0x80DF +typedef void (APIENTRYP PFNGLCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *table); +typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLCOPYCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (APIENTRYP PFNGLGETCOLORTABLESGIPROC) (GLenum target, GLenum format, GLenum type, void *table); +typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, GLint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glColorTableSGI (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *table); +GLAPI void APIENTRY glColorTableParameterfvSGI (GLenum target, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glColorTableParameterivSGI (GLenum target, GLenum pname, const GLint *params); +GLAPI void APIENTRY glCopyColorTableSGI (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +GLAPI void APIENTRY glGetColorTableSGI (GLenum target, GLenum format, GLenum type, void *table); +GLAPI void APIENTRY glGetColorTableParameterfvSGI (GLenum target, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetColorTableParameterivSGI (GLenum target, GLenum pname, GLint *params); +#endif +#endif /* GL_SGI_color_table */ + +#ifndef GL_SGI_texture_color_table +#define GL_SGI_texture_color_table 1 +#define GL_TEXTURE_COLOR_TABLE_SGI 0x80BC +#define GL_PROXY_TEXTURE_COLOR_TABLE_SGI 0x80BD +#endif /* GL_SGI_texture_color_table */ + +#ifndef GL_SUNX_constant_data +#define GL_SUNX_constant_data 1 +#define GL_UNPACK_CONSTANT_DATA_SUNX 0x81D5 +#define GL_TEXTURE_CONSTANT_DATA_SUNX 0x81D6 +typedef void (APIENTRYP PFNGLFINISHTEXTURESUNXPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFinishTextureSUNX (void); +#endif +#endif /* GL_SUNX_constant_data */ + +#ifndef GL_SUN_convolution_border_modes +#define GL_SUN_convolution_border_modes 1 +#define GL_WRAP_BORDER_SUN 0x81D4 +#endif /* GL_SUN_convolution_border_modes */ + +#ifndef GL_SUN_global_alpha +#define GL_SUN_global_alpha 1 +#define GL_GLOBAL_ALPHA_SUN 0x81D9 +#define GL_GLOBAL_ALPHA_FACTOR_SUN 0x81DA +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORBSUNPROC) (GLbyte factor); +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORSSUNPROC) (GLshort factor); +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORISUNPROC) (GLint factor); +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORFSUNPROC) (GLfloat factor); +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORDSUNPROC) (GLdouble factor); +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUBSUNPROC) (GLubyte factor); +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUSSUNPROC) (GLushort factor); +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUISUNPROC) (GLuint factor); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGlobalAlphaFactorbSUN (GLbyte factor); +GLAPI void APIENTRY glGlobalAlphaFactorsSUN (GLshort factor); +GLAPI void APIENTRY glGlobalAlphaFactoriSUN (GLint factor); +GLAPI void APIENTRY glGlobalAlphaFactorfSUN (GLfloat factor); +GLAPI void APIENTRY glGlobalAlphaFactordSUN (GLdouble factor); +GLAPI void APIENTRY glGlobalAlphaFactorubSUN (GLubyte factor); +GLAPI void APIENTRY glGlobalAlphaFactorusSUN (GLushort factor); +GLAPI void APIENTRY glGlobalAlphaFactoruiSUN (GLuint factor); +#endif +#endif /* GL_SUN_global_alpha */ + +#ifndef GL_SUN_mesh_array +#define GL_SUN_mesh_array 1 +#define GL_QUAD_MESH_SUN 0x8614 +#define GL_TRIANGLE_MESH_SUN 0x8615 +typedef void (APIENTRYP PFNGLDRAWMESHARRAYSSUNPROC) (GLenum mode, GLint first, GLsizei count, GLsizei width); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawMeshArraysSUN (GLenum mode, GLint first, GLsizei count, GLsizei width); +#endif +#endif /* GL_SUN_mesh_array */ + +#ifndef GL_SUN_slice_accum +#define GL_SUN_slice_accum 1 +#define GL_SLICE_ACCUM_SUN 0x85CC +#endif /* GL_SUN_slice_accum */ + +#ifndef GL_SUN_triangle_list +#define GL_SUN_triangle_list 1 +#define GL_RESTART_SUN 0x0001 +#define GL_REPLACE_MIDDLE_SUN 0x0002 +#define GL_REPLACE_OLDEST_SUN 0x0003 +#define GL_TRIANGLE_LIST_SUN 0x81D7 +#define GL_REPLACEMENT_CODE_SUN 0x81D8 +#define GL_REPLACEMENT_CODE_ARRAY_SUN 0x85C0 +#define GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN 0x85C1 +#define GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN 0x85C2 +#define GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN 0x85C3 +#define GL_R1UI_V3F_SUN 0x85C4 +#define GL_R1UI_C4UB_V3F_SUN 0x85C5 +#define GL_R1UI_C3F_V3F_SUN 0x85C6 +#define GL_R1UI_N3F_V3F_SUN 0x85C7 +#define GL_R1UI_C4F_N3F_V3F_SUN 0x85C8 +#define GL_R1UI_T2F_V3F_SUN 0x85C9 +#define GL_R1UI_T2F_N3F_V3F_SUN 0x85CA +#define GL_R1UI_T2F_C4F_N3F_V3F_SUN 0x85CB +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUISUNPROC) (GLuint code); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUSSUNPROC) (GLushort code); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUBSUNPROC) (GLubyte code); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVSUNPROC) (const GLuint *code); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUSVSUNPROC) (const GLushort *code); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUBVSUNPROC) (const GLubyte *code); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEPOINTERSUNPROC) (GLenum type, GLsizei stride, const void **pointer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glReplacementCodeuiSUN (GLuint code); +GLAPI void APIENTRY glReplacementCodeusSUN (GLushort code); +GLAPI void APIENTRY glReplacementCodeubSUN (GLubyte code); +GLAPI void APIENTRY glReplacementCodeuivSUN (const GLuint *code); +GLAPI void APIENTRY glReplacementCodeusvSUN (const GLushort *code); +GLAPI void APIENTRY glReplacementCodeubvSUN (const GLubyte *code); +GLAPI void APIENTRY glReplacementCodePointerSUN (GLenum type, GLsizei stride, const void **pointer); +#endif +#endif /* GL_SUN_triangle_list */ + +#ifndef GL_SUN_vertex +#define GL_SUN_vertex 1 +typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX2FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX2FVSUNPROC) (const GLubyte *c, const GLfloat *v); +typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX3FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX3FVSUNPROC) (const GLubyte *c, const GLfloat *v); +typedef void (APIENTRYP PFNGLCOLOR3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *v); +typedef void (APIENTRYP PFNGLNORMAL3FVERTEX3FSUNPROC) (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLTEXCOORD2FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLTEXCOORD2FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *v); +typedef void (APIENTRYP PFNGLTEXCOORD4FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLTEXCOORD4FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *v); +typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC) (const GLfloat *tc, const GLubyte *c, const GLfloat *v); +typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *v); +typedef void (APIENTRYP PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC) (GLuint rc, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC) (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC) (const GLuint *rc, const GLubyte *c, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *c, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glColor4ubVertex2fSUN (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y); +GLAPI void APIENTRY glColor4ubVertex2fvSUN (const GLubyte *c, const GLfloat *v); +GLAPI void APIENTRY glColor4ubVertex3fSUN (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glColor4ubVertex3fvSUN (const GLubyte *c, const GLfloat *v); +GLAPI void APIENTRY glColor3fVertex3fSUN (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glColor3fVertex3fvSUN (const GLfloat *c, const GLfloat *v); +GLAPI void APIENTRY glNormal3fVertex3fSUN (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glNormal3fVertex3fvSUN (const GLfloat *n, const GLfloat *v); +GLAPI void APIENTRY glColor4fNormal3fVertex3fSUN (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glColor4fNormal3fVertex3fvSUN (const GLfloat *c, const GLfloat *n, const GLfloat *v); +GLAPI void APIENTRY glTexCoord2fVertex3fSUN (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glTexCoord2fVertex3fvSUN (const GLfloat *tc, const GLfloat *v); +GLAPI void APIENTRY glTexCoord4fVertex4fSUN (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void APIENTRY glTexCoord4fVertex4fvSUN (const GLfloat *tc, const GLfloat *v); +GLAPI void APIENTRY glTexCoord2fColor4ubVertex3fSUN (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glTexCoord2fColor4ubVertex3fvSUN (const GLfloat *tc, const GLubyte *c, const GLfloat *v); +GLAPI void APIENTRY glTexCoord2fColor3fVertex3fSUN (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glTexCoord2fColor3fVertex3fvSUN (const GLfloat *tc, const GLfloat *c, const GLfloat *v); +GLAPI void APIENTRY glTexCoord2fNormal3fVertex3fSUN (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glTexCoord2fNormal3fVertex3fvSUN (const GLfloat *tc, const GLfloat *n, const GLfloat *v); +GLAPI void APIENTRY glTexCoord2fColor4fNormal3fVertex3fSUN (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glTexCoord2fColor4fNormal3fVertex3fvSUN (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +GLAPI void APIENTRY glTexCoord4fColor4fNormal3fVertex4fSUN (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void APIENTRY glTexCoord4fColor4fNormal3fVertex4fvSUN (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +GLAPI void APIENTRY glReplacementCodeuiVertex3fSUN (GLuint rc, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glReplacementCodeuiVertex3fvSUN (const GLuint *rc, const GLfloat *v); +GLAPI void APIENTRY glReplacementCodeuiColor4ubVertex3fSUN (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glReplacementCodeuiColor4ubVertex3fvSUN (const GLuint *rc, const GLubyte *c, const GLfloat *v); +GLAPI void APIENTRY glReplacementCodeuiColor3fVertex3fSUN (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glReplacementCodeuiColor3fVertex3fvSUN (const GLuint *rc, const GLfloat *c, const GLfloat *v); +GLAPI void APIENTRY glReplacementCodeuiNormal3fVertex3fSUN (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glReplacementCodeuiNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *n, const GLfloat *v); +GLAPI void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fSUN (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +GLAPI void APIENTRY glReplacementCodeuiTexCoord2fVertex3fSUN (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glReplacementCodeuiTexCoord2fVertex3fvSUN (const GLuint *rc, const GLfloat *tc, const GLfloat *v); +GLAPI void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v); +GLAPI void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN (GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +#endif +#endif /* GL_SUN_vertex */ + +#ifndef GL_WIN_phong_shading +#define GL_WIN_phong_shading 1 +#define GL_PHONG_WIN 0x80EA +#define GL_PHONG_HINT_WIN 0x80EB +#endif /* GL_WIN_phong_shading */ + +#ifndef GL_WIN_specular_fog +#define GL_WIN_specular_fog 1 +#define GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC +#endif /* GL_WIN_specular_fog */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/testbed/glfw/deps/GL/glxext.h b/testbed/glfw/deps/GL/glxext.h new file mode 100644 index 00000000..174fc218 --- /dev/null +++ b/testbed/glfw/deps/GL/glxext.h @@ -0,0 +1,906 @@ +#ifndef __glxext_h_ +#define __glxext_h_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Copyright (c) 2013-2014 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE 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 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ +/* +** This header is generated from the Khronos OpenGL / OpenGL ES XML +** API Registry. The current version of the Registry, generator scripts +** used to make the header, and the header can be found at +** http://www.opengl.org/registry/ +** +** Khronos $Revision: 27684 $ on $Date: 2014-08-11 01:21:35 -0700 (Mon, 11 Aug 2014) $ +*/ + +#define GLX_GLXEXT_VERSION 20140810 + +/* Generated C header for: + * API: glx + * Versions considered: .* + * Versions emitted: 1\.[3-9] + * Default extensions included: glx + * Additional extensions included: _nomatch_^ + * Extensions removed: _nomatch_^ + */ + +#ifndef GLX_VERSION_1_3 +#define GLX_VERSION_1_3 1 +typedef XID GLXContextID; +typedef struct __GLXFBConfigRec *GLXFBConfig; +typedef XID GLXWindow; +typedef XID GLXPbuffer; +#define GLX_WINDOW_BIT 0x00000001 +#define GLX_PIXMAP_BIT 0x00000002 +#define GLX_PBUFFER_BIT 0x00000004 +#define GLX_RGBA_BIT 0x00000001 +#define GLX_COLOR_INDEX_BIT 0x00000002 +#define GLX_PBUFFER_CLOBBER_MASK 0x08000000 +#define GLX_FRONT_LEFT_BUFFER_BIT 0x00000001 +#define GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002 +#define GLX_BACK_LEFT_BUFFER_BIT 0x00000004 +#define GLX_BACK_RIGHT_BUFFER_BIT 0x00000008 +#define GLX_AUX_BUFFERS_BIT 0x00000010 +#define GLX_DEPTH_BUFFER_BIT 0x00000020 +#define GLX_STENCIL_BUFFER_BIT 0x00000040 +#define GLX_ACCUM_BUFFER_BIT 0x00000080 +#define GLX_CONFIG_CAVEAT 0x20 +#define GLX_X_VISUAL_TYPE 0x22 +#define GLX_TRANSPARENT_TYPE 0x23 +#define GLX_TRANSPARENT_INDEX_VALUE 0x24 +#define GLX_TRANSPARENT_RED_VALUE 0x25 +#define GLX_TRANSPARENT_GREEN_VALUE 0x26 +#define GLX_TRANSPARENT_BLUE_VALUE 0x27 +#define GLX_TRANSPARENT_ALPHA_VALUE 0x28 +#define GLX_DONT_CARE 0xFFFFFFFF +#define GLX_NONE 0x8000 +#define GLX_SLOW_CONFIG 0x8001 +#define GLX_TRUE_COLOR 0x8002 +#define GLX_DIRECT_COLOR 0x8003 +#define GLX_PSEUDO_COLOR 0x8004 +#define GLX_STATIC_COLOR 0x8005 +#define GLX_GRAY_SCALE 0x8006 +#define GLX_STATIC_GRAY 0x8007 +#define GLX_TRANSPARENT_RGB 0x8008 +#define GLX_TRANSPARENT_INDEX 0x8009 +#define GLX_VISUAL_ID 0x800B +#define GLX_SCREEN 0x800C +#define GLX_NON_CONFORMANT_CONFIG 0x800D +#define GLX_DRAWABLE_TYPE 0x8010 +#define GLX_RENDER_TYPE 0x8011 +#define GLX_X_RENDERABLE 0x8012 +#define GLX_FBCONFIG_ID 0x8013 +#define GLX_RGBA_TYPE 0x8014 +#define GLX_COLOR_INDEX_TYPE 0x8015 +#define GLX_MAX_PBUFFER_WIDTH 0x8016 +#define GLX_MAX_PBUFFER_HEIGHT 0x8017 +#define GLX_MAX_PBUFFER_PIXELS 0x8018 +#define GLX_PRESERVED_CONTENTS 0x801B +#define GLX_LARGEST_PBUFFER 0x801C +#define GLX_WIDTH 0x801D +#define GLX_HEIGHT 0x801E +#define GLX_EVENT_MASK 0x801F +#define GLX_DAMAGED 0x8020 +#define GLX_SAVED 0x8021 +#define GLX_WINDOW 0x8022 +#define GLX_PBUFFER 0x8023 +#define GLX_PBUFFER_HEIGHT 0x8040 +#define GLX_PBUFFER_WIDTH 0x8041 +typedef GLXFBConfig *( *PFNGLXGETFBCONFIGSPROC) (Display *dpy, int screen, int *nelements); +typedef GLXFBConfig *( *PFNGLXCHOOSEFBCONFIGPROC) (Display *dpy, int screen, const int *attrib_list, int *nelements); +typedef int ( *PFNGLXGETFBCONFIGATTRIBPROC) (Display *dpy, GLXFBConfig config, int attribute, int *value); +typedef XVisualInfo *( *PFNGLXGETVISUALFROMFBCONFIGPROC) (Display *dpy, GLXFBConfig config); +typedef GLXWindow ( *PFNGLXCREATEWINDOWPROC) (Display *dpy, GLXFBConfig config, Window win, const int *attrib_list); +typedef void ( *PFNGLXDESTROYWINDOWPROC) (Display *dpy, GLXWindow win); +typedef GLXPixmap ( *PFNGLXCREATEPIXMAPPROC) (Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attrib_list); +typedef void ( *PFNGLXDESTROYPIXMAPPROC) (Display *dpy, GLXPixmap pixmap); +typedef GLXPbuffer ( *PFNGLXCREATEPBUFFERPROC) (Display *dpy, GLXFBConfig config, const int *attrib_list); +typedef void ( *PFNGLXDESTROYPBUFFERPROC) (Display *dpy, GLXPbuffer pbuf); +typedef void ( *PFNGLXQUERYDRAWABLEPROC) (Display *dpy, GLXDrawable draw, int attribute, unsigned int *value); +typedef GLXContext ( *PFNGLXCREATENEWCONTEXTPROC) (Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct); +typedef Bool ( *PFNGLXMAKECONTEXTCURRENTPROC) (Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx); +typedef GLXDrawable ( *PFNGLXGETCURRENTREADDRAWABLEPROC) (void); +typedef int ( *PFNGLXQUERYCONTEXTPROC) (Display *dpy, GLXContext ctx, int attribute, int *value); +typedef void ( *PFNGLXSELECTEVENTPROC) (Display *dpy, GLXDrawable draw, unsigned long event_mask); +typedef void ( *PFNGLXGETSELECTEDEVENTPROC) (Display *dpy, GLXDrawable draw, unsigned long *event_mask); +#ifdef GLX_GLXEXT_PROTOTYPES +GLXFBConfig *glXGetFBConfigs (Display *dpy, int screen, int *nelements); +GLXFBConfig *glXChooseFBConfig (Display *dpy, int screen, const int *attrib_list, int *nelements); +int glXGetFBConfigAttrib (Display *dpy, GLXFBConfig config, int attribute, int *value); +XVisualInfo *glXGetVisualFromFBConfig (Display *dpy, GLXFBConfig config); +GLXWindow glXCreateWindow (Display *dpy, GLXFBConfig config, Window win, const int *attrib_list); +void glXDestroyWindow (Display *dpy, GLXWindow win); +GLXPixmap glXCreatePixmap (Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attrib_list); +void glXDestroyPixmap (Display *dpy, GLXPixmap pixmap); +GLXPbuffer glXCreatePbuffer (Display *dpy, GLXFBConfig config, const int *attrib_list); +void glXDestroyPbuffer (Display *dpy, GLXPbuffer pbuf); +void glXQueryDrawable (Display *dpy, GLXDrawable draw, int attribute, unsigned int *value); +GLXContext glXCreateNewContext (Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct); +Bool glXMakeContextCurrent (Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx); +GLXDrawable glXGetCurrentReadDrawable (void); +int glXQueryContext (Display *dpy, GLXContext ctx, int attribute, int *value); +void glXSelectEvent (Display *dpy, GLXDrawable draw, unsigned long event_mask); +void glXGetSelectedEvent (Display *dpy, GLXDrawable draw, unsigned long *event_mask); +#endif +#endif /* GLX_VERSION_1_3 */ + +#ifndef GLX_VERSION_1_4 +#define GLX_VERSION_1_4 1 +typedef void ( *__GLXextFuncPtr)(void); +#define GLX_SAMPLE_BUFFERS 100000 +#define GLX_SAMPLES 100001 +typedef __GLXextFuncPtr ( *PFNGLXGETPROCADDRESSPROC) (const GLubyte *procName); +#ifdef GLX_GLXEXT_PROTOTYPES +__GLXextFuncPtr glXGetProcAddress (const GLubyte *procName); +#endif +#endif /* GLX_VERSION_1_4 */ + +#ifndef GLX_ARB_context_flush_control +#define GLX_ARB_context_flush_control 1 +#define GLX_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097 +#define GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0 +#define GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098 +#endif /* GLX_ARB_context_flush_control */ + +#ifndef GLX_ARB_create_context +#define GLX_ARB_create_context 1 +#define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001 +#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002 +#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 +#define GLX_CONTEXT_FLAGS_ARB 0x2094 +typedef GLXContext ( *PFNGLXCREATECONTEXTATTRIBSARBPROC) (Display *dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list); +#ifdef GLX_GLXEXT_PROTOTYPES +GLXContext glXCreateContextAttribsARB (Display *dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list); +#endif +#endif /* GLX_ARB_create_context */ + +#ifndef GLX_ARB_create_context_profile +#define GLX_ARB_create_context_profile 1 +#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 +#define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 +#define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126 +#endif /* GLX_ARB_create_context_profile */ + +#ifndef GLX_ARB_create_context_robustness +#define GLX_ARB_create_context_robustness 1 +#define GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004 +#define GLX_LOSE_CONTEXT_ON_RESET_ARB 0x8252 +#define GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 +#define GLX_NO_RESET_NOTIFICATION_ARB 0x8261 +#endif /* GLX_ARB_create_context_robustness */ + +#ifndef GLX_ARB_fbconfig_float +#define GLX_ARB_fbconfig_float 1 +#define GLX_RGBA_FLOAT_TYPE_ARB 0x20B9 +#define GLX_RGBA_FLOAT_BIT_ARB 0x00000004 +#endif /* GLX_ARB_fbconfig_float */ + +#ifndef GLX_ARB_framebuffer_sRGB +#define GLX_ARB_framebuffer_sRGB 1 +#define GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20B2 +#endif /* GLX_ARB_framebuffer_sRGB */ + +#ifndef GLX_ARB_get_proc_address +#define GLX_ARB_get_proc_address 1 +typedef __GLXextFuncPtr ( *PFNGLXGETPROCADDRESSARBPROC) (const GLubyte *procName); +#ifdef GLX_GLXEXT_PROTOTYPES +__GLXextFuncPtr glXGetProcAddressARB (const GLubyte *procName); +#endif +#endif /* GLX_ARB_get_proc_address */ + +#ifndef GLX_ARB_multisample +#define GLX_ARB_multisample 1 +#define GLX_SAMPLE_BUFFERS_ARB 100000 +#define GLX_SAMPLES_ARB 100001 +#endif /* GLX_ARB_multisample */ + +#ifndef GLX_ARB_robustness_application_isolation +#define GLX_ARB_robustness_application_isolation 1 +#define GLX_CONTEXT_RESET_ISOLATION_BIT_ARB 0x00000008 +#endif /* GLX_ARB_robustness_application_isolation */ + +#ifndef GLX_ARB_robustness_share_group_isolation +#define GLX_ARB_robustness_share_group_isolation 1 +#endif /* GLX_ARB_robustness_share_group_isolation */ + +#ifndef GLX_ARB_vertex_buffer_object +#define GLX_ARB_vertex_buffer_object 1 +#define GLX_CONTEXT_ALLOW_BUFFER_BYTE_ORDER_MISMATCH_ARB 0x2095 +#endif /* GLX_ARB_vertex_buffer_object */ + +#ifndef GLX_3DFX_multisample +#define GLX_3DFX_multisample 1 +#define GLX_SAMPLE_BUFFERS_3DFX 0x8050 +#define GLX_SAMPLES_3DFX 0x8051 +#endif /* GLX_3DFX_multisample */ + +#ifndef GLX_AMD_gpu_association +#define GLX_AMD_gpu_association 1 +#define GLX_GPU_VENDOR_AMD 0x1F00 +#define GLX_GPU_RENDERER_STRING_AMD 0x1F01 +#define GLX_GPU_OPENGL_VERSION_STRING_AMD 0x1F02 +#define GLX_GPU_FASTEST_TARGET_GPUS_AMD 0x21A2 +#define GLX_GPU_RAM_AMD 0x21A3 +#define GLX_GPU_CLOCK_AMD 0x21A4 +#define GLX_GPU_NUM_PIPES_AMD 0x21A5 +#define GLX_GPU_NUM_SIMD_AMD 0x21A6 +#define GLX_GPU_NUM_RB_AMD 0x21A7 +#define GLX_GPU_NUM_SPI_AMD 0x21A8 +#endif /* GLX_AMD_gpu_association */ + +#ifndef GLX_EXT_buffer_age +#define GLX_EXT_buffer_age 1 +#define GLX_BACK_BUFFER_AGE_EXT 0x20F4 +#endif /* GLX_EXT_buffer_age */ + +#ifndef GLX_EXT_create_context_es2_profile +#define GLX_EXT_create_context_es2_profile 1 +#define GLX_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004 +#endif /* GLX_EXT_create_context_es2_profile */ + +#ifndef GLX_EXT_create_context_es_profile +#define GLX_EXT_create_context_es_profile 1 +#define GLX_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004 +#endif /* GLX_EXT_create_context_es_profile */ + +#ifndef GLX_EXT_fbconfig_packed_float +#define GLX_EXT_fbconfig_packed_float 1 +#define GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT 0x20B1 +#define GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT 0x00000008 +#endif /* GLX_EXT_fbconfig_packed_float */ + +#ifndef GLX_EXT_framebuffer_sRGB +#define GLX_EXT_framebuffer_sRGB 1 +#define GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20B2 +#endif /* GLX_EXT_framebuffer_sRGB */ + +#ifndef GLX_EXT_import_context +#define GLX_EXT_import_context 1 +#define GLX_SHARE_CONTEXT_EXT 0x800A +#define GLX_VISUAL_ID_EXT 0x800B +#define GLX_SCREEN_EXT 0x800C +typedef Display *( *PFNGLXGETCURRENTDISPLAYEXTPROC) (void); +typedef int ( *PFNGLXQUERYCONTEXTINFOEXTPROC) (Display *dpy, GLXContext context, int attribute, int *value); +typedef GLXContextID ( *PFNGLXGETCONTEXTIDEXTPROC) (const GLXContext context); +typedef GLXContext ( *PFNGLXIMPORTCONTEXTEXTPROC) (Display *dpy, GLXContextID contextID); +typedef void ( *PFNGLXFREECONTEXTEXTPROC) (Display *dpy, GLXContext context); +#ifdef GLX_GLXEXT_PROTOTYPES +Display *glXGetCurrentDisplayEXT (void); +int glXQueryContextInfoEXT (Display *dpy, GLXContext context, int attribute, int *value); +GLXContextID glXGetContextIDEXT (const GLXContext context); +GLXContext glXImportContextEXT (Display *dpy, GLXContextID contextID); +void glXFreeContextEXT (Display *dpy, GLXContext context); +#endif +#endif /* GLX_EXT_import_context */ + +#ifndef GLX_EXT_stereo_tree +#define GLX_EXT_stereo_tree 1 +typedef struct { + int type; + unsigned long serial; + Bool send_event; + Display *display; + int extension; + int evtype; + GLXDrawable window; + Bool stereo_tree; +} GLXStereoNotifyEventEXT; +#define GLX_STEREO_TREE_EXT 0x20F5 +#define GLX_STEREO_NOTIFY_MASK_EXT 0x00000001 +#define GLX_STEREO_NOTIFY_EXT 0x00000000 +#endif /* GLX_EXT_stereo_tree */ + +#ifndef GLX_EXT_swap_control +#define GLX_EXT_swap_control 1 +#define GLX_SWAP_INTERVAL_EXT 0x20F1 +#define GLX_MAX_SWAP_INTERVAL_EXT 0x20F2 +typedef void ( *PFNGLXSWAPINTERVALEXTPROC) (Display *dpy, GLXDrawable drawable, int interval); +#ifdef GLX_GLXEXT_PROTOTYPES +void glXSwapIntervalEXT (Display *dpy, GLXDrawable drawable, int interval); +#endif +#endif /* GLX_EXT_swap_control */ + +#ifndef GLX_EXT_swap_control_tear +#define GLX_EXT_swap_control_tear 1 +#define GLX_LATE_SWAPS_TEAR_EXT 0x20F3 +#endif /* GLX_EXT_swap_control_tear */ + +#ifndef GLX_EXT_texture_from_pixmap +#define GLX_EXT_texture_from_pixmap 1 +#define GLX_TEXTURE_1D_BIT_EXT 0x00000001 +#define GLX_TEXTURE_2D_BIT_EXT 0x00000002 +#define GLX_TEXTURE_RECTANGLE_BIT_EXT 0x00000004 +#define GLX_BIND_TO_TEXTURE_RGB_EXT 0x20D0 +#define GLX_BIND_TO_TEXTURE_RGBA_EXT 0x20D1 +#define GLX_BIND_TO_MIPMAP_TEXTURE_EXT 0x20D2 +#define GLX_BIND_TO_TEXTURE_TARGETS_EXT 0x20D3 +#define GLX_Y_INVERTED_EXT 0x20D4 +#define GLX_TEXTURE_FORMAT_EXT 0x20D5 +#define GLX_TEXTURE_TARGET_EXT 0x20D6 +#define GLX_MIPMAP_TEXTURE_EXT 0x20D7 +#define GLX_TEXTURE_FORMAT_NONE_EXT 0x20D8 +#define GLX_TEXTURE_FORMAT_RGB_EXT 0x20D9 +#define GLX_TEXTURE_FORMAT_RGBA_EXT 0x20DA +#define GLX_TEXTURE_1D_EXT 0x20DB +#define GLX_TEXTURE_2D_EXT 0x20DC +#define GLX_TEXTURE_RECTANGLE_EXT 0x20DD +#define GLX_FRONT_LEFT_EXT 0x20DE +#define GLX_FRONT_RIGHT_EXT 0x20DF +#define GLX_BACK_LEFT_EXT 0x20E0 +#define GLX_BACK_RIGHT_EXT 0x20E1 +#define GLX_FRONT_EXT 0x20DE +#define GLX_BACK_EXT 0x20E0 +#define GLX_AUX0_EXT 0x20E2 +#define GLX_AUX1_EXT 0x20E3 +#define GLX_AUX2_EXT 0x20E4 +#define GLX_AUX3_EXT 0x20E5 +#define GLX_AUX4_EXT 0x20E6 +#define GLX_AUX5_EXT 0x20E7 +#define GLX_AUX6_EXT 0x20E8 +#define GLX_AUX7_EXT 0x20E9 +#define GLX_AUX8_EXT 0x20EA +#define GLX_AUX9_EXT 0x20EB +typedef void ( *PFNGLXBINDTEXIMAGEEXTPROC) (Display *dpy, GLXDrawable drawable, int buffer, const int *attrib_list); +typedef void ( *PFNGLXRELEASETEXIMAGEEXTPROC) (Display *dpy, GLXDrawable drawable, int buffer); +#ifdef GLX_GLXEXT_PROTOTYPES +void glXBindTexImageEXT (Display *dpy, GLXDrawable drawable, int buffer, const int *attrib_list); +void glXReleaseTexImageEXT (Display *dpy, GLXDrawable drawable, int buffer); +#endif +#endif /* GLX_EXT_texture_from_pixmap */ + +#ifndef GLX_EXT_visual_info +#define GLX_EXT_visual_info 1 +#define GLX_X_VISUAL_TYPE_EXT 0x22 +#define GLX_TRANSPARENT_TYPE_EXT 0x23 +#define GLX_TRANSPARENT_INDEX_VALUE_EXT 0x24 +#define GLX_TRANSPARENT_RED_VALUE_EXT 0x25 +#define GLX_TRANSPARENT_GREEN_VALUE_EXT 0x26 +#define GLX_TRANSPARENT_BLUE_VALUE_EXT 0x27 +#define GLX_TRANSPARENT_ALPHA_VALUE_EXT 0x28 +#define GLX_NONE_EXT 0x8000 +#define GLX_TRUE_COLOR_EXT 0x8002 +#define GLX_DIRECT_COLOR_EXT 0x8003 +#define GLX_PSEUDO_COLOR_EXT 0x8004 +#define GLX_STATIC_COLOR_EXT 0x8005 +#define GLX_GRAY_SCALE_EXT 0x8006 +#define GLX_STATIC_GRAY_EXT 0x8007 +#define GLX_TRANSPARENT_RGB_EXT 0x8008 +#define GLX_TRANSPARENT_INDEX_EXT 0x8009 +#endif /* GLX_EXT_visual_info */ + +#ifndef GLX_EXT_visual_rating +#define GLX_EXT_visual_rating 1 +#define GLX_VISUAL_CAVEAT_EXT 0x20 +#define GLX_SLOW_VISUAL_EXT 0x8001 +#define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D +#endif /* GLX_EXT_visual_rating */ + +#ifndef GLX_INTEL_swap_event +#define GLX_INTEL_swap_event 1 +#define GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK 0x04000000 +#define GLX_EXCHANGE_COMPLETE_INTEL 0x8180 +#define GLX_COPY_COMPLETE_INTEL 0x8181 +#define GLX_FLIP_COMPLETE_INTEL 0x8182 +#endif /* GLX_INTEL_swap_event */ + +#ifndef GLX_MESA_agp_offset +#define GLX_MESA_agp_offset 1 +typedef unsigned int ( *PFNGLXGETAGPOFFSETMESAPROC) (const void *pointer); +#ifdef GLX_GLXEXT_PROTOTYPES +unsigned int glXGetAGPOffsetMESA (const void *pointer); +#endif +#endif /* GLX_MESA_agp_offset */ + +#ifndef GLX_MESA_copy_sub_buffer +#define GLX_MESA_copy_sub_buffer 1 +typedef void ( *PFNGLXCOPYSUBBUFFERMESAPROC) (Display *dpy, GLXDrawable drawable, int x, int y, int width, int height); +#ifdef GLX_GLXEXT_PROTOTYPES +void glXCopySubBufferMESA (Display *dpy, GLXDrawable drawable, int x, int y, int width, int height); +#endif +#endif /* GLX_MESA_copy_sub_buffer */ + +#ifndef GLX_MESA_pixmap_colormap +#define GLX_MESA_pixmap_colormap 1 +typedef GLXPixmap ( *PFNGLXCREATEGLXPIXMAPMESAPROC) (Display *dpy, XVisualInfo *visual, Pixmap pixmap, Colormap cmap); +#ifdef GLX_GLXEXT_PROTOTYPES +GLXPixmap glXCreateGLXPixmapMESA (Display *dpy, XVisualInfo *visual, Pixmap pixmap, Colormap cmap); +#endif +#endif /* GLX_MESA_pixmap_colormap */ + +#ifndef GLX_MESA_query_renderer +#define GLX_MESA_query_renderer 1 +#define GLX_RENDERER_VENDOR_ID_MESA 0x8183 +#define GLX_RENDERER_DEVICE_ID_MESA 0x8184 +#define GLX_RENDERER_VERSION_MESA 0x8185 +#define GLX_RENDERER_ACCELERATED_MESA 0x8186 +#define GLX_RENDERER_VIDEO_MEMORY_MESA 0x8187 +#define GLX_RENDERER_UNIFIED_MEMORY_ARCHITECTURE_MESA 0x8188 +#define GLX_RENDERER_PREFERRED_PROFILE_MESA 0x8189 +#define GLX_RENDERER_OPENGL_CORE_PROFILE_VERSION_MESA 0x818A +#define GLX_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION_MESA 0x818B +#define GLX_RENDERER_OPENGL_ES_PROFILE_VERSION_MESA 0x818C +#define GLX_RENDERER_OPENGL_ES2_PROFILE_VERSION_MESA 0x818D +#define GLX_RENDERER_ID_MESA 0x818E +typedef Bool ( *PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC) (int attribute, unsigned int *value); +typedef const char *( *PFNGLXQUERYCURRENTRENDERERSTRINGMESAPROC) (int attribute); +typedef Bool ( *PFNGLXQUERYRENDERERINTEGERMESAPROC) (Display *dpy, int screen, int renderer, int attribute, unsigned int *value); +typedef const char *( *PFNGLXQUERYRENDERERSTRINGMESAPROC) (Display *dpy, int screen, int renderer, int attribute); +#ifdef GLX_GLXEXT_PROTOTYPES +Bool glXQueryCurrentRendererIntegerMESA (int attribute, unsigned int *value); +const char *glXQueryCurrentRendererStringMESA (int attribute); +Bool glXQueryRendererIntegerMESA (Display *dpy, int screen, int renderer, int attribute, unsigned int *value); +const char *glXQueryRendererStringMESA (Display *dpy, int screen, int renderer, int attribute); +#endif +#endif /* GLX_MESA_query_renderer */ + +#ifndef GLX_MESA_release_buffers +#define GLX_MESA_release_buffers 1 +typedef Bool ( *PFNGLXRELEASEBUFFERSMESAPROC) (Display *dpy, GLXDrawable drawable); +#ifdef GLX_GLXEXT_PROTOTYPES +Bool glXReleaseBuffersMESA (Display *dpy, GLXDrawable drawable); +#endif +#endif /* GLX_MESA_release_buffers */ + +#ifndef GLX_MESA_set_3dfx_mode +#define GLX_MESA_set_3dfx_mode 1 +#define GLX_3DFX_WINDOW_MODE_MESA 0x1 +#define GLX_3DFX_FULLSCREEN_MODE_MESA 0x2 +typedef Bool ( *PFNGLXSET3DFXMODEMESAPROC) (int mode); +#ifdef GLX_GLXEXT_PROTOTYPES +Bool glXSet3DfxModeMESA (int mode); +#endif +#endif /* GLX_MESA_set_3dfx_mode */ + +#ifndef GLX_NV_copy_buffer +#define GLX_NV_copy_buffer 1 +typedef void ( *PFNGLXCOPYBUFFERSUBDATANVPROC) (Display *dpy, GLXContext readCtx, GLXContext writeCtx, GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +typedef void ( *PFNGLXNAMEDCOPYBUFFERSUBDATANVPROC) (Display *dpy, GLXContext readCtx, GLXContext writeCtx, GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +#ifdef GLX_GLXEXT_PROTOTYPES +void glXCopyBufferSubDataNV (Display *dpy, GLXContext readCtx, GLXContext writeCtx, GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +void glXNamedCopyBufferSubDataNV (Display *dpy, GLXContext readCtx, GLXContext writeCtx, GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +#endif +#endif /* GLX_NV_copy_buffer */ + +#ifndef GLX_NV_copy_image +#define GLX_NV_copy_image 1 +typedef void ( *PFNGLXCOPYIMAGESUBDATANVPROC) (Display *dpy, GLXContext srcCtx, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLXContext dstCtx, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); +#ifdef GLX_GLXEXT_PROTOTYPES +void glXCopyImageSubDataNV (Display *dpy, GLXContext srcCtx, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLXContext dstCtx, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); +#endif +#endif /* GLX_NV_copy_image */ + +#ifndef GLX_NV_delay_before_swap +#define GLX_NV_delay_before_swap 1 +typedef Bool ( *PFNGLXDELAYBEFORESWAPNVPROC) (Display *dpy, GLXDrawable drawable, GLfloat seconds); +#ifdef GLX_GLXEXT_PROTOTYPES +Bool glXDelayBeforeSwapNV (Display *dpy, GLXDrawable drawable, GLfloat seconds); +#endif +#endif /* GLX_NV_delay_before_swap */ + +#ifndef GLX_NV_float_buffer +#define GLX_NV_float_buffer 1 +#define GLX_FLOAT_COMPONENTS_NV 0x20B0 +#endif /* GLX_NV_float_buffer */ + +#ifndef GLX_NV_multisample_coverage +#define GLX_NV_multisample_coverage 1 +#define GLX_COVERAGE_SAMPLES_NV 100001 +#define GLX_COLOR_SAMPLES_NV 0x20B3 +#endif /* GLX_NV_multisample_coverage */ + +#ifndef GLX_NV_present_video +#define GLX_NV_present_video 1 +#define GLX_NUM_VIDEO_SLOTS_NV 0x20F0 +typedef unsigned int *( *PFNGLXENUMERATEVIDEODEVICESNVPROC) (Display *dpy, int screen, int *nelements); +typedef int ( *PFNGLXBINDVIDEODEVICENVPROC) (Display *dpy, unsigned int video_slot, unsigned int video_device, const int *attrib_list); +#ifdef GLX_GLXEXT_PROTOTYPES +unsigned int *glXEnumerateVideoDevicesNV (Display *dpy, int screen, int *nelements); +int glXBindVideoDeviceNV (Display *dpy, unsigned int video_slot, unsigned int video_device, const int *attrib_list); +#endif +#endif /* GLX_NV_present_video */ + +#ifndef GLX_NV_swap_group +#define GLX_NV_swap_group 1 +typedef Bool ( *PFNGLXJOINSWAPGROUPNVPROC) (Display *dpy, GLXDrawable drawable, GLuint group); +typedef Bool ( *PFNGLXBINDSWAPBARRIERNVPROC) (Display *dpy, GLuint group, GLuint barrier); +typedef Bool ( *PFNGLXQUERYSWAPGROUPNVPROC) (Display *dpy, GLXDrawable drawable, GLuint *group, GLuint *barrier); +typedef Bool ( *PFNGLXQUERYMAXSWAPGROUPSNVPROC) (Display *dpy, int screen, GLuint *maxGroups, GLuint *maxBarriers); +typedef Bool ( *PFNGLXQUERYFRAMECOUNTNVPROC) (Display *dpy, int screen, GLuint *count); +typedef Bool ( *PFNGLXRESETFRAMECOUNTNVPROC) (Display *dpy, int screen); +#ifdef GLX_GLXEXT_PROTOTYPES +Bool glXJoinSwapGroupNV (Display *dpy, GLXDrawable drawable, GLuint group); +Bool glXBindSwapBarrierNV (Display *dpy, GLuint group, GLuint barrier); +Bool glXQuerySwapGroupNV (Display *dpy, GLXDrawable drawable, GLuint *group, GLuint *barrier); +Bool glXQueryMaxSwapGroupsNV (Display *dpy, int screen, GLuint *maxGroups, GLuint *maxBarriers); +Bool glXQueryFrameCountNV (Display *dpy, int screen, GLuint *count); +Bool glXResetFrameCountNV (Display *dpy, int screen); +#endif +#endif /* GLX_NV_swap_group */ + +#ifndef GLX_NV_video_capture +#define GLX_NV_video_capture 1 +typedef XID GLXVideoCaptureDeviceNV; +#define GLX_DEVICE_ID_NV 0x20CD +#define GLX_UNIQUE_ID_NV 0x20CE +#define GLX_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF +typedef int ( *PFNGLXBINDVIDEOCAPTUREDEVICENVPROC) (Display *dpy, unsigned int video_capture_slot, GLXVideoCaptureDeviceNV device); +typedef GLXVideoCaptureDeviceNV *( *PFNGLXENUMERATEVIDEOCAPTUREDEVICESNVPROC) (Display *dpy, int screen, int *nelements); +typedef void ( *PFNGLXLOCKVIDEOCAPTUREDEVICENVPROC) (Display *dpy, GLXVideoCaptureDeviceNV device); +typedef int ( *PFNGLXQUERYVIDEOCAPTUREDEVICENVPROC) (Display *dpy, GLXVideoCaptureDeviceNV device, int attribute, int *value); +typedef void ( *PFNGLXRELEASEVIDEOCAPTUREDEVICENVPROC) (Display *dpy, GLXVideoCaptureDeviceNV device); +#ifdef GLX_GLXEXT_PROTOTYPES +int glXBindVideoCaptureDeviceNV (Display *dpy, unsigned int video_capture_slot, GLXVideoCaptureDeviceNV device); +GLXVideoCaptureDeviceNV *glXEnumerateVideoCaptureDevicesNV (Display *dpy, int screen, int *nelements); +void glXLockVideoCaptureDeviceNV (Display *dpy, GLXVideoCaptureDeviceNV device); +int glXQueryVideoCaptureDeviceNV (Display *dpy, GLXVideoCaptureDeviceNV device, int attribute, int *value); +void glXReleaseVideoCaptureDeviceNV (Display *dpy, GLXVideoCaptureDeviceNV device); +#endif +#endif /* GLX_NV_video_capture */ + +#ifndef GLX_NV_video_out +#define GLX_NV_video_out 1 +typedef unsigned int GLXVideoDeviceNV; +#define GLX_VIDEO_OUT_COLOR_NV 0x20C3 +#define GLX_VIDEO_OUT_ALPHA_NV 0x20C4 +#define GLX_VIDEO_OUT_DEPTH_NV 0x20C5 +#define GLX_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6 +#define GLX_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7 +#define GLX_VIDEO_OUT_FRAME_NV 0x20C8 +#define GLX_VIDEO_OUT_FIELD_1_NV 0x20C9 +#define GLX_VIDEO_OUT_FIELD_2_NV 0x20CA +#define GLX_VIDEO_OUT_STACKED_FIELDS_1_2_NV 0x20CB +#define GLX_VIDEO_OUT_STACKED_FIELDS_2_1_NV 0x20CC +typedef int ( *PFNGLXGETVIDEODEVICENVPROC) (Display *dpy, int screen, int numVideoDevices, GLXVideoDeviceNV *pVideoDevice); +typedef int ( *PFNGLXRELEASEVIDEODEVICENVPROC) (Display *dpy, int screen, GLXVideoDeviceNV VideoDevice); +typedef int ( *PFNGLXBINDVIDEOIMAGENVPROC) (Display *dpy, GLXVideoDeviceNV VideoDevice, GLXPbuffer pbuf, int iVideoBuffer); +typedef int ( *PFNGLXRELEASEVIDEOIMAGENVPROC) (Display *dpy, GLXPbuffer pbuf); +typedef int ( *PFNGLXSENDPBUFFERTOVIDEONVPROC) (Display *dpy, GLXPbuffer pbuf, int iBufferType, unsigned long *pulCounterPbuffer, GLboolean bBlock); +typedef int ( *PFNGLXGETVIDEOINFONVPROC) (Display *dpy, int screen, GLXVideoDeviceNV VideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo); +#ifdef GLX_GLXEXT_PROTOTYPES +int glXGetVideoDeviceNV (Display *dpy, int screen, int numVideoDevices, GLXVideoDeviceNV *pVideoDevice); +int glXReleaseVideoDeviceNV (Display *dpy, int screen, GLXVideoDeviceNV VideoDevice); +int glXBindVideoImageNV (Display *dpy, GLXVideoDeviceNV VideoDevice, GLXPbuffer pbuf, int iVideoBuffer); +int glXReleaseVideoImageNV (Display *dpy, GLXPbuffer pbuf); +int glXSendPbufferToVideoNV (Display *dpy, GLXPbuffer pbuf, int iBufferType, unsigned long *pulCounterPbuffer, GLboolean bBlock); +int glXGetVideoInfoNV (Display *dpy, int screen, GLXVideoDeviceNV VideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo); +#endif +#endif /* GLX_NV_video_out */ + +#ifndef GLX_OML_swap_method +#define GLX_OML_swap_method 1 +#define GLX_SWAP_METHOD_OML 0x8060 +#define GLX_SWAP_EXCHANGE_OML 0x8061 +#define GLX_SWAP_COPY_OML 0x8062 +#define GLX_SWAP_UNDEFINED_OML 0x8063 +#endif /* GLX_OML_swap_method */ + +#ifndef GLX_OML_sync_control +#define GLX_OML_sync_control 1 +#ifndef GLEXT_64_TYPES_DEFINED +/* This code block is duplicated in glext.h, so must be protected */ +#define GLEXT_64_TYPES_DEFINED +/* Define int32_t, int64_t, and uint64_t types for UST/MSC */ +/* (as used in the GLX_OML_sync_control extension). */ +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#include +#elif defined(__sun__) || defined(__digital__) +#include +#if defined(__STDC__) +#if defined(__arch64__) || defined(_LP64) +typedef long int int64_t; +typedef unsigned long int uint64_t; +#else +typedef long long int int64_t; +typedef unsigned long long int uint64_t; +#endif /* __arch64__ */ +#endif /* __STDC__ */ +#elif defined( __VMS ) || defined(__sgi) +#include +#elif defined(__SCO__) || defined(__USLC__) +#include +#elif defined(__UNIXOS2__) || defined(__SOL64__) +typedef long int int32_t; +typedef long long int int64_t; +typedef unsigned long long int uint64_t; +#elif defined(_WIN32) && defined(__GNUC__) +#include +#elif defined(_WIN32) +typedef __int32 int32_t; +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +#else +/* Fallback if nothing above works */ +#include +#endif +#endif +typedef Bool ( *PFNGLXGETSYNCVALUESOMLPROC) (Display *dpy, GLXDrawable drawable, int64_t *ust, int64_t *msc, int64_t *sbc); +typedef Bool ( *PFNGLXGETMSCRATEOMLPROC) (Display *dpy, GLXDrawable drawable, int32_t *numerator, int32_t *denominator); +typedef int64_t ( *PFNGLXSWAPBUFFERSMSCOMLPROC) (Display *dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder); +typedef Bool ( *PFNGLXWAITFORMSCOMLPROC) (Display *dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc); +typedef Bool ( *PFNGLXWAITFORSBCOMLPROC) (Display *dpy, GLXDrawable drawable, int64_t target_sbc, int64_t *ust, int64_t *msc, int64_t *sbc); +#ifdef GLX_GLXEXT_PROTOTYPES +Bool glXGetSyncValuesOML (Display *dpy, GLXDrawable drawable, int64_t *ust, int64_t *msc, int64_t *sbc); +Bool glXGetMscRateOML (Display *dpy, GLXDrawable drawable, int32_t *numerator, int32_t *denominator); +int64_t glXSwapBuffersMscOML (Display *dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder); +Bool glXWaitForMscOML (Display *dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc); +Bool glXWaitForSbcOML (Display *dpy, GLXDrawable drawable, int64_t target_sbc, int64_t *ust, int64_t *msc, int64_t *sbc); +#endif +#endif /* GLX_OML_sync_control */ + +#ifndef GLX_SGIS_blended_overlay +#define GLX_SGIS_blended_overlay 1 +#define GLX_BLENDED_RGBA_SGIS 0x8025 +#endif /* GLX_SGIS_blended_overlay */ + +#ifndef GLX_SGIS_multisample +#define GLX_SGIS_multisample 1 +#define GLX_SAMPLE_BUFFERS_SGIS 100000 +#define GLX_SAMPLES_SGIS 100001 +#endif /* GLX_SGIS_multisample */ + +#ifndef GLX_SGIS_shared_multisample +#define GLX_SGIS_shared_multisample 1 +#define GLX_MULTISAMPLE_SUB_RECT_WIDTH_SGIS 0x8026 +#define GLX_MULTISAMPLE_SUB_RECT_HEIGHT_SGIS 0x8027 +#endif /* GLX_SGIS_shared_multisample */ + +#ifndef GLX_SGIX_dmbuffer +#define GLX_SGIX_dmbuffer 1 +typedef XID GLXPbufferSGIX; +#ifdef _DM_BUFFER_H_ +#define GLX_DIGITAL_MEDIA_PBUFFER_SGIX 0x8024 +typedef Bool ( *PFNGLXASSOCIATEDMPBUFFERSGIXPROC) (Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer); +#ifdef GLX_GLXEXT_PROTOTYPES +Bool glXAssociateDMPbufferSGIX (Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer); +#endif +#endif /* _DM_BUFFER_H_ */ +#endif /* GLX_SGIX_dmbuffer */ + +#ifndef GLX_SGIX_fbconfig +#define GLX_SGIX_fbconfig 1 +typedef struct __GLXFBConfigRec *GLXFBConfigSGIX; +#define GLX_WINDOW_BIT_SGIX 0x00000001 +#define GLX_PIXMAP_BIT_SGIX 0x00000002 +#define GLX_RGBA_BIT_SGIX 0x00000001 +#define GLX_COLOR_INDEX_BIT_SGIX 0x00000002 +#define GLX_DRAWABLE_TYPE_SGIX 0x8010 +#define GLX_RENDER_TYPE_SGIX 0x8011 +#define GLX_X_RENDERABLE_SGIX 0x8012 +#define GLX_FBCONFIG_ID_SGIX 0x8013 +#define GLX_RGBA_TYPE_SGIX 0x8014 +#define GLX_COLOR_INDEX_TYPE_SGIX 0x8015 +typedef int ( *PFNGLXGETFBCONFIGATTRIBSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, int attribute, int *value); +typedef GLXFBConfigSGIX *( *PFNGLXCHOOSEFBCONFIGSGIXPROC) (Display *dpy, int screen, int *attrib_list, int *nelements); +typedef GLXPixmap ( *PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap); +typedef GLXContext ( *PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct); +typedef XVisualInfo *( *PFNGLXGETVISUALFROMFBCONFIGSGIXPROC) (Display *dpy, GLXFBConfigSGIX config); +typedef GLXFBConfigSGIX ( *PFNGLXGETFBCONFIGFROMVISUALSGIXPROC) (Display *dpy, XVisualInfo *vis); +#ifdef GLX_GLXEXT_PROTOTYPES +int glXGetFBConfigAttribSGIX (Display *dpy, GLXFBConfigSGIX config, int attribute, int *value); +GLXFBConfigSGIX *glXChooseFBConfigSGIX (Display *dpy, int screen, int *attrib_list, int *nelements); +GLXPixmap glXCreateGLXPixmapWithConfigSGIX (Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap); +GLXContext glXCreateContextWithConfigSGIX (Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct); +XVisualInfo *glXGetVisualFromFBConfigSGIX (Display *dpy, GLXFBConfigSGIX config); +GLXFBConfigSGIX glXGetFBConfigFromVisualSGIX (Display *dpy, XVisualInfo *vis); +#endif +#endif /* GLX_SGIX_fbconfig */ + +#ifndef GLX_SGIX_hyperpipe +#define GLX_SGIX_hyperpipe 1 +typedef struct { + char pipeName[80]; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */ + int networkId; +} GLXHyperpipeNetworkSGIX; +typedef struct { + char pipeName[80]; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */ + int channel; + unsigned int participationType; + int timeSlice; +} GLXHyperpipeConfigSGIX; +typedef struct { + char pipeName[80]; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */ + int srcXOrigin, srcYOrigin, srcWidth, srcHeight; + int destXOrigin, destYOrigin, destWidth, destHeight; +} GLXPipeRect; +typedef struct { + char pipeName[80]; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */ + int XOrigin, YOrigin, maxHeight, maxWidth; +} GLXPipeRectLimits; +#define GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX 80 +#define GLX_BAD_HYPERPIPE_CONFIG_SGIX 91 +#define GLX_BAD_HYPERPIPE_SGIX 92 +#define GLX_HYPERPIPE_DISPLAY_PIPE_SGIX 0x00000001 +#define GLX_HYPERPIPE_RENDER_PIPE_SGIX 0x00000002 +#define GLX_PIPE_RECT_SGIX 0x00000001 +#define GLX_PIPE_RECT_LIMITS_SGIX 0x00000002 +#define GLX_HYPERPIPE_STEREO_SGIX 0x00000003 +#define GLX_HYPERPIPE_PIXEL_AVERAGE_SGIX 0x00000004 +#define GLX_HYPERPIPE_ID_SGIX 0x8030 +typedef GLXHyperpipeNetworkSGIX *( *PFNGLXQUERYHYPERPIPENETWORKSGIXPROC) (Display *dpy, int *npipes); +typedef int ( *PFNGLXHYPERPIPECONFIGSGIXPROC) (Display *dpy, int networkId, int npipes, GLXHyperpipeConfigSGIX *cfg, int *hpId); +typedef GLXHyperpipeConfigSGIX *( *PFNGLXQUERYHYPERPIPECONFIGSGIXPROC) (Display *dpy, int hpId, int *npipes); +typedef int ( *PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC) (Display *dpy, int hpId); +typedef int ( *PFNGLXBINDHYPERPIPESGIXPROC) (Display *dpy, int hpId); +typedef int ( *PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *attribList, void *returnAttribList); +typedef int ( *PFNGLXHYPERPIPEATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *attribList); +typedef int ( *PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *returnAttribList); +#ifdef GLX_GLXEXT_PROTOTYPES +GLXHyperpipeNetworkSGIX *glXQueryHyperpipeNetworkSGIX (Display *dpy, int *npipes); +int glXHyperpipeConfigSGIX (Display *dpy, int networkId, int npipes, GLXHyperpipeConfigSGIX *cfg, int *hpId); +GLXHyperpipeConfigSGIX *glXQueryHyperpipeConfigSGIX (Display *dpy, int hpId, int *npipes); +int glXDestroyHyperpipeConfigSGIX (Display *dpy, int hpId); +int glXBindHyperpipeSGIX (Display *dpy, int hpId); +int glXQueryHyperpipeBestAttribSGIX (Display *dpy, int timeSlice, int attrib, int size, void *attribList, void *returnAttribList); +int glXHyperpipeAttribSGIX (Display *dpy, int timeSlice, int attrib, int size, void *attribList); +int glXQueryHyperpipeAttribSGIX (Display *dpy, int timeSlice, int attrib, int size, void *returnAttribList); +#endif +#endif /* GLX_SGIX_hyperpipe */ + +#ifndef GLX_SGIX_pbuffer +#define GLX_SGIX_pbuffer 1 +#define GLX_PBUFFER_BIT_SGIX 0x00000004 +#define GLX_BUFFER_CLOBBER_MASK_SGIX 0x08000000 +#define GLX_FRONT_LEFT_BUFFER_BIT_SGIX 0x00000001 +#define GLX_FRONT_RIGHT_BUFFER_BIT_SGIX 0x00000002 +#define GLX_BACK_LEFT_BUFFER_BIT_SGIX 0x00000004 +#define GLX_BACK_RIGHT_BUFFER_BIT_SGIX 0x00000008 +#define GLX_AUX_BUFFERS_BIT_SGIX 0x00000010 +#define GLX_DEPTH_BUFFER_BIT_SGIX 0x00000020 +#define GLX_STENCIL_BUFFER_BIT_SGIX 0x00000040 +#define GLX_ACCUM_BUFFER_BIT_SGIX 0x00000080 +#define GLX_SAMPLE_BUFFERS_BIT_SGIX 0x00000100 +#define GLX_MAX_PBUFFER_WIDTH_SGIX 0x8016 +#define GLX_MAX_PBUFFER_HEIGHT_SGIX 0x8017 +#define GLX_MAX_PBUFFER_PIXELS_SGIX 0x8018 +#define GLX_OPTIMAL_PBUFFER_WIDTH_SGIX 0x8019 +#define GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX 0x801A +#define GLX_PRESERVED_CONTENTS_SGIX 0x801B +#define GLX_LARGEST_PBUFFER_SGIX 0x801C +#define GLX_WIDTH_SGIX 0x801D +#define GLX_HEIGHT_SGIX 0x801E +#define GLX_EVENT_MASK_SGIX 0x801F +#define GLX_DAMAGED_SGIX 0x8020 +#define GLX_SAVED_SGIX 0x8021 +#define GLX_WINDOW_SGIX 0x8022 +#define GLX_PBUFFER_SGIX 0x8023 +typedef GLXPbufferSGIX ( *PFNGLXCREATEGLXPBUFFERSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int *attrib_list); +typedef void ( *PFNGLXDESTROYGLXPBUFFERSGIXPROC) (Display *dpy, GLXPbufferSGIX pbuf); +typedef int ( *PFNGLXQUERYGLXPBUFFERSGIXPROC) (Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value); +typedef void ( *PFNGLXSELECTEVENTSGIXPROC) (Display *dpy, GLXDrawable drawable, unsigned long mask); +typedef void ( *PFNGLXGETSELECTEDEVENTSGIXPROC) (Display *dpy, GLXDrawable drawable, unsigned long *mask); +#ifdef GLX_GLXEXT_PROTOTYPES +GLXPbufferSGIX glXCreateGLXPbufferSGIX (Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int *attrib_list); +void glXDestroyGLXPbufferSGIX (Display *dpy, GLXPbufferSGIX pbuf); +int glXQueryGLXPbufferSGIX (Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value); +void glXSelectEventSGIX (Display *dpy, GLXDrawable drawable, unsigned long mask); +void glXGetSelectedEventSGIX (Display *dpy, GLXDrawable drawable, unsigned long *mask); +#endif +#endif /* GLX_SGIX_pbuffer */ + +#ifndef GLX_SGIX_swap_barrier +#define GLX_SGIX_swap_barrier 1 +typedef void ( *PFNGLXBINDSWAPBARRIERSGIXPROC) (Display *dpy, GLXDrawable drawable, int barrier); +typedef Bool ( *PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC) (Display *dpy, int screen, int *max); +#ifdef GLX_GLXEXT_PROTOTYPES +void glXBindSwapBarrierSGIX (Display *dpy, GLXDrawable drawable, int barrier); +Bool glXQueryMaxSwapBarriersSGIX (Display *dpy, int screen, int *max); +#endif +#endif /* GLX_SGIX_swap_barrier */ + +#ifndef GLX_SGIX_swap_group +#define GLX_SGIX_swap_group 1 +typedef void ( *PFNGLXJOINSWAPGROUPSGIXPROC) (Display *dpy, GLXDrawable drawable, GLXDrawable member); +#ifdef GLX_GLXEXT_PROTOTYPES +void glXJoinSwapGroupSGIX (Display *dpy, GLXDrawable drawable, GLXDrawable member); +#endif +#endif /* GLX_SGIX_swap_group */ + +#ifndef GLX_SGIX_video_resize +#define GLX_SGIX_video_resize 1 +#define GLX_SYNC_FRAME_SGIX 0x00000000 +#define GLX_SYNC_SWAP_SGIX 0x00000001 +typedef int ( *PFNGLXBINDCHANNELTOWINDOWSGIXPROC) (Display *display, int screen, int channel, Window window); +typedef int ( *PFNGLXCHANNELRECTSGIXPROC) (Display *display, int screen, int channel, int x, int y, int w, int h); +typedef int ( *PFNGLXQUERYCHANNELRECTSGIXPROC) (Display *display, int screen, int channel, int *dx, int *dy, int *dw, int *dh); +typedef int ( *PFNGLXQUERYCHANNELDELTASSGIXPROC) (Display *display, int screen, int channel, int *x, int *y, int *w, int *h); +typedef int ( *PFNGLXCHANNELRECTSYNCSGIXPROC) (Display *display, int screen, int channel, GLenum synctype); +#ifdef GLX_GLXEXT_PROTOTYPES +int glXBindChannelToWindowSGIX (Display *display, int screen, int channel, Window window); +int glXChannelRectSGIX (Display *display, int screen, int channel, int x, int y, int w, int h); +int glXQueryChannelRectSGIX (Display *display, int screen, int channel, int *dx, int *dy, int *dw, int *dh); +int glXQueryChannelDeltasSGIX (Display *display, int screen, int channel, int *x, int *y, int *w, int *h); +int glXChannelRectSyncSGIX (Display *display, int screen, int channel, GLenum synctype); +#endif +#endif /* GLX_SGIX_video_resize */ + +#ifndef GLX_SGIX_video_source +#define GLX_SGIX_video_source 1 +typedef XID GLXVideoSourceSGIX; +#ifdef _VL_H +typedef GLXVideoSourceSGIX ( *PFNGLXCREATEGLXVIDEOSOURCESGIXPROC) (Display *display, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode); +typedef void ( *PFNGLXDESTROYGLXVIDEOSOURCESGIXPROC) (Display *dpy, GLXVideoSourceSGIX glxvideosource); +#ifdef GLX_GLXEXT_PROTOTYPES +GLXVideoSourceSGIX glXCreateGLXVideoSourceSGIX (Display *display, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode); +void glXDestroyGLXVideoSourceSGIX (Display *dpy, GLXVideoSourceSGIX glxvideosource); +#endif +#endif /* _VL_H */ +#endif /* GLX_SGIX_video_source */ + +#ifndef GLX_SGIX_visual_select_group +#define GLX_SGIX_visual_select_group 1 +#define GLX_VISUAL_SELECT_GROUP_SGIX 0x8028 +#endif /* GLX_SGIX_visual_select_group */ + +#ifndef GLX_SGI_cushion +#define GLX_SGI_cushion 1 +typedef void ( *PFNGLXCUSHIONSGIPROC) (Display *dpy, Window window, float cushion); +#ifdef GLX_GLXEXT_PROTOTYPES +void glXCushionSGI (Display *dpy, Window window, float cushion); +#endif +#endif /* GLX_SGI_cushion */ + +#ifndef GLX_SGI_make_current_read +#define GLX_SGI_make_current_read 1 +typedef Bool ( *PFNGLXMAKECURRENTREADSGIPROC) (Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx); +typedef GLXDrawable ( *PFNGLXGETCURRENTREADDRAWABLESGIPROC) (void); +#ifdef GLX_GLXEXT_PROTOTYPES +Bool glXMakeCurrentReadSGI (Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx); +GLXDrawable glXGetCurrentReadDrawableSGI (void); +#endif +#endif /* GLX_SGI_make_current_read */ + +#ifndef GLX_SGI_swap_control +#define GLX_SGI_swap_control 1 +typedef int ( *PFNGLXSWAPINTERVALSGIPROC) (int interval); +#ifdef GLX_GLXEXT_PROTOTYPES +int glXSwapIntervalSGI (int interval); +#endif +#endif /* GLX_SGI_swap_control */ + +#ifndef GLX_SGI_video_sync +#define GLX_SGI_video_sync 1 +typedef int ( *PFNGLXGETVIDEOSYNCSGIPROC) (unsigned int *count); +typedef int ( *PFNGLXWAITVIDEOSYNCSGIPROC) (int divisor, int remainder, unsigned int *count); +#ifdef GLX_GLXEXT_PROTOTYPES +int glXGetVideoSyncSGI (unsigned int *count); +int glXWaitVideoSyncSGI (int divisor, int remainder, unsigned int *count); +#endif +#endif /* GLX_SGI_video_sync */ + +#ifndef GLX_SUN_get_transparent_index +#define GLX_SUN_get_transparent_index 1 +typedef Status ( *PFNGLXGETTRANSPARENTINDEXSUNPROC) (Display *dpy, Window overlay, Window underlay, long *pTransparentIndex); +#ifdef GLX_GLXEXT_PROTOTYPES +Status glXGetTransparentIndexSUN (Display *dpy, Window overlay, Window underlay, long *pTransparentIndex); +#endif +#endif /* GLX_SUN_get_transparent_index */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/testbed/glfw/deps/GL/wglext.h b/testbed/glfw/deps/GL/wglext.h new file mode 100644 index 00000000..daba4109 --- /dev/null +++ b/testbed/glfw/deps/GL/wglext.h @@ -0,0 +1,840 @@ +#ifndef __wglext_h_ +#define __wglext_h_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Copyright (c) 2013-2014 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE 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 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ +/* +** This header is generated from the Khronos OpenGL / OpenGL ES XML +** API Registry. The current version of the Registry, generator scripts +** used to make the header, and the header can be found at +** http://www.opengl.org/registry/ +** +** Khronos $Revision: 27684 $ on $Date: 2014-08-11 01:21:35 -0700 (Mon, 11 Aug 2014) $ +*/ + +#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) +#define WIN32_LEAN_AND_MEAN 1 +#include +#endif + +#define WGL_WGLEXT_VERSION 20140810 + +/* Generated C header for: + * API: wgl + * Versions considered: .* + * Versions emitted: _nomatch_^ + * Default extensions included: wgl + * Additional extensions included: _nomatch_^ + * Extensions removed: _nomatch_^ + */ + +#ifndef WGL_ARB_buffer_region +#define WGL_ARB_buffer_region 1 +#define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001 +#define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002 +#define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004 +#define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008 +typedef HANDLE (WINAPI * PFNWGLCREATEBUFFERREGIONARBPROC) (HDC hDC, int iLayerPlane, UINT uType); +typedef VOID (WINAPI * PFNWGLDELETEBUFFERREGIONARBPROC) (HANDLE hRegion); +typedef BOOL (WINAPI * PFNWGLSAVEBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height); +typedef BOOL (WINAPI * PFNWGLRESTOREBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc); +#ifdef WGL_WGLEXT_PROTOTYPES +HANDLE WINAPI wglCreateBufferRegionARB (HDC hDC, int iLayerPlane, UINT uType); +VOID WINAPI wglDeleteBufferRegionARB (HANDLE hRegion); +BOOL WINAPI wglSaveBufferRegionARB (HANDLE hRegion, int x, int y, int width, int height); +BOOL WINAPI wglRestoreBufferRegionARB (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc); +#endif +#endif /* WGL_ARB_buffer_region */ + +#ifndef WGL_ARB_context_flush_control +#define WGL_ARB_context_flush_control 1 +#define WGL_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097 +#define WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0 +#define WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098 +#endif /* WGL_ARB_context_flush_control */ + +#ifndef WGL_ARB_create_context +#define WGL_ARB_create_context 1 +#define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001 +#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002 +#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 +#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093 +#define WGL_CONTEXT_FLAGS_ARB 0x2094 +#define ERROR_INVALID_VERSION_ARB 0x2095 +typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int *attribList); +#ifdef WGL_WGLEXT_PROTOTYPES +HGLRC WINAPI wglCreateContextAttribsARB (HDC hDC, HGLRC hShareContext, const int *attribList); +#endif +#endif /* WGL_ARB_create_context */ + +#ifndef WGL_ARB_create_context_profile +#define WGL_ARB_create_context_profile 1 +#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 +#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 +#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 +#define ERROR_INVALID_PROFILE_ARB 0x2096 +#endif /* WGL_ARB_create_context_profile */ + +#ifndef WGL_ARB_create_context_robustness +#define WGL_ARB_create_context_robustness 1 +#define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004 +#define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252 +#define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 +#define WGL_NO_RESET_NOTIFICATION_ARB 0x8261 +#endif /* WGL_ARB_create_context_robustness */ + +#ifndef WGL_ARB_extensions_string +#define WGL_ARB_extensions_string 1 +typedef const char *(WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc); +#ifdef WGL_WGLEXT_PROTOTYPES +const char *WINAPI wglGetExtensionsStringARB (HDC hdc); +#endif +#endif /* WGL_ARB_extensions_string */ + +#ifndef WGL_ARB_framebuffer_sRGB +#define WGL_ARB_framebuffer_sRGB 1 +#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9 +#endif /* WGL_ARB_framebuffer_sRGB */ + +#ifndef WGL_ARB_make_current_read +#define WGL_ARB_make_current_read 1 +#define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043 +#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054 +typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTARBPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); +typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCARBPROC) (void); +#ifdef WGL_WGLEXT_PROTOTYPES +BOOL WINAPI wglMakeContextCurrentARB (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); +HDC WINAPI wglGetCurrentReadDCARB (void); +#endif +#endif /* WGL_ARB_make_current_read */ + +#ifndef WGL_ARB_multisample +#define WGL_ARB_multisample 1 +#define WGL_SAMPLE_BUFFERS_ARB 0x2041 +#define WGL_SAMPLES_ARB 0x2042 +#endif /* WGL_ARB_multisample */ + +#ifndef WGL_ARB_pbuffer +#define WGL_ARB_pbuffer 1 +DECLARE_HANDLE(HPBUFFERARB); +#define WGL_DRAW_TO_PBUFFER_ARB 0x202D +#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E +#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F +#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030 +#define WGL_PBUFFER_LARGEST_ARB 0x2033 +#define WGL_PBUFFER_WIDTH_ARB 0x2034 +#define WGL_PBUFFER_HEIGHT_ARB 0x2035 +#define WGL_PBUFFER_LOST_ARB 0x2036 +typedef HPBUFFERARB (WINAPI * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); +typedef HDC (WINAPI * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer); +typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC); +typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer); +typedef BOOL (WINAPI * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int *piValue); +#ifdef WGL_WGLEXT_PROTOTYPES +HPBUFFERARB WINAPI wglCreatePbufferARB (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); +HDC WINAPI wglGetPbufferDCARB (HPBUFFERARB hPbuffer); +int WINAPI wglReleasePbufferDCARB (HPBUFFERARB hPbuffer, HDC hDC); +BOOL WINAPI wglDestroyPbufferARB (HPBUFFERARB hPbuffer); +BOOL WINAPI wglQueryPbufferARB (HPBUFFERARB hPbuffer, int iAttribute, int *piValue); +#endif +#endif /* WGL_ARB_pbuffer */ + +#ifndef WGL_ARB_pixel_format +#define WGL_ARB_pixel_format 1 +#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 +#define WGL_DRAW_TO_WINDOW_ARB 0x2001 +#define WGL_DRAW_TO_BITMAP_ARB 0x2002 +#define WGL_ACCELERATION_ARB 0x2003 +#define WGL_NEED_PALETTE_ARB 0x2004 +#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 +#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 +#define WGL_SWAP_METHOD_ARB 0x2007 +#define WGL_NUMBER_OVERLAYS_ARB 0x2008 +#define WGL_NUMBER_UNDERLAYS_ARB 0x2009 +#define WGL_TRANSPARENT_ARB 0x200A +#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 +#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 +#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 +#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A +#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B +#define WGL_SHARE_DEPTH_ARB 0x200C +#define WGL_SHARE_STENCIL_ARB 0x200D +#define WGL_SHARE_ACCUM_ARB 0x200E +#define WGL_SUPPORT_GDI_ARB 0x200F +#define WGL_SUPPORT_OPENGL_ARB 0x2010 +#define WGL_DOUBLE_BUFFER_ARB 0x2011 +#define WGL_STEREO_ARB 0x2012 +#define WGL_PIXEL_TYPE_ARB 0x2013 +#define WGL_COLOR_BITS_ARB 0x2014 +#define WGL_RED_BITS_ARB 0x2015 +#define WGL_RED_SHIFT_ARB 0x2016 +#define WGL_GREEN_BITS_ARB 0x2017 +#define WGL_GREEN_SHIFT_ARB 0x2018 +#define WGL_BLUE_BITS_ARB 0x2019 +#define WGL_BLUE_SHIFT_ARB 0x201A +#define WGL_ALPHA_BITS_ARB 0x201B +#define WGL_ALPHA_SHIFT_ARB 0x201C +#define WGL_ACCUM_BITS_ARB 0x201D +#define WGL_ACCUM_RED_BITS_ARB 0x201E +#define WGL_ACCUM_GREEN_BITS_ARB 0x201F +#define WGL_ACCUM_BLUE_BITS_ARB 0x2020 +#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 +#define WGL_DEPTH_BITS_ARB 0x2022 +#define WGL_STENCIL_BITS_ARB 0x2023 +#define WGL_AUX_BUFFERS_ARB 0x2024 +#define WGL_NO_ACCELERATION_ARB 0x2025 +#define WGL_GENERIC_ACCELERATION_ARB 0x2026 +#define WGL_FULL_ACCELERATION_ARB 0x2027 +#define WGL_SWAP_EXCHANGE_ARB 0x2028 +#define WGL_SWAP_COPY_ARB 0x2029 +#define WGL_SWAP_UNDEFINED_ARB 0x202A +#define WGL_TYPE_RGBA_ARB 0x202B +#define WGL_TYPE_COLORINDEX_ARB 0x202C +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues); +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues); +typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); +#ifdef WGL_WGLEXT_PROTOTYPES +BOOL WINAPI wglGetPixelFormatAttribivARB (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues); +BOOL WINAPI wglGetPixelFormatAttribfvARB (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues); +BOOL WINAPI wglChoosePixelFormatARB (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); +#endif +#endif /* WGL_ARB_pixel_format */ + +#ifndef WGL_ARB_pixel_format_float +#define WGL_ARB_pixel_format_float 1 +#define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0 +#endif /* WGL_ARB_pixel_format_float */ + +#ifndef WGL_ARB_render_texture +#define WGL_ARB_render_texture 1 +#define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070 +#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071 +#define WGL_TEXTURE_FORMAT_ARB 0x2072 +#define WGL_TEXTURE_TARGET_ARB 0x2073 +#define WGL_MIPMAP_TEXTURE_ARB 0x2074 +#define WGL_TEXTURE_RGB_ARB 0x2075 +#define WGL_TEXTURE_RGBA_ARB 0x2076 +#define WGL_NO_TEXTURE_ARB 0x2077 +#define WGL_TEXTURE_CUBE_MAP_ARB 0x2078 +#define WGL_TEXTURE_1D_ARB 0x2079 +#define WGL_TEXTURE_2D_ARB 0x207A +#define WGL_MIPMAP_LEVEL_ARB 0x207B +#define WGL_CUBE_MAP_FACE_ARB 0x207C +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080 +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081 +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082 +#define WGL_FRONT_LEFT_ARB 0x2083 +#define WGL_FRONT_RIGHT_ARB 0x2084 +#define WGL_BACK_LEFT_ARB 0x2085 +#define WGL_BACK_RIGHT_ARB 0x2086 +#define WGL_AUX0_ARB 0x2087 +#define WGL_AUX1_ARB 0x2088 +#define WGL_AUX2_ARB 0x2089 +#define WGL_AUX3_ARB 0x208A +#define WGL_AUX4_ARB 0x208B +#define WGL_AUX5_ARB 0x208C +#define WGL_AUX6_ARB 0x208D +#define WGL_AUX7_ARB 0x208E +#define WGL_AUX8_ARB 0x208F +#define WGL_AUX9_ARB 0x2090 +typedef BOOL (WINAPI * PFNWGLBINDTEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); +typedef BOOL (WINAPI * PFNWGLRELEASETEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); +typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, const int *piAttribList); +#ifdef WGL_WGLEXT_PROTOTYPES +BOOL WINAPI wglBindTexImageARB (HPBUFFERARB hPbuffer, int iBuffer); +BOOL WINAPI wglReleaseTexImageARB (HPBUFFERARB hPbuffer, int iBuffer); +BOOL WINAPI wglSetPbufferAttribARB (HPBUFFERARB hPbuffer, const int *piAttribList); +#endif +#endif /* WGL_ARB_render_texture */ + +#ifndef WGL_ARB_robustness_application_isolation +#define WGL_ARB_robustness_application_isolation 1 +#define WGL_CONTEXT_RESET_ISOLATION_BIT_ARB 0x00000008 +#endif /* WGL_ARB_robustness_application_isolation */ + +#ifndef WGL_ARB_robustness_share_group_isolation +#define WGL_ARB_robustness_share_group_isolation 1 +#endif /* WGL_ARB_robustness_share_group_isolation */ + +#ifndef WGL_3DFX_multisample +#define WGL_3DFX_multisample 1 +#define WGL_SAMPLE_BUFFERS_3DFX 0x2060 +#define WGL_SAMPLES_3DFX 0x2061 +#endif /* WGL_3DFX_multisample */ + +#ifndef WGL_3DL_stereo_control +#define WGL_3DL_stereo_control 1 +#define WGL_STEREO_EMITTER_ENABLE_3DL 0x2055 +#define WGL_STEREO_EMITTER_DISABLE_3DL 0x2056 +#define WGL_STEREO_POLARITY_NORMAL_3DL 0x2057 +#define WGL_STEREO_POLARITY_INVERT_3DL 0x2058 +typedef BOOL (WINAPI * PFNWGLSETSTEREOEMITTERSTATE3DLPROC) (HDC hDC, UINT uState); +#ifdef WGL_WGLEXT_PROTOTYPES +BOOL WINAPI wglSetStereoEmitterState3DL (HDC hDC, UINT uState); +#endif +#endif /* WGL_3DL_stereo_control */ + +#ifndef WGL_AMD_gpu_association +#define WGL_AMD_gpu_association 1 +#define WGL_GPU_VENDOR_AMD 0x1F00 +#define WGL_GPU_RENDERER_STRING_AMD 0x1F01 +#define WGL_GPU_OPENGL_VERSION_STRING_AMD 0x1F02 +#define WGL_GPU_FASTEST_TARGET_GPUS_AMD 0x21A2 +#define WGL_GPU_RAM_AMD 0x21A3 +#define WGL_GPU_CLOCK_AMD 0x21A4 +#define WGL_GPU_NUM_PIPES_AMD 0x21A5 +#define WGL_GPU_NUM_SIMD_AMD 0x21A6 +#define WGL_GPU_NUM_RB_AMD 0x21A7 +#define WGL_GPU_NUM_SPI_AMD 0x21A8 +typedef UINT (WINAPI * PFNWGLGETGPUIDSAMDPROC) (UINT maxCount, UINT *ids); +typedef INT (WINAPI * PFNWGLGETGPUINFOAMDPROC) (UINT id, int property, GLenum dataType, UINT size, void *data); +typedef UINT (WINAPI * PFNWGLGETCONTEXTGPUIDAMDPROC) (HGLRC hglrc); +typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC) (UINT id); +typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC) (UINT id, HGLRC hShareContext, const int *attribList); +typedef BOOL (WINAPI * PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC) (HGLRC hglrc); +typedef BOOL (WINAPI * PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC) (HGLRC hglrc); +typedef HGLRC (WINAPI * PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC) (void); +typedef VOID (WINAPI * PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC) (HGLRC dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +#ifdef WGL_WGLEXT_PROTOTYPES +UINT WINAPI wglGetGPUIDsAMD (UINT maxCount, UINT *ids); +INT WINAPI wglGetGPUInfoAMD (UINT id, int property, GLenum dataType, UINT size, void *data); +UINT WINAPI wglGetContextGPUIDAMD (HGLRC hglrc); +HGLRC WINAPI wglCreateAssociatedContextAMD (UINT id); +HGLRC WINAPI wglCreateAssociatedContextAttribsAMD (UINT id, HGLRC hShareContext, const int *attribList); +BOOL WINAPI wglDeleteAssociatedContextAMD (HGLRC hglrc); +BOOL WINAPI wglMakeAssociatedContextCurrentAMD (HGLRC hglrc); +HGLRC WINAPI wglGetCurrentAssociatedContextAMD (void); +VOID WINAPI wglBlitContextFramebufferAMD (HGLRC dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +#endif +#endif /* WGL_AMD_gpu_association */ + +#ifndef WGL_ATI_pixel_format_float +#define WGL_ATI_pixel_format_float 1 +#define WGL_TYPE_RGBA_FLOAT_ATI 0x21A0 +#endif /* WGL_ATI_pixel_format_float */ + +#ifndef WGL_EXT_create_context_es2_profile +#define WGL_EXT_create_context_es2_profile 1 +#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004 +#endif /* WGL_EXT_create_context_es2_profile */ + +#ifndef WGL_EXT_create_context_es_profile +#define WGL_EXT_create_context_es_profile 1 +#define WGL_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004 +#endif /* WGL_EXT_create_context_es_profile */ + +#ifndef WGL_EXT_depth_float +#define WGL_EXT_depth_float 1 +#define WGL_DEPTH_FLOAT_EXT 0x2040 +#endif /* WGL_EXT_depth_float */ + +#ifndef WGL_EXT_display_color_table +#define WGL_EXT_display_color_table 1 +typedef GLboolean (WINAPI * PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC) (GLushort id); +typedef GLboolean (WINAPI * PFNWGLLOADDISPLAYCOLORTABLEEXTPROC) (const GLushort *table, GLuint length); +typedef GLboolean (WINAPI * PFNWGLBINDDISPLAYCOLORTABLEEXTPROC) (GLushort id); +typedef VOID (WINAPI * PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC) (GLushort id); +#ifdef WGL_WGLEXT_PROTOTYPES +GLboolean WINAPI wglCreateDisplayColorTableEXT (GLushort id); +GLboolean WINAPI wglLoadDisplayColorTableEXT (const GLushort *table, GLuint length); +GLboolean WINAPI wglBindDisplayColorTableEXT (GLushort id); +VOID WINAPI wglDestroyDisplayColorTableEXT (GLushort id); +#endif +#endif /* WGL_EXT_display_color_table */ + +#ifndef WGL_EXT_extensions_string +#define WGL_EXT_extensions_string 1 +typedef const char *(WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC) (void); +#ifdef WGL_WGLEXT_PROTOTYPES +const char *WINAPI wglGetExtensionsStringEXT (void); +#endif +#endif /* WGL_EXT_extensions_string */ + +#ifndef WGL_EXT_framebuffer_sRGB +#define WGL_EXT_framebuffer_sRGB 1 +#define WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20A9 +#endif /* WGL_EXT_framebuffer_sRGB */ + +#ifndef WGL_EXT_make_current_read +#define WGL_EXT_make_current_read 1 +#define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043 +typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTEXTPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); +typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCEXTPROC) (void); +#ifdef WGL_WGLEXT_PROTOTYPES +BOOL WINAPI wglMakeContextCurrentEXT (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); +HDC WINAPI wglGetCurrentReadDCEXT (void); +#endif +#endif /* WGL_EXT_make_current_read */ + +#ifndef WGL_EXT_multisample +#define WGL_EXT_multisample 1 +#define WGL_SAMPLE_BUFFERS_EXT 0x2041 +#define WGL_SAMPLES_EXT 0x2042 +#endif /* WGL_EXT_multisample */ + +#ifndef WGL_EXT_pbuffer +#define WGL_EXT_pbuffer 1 +DECLARE_HANDLE(HPBUFFEREXT); +#define WGL_DRAW_TO_PBUFFER_EXT 0x202D +#define WGL_MAX_PBUFFER_PIXELS_EXT 0x202E +#define WGL_MAX_PBUFFER_WIDTH_EXT 0x202F +#define WGL_MAX_PBUFFER_HEIGHT_EXT 0x2030 +#define WGL_OPTIMAL_PBUFFER_WIDTH_EXT 0x2031 +#define WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032 +#define WGL_PBUFFER_LARGEST_EXT 0x2033 +#define WGL_PBUFFER_WIDTH_EXT 0x2034 +#define WGL_PBUFFER_HEIGHT_EXT 0x2035 +typedef HPBUFFEREXT (WINAPI * PFNWGLCREATEPBUFFEREXTPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); +typedef HDC (WINAPI * PFNWGLGETPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer); +typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer, HDC hDC); +typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer); +typedef BOOL (WINAPI * PFNWGLQUERYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue); +#ifdef WGL_WGLEXT_PROTOTYPES +HPBUFFEREXT WINAPI wglCreatePbufferEXT (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); +HDC WINAPI wglGetPbufferDCEXT (HPBUFFEREXT hPbuffer); +int WINAPI wglReleasePbufferDCEXT (HPBUFFEREXT hPbuffer, HDC hDC); +BOOL WINAPI wglDestroyPbufferEXT (HPBUFFEREXT hPbuffer); +BOOL WINAPI wglQueryPbufferEXT (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue); +#endif +#endif /* WGL_EXT_pbuffer */ + +#ifndef WGL_EXT_pixel_format +#define WGL_EXT_pixel_format 1 +#define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000 +#define WGL_DRAW_TO_WINDOW_EXT 0x2001 +#define WGL_DRAW_TO_BITMAP_EXT 0x2002 +#define WGL_ACCELERATION_EXT 0x2003 +#define WGL_NEED_PALETTE_EXT 0x2004 +#define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005 +#define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006 +#define WGL_SWAP_METHOD_EXT 0x2007 +#define WGL_NUMBER_OVERLAYS_EXT 0x2008 +#define WGL_NUMBER_UNDERLAYS_EXT 0x2009 +#define WGL_TRANSPARENT_EXT 0x200A +#define WGL_TRANSPARENT_VALUE_EXT 0x200B +#define WGL_SHARE_DEPTH_EXT 0x200C +#define WGL_SHARE_STENCIL_EXT 0x200D +#define WGL_SHARE_ACCUM_EXT 0x200E +#define WGL_SUPPORT_GDI_EXT 0x200F +#define WGL_SUPPORT_OPENGL_EXT 0x2010 +#define WGL_DOUBLE_BUFFER_EXT 0x2011 +#define WGL_STEREO_EXT 0x2012 +#define WGL_PIXEL_TYPE_EXT 0x2013 +#define WGL_COLOR_BITS_EXT 0x2014 +#define WGL_RED_BITS_EXT 0x2015 +#define WGL_RED_SHIFT_EXT 0x2016 +#define WGL_GREEN_BITS_EXT 0x2017 +#define WGL_GREEN_SHIFT_EXT 0x2018 +#define WGL_BLUE_BITS_EXT 0x2019 +#define WGL_BLUE_SHIFT_EXT 0x201A +#define WGL_ALPHA_BITS_EXT 0x201B +#define WGL_ALPHA_SHIFT_EXT 0x201C +#define WGL_ACCUM_BITS_EXT 0x201D +#define WGL_ACCUM_RED_BITS_EXT 0x201E +#define WGL_ACCUM_GREEN_BITS_EXT 0x201F +#define WGL_ACCUM_BLUE_BITS_EXT 0x2020 +#define WGL_ACCUM_ALPHA_BITS_EXT 0x2021 +#define WGL_DEPTH_BITS_EXT 0x2022 +#define WGL_STENCIL_BITS_EXT 0x2023 +#define WGL_AUX_BUFFERS_EXT 0x2024 +#define WGL_NO_ACCELERATION_EXT 0x2025 +#define WGL_GENERIC_ACCELERATION_EXT 0x2026 +#define WGL_FULL_ACCELERATION_EXT 0x2027 +#define WGL_SWAP_EXCHANGE_EXT 0x2028 +#define WGL_SWAP_COPY_EXT 0x2029 +#define WGL_SWAP_UNDEFINED_EXT 0x202A +#define WGL_TYPE_RGBA_EXT 0x202B +#define WGL_TYPE_COLORINDEX_EXT 0x202C +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues); +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues); +typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATEXTPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); +#ifdef WGL_WGLEXT_PROTOTYPES +BOOL WINAPI wglGetPixelFormatAttribivEXT (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues); +BOOL WINAPI wglGetPixelFormatAttribfvEXT (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues); +BOOL WINAPI wglChoosePixelFormatEXT (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); +#endif +#endif /* WGL_EXT_pixel_format */ + +#ifndef WGL_EXT_pixel_format_packed_float +#define WGL_EXT_pixel_format_packed_float 1 +#define WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT 0x20A8 +#endif /* WGL_EXT_pixel_format_packed_float */ + +#ifndef WGL_EXT_swap_control +#define WGL_EXT_swap_control 1 +typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval); +typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void); +#ifdef WGL_WGLEXT_PROTOTYPES +BOOL WINAPI wglSwapIntervalEXT (int interval); +int WINAPI wglGetSwapIntervalEXT (void); +#endif +#endif /* WGL_EXT_swap_control */ + +#ifndef WGL_EXT_swap_control_tear +#define WGL_EXT_swap_control_tear 1 +#endif /* WGL_EXT_swap_control_tear */ + +#ifndef WGL_I3D_digital_video_control +#define WGL_I3D_digital_video_control 1 +#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050 +#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051 +#define WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052 +#define WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053 +typedef BOOL (WINAPI * PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue); +typedef BOOL (WINAPI * PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue); +#ifdef WGL_WGLEXT_PROTOTYPES +BOOL WINAPI wglGetDigitalVideoParametersI3D (HDC hDC, int iAttribute, int *piValue); +BOOL WINAPI wglSetDigitalVideoParametersI3D (HDC hDC, int iAttribute, const int *piValue); +#endif +#endif /* WGL_I3D_digital_video_control */ + +#ifndef WGL_I3D_gamma +#define WGL_I3D_gamma 1 +#define WGL_GAMMA_TABLE_SIZE_I3D 0x204E +#define WGL_GAMMA_EXCLUDE_DESKTOP_I3D 0x204F +typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue); +typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue); +typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue); +typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue); +#ifdef WGL_WGLEXT_PROTOTYPES +BOOL WINAPI wglGetGammaTableParametersI3D (HDC hDC, int iAttribute, int *piValue); +BOOL WINAPI wglSetGammaTableParametersI3D (HDC hDC, int iAttribute, const int *piValue); +BOOL WINAPI wglGetGammaTableI3D (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue); +BOOL WINAPI wglSetGammaTableI3D (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue); +#endif +#endif /* WGL_I3D_gamma */ + +#ifndef WGL_I3D_genlock +#define WGL_I3D_genlock 1 +#define WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044 +#define WGL_GENLOCK_SOURCE_EXTERNAL_SYNC_I3D 0x2045 +#define WGL_GENLOCK_SOURCE_EXTERNAL_FIELD_I3D 0x2046 +#define WGL_GENLOCK_SOURCE_EXTERNAL_TTL_I3D 0x2047 +#define WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048 +#define WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049 +#define WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A +#define WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B +#define WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C +typedef BOOL (WINAPI * PFNWGLENABLEGENLOCKI3DPROC) (HDC hDC); +typedef BOOL (WINAPI * PFNWGLDISABLEGENLOCKI3DPROC) (HDC hDC); +typedef BOOL (WINAPI * PFNWGLISENABLEDGENLOCKI3DPROC) (HDC hDC, BOOL *pFlag); +typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEI3DPROC) (HDC hDC, UINT uSource); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEI3DPROC) (HDC hDC, UINT *uSource); +typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT uEdge); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT *uEdge); +typedef BOOL (WINAPI * PFNWGLGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT uRate); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT *uRate); +typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT uDelay); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT *uDelay); +typedef BOOL (WINAPI * PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC) (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay); +#ifdef WGL_WGLEXT_PROTOTYPES +BOOL WINAPI wglEnableGenlockI3D (HDC hDC); +BOOL WINAPI wglDisableGenlockI3D (HDC hDC); +BOOL WINAPI wglIsEnabledGenlockI3D (HDC hDC, BOOL *pFlag); +BOOL WINAPI wglGenlockSourceI3D (HDC hDC, UINT uSource); +BOOL WINAPI wglGetGenlockSourceI3D (HDC hDC, UINT *uSource); +BOOL WINAPI wglGenlockSourceEdgeI3D (HDC hDC, UINT uEdge); +BOOL WINAPI wglGetGenlockSourceEdgeI3D (HDC hDC, UINT *uEdge); +BOOL WINAPI wglGenlockSampleRateI3D (HDC hDC, UINT uRate); +BOOL WINAPI wglGetGenlockSampleRateI3D (HDC hDC, UINT *uRate); +BOOL WINAPI wglGenlockSourceDelayI3D (HDC hDC, UINT uDelay); +BOOL WINAPI wglGetGenlockSourceDelayI3D (HDC hDC, UINT *uDelay); +BOOL WINAPI wglQueryGenlockMaxSourceDelayI3D (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay); +#endif +#endif /* WGL_I3D_genlock */ + +#ifndef WGL_I3D_image_buffer +#define WGL_I3D_image_buffer 1 +#define WGL_IMAGE_BUFFER_MIN_ACCESS_I3D 0x00000001 +#define WGL_IMAGE_BUFFER_LOCK_I3D 0x00000002 +typedef LPVOID (WINAPI * PFNWGLCREATEIMAGEBUFFERI3DPROC) (HDC hDC, DWORD dwSize, UINT uFlags); +typedef BOOL (WINAPI * PFNWGLDESTROYIMAGEBUFFERI3DPROC) (HDC hDC, LPVOID pAddress); +typedef BOOL (WINAPI * PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count); +typedef BOOL (WINAPI * PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const LPVOID *pAddress, UINT count); +#ifdef WGL_WGLEXT_PROTOTYPES +LPVOID WINAPI wglCreateImageBufferI3D (HDC hDC, DWORD dwSize, UINT uFlags); +BOOL WINAPI wglDestroyImageBufferI3D (HDC hDC, LPVOID pAddress); +BOOL WINAPI wglAssociateImageBufferEventsI3D (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count); +BOOL WINAPI wglReleaseImageBufferEventsI3D (HDC hDC, const LPVOID *pAddress, UINT count); +#endif +#endif /* WGL_I3D_image_buffer */ + +#ifndef WGL_I3D_swap_frame_lock +#define WGL_I3D_swap_frame_lock 1 +typedef BOOL (WINAPI * PFNWGLENABLEFRAMELOCKI3DPROC) (void); +typedef BOOL (WINAPI * PFNWGLDISABLEFRAMELOCKI3DPROC) (void); +typedef BOOL (WINAPI * PFNWGLISENABLEDFRAMELOCKI3DPROC) (BOOL *pFlag); +typedef BOOL (WINAPI * PFNWGLQUERYFRAMELOCKMASTERI3DPROC) (BOOL *pFlag); +#ifdef WGL_WGLEXT_PROTOTYPES +BOOL WINAPI wglEnableFrameLockI3D (void); +BOOL WINAPI wglDisableFrameLockI3D (void); +BOOL WINAPI wglIsEnabledFrameLockI3D (BOOL *pFlag); +BOOL WINAPI wglQueryFrameLockMasterI3D (BOOL *pFlag); +#endif +#endif /* WGL_I3D_swap_frame_lock */ + +#ifndef WGL_I3D_swap_frame_usage +#define WGL_I3D_swap_frame_usage 1 +typedef BOOL (WINAPI * PFNWGLGETFRAMEUSAGEI3DPROC) (float *pUsage); +typedef BOOL (WINAPI * PFNWGLBEGINFRAMETRACKINGI3DPROC) (void); +typedef BOOL (WINAPI * PFNWGLENDFRAMETRACKINGI3DPROC) (void); +typedef BOOL (WINAPI * PFNWGLQUERYFRAMETRACKINGI3DPROC) (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage); +#ifdef WGL_WGLEXT_PROTOTYPES +BOOL WINAPI wglGetFrameUsageI3D (float *pUsage); +BOOL WINAPI wglBeginFrameTrackingI3D (void); +BOOL WINAPI wglEndFrameTrackingI3D (void); +BOOL WINAPI wglQueryFrameTrackingI3D (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage); +#endif +#endif /* WGL_I3D_swap_frame_usage */ + +#ifndef WGL_NV_DX_interop +#define WGL_NV_DX_interop 1 +#define WGL_ACCESS_READ_ONLY_NV 0x00000000 +#define WGL_ACCESS_READ_WRITE_NV 0x00000001 +#define WGL_ACCESS_WRITE_DISCARD_NV 0x00000002 +typedef BOOL (WINAPI * PFNWGLDXSETRESOURCESHAREHANDLENVPROC) (void *dxObject, HANDLE shareHandle); +typedef HANDLE (WINAPI * PFNWGLDXOPENDEVICENVPROC) (void *dxDevice); +typedef BOOL (WINAPI * PFNWGLDXCLOSEDEVICENVPROC) (HANDLE hDevice); +typedef HANDLE (WINAPI * PFNWGLDXREGISTEROBJECTNVPROC) (HANDLE hDevice, void *dxObject, GLuint name, GLenum type, GLenum access); +typedef BOOL (WINAPI * PFNWGLDXUNREGISTEROBJECTNVPROC) (HANDLE hDevice, HANDLE hObject); +typedef BOOL (WINAPI * PFNWGLDXOBJECTACCESSNVPROC) (HANDLE hObject, GLenum access); +typedef BOOL (WINAPI * PFNWGLDXLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE *hObjects); +typedef BOOL (WINAPI * PFNWGLDXUNLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE *hObjects); +#ifdef WGL_WGLEXT_PROTOTYPES +BOOL WINAPI wglDXSetResourceShareHandleNV (void *dxObject, HANDLE shareHandle); +HANDLE WINAPI wglDXOpenDeviceNV (void *dxDevice); +BOOL WINAPI wglDXCloseDeviceNV (HANDLE hDevice); +HANDLE WINAPI wglDXRegisterObjectNV (HANDLE hDevice, void *dxObject, GLuint name, GLenum type, GLenum access); +BOOL WINAPI wglDXUnregisterObjectNV (HANDLE hDevice, HANDLE hObject); +BOOL WINAPI wglDXObjectAccessNV (HANDLE hObject, GLenum access); +BOOL WINAPI wglDXLockObjectsNV (HANDLE hDevice, GLint count, HANDLE *hObjects); +BOOL WINAPI wglDXUnlockObjectsNV (HANDLE hDevice, GLint count, HANDLE *hObjects); +#endif +#endif /* WGL_NV_DX_interop */ + +#ifndef WGL_NV_DX_interop2 +#define WGL_NV_DX_interop2 1 +#endif /* WGL_NV_DX_interop2 */ + +#ifndef WGL_NV_copy_image +#define WGL_NV_copy_image 1 +typedef BOOL (WINAPI * PFNWGLCOPYIMAGESUBDATANVPROC) (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); +#ifdef WGL_WGLEXT_PROTOTYPES +BOOL WINAPI wglCopyImageSubDataNV (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); +#endif +#endif /* WGL_NV_copy_image */ + +#ifndef WGL_NV_delay_before_swap +#define WGL_NV_delay_before_swap 1 +typedef BOOL (WINAPI * PFNWGLDELAYBEFORESWAPNVPROC) (HDC hDC, GLfloat seconds); +#ifdef WGL_WGLEXT_PROTOTYPES +BOOL WINAPI wglDelayBeforeSwapNV (HDC hDC, GLfloat seconds); +#endif +#endif /* WGL_NV_delay_before_swap */ + +#ifndef WGL_NV_float_buffer +#define WGL_NV_float_buffer 1 +#define WGL_FLOAT_COMPONENTS_NV 0x20B0 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV 0x20B1 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV 0x20B2 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV 0x20B3 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV 0x20B4 +#define WGL_TEXTURE_FLOAT_R_NV 0x20B5 +#define WGL_TEXTURE_FLOAT_RG_NV 0x20B6 +#define WGL_TEXTURE_FLOAT_RGB_NV 0x20B7 +#define WGL_TEXTURE_FLOAT_RGBA_NV 0x20B8 +#endif /* WGL_NV_float_buffer */ + +#ifndef WGL_NV_gpu_affinity +#define WGL_NV_gpu_affinity 1 +DECLARE_HANDLE(HGPUNV); +struct _GPU_DEVICE { + DWORD cb; + CHAR DeviceName[32]; + CHAR DeviceString[128]; + DWORD Flags; + RECT rcVirtualScreen; +}; +typedef struct _GPU_DEVICE *PGPU_DEVICE; +#define ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV 0x20D0 +#define ERROR_MISSING_AFFINITY_MASK_NV 0x20D1 +typedef BOOL (WINAPI * PFNWGLENUMGPUSNVPROC) (UINT iGpuIndex, HGPUNV *phGpu); +typedef BOOL (WINAPI * PFNWGLENUMGPUDEVICESNVPROC) (HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice); +typedef HDC (WINAPI * PFNWGLCREATEAFFINITYDCNVPROC) (const HGPUNV *phGpuList); +typedef BOOL (WINAPI * PFNWGLENUMGPUSFROMAFFINITYDCNVPROC) (HDC hAffinityDC, UINT iGpuIndex, HGPUNV *hGpu); +typedef BOOL (WINAPI * PFNWGLDELETEDCNVPROC) (HDC hdc); +#ifdef WGL_WGLEXT_PROTOTYPES +BOOL WINAPI wglEnumGpusNV (UINT iGpuIndex, HGPUNV *phGpu); +BOOL WINAPI wglEnumGpuDevicesNV (HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice); +HDC WINAPI wglCreateAffinityDCNV (const HGPUNV *phGpuList); +BOOL WINAPI wglEnumGpusFromAffinityDCNV (HDC hAffinityDC, UINT iGpuIndex, HGPUNV *hGpu); +BOOL WINAPI wglDeleteDCNV (HDC hdc); +#endif +#endif /* WGL_NV_gpu_affinity */ + +#ifndef WGL_NV_multisample_coverage +#define WGL_NV_multisample_coverage 1 +#define WGL_COVERAGE_SAMPLES_NV 0x2042 +#define WGL_COLOR_SAMPLES_NV 0x20B9 +#endif /* WGL_NV_multisample_coverage */ + +#ifndef WGL_NV_present_video +#define WGL_NV_present_video 1 +DECLARE_HANDLE(HVIDEOOUTPUTDEVICENV); +#define WGL_NUM_VIDEO_SLOTS_NV 0x20F0 +typedef int (WINAPI * PFNWGLENUMERATEVIDEODEVICESNVPROC) (HDC hDC, HVIDEOOUTPUTDEVICENV *phDeviceList); +typedef BOOL (WINAPI * PFNWGLBINDVIDEODEVICENVPROC) (HDC hDC, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int *piAttribList); +typedef BOOL (WINAPI * PFNWGLQUERYCURRENTCONTEXTNVPROC) (int iAttribute, int *piValue); +#ifdef WGL_WGLEXT_PROTOTYPES +int WINAPI wglEnumerateVideoDevicesNV (HDC hDC, HVIDEOOUTPUTDEVICENV *phDeviceList); +BOOL WINAPI wglBindVideoDeviceNV (HDC hDC, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int *piAttribList); +BOOL WINAPI wglQueryCurrentContextNV (int iAttribute, int *piValue); +#endif +#endif /* WGL_NV_present_video */ + +#ifndef WGL_NV_render_depth_texture +#define WGL_NV_render_depth_texture 1 +#define WGL_BIND_TO_TEXTURE_DEPTH_NV 0x20A3 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV 0x20A4 +#define WGL_DEPTH_TEXTURE_FORMAT_NV 0x20A5 +#define WGL_TEXTURE_DEPTH_COMPONENT_NV 0x20A6 +#define WGL_DEPTH_COMPONENT_NV 0x20A7 +#endif /* WGL_NV_render_depth_texture */ + +#ifndef WGL_NV_render_texture_rectangle +#define WGL_NV_render_texture_rectangle 1 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1 +#define WGL_TEXTURE_RECTANGLE_NV 0x20A2 +#endif /* WGL_NV_render_texture_rectangle */ + +#ifndef WGL_NV_swap_group +#define WGL_NV_swap_group 1 +typedef BOOL (WINAPI * PFNWGLJOINSWAPGROUPNVPROC) (HDC hDC, GLuint group); +typedef BOOL (WINAPI * PFNWGLBINDSWAPBARRIERNVPROC) (GLuint group, GLuint barrier); +typedef BOOL (WINAPI * PFNWGLQUERYSWAPGROUPNVPROC) (HDC hDC, GLuint *group, GLuint *barrier); +typedef BOOL (WINAPI * PFNWGLQUERYMAXSWAPGROUPSNVPROC) (HDC hDC, GLuint *maxGroups, GLuint *maxBarriers); +typedef BOOL (WINAPI * PFNWGLQUERYFRAMECOUNTNVPROC) (HDC hDC, GLuint *count); +typedef BOOL (WINAPI * PFNWGLRESETFRAMECOUNTNVPROC) (HDC hDC); +#ifdef WGL_WGLEXT_PROTOTYPES +BOOL WINAPI wglJoinSwapGroupNV (HDC hDC, GLuint group); +BOOL WINAPI wglBindSwapBarrierNV (GLuint group, GLuint barrier); +BOOL WINAPI wglQuerySwapGroupNV (HDC hDC, GLuint *group, GLuint *barrier); +BOOL WINAPI wglQueryMaxSwapGroupsNV (HDC hDC, GLuint *maxGroups, GLuint *maxBarriers); +BOOL WINAPI wglQueryFrameCountNV (HDC hDC, GLuint *count); +BOOL WINAPI wglResetFrameCountNV (HDC hDC); +#endif +#endif /* WGL_NV_swap_group */ + +#ifndef WGL_NV_vertex_array_range +#define WGL_NV_vertex_array_range 1 +typedef void *(WINAPI * PFNWGLALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority); +typedef void (WINAPI * PFNWGLFREEMEMORYNVPROC) (void *pointer); +#ifdef WGL_WGLEXT_PROTOTYPES +void *WINAPI wglAllocateMemoryNV (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority); +void WINAPI wglFreeMemoryNV (void *pointer); +#endif +#endif /* WGL_NV_vertex_array_range */ + +#ifndef WGL_NV_video_capture +#define WGL_NV_video_capture 1 +DECLARE_HANDLE(HVIDEOINPUTDEVICENV); +#define WGL_UNIQUE_ID_NV 0x20CE +#define WGL_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF +typedef BOOL (WINAPI * PFNWGLBINDVIDEOCAPTUREDEVICENVPROC) (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice); +typedef UINT (WINAPI * PFNWGLENUMERATEVIDEOCAPTUREDEVICESNVPROC) (HDC hDc, HVIDEOINPUTDEVICENV *phDeviceList); +typedef BOOL (WINAPI * PFNWGLLOCKVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice); +typedef BOOL (WINAPI * PFNWGLQUERYVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int *piValue); +typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice); +#ifdef WGL_WGLEXT_PROTOTYPES +BOOL WINAPI wglBindVideoCaptureDeviceNV (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice); +UINT WINAPI wglEnumerateVideoCaptureDevicesNV (HDC hDc, HVIDEOINPUTDEVICENV *phDeviceList); +BOOL WINAPI wglLockVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice); +BOOL WINAPI wglQueryVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int *piValue); +BOOL WINAPI wglReleaseVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice); +#endif +#endif /* WGL_NV_video_capture */ + +#ifndef WGL_NV_video_output +#define WGL_NV_video_output 1 +DECLARE_HANDLE(HPVIDEODEV); +#define WGL_BIND_TO_VIDEO_RGB_NV 0x20C0 +#define WGL_BIND_TO_VIDEO_RGBA_NV 0x20C1 +#define WGL_BIND_TO_VIDEO_RGB_AND_DEPTH_NV 0x20C2 +#define WGL_VIDEO_OUT_COLOR_NV 0x20C3 +#define WGL_VIDEO_OUT_ALPHA_NV 0x20C4 +#define WGL_VIDEO_OUT_DEPTH_NV 0x20C5 +#define WGL_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6 +#define WGL_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7 +#define WGL_VIDEO_OUT_FRAME 0x20C8 +#define WGL_VIDEO_OUT_FIELD_1 0x20C9 +#define WGL_VIDEO_OUT_FIELD_2 0x20CA +#define WGL_VIDEO_OUT_STACKED_FIELDS_1_2 0x20CB +#define WGL_VIDEO_OUT_STACKED_FIELDS_2_1 0x20CC +typedef BOOL (WINAPI * PFNWGLGETVIDEODEVICENVPROC) (HDC hDC, int numDevices, HPVIDEODEV *hVideoDevice); +typedef BOOL (WINAPI * PFNWGLRELEASEVIDEODEVICENVPROC) (HPVIDEODEV hVideoDevice); +typedef BOOL (WINAPI * PFNWGLBINDVIDEOIMAGENVPROC) (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer); +typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOIMAGENVPROC) (HPBUFFERARB hPbuffer, int iVideoBuffer); +typedef BOOL (WINAPI * PFNWGLSENDPBUFFERTOVIDEONVPROC) (HPBUFFERARB hPbuffer, int iBufferType, unsigned long *pulCounterPbuffer, BOOL bBlock); +typedef BOOL (WINAPI * PFNWGLGETVIDEOINFONVPROC) (HPVIDEODEV hpVideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo); +#ifdef WGL_WGLEXT_PROTOTYPES +BOOL WINAPI wglGetVideoDeviceNV (HDC hDC, int numDevices, HPVIDEODEV *hVideoDevice); +BOOL WINAPI wglReleaseVideoDeviceNV (HPVIDEODEV hVideoDevice); +BOOL WINAPI wglBindVideoImageNV (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer); +BOOL WINAPI wglReleaseVideoImageNV (HPBUFFERARB hPbuffer, int iVideoBuffer); +BOOL WINAPI wglSendPbufferToVideoNV (HPBUFFERARB hPbuffer, int iBufferType, unsigned long *pulCounterPbuffer, BOOL bBlock); +BOOL WINAPI wglGetVideoInfoNV (HPVIDEODEV hpVideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo); +#endif +#endif /* WGL_NV_video_output */ + +#ifndef WGL_OML_sync_control +#define WGL_OML_sync_control 1 +typedef BOOL (WINAPI * PFNWGLGETSYNCVALUESOMLPROC) (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc); +typedef BOOL (WINAPI * PFNWGLGETMSCRATEOMLPROC) (HDC hdc, INT32 *numerator, INT32 *denominator); +typedef INT64 (WINAPI * PFNWGLSWAPBUFFERSMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder); +typedef INT64 (WINAPI * PFNWGLSWAPLAYERBUFFERSMSCOMLPROC) (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder); +typedef BOOL (WINAPI * PFNWGLWAITFORMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc); +typedef BOOL (WINAPI * PFNWGLWAITFORSBCOMLPROC) (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc); +#ifdef WGL_WGLEXT_PROTOTYPES +BOOL WINAPI wglGetSyncValuesOML (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc); +BOOL WINAPI wglGetMscRateOML (HDC hdc, INT32 *numerator, INT32 *denominator); +INT64 WINAPI wglSwapBuffersMscOML (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder); +INT64 WINAPI wglSwapLayerBuffersMscOML (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder); +BOOL WINAPI wglWaitForMscOML (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc); +BOOL WINAPI wglWaitForSbcOML (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc); +#endif +#endif /* WGL_OML_sync_control */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/testbed/glfw/deps/KHR/khrplatform.h b/testbed/glfw/deps/KHR/khrplatform.h new file mode 100644 index 00000000..c9e6f17d --- /dev/null +++ b/testbed/glfw/deps/KHR/khrplatform.h @@ -0,0 +1,282 @@ +#ifndef __khrplatform_h_ +#define __khrplatform_h_ + +/* +** Copyright (c) 2008-2009 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE 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 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +/* Khronos platform-specific types and definitions. + * + * $Revision: 23298 $ on $Date: 2013-09-30 17:07:13 -0700 (Mon, 30 Sep 2013) $ + * + * Adopters may modify this file to suit their platform. Adopters are + * encouraged to submit platform specific modifications to the Khronos + * group so that they can be included in future versions of this file. + * Please submit changes by sending them to the public Khronos Bugzilla + * (http://khronos.org/bugzilla) by filing a bug against product + * "Khronos (general)" component "Registry". + * + * A predefined template which fills in some of the bug fields can be + * reached using http://tinyurl.com/khrplatform-h-bugreport, but you + * must create a Bugzilla login first. + * + * + * See the Implementer's Guidelines for information about where this file + * should be located on your system and for more details of its use: + * http://www.khronos.org/registry/implementers_guide.pdf + * + * This file should be included as + * #include + * by Khronos client API header files that use its types and defines. + * + * The types in khrplatform.h should only be used to define API-specific types. + * + * Types defined in khrplatform.h: + * khronos_int8_t signed 8 bit + * khronos_uint8_t unsigned 8 bit + * khronos_int16_t signed 16 bit + * khronos_uint16_t unsigned 16 bit + * khronos_int32_t signed 32 bit + * khronos_uint32_t unsigned 32 bit + * khronos_int64_t signed 64 bit + * khronos_uint64_t unsigned 64 bit + * khronos_intptr_t signed same number of bits as a pointer + * khronos_uintptr_t unsigned same number of bits as a pointer + * khronos_ssize_t signed size + * khronos_usize_t unsigned size + * khronos_float_t signed 32 bit floating point + * khronos_time_ns_t unsigned 64 bit time in nanoseconds + * khronos_utime_nanoseconds_t unsigned time interval or absolute time in + * nanoseconds + * khronos_stime_nanoseconds_t signed time interval in nanoseconds + * khronos_boolean_enum_t enumerated boolean type. This should + * only be used as a base type when a client API's boolean type is + * an enum. Client APIs which use an integer or other type for + * booleans cannot use this as the base type for their boolean. + * + * Tokens defined in khrplatform.h: + * + * KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values. + * + * KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0. + * KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0. + * + * Calling convention macros defined in this file: + * KHRONOS_APICALL + * KHRONOS_APIENTRY + * KHRONOS_APIATTRIBUTES + * + * These may be used in function prototypes as: + * + * KHRONOS_APICALL void KHRONOS_APIENTRY funcname( + * int arg1, + * int arg2) KHRONOS_APIATTRIBUTES; + */ + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APICALL + *------------------------------------------------------------------------- + * This precedes the return type of the function in the function prototype. + */ +#if defined(_WIN32) && !defined(__SCITECH_SNAP__) +# define KHRONOS_APICALL __declspec(dllimport) +#elif defined (__SYMBIAN32__) +# define KHRONOS_APICALL IMPORT_C +#else +# define KHRONOS_APICALL +#endif + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APIENTRY + *------------------------------------------------------------------------- + * This follows the return type of the function and precedes the function + * name in the function prototype. + */ +#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__) + /* Win32 but not WinCE */ +# define KHRONOS_APIENTRY __stdcall +#else +# define KHRONOS_APIENTRY +#endif + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APIATTRIBUTES + *------------------------------------------------------------------------- + * This follows the closing parenthesis of the function prototype arguments. + */ +#if defined (__ARMCC_2__) +#define KHRONOS_APIATTRIBUTES __softfp +#else +#define KHRONOS_APIATTRIBUTES +#endif + +/*------------------------------------------------------------------------- + * basic type definitions + *-----------------------------------------------------------------------*/ +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__) + + +/* + * Using + */ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(__VMS ) || defined(__sgi) + +/* + * Using + */ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(_WIN32) && !defined(__SCITECH_SNAP__) + +/* + * Win32 + */ +typedef __int32 khronos_int32_t; +typedef unsigned __int32 khronos_uint32_t; +typedef __int64 khronos_int64_t; +typedef unsigned __int64 khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(__sun__) || defined(__digital__) + +/* + * Sun or Digital + */ +typedef int khronos_int32_t; +typedef unsigned int khronos_uint32_t; +#if defined(__arch64__) || defined(_LP64) +typedef long int khronos_int64_t; +typedef unsigned long int khronos_uint64_t; +#else +typedef long long int khronos_int64_t; +typedef unsigned long long int khronos_uint64_t; +#endif /* __arch64__ */ +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif 0 + +/* + * Hypothetical platform with no float or int64 support + */ +typedef int khronos_int32_t; +typedef unsigned int khronos_uint32_t; +#define KHRONOS_SUPPORT_INT64 0 +#define KHRONOS_SUPPORT_FLOAT 0 + +#else + +/* + * Generic fallback + */ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#endif + + +/* + * Types that are (so far) the same on all platforms + */ +typedef signed char khronos_int8_t; +typedef unsigned char khronos_uint8_t; +typedef signed short int khronos_int16_t; +typedef unsigned short int khronos_uint16_t; + +/* + * Types that differ between LLP64 and LP64 architectures - in LLP64, + * pointers are 64 bits, but 'long' is still 32 bits. Win64 appears + * to be the only LLP64 architecture in current use. + */ +#ifdef _WIN64 +typedef signed long long int khronos_intptr_t; +typedef unsigned long long int khronos_uintptr_t; +typedef signed long long int khronos_ssize_t; +typedef unsigned long long int khronos_usize_t; +#else +typedef signed long int khronos_intptr_t; +typedef unsigned long int khronos_uintptr_t; +typedef signed long int khronos_ssize_t; +typedef unsigned long int khronos_usize_t; +#endif + +#if KHRONOS_SUPPORT_FLOAT +/* + * Float type + */ +typedef float khronos_float_t; +#endif + +#if KHRONOS_SUPPORT_INT64 +/* Time types + * + * These types can be used to represent a time interval in nanoseconds or + * an absolute Unadjusted System Time. Unadjusted System Time is the number + * of nanoseconds since some arbitrary system event (e.g. since the last + * time the system booted). The Unadjusted System Time is an unsigned + * 64 bit value that wraps back to 0 every 584 years. Time intervals + * may be either signed or unsigned. + */ +typedef khronos_uint64_t khronos_utime_nanoseconds_t; +typedef khronos_int64_t khronos_stime_nanoseconds_t; +#endif + +/* + * Dummy value used to pad enum types to 32 bits. + */ +#ifndef KHRONOS_MAX_ENUM +#define KHRONOS_MAX_ENUM 0x7FFFFFFF +#endif + +/* + * Enumerated boolean type + * + * Values other than zero should be considered to be true. Therefore + * comparisons should not be made against KHRONOS_TRUE. + */ +typedef enum { + KHRONOS_FALSE = 0, + KHRONOS_TRUE = 1, + KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM +} khronos_boolean_enum_t; + +#endif /* __khrplatform_h_ */ diff --git a/testbed/glfw/deps/getopt.c b/testbed/glfw/deps/getopt.c new file mode 100644 index 00000000..9743046f --- /dev/null +++ b/testbed/glfw/deps/getopt.c @@ -0,0 +1,230 @@ +/* Copyright (c) 2012, Kim Gräsman + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of Kim Gräsman nor the names of contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL KIM GRÄSMAN BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "getopt.h" + +#include +#include + +const int no_argument = 0; +const int required_argument = 1; +const int optional_argument = 2; + +char* optarg; +int optopt; +/* The variable optind [...] shall be initialized to 1 by the system. */ +int optind = 1; +int opterr; + +static char* optcursor = NULL; + +/* Implemented based on [1] and [2] for optional arguments. + optopt is handled FreeBSD-style, per [3]. + Other GNU and FreeBSD extensions are purely accidental. + +[1] http://pubs.opengroup.org/onlinepubs/000095399/functions/getopt.html +[2] http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html +[3] http://www.freebsd.org/cgi/man.cgi?query=getopt&sektion=3&manpath=FreeBSD+9.0-RELEASE +*/ +int getopt(int argc, char* const argv[], const char* optstring) { + int optchar = -1; + const char* optdecl = NULL; + + optarg = NULL; + opterr = 0; + optopt = 0; + + /* Unspecified, but we need it to avoid overrunning the argv bounds. */ + if (optind >= argc) + goto no_more_optchars; + + /* If, when getopt() is called argv[optind] is a null pointer, getopt() + shall return -1 without changing optind. */ + if (argv[optind] == NULL) + goto no_more_optchars; + + /* If, when getopt() is called *argv[optind] is not the character '-', + getopt() shall return -1 without changing optind. */ + if (*argv[optind] != '-') + goto no_more_optchars; + + /* If, when getopt() is called argv[optind] points to the string "-", + getopt() shall return -1 without changing optind. */ + if (strcmp(argv[optind], "-") == 0) + goto no_more_optchars; + + /* If, when getopt() is called argv[optind] points to the string "--", + getopt() shall return -1 after incrementing optind. */ + if (strcmp(argv[optind], "--") == 0) { + ++optind; + goto no_more_optchars; + } + + if (optcursor == NULL || *optcursor == '\0') + optcursor = argv[optind] + 1; + + optchar = *optcursor; + + /* FreeBSD: The variable optopt saves the last known option character + returned by getopt(). */ + optopt = optchar; + + /* The getopt() function shall return the next option character (if one is + found) from argv that matches a character in optstring, if there is + one that matches. */ + optdecl = strchr(optstring, optchar); + if (optdecl) { + /* [I]f a character is followed by a colon, the option takes an + argument. */ + if (optdecl[1] == ':') { + optarg = ++optcursor; + if (*optarg == '\0') { + /* GNU extension: Two colons mean an option takes an + optional arg; if there is text in the current argv-element + (i.e., in the same word as the option name itself, for example, + "-oarg"), then it is returned in optarg, otherwise optarg is set + to zero. */ + if (optdecl[2] != ':') { + /* If the option was the last character in the string pointed to by + an element of argv, then optarg shall contain the next element + of argv, and optind shall be incremented by 2. If the resulting + value of optind is greater than argc, this indicates a missing + option-argument, and getopt() shall return an error indication. + + Otherwise, optarg shall point to the string following the + option character in that element of argv, and optind shall be + incremented by 1. + */ + if (++optind < argc) { + optarg = argv[optind]; + } else { + /* If it detects a missing option-argument, it shall return the + colon character ( ':' ) if the first character of optstring + was a colon, or a question-mark character ( '?' ) otherwise. + */ + optarg = NULL; + optchar = (optstring[0] == ':') ? ':' : '?'; + } + } else { + optarg = NULL; + } + } + + optcursor = NULL; + } + } else { + /* If getopt() encounters an option character that is not contained in + optstring, it shall return the question-mark ( '?' ) character. */ + optchar = '?'; + } + + if (optcursor == NULL || *++optcursor == '\0') + ++optind; + + return optchar; + +no_more_optchars: + optcursor = NULL; + return -1; +} + +/* Implementation based on [1]. + +[1] http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html +*/ +int getopt_long(int argc, char* const argv[], const char* optstring, + const struct option* longopts, int* longindex) { + const struct option* o = longopts; + const struct option* match = NULL; + int num_matches = 0; + size_t argument_name_length = 0; + const char* current_argument = NULL; + int retval = -1; + + optarg = NULL; + optopt = 0; + + if (optind >= argc) + return -1; + + if (strlen(argv[optind]) < 3 || strncmp(argv[optind], "--", 2) != 0) + return getopt(argc, argv, optstring); + + /* It's an option; starts with -- and is longer than two chars. */ + current_argument = argv[optind] + 2; + argument_name_length = strcspn(current_argument, "="); + for (; o->name; ++o) { + if (strncmp(o->name, current_argument, argument_name_length) == 0) { + match = o; + ++num_matches; + } + } + + if (num_matches == 1) { + /* If longindex is not NULL, it points to a variable which is set to the + index of the long option relative to longopts. */ + if (longindex) + *longindex = (int) (match - longopts); + + /* If flag is NULL, then getopt_long() shall return val. + Otherwise, getopt_long() returns 0, and flag shall point to a variable + which shall be set to val if the option is found, but left unchanged if + the option is not found. */ + if (match->flag) + *(match->flag) = match->val; + + retval = match->flag ? 0 : match->val; + + if (match->has_arg != no_argument) { + optarg = strchr(argv[optind], '='); + if (optarg != NULL) + ++optarg; + + if (match->has_arg == required_argument) { + /* Only scan the next argv for required arguments. Behavior is not + specified, but has been observed with Ubuntu and Mac OSX. */ + if (optarg == NULL && ++optind < argc) { + optarg = argv[optind]; + } + + if (optarg == NULL) + retval = ':'; + } + } else if (strchr(argv[optind], '=')) { + /* An argument was provided to a non-argument option. + I haven't seen this specified explicitly, but both GNU and BSD-based + implementations show this behavior. + */ + retval = '?'; + } + } else { + /* Unknown option or ambiguous match. */ + retval = '?'; + } + + ++optind; + return retval; +} diff --git a/testbed/glfw/deps/getopt.h b/testbed/glfw/deps/getopt.h new file mode 100644 index 00000000..e1eb540f --- /dev/null +++ b/testbed/glfw/deps/getopt.h @@ -0,0 +1,57 @@ +/* Copyright (c) 2012, Kim Gräsman + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of Kim Gräsman nor the names of contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL KIM GRÄSMAN BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef INCLUDED_GETOPT_PORT_H +#define INCLUDED_GETOPT_PORT_H + +#if defined(__cplusplus) +extern "C" { +#endif + +extern const int no_argument; +extern const int required_argument; +extern const int optional_argument; + +extern char* optarg; +extern int optind, opterr, optopt; + +struct option { + const char* name; + int has_arg; + int* flag; + int val; +}; + +int getopt(int argc, char* const argv[], const char* optstring); + +int getopt_long(int argc, char* const argv[], + const char* optstring, const struct option* longopts, int* longindex); + +#if defined(__cplusplus) +} +#endif + +#endif // INCLUDED_GETOPT_PORT_H diff --git a/testbed/glfw/deps/glad.c b/testbed/glfw/deps/glad.c new file mode 100644 index 00000000..da75d08d --- /dev/null +++ b/testbed/glfw/deps/glad.c @@ -0,0 +1,728 @@ +#include +#include + +struct gladGLversionStruct GLVersion; + +#if defined(GL_ES_VERSION_3_0) || defined(GL_VERSION_3_0) +#define _GLAD_IS_SOME_NEW_VERSION 1 +#endif + +int GLAD_GL_VERSION_1_0; +int GLAD_GL_VERSION_1_1; +int GLAD_GL_VERSION_1_2; +int GLAD_GL_VERSION_1_3; +int GLAD_GL_VERSION_1_4; +int GLAD_GL_VERSION_1_5; +int GLAD_GL_VERSION_2_0; +int GLAD_GL_VERSION_2_1; +int GLAD_GL_VERSION_3_0; +int GLAD_GL_VERSION_3_1; +int GLAD_GL_VERSION_3_2; +PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays; +PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback; +PFNGLFLUSHPROC glad_glFlush; +PFNGLCOPYTEXIMAGE1DPROC glad_glCopyTexImage1D; +PFNGLCLEARCOLORPROC glad_glClearColor; +PFNGLVERTEXATTRIBI3UIPROC glad_glVertexAttribI3ui; +PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex; +PFNGLVERTEXATTRIB4NIVPROC glad_glVertexAttrib4Niv; +PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv; +PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate; +PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv; +PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv; +PFNGLBINDFRAGDATALOCATIONPROC glad_glBindFragDataLocation; +PFNGLLINKPROGRAMPROC glad_glLinkProgram; +PFNGLBINDTEXTUREPROC glad_glBindTexture; +PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName; +PFNGLVERTEXATTRIBI2UIVPROC glad_glVertexAttribI2uiv; +PFNGLFENCESYNCPROC glad_glFenceSync; +PFNGLUNIFORM3UIPROC glad_glUniform3ui; +PFNGLUNIFORM2UIVPROC glad_glUniform2uiv; +PFNGLGETSTRINGPROC glad_glGetString; +PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D; +PFNGLDETACHSHADERPROC glad_glDetachShader; +PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv; +PFNGLGENBUFFERSPROC glad_glGenBuffers; +PFNGLENDQUERYPROC glad_glEndQuery; +PFNGLPOINTPARAMETERFVPROC glad_glPointParameterfv; +PFNGLLINEWIDTHPROC glad_glLineWidth; +PFNGLUNIFORM2FVPROC glad_glUniform2fv; +PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced; +PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v; +PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation; +PFNGLCOMPILESHADERPROC glad_glCompileShader; +PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying; +PFNGLDELETETEXTURESPROC glad_glDeleteTextures; +PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate; +PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv; +PFNGLPOLYGONMODEPROC glad_glPolygonMode; +PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange; +PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f; +PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers; +PFNGLVERTEXATTRIB4DPROC glad_glVertexAttrib4d; +PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f; +PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v; +PFNGLISSYNCPROC glad_glIsSync; +PFNGLCLAMPCOLORPROC glad_glClampColor; +PFNGLUNIFORM4IVPROC glad_glUniform4iv; +PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv; +PFNGLCLEARSTENCILPROC glad_glClearStencil; +PFNGLFRAMEBUFFERTEXTUREPROC glad_glFramebufferTexture; +PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv; +PFNGLVERTEXATTRIB4SPROC glad_glVertexAttrib4s; +PFNGLDRAWELEMENTSBASEVERTEXPROC glad_glDrawElementsBaseVertex; +PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv; +PFNGLENABLEIPROC glad_glEnablei; +PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage; +PFNGLVERTEXATTRIB4NUSVPROC glad_glVertexAttrib4Nusv; +PFNGLGENTEXTURESPROC glad_glGenTextures; +PFNGLDEPTHFUNCPROC glad_glDepthFunc; +PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D; +PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv; +PFNGLUNIFORM1FPROC glad_glUniform1f; +PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv; +PFNGLVERTEXATTRIBI4BVPROC glad_glVertexAttribI4bv; +PFNGLVERTEXATTRIB4NBVPROC glad_glVertexAttrib4Nbv; +PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv; +PFNGLGETCOMPRESSEDTEXIMAGEPROC glad_glGetCompressedTexImage; +PFNGLISVERTEXARRAYPROC glad_glIsVertexArray; +PFNGLCREATESHADERPROC glad_glCreateShader; +PFNGLISBUFFERPROC glad_glIsBuffer; +PFNGLUNIFORM1IPROC glad_glUniform1i; +PFNGLVERTEXATTRIB3SPROC glad_glVertexAttrib3s; +PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib; +PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D; +PFNGLVERTEXATTRIB3DVPROC glad_glVertexAttrib3dv; +PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D; +PFNGLDISABLEPROC glad_glDisable; +PFNGLUNIFORM2IPROC glad_glUniform2i; +PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate; +PFNGLLOGICOPPROC glad_glLogicOp; +PFNGLVERTEXATTRIBI4SVPROC glad_glVertexAttribI4sv; +PFNGLGETPROGRAMIVPROC glad_glGetProgramiv; +PFNGLCOLORMASKPROC glad_glColorMask; +PFNGLHINTPROC glad_glHint; +PFNGLVERTEXATTRIB1SPROC glad_glVertexAttrib1s; +PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer; +PFNGLTEXPARAMETERIIVPROC glad_glTexParameterIiv; +PFNGLBLENDEQUATIONPROC glad_glBlendEquation; +PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation; +PFNGLSAMPLEMASKIPROC glad_glSampleMaski; +PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer; +PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback; +PFNGLCULLFACEPROC glad_glCullFace; +PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv; +PFNGLVERTEXATTRIB4USVPROC glad_glVertexAttrib4usv; +PFNGLUNIFORM4FVPROC glad_glUniform4fv; +PFNGLGETTEXPARAMETERIUIVPROC glad_glGetTexParameterIuiv; +PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers; +PFNGLUNIFORM1UIVPROC glad_glUniform1uiv; +PFNGLPOINTSIZEPROC glad_glPointSize; +PFNGLGETSTRINGIPROC glad_glGetStringi; +PFNGLVERTEXATTRIB2DVPROC glad_glVertexAttrib2dv; +PFNGLVERTEXATTRIBI1IVPROC glad_glVertexAttribI1iv; +PFNGLDELETEPROGRAMPROC glad_glDeleteProgram; +PFNGLVERTEXATTRIB4NUIVPROC glad_glVertexAttrib4Nuiv; +PFNGLGENQUERIESPROC glad_glGenQueries; +PFNGLWAITSYNCPROC glad_glWaitSync; +PFNGLATTACHSHADERPROC glad_glAttachShader; +PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer; +PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage; +PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv; +PFNGLUNIFORM3IPROC glad_glUniform3i; +PFNGLCOMPRESSEDTEXIMAGE1DPROC glad_glCompressedTexImage1D; +PFNGLCOPYTEXSUBIMAGE1DPROC glad_glCopyTexSubImage1D; +PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex; +PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus; +PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D; +PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v; +PFNGLPROVOKINGVERTEXPROC glad_glProvokingVertex; +PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv; +PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D; +PFNGLUNIFORM3FPROC glad_glUniform3f; +PFNGLVERTEXATTRIB4UBVPROC glad_glVertexAttrib4ubv; +PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv; +PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv; +PFNGLENDCONDITIONALRENDERPROC glad_glEndConditionalRender; +PFNGLDRAWELEMENTSPROC glad_glDrawElements; +PFNGLCOLORMASKIPROC glad_glColorMaski; +PFNGLISENABLEDIPROC glad_glIsEnabledi; +PFNGLVERTEXATTRIB1DVPROC glad_glVertexAttrib1dv; +PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements; +PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv; +PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays; +PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase; +PFNGLBUFFERSUBDATAPROC glad_glBufferSubData; +PFNGLUNIFORM1IVPROC glad_glUniform1iv; +PFNGLGETQUERYOBJECTIVPROC glad_glGetQueryObjectiv; +PFNGLUNIFORM4UIVPROC glad_glUniform4uiv; +PFNGLREADBUFFERPROC glad_glReadBuffer; +PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData; +PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray; +PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync; +PFNGLBEGINCONDITIONALRENDERPROC glad_glBeginConditionalRender; +PFNGLVERTEXATTRIB3SVPROC glad_glVertexAttrib3sv; +PFNGLVERTEXATTRIBI2UIPROC glad_glVertexAttribI2ui; +PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap; +PFNGLMULTIDRAWARRAYSPROC glad_glMultiDrawArrays; +PFNGLFRAMEBUFFERTEXTURE1DPROC glad_glFramebufferTexture1D; +PFNGLGETSHADERIVPROC glad_glGetShaderiv; +PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv; +PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv; +PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f; +PFNGLVERTEXATTRIB4UIVPROC glad_glVertexAttrib4uiv; +PFNGLPOINTPARAMETERIPROC glad_glPointParameteri; +PFNGLBLENDCOLORPROC glad_glBlendColor; +PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray; +PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer; +PFNGLDEPTHMASKPROC glad_glDepthMask; +PFNGLPOINTPARAMETERFPROC glad_glPointParameterf; +PFNGLDISABLEIPROC glad_glDisablei; +PFNGLGETDOUBLEVPROC glad_glGetDoublev; +PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv; +PFNGLVERTEXATTRIB1SVPROC glad_glVertexAttrib1sv; +PFNGLSHADERSOURCEPROC glad_glShaderSource; +PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer; +PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D; +PFNGLVERTEXATTRIBI3UIVPROC glad_glVertexAttribI3uiv; +PFNGLVERTEXATTRIBI2IVPROC glad_glVertexAttribI2iv; +PFNGLDRAWARRAYSPROC glad_glDrawArrays; +PFNGLUNIFORM1UIPROC glad_glUniform1ui; +PFNGLISPROGRAMPROC glad_glIsProgram; +PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv; +PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation; +PFNGLGETSYNCIVPROC glad_glGetSynciv; +PFNGLGETUNIFORMIVPROC glad_glGetUniformiv; +PFNGLVERTEXATTRIBI2IPROC glad_glVertexAttribI2i; +PFNGLUNIFORM4IPROC glad_glUniform4i; +PFNGLVERTEXATTRIB3DPROC glad_glVertexAttrib3d; +PFNGLCLEARPROC glad_glClear; +PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv; +PFNGLGETACTIVEUNIFORMNAMEPROC glad_glGetActiveUniformName; +PFNGLUNIFORM2FPROC glad_glUniform2f; +PFNGLTEXIMAGE2DMULTISAMPLEPROC glad_glTexImage2DMultisample; +PFNGLACTIVETEXTUREPROC glad_glActiveTexture; +PFNGLBEGINQUERYPROC glad_glBeginQuery; +PFNGLUNIFORM2IVPROC glad_glUniform2iv; +PFNGLBINDBUFFERPROC glad_glBindBuffer; +PFNGLISENABLEDPROC glad_glIsEnabled; +PFNGLSTENCILOPPROC glad_glStencilOp; +PFNGLREADPIXELSPROC glad_glReadPixels; +PFNGLCLEARDEPTHPROC glad_glClearDepth; +PFNGLVERTEXATTRIBI3IVPROC glad_glVertexAttribI3iv; +PFNGLUNIFORM4FPROC glad_glUniform4f; +PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D; +PFNGLMAPBUFFERPROC glad_glMapBuffer; +PFNGLVERTEXATTRIB1DPROC glad_glVertexAttrib1d; +PFNGLVERTEXATTRIB4NUBPROC glad_glVertexAttrib4Nub; +PFNGLUNIFORM3FVPROC glad_glUniform3fv; +PFNGLGETUNIFORMFVPROC glad_glGetUniformfv; +PFNGLBUFFERDATAPROC glad_glBufferData; +PFNGLGETTEXPARAMETERIIVPROC glad_glGetTexParameterIiv; +PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D; +PFNGLTEXIMAGE1DPROC glad_glTexImage1D; +PFNGLDELETESYNCPROC glad_glDeleteSync; +PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D; +PFNGLGETERRORPROC glad_glGetError; +PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers; +PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv; +PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv; +PFNGLMULTIDRAWELEMENTSPROC glad_glMultiDrawElements; +PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv; +PFNGLGETFLOATVPROC glad_glGetFloatv; +PFNGLTEXSUBIMAGE1DPROC glad_glTexSubImage1D; +PFNGLUNIFORM3IVPROC glad_glUniform3iv; +PFNGLGETTEXIMAGEPROC glad_glGetTexImage; +PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv; +PFNGLUSEPROGRAMPROC glad_glUseProgram; +PFNGLVERTEXATTRIB4IVPROC glad_glVertexAttrib4iv; +PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv; +PFNGLVERTEXATTRIBI1IPROC glad_glVertexAttribI1i; +PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers; +PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer; +PFNGLDRAWBUFFERSPROC glad_glDrawBuffers; +PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv; +PFNGLSTENCILFUNCPROC glad_glStencilFunc; +PFNGLGETINTEGERVPROC glad_glGetIntegerv; +PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders; +PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding; +PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer; +PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv; +PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv; +PFNGLDRAWBUFFERPROC glad_glDrawBuffer; +PFNGLFRAMEBUFFERTEXTURE3DPROC glad_glFramebufferTexture3D; +PFNGLUNIFORM1FVPROC glad_glUniform1fv; +PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample; +PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange; +PFNGLISQUERYPROC glad_glIsQuery; +PFNGLVERTEXATTRIB4NUBVPROC glad_glVertexAttrib4Nubv; +PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv; +PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray; +PFNGLVERTEXATTRIB4SVPROC glad_glVertexAttrib4sv; +PFNGLGETQUERYIVPROC glad_glGetQueryiv; +PFNGLTEXIMAGE2DPROC glad_glTexImage2D; +PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog; +PFNGLSTENCILMASKPROC glad_glStencilMask; +PFNGLUNIFORM4UIPROC glad_glUniform4ui; +PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv; +PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog; +PFNGLISTEXTUREPROC glad_glIsTexture; +PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices; +PFNGLISSHADERPROC glad_glIsShader; +PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource; +PFNGLVERTEXATTRIBI4UBVPROC glad_glVertexAttribI4ubv; +PFNGLVERTEXATTRIB4BVPROC glad_glVertexAttrib4bv; +PFNGLGETINTEGER64VPROC glad_glGetInteger64v; +PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer; +PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv; +PFNGLGETBUFFERSUBDATAPROC glad_glGetBufferSubData; +PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv; +PFNGLTEXPARAMETERIUIVPROC glad_glTexParameterIuiv; +PFNGLENABLEPROC glad_glEnable; +PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv; +PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced; +PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i; +PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate; +PFNGLDELETEQUERIESPROC glad_glDeleteQueries; +PFNGLPOINTPARAMETERIVPROC glad_glPointParameteriv; +PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate; +PFNGLVERTEXATTRIBI1UIPROC glad_glVertexAttribI1ui; +PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glad_glCompressedTexSubImage1D; +PFNGLFINISHPROC glad_glFinish; +PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation; +PFNGLVERTEXATTRIB4DVPROC glad_glVertexAttrib4dv; +PFNGLVERTEXATTRIB2SVPROC glad_glVertexAttrib2sv; +PFNGLDELETESHADERPROC glad_glDeleteShader; +PFNGLBLENDFUNCPROC glad_glBlendFunc; +PFNGLCREATEPROGRAMPROC glad_glCreateProgram; +PFNGLTEXIMAGE3DPROC glad_glTexImage3D; +PFNGLVERTEXATTRIB4NSVPROC glad_glVertexAttrib4Nsv; +PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer; +PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui; +PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange; +PFNGLVIEWPORTPROC glad_glViewport; +PFNGLVERTEXATTRIBI1UIVPROC glad_glVertexAttribI1uiv; +PFNGLVERTEXATTRIB2DPROC glad_glVertexAttrib2d; +PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings; +PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f; +PFNGLGETVERTEXATTRIBDVPROC glad_glGetVertexAttribdv; +PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glad_glMultiDrawElementsBaseVertex; +PFNGLPRIMITIVERESTARTINDEXPROC glad_glPrimitiveRestartIndex; +PFNGLUNIFORM2UIPROC glad_glUniform2ui; +PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset; +PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv; +PFNGLVERTEXATTRIBI3IPROC glad_glVertexAttribI3i; +PFNGLVERTEXATTRIB2SPROC glad_glVertexAttrib2s; +PFNGLTEXIMAGE3DMULTISAMPLEPROC glad_glTexImage3DMultisample; +PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv; +PFNGLDEPTHRANGEPROC glad_glDepthRange; +PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform; +PFNGLVERTEXATTRIBI4USVPROC glad_glVertexAttribI4usv; +PFNGLTEXPARAMETERFPROC glad_glTexParameterf; +PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi; +PFNGLTEXPARAMETERIPROC glad_glTexParameteri; +PFNGLFRONTFACEPROC glad_glFrontFace; +PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers; +PFNGLSCISSORPROC glad_glScissor; +PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex; +PFNGLGETBOOLEANVPROC glad_glGetBooleanv; +PFNGLTEXBUFFERPROC glad_glTexBuffer; +PFNGLPIXELSTOREIPROC glad_glPixelStorei; +PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram; +PFNGLPIXELSTOREFPROC glad_glPixelStoref; +PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv; +PFNGLUNIFORM3UIVPROC glad_glUniform3uiv; +PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v; +PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer; +static void load_GL_VERSION_1_0(GLADloadproc load) { + if(!GLAD_GL_VERSION_1_0) return; + glad_glCullFace = (PFNGLCULLFACEPROC)load("glCullFace"); + glad_glFrontFace = (PFNGLFRONTFACEPROC)load("glFrontFace"); + glad_glHint = (PFNGLHINTPROC)load("glHint"); + glad_glLineWidth = (PFNGLLINEWIDTHPROC)load("glLineWidth"); + glad_glPointSize = (PFNGLPOINTSIZEPROC)load("glPointSize"); + glad_glPolygonMode = (PFNGLPOLYGONMODEPROC)load("glPolygonMode"); + glad_glScissor = (PFNGLSCISSORPROC)load("glScissor"); + glad_glTexParameterf = (PFNGLTEXPARAMETERFPROC)load("glTexParameterf"); + glad_glTexParameterfv = (PFNGLTEXPARAMETERFVPROC)load("glTexParameterfv"); + glad_glTexParameteri = (PFNGLTEXPARAMETERIPROC)load("glTexParameteri"); + glad_glTexParameteriv = (PFNGLTEXPARAMETERIVPROC)load("glTexParameteriv"); + glad_glTexImage1D = (PFNGLTEXIMAGE1DPROC)load("glTexImage1D"); + glad_glTexImage2D = (PFNGLTEXIMAGE2DPROC)load("glTexImage2D"); + glad_glDrawBuffer = (PFNGLDRAWBUFFERPROC)load("glDrawBuffer"); + glad_glClear = (PFNGLCLEARPROC)load("glClear"); + glad_glClearColor = (PFNGLCLEARCOLORPROC)load("glClearColor"); + glad_glClearStencil = (PFNGLCLEARSTENCILPROC)load("glClearStencil"); + glad_glClearDepth = (PFNGLCLEARDEPTHPROC)load("glClearDepth"); + glad_glStencilMask = (PFNGLSTENCILMASKPROC)load("glStencilMask"); + glad_glColorMask = (PFNGLCOLORMASKPROC)load("glColorMask"); + glad_glDepthMask = (PFNGLDEPTHMASKPROC)load("glDepthMask"); + glad_glDisable = (PFNGLDISABLEPROC)load("glDisable"); + glad_glEnable = (PFNGLENABLEPROC)load("glEnable"); + glad_glFinish = (PFNGLFINISHPROC)load("glFinish"); + glad_glFlush = (PFNGLFLUSHPROC)load("glFlush"); + glad_glBlendFunc = (PFNGLBLENDFUNCPROC)load("glBlendFunc"); + glad_glLogicOp = (PFNGLLOGICOPPROC)load("glLogicOp"); + glad_glStencilFunc = (PFNGLSTENCILFUNCPROC)load("glStencilFunc"); + glad_glStencilOp = (PFNGLSTENCILOPPROC)load("glStencilOp"); + glad_glDepthFunc = (PFNGLDEPTHFUNCPROC)load("glDepthFunc"); + glad_glPixelStoref = (PFNGLPIXELSTOREFPROC)load("glPixelStoref"); + glad_glPixelStorei = (PFNGLPIXELSTOREIPROC)load("glPixelStorei"); + glad_glReadBuffer = (PFNGLREADBUFFERPROC)load("glReadBuffer"); + glad_glReadPixels = (PFNGLREADPIXELSPROC)load("glReadPixels"); + glad_glGetBooleanv = (PFNGLGETBOOLEANVPROC)load("glGetBooleanv"); + glad_glGetDoublev = (PFNGLGETDOUBLEVPROC)load("glGetDoublev"); + glad_glGetError = (PFNGLGETERRORPROC)load("glGetError"); + glad_glGetFloatv = (PFNGLGETFLOATVPROC)load("glGetFloatv"); + glad_glGetIntegerv = (PFNGLGETINTEGERVPROC)load("glGetIntegerv"); + glad_glGetString = (PFNGLGETSTRINGPROC)load("glGetString"); + glad_glGetTexImage = (PFNGLGETTEXIMAGEPROC)load("glGetTexImage"); + glad_glGetTexParameterfv = (PFNGLGETTEXPARAMETERFVPROC)load("glGetTexParameterfv"); + glad_glGetTexParameteriv = (PFNGLGETTEXPARAMETERIVPROC)load("glGetTexParameteriv"); + glad_glGetTexLevelParameterfv = (PFNGLGETTEXLEVELPARAMETERFVPROC)load("glGetTexLevelParameterfv"); + glad_glGetTexLevelParameteriv = (PFNGLGETTEXLEVELPARAMETERIVPROC)load("glGetTexLevelParameteriv"); + glad_glIsEnabled = (PFNGLISENABLEDPROC)load("glIsEnabled"); + glad_glDepthRange = (PFNGLDEPTHRANGEPROC)load("glDepthRange"); + glad_glViewport = (PFNGLVIEWPORTPROC)load("glViewport"); +} +static void load_GL_VERSION_1_1(GLADloadproc load) { + if(!GLAD_GL_VERSION_1_1) return; + glad_glDrawArrays = (PFNGLDRAWARRAYSPROC)load("glDrawArrays"); + glad_glDrawElements = (PFNGLDRAWELEMENTSPROC)load("glDrawElements"); + glad_glPolygonOffset = (PFNGLPOLYGONOFFSETPROC)load("glPolygonOffset"); + glad_glCopyTexImage1D = (PFNGLCOPYTEXIMAGE1DPROC)load("glCopyTexImage1D"); + glad_glCopyTexImage2D = (PFNGLCOPYTEXIMAGE2DPROC)load("glCopyTexImage2D"); + glad_glCopyTexSubImage1D = (PFNGLCOPYTEXSUBIMAGE1DPROC)load("glCopyTexSubImage1D"); + glad_glCopyTexSubImage2D = (PFNGLCOPYTEXSUBIMAGE2DPROC)load("glCopyTexSubImage2D"); + glad_glTexSubImage1D = (PFNGLTEXSUBIMAGE1DPROC)load("glTexSubImage1D"); + glad_glTexSubImage2D = (PFNGLTEXSUBIMAGE2DPROC)load("glTexSubImage2D"); + glad_glBindTexture = (PFNGLBINDTEXTUREPROC)load("glBindTexture"); + glad_glDeleteTextures = (PFNGLDELETETEXTURESPROC)load("glDeleteTextures"); + glad_glGenTextures = (PFNGLGENTEXTURESPROC)load("glGenTextures"); + glad_glIsTexture = (PFNGLISTEXTUREPROC)load("glIsTexture"); +} +static void load_GL_VERSION_1_2(GLADloadproc load) { + if(!GLAD_GL_VERSION_1_2) return; + glad_glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)load("glDrawRangeElements"); + glad_glTexImage3D = (PFNGLTEXIMAGE3DPROC)load("glTexImage3D"); + glad_glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC)load("glTexSubImage3D"); + glad_glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC)load("glCopyTexSubImage3D"); +} +static void load_GL_VERSION_1_3(GLADloadproc load) { + if(!GLAD_GL_VERSION_1_3) return; + glad_glActiveTexture = (PFNGLACTIVETEXTUREPROC)load("glActiveTexture"); + glad_glSampleCoverage = (PFNGLSAMPLECOVERAGEPROC)load("glSampleCoverage"); + glad_glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC)load("glCompressedTexImage3D"); + glad_glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC)load("glCompressedTexImage2D"); + glad_glCompressedTexImage1D = (PFNGLCOMPRESSEDTEXIMAGE1DPROC)load("glCompressedTexImage1D"); + glad_glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)load("glCompressedTexSubImage3D"); + glad_glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)load("glCompressedTexSubImage2D"); + glad_glCompressedTexSubImage1D = (PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)load("glCompressedTexSubImage1D"); + glad_glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC)load("glGetCompressedTexImage"); +} +static void load_GL_VERSION_1_4(GLADloadproc load) { + if(!GLAD_GL_VERSION_1_4) return; + glad_glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC)load("glBlendFuncSeparate"); + glad_glMultiDrawArrays = (PFNGLMULTIDRAWARRAYSPROC)load("glMultiDrawArrays"); + glad_glMultiDrawElements = (PFNGLMULTIDRAWELEMENTSPROC)load("glMultiDrawElements"); + glad_glPointParameterf = (PFNGLPOINTPARAMETERFPROC)load("glPointParameterf"); + glad_glPointParameterfv = (PFNGLPOINTPARAMETERFVPROC)load("glPointParameterfv"); + glad_glPointParameteri = (PFNGLPOINTPARAMETERIPROC)load("glPointParameteri"); + glad_glPointParameteriv = (PFNGLPOINTPARAMETERIVPROC)load("glPointParameteriv"); + glad_glBlendColor = (PFNGLBLENDCOLORPROC)load("glBlendColor"); + glad_glBlendEquation = (PFNGLBLENDEQUATIONPROC)load("glBlendEquation"); +} +static void load_GL_VERSION_1_5(GLADloadproc load) { + if(!GLAD_GL_VERSION_1_5) return; + glad_glGenQueries = (PFNGLGENQUERIESPROC)load("glGenQueries"); + glad_glDeleteQueries = (PFNGLDELETEQUERIESPROC)load("glDeleteQueries"); + glad_glIsQuery = (PFNGLISQUERYPROC)load("glIsQuery"); + glad_glBeginQuery = (PFNGLBEGINQUERYPROC)load("glBeginQuery"); + glad_glEndQuery = (PFNGLENDQUERYPROC)load("glEndQuery"); + glad_glGetQueryiv = (PFNGLGETQUERYIVPROC)load("glGetQueryiv"); + glad_glGetQueryObjectiv = (PFNGLGETQUERYOBJECTIVPROC)load("glGetQueryObjectiv"); + glad_glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC)load("glGetQueryObjectuiv"); + glad_glBindBuffer = (PFNGLBINDBUFFERPROC)load("glBindBuffer"); + glad_glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)load("glDeleteBuffers"); + glad_glGenBuffers = (PFNGLGENBUFFERSPROC)load("glGenBuffers"); + glad_glIsBuffer = (PFNGLISBUFFERPROC)load("glIsBuffer"); + glad_glBufferData = (PFNGLBUFFERDATAPROC)load("glBufferData"); + glad_glBufferSubData = (PFNGLBUFFERSUBDATAPROC)load("glBufferSubData"); + glad_glGetBufferSubData = (PFNGLGETBUFFERSUBDATAPROC)load("glGetBufferSubData"); + glad_glMapBuffer = (PFNGLMAPBUFFERPROC)load("glMapBuffer"); + glad_glUnmapBuffer = (PFNGLUNMAPBUFFERPROC)load("glUnmapBuffer"); + glad_glGetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC)load("glGetBufferParameteriv"); + glad_glGetBufferPointerv = (PFNGLGETBUFFERPOINTERVPROC)load("glGetBufferPointerv"); +} +static void load_GL_VERSION_2_0(GLADloadproc load) { + if(!GLAD_GL_VERSION_2_0) return; + glad_glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC)load("glBlendEquationSeparate"); + glad_glDrawBuffers = (PFNGLDRAWBUFFERSPROC)load("glDrawBuffers"); + glad_glStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC)load("glStencilOpSeparate"); + glad_glStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC)load("glStencilFuncSeparate"); + glad_glStencilMaskSeparate = (PFNGLSTENCILMASKSEPARATEPROC)load("glStencilMaskSeparate"); + glad_glAttachShader = (PFNGLATTACHSHADERPROC)load("glAttachShader"); + glad_glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC)load("glBindAttribLocation"); + glad_glCompileShader = (PFNGLCOMPILESHADERPROC)load("glCompileShader"); + glad_glCreateProgram = (PFNGLCREATEPROGRAMPROC)load("glCreateProgram"); + glad_glCreateShader = (PFNGLCREATESHADERPROC)load("glCreateShader"); + glad_glDeleteProgram = (PFNGLDELETEPROGRAMPROC)load("glDeleteProgram"); + glad_glDeleteShader = (PFNGLDELETESHADERPROC)load("glDeleteShader"); + glad_glDetachShader = (PFNGLDETACHSHADERPROC)load("glDetachShader"); + glad_glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)load("glDisableVertexAttribArray"); + glad_glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)load("glEnableVertexAttribArray"); + glad_glGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC)load("glGetActiveAttrib"); + glad_glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC)load("glGetActiveUniform"); + glad_glGetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC)load("glGetAttachedShaders"); + glad_glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)load("glGetAttribLocation"); + glad_glGetProgramiv = (PFNGLGETPROGRAMIVPROC)load("glGetProgramiv"); + glad_glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)load("glGetProgramInfoLog"); + glad_glGetShaderiv = (PFNGLGETSHADERIVPROC)load("glGetShaderiv"); + glad_glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)load("glGetShaderInfoLog"); + glad_glGetShaderSource = (PFNGLGETSHADERSOURCEPROC)load("glGetShaderSource"); + glad_glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)load("glGetUniformLocation"); + glad_glGetUniformfv = (PFNGLGETUNIFORMFVPROC)load("glGetUniformfv"); + glad_glGetUniformiv = (PFNGLGETUNIFORMIVPROC)load("glGetUniformiv"); + glad_glGetVertexAttribdv = (PFNGLGETVERTEXATTRIBDVPROC)load("glGetVertexAttribdv"); + glad_glGetVertexAttribfv = (PFNGLGETVERTEXATTRIBFVPROC)load("glGetVertexAttribfv"); + glad_glGetVertexAttribiv = (PFNGLGETVERTEXATTRIBIVPROC)load("glGetVertexAttribiv"); + glad_glGetVertexAttribPointerv = (PFNGLGETVERTEXATTRIBPOINTERVPROC)load("glGetVertexAttribPointerv"); + glad_glIsProgram = (PFNGLISPROGRAMPROC)load("glIsProgram"); + glad_glIsShader = (PFNGLISSHADERPROC)load("glIsShader"); + glad_glLinkProgram = (PFNGLLINKPROGRAMPROC)load("glLinkProgram"); + glad_glShaderSource = (PFNGLSHADERSOURCEPROC)load("glShaderSource"); + glad_glUseProgram = (PFNGLUSEPROGRAMPROC)load("glUseProgram"); + glad_glUniform1f = (PFNGLUNIFORM1FPROC)load("glUniform1f"); + glad_glUniform2f = (PFNGLUNIFORM2FPROC)load("glUniform2f"); + glad_glUniform3f = (PFNGLUNIFORM3FPROC)load("glUniform3f"); + glad_glUniform4f = (PFNGLUNIFORM4FPROC)load("glUniform4f"); + glad_glUniform1i = (PFNGLUNIFORM1IPROC)load("glUniform1i"); + glad_glUniform2i = (PFNGLUNIFORM2IPROC)load("glUniform2i"); + glad_glUniform3i = (PFNGLUNIFORM3IPROC)load("glUniform3i"); + glad_glUniform4i = (PFNGLUNIFORM4IPROC)load("glUniform4i"); + glad_glUniform1fv = (PFNGLUNIFORM1FVPROC)load("glUniform1fv"); + glad_glUniform2fv = (PFNGLUNIFORM2FVPROC)load("glUniform2fv"); + glad_glUniform3fv = (PFNGLUNIFORM3FVPROC)load("glUniform3fv"); + glad_glUniform4fv = (PFNGLUNIFORM4FVPROC)load("glUniform4fv"); + glad_glUniform1iv = (PFNGLUNIFORM1IVPROC)load("glUniform1iv"); + glad_glUniform2iv = (PFNGLUNIFORM2IVPROC)load("glUniform2iv"); + glad_glUniform3iv = (PFNGLUNIFORM3IVPROC)load("glUniform3iv"); + glad_glUniform4iv = (PFNGLUNIFORM4IVPROC)load("glUniform4iv"); + glad_glUniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC)load("glUniformMatrix2fv"); + glad_glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC)load("glUniformMatrix3fv"); + glad_glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)load("glUniformMatrix4fv"); + glad_glValidateProgram = (PFNGLVALIDATEPROGRAMPROC)load("glValidateProgram"); + glad_glVertexAttrib1d = (PFNGLVERTEXATTRIB1DPROC)load("glVertexAttrib1d"); + glad_glVertexAttrib1dv = (PFNGLVERTEXATTRIB1DVPROC)load("glVertexAttrib1dv"); + glad_glVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC)load("glVertexAttrib1f"); + glad_glVertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC)load("glVertexAttrib1fv"); + glad_glVertexAttrib1s = (PFNGLVERTEXATTRIB1SPROC)load("glVertexAttrib1s"); + glad_glVertexAttrib1sv = (PFNGLVERTEXATTRIB1SVPROC)load("glVertexAttrib1sv"); + glad_glVertexAttrib2d = (PFNGLVERTEXATTRIB2DPROC)load("glVertexAttrib2d"); + glad_glVertexAttrib2dv = (PFNGLVERTEXATTRIB2DVPROC)load("glVertexAttrib2dv"); + glad_glVertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC)load("glVertexAttrib2f"); + glad_glVertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC)load("glVertexAttrib2fv"); + glad_glVertexAttrib2s = (PFNGLVERTEXATTRIB2SPROC)load("glVertexAttrib2s"); + glad_glVertexAttrib2sv = (PFNGLVERTEXATTRIB2SVPROC)load("glVertexAttrib2sv"); + glad_glVertexAttrib3d = (PFNGLVERTEXATTRIB3DPROC)load("glVertexAttrib3d"); + glad_glVertexAttrib3dv = (PFNGLVERTEXATTRIB3DVPROC)load("glVertexAttrib3dv"); + glad_glVertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC)load("glVertexAttrib3f"); + glad_glVertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC)load("glVertexAttrib3fv"); + glad_glVertexAttrib3s = (PFNGLVERTEXATTRIB3SPROC)load("glVertexAttrib3s"); + glad_glVertexAttrib3sv = (PFNGLVERTEXATTRIB3SVPROC)load("glVertexAttrib3sv"); + glad_glVertexAttrib4Nbv = (PFNGLVERTEXATTRIB4NBVPROC)load("glVertexAttrib4Nbv"); + glad_glVertexAttrib4Niv = (PFNGLVERTEXATTRIB4NIVPROC)load("glVertexAttrib4Niv"); + glad_glVertexAttrib4Nsv = (PFNGLVERTEXATTRIB4NSVPROC)load("glVertexAttrib4Nsv"); + glad_glVertexAttrib4Nub = (PFNGLVERTEXATTRIB4NUBPROC)load("glVertexAttrib4Nub"); + glad_glVertexAttrib4Nubv = (PFNGLVERTEXATTRIB4NUBVPROC)load("glVertexAttrib4Nubv"); + glad_glVertexAttrib4Nuiv = (PFNGLVERTEXATTRIB4NUIVPROC)load("glVertexAttrib4Nuiv"); + glad_glVertexAttrib4Nusv = (PFNGLVERTEXATTRIB4NUSVPROC)load("glVertexAttrib4Nusv"); + glad_glVertexAttrib4bv = (PFNGLVERTEXATTRIB4BVPROC)load("glVertexAttrib4bv"); + glad_glVertexAttrib4d = (PFNGLVERTEXATTRIB4DPROC)load("glVertexAttrib4d"); + glad_glVertexAttrib4dv = (PFNGLVERTEXATTRIB4DVPROC)load("glVertexAttrib4dv"); + glad_glVertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC)load("glVertexAttrib4f"); + glad_glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC)load("glVertexAttrib4fv"); + glad_glVertexAttrib4iv = (PFNGLVERTEXATTRIB4IVPROC)load("glVertexAttrib4iv"); + glad_glVertexAttrib4s = (PFNGLVERTEXATTRIB4SPROC)load("glVertexAttrib4s"); + glad_glVertexAttrib4sv = (PFNGLVERTEXATTRIB4SVPROC)load("glVertexAttrib4sv"); + glad_glVertexAttrib4ubv = (PFNGLVERTEXATTRIB4UBVPROC)load("glVertexAttrib4ubv"); + glad_glVertexAttrib4uiv = (PFNGLVERTEXATTRIB4UIVPROC)load("glVertexAttrib4uiv"); + glad_glVertexAttrib4usv = (PFNGLVERTEXATTRIB4USVPROC)load("glVertexAttrib4usv"); + glad_glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)load("glVertexAttribPointer"); +} +static void load_GL_VERSION_2_1(GLADloadproc load) { + if(!GLAD_GL_VERSION_2_1) return; + glad_glUniformMatrix2x3fv = (PFNGLUNIFORMMATRIX2X3FVPROC)load("glUniformMatrix2x3fv"); + glad_glUniformMatrix3x2fv = (PFNGLUNIFORMMATRIX3X2FVPROC)load("glUniformMatrix3x2fv"); + glad_glUniformMatrix2x4fv = (PFNGLUNIFORMMATRIX2X4FVPROC)load("glUniformMatrix2x4fv"); + glad_glUniformMatrix4x2fv = (PFNGLUNIFORMMATRIX4X2FVPROC)load("glUniformMatrix4x2fv"); + glad_glUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC)load("glUniformMatrix3x4fv"); + glad_glUniformMatrix4x3fv = (PFNGLUNIFORMMATRIX4X3FVPROC)load("glUniformMatrix4x3fv"); +} +static void load_GL_VERSION_3_0(GLADloadproc load) { + if(!GLAD_GL_VERSION_3_0) return; + glad_glColorMaski = (PFNGLCOLORMASKIPROC)load("glColorMaski"); + glad_glGetBooleani_v = (PFNGLGETBOOLEANI_VPROC)load("glGetBooleani_v"); + glad_glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC)load("glGetIntegeri_v"); + glad_glEnablei = (PFNGLENABLEIPROC)load("glEnablei"); + glad_glDisablei = (PFNGLDISABLEIPROC)load("glDisablei"); + glad_glIsEnabledi = (PFNGLISENABLEDIPROC)load("glIsEnabledi"); + glad_glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC)load("glBeginTransformFeedback"); + glad_glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC)load("glEndTransformFeedback"); + glad_glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC)load("glBindBufferRange"); + glad_glBindBufferBase = (PFNGLBINDBUFFERBASEPROC)load("glBindBufferBase"); + glad_glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC)load("glTransformFeedbackVaryings"); + glad_glGetTransformFeedbackVarying = (PFNGLGETTRANSFORMFEEDBACKVARYINGPROC)load("glGetTransformFeedbackVarying"); + glad_glClampColor = (PFNGLCLAMPCOLORPROC)load("glClampColor"); + glad_glBeginConditionalRender = (PFNGLBEGINCONDITIONALRENDERPROC)load("glBeginConditionalRender"); + glad_glEndConditionalRender = (PFNGLENDCONDITIONALRENDERPROC)load("glEndConditionalRender"); + glad_glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC)load("glVertexAttribIPointer"); + glad_glGetVertexAttribIiv = (PFNGLGETVERTEXATTRIBIIVPROC)load("glGetVertexAttribIiv"); + glad_glGetVertexAttribIuiv = (PFNGLGETVERTEXATTRIBIUIVPROC)load("glGetVertexAttribIuiv"); + glad_glVertexAttribI1i = (PFNGLVERTEXATTRIBI1IPROC)load("glVertexAttribI1i"); + glad_glVertexAttribI2i = (PFNGLVERTEXATTRIBI2IPROC)load("glVertexAttribI2i"); + glad_glVertexAttribI3i = (PFNGLVERTEXATTRIBI3IPROC)load("glVertexAttribI3i"); + glad_glVertexAttribI4i = (PFNGLVERTEXATTRIBI4IPROC)load("glVertexAttribI4i"); + glad_glVertexAttribI1ui = (PFNGLVERTEXATTRIBI1UIPROC)load("glVertexAttribI1ui"); + glad_glVertexAttribI2ui = (PFNGLVERTEXATTRIBI2UIPROC)load("glVertexAttribI2ui"); + glad_glVertexAttribI3ui = (PFNGLVERTEXATTRIBI3UIPROC)load("glVertexAttribI3ui"); + glad_glVertexAttribI4ui = (PFNGLVERTEXATTRIBI4UIPROC)load("glVertexAttribI4ui"); + glad_glVertexAttribI1iv = (PFNGLVERTEXATTRIBI1IVPROC)load("glVertexAttribI1iv"); + glad_glVertexAttribI2iv = (PFNGLVERTEXATTRIBI2IVPROC)load("glVertexAttribI2iv"); + glad_glVertexAttribI3iv = (PFNGLVERTEXATTRIBI3IVPROC)load("glVertexAttribI3iv"); + glad_glVertexAttribI4iv = (PFNGLVERTEXATTRIBI4IVPROC)load("glVertexAttribI4iv"); + glad_glVertexAttribI1uiv = (PFNGLVERTEXATTRIBI1UIVPROC)load("glVertexAttribI1uiv"); + glad_glVertexAttribI2uiv = (PFNGLVERTEXATTRIBI2UIVPROC)load("glVertexAttribI2uiv"); + glad_glVertexAttribI3uiv = (PFNGLVERTEXATTRIBI3UIVPROC)load("glVertexAttribI3uiv"); + glad_glVertexAttribI4uiv = (PFNGLVERTEXATTRIBI4UIVPROC)load("glVertexAttribI4uiv"); + glad_glVertexAttribI4bv = (PFNGLVERTEXATTRIBI4BVPROC)load("glVertexAttribI4bv"); + glad_glVertexAttribI4sv = (PFNGLVERTEXATTRIBI4SVPROC)load("glVertexAttribI4sv"); + glad_glVertexAttribI4ubv = (PFNGLVERTEXATTRIBI4UBVPROC)load("glVertexAttribI4ubv"); + glad_glVertexAttribI4usv = (PFNGLVERTEXATTRIBI4USVPROC)load("glVertexAttribI4usv"); + glad_glGetUniformuiv = (PFNGLGETUNIFORMUIVPROC)load("glGetUniformuiv"); + glad_glBindFragDataLocation = (PFNGLBINDFRAGDATALOCATIONPROC)load("glBindFragDataLocation"); + glad_glGetFragDataLocation = (PFNGLGETFRAGDATALOCATIONPROC)load("glGetFragDataLocation"); + glad_glUniform1ui = (PFNGLUNIFORM1UIPROC)load("glUniform1ui"); + glad_glUniform2ui = (PFNGLUNIFORM2UIPROC)load("glUniform2ui"); + glad_glUniform3ui = (PFNGLUNIFORM3UIPROC)load("glUniform3ui"); + glad_glUniform4ui = (PFNGLUNIFORM4UIPROC)load("glUniform4ui"); + glad_glUniform1uiv = (PFNGLUNIFORM1UIVPROC)load("glUniform1uiv"); + glad_glUniform2uiv = (PFNGLUNIFORM2UIVPROC)load("glUniform2uiv"); + glad_glUniform3uiv = (PFNGLUNIFORM3UIVPROC)load("glUniform3uiv"); + glad_glUniform4uiv = (PFNGLUNIFORM4UIVPROC)load("glUniform4uiv"); + glad_glTexParameterIiv = (PFNGLTEXPARAMETERIIVPROC)load("glTexParameterIiv"); + glad_glTexParameterIuiv = (PFNGLTEXPARAMETERIUIVPROC)load("glTexParameterIuiv"); + glad_glGetTexParameterIiv = (PFNGLGETTEXPARAMETERIIVPROC)load("glGetTexParameterIiv"); + glad_glGetTexParameterIuiv = (PFNGLGETTEXPARAMETERIUIVPROC)load("glGetTexParameterIuiv"); + glad_glClearBufferiv = (PFNGLCLEARBUFFERIVPROC)load("glClearBufferiv"); + glad_glClearBufferuiv = (PFNGLCLEARBUFFERUIVPROC)load("glClearBufferuiv"); + glad_glClearBufferfv = (PFNGLCLEARBUFFERFVPROC)load("glClearBufferfv"); + glad_glClearBufferfi = (PFNGLCLEARBUFFERFIPROC)load("glClearBufferfi"); + glad_glGetStringi = (PFNGLGETSTRINGIPROC)load("glGetStringi"); + glad_glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC)load("glIsRenderbuffer"); + glad_glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)load("glBindRenderbuffer"); + glad_glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)load("glDeleteRenderbuffers"); + glad_glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)load("glGenRenderbuffers"); + glad_glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)load("glRenderbufferStorage"); + glad_glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC)load("glGetRenderbufferParameteriv"); + glad_glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC)load("glIsFramebuffer"); + glad_glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)load("glBindFramebuffer"); + glad_glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)load("glDeleteFramebuffers"); + glad_glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)load("glGenFramebuffers"); + glad_glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)load("glCheckFramebufferStatus"); + glad_glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC)load("glFramebufferTexture1D"); + glad_glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)load("glFramebufferTexture2D"); + glad_glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC)load("glFramebufferTexture3D"); + glad_glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)load("glFramebufferRenderbuffer"); + glad_glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)load("glGetFramebufferAttachmentParameteriv"); + glad_glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC)load("glGenerateMipmap"); + glad_glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC)load("glBlitFramebuffer"); + glad_glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)load("glRenderbufferStorageMultisample"); + glad_glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC)load("glFramebufferTextureLayer"); + glad_glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC)load("glMapBufferRange"); + glad_glFlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC)load("glFlushMappedBufferRange"); + glad_glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)load("glBindVertexArray"); + glad_glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC)load("glDeleteVertexArrays"); + glad_glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)load("glGenVertexArrays"); + glad_glIsVertexArray = (PFNGLISVERTEXARRAYPROC)load("glIsVertexArray"); +} +static void load_GL_VERSION_3_1(GLADloadproc load) { + if(!GLAD_GL_VERSION_3_1) return; + glad_glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)load("glDrawArraysInstanced"); + glad_glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)load("glDrawElementsInstanced"); + glad_glTexBuffer = (PFNGLTEXBUFFERPROC)load("glTexBuffer"); + glad_glPrimitiveRestartIndex = (PFNGLPRIMITIVERESTARTINDEXPROC)load("glPrimitiveRestartIndex"); + glad_glCopyBufferSubData = (PFNGLCOPYBUFFERSUBDATAPROC)load("glCopyBufferSubData"); + glad_glGetUniformIndices = (PFNGLGETUNIFORMINDICESPROC)load("glGetUniformIndices"); + glad_glGetActiveUniformsiv = (PFNGLGETACTIVEUNIFORMSIVPROC)load("glGetActiveUniformsiv"); + glad_glGetActiveUniformName = (PFNGLGETACTIVEUNIFORMNAMEPROC)load("glGetActiveUniformName"); + glad_glGetUniformBlockIndex = (PFNGLGETUNIFORMBLOCKINDEXPROC)load("glGetUniformBlockIndex"); + glad_glGetActiveUniformBlockiv = (PFNGLGETACTIVEUNIFORMBLOCKIVPROC)load("glGetActiveUniformBlockiv"); + glad_glGetActiveUniformBlockName = (PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC)load("glGetActiveUniformBlockName"); + glad_glUniformBlockBinding = (PFNGLUNIFORMBLOCKBINDINGPROC)load("glUniformBlockBinding"); +} +static void load_GL_VERSION_3_2(GLADloadproc load) { + if(!GLAD_GL_VERSION_3_2) return; + glad_glDrawElementsBaseVertex = (PFNGLDRAWELEMENTSBASEVERTEXPROC)load("glDrawElementsBaseVertex"); + glad_glDrawRangeElementsBaseVertex = (PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC)load("glDrawRangeElementsBaseVertex"); + glad_glDrawElementsInstancedBaseVertex = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)load("glDrawElementsInstancedBaseVertex"); + glad_glMultiDrawElementsBaseVertex = (PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC)load("glMultiDrawElementsBaseVertex"); + glad_glProvokingVertex = (PFNGLPROVOKINGVERTEXPROC)load("glProvokingVertex"); + glad_glFenceSync = (PFNGLFENCESYNCPROC)load("glFenceSync"); + glad_glIsSync = (PFNGLISSYNCPROC)load("glIsSync"); + glad_glDeleteSync = (PFNGLDELETESYNCPROC)load("glDeleteSync"); + glad_glClientWaitSync = (PFNGLCLIENTWAITSYNCPROC)load("glClientWaitSync"); + glad_glWaitSync = (PFNGLWAITSYNCPROC)load("glWaitSync"); + glad_glGetInteger64v = (PFNGLGETINTEGER64VPROC)load("glGetInteger64v"); + glad_glGetSynciv = (PFNGLGETSYNCIVPROC)load("glGetSynciv"); + glad_glGetInteger64i_v = (PFNGLGETINTEGER64I_VPROC)load("glGetInteger64i_v"); + glad_glGetBufferParameteri64v = (PFNGLGETBUFFERPARAMETERI64VPROC)load("glGetBufferParameteri64v"); + glad_glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREPROC)load("glFramebufferTexture"); + glad_glTexImage2DMultisample = (PFNGLTEXIMAGE2DMULTISAMPLEPROC)load("glTexImage2DMultisample"); + glad_glTexImage3DMultisample = (PFNGLTEXIMAGE3DMULTISAMPLEPROC)load("glTexImage3DMultisample"); + glad_glGetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC)load("glGetMultisamplefv"); + glad_glSampleMaski = (PFNGLSAMPLEMASKIPROC)load("glSampleMaski"); +} +static void find_extensionsGL(void) { +} + +static void find_coreGL(void) { + const char *v = (const char *)glGetString(GL_VERSION); + int major = v[0] - '0'; + int minor = v[2] - '0'; + GLVersion.major = major; GLVersion.minor = minor; + GLAD_GL_VERSION_1_0 = (major == 1 && minor >= 0) || major > 1; + GLAD_GL_VERSION_1_1 = (major == 1 && minor >= 1) || major > 1; + GLAD_GL_VERSION_1_2 = (major == 1 && minor >= 2) || major > 1; + GLAD_GL_VERSION_1_3 = (major == 1 && minor >= 3) || major > 1; + GLAD_GL_VERSION_1_4 = (major == 1 && minor >= 4) || major > 1; + GLAD_GL_VERSION_1_5 = (major == 1 && minor >= 5) || major > 1; + GLAD_GL_VERSION_2_0 = (major == 2 && minor >= 0) || major > 2; + GLAD_GL_VERSION_2_1 = (major == 2 && minor >= 1) || major > 2; + GLAD_GL_VERSION_3_0 = (major == 3 && minor >= 0) || major > 3; + GLAD_GL_VERSION_3_1 = (major == 3 && minor >= 1) || major > 3; + GLAD_GL_VERSION_3_2 = (major == 3 && minor >= 2) || major > 3; +} + +void gladLoadGLLoader(GLADloadproc load) { + GLVersion.major = 0; GLVersion.minor = 0; + glGetString = (PFNGLGETSTRINGPROC)load("glGetString"); + if(glGetString == NULL) return; + find_coreGL(); + load_GL_VERSION_1_0(load); + load_GL_VERSION_1_1(load); + load_GL_VERSION_1_2(load); + load_GL_VERSION_1_3(load); + load_GL_VERSION_1_4(load); + load_GL_VERSION_1_5(load); + load_GL_VERSION_2_0(load); + load_GL_VERSION_2_1(load); + load_GL_VERSION_3_0(load); + load_GL_VERSION_3_1(load); + load_GL_VERSION_3_2(load); + + find_extensionsGL(); + + return; +} + diff --git a/testbed/glfw/deps/glad/glad.h b/testbed/glfw/deps/glad/glad.h new file mode 100644 index 00000000..e5de4efc --- /dev/null +++ b/testbed/glfw/deps/glad/glad.h @@ -0,0 +1,1925 @@ + +#ifndef __glad_h_ + +#ifdef __gl_h_ +#error OpenGL header already included, remove this include, glad already provides it +#endif + +#define __glad_h_ +#define __gl_h_ + +#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN 1 +#endif +#include +#endif + +#ifndef APIENTRY +#define APIENTRY +#endif +#ifndef APIENTRYP +#define APIENTRYP APIENTRY * +#endif + +extern struct gladGLversionStruct { + int major; + int minor; +} GLVersion; + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void* (* GLADloadproc)(const char *name); + +#ifndef GLAPI +# if defined(GLAD_GLAPI_EXPORT) +# if defined(WIN32) || defined(__CYGWIN__) +# if defined(GLAD_GLAPI_EXPORT_BUILD) +# if defined(__GNUC__) +# define GLAPI __attribute__ ((dllexport)) extern +# else +# define GLAPI __declspec(dllexport) extern +# endif +# else +# if defined(__GNUC__) +# define GLAPI __attribute__ ((dllimport)) extern +# else +# define GLAPI __declspec(dllimport) extern +# endif +# endif +# elif defined(__GNUC__) && defined(GLAD_GLAPI_EXPORT_BUILD) +# define GLAPI __attribute__ ((visibility ("default"))) extern +# else +# define GLAPI extern +# endif +# else +# define GLAPI extern +# endif +#endif +GLAPI void gladLoadGLLoader(GLADloadproc); + +#include +#include +#ifndef GLEXT_64_TYPES_DEFINED +/* This code block is duplicated in glxext.h, so must be protected */ +#define GLEXT_64_TYPES_DEFINED +/* Define int32_t, int64_t, and uint64_t types for UST/MSC */ +/* (as used in the GL_EXT_timer_query extension). */ +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#include +#elif defined(__sun__) || defined(__digital__) +#include +#if defined(__STDC__) +#if defined(__arch64__) || defined(_LP64) +typedef long int int64_t; +typedef unsigned long int uint64_t; +#else +typedef long long int int64_t; +typedef unsigned long long int uint64_t; +#endif /* __arch64__ */ +#endif /* __STDC__ */ +#elif defined( __VMS ) || defined(__sgi) +#include +#elif defined(__SCO__) || defined(__USLC__) +#include +#elif defined(__UNIXOS2__) || defined(__SOL64__) +typedef long int int32_t; +typedef long long int int64_t; +typedef unsigned long long int uint64_t; +#elif defined(_WIN32) && defined(__GNUC__) +#include +#elif defined(_WIN32) +typedef __int32 int32_t; +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +#else +/* Fallback if nothing above works */ +#include +#endif +#endif +typedef unsigned int GLenum; +typedef unsigned char GLboolean; +typedef unsigned int GLbitfield; +typedef void GLvoid; +typedef signed char GLbyte; +typedef short GLshort; +typedef int GLint; +typedef int GLclampx; +typedef unsigned char GLubyte; +typedef unsigned short GLushort; +typedef unsigned int GLuint; +typedef int GLsizei; +typedef float GLfloat; +typedef float GLclampf; +typedef double GLdouble; +typedef double GLclampd; +typedef void *GLeglImageOES; +typedef char GLchar; +typedef char GLcharARB; +#ifdef __APPLE__ +typedef void *GLhandleARB; +#else +typedef unsigned int GLhandleARB; +#endif +typedef unsigned short GLhalfARB; +typedef unsigned short GLhalf; +typedef GLint GLfixed; +typedef ptrdiff_t GLintptr; +typedef ptrdiff_t GLsizeiptr; +typedef int64_t GLint64; +typedef uint64_t GLuint64; +typedef ptrdiff_t GLintptrARB; +typedef ptrdiff_t GLsizeiptrARB; +typedef int64_t GLint64EXT; +typedef uint64_t GLuint64EXT; +typedef struct __GLsync *GLsync; +struct _cl_context; +struct _cl_event; +typedef void (APIENTRY *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); +typedef void (APIENTRY *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); +typedef void (APIENTRY *GLDEBUGPROCKHR)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); +typedef void (APIENTRY *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,void *userParam); +typedef unsigned short GLhalfNV; +typedef GLintptr GLvdpauSurfaceNV; +#define GL_DEPTH_BUFFER_BIT 0x00000100 +#define GL_STENCIL_BUFFER_BIT 0x00000400 +#define GL_COLOR_BUFFER_BIT 0x00004000 +#define GL_FALSE 0 +#define GL_TRUE 1 +#define GL_POINTS 0x0000 +#define GL_LINES 0x0001 +#define GL_LINE_LOOP 0x0002 +#define GL_LINE_STRIP 0x0003 +#define GL_TRIANGLES 0x0004 +#define GL_TRIANGLE_STRIP 0x0005 +#define GL_TRIANGLE_FAN 0x0006 +#define GL_NEVER 0x0200 +#define GL_LESS 0x0201 +#define GL_EQUAL 0x0202 +#define GL_LEQUAL 0x0203 +#define GL_GREATER 0x0204 +#define GL_NOTEQUAL 0x0205 +#define GL_GEQUAL 0x0206 +#define GL_ALWAYS 0x0207 +#define GL_ZERO 0 +#define GL_ONE 1 +#define GL_SRC_COLOR 0x0300 +#define GL_ONE_MINUS_SRC_COLOR 0x0301 +#define GL_SRC_ALPHA 0x0302 +#define GL_ONE_MINUS_SRC_ALPHA 0x0303 +#define GL_DST_ALPHA 0x0304 +#define GL_ONE_MINUS_DST_ALPHA 0x0305 +#define GL_DST_COLOR 0x0306 +#define GL_ONE_MINUS_DST_COLOR 0x0307 +#define GL_SRC_ALPHA_SATURATE 0x0308 +#define GL_NONE 0 +#define GL_FRONT_LEFT 0x0400 +#define GL_FRONT_RIGHT 0x0401 +#define GL_BACK_LEFT 0x0402 +#define GL_BACK_RIGHT 0x0403 +#define GL_FRONT 0x0404 +#define GL_BACK 0x0405 +#define GL_LEFT 0x0406 +#define GL_RIGHT 0x0407 +#define GL_FRONT_AND_BACK 0x0408 +#define GL_NO_ERROR 0 +#define GL_INVALID_ENUM 0x0500 +#define GL_INVALID_VALUE 0x0501 +#define GL_INVALID_OPERATION 0x0502 +#define GL_OUT_OF_MEMORY 0x0505 +#define GL_CW 0x0900 +#define GL_CCW 0x0901 +#define GL_POINT_SIZE 0x0B11 +#define GL_POINT_SIZE_RANGE 0x0B12 +#define GL_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_LINE_SMOOTH 0x0B20 +#define GL_LINE_WIDTH 0x0B21 +#define GL_LINE_WIDTH_RANGE 0x0B22 +#define GL_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_POLYGON_MODE 0x0B40 +#define GL_POLYGON_SMOOTH 0x0B41 +#define GL_CULL_FACE 0x0B44 +#define GL_CULL_FACE_MODE 0x0B45 +#define GL_FRONT_FACE 0x0B46 +#define GL_DEPTH_RANGE 0x0B70 +#define GL_DEPTH_TEST 0x0B71 +#define GL_DEPTH_WRITEMASK 0x0B72 +#define GL_DEPTH_CLEAR_VALUE 0x0B73 +#define GL_DEPTH_FUNC 0x0B74 +#define GL_STENCIL_TEST 0x0B90 +#define GL_STENCIL_CLEAR_VALUE 0x0B91 +#define GL_STENCIL_FUNC 0x0B92 +#define GL_STENCIL_VALUE_MASK 0x0B93 +#define GL_STENCIL_FAIL 0x0B94 +#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 +#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 +#define GL_STENCIL_REF 0x0B97 +#define GL_STENCIL_WRITEMASK 0x0B98 +#define GL_VIEWPORT 0x0BA2 +#define GL_DITHER 0x0BD0 +#define GL_BLEND_DST 0x0BE0 +#define GL_BLEND_SRC 0x0BE1 +#define GL_BLEND 0x0BE2 +#define GL_LOGIC_OP_MODE 0x0BF0 +#define GL_COLOR_LOGIC_OP 0x0BF2 +#define GL_DRAW_BUFFER 0x0C01 +#define GL_READ_BUFFER 0x0C02 +#define GL_SCISSOR_BOX 0x0C10 +#define GL_SCISSOR_TEST 0x0C11 +#define GL_COLOR_CLEAR_VALUE 0x0C22 +#define GL_COLOR_WRITEMASK 0x0C23 +#define GL_DOUBLEBUFFER 0x0C32 +#define GL_STEREO 0x0C33 +#define GL_LINE_SMOOTH_HINT 0x0C52 +#define GL_POLYGON_SMOOTH_HINT 0x0C53 +#define GL_UNPACK_SWAP_BYTES 0x0CF0 +#define GL_UNPACK_LSB_FIRST 0x0CF1 +#define GL_UNPACK_ROW_LENGTH 0x0CF2 +#define GL_UNPACK_SKIP_ROWS 0x0CF3 +#define GL_UNPACK_SKIP_PIXELS 0x0CF4 +#define GL_UNPACK_ALIGNMENT 0x0CF5 +#define GL_PACK_SWAP_BYTES 0x0D00 +#define GL_PACK_LSB_FIRST 0x0D01 +#define GL_PACK_ROW_LENGTH 0x0D02 +#define GL_PACK_SKIP_ROWS 0x0D03 +#define GL_PACK_SKIP_PIXELS 0x0D04 +#define GL_PACK_ALIGNMENT 0x0D05 +#define GL_MAX_TEXTURE_SIZE 0x0D33 +#define GL_MAX_VIEWPORT_DIMS 0x0D3A +#define GL_SUBPIXEL_BITS 0x0D50 +#define GL_TEXTURE_1D 0x0DE0 +#define GL_TEXTURE_2D 0x0DE1 +#define GL_POLYGON_OFFSET_UNITS 0x2A00 +#define GL_POLYGON_OFFSET_POINT 0x2A01 +#define GL_POLYGON_OFFSET_LINE 0x2A02 +#define GL_POLYGON_OFFSET_FILL 0x8037 +#define GL_POLYGON_OFFSET_FACTOR 0x8038 +#define GL_TEXTURE_BINDING_1D 0x8068 +#define GL_TEXTURE_BINDING_2D 0x8069 +#define GL_TEXTURE_WIDTH 0x1000 +#define GL_TEXTURE_HEIGHT 0x1001 +#define GL_TEXTURE_INTERNAL_FORMAT 0x1003 +#define GL_TEXTURE_BORDER_COLOR 0x1004 +#define GL_TEXTURE_RED_SIZE 0x805C +#define GL_TEXTURE_GREEN_SIZE 0x805D +#define GL_TEXTURE_BLUE_SIZE 0x805E +#define GL_TEXTURE_ALPHA_SIZE 0x805F +#define GL_DONT_CARE 0x1100 +#define GL_FASTEST 0x1101 +#define GL_NICEST 0x1102 +#define GL_BYTE 0x1400 +#define GL_UNSIGNED_BYTE 0x1401 +#define GL_SHORT 0x1402 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_INT 0x1404 +#define GL_UNSIGNED_INT 0x1405 +#define GL_FLOAT 0x1406 +#define GL_DOUBLE 0x140A +#define GL_CLEAR 0x1500 +#define GL_AND 0x1501 +#define GL_AND_REVERSE 0x1502 +#define GL_COPY 0x1503 +#define GL_AND_INVERTED 0x1504 +#define GL_NOOP 0x1505 +#define GL_XOR 0x1506 +#define GL_OR 0x1507 +#define GL_NOR 0x1508 +#define GL_EQUIV 0x1509 +#define GL_INVERT 0x150A +#define GL_OR_REVERSE 0x150B +#define GL_COPY_INVERTED 0x150C +#define GL_OR_INVERTED 0x150D +#define GL_NAND 0x150E +#define GL_SET 0x150F +#define GL_TEXTURE 0x1702 +#define GL_COLOR 0x1800 +#define GL_DEPTH 0x1801 +#define GL_STENCIL 0x1802 +#define GL_STENCIL_INDEX 0x1901 +#define GL_DEPTH_COMPONENT 0x1902 +#define GL_RED 0x1903 +#define GL_GREEN 0x1904 +#define GL_BLUE 0x1905 +#define GL_ALPHA 0x1906 +#define GL_RGB 0x1907 +#define GL_RGBA 0x1908 +#define GL_POINT 0x1B00 +#define GL_LINE 0x1B01 +#define GL_FILL 0x1B02 +#define GL_KEEP 0x1E00 +#define GL_REPLACE 0x1E01 +#define GL_INCR 0x1E02 +#define GL_DECR 0x1E03 +#define GL_VENDOR 0x1F00 +#define GL_RENDERER 0x1F01 +#define GL_VERSION 0x1F02 +#define GL_EXTENSIONS 0x1F03 +#define GL_NEAREST 0x2600 +#define GL_LINEAR 0x2601 +#define GL_NEAREST_MIPMAP_NEAREST 0x2700 +#define GL_LINEAR_MIPMAP_NEAREST 0x2701 +#define GL_NEAREST_MIPMAP_LINEAR 0x2702 +#define GL_LINEAR_MIPMAP_LINEAR 0x2703 +#define GL_TEXTURE_MAG_FILTER 0x2800 +#define GL_TEXTURE_MIN_FILTER 0x2801 +#define GL_TEXTURE_WRAP_S 0x2802 +#define GL_TEXTURE_WRAP_T 0x2803 +#define GL_PROXY_TEXTURE_1D 0x8063 +#define GL_PROXY_TEXTURE_2D 0x8064 +#define GL_REPEAT 0x2901 +#define GL_R3_G3_B2 0x2A10 +#define GL_RGB4 0x804F +#define GL_RGB5 0x8050 +#define GL_RGB8 0x8051 +#define GL_RGB10 0x8052 +#define GL_RGB12 0x8053 +#define GL_RGB16 0x8054 +#define GL_RGBA2 0x8055 +#define GL_RGBA4 0x8056 +#define GL_RGB5_A1 0x8057 +#define GL_RGBA8 0x8058 +#define GL_RGB10_A2 0x8059 +#define GL_RGBA12 0x805A +#define GL_RGBA16 0x805B +#define GL_UNSIGNED_BYTE_3_3_2 0x8032 +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_INT_8_8_8_8 0x8035 +#define GL_UNSIGNED_INT_10_10_10_2 0x8036 +#define GL_TEXTURE_BINDING_3D 0x806A +#define GL_PACK_SKIP_IMAGES 0x806B +#define GL_PACK_IMAGE_HEIGHT 0x806C +#define GL_UNPACK_SKIP_IMAGES 0x806D +#define GL_UNPACK_IMAGE_HEIGHT 0x806E +#define GL_TEXTURE_3D 0x806F +#define GL_PROXY_TEXTURE_3D 0x8070 +#define GL_TEXTURE_DEPTH 0x8071 +#define GL_TEXTURE_WRAP_R 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE 0x8073 +#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 +#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_BGR 0x80E0 +#define GL_BGRA 0x80E1 +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_ELEMENTS_INDICES 0x80E9 +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_TEXTURE_MIN_LOD 0x813A +#define GL_TEXTURE_MAX_LOD 0x813B +#define GL_TEXTURE_BASE_LEVEL 0x813C +#define GL_TEXTURE_MAX_LEVEL 0x813D +#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 +#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 +#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_ACTIVE_TEXTURE 0x84E0 +#define GL_MULTISAMPLE 0x809D +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE 0x809F +#define GL_SAMPLE_COVERAGE 0x80A0 +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C +#define GL_COMPRESSED_RGB 0x84ED +#define GL_COMPRESSED_RGBA 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT 0x84EF +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 +#define GL_TEXTURE_COMPRESSED 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 +#define GL_CLAMP_TO_BORDER 0x812D +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_SRC_ALPHA 0x80CB +#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_DEPTH_COMPONENT24 0x81A6 +#define GL_DEPTH_COMPONENT32 0x81A7 +#define GL_MIRRORED_REPEAT 0x8370 +#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD +#define GL_TEXTURE_LOD_BIAS 0x8501 +#define GL_INCR_WRAP 0x8507 +#define GL_DECR_WRAP 0x8508 +#define GL_TEXTURE_DEPTH_SIZE 0x884A +#define GL_TEXTURE_COMPARE_MODE 0x884C +#define GL_TEXTURE_COMPARE_FUNC 0x884D +#define GL_FUNC_ADD 0x8006 +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#define GL_MIN 0x8007 +#define GL_MAX 0x8008 +#define GL_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_USAGE 0x8765 +#define GL_QUERY_COUNTER_BITS 0x8864 +#define GL_CURRENT_QUERY 0x8865 +#define GL_QUERY_RESULT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE 0x8867 +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F +#define GL_READ_ONLY 0x88B8 +#define GL_WRITE_ONLY 0x88B9 +#define GL_READ_WRITE 0x88BA +#define GL_BUFFER_ACCESS 0x88BB +#define GL_BUFFER_MAPPED 0x88BC +#define GL_BUFFER_MAP_POINTER 0x88BD +#define GL_STREAM_DRAW 0x88E0 +#define GL_STREAM_READ 0x88E1 +#define GL_STREAM_COPY 0x88E2 +#define GL_STATIC_DRAW 0x88E4 +#define GL_STATIC_READ 0x88E5 +#define GL_STATIC_COPY 0x88E6 +#define GL_DYNAMIC_DRAW 0x88E8 +#define GL_DYNAMIC_READ 0x88E9 +#define GL_DYNAMIC_COPY 0x88EA +#define GL_SAMPLES_PASSED 0x8914 +#define GL_SRC1_ALPHA 0x8589 +#define GL_BLEND_EQUATION_RGB 0x8009 +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 +#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_STENCIL_BACK_FUNC 0x8800 +#define GL_STENCIL_BACK_FAIL 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 +#define GL_MAX_DRAW_BUFFERS 0x8824 +#define GL_DRAW_BUFFER0 0x8825 +#define GL_DRAW_BUFFER1 0x8826 +#define GL_DRAW_BUFFER2 0x8827 +#define GL_DRAW_BUFFER3 0x8828 +#define GL_DRAW_BUFFER4 0x8829 +#define GL_DRAW_BUFFER5 0x882A +#define GL_DRAW_BUFFER6 0x882B +#define GL_DRAW_BUFFER7 0x882C +#define GL_DRAW_BUFFER8 0x882D +#define GL_DRAW_BUFFER9 0x882E +#define GL_DRAW_BUFFER10 0x882F +#define GL_DRAW_BUFFER11 0x8830 +#define GL_DRAW_BUFFER12 0x8831 +#define GL_DRAW_BUFFER13 0x8832 +#define GL_DRAW_BUFFER14 0x8833 +#define GL_DRAW_BUFFER15 0x8834 +#define GL_BLEND_EQUATION_ALPHA 0x883D +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A +#define GL_MAX_VARYING_FLOATS 0x8B4B +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_SHADER_TYPE 0x8B4F +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_BOOL 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT4 0x8B5C +#define GL_SAMPLER_1D 0x8B5D +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_3D 0x8B5F +#define GL_SAMPLER_CUBE 0x8B60 +#define GL_SAMPLER_1D_SHADOW 0x8B61 +#define GL_SAMPLER_2D_SHADOW 0x8B62 +#define GL_DELETE_STATUS 0x8B80 +#define GL_COMPILE_STATUS 0x8B81 +#define GL_LINK_STATUS 0x8B82 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_CURRENT_PROGRAM 0x8B8D +#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 +#define GL_LOWER_LEFT 0x8CA1 +#define GL_UPPER_LEFT 0x8CA2 +#define GL_STENCIL_BACK_REF 0x8CA3 +#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 +#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 +#define GL_PIXEL_PACK_BUFFER 0x88EB +#define GL_PIXEL_UNPACK_BUFFER 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF +#define GL_FLOAT_MAT2x3 0x8B65 +#define GL_FLOAT_MAT2x4 0x8B66 +#define GL_FLOAT_MAT3x2 0x8B67 +#define GL_FLOAT_MAT3x4 0x8B68 +#define GL_FLOAT_MAT4x2 0x8B69 +#define GL_FLOAT_MAT4x3 0x8B6A +#define GL_SRGB 0x8C40 +#define GL_SRGB8 0x8C41 +#define GL_SRGB_ALPHA 0x8C42 +#define GL_SRGB8_ALPHA8 0x8C43 +#define GL_COMPRESSED_SRGB 0x8C48 +#define GL_COMPRESSED_SRGB_ALPHA 0x8C49 +#define GL_COMPARE_REF_TO_TEXTURE 0x884E +#define GL_CLIP_DISTANCE0 0x3000 +#define GL_CLIP_DISTANCE1 0x3001 +#define GL_CLIP_DISTANCE2 0x3002 +#define GL_CLIP_DISTANCE3 0x3003 +#define GL_CLIP_DISTANCE4 0x3004 +#define GL_CLIP_DISTANCE5 0x3005 +#define GL_CLIP_DISTANCE6 0x3006 +#define GL_CLIP_DISTANCE7 0x3007 +#define GL_MAX_CLIP_DISTANCES 0x0D32 +#define GL_MAJOR_VERSION 0x821B +#define GL_MINOR_VERSION 0x821C +#define GL_NUM_EXTENSIONS 0x821D +#define GL_CONTEXT_FLAGS 0x821E +#define GL_COMPRESSED_RED 0x8225 +#define GL_COMPRESSED_RG 0x8226 +#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x00000001 +#define GL_RGBA32F 0x8814 +#define GL_RGB32F 0x8815 +#define GL_RGBA16F 0x881A +#define GL_RGB16F 0x881B +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD +#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF +#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 +#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 +#define GL_CLAMP_READ_COLOR 0x891C +#define GL_FIXED_ONLY 0x891D +#define GL_MAX_VARYING_COMPONENTS 0x8B4B +#define GL_TEXTURE_1D_ARRAY 0x8C18 +#define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19 +#define GL_TEXTURE_2D_ARRAY 0x8C1A +#define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B +#define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C +#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D +#define GL_R11F_G11F_B10F 0x8C3A +#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B +#define GL_RGB9_E5 0x8C3D +#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E +#define GL_TEXTURE_SHARED_SIZE 0x8C3F +#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 +#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 +#define GL_PRIMITIVES_GENERATED 0x8C87 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 +#define GL_RASTERIZER_DISCARD 0x8C89 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B +#define GL_INTERLEAVED_ATTRIBS 0x8C8C +#define GL_SEPARATE_ATTRIBS 0x8C8D +#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F +#define GL_RGBA32UI 0x8D70 +#define GL_RGB32UI 0x8D71 +#define GL_RGBA16UI 0x8D76 +#define GL_RGB16UI 0x8D77 +#define GL_RGBA8UI 0x8D7C +#define GL_RGB8UI 0x8D7D +#define GL_RGBA32I 0x8D82 +#define GL_RGB32I 0x8D83 +#define GL_RGBA16I 0x8D88 +#define GL_RGB16I 0x8D89 +#define GL_RGBA8I 0x8D8E +#define GL_RGB8I 0x8D8F +#define GL_RED_INTEGER 0x8D94 +#define GL_GREEN_INTEGER 0x8D95 +#define GL_BLUE_INTEGER 0x8D96 +#define GL_RGB_INTEGER 0x8D98 +#define GL_RGBA_INTEGER 0x8D99 +#define GL_BGR_INTEGER 0x8D9A +#define GL_BGRA_INTEGER 0x8D9B +#define GL_SAMPLER_1D_ARRAY 0x8DC0 +#define GL_SAMPLER_2D_ARRAY 0x8DC1 +#define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3 +#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 +#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 +#define GL_UNSIGNED_INT_VEC2 0x8DC6 +#define GL_UNSIGNED_INT_VEC3 0x8DC7 +#define GL_UNSIGNED_INT_VEC4 0x8DC8 +#define GL_INT_SAMPLER_1D 0x8DC9 +#define GL_INT_SAMPLER_2D 0x8DCA +#define GL_INT_SAMPLER_3D 0x8DCB +#define GL_INT_SAMPLER_CUBE 0x8DCC +#define GL_INT_SAMPLER_1D_ARRAY 0x8DCE +#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF +#define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1 +#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 +#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 +#define GL_QUERY_WAIT 0x8E13 +#define GL_QUERY_NO_WAIT 0x8E14 +#define GL_QUERY_BY_REGION_WAIT 0x8E15 +#define GL_QUERY_BY_REGION_NO_WAIT 0x8E16 +#define GL_BUFFER_ACCESS_FLAGS 0x911F +#define GL_BUFFER_MAP_LENGTH 0x9120 +#define GL_BUFFER_MAP_OFFSET 0x9121 +#define GL_DEPTH_COMPONENT32F 0x8CAC +#define GL_DEPTH32F_STENCIL8 0x8CAD +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD +#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 +#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 +#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 +#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 +#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 +#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 +#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 +#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 +#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 +#define GL_FRAMEBUFFER_DEFAULT 0x8218 +#define GL_FRAMEBUFFER_UNDEFINED 0x8219 +#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A +#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 +#define GL_DEPTH_STENCIL 0x84F9 +#define GL_UNSIGNED_INT_24_8 0x84FA +#define GL_DEPTH24_STENCIL8 0x88F0 +#define GL_TEXTURE_STENCIL_SIZE 0x88F1 +#define GL_TEXTURE_RED_TYPE 0x8C10 +#define GL_TEXTURE_GREEN_TYPE 0x8C11 +#define GL_TEXTURE_BLUE_TYPE 0x8C12 +#define GL_TEXTURE_ALPHA_TYPE 0x8C13 +#define GL_TEXTURE_DEPTH_TYPE 0x8C16 +#define GL_UNSIGNED_NORMALIZED 0x8C17 +#define GL_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_RENDERBUFFER_BINDING 0x8CA7 +#define GL_READ_FRAMEBUFFER 0x8CA8 +#define GL_DRAW_FRAMEBUFFER 0x8CA9 +#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA +#define GL_RENDERBUFFER_SAMPLES 0x8CAB +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 +#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC +#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD +#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF +#define GL_COLOR_ATTACHMENT0 0x8CE0 +#define GL_COLOR_ATTACHMENT1 0x8CE1 +#define GL_COLOR_ATTACHMENT2 0x8CE2 +#define GL_COLOR_ATTACHMENT3 0x8CE3 +#define GL_COLOR_ATTACHMENT4 0x8CE4 +#define GL_COLOR_ATTACHMENT5 0x8CE5 +#define GL_COLOR_ATTACHMENT6 0x8CE6 +#define GL_COLOR_ATTACHMENT7 0x8CE7 +#define GL_COLOR_ATTACHMENT8 0x8CE8 +#define GL_COLOR_ATTACHMENT9 0x8CE9 +#define GL_COLOR_ATTACHMENT10 0x8CEA +#define GL_COLOR_ATTACHMENT11 0x8CEB +#define GL_COLOR_ATTACHMENT12 0x8CEC +#define GL_COLOR_ATTACHMENT13 0x8CED +#define GL_COLOR_ATTACHMENT14 0x8CEE +#define GL_COLOR_ATTACHMENT15 0x8CEF +#define GL_DEPTH_ATTACHMENT 0x8D00 +#define GL_STENCIL_ATTACHMENT 0x8D20 +#define GL_FRAMEBUFFER 0x8D40 +#define GL_RENDERBUFFER 0x8D41 +#define GL_RENDERBUFFER_WIDTH 0x8D42 +#define GL_RENDERBUFFER_HEIGHT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 +#define GL_STENCIL_INDEX1 0x8D46 +#define GL_STENCIL_INDEX4 0x8D47 +#define GL_STENCIL_INDEX8 0x8D48 +#define GL_STENCIL_INDEX16 0x8D49 +#define GL_RENDERBUFFER_RED_SIZE 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 +#define GL_MAX_SAMPLES 0x8D57 +#define GL_INDEX 0x8222 +#define GL_FRAMEBUFFER_SRGB 0x8DB9 +#define GL_HALF_FLOAT 0x140B +#define GL_MAP_READ_BIT 0x0001 +#define GL_MAP_WRITE_BIT 0x0002 +#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 +#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 +#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 +#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 +#define GL_COMPRESSED_RED_RGTC1 0x8DBB +#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC +#define GL_COMPRESSED_RG_RGTC2 0x8DBD +#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE +#define GL_RG 0x8227 +#define GL_RG_INTEGER 0x8228 +#define GL_R8 0x8229 +#define GL_R16 0x822A +#define GL_RG8 0x822B +#define GL_RG16 0x822C +#define GL_R16F 0x822D +#define GL_R32F 0x822E +#define GL_RG16F 0x822F +#define GL_RG32F 0x8230 +#define GL_R8I 0x8231 +#define GL_R8UI 0x8232 +#define GL_R16I 0x8233 +#define GL_R16UI 0x8234 +#define GL_R32I 0x8235 +#define GL_R32UI 0x8236 +#define GL_RG8I 0x8237 +#define GL_RG8UI 0x8238 +#define GL_RG16I 0x8239 +#define GL_RG16UI 0x823A +#define GL_RG32I 0x823B +#define GL_RG32UI 0x823C +#define GL_VERTEX_ARRAY_BINDING 0x85B5 +#define GL_SAMPLER_2D_RECT 0x8B63 +#define GL_SAMPLER_2D_RECT_SHADOW 0x8B64 +#define GL_SAMPLER_BUFFER 0x8DC2 +#define GL_INT_SAMPLER_2D_RECT 0x8DCD +#define GL_INT_SAMPLER_BUFFER 0x8DD0 +#define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8 +#define GL_TEXTURE_BUFFER 0x8C2A +#define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B +#define GL_TEXTURE_BINDING_BUFFER 0x8C2C +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D +#define GL_TEXTURE_RECTANGLE 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8 +#define GL_R8_SNORM 0x8F94 +#define GL_RG8_SNORM 0x8F95 +#define GL_RGB8_SNORM 0x8F96 +#define GL_RGBA8_SNORM 0x8F97 +#define GL_R16_SNORM 0x8F98 +#define GL_RG16_SNORM 0x8F99 +#define GL_RGB16_SNORM 0x8F9A +#define GL_RGBA16_SNORM 0x8F9B +#define GL_SIGNED_NORMALIZED 0x8F9C +#define GL_PRIMITIVE_RESTART 0x8F9D +#define GL_PRIMITIVE_RESTART_INDEX 0x8F9E +#define GL_COPY_READ_BUFFER 0x8F36 +#define GL_COPY_WRITE_BUFFER 0x8F37 +#define GL_UNIFORM_BUFFER 0x8A11 +#define GL_UNIFORM_BUFFER_BINDING 0x8A28 +#define GL_UNIFORM_BUFFER_START 0x8A29 +#define GL_UNIFORM_BUFFER_SIZE 0x8A2A +#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B +#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D +#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E +#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F +#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 +#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 +#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 +#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34 +#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35 +#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 +#define GL_UNIFORM_TYPE 0x8A37 +#define GL_UNIFORM_SIZE 0x8A38 +#define GL_UNIFORM_NAME_LENGTH 0x8A39 +#define GL_UNIFORM_BLOCK_INDEX 0x8A3A +#define GL_UNIFORM_OFFSET 0x8A3B +#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C +#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D +#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E +#define GL_UNIFORM_BLOCK_BINDING 0x8A3F +#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 +#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 +#define GL_INVALID_INDEX 0xFFFFFFFF +#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001 +#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002 +#define GL_LINES_ADJACENCY 0x000A +#define GL_LINE_STRIP_ADJACENCY 0x000B +#define GL_TRIANGLES_ADJACENCY 0x000C +#define GL_TRIANGLE_STRIP_ADJACENCY 0x000D +#define GL_PROGRAM_POINT_SIZE 0x8642 +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8 +#define GL_GEOMETRY_SHADER 0x8DD9 +#define GL_GEOMETRY_VERTICES_OUT 0x8916 +#define GL_GEOMETRY_INPUT_TYPE 0x8917 +#define GL_GEOMETRY_OUTPUT_TYPE 0x8918 +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1 +#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 +#define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123 +#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124 +#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 +#define GL_CONTEXT_PROFILE_MASK 0x9126 +#define GL_DEPTH_CLAMP 0x864F +#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C +#define GL_FIRST_VERTEX_CONVENTION 0x8E4D +#define GL_LAST_VERTEX_CONVENTION 0x8E4E +#define GL_PROVOKING_VERTEX 0x8E4F +#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F +#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111 +#define GL_OBJECT_TYPE 0x9112 +#define GL_SYNC_CONDITION 0x9113 +#define GL_SYNC_STATUS 0x9114 +#define GL_SYNC_FLAGS 0x9115 +#define GL_SYNC_FENCE 0x9116 +#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 +#define GL_UNSIGNALED 0x9118 +#define GL_SIGNALED 0x9119 +#define GL_ALREADY_SIGNALED 0x911A +#define GL_TIMEOUT_EXPIRED 0x911B +#define GL_CONDITION_SATISFIED 0x911C +#define GL_WAIT_FAILED 0x911D +#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFF +#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 +#define GL_SAMPLE_POSITION 0x8E50 +#define GL_SAMPLE_MASK 0x8E51 +#define GL_SAMPLE_MASK_VALUE 0x8E52 +#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59 +#define GL_TEXTURE_2D_MULTISAMPLE 0x9100 +#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101 +#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102 +#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105 +#define GL_TEXTURE_SAMPLES 0x9106 +#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107 +#define GL_SAMPLER_2D_MULTISAMPLE 0x9108 +#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A +#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B +#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D +#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E +#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F +#define GL_MAX_INTEGER_SAMPLES 0x9110 +#ifndef GL_VERSION_1_0 +#define GL_VERSION_1_0 1 +GLAPI int GLAD_GL_VERSION_1_0; +typedef void (APIENTRYP PFNGLCULLFACEPROC)(GLenum); +GLAPI PFNGLCULLFACEPROC glad_glCullFace; +#define glCullFace glad_glCullFace +typedef void (APIENTRYP PFNGLFRONTFACEPROC)(GLenum); +GLAPI PFNGLFRONTFACEPROC glad_glFrontFace; +#define glFrontFace glad_glFrontFace +typedef void (APIENTRYP PFNGLHINTPROC)(GLenum, GLenum); +GLAPI PFNGLHINTPROC glad_glHint; +#define glHint glad_glHint +typedef void (APIENTRYP PFNGLLINEWIDTHPROC)(GLfloat); +GLAPI PFNGLLINEWIDTHPROC glad_glLineWidth; +#define glLineWidth glad_glLineWidth +typedef void (APIENTRYP PFNGLPOINTSIZEPROC)(GLfloat); +GLAPI PFNGLPOINTSIZEPROC glad_glPointSize; +#define glPointSize glad_glPointSize +typedef void (APIENTRYP PFNGLPOLYGONMODEPROC)(GLenum, GLenum); +GLAPI PFNGLPOLYGONMODEPROC glad_glPolygonMode; +#define glPolygonMode glad_glPolygonMode +typedef void (APIENTRYP PFNGLSCISSORPROC)(GLint, GLint, GLsizei, GLsizei); +GLAPI PFNGLSCISSORPROC glad_glScissor; +#define glScissor glad_glScissor +typedef void (APIENTRYP PFNGLTEXPARAMETERFPROC)(GLenum, GLenum, GLfloat); +GLAPI PFNGLTEXPARAMETERFPROC glad_glTexParameterf; +#define glTexParameterf glad_glTexParameterf +typedef void (APIENTRYP PFNGLTEXPARAMETERFVPROC)(GLenum, GLenum, const GLfloat*); +GLAPI PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv; +#define glTexParameterfv glad_glTexParameterfv +typedef void (APIENTRYP PFNGLTEXPARAMETERIPROC)(GLenum, GLenum, GLint); +GLAPI PFNGLTEXPARAMETERIPROC glad_glTexParameteri; +#define glTexParameteri glad_glTexParameteri +typedef void (APIENTRYP PFNGLTEXPARAMETERIVPROC)(GLenum, GLenum, const GLint*); +GLAPI PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv; +#define glTexParameteriv glad_glTexParameteriv +typedef void (APIENTRYP PFNGLTEXIMAGE1DPROC)(GLenum, GLint, GLint, GLsizei, GLint, GLenum, GLenum, const void*); +GLAPI PFNGLTEXIMAGE1DPROC glad_glTexImage1D; +#define glTexImage1D glad_glTexImage1D +typedef void (APIENTRYP PFNGLTEXIMAGE2DPROC)(GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const void*); +GLAPI PFNGLTEXIMAGE2DPROC glad_glTexImage2D; +#define glTexImage2D glad_glTexImage2D +typedef void (APIENTRYP PFNGLDRAWBUFFERPROC)(GLenum); +GLAPI PFNGLDRAWBUFFERPROC glad_glDrawBuffer; +#define glDrawBuffer glad_glDrawBuffer +typedef void (APIENTRYP PFNGLCLEARPROC)(GLbitfield); +GLAPI PFNGLCLEARPROC glad_glClear; +#define glClear glad_glClear +typedef void (APIENTRYP PFNGLCLEARCOLORPROC)(GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI PFNGLCLEARCOLORPROC glad_glClearColor; +#define glClearColor glad_glClearColor +typedef void (APIENTRYP PFNGLCLEARSTENCILPROC)(GLint); +GLAPI PFNGLCLEARSTENCILPROC glad_glClearStencil; +#define glClearStencil glad_glClearStencil +typedef void (APIENTRYP PFNGLCLEARDEPTHPROC)(GLdouble); +GLAPI PFNGLCLEARDEPTHPROC glad_glClearDepth; +#define glClearDepth glad_glClearDepth +typedef void (APIENTRYP PFNGLSTENCILMASKPROC)(GLuint); +GLAPI PFNGLSTENCILMASKPROC glad_glStencilMask; +#define glStencilMask glad_glStencilMask +typedef void (APIENTRYP PFNGLCOLORMASKPROC)(GLboolean, GLboolean, GLboolean, GLboolean); +GLAPI PFNGLCOLORMASKPROC glad_glColorMask; +#define glColorMask glad_glColorMask +typedef void (APIENTRYP PFNGLDEPTHMASKPROC)(GLboolean); +GLAPI PFNGLDEPTHMASKPROC glad_glDepthMask; +#define glDepthMask glad_glDepthMask +typedef void (APIENTRYP PFNGLDISABLEPROC)(GLenum); +GLAPI PFNGLDISABLEPROC glad_glDisable; +#define glDisable glad_glDisable +typedef void (APIENTRYP PFNGLENABLEPROC)(GLenum); +GLAPI PFNGLENABLEPROC glad_glEnable; +#define glEnable glad_glEnable +typedef void (APIENTRYP PFNGLFINISHPROC)(); +GLAPI PFNGLFINISHPROC glad_glFinish; +#define glFinish glad_glFinish +typedef void (APIENTRYP PFNGLFLUSHPROC)(); +GLAPI PFNGLFLUSHPROC glad_glFlush; +#define glFlush glad_glFlush +typedef void (APIENTRYP PFNGLBLENDFUNCPROC)(GLenum, GLenum); +GLAPI PFNGLBLENDFUNCPROC glad_glBlendFunc; +#define glBlendFunc glad_glBlendFunc +typedef void (APIENTRYP PFNGLLOGICOPPROC)(GLenum); +GLAPI PFNGLLOGICOPPROC glad_glLogicOp; +#define glLogicOp glad_glLogicOp +typedef void (APIENTRYP PFNGLSTENCILFUNCPROC)(GLenum, GLint, GLuint); +GLAPI PFNGLSTENCILFUNCPROC glad_glStencilFunc; +#define glStencilFunc glad_glStencilFunc +typedef void (APIENTRYP PFNGLSTENCILOPPROC)(GLenum, GLenum, GLenum); +GLAPI PFNGLSTENCILOPPROC glad_glStencilOp; +#define glStencilOp glad_glStencilOp +typedef void (APIENTRYP PFNGLDEPTHFUNCPROC)(GLenum); +GLAPI PFNGLDEPTHFUNCPROC glad_glDepthFunc; +#define glDepthFunc glad_glDepthFunc +typedef void (APIENTRYP PFNGLPIXELSTOREFPROC)(GLenum, GLfloat); +GLAPI PFNGLPIXELSTOREFPROC glad_glPixelStoref; +#define glPixelStoref glad_glPixelStoref +typedef void (APIENTRYP PFNGLPIXELSTOREIPROC)(GLenum, GLint); +GLAPI PFNGLPIXELSTOREIPROC glad_glPixelStorei; +#define glPixelStorei glad_glPixelStorei +typedef void (APIENTRYP PFNGLREADBUFFERPROC)(GLenum); +GLAPI PFNGLREADBUFFERPROC glad_glReadBuffer; +#define glReadBuffer glad_glReadBuffer +typedef void (APIENTRYP PFNGLREADPIXELSPROC)(GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, void*); +GLAPI PFNGLREADPIXELSPROC glad_glReadPixels; +#define glReadPixels glad_glReadPixels +typedef void (APIENTRYP PFNGLGETBOOLEANVPROC)(GLenum, GLboolean*); +GLAPI PFNGLGETBOOLEANVPROC glad_glGetBooleanv; +#define glGetBooleanv glad_glGetBooleanv +typedef void (APIENTRYP PFNGLGETDOUBLEVPROC)(GLenum, GLdouble*); +GLAPI PFNGLGETDOUBLEVPROC glad_glGetDoublev; +#define glGetDoublev glad_glGetDoublev +typedef GLenum (APIENTRYP PFNGLGETERRORPROC)(); +GLAPI PFNGLGETERRORPROC glad_glGetError; +#define glGetError glad_glGetError +typedef void (APIENTRYP PFNGLGETFLOATVPROC)(GLenum, GLfloat*); +GLAPI PFNGLGETFLOATVPROC glad_glGetFloatv; +#define glGetFloatv glad_glGetFloatv +typedef void (APIENTRYP PFNGLGETINTEGERVPROC)(GLenum, GLint*); +GLAPI PFNGLGETINTEGERVPROC glad_glGetIntegerv; +#define glGetIntegerv glad_glGetIntegerv +typedef const GLubyte* (APIENTRYP PFNGLGETSTRINGPROC)(GLenum); +GLAPI PFNGLGETSTRINGPROC glad_glGetString; +#define glGetString glad_glGetString +typedef void (APIENTRYP PFNGLGETTEXIMAGEPROC)(GLenum, GLint, GLenum, GLenum, void*); +GLAPI PFNGLGETTEXIMAGEPROC glad_glGetTexImage; +#define glGetTexImage glad_glGetTexImage +typedef void (APIENTRYP PFNGLGETTEXPARAMETERFVPROC)(GLenum, GLenum, GLfloat*); +GLAPI PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv; +#define glGetTexParameterfv glad_glGetTexParameterfv +typedef void (APIENTRYP PFNGLGETTEXPARAMETERIVPROC)(GLenum, GLenum, GLint*); +GLAPI PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv; +#define glGetTexParameteriv glad_glGetTexParameteriv +typedef void (APIENTRYP PFNGLGETTEXLEVELPARAMETERFVPROC)(GLenum, GLint, GLenum, GLfloat*); +GLAPI PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv; +#define glGetTexLevelParameterfv glad_glGetTexLevelParameterfv +typedef void (APIENTRYP PFNGLGETTEXLEVELPARAMETERIVPROC)(GLenum, GLint, GLenum, GLint*); +GLAPI PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv; +#define glGetTexLevelParameteriv glad_glGetTexLevelParameteriv +typedef GLboolean (APIENTRYP PFNGLISENABLEDPROC)(GLenum); +GLAPI PFNGLISENABLEDPROC glad_glIsEnabled; +#define glIsEnabled glad_glIsEnabled +typedef void (APIENTRYP PFNGLDEPTHRANGEPROC)(GLdouble, GLdouble); +GLAPI PFNGLDEPTHRANGEPROC glad_glDepthRange; +#define glDepthRange glad_glDepthRange +typedef void (APIENTRYP PFNGLVIEWPORTPROC)(GLint, GLint, GLsizei, GLsizei); +GLAPI PFNGLVIEWPORTPROC glad_glViewport; +#define glViewport glad_glViewport +#endif +#ifndef GL_VERSION_1_1 +#define GL_VERSION_1_1 1 +GLAPI int GLAD_GL_VERSION_1_1; +typedef void (APIENTRYP PFNGLDRAWARRAYSPROC)(GLenum, GLint, GLsizei); +GLAPI PFNGLDRAWARRAYSPROC glad_glDrawArrays; +#define glDrawArrays glad_glDrawArrays +typedef void (APIENTRYP PFNGLDRAWELEMENTSPROC)(GLenum, GLsizei, GLenum, const void*); +GLAPI PFNGLDRAWELEMENTSPROC glad_glDrawElements; +#define glDrawElements glad_glDrawElements +typedef void (APIENTRYP PFNGLPOLYGONOFFSETPROC)(GLfloat, GLfloat); +GLAPI PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset; +#define glPolygonOffset glad_glPolygonOffset +typedef void (APIENTRYP PFNGLCOPYTEXIMAGE1DPROC)(GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLint); +GLAPI PFNGLCOPYTEXIMAGE1DPROC glad_glCopyTexImage1D; +#define glCopyTexImage1D glad_glCopyTexImage1D +typedef void (APIENTRYP PFNGLCOPYTEXIMAGE2DPROC)(GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint); +GLAPI PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D; +#define glCopyTexImage2D glad_glCopyTexImage2D +typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE1DPROC)(GLenum, GLint, GLint, GLint, GLint, GLsizei); +GLAPI PFNGLCOPYTEXSUBIMAGE1DPROC glad_glCopyTexSubImage1D; +#define glCopyTexSubImage1D glad_glCopyTexSubImage1D +typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE2DPROC)(GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); +GLAPI PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D; +#define glCopyTexSubImage2D glad_glCopyTexSubImage2D +typedef void (APIENTRYP PFNGLTEXSUBIMAGE1DPROC)(GLenum, GLint, GLint, GLsizei, GLenum, GLenum, const void*); +GLAPI PFNGLTEXSUBIMAGE1DPROC glad_glTexSubImage1D; +#define glTexSubImage1D glad_glTexSubImage1D +typedef void (APIENTRYP PFNGLTEXSUBIMAGE2DPROC)(GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const void*); +GLAPI PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D; +#define glTexSubImage2D glad_glTexSubImage2D +typedef void (APIENTRYP PFNGLBINDTEXTUREPROC)(GLenum, GLuint); +GLAPI PFNGLBINDTEXTUREPROC glad_glBindTexture; +#define glBindTexture glad_glBindTexture +typedef void (APIENTRYP PFNGLDELETETEXTURESPROC)(GLsizei, const GLuint*); +GLAPI PFNGLDELETETEXTURESPROC glad_glDeleteTextures; +#define glDeleteTextures glad_glDeleteTextures +typedef void (APIENTRYP PFNGLGENTEXTURESPROC)(GLsizei, GLuint*); +GLAPI PFNGLGENTEXTURESPROC glad_glGenTextures; +#define glGenTextures glad_glGenTextures +typedef GLboolean (APIENTRYP PFNGLISTEXTUREPROC)(GLuint); +GLAPI PFNGLISTEXTUREPROC glad_glIsTexture; +#define glIsTexture glad_glIsTexture +#endif +#ifndef GL_VERSION_1_2 +#define GL_VERSION_1_2 1 +GLAPI int GLAD_GL_VERSION_1_2; +typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSPROC)(GLenum, GLuint, GLuint, GLsizei, GLenum, const void*); +GLAPI PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements; +#define glDrawRangeElements glad_glDrawRangeElements +typedef void (APIENTRYP PFNGLTEXIMAGE3DPROC)(GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const void*); +GLAPI PFNGLTEXIMAGE3DPROC glad_glTexImage3D; +#define glTexImage3D glad_glTexImage3D +typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DPROC)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const void*); +GLAPI PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D; +#define glTexSubImage3D glad_glTexSubImage3D +typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DPROC)(GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); +GLAPI PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D; +#define glCopyTexSubImage3D glad_glCopyTexSubImage3D +#endif +#ifndef GL_VERSION_1_3 +#define GL_VERSION_1_3 1 +GLAPI int GLAD_GL_VERSION_1_3; +typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC)(GLenum); +GLAPI PFNGLACTIVETEXTUREPROC glad_glActiveTexture; +#define glActiveTexture glad_glActiveTexture +typedef void (APIENTRYP PFNGLSAMPLECOVERAGEPROC)(GLfloat, GLboolean); +GLAPI PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage; +#define glSampleCoverage glad_glSampleCoverage +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const void*); +GLAPI PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D; +#define glCompressedTexImage3D glad_glCompressedTexImage3D +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const void*); +GLAPI PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D; +#define glCompressedTexImage2D glad_glCompressedTexImage2D +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DPROC)(GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const void*); +GLAPI PFNGLCOMPRESSEDTEXIMAGE1DPROC glad_glCompressedTexImage1D; +#define glCompressedTexImage1D glad_glCompressedTexImage1D +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const void*); +GLAPI PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D; +#define glCompressedTexSubImage3D glad_glCompressedTexSubImage3D +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)(GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const void*); +GLAPI PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D; +#define glCompressedTexSubImage2D glad_glCompressedTexSubImage2D +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)(GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const void*); +GLAPI PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glad_glCompressedTexSubImage1D; +#define glCompressedTexSubImage1D glad_glCompressedTexSubImage1D +typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC)(GLenum, GLint, void*); +GLAPI PFNGLGETCOMPRESSEDTEXIMAGEPROC glad_glGetCompressedTexImage; +#define glGetCompressedTexImage glad_glGetCompressedTexImage +#endif +#ifndef GL_VERSION_1_4 +#define GL_VERSION_1_4 1 +GLAPI int GLAD_GL_VERSION_1_4; +typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC)(GLenum, GLenum, GLenum, GLenum); +GLAPI PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate; +#define glBlendFuncSeparate glad_glBlendFuncSeparate +typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSPROC)(GLenum, const GLint*, const GLsizei*, GLsizei); +GLAPI PFNGLMULTIDRAWARRAYSPROC glad_glMultiDrawArrays; +#define glMultiDrawArrays glad_glMultiDrawArrays +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSPROC)(GLenum, const GLsizei*, GLenum, const void**, GLsizei); +GLAPI PFNGLMULTIDRAWELEMENTSPROC glad_glMultiDrawElements; +#define glMultiDrawElements glad_glMultiDrawElements +typedef void (APIENTRYP PFNGLPOINTPARAMETERFPROC)(GLenum, GLfloat); +GLAPI PFNGLPOINTPARAMETERFPROC glad_glPointParameterf; +#define glPointParameterf glad_glPointParameterf +typedef void (APIENTRYP PFNGLPOINTPARAMETERFVPROC)(GLenum, const GLfloat*); +GLAPI PFNGLPOINTPARAMETERFVPROC glad_glPointParameterfv; +#define glPointParameterfv glad_glPointParameterfv +typedef void (APIENTRYP PFNGLPOINTPARAMETERIPROC)(GLenum, GLint); +GLAPI PFNGLPOINTPARAMETERIPROC glad_glPointParameteri; +#define glPointParameteri glad_glPointParameteri +typedef void (APIENTRYP PFNGLPOINTPARAMETERIVPROC)(GLenum, const GLint*); +GLAPI PFNGLPOINTPARAMETERIVPROC glad_glPointParameteriv; +#define glPointParameteriv glad_glPointParameteriv +typedef void (APIENTRYP PFNGLBLENDCOLORPROC)(GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI PFNGLBLENDCOLORPROC glad_glBlendColor; +#define glBlendColor glad_glBlendColor +typedef void (APIENTRYP PFNGLBLENDEQUATIONPROC)(GLenum); +GLAPI PFNGLBLENDEQUATIONPROC glad_glBlendEquation; +#define glBlendEquation glad_glBlendEquation +#endif +#ifndef GL_VERSION_1_5 +#define GL_VERSION_1_5 1 +GLAPI int GLAD_GL_VERSION_1_5; +typedef void (APIENTRYP PFNGLGENQUERIESPROC)(GLsizei, GLuint*); +GLAPI PFNGLGENQUERIESPROC glad_glGenQueries; +#define glGenQueries glad_glGenQueries +typedef void (APIENTRYP PFNGLDELETEQUERIESPROC)(GLsizei, const GLuint*); +GLAPI PFNGLDELETEQUERIESPROC glad_glDeleteQueries; +#define glDeleteQueries glad_glDeleteQueries +typedef GLboolean (APIENTRYP PFNGLISQUERYPROC)(GLuint); +GLAPI PFNGLISQUERYPROC glad_glIsQuery; +#define glIsQuery glad_glIsQuery +typedef void (APIENTRYP PFNGLBEGINQUERYPROC)(GLenum, GLuint); +GLAPI PFNGLBEGINQUERYPROC glad_glBeginQuery; +#define glBeginQuery glad_glBeginQuery +typedef void (APIENTRYP PFNGLENDQUERYPROC)(GLenum); +GLAPI PFNGLENDQUERYPROC glad_glEndQuery; +#define glEndQuery glad_glEndQuery +typedef void (APIENTRYP PFNGLGETQUERYIVPROC)(GLenum, GLenum, GLint*); +GLAPI PFNGLGETQUERYIVPROC glad_glGetQueryiv; +#define glGetQueryiv glad_glGetQueryiv +typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVPROC)(GLuint, GLenum, GLint*); +GLAPI PFNGLGETQUERYOBJECTIVPROC glad_glGetQueryObjectiv; +#define glGetQueryObjectiv glad_glGetQueryObjectiv +typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVPROC)(GLuint, GLenum, GLuint*); +GLAPI PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv; +#define glGetQueryObjectuiv glad_glGetQueryObjectuiv +typedef void (APIENTRYP PFNGLBINDBUFFERPROC)(GLenum, GLuint); +GLAPI PFNGLBINDBUFFERPROC glad_glBindBuffer; +#define glBindBuffer glad_glBindBuffer +typedef void (APIENTRYP PFNGLDELETEBUFFERSPROC)(GLsizei, const GLuint*); +GLAPI PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers; +#define glDeleteBuffers glad_glDeleteBuffers +typedef void (APIENTRYP PFNGLGENBUFFERSPROC)(GLsizei, GLuint*); +GLAPI PFNGLGENBUFFERSPROC glad_glGenBuffers; +#define glGenBuffers glad_glGenBuffers +typedef GLboolean (APIENTRYP PFNGLISBUFFERPROC)(GLuint); +GLAPI PFNGLISBUFFERPROC glad_glIsBuffer; +#define glIsBuffer glad_glIsBuffer +typedef void (APIENTRYP PFNGLBUFFERDATAPROC)(GLenum, GLsizeiptr, const void*, GLenum); +GLAPI PFNGLBUFFERDATAPROC glad_glBufferData; +#define glBufferData glad_glBufferData +typedef void (APIENTRYP PFNGLBUFFERSUBDATAPROC)(GLenum, GLintptr, GLsizeiptr, const void*); +GLAPI PFNGLBUFFERSUBDATAPROC glad_glBufferSubData; +#define glBufferSubData glad_glBufferSubData +typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAPROC)(GLenum, GLintptr, GLsizeiptr, void*); +GLAPI PFNGLGETBUFFERSUBDATAPROC glad_glGetBufferSubData; +#define glGetBufferSubData glad_glGetBufferSubData +typedef void* (APIENTRYP PFNGLMAPBUFFERPROC)(GLenum, GLenum); +GLAPI PFNGLMAPBUFFERPROC glad_glMapBuffer; +#define glMapBuffer glad_glMapBuffer +typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERPROC)(GLenum); +GLAPI PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer; +#define glUnmapBuffer glad_glUnmapBuffer +typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC)(GLenum, GLenum, GLint*); +GLAPI PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv; +#define glGetBufferParameteriv glad_glGetBufferParameteriv +typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVPROC)(GLenum, GLenum, void**); +GLAPI PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv; +#define glGetBufferPointerv glad_glGetBufferPointerv +#endif +#ifndef GL_VERSION_2_0 +#define GL_VERSION_2_0 1 +GLAPI int GLAD_GL_VERSION_2_0; +typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC)(GLenum, GLenum); +GLAPI PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate; +#define glBlendEquationSeparate glad_glBlendEquationSeparate +typedef void (APIENTRYP PFNGLDRAWBUFFERSPROC)(GLsizei, const GLenum*); +GLAPI PFNGLDRAWBUFFERSPROC glad_glDrawBuffers; +#define glDrawBuffers glad_glDrawBuffers +typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEPROC)(GLenum, GLenum, GLenum, GLenum); +GLAPI PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate; +#define glStencilOpSeparate glad_glStencilOpSeparate +typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC)(GLenum, GLenum, GLint, GLuint); +GLAPI PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate; +#define glStencilFuncSeparate glad_glStencilFuncSeparate +typedef void (APIENTRYP PFNGLSTENCILMASKSEPARATEPROC)(GLenum, GLuint); +GLAPI PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate; +#define glStencilMaskSeparate glad_glStencilMaskSeparate +typedef void (APIENTRYP PFNGLATTACHSHADERPROC)(GLuint, GLuint); +GLAPI PFNGLATTACHSHADERPROC glad_glAttachShader; +#define glAttachShader glad_glAttachShader +typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONPROC)(GLuint, GLuint, const GLchar*); +GLAPI PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation; +#define glBindAttribLocation glad_glBindAttribLocation +typedef void (APIENTRYP PFNGLCOMPILESHADERPROC)(GLuint); +GLAPI PFNGLCOMPILESHADERPROC glad_glCompileShader; +#define glCompileShader glad_glCompileShader +typedef GLuint (APIENTRYP PFNGLCREATEPROGRAMPROC)(); +GLAPI PFNGLCREATEPROGRAMPROC glad_glCreateProgram; +#define glCreateProgram glad_glCreateProgram +typedef GLuint (APIENTRYP PFNGLCREATESHADERPROC)(GLenum); +GLAPI PFNGLCREATESHADERPROC glad_glCreateShader; +#define glCreateShader glad_glCreateShader +typedef void (APIENTRYP PFNGLDELETEPROGRAMPROC)(GLuint); +GLAPI PFNGLDELETEPROGRAMPROC glad_glDeleteProgram; +#define glDeleteProgram glad_glDeleteProgram +typedef void (APIENTRYP PFNGLDELETESHADERPROC)(GLuint); +GLAPI PFNGLDELETESHADERPROC glad_glDeleteShader; +#define glDeleteShader glad_glDeleteShader +typedef void (APIENTRYP PFNGLDETACHSHADERPROC)(GLuint, GLuint); +GLAPI PFNGLDETACHSHADERPROC glad_glDetachShader; +#define glDetachShader glad_glDetachShader +typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC)(GLuint); +GLAPI PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray; +#define glDisableVertexAttribArray glad_glDisableVertexAttribArray +typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC)(GLuint); +GLAPI PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray; +#define glEnableVertexAttribArray glad_glEnableVertexAttribArray +typedef void (APIENTRYP PFNGLGETACTIVEATTRIBPROC)(GLuint, GLuint, GLsizei, GLsizei*, GLint*, GLenum*, GLchar*); +GLAPI PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib; +#define glGetActiveAttrib glad_glGetActiveAttrib +typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMPROC)(GLuint, GLuint, GLsizei, GLsizei*, GLint*, GLenum*, GLchar*); +GLAPI PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform; +#define glGetActiveUniform glad_glGetActiveUniform +typedef void (APIENTRYP PFNGLGETATTACHEDSHADERSPROC)(GLuint, GLsizei, GLsizei*, GLuint*); +GLAPI PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders; +#define glGetAttachedShaders glad_glGetAttachedShaders +typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONPROC)(GLuint, const GLchar*); +GLAPI PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation; +#define glGetAttribLocation glad_glGetAttribLocation +typedef void (APIENTRYP PFNGLGETPROGRAMIVPROC)(GLuint, GLenum, GLint*); +GLAPI PFNGLGETPROGRAMIVPROC glad_glGetProgramiv; +#define glGetProgramiv glad_glGetProgramiv +typedef void (APIENTRYP PFNGLGETPROGRAMINFOLOGPROC)(GLuint, GLsizei, GLsizei*, GLchar*); +GLAPI PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog; +#define glGetProgramInfoLog glad_glGetProgramInfoLog +typedef void (APIENTRYP PFNGLGETSHADERIVPROC)(GLuint, GLenum, GLint*); +GLAPI PFNGLGETSHADERIVPROC glad_glGetShaderiv; +#define glGetShaderiv glad_glGetShaderiv +typedef void (APIENTRYP PFNGLGETSHADERINFOLOGPROC)(GLuint, GLsizei, GLsizei*, GLchar*); +GLAPI PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog; +#define glGetShaderInfoLog glad_glGetShaderInfoLog +typedef void (APIENTRYP PFNGLGETSHADERSOURCEPROC)(GLuint, GLsizei, GLsizei*, GLchar*); +GLAPI PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource; +#define glGetShaderSource glad_glGetShaderSource +typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONPROC)(GLuint, const GLchar*); +GLAPI PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation; +#define glGetUniformLocation glad_glGetUniformLocation +typedef void (APIENTRYP PFNGLGETUNIFORMFVPROC)(GLuint, GLint, GLfloat*); +GLAPI PFNGLGETUNIFORMFVPROC glad_glGetUniformfv; +#define glGetUniformfv glad_glGetUniformfv +typedef void (APIENTRYP PFNGLGETUNIFORMIVPROC)(GLuint, GLint, GLint*); +GLAPI PFNGLGETUNIFORMIVPROC glad_glGetUniformiv; +#define glGetUniformiv glad_glGetUniformiv +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVPROC)(GLuint, GLenum, GLdouble*); +GLAPI PFNGLGETVERTEXATTRIBDVPROC glad_glGetVertexAttribdv; +#define glGetVertexAttribdv glad_glGetVertexAttribdv +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVPROC)(GLuint, GLenum, GLfloat*); +GLAPI PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv; +#define glGetVertexAttribfv glad_glGetVertexAttribfv +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVPROC)(GLuint, GLenum, GLint*); +GLAPI PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv; +#define glGetVertexAttribiv glad_glGetVertexAttribiv +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC)(GLuint, GLenum, void**); +GLAPI PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv; +#define glGetVertexAttribPointerv glad_glGetVertexAttribPointerv +typedef GLboolean (APIENTRYP PFNGLISPROGRAMPROC)(GLuint); +GLAPI PFNGLISPROGRAMPROC glad_glIsProgram; +#define glIsProgram glad_glIsProgram +typedef GLboolean (APIENTRYP PFNGLISSHADERPROC)(GLuint); +GLAPI PFNGLISSHADERPROC glad_glIsShader; +#define glIsShader glad_glIsShader +typedef void (APIENTRYP PFNGLLINKPROGRAMPROC)(GLuint); +GLAPI PFNGLLINKPROGRAMPROC glad_glLinkProgram; +#define glLinkProgram glad_glLinkProgram +typedef void (APIENTRYP PFNGLSHADERSOURCEPROC)(GLuint, GLsizei, const GLchar**, const GLint*); +GLAPI PFNGLSHADERSOURCEPROC glad_glShaderSource; +#define glShaderSource glad_glShaderSource +typedef void (APIENTRYP PFNGLUSEPROGRAMPROC)(GLuint); +GLAPI PFNGLUSEPROGRAMPROC glad_glUseProgram; +#define glUseProgram glad_glUseProgram +typedef void (APIENTRYP PFNGLUNIFORM1FPROC)(GLint, GLfloat); +GLAPI PFNGLUNIFORM1FPROC glad_glUniform1f; +#define glUniform1f glad_glUniform1f +typedef void (APIENTRYP PFNGLUNIFORM2FPROC)(GLint, GLfloat, GLfloat); +GLAPI PFNGLUNIFORM2FPROC glad_glUniform2f; +#define glUniform2f glad_glUniform2f +typedef void (APIENTRYP PFNGLUNIFORM3FPROC)(GLint, GLfloat, GLfloat, GLfloat); +GLAPI PFNGLUNIFORM3FPROC glad_glUniform3f; +#define glUniform3f glad_glUniform3f +typedef void (APIENTRYP PFNGLUNIFORM4FPROC)(GLint, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI PFNGLUNIFORM4FPROC glad_glUniform4f; +#define glUniform4f glad_glUniform4f +typedef void (APIENTRYP PFNGLUNIFORM1IPROC)(GLint, GLint); +GLAPI PFNGLUNIFORM1IPROC glad_glUniform1i; +#define glUniform1i glad_glUniform1i +typedef void (APIENTRYP PFNGLUNIFORM2IPROC)(GLint, GLint, GLint); +GLAPI PFNGLUNIFORM2IPROC glad_glUniform2i; +#define glUniform2i glad_glUniform2i +typedef void (APIENTRYP PFNGLUNIFORM3IPROC)(GLint, GLint, GLint, GLint); +GLAPI PFNGLUNIFORM3IPROC glad_glUniform3i; +#define glUniform3i glad_glUniform3i +typedef void (APIENTRYP PFNGLUNIFORM4IPROC)(GLint, GLint, GLint, GLint, GLint); +GLAPI PFNGLUNIFORM4IPROC glad_glUniform4i; +#define glUniform4i glad_glUniform4i +typedef void (APIENTRYP PFNGLUNIFORM1FVPROC)(GLint, GLsizei, const GLfloat*); +GLAPI PFNGLUNIFORM1FVPROC glad_glUniform1fv; +#define glUniform1fv glad_glUniform1fv +typedef void (APIENTRYP PFNGLUNIFORM2FVPROC)(GLint, GLsizei, const GLfloat*); +GLAPI PFNGLUNIFORM2FVPROC glad_glUniform2fv; +#define glUniform2fv glad_glUniform2fv +typedef void (APIENTRYP PFNGLUNIFORM3FVPROC)(GLint, GLsizei, const GLfloat*); +GLAPI PFNGLUNIFORM3FVPROC glad_glUniform3fv; +#define glUniform3fv glad_glUniform3fv +typedef void (APIENTRYP PFNGLUNIFORM4FVPROC)(GLint, GLsizei, const GLfloat*); +GLAPI PFNGLUNIFORM4FVPROC glad_glUniform4fv; +#define glUniform4fv glad_glUniform4fv +typedef void (APIENTRYP PFNGLUNIFORM1IVPROC)(GLint, GLsizei, const GLint*); +GLAPI PFNGLUNIFORM1IVPROC glad_glUniform1iv; +#define glUniform1iv glad_glUniform1iv +typedef void (APIENTRYP PFNGLUNIFORM2IVPROC)(GLint, GLsizei, const GLint*); +GLAPI PFNGLUNIFORM2IVPROC glad_glUniform2iv; +#define glUniform2iv glad_glUniform2iv +typedef void (APIENTRYP PFNGLUNIFORM3IVPROC)(GLint, GLsizei, const GLint*); +GLAPI PFNGLUNIFORM3IVPROC glad_glUniform3iv; +#define glUniform3iv glad_glUniform3iv +typedef void (APIENTRYP PFNGLUNIFORM4IVPROC)(GLint, GLsizei, const GLint*); +GLAPI PFNGLUNIFORM4IVPROC glad_glUniform4iv; +#define glUniform4iv glad_glUniform4iv +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVPROC)(GLint, GLsizei, GLboolean, const GLfloat*); +GLAPI PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv; +#define glUniformMatrix2fv glad_glUniformMatrix2fv +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVPROC)(GLint, GLsizei, GLboolean, const GLfloat*); +GLAPI PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv; +#define glUniformMatrix3fv glad_glUniformMatrix3fv +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVPROC)(GLint, GLsizei, GLboolean, const GLfloat*); +GLAPI PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv; +#define glUniformMatrix4fv glad_glUniformMatrix4fv +typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPROC)(GLuint); +GLAPI PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram; +#define glValidateProgram glad_glValidateProgram +typedef void (APIENTRYP PFNGLVERTEXATTRIB1DPROC)(GLuint, GLdouble); +GLAPI PFNGLVERTEXATTRIB1DPROC glad_glVertexAttrib1d; +#define glVertexAttrib1d glad_glVertexAttrib1d +typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVPROC)(GLuint, const GLdouble*); +GLAPI PFNGLVERTEXATTRIB1DVPROC glad_glVertexAttrib1dv; +#define glVertexAttrib1dv glad_glVertexAttrib1dv +typedef void (APIENTRYP PFNGLVERTEXATTRIB1FPROC)(GLuint, GLfloat); +GLAPI PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f; +#define glVertexAttrib1f glad_glVertexAttrib1f +typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVPROC)(GLuint, const GLfloat*); +GLAPI PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv; +#define glVertexAttrib1fv glad_glVertexAttrib1fv +typedef void (APIENTRYP PFNGLVERTEXATTRIB1SPROC)(GLuint, GLshort); +GLAPI PFNGLVERTEXATTRIB1SPROC glad_glVertexAttrib1s; +#define glVertexAttrib1s glad_glVertexAttrib1s +typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVPROC)(GLuint, const GLshort*); +GLAPI PFNGLVERTEXATTRIB1SVPROC glad_glVertexAttrib1sv; +#define glVertexAttrib1sv glad_glVertexAttrib1sv +typedef void (APIENTRYP PFNGLVERTEXATTRIB2DPROC)(GLuint, GLdouble, GLdouble); +GLAPI PFNGLVERTEXATTRIB2DPROC glad_glVertexAttrib2d; +#define glVertexAttrib2d glad_glVertexAttrib2d +typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVPROC)(GLuint, const GLdouble*); +GLAPI PFNGLVERTEXATTRIB2DVPROC glad_glVertexAttrib2dv; +#define glVertexAttrib2dv glad_glVertexAttrib2dv +typedef void (APIENTRYP PFNGLVERTEXATTRIB2FPROC)(GLuint, GLfloat, GLfloat); +GLAPI PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f; +#define glVertexAttrib2f glad_glVertexAttrib2f +typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVPROC)(GLuint, const GLfloat*); +GLAPI PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv; +#define glVertexAttrib2fv glad_glVertexAttrib2fv +typedef void (APIENTRYP PFNGLVERTEXATTRIB2SPROC)(GLuint, GLshort, GLshort); +GLAPI PFNGLVERTEXATTRIB2SPROC glad_glVertexAttrib2s; +#define glVertexAttrib2s glad_glVertexAttrib2s +typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVPROC)(GLuint, const GLshort*); +GLAPI PFNGLVERTEXATTRIB2SVPROC glad_glVertexAttrib2sv; +#define glVertexAttrib2sv glad_glVertexAttrib2sv +typedef void (APIENTRYP PFNGLVERTEXATTRIB3DPROC)(GLuint, GLdouble, GLdouble, GLdouble); +GLAPI PFNGLVERTEXATTRIB3DPROC glad_glVertexAttrib3d; +#define glVertexAttrib3d glad_glVertexAttrib3d +typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVPROC)(GLuint, const GLdouble*); +GLAPI PFNGLVERTEXATTRIB3DVPROC glad_glVertexAttrib3dv; +#define glVertexAttrib3dv glad_glVertexAttrib3dv +typedef void (APIENTRYP PFNGLVERTEXATTRIB3FPROC)(GLuint, GLfloat, GLfloat, GLfloat); +GLAPI PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f; +#define glVertexAttrib3f glad_glVertexAttrib3f +typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVPROC)(GLuint, const GLfloat*); +GLAPI PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv; +#define glVertexAttrib3fv glad_glVertexAttrib3fv +typedef void (APIENTRYP PFNGLVERTEXATTRIB3SPROC)(GLuint, GLshort, GLshort, GLshort); +GLAPI PFNGLVERTEXATTRIB3SPROC glad_glVertexAttrib3s; +#define glVertexAttrib3s glad_glVertexAttrib3s +typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVPROC)(GLuint, const GLshort*); +GLAPI PFNGLVERTEXATTRIB3SVPROC glad_glVertexAttrib3sv; +#define glVertexAttrib3sv glad_glVertexAttrib3sv +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVPROC)(GLuint, const GLbyte*); +GLAPI PFNGLVERTEXATTRIB4NBVPROC glad_glVertexAttrib4Nbv; +#define glVertexAttrib4Nbv glad_glVertexAttrib4Nbv +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVPROC)(GLuint, const GLint*); +GLAPI PFNGLVERTEXATTRIB4NIVPROC glad_glVertexAttrib4Niv; +#define glVertexAttrib4Niv glad_glVertexAttrib4Niv +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVPROC)(GLuint, const GLshort*); +GLAPI PFNGLVERTEXATTRIB4NSVPROC glad_glVertexAttrib4Nsv; +#define glVertexAttrib4Nsv glad_glVertexAttrib4Nsv +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBPROC)(GLuint, GLubyte, GLubyte, GLubyte, GLubyte); +GLAPI PFNGLVERTEXATTRIB4NUBPROC glad_glVertexAttrib4Nub; +#define glVertexAttrib4Nub glad_glVertexAttrib4Nub +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVPROC)(GLuint, const GLubyte*); +GLAPI PFNGLVERTEXATTRIB4NUBVPROC glad_glVertexAttrib4Nubv; +#define glVertexAttrib4Nubv glad_glVertexAttrib4Nubv +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVPROC)(GLuint, const GLuint*); +GLAPI PFNGLVERTEXATTRIB4NUIVPROC glad_glVertexAttrib4Nuiv; +#define glVertexAttrib4Nuiv glad_glVertexAttrib4Nuiv +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVPROC)(GLuint, const GLushort*); +GLAPI PFNGLVERTEXATTRIB4NUSVPROC glad_glVertexAttrib4Nusv; +#define glVertexAttrib4Nusv glad_glVertexAttrib4Nusv +typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVPROC)(GLuint, const GLbyte*); +GLAPI PFNGLVERTEXATTRIB4BVPROC glad_glVertexAttrib4bv; +#define glVertexAttrib4bv glad_glVertexAttrib4bv +typedef void (APIENTRYP PFNGLVERTEXATTRIB4DPROC)(GLuint, GLdouble, GLdouble, GLdouble, GLdouble); +GLAPI PFNGLVERTEXATTRIB4DPROC glad_glVertexAttrib4d; +#define glVertexAttrib4d glad_glVertexAttrib4d +typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVPROC)(GLuint, const GLdouble*); +GLAPI PFNGLVERTEXATTRIB4DVPROC glad_glVertexAttrib4dv; +#define glVertexAttrib4dv glad_glVertexAttrib4dv +typedef void (APIENTRYP PFNGLVERTEXATTRIB4FPROC)(GLuint, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f; +#define glVertexAttrib4f glad_glVertexAttrib4f +typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVPROC)(GLuint, const GLfloat*); +GLAPI PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv; +#define glVertexAttrib4fv glad_glVertexAttrib4fv +typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVPROC)(GLuint, const GLint*); +GLAPI PFNGLVERTEXATTRIB4IVPROC glad_glVertexAttrib4iv; +#define glVertexAttrib4iv glad_glVertexAttrib4iv +typedef void (APIENTRYP PFNGLVERTEXATTRIB4SPROC)(GLuint, GLshort, GLshort, GLshort, GLshort); +GLAPI PFNGLVERTEXATTRIB4SPROC glad_glVertexAttrib4s; +#define glVertexAttrib4s glad_glVertexAttrib4s +typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVPROC)(GLuint, const GLshort*); +GLAPI PFNGLVERTEXATTRIB4SVPROC glad_glVertexAttrib4sv; +#define glVertexAttrib4sv glad_glVertexAttrib4sv +typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVPROC)(GLuint, const GLubyte*); +GLAPI PFNGLVERTEXATTRIB4UBVPROC glad_glVertexAttrib4ubv; +#define glVertexAttrib4ubv glad_glVertexAttrib4ubv +typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVPROC)(GLuint, const GLuint*); +GLAPI PFNGLVERTEXATTRIB4UIVPROC glad_glVertexAttrib4uiv; +#define glVertexAttrib4uiv glad_glVertexAttrib4uiv +typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVPROC)(GLuint, const GLushort*); +GLAPI PFNGLVERTEXATTRIB4USVPROC glad_glVertexAttrib4usv; +#define glVertexAttrib4usv glad_glVertexAttrib4usv +typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC)(GLuint, GLint, GLenum, GLboolean, GLsizei, const void*); +GLAPI PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer; +#define glVertexAttribPointer glad_glVertexAttribPointer +#endif +#ifndef GL_VERSION_2_1 +#define GL_VERSION_2_1 1 +GLAPI int GLAD_GL_VERSION_2_1; +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3FVPROC)(GLint, GLsizei, GLboolean, const GLfloat*); +GLAPI PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv; +#define glUniformMatrix2x3fv glad_glUniformMatrix2x3fv +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2FVPROC)(GLint, GLsizei, GLboolean, const GLfloat*); +GLAPI PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv; +#define glUniformMatrix3x2fv glad_glUniformMatrix3x2fv +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4FVPROC)(GLint, GLsizei, GLboolean, const GLfloat*); +GLAPI PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv; +#define glUniformMatrix2x4fv glad_glUniformMatrix2x4fv +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2FVPROC)(GLint, GLsizei, GLboolean, const GLfloat*); +GLAPI PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv; +#define glUniformMatrix4x2fv glad_glUniformMatrix4x2fv +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4FVPROC)(GLint, GLsizei, GLboolean, const GLfloat*); +GLAPI PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv; +#define glUniformMatrix3x4fv glad_glUniformMatrix3x4fv +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3FVPROC)(GLint, GLsizei, GLboolean, const GLfloat*); +GLAPI PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv; +#define glUniformMatrix4x3fv glad_glUniformMatrix4x3fv +#endif +#ifndef GL_VERSION_3_0 +#define GL_VERSION_3_0 1 +GLAPI int GLAD_GL_VERSION_3_0; +typedef void (APIENTRYP PFNGLCOLORMASKIPROC)(GLuint, GLboolean, GLboolean, GLboolean, GLboolean); +GLAPI PFNGLCOLORMASKIPROC glad_glColorMaski; +#define glColorMaski glad_glColorMaski +typedef void (APIENTRYP PFNGLGETBOOLEANI_VPROC)(GLenum, GLuint, GLboolean*); +GLAPI PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v; +#define glGetBooleani_v glad_glGetBooleani_v +typedef void (APIENTRYP PFNGLGETINTEGERI_VPROC)(GLenum, GLuint, GLint*); +GLAPI PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v; +#define glGetIntegeri_v glad_glGetIntegeri_v +typedef void (APIENTRYP PFNGLENABLEIPROC)(GLenum, GLuint); +GLAPI PFNGLENABLEIPROC glad_glEnablei; +#define glEnablei glad_glEnablei +typedef void (APIENTRYP PFNGLDISABLEIPROC)(GLenum, GLuint); +GLAPI PFNGLDISABLEIPROC glad_glDisablei; +#define glDisablei glad_glDisablei +typedef GLboolean (APIENTRYP PFNGLISENABLEDIPROC)(GLenum, GLuint); +GLAPI PFNGLISENABLEDIPROC glad_glIsEnabledi; +#define glIsEnabledi glad_glIsEnabledi +typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKPROC)(GLenum); +GLAPI PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback; +#define glBeginTransformFeedback glad_glBeginTransformFeedback +typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKPROC)(); +GLAPI PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback; +#define glEndTransformFeedback glad_glEndTransformFeedback +typedef void (APIENTRYP PFNGLBINDBUFFERRANGEPROC)(GLenum, GLuint, GLuint, GLintptr, GLsizeiptr); +GLAPI PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange; +#define glBindBufferRange glad_glBindBufferRange +typedef void (APIENTRYP PFNGLBINDBUFFERBASEPROC)(GLenum, GLuint, GLuint); +GLAPI PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase; +#define glBindBufferBase glad_glBindBufferBase +typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSPROC)(GLuint, GLsizei, const GLchar**, GLenum); +GLAPI PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings; +#define glTransformFeedbackVaryings glad_glTransformFeedbackVaryings +typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGPROC)(GLuint, GLuint, GLsizei, GLsizei*, GLsizei*, GLenum*, GLchar*); +GLAPI PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying; +#define glGetTransformFeedbackVarying glad_glGetTransformFeedbackVarying +typedef void (APIENTRYP PFNGLCLAMPCOLORPROC)(GLenum, GLenum); +GLAPI PFNGLCLAMPCOLORPROC glad_glClampColor; +#define glClampColor glad_glClampColor +typedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERPROC)(GLuint, GLenum); +GLAPI PFNGLBEGINCONDITIONALRENDERPROC glad_glBeginConditionalRender; +#define glBeginConditionalRender glad_glBeginConditionalRender +typedef void (APIENTRYP PFNGLENDCONDITIONALRENDERPROC)(); +GLAPI PFNGLENDCONDITIONALRENDERPROC glad_glEndConditionalRender; +#define glEndConditionalRender glad_glEndConditionalRender +typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTERPROC)(GLuint, GLint, GLenum, GLsizei, const void*); +GLAPI PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer; +#define glVertexAttribIPointer glad_glVertexAttribIPointer +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVPROC)(GLuint, GLenum, GLint*); +GLAPI PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv; +#define glGetVertexAttribIiv glad_glGetVertexAttribIiv +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVPROC)(GLuint, GLenum, GLuint*); +GLAPI PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv; +#define glGetVertexAttribIuiv glad_glGetVertexAttribIuiv +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IPROC)(GLuint, GLint); +GLAPI PFNGLVERTEXATTRIBI1IPROC glad_glVertexAttribI1i; +#define glVertexAttribI1i glad_glVertexAttribI1i +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IPROC)(GLuint, GLint, GLint); +GLAPI PFNGLVERTEXATTRIBI2IPROC glad_glVertexAttribI2i; +#define glVertexAttribI2i glad_glVertexAttribI2i +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IPROC)(GLuint, GLint, GLint, GLint); +GLAPI PFNGLVERTEXATTRIBI3IPROC glad_glVertexAttribI3i; +#define glVertexAttribI3i glad_glVertexAttribI3i +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IPROC)(GLuint, GLint, GLint, GLint, GLint); +GLAPI PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i; +#define glVertexAttribI4i glad_glVertexAttribI4i +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIPROC)(GLuint, GLuint); +GLAPI PFNGLVERTEXATTRIBI1UIPROC glad_glVertexAttribI1ui; +#define glVertexAttribI1ui glad_glVertexAttribI1ui +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIPROC)(GLuint, GLuint, GLuint); +GLAPI PFNGLVERTEXATTRIBI2UIPROC glad_glVertexAttribI2ui; +#define glVertexAttribI2ui glad_glVertexAttribI2ui +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIPROC)(GLuint, GLuint, GLuint, GLuint); +GLAPI PFNGLVERTEXATTRIBI3UIPROC glad_glVertexAttribI3ui; +#define glVertexAttribI3ui glad_glVertexAttribI3ui +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIPROC)(GLuint, GLuint, GLuint, GLuint, GLuint); +GLAPI PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui; +#define glVertexAttribI4ui glad_glVertexAttribI4ui +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IVPROC)(GLuint, const GLint*); +GLAPI PFNGLVERTEXATTRIBI1IVPROC glad_glVertexAttribI1iv; +#define glVertexAttribI1iv glad_glVertexAttribI1iv +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IVPROC)(GLuint, const GLint*); +GLAPI PFNGLVERTEXATTRIBI2IVPROC glad_glVertexAttribI2iv; +#define glVertexAttribI2iv glad_glVertexAttribI2iv +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IVPROC)(GLuint, const GLint*); +GLAPI PFNGLVERTEXATTRIBI3IVPROC glad_glVertexAttribI3iv; +#define glVertexAttribI3iv glad_glVertexAttribI3iv +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IVPROC)(GLuint, const GLint*); +GLAPI PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv; +#define glVertexAttribI4iv glad_glVertexAttribI4iv +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIVPROC)(GLuint, const GLuint*); +GLAPI PFNGLVERTEXATTRIBI1UIVPROC glad_glVertexAttribI1uiv; +#define glVertexAttribI1uiv glad_glVertexAttribI1uiv +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIVPROC)(GLuint, const GLuint*); +GLAPI PFNGLVERTEXATTRIBI2UIVPROC glad_glVertexAttribI2uiv; +#define glVertexAttribI2uiv glad_glVertexAttribI2uiv +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIVPROC)(GLuint, const GLuint*); +GLAPI PFNGLVERTEXATTRIBI3UIVPROC glad_glVertexAttribI3uiv; +#define glVertexAttribI3uiv glad_glVertexAttribI3uiv +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIVPROC)(GLuint, const GLuint*); +GLAPI PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv; +#define glVertexAttribI4uiv glad_glVertexAttribI4uiv +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4BVPROC)(GLuint, const GLbyte*); +GLAPI PFNGLVERTEXATTRIBI4BVPROC glad_glVertexAttribI4bv; +#define glVertexAttribI4bv glad_glVertexAttribI4bv +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4SVPROC)(GLuint, const GLshort*); +GLAPI PFNGLVERTEXATTRIBI4SVPROC glad_glVertexAttribI4sv; +#define glVertexAttribI4sv glad_glVertexAttribI4sv +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UBVPROC)(GLuint, const GLubyte*); +GLAPI PFNGLVERTEXATTRIBI4UBVPROC glad_glVertexAttribI4ubv; +#define glVertexAttribI4ubv glad_glVertexAttribI4ubv +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4USVPROC)(GLuint, const GLushort*); +GLAPI PFNGLVERTEXATTRIBI4USVPROC glad_glVertexAttribI4usv; +#define glVertexAttribI4usv glad_glVertexAttribI4usv +typedef void (APIENTRYP PFNGLGETUNIFORMUIVPROC)(GLuint, GLint, GLuint*); +GLAPI PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv; +#define glGetUniformuiv glad_glGetUniformuiv +typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONPROC)(GLuint, GLuint, const GLchar*); +GLAPI PFNGLBINDFRAGDATALOCATIONPROC glad_glBindFragDataLocation; +#define glBindFragDataLocation glad_glBindFragDataLocation +typedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONPROC)(GLuint, const GLchar*); +GLAPI PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation; +#define glGetFragDataLocation glad_glGetFragDataLocation +typedef void (APIENTRYP PFNGLUNIFORM1UIPROC)(GLint, GLuint); +GLAPI PFNGLUNIFORM1UIPROC glad_glUniform1ui; +#define glUniform1ui glad_glUniform1ui +typedef void (APIENTRYP PFNGLUNIFORM2UIPROC)(GLint, GLuint, GLuint); +GLAPI PFNGLUNIFORM2UIPROC glad_glUniform2ui; +#define glUniform2ui glad_glUniform2ui +typedef void (APIENTRYP PFNGLUNIFORM3UIPROC)(GLint, GLuint, GLuint, GLuint); +GLAPI PFNGLUNIFORM3UIPROC glad_glUniform3ui; +#define glUniform3ui glad_glUniform3ui +typedef void (APIENTRYP PFNGLUNIFORM4UIPROC)(GLint, GLuint, GLuint, GLuint, GLuint); +GLAPI PFNGLUNIFORM4UIPROC glad_glUniform4ui; +#define glUniform4ui glad_glUniform4ui +typedef void (APIENTRYP PFNGLUNIFORM1UIVPROC)(GLint, GLsizei, const GLuint*); +GLAPI PFNGLUNIFORM1UIVPROC glad_glUniform1uiv; +#define glUniform1uiv glad_glUniform1uiv +typedef void (APIENTRYP PFNGLUNIFORM2UIVPROC)(GLint, GLsizei, const GLuint*); +GLAPI PFNGLUNIFORM2UIVPROC glad_glUniform2uiv; +#define glUniform2uiv glad_glUniform2uiv +typedef void (APIENTRYP PFNGLUNIFORM3UIVPROC)(GLint, GLsizei, const GLuint*); +GLAPI PFNGLUNIFORM3UIVPROC glad_glUniform3uiv; +#define glUniform3uiv glad_glUniform3uiv +typedef void (APIENTRYP PFNGLUNIFORM4UIVPROC)(GLint, GLsizei, const GLuint*); +GLAPI PFNGLUNIFORM4UIVPROC glad_glUniform4uiv; +#define glUniform4uiv glad_glUniform4uiv +typedef void (APIENTRYP PFNGLTEXPARAMETERIIVPROC)(GLenum, GLenum, const GLint*); +GLAPI PFNGLTEXPARAMETERIIVPROC glad_glTexParameterIiv; +#define glTexParameterIiv glad_glTexParameterIiv +typedef void (APIENTRYP PFNGLTEXPARAMETERIUIVPROC)(GLenum, GLenum, const GLuint*); +GLAPI PFNGLTEXPARAMETERIUIVPROC glad_glTexParameterIuiv; +#define glTexParameterIuiv glad_glTexParameterIuiv +typedef void (APIENTRYP PFNGLGETTEXPARAMETERIIVPROC)(GLenum, GLenum, GLint*); +GLAPI PFNGLGETTEXPARAMETERIIVPROC glad_glGetTexParameterIiv; +#define glGetTexParameterIiv glad_glGetTexParameterIiv +typedef void (APIENTRYP PFNGLGETTEXPARAMETERIUIVPROC)(GLenum, GLenum, GLuint*); +GLAPI PFNGLGETTEXPARAMETERIUIVPROC glad_glGetTexParameterIuiv; +#define glGetTexParameterIuiv glad_glGetTexParameterIuiv +typedef void (APIENTRYP PFNGLCLEARBUFFERIVPROC)(GLenum, GLint, const GLint*); +GLAPI PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv; +#define glClearBufferiv glad_glClearBufferiv +typedef void (APIENTRYP PFNGLCLEARBUFFERUIVPROC)(GLenum, GLint, const GLuint*); +GLAPI PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv; +#define glClearBufferuiv glad_glClearBufferuiv +typedef void (APIENTRYP PFNGLCLEARBUFFERFVPROC)(GLenum, GLint, const GLfloat*); +GLAPI PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv; +#define glClearBufferfv glad_glClearBufferfv +typedef void (APIENTRYP PFNGLCLEARBUFFERFIPROC)(GLenum, GLint, GLfloat, GLint); +GLAPI PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi; +#define glClearBufferfi glad_glClearBufferfi +typedef const GLubyte* (APIENTRYP PFNGLGETSTRINGIPROC)(GLenum, GLuint); +GLAPI PFNGLGETSTRINGIPROC glad_glGetStringi; +#define glGetStringi glad_glGetStringi +typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFERPROC)(GLuint); +GLAPI PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer; +#define glIsRenderbuffer glad_glIsRenderbuffer +typedef void (APIENTRYP PFNGLBINDRENDERBUFFERPROC)(GLenum, GLuint); +GLAPI PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer; +#define glBindRenderbuffer glad_glBindRenderbuffer +typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSPROC)(GLsizei, const GLuint*); +GLAPI PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers; +#define glDeleteRenderbuffers glad_glDeleteRenderbuffers +typedef void (APIENTRYP PFNGLGENRENDERBUFFERSPROC)(GLsizei, GLuint*); +GLAPI PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers; +#define glGenRenderbuffers glad_glGenRenderbuffers +typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEPROC)(GLenum, GLenum, GLsizei, GLsizei); +GLAPI PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage; +#define glRenderbufferStorage glad_glRenderbufferStorage +typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVPROC)(GLenum, GLenum, GLint*); +GLAPI PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv; +#define glGetRenderbufferParameteriv glad_glGetRenderbufferParameteriv +typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFERPROC)(GLuint); +GLAPI PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer; +#define glIsFramebuffer glad_glIsFramebuffer +typedef void (APIENTRYP PFNGLBINDFRAMEBUFFERPROC)(GLenum, GLuint); +GLAPI PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer; +#define glBindFramebuffer glad_glBindFramebuffer +typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSPROC)(GLsizei, const GLuint*); +GLAPI PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers; +#define glDeleteFramebuffers glad_glDeleteFramebuffers +typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSPROC)(GLsizei, GLuint*); +GLAPI PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers; +#define glGenFramebuffers glad_glGenFramebuffers +typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSPROC)(GLenum); +GLAPI PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus; +#define glCheckFramebufferStatus glad_glCheckFramebufferStatus +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DPROC)(GLenum, GLenum, GLenum, GLuint, GLint); +GLAPI PFNGLFRAMEBUFFERTEXTURE1DPROC glad_glFramebufferTexture1D; +#define glFramebufferTexture1D glad_glFramebufferTexture1D +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DPROC)(GLenum, GLenum, GLenum, GLuint, GLint); +GLAPI PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D; +#define glFramebufferTexture2D glad_glFramebufferTexture2D +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DPROC)(GLenum, GLenum, GLenum, GLuint, GLint, GLint); +GLAPI PFNGLFRAMEBUFFERTEXTURE3DPROC glad_glFramebufferTexture3D; +#define glFramebufferTexture3D glad_glFramebufferTexture3D +typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFERPROC)(GLenum, GLenum, GLenum, GLuint); +GLAPI PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer; +#define glFramebufferRenderbuffer glad_glFramebufferRenderbuffer +typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)(GLenum, GLenum, GLenum, GLint*); +GLAPI PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv; +#define glGetFramebufferAttachmentParameteriv glad_glGetFramebufferAttachmentParameteriv +typedef void (APIENTRYP PFNGLGENERATEMIPMAPPROC)(GLenum); +GLAPI PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap; +#define glGenerateMipmap glad_glGenerateMipmap +typedef void (APIENTRYP PFNGLBLITFRAMEBUFFERPROC)(GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum); +GLAPI PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer; +#define glBlitFramebuffer glad_glBlitFramebuffer +typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)(GLenum, GLsizei, GLenum, GLsizei, GLsizei); +GLAPI PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample; +#define glRenderbufferStorageMultisample glad_glRenderbufferStorageMultisample +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERPROC)(GLenum, GLenum, GLuint, GLint, GLint); +GLAPI PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer; +#define glFramebufferTextureLayer glad_glFramebufferTextureLayer +typedef void* (APIENTRYP PFNGLMAPBUFFERRANGEPROC)(GLenum, GLintptr, GLsizeiptr, GLbitfield); +GLAPI PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange; +#define glMapBufferRange glad_glMapBufferRange +typedef void (APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEPROC)(GLenum, GLintptr, GLsizeiptr); +GLAPI PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange; +#define glFlushMappedBufferRange glad_glFlushMappedBufferRange +typedef void (APIENTRYP PFNGLBINDVERTEXARRAYPROC)(GLuint); +GLAPI PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray; +#define glBindVertexArray glad_glBindVertexArray +typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSPROC)(GLsizei, const GLuint*); +GLAPI PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays; +#define glDeleteVertexArrays glad_glDeleteVertexArrays +typedef void (APIENTRYP PFNGLGENVERTEXARRAYSPROC)(GLsizei, GLuint*); +GLAPI PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays; +#define glGenVertexArrays glad_glGenVertexArrays +typedef GLboolean (APIENTRYP PFNGLISVERTEXARRAYPROC)(GLuint); +GLAPI PFNGLISVERTEXARRAYPROC glad_glIsVertexArray; +#define glIsVertexArray glad_glIsVertexArray +#endif +#ifndef GL_VERSION_3_1 +#define GL_VERSION_3_1 1 +GLAPI int GLAD_GL_VERSION_3_1; +typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDPROC)(GLenum, GLint, GLsizei, GLsizei); +GLAPI PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced; +#define glDrawArraysInstanced glad_glDrawArraysInstanced +typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDPROC)(GLenum, GLsizei, GLenum, const void*, GLsizei); +GLAPI PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced; +#define glDrawElementsInstanced glad_glDrawElementsInstanced +typedef void (APIENTRYP PFNGLTEXBUFFERPROC)(GLenum, GLenum, GLuint); +GLAPI PFNGLTEXBUFFERPROC glad_glTexBuffer; +#define glTexBuffer glad_glTexBuffer +typedef void (APIENTRYP PFNGLPRIMITIVERESTARTINDEXPROC)(GLuint); +GLAPI PFNGLPRIMITIVERESTARTINDEXPROC glad_glPrimitiveRestartIndex; +#define glPrimitiveRestartIndex glad_glPrimitiveRestartIndex +typedef void (APIENTRYP PFNGLCOPYBUFFERSUBDATAPROC)(GLenum, GLenum, GLintptr, GLintptr, GLsizeiptr); +GLAPI PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData; +#define glCopyBufferSubData glad_glCopyBufferSubData +typedef void (APIENTRYP PFNGLGETUNIFORMINDICESPROC)(GLuint, GLsizei, const GLchar**, GLuint*); +GLAPI PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices; +#define glGetUniformIndices glad_glGetUniformIndices +typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMSIVPROC)(GLuint, GLsizei, const GLuint*, GLenum, GLint*); +GLAPI PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv; +#define glGetActiveUniformsiv glad_glGetActiveUniformsiv +typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMNAMEPROC)(GLuint, GLuint, GLsizei, GLsizei*, GLchar*); +GLAPI PFNGLGETACTIVEUNIFORMNAMEPROC glad_glGetActiveUniformName; +#define glGetActiveUniformName glad_glGetActiveUniformName +typedef GLuint (APIENTRYP PFNGLGETUNIFORMBLOCKINDEXPROC)(GLuint, const GLchar*); +GLAPI PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex; +#define glGetUniformBlockIndex glad_glGetUniformBlockIndex +typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKIVPROC)(GLuint, GLuint, GLenum, GLint*); +GLAPI PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv; +#define glGetActiveUniformBlockiv glad_glGetActiveUniformBlockiv +typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC)(GLuint, GLuint, GLsizei, GLsizei*, GLchar*); +GLAPI PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName; +#define glGetActiveUniformBlockName glad_glGetActiveUniformBlockName +typedef void (APIENTRYP PFNGLUNIFORMBLOCKBINDINGPROC)(GLuint, GLuint, GLuint); +GLAPI PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding; +#define glUniformBlockBinding glad_glUniformBlockBinding +#endif +#ifndef GL_VERSION_3_2 +#define GL_VERSION_3_2 1 +GLAPI int GLAD_GL_VERSION_3_2; +typedef void (APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXPROC)(GLenum, GLsizei, GLenum, const void*, GLint); +GLAPI PFNGLDRAWELEMENTSBASEVERTEXPROC glad_glDrawElementsBaseVertex; +#define glDrawElementsBaseVertex glad_glDrawElementsBaseVertex +typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC)(GLenum, GLuint, GLuint, GLsizei, GLenum, const void*, GLint); +GLAPI PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex; +#define glDrawRangeElementsBaseVertex glad_glDrawRangeElementsBaseVertex +typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)(GLenum, GLsizei, GLenum, const void*, GLsizei, GLint); +GLAPI PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex; +#define glDrawElementsInstancedBaseVertex glad_glDrawElementsInstancedBaseVertex +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC)(GLenum, const GLsizei*, GLenum, const void**, GLsizei, const GLint*); +GLAPI PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glad_glMultiDrawElementsBaseVertex; +#define glMultiDrawElementsBaseVertex glad_glMultiDrawElementsBaseVertex +typedef void (APIENTRYP PFNGLPROVOKINGVERTEXPROC)(GLenum); +GLAPI PFNGLPROVOKINGVERTEXPROC glad_glProvokingVertex; +#define glProvokingVertex glad_glProvokingVertex +typedef GLsync (APIENTRYP PFNGLFENCESYNCPROC)(GLenum, GLbitfield); +GLAPI PFNGLFENCESYNCPROC glad_glFenceSync; +#define glFenceSync glad_glFenceSync +typedef GLboolean (APIENTRYP PFNGLISSYNCPROC)(GLsync); +GLAPI PFNGLISSYNCPROC glad_glIsSync; +#define glIsSync glad_glIsSync +typedef void (APIENTRYP PFNGLDELETESYNCPROC)(GLsync); +GLAPI PFNGLDELETESYNCPROC glad_glDeleteSync; +#define glDeleteSync glad_glDeleteSync +typedef GLenum (APIENTRYP PFNGLCLIENTWAITSYNCPROC)(GLsync, GLbitfield, GLuint64); +GLAPI PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync; +#define glClientWaitSync glad_glClientWaitSync +typedef void (APIENTRYP PFNGLWAITSYNCPROC)(GLsync, GLbitfield, GLuint64); +GLAPI PFNGLWAITSYNCPROC glad_glWaitSync; +#define glWaitSync glad_glWaitSync +typedef void (APIENTRYP PFNGLGETINTEGER64VPROC)(GLenum, GLint64*); +GLAPI PFNGLGETINTEGER64VPROC glad_glGetInteger64v; +#define glGetInteger64v glad_glGetInteger64v +typedef void (APIENTRYP PFNGLGETSYNCIVPROC)(GLsync, GLenum, GLsizei, GLsizei*, GLint*); +GLAPI PFNGLGETSYNCIVPROC glad_glGetSynciv; +#define glGetSynciv glad_glGetSynciv +typedef void (APIENTRYP PFNGLGETINTEGER64I_VPROC)(GLenum, GLuint, GLint64*); +GLAPI PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v; +#define glGetInteger64i_v glad_glGetInteger64i_v +typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERI64VPROC)(GLenum, GLenum, GLint64*); +GLAPI PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v; +#define glGetBufferParameteri64v glad_glGetBufferParameteri64v +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREPROC)(GLenum, GLenum, GLuint, GLint); +GLAPI PFNGLFRAMEBUFFERTEXTUREPROC glad_glFramebufferTexture; +#define glFramebufferTexture glad_glFramebufferTexture +typedef void (APIENTRYP PFNGLTEXIMAGE2DMULTISAMPLEPROC)(GLenum, GLsizei, GLenum, GLsizei, GLsizei, GLboolean); +GLAPI PFNGLTEXIMAGE2DMULTISAMPLEPROC glad_glTexImage2DMultisample; +#define glTexImage2DMultisample glad_glTexImage2DMultisample +typedef void (APIENTRYP PFNGLTEXIMAGE3DMULTISAMPLEPROC)(GLenum, GLsizei, GLenum, GLsizei, GLsizei, GLsizei, GLboolean); +GLAPI PFNGLTEXIMAGE3DMULTISAMPLEPROC glad_glTexImage3DMultisample; +#define glTexImage3DMultisample glad_glTexImage3DMultisample +typedef void (APIENTRYP PFNGLGETMULTISAMPLEFVPROC)(GLenum, GLuint, GLfloat*); +GLAPI PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv; +#define glGetMultisamplefv glad_glGetMultisamplefv +typedef void (APIENTRYP PFNGLSAMPLEMASKIPROC)(GLuint, GLbitfield); +GLAPI PFNGLSAMPLEMASKIPROC glad_glSampleMaski; +#define glSampleMaski glad_glSampleMaski +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/testbed/glfw/deps/tinycthread.c b/testbed/glfw/deps/tinycthread.c new file mode 100644 index 00000000..670857eb --- /dev/null +++ b/testbed/glfw/deps/tinycthread.c @@ -0,0 +1,593 @@ +/* -*- mode: c; tab-width: 2; indent-tabs-mode: nil; -*- +Copyright (c) 2012 Marcus Geelnard + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +*/ + +/* 2013-01-06 Camilla Berglund + * + * Added casts from time_t to DWORD to avoid warnings on VC++. + */ + +#include "tinycthread.h" +#include + +/* Platform specific includes */ +#if defined(_TTHREAD_POSIX_) + #include + #include + #include + #include + #include +#elif defined(_TTHREAD_WIN32_) + #include + #include +#endif + +/* Standard, good-to-have defines */ +#ifndef NULL + #define NULL (void*)0 +#endif +#ifndef TRUE + #define TRUE 1 +#endif +#ifndef FALSE + #define FALSE 0 +#endif + +int mtx_init(mtx_t *mtx, int type) +{ +#if defined(_TTHREAD_WIN32_) + mtx->mAlreadyLocked = FALSE; + mtx->mRecursive = type & mtx_recursive; + InitializeCriticalSection(&mtx->mHandle); + return thrd_success; +#else + int ret; + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + if (type & mtx_recursive) + { + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + } + ret = pthread_mutex_init(mtx, &attr); + pthread_mutexattr_destroy(&attr); + return ret == 0 ? thrd_success : thrd_error; +#endif +} + +void mtx_destroy(mtx_t *mtx) +{ +#if defined(_TTHREAD_WIN32_) + DeleteCriticalSection(&mtx->mHandle); +#else + pthread_mutex_destroy(mtx); +#endif +} + +int mtx_lock(mtx_t *mtx) +{ +#if defined(_TTHREAD_WIN32_) + EnterCriticalSection(&mtx->mHandle); + if (!mtx->mRecursive) + { + while(mtx->mAlreadyLocked) Sleep(1000); /* Simulate deadlock... */ + mtx->mAlreadyLocked = TRUE; + } + return thrd_success; +#else + return pthread_mutex_lock(mtx) == 0 ? thrd_success : thrd_error; +#endif +} + +int mtx_timedlock(mtx_t *mtx, const struct timespec *ts) +{ + /* FIXME! */ + (void)mtx; + (void)ts; + return thrd_error; +} + +int mtx_trylock(mtx_t *mtx) +{ +#if defined(_TTHREAD_WIN32_) + int ret = TryEnterCriticalSection(&mtx->mHandle) ? thrd_success : thrd_busy; + if ((!mtx->mRecursive) && (ret == thrd_success) && mtx->mAlreadyLocked) + { + LeaveCriticalSection(&mtx->mHandle); + ret = thrd_busy; + } + return ret; +#else + return (pthread_mutex_trylock(mtx) == 0) ? thrd_success : thrd_busy; +#endif +} + +int mtx_unlock(mtx_t *mtx) +{ +#if defined(_TTHREAD_WIN32_) + mtx->mAlreadyLocked = FALSE; + LeaveCriticalSection(&mtx->mHandle); + return thrd_success; +#else + return pthread_mutex_unlock(mtx) == 0 ? thrd_success : thrd_error;; +#endif +} + +#if defined(_TTHREAD_WIN32_) +#define _CONDITION_EVENT_ONE 0 +#define _CONDITION_EVENT_ALL 1 +#endif + +int cnd_init(cnd_t *cond) +{ +#if defined(_TTHREAD_WIN32_) + cond->mWaitersCount = 0; + + /* Init critical section */ + InitializeCriticalSection(&cond->mWaitersCountLock); + + /* Init events */ + cond->mEvents[_CONDITION_EVENT_ONE] = CreateEvent(NULL, FALSE, FALSE, NULL); + if (cond->mEvents[_CONDITION_EVENT_ONE] == NULL) + { + cond->mEvents[_CONDITION_EVENT_ALL] = NULL; + return thrd_error; + } + cond->mEvents[_CONDITION_EVENT_ALL] = CreateEvent(NULL, TRUE, FALSE, NULL); + if (cond->mEvents[_CONDITION_EVENT_ALL] == NULL) + { + CloseHandle(cond->mEvents[_CONDITION_EVENT_ONE]); + cond->mEvents[_CONDITION_EVENT_ONE] = NULL; + return thrd_error; + } + + return thrd_success; +#else + return pthread_cond_init(cond, NULL) == 0 ? thrd_success : thrd_error; +#endif +} + +void cnd_destroy(cnd_t *cond) +{ +#if defined(_TTHREAD_WIN32_) + if (cond->mEvents[_CONDITION_EVENT_ONE] != NULL) + { + CloseHandle(cond->mEvents[_CONDITION_EVENT_ONE]); + } + if (cond->mEvents[_CONDITION_EVENT_ALL] != NULL) + { + CloseHandle(cond->mEvents[_CONDITION_EVENT_ALL]); + } + DeleteCriticalSection(&cond->mWaitersCountLock); +#else + pthread_cond_destroy(cond); +#endif +} + +int cnd_signal(cnd_t *cond) +{ +#if defined(_TTHREAD_WIN32_) + int haveWaiters; + + /* Are there any waiters? */ + EnterCriticalSection(&cond->mWaitersCountLock); + haveWaiters = (cond->mWaitersCount > 0); + LeaveCriticalSection(&cond->mWaitersCountLock); + + /* If we have any waiting threads, send them a signal */ + if(haveWaiters) + { + if (SetEvent(cond->mEvents[_CONDITION_EVENT_ONE]) == 0) + { + return thrd_error; + } + } + + return thrd_success; +#else + return pthread_cond_signal(cond) == 0 ? thrd_success : thrd_error; +#endif +} + +int cnd_broadcast(cnd_t *cond) +{ +#if defined(_TTHREAD_WIN32_) + int haveWaiters; + + /* Are there any waiters? */ + EnterCriticalSection(&cond->mWaitersCountLock); + haveWaiters = (cond->mWaitersCount > 0); + LeaveCriticalSection(&cond->mWaitersCountLock); + + /* If we have any waiting threads, send them a signal */ + if(haveWaiters) + { + if (SetEvent(cond->mEvents[_CONDITION_EVENT_ALL]) == 0) + { + return thrd_error; + } + } + + return thrd_success; +#else + return pthread_cond_signal(cond) == 0 ? thrd_success : thrd_error; +#endif +} + +#if defined(_TTHREAD_WIN32_) +static int _cnd_timedwait_win32(cnd_t *cond, mtx_t *mtx, DWORD timeout) +{ + int result, lastWaiter; + + /* Increment number of waiters */ + EnterCriticalSection(&cond->mWaitersCountLock); + ++ cond->mWaitersCount; + LeaveCriticalSection(&cond->mWaitersCountLock); + + /* Release the mutex while waiting for the condition (will decrease + the number of waiters when done)... */ + mtx_unlock(mtx); + + /* Wait for either event to become signaled due to cnd_signal() or + cnd_broadcast() being called */ + result = WaitForMultipleObjects(2, cond->mEvents, FALSE, timeout); + if (result == WAIT_TIMEOUT) + { + return thrd_timeout; + } + else if (result == (int)WAIT_FAILED) + { + return thrd_error; + } + + /* Check if we are the last waiter */ + EnterCriticalSection(&cond->mWaitersCountLock); + -- cond->mWaitersCount; + lastWaiter = (result == (WAIT_OBJECT_0 + _CONDITION_EVENT_ALL)) && + (cond->mWaitersCount == 0); + LeaveCriticalSection(&cond->mWaitersCountLock); + + /* If we are the last waiter to be notified to stop waiting, reset the event */ + if (lastWaiter) + { + if (ResetEvent(cond->mEvents[_CONDITION_EVENT_ALL]) == 0) + { + return thrd_error; + } + } + + /* Re-acquire the mutex */ + mtx_lock(mtx); + + return thrd_success; +} +#endif + +int cnd_wait(cnd_t *cond, mtx_t *mtx) +{ +#if defined(_TTHREAD_WIN32_) + return _cnd_timedwait_win32(cond, mtx, INFINITE); +#else + return pthread_cond_wait(cond, mtx) == 0 ? thrd_success : thrd_error; +#endif +} + +int cnd_timedwait(cnd_t *cond, mtx_t *mtx, const struct timespec *ts) +{ +#if defined(_TTHREAD_WIN32_) + struct timespec now; + if (clock_gettime(TIME_UTC, &now) == 0) + { + DWORD delta = (DWORD) ((ts->tv_sec - now.tv_sec) * 1000 + + (ts->tv_nsec - now.tv_nsec + 500000) / 1000000); + return _cnd_timedwait_win32(cond, mtx, delta); + } + else + return thrd_error; +#else + int ret; + ret = pthread_cond_timedwait(cond, mtx, ts); + if (ret == ETIMEDOUT) + { + return thrd_timeout; + } + return ret == 0 ? thrd_success : thrd_error; +#endif +} + + +/** Information to pass to the new thread (what to run). */ +typedef struct { + thrd_start_t mFunction; /**< Pointer to the function to be executed. */ + void * mArg; /**< Function argument for the thread function. */ +} _thread_start_info; + +/* Thread wrapper function. */ +#if defined(_TTHREAD_WIN32_) +static unsigned WINAPI _thrd_wrapper_function(void * aArg) +#elif defined(_TTHREAD_POSIX_) +static void * _thrd_wrapper_function(void * aArg) +#endif +{ + thrd_start_t fun; + void *arg; + int res; +#if defined(_TTHREAD_POSIX_) + void *pres; +#endif + + /* Get thread startup information */ + _thread_start_info *ti = (_thread_start_info *) aArg; + fun = ti->mFunction; + arg = ti->mArg; + + /* The thread is responsible for freeing the startup information */ + free((void *)ti); + + /* Call the actual client thread function */ + res = fun(arg); + +#if defined(_TTHREAD_WIN32_) + return res; +#else + pres = malloc(sizeof(int)); + if (pres != NULL) + { + *(int*)pres = res; + } + return pres; +#endif +} + +int thrd_create(thrd_t *thr, thrd_start_t func, void *arg) +{ + /* Fill out the thread startup information (passed to the thread wrapper, + which will eventually free it) */ + _thread_start_info* ti = (_thread_start_info*)malloc(sizeof(_thread_start_info)); + if (ti == NULL) + { + return thrd_nomem; + } + ti->mFunction = func; + ti->mArg = arg; + + /* Create the thread */ +#if defined(_TTHREAD_WIN32_) + *thr = (HANDLE)_beginthreadex(NULL, 0, _thrd_wrapper_function, (void *)ti, 0, NULL); +#elif defined(_TTHREAD_POSIX_) + if(pthread_create(thr, NULL, _thrd_wrapper_function, (void *)ti) != 0) + { + *thr = 0; + } +#endif + + /* Did we fail to create the thread? */ + if(!*thr) + { + free(ti); + return thrd_error; + } + + return thrd_success; +} + +thrd_t thrd_current(void) +{ +#if defined(_TTHREAD_WIN32_) + return GetCurrentThread(); +#else + return pthread_self(); +#endif +} + +int thrd_detach(thrd_t thr) +{ + /* FIXME! */ + (void)thr; + return thrd_error; +} + +int thrd_equal(thrd_t thr0, thrd_t thr1) +{ +#if defined(_TTHREAD_WIN32_) + return thr0 == thr1; +#else + return pthread_equal(thr0, thr1); +#endif +} + +void thrd_exit(int res) +{ +#if defined(_TTHREAD_WIN32_) + ExitThread(res); +#else + void *pres = malloc(sizeof(int)); + if (pres != NULL) + { + *(int*)pres = res; + } + pthread_exit(pres); +#endif +} + +int thrd_join(thrd_t thr, int *res) +{ +#if defined(_TTHREAD_WIN32_) + if (WaitForSingleObject(thr, INFINITE) == WAIT_FAILED) + { + return thrd_error; + } + if (res != NULL) + { + DWORD dwRes; + GetExitCodeThread(thr, &dwRes); + *res = dwRes; + } +#elif defined(_TTHREAD_POSIX_) + void *pres; + int ires = 0; + if (pthread_join(thr, &pres) != 0) + { + return thrd_error; + } + if (pres != NULL) + { + ires = *(int*)pres; + free(pres); + } + if (res != NULL) + { + *res = ires; + } +#endif + return thrd_success; +} + +int thrd_sleep(const struct timespec *time_point, struct timespec *remaining) +{ + struct timespec now; +#if defined(_TTHREAD_WIN32_) + DWORD delta; +#else + long delta; +#endif + + /* Get the current time */ + if (clock_gettime(TIME_UTC, &now) != 0) + return -2; // FIXME: Some specific error code? + +#if defined(_TTHREAD_WIN32_) + /* Delta in milliseconds */ + delta = (DWORD) ((time_point->tv_sec - now.tv_sec) * 1000 + + (time_point->tv_nsec - now.tv_nsec + 500000) / 1000000); + if (delta > 0) + { + Sleep(delta); + } +#else + /* Delta in microseconds */ + delta = (time_point->tv_sec - now.tv_sec) * 1000000L + + (time_point->tv_nsec - now.tv_nsec + 500L) / 1000L; + + /* On some systems, the usleep argument must be < 1000000 */ + while (delta > 999999L) + { + usleep(999999); + delta -= 999999L; + } + if (delta > 0L) + { + usleep((useconds_t)delta); + } +#endif + + /* We don't support waking up prematurely (yet) */ + if (remaining) + { + remaining->tv_sec = 0; + remaining->tv_nsec = 0; + } + return 0; +} + +void thrd_yield(void) +{ +#if defined(_TTHREAD_WIN32_) + Sleep(0); +#else + sched_yield(); +#endif +} + +int tss_create(tss_t *key, tss_dtor_t dtor) +{ +#if defined(_TTHREAD_WIN32_) + /* FIXME: The destructor function is not supported yet... */ + if (dtor != NULL) + { + return thrd_error; + } + *key = TlsAlloc(); + if (*key == TLS_OUT_OF_INDEXES) + { + return thrd_error; + } +#else + if (pthread_key_create(key, dtor) != 0) + { + return thrd_error; + } +#endif + return thrd_success; +} + +void tss_delete(tss_t key) +{ +#if defined(_TTHREAD_WIN32_) + TlsFree(key); +#else + pthread_key_delete(key); +#endif +} + +void *tss_get(tss_t key) +{ +#if defined(_TTHREAD_WIN32_) + return TlsGetValue(key); +#else + return pthread_getspecific(key); +#endif +} + +int tss_set(tss_t key, void *val) +{ +#if defined(_TTHREAD_WIN32_) + if (TlsSetValue(key, val) == 0) + { + return thrd_error; + } +#else + if (pthread_setspecific(key, val) != 0) + { + return thrd_error; + } +#endif + return thrd_success; +} + +#if defined(_TTHREAD_EMULATE_CLOCK_GETTIME_) +int _tthread_clock_gettime(clockid_t clk_id, struct timespec *ts) +{ +#if defined(_TTHREAD_WIN32_) + struct _timeb tb; + _ftime(&tb); + ts->tv_sec = (time_t)tb.time; + ts->tv_nsec = 1000000L * (long)tb.millitm; +#else + struct timeval tv; + gettimeofday(&tv, NULL); + ts->tv_sec = (time_t)tv.tv_sec; + ts->tv_nsec = 1000L * (long)tv.tv_usec; +#endif + return 0; +} +#endif // _TTHREAD_EMULATE_CLOCK_GETTIME_ + diff --git a/testbed/glfw/deps/tinycthread.h b/testbed/glfw/deps/tinycthread.h new file mode 100644 index 00000000..86a90804 --- /dev/null +++ b/testbed/glfw/deps/tinycthread.h @@ -0,0 +1,440 @@ +/* -*- mode: c; tab-width: 2; indent-tabs-mode: nil; -*- +Copyright (c) 2012 Marcus Geelnard + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +*/ + +#ifndef _TINYCTHREAD_H_ +#define _TINYCTHREAD_H_ + +/** +* @file +* @mainpage TinyCThread API Reference +* +* @section intro_sec Introduction +* TinyCThread is a minimal, portable implementation of basic threading +* classes for C. +* +* They closely mimic the functionality and naming of the C11 standard, and +* should be easily replaceable with the corresponding standard variants. +* +* @section port_sec Portability +* The Win32 variant uses the native Win32 API for implementing the thread +* classes, while for other systems, the POSIX threads API (pthread) is used. +* +* @section misc_sec Miscellaneous +* The following special keywords are available: #_Thread_local. +* +* For more detailed information, browse the different sections of this +* documentation. A good place to start is: +* tinycthread.h. +*/ + +/* Which platform are we on? */ +#if !defined(_TTHREAD_PLATFORM_DEFINED_) + #if defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__) + #define _TTHREAD_WIN32_ + #else + #define _TTHREAD_POSIX_ + #endif + #define _TTHREAD_PLATFORM_DEFINED_ +#endif + +/* Activate some POSIX functionality (e.g. clock_gettime and recursive mutexes) */ +#if defined(_TTHREAD_POSIX_) + #undef _FEATURES_H + #if !defined(_GNU_SOURCE) + #define _GNU_SOURCE + #endif + #if !defined(_POSIX_C_SOURCE) || ((_POSIX_C_SOURCE - 0) < 199309L) + #undef _POSIX_C_SOURCE + #define _POSIX_C_SOURCE 199309L + #endif + #if !defined(_XOPEN_SOURCE) || ((_XOPEN_SOURCE - 0) < 500) + #undef _XOPEN_SOURCE + #define _XOPEN_SOURCE 500 + #endif +#endif + +/* Generic includes */ +#include + +/* Platform specific includes */ +#if defined(_TTHREAD_POSIX_) + #include +#elif defined(_TTHREAD_WIN32_) + #ifndef WIN32_LEAN_AND_MEAN + #define WIN32_LEAN_AND_MEAN + #define __UNDEF_LEAN_AND_MEAN + #endif + #include + #ifdef __UNDEF_LEAN_AND_MEAN + #undef WIN32_LEAN_AND_MEAN + #undef __UNDEF_LEAN_AND_MEAN + #endif +#endif + +/* Workaround for missing TIME_UTC: If time.h doesn't provide TIME_UTC, + it's quite likely that libc does not support it either. Hence, fall back to + the only other supported time specifier: CLOCK_REALTIME (and if that fails, + we're probably emulating clock_gettime anyway, so anything goes). */ +#ifndef TIME_UTC + #ifdef CLOCK_REALTIME + #define TIME_UTC CLOCK_REALTIME + #else + #define TIME_UTC 0 + #endif +#endif + +/* Workaround for missing clock_gettime (most Windows compilers, afaik) */ +#if defined(_TTHREAD_WIN32_) || defined(__APPLE_CC__) +#define _TTHREAD_EMULATE_CLOCK_GETTIME_ +/* Emulate struct timespec */ +#if defined(_TTHREAD_WIN32_) +struct _ttherad_timespec { + time_t tv_sec; + long tv_nsec; +}; +#define timespec _ttherad_timespec +#endif + +/* Emulate clockid_t */ +typedef int _tthread_clockid_t; +#define clockid_t _tthread_clockid_t + +/* Emulate clock_gettime */ +int _tthread_clock_gettime(clockid_t clk_id, struct timespec *ts); +#define clock_gettime _tthread_clock_gettime +#define CLOCK_REALTIME 0 +#endif + + +/** TinyCThread version (major number). */ +#define TINYCTHREAD_VERSION_MAJOR 1 +/** TinyCThread version (minor number). */ +#define TINYCTHREAD_VERSION_MINOR 1 +/** TinyCThread version (full version). */ +#define TINYCTHREAD_VERSION (TINYCTHREAD_VERSION_MAJOR * 100 + TINYCTHREAD_VERSION_MINOR) + +/** +* @def _Thread_local +* Thread local storage keyword. +* A variable that is declared with the @c _Thread_local keyword makes the +* value of the variable local to each thread (known as thread-local storage, +* or TLS). Example usage: +* @code +* // This variable is local to each thread. +* _Thread_local int variable; +* @endcode +* @note The @c _Thread_local keyword is a macro that maps to the corresponding +* compiler directive (e.g. @c __declspec(thread)). +* @note This directive is currently not supported on Mac OS X (it will give +* a compiler error), since compile-time TLS is not supported in the Mac OS X +* executable format. Also, some older versions of MinGW (before GCC 4.x) do +* not support this directive. +* @hideinitializer +*/ + +/* FIXME: Check for a PROPER value of __STDC_VERSION__ to know if we have C11 */ +#if !(defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201102L)) && !defined(_Thread_local) + #if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_CC) || defined(__IBMCPP__) + #define _Thread_local __thread + #else + #define _Thread_local __declspec(thread) + #endif +#endif + +/* Macros */ +#define TSS_DTOR_ITERATIONS 0 + +/* Function return values */ +#define thrd_error 0 /**< The requested operation failed */ +#define thrd_success 1 /**< The requested operation succeeded */ +#define thrd_timeout 2 /**< The time specified in the call was reached without acquiring the requested resource */ +#define thrd_busy 3 /**< The requested operation failed because a tesource requested by a test and return function is already in use */ +#define thrd_nomem 4 /**< The requested operation failed because it was unable to allocate memory */ + +/* Mutex types */ +#define mtx_plain 1 +#define mtx_timed 2 +#define mtx_try 4 +#define mtx_recursive 8 + +/* Mutex */ +#if defined(_TTHREAD_WIN32_) +typedef struct { + CRITICAL_SECTION mHandle; /* Critical section handle */ + int mAlreadyLocked; /* TRUE if the mutex is already locked */ + int mRecursive; /* TRUE if the mutex is recursive */ +} mtx_t; +#else +typedef pthread_mutex_t mtx_t; +#endif + +/** Create a mutex object. +* @param mtx A mutex object. +* @param type Bit-mask that must have one of the following six values: +* @li @c mtx_plain for a simple non-recursive mutex +* @li @c mtx_timed for a non-recursive mutex that supports timeout +* @li @c mtx_try for a non-recursive mutex that supports test and return +* @li @c mtx_plain | @c mtx_recursive (same as @c mtx_plain, but recursive) +* @li @c mtx_timed | @c mtx_recursive (same as @c mtx_timed, but recursive) +* @li @c mtx_try | @c mtx_recursive (same as @c mtx_try, but recursive) +* @return @ref thrd_success on success, or @ref thrd_error if the request could +* not be honored. +*/ +int mtx_init(mtx_t *mtx, int type); + +/** Release any resources used by the given mutex. +* @param mtx A mutex object. +*/ +void mtx_destroy(mtx_t *mtx); + +/** Lock the given mutex. +* Blocks until the given mutex can be locked. If the mutex is non-recursive, and +* the calling thread already has a lock on the mutex, this call will block +* forever. +* @param mtx A mutex object. +* @return @ref thrd_success on success, or @ref thrd_error if the request could +* not be honored. +*/ +int mtx_lock(mtx_t *mtx); + +/** NOT YET IMPLEMENTED. +*/ +int mtx_timedlock(mtx_t *mtx, const struct timespec *ts); + +/** Try to lock the given mutex. +* The specified mutex shall support either test and return or timeout. If the +* mutex is already locked, the function returns without blocking. +* @param mtx A mutex object. +* @return @ref thrd_success on success, or @ref thrd_busy if the resource +* requested is already in use, or @ref thrd_error if the request could not be +* honored. +*/ +int mtx_trylock(mtx_t *mtx); + +/** Unlock the given mutex. +* @param mtx A mutex object. +* @return @ref thrd_success on success, or @ref thrd_error if the request could +* not be honored. +*/ +int mtx_unlock(mtx_t *mtx); + +/* Condition variable */ +#if defined(_TTHREAD_WIN32_) +typedef struct { + HANDLE mEvents[2]; /* Signal and broadcast event HANDLEs. */ + unsigned int mWaitersCount; /* Count of the number of waiters. */ + CRITICAL_SECTION mWaitersCountLock; /* Serialize access to mWaitersCount. */ +} cnd_t; +#else +typedef pthread_cond_t cnd_t; +#endif + +/** Create a condition variable object. +* @param cond A condition variable object. +* @return @ref thrd_success on success, or @ref thrd_error if the request could +* not be honored. +*/ +int cnd_init(cnd_t *cond); + +/** Release any resources used by the given condition variable. +* @param cond A condition variable object. +*/ +void cnd_destroy(cnd_t *cond); + +/** Signal a condition variable. +* Unblocks one of the threads that are blocked on the given condition variable +* at the time of the call. If no threads are blocked on the condition variable +* at the time of the call, the function does nothing and return success. +* @param cond A condition variable object. +* @return @ref thrd_success on success, or @ref thrd_error if the request could +* not be honored. +*/ +int cnd_signal(cnd_t *cond); + +/** Broadcast a condition variable. +* Unblocks all of the threads that are blocked on the given condition variable +* at the time of the call. If no threads are blocked on the condition variable +* at the time of the call, the function does nothing and return success. +* @param cond A condition variable object. +* @return @ref thrd_success on success, or @ref thrd_error if the request could +* not be honored. +*/ +int cnd_broadcast(cnd_t *cond); + +/** Wait for a condition variable to become signaled. +* The function atomically unlocks the given mutex and endeavors to block until +* the given condition variable is signaled by a call to cnd_signal or to +* cnd_broadcast. When the calling thread becomes unblocked it locks the mutex +* before it returns. +* @param cond A condition variable object. +* @param mtx A mutex object. +* @return @ref thrd_success on success, or @ref thrd_error if the request could +* not be honored. +*/ +int cnd_wait(cnd_t *cond, mtx_t *mtx); + +/** Wait for a condition variable to become signaled. +* The function atomically unlocks the given mutex and endeavors to block until +* the given condition variable is signaled by a call to cnd_signal or to +* cnd_broadcast, or until after the specified time. When the calling thread +* becomes unblocked it locks the mutex before it returns. +* @param cond A condition variable object. +* @param mtx A mutex object. +* @param xt A point in time at which the request will time out (absolute time). +* @return @ref thrd_success upon success, or @ref thrd_timeout if the time +* specified in the call was reached without acquiring the requested resource, or +* @ref thrd_error if the request could not be honored. +*/ +int cnd_timedwait(cnd_t *cond, mtx_t *mtx, const struct timespec *ts); + +/* Thread */ +#if defined(_TTHREAD_WIN32_) +typedef HANDLE thrd_t; +#else +typedef pthread_t thrd_t; +#endif + +/** Thread start function. +* Any thread that is started with the @ref thrd_create() function must be +* started through a function of this type. +* @param arg The thread argument (the @c arg argument of the corresponding +* @ref thrd_create() call). +* @return The thread return value, which can be obtained by another thread +* by using the @ref thrd_join() function. +*/ +typedef int (*thrd_start_t)(void *arg); + +/** Create a new thread. +* @param thr Identifier of the newly created thread. +* @param func A function pointer to the function that will be executed in +* the new thread. +* @param arg An argument to the thread function. +* @return @ref thrd_success on success, or @ref thrd_nomem if no memory could +* be allocated for the thread requested, or @ref thrd_error if the request +* could not be honored. +* @note A thread’s identifier may be reused for a different thread once the +* original thread has exited and either been detached or joined to another +* thread. +*/ +int thrd_create(thrd_t *thr, thrd_start_t func, void *arg); + +/** Identify the calling thread. +* @return The identifier of the calling thread. +*/ +thrd_t thrd_current(void); + +/** NOT YET IMPLEMENTED. +*/ +int thrd_detach(thrd_t thr); + +/** Compare two thread identifiers. +* The function determines if two thread identifiers refer to the same thread. +* @return Zero if the two thread identifiers refer to different threads. +* Otherwise a nonzero value is returned. +*/ +int thrd_equal(thrd_t thr0, thrd_t thr1); + +/** Terminate execution of the calling thread. +* @param res Result code of the calling thread. +*/ +void thrd_exit(int res); + +/** Wait for a thread to terminate. +* The function joins the given thread with the current thread by blocking +* until the other thread has terminated. +* @param thr The thread to join with. +* @param res If this pointer is not NULL, the function will store the result +* code of the given thread in the integer pointed to by @c res. +* @return @ref thrd_success on success, or @ref thrd_error if the request could +* not be honored. +*/ +int thrd_join(thrd_t thr, int *res); + +/** Put the calling thread to sleep. +* Suspend execution of the calling thread. +* @param time_point A point in time at which the thread will resume (absolute time). +* @param remaining If non-NULL, this parameter will hold the remaining time until +* time_point upon return. This will typically be zero, but if +* the thread was woken up by a signal that is not ignored before +* time_point was reached @c remaining will hold a positive +* time. +* @return 0 (zero) on successful sleep, or -1 if an interrupt occurred. +*/ +int thrd_sleep(const struct timespec *time_point, struct timespec *remaining); + +/** Yield execution to another thread. +* Permit other threads to run, even if the current thread would ordinarily +* continue to run. +*/ +void thrd_yield(void); + +/* Thread local storage */ +#if defined(_TTHREAD_WIN32_) +typedef DWORD tss_t; +#else +typedef pthread_key_t tss_t; +#endif + +/** Destructor function for a thread-specific storage. +* @param val The value of the destructed thread-specific storage. +*/ +typedef void (*tss_dtor_t)(void *val); + +/** Create a thread-specific storage. +* @param key The unique key identifier that will be set if the function is +* successful. +* @param dtor Destructor function. This can be NULL. +* @return @ref thrd_success on success, or @ref thrd_error if the request could +* not be honored. +* @note The destructor function is not supported under Windows. If @c dtor is +* not NULL when calling this function under Windows, the function will fail +* and return @ref thrd_error. +*/ +int tss_create(tss_t *key, tss_dtor_t dtor); + +/** Delete a thread-specific storage. +* The function releases any resources used by the given thread-specific +* storage. +* @param key The key that shall be deleted. +*/ +void tss_delete(tss_t key); + +/** Get the value for a thread-specific storage. +* @param key The thread-specific storage identifier. +* @return The value for the current thread held in the given thread-specific +* storage. +*/ +void *tss_get(tss_t key); + +/** Set the value for a thread-specific storage. +* @param key The thread-specific storage identifier. +* @param val The value of the thread-specific storage to set for the current +* thread. +* @return @ref thrd_success on success, or @ref thrd_error if the request could +* not be honored. +*/ +int tss_set(tss_t key, void *val); + + +#endif /* _TINYTHREAD_H_ */ + diff --git a/testbed/glfw/docs/CMakeLists.txt b/testbed/glfw/docs/CMakeLists.txt new file mode 100644 index 00000000..45a6162e --- /dev/null +++ b/testbed/glfw/docs/CMakeLists.txt @@ -0,0 +1,5 @@ + +add_custom_target(docs ALL ${DOXYGEN_EXECUTABLE} + WORKING_DIRECTORY ${GLFW_BINARY_DIR}/docs + COMMENT "Generating HTML documentation" VERBATIM) + diff --git a/testbed/glfw/docs/Doxyfile.in b/testbed/glfw/docs/Doxyfile.in new file mode 100644 index 00000000..8410a850 --- /dev/null +++ b/testbed/glfw/docs/Doxyfile.in @@ -0,0 +1,1863 @@ +# Doxyfile 1.8.3.1 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" "). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or sequence of words) that should +# identify the project. Note that if you do not use Doxywizard you need +# to put quotes around the project name if it contains spaces. + +PROJECT_NAME = "GLFW" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = @GLFW_VERSION_FULL@ + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer +# a quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = "A multi-platform library for OpenGL, window and input" + +# With the PROJECT_LOGO tag one can specify an logo or icon that is +# included in the documentation. The maximum height of the logo should not +# exceed 55 pixels and the maximum width should not exceed 200 pixels. +# Doxygen will copy the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = @GLFW_BINARY_DIR@/docs + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = NO + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = YES + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. Note that you specify absolute paths here, but also +# relative paths, which will be relative from the directory where doxygen is +# started. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful if your file system +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding +# "class=itcl::class" will allow you to use the command class in the +# itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, +# and language is one of the parsers supported by doxygen: IDL, Java, +# Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, +# C++. For instance to make doxygen treat .inc files as Fortran files (default +# is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note +# that for custom extensions you also need to set FILE_PATTERNS otherwise the +# files are not read by doxygen. + +EXTENSION_MAPPING = + +# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all +# comments according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you +# can mix doxygen, HTML, and XML commands with Markdown formatting. +# Disable only in case of backward compatibilities issues. + +MARKDOWN_SUPPORT = YES + +# When enabled doxygen tries to link words that correspond to documented classes, +# or namespaces to their corresponding documentation. Such a link can be +# prevented in individual cases by by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also makes the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES (the +# default) will make doxygen replace the get and set methods by a property in +# the documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = NO + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and +# unions are shown inside the group in which they are included (e.g. using +# @ingroup) instead of on a separate page (for HTML and Man pages) or +# section (for LaTeX and RTF). + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and +# unions with only public data fields will be shown inline in the documentation +# of the scope in which they are defined (i.e. file, namespace, or group +# documentation), provided this scope is documented. If set to NO (the default), +# structs, classes, and unions are shown on a separate page (for HTML and Man +# pages) or section (for LaTeX and RTF). + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be +# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given +# their name and scope. Since this can be an expensive process and often the +# same symbol appear multiple times in the code, doxygen keeps a cache of +# pre-resolved symbols. If the cache is too small doxygen will become slower. +# If the cache is too large, memory is wasted. The cache size is given by this +# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal +# scope will be included in the documentation. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespaces are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = YES + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to +# do proper type resolution of all parameters of a function it will reject a +# match between the prototype and the implementation of a member function even +# if there is only one candidate or it is obvious which candidate to choose +# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen +# will still accept a match between prototype and implementation in such cases. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if section-label ... \endif +# and \cond section-label ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or macro consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and macros in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. +# This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = NO + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files +# containing the references data. This must be a list of .bib files. The +# .bib extension is automatically appended if omitted. Using this command +# requires the bibtex tool to be installed. See also +# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style +# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this +# feature you need bibtex and perl available in the search path. Do not use +# file names with spaces, bibtex cannot handle them. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = YES + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_NO_PARAMDOC option can be enabled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = YES + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = @GLFW_BINARY_DIR@/docs/warnings.txt + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = @GLFW_INTERNAL_DOCS@ \ + @GLFW_SOURCE_DIR@/include/GLFW/glfw3.h \ + @GLFW_SOURCE_DIR@/include/GLFW/glfw3native.h \ + @GLFW_SOURCE_DIR@/docs/main.dox \ + @GLFW_SOURCE_DIR@/docs/news.dox \ + @GLFW_SOURCE_DIR@/docs/moving.dox \ + @GLFW_SOURCE_DIR@/docs/quick.dox \ + @GLFW_SOURCE_DIR@/docs/compile.dox \ + @GLFW_SOURCE_DIR@/docs/build.dox \ + @GLFW_SOURCE_DIR@/docs/intro.dox \ + @GLFW_SOURCE_DIR@/docs/context.dox \ + @GLFW_SOURCE_DIR@/docs/monitor.dox \ + @GLFW_SOURCE_DIR@/docs/window.dox \ + @GLFW_SOURCE_DIR@/docs/input.dox \ + @GLFW_SOURCE_DIR@/docs/rift.dox \ + @GLFW_SOURCE_DIR@/docs/compat.dox + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh +# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py +# *.f90 *.f *.for *.vhd *.vhdl + +FILE_PATTERNS = *.h *.dox + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = APIENTRY GLFWAPI + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = @GLFW_SOURCE_DIR@/examples + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. +# If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. +# Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. +# The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty or if +# non of the patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) +# and it is also possible to disable source filtering for a specific pattern +# using *.ext= (so without naming a filter). This option only has effect when +# FILTER_SOURCE_FILES is enabled. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MD_FILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page (index.html). +# This can be useful if you have a project on for instance GitHub and want reuse +# the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C, C++ and Fortran comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. +# Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = glfw GLFW_ + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. Note that when using a custom header you are responsible +# for the proper inclusion of any scripts and style sheets that doxygen +# needs, which is dependent on the configuration options used. +# It is advised to generate a default header using "doxygen -w html +# header.html footer.html stylesheet.css YourConfigFile" and then modify +# that header. Note that the header is subject to change so you typically +# have to redo this when upgrading to a newer version of doxygen or when +# changing the value of configuration settings such as GENERATE_TREEVIEW! + +HTML_HEADER = @GLFW_SOURCE_DIR@/docs/header.html + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = @GLFW_SOURCE_DIR@/docs/footer.html + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If left blank doxygen will +# generate a default style sheet. Note that it is recommended to use +# HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this +# tag will in the future become obsolete. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional +# user-defined cascading style sheet that is included after the standard +# style sheets created by doxygen. Using this option one can overrule +# certain style aspects. This is preferred over using HTML_STYLESHEET +# since it does not replace the standard style sheet and is therefor more +# robust against future updates. Doxygen will copy the style sheet file to +# the output directory. + +HTML_EXTRA_STYLESHEET = @GLFW_SOURCE_DIR@/docs/extra.css + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that +# the files will be copied as-is; there are no commands or markers available. + +HTML_EXTRA_FILES = @GLFW_SOURCE_DIR@/docs/spaces.svg + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the style sheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of +# entries shown in the various tree structured indices initially; the user +# can expand and collapse entries dynamically later on. Doxygen will expand +# the tree to such a level that at most the specified number of entries are +# visible (unless a fully collapsed tree already exceeds this amount). +# So setting the number of entries 1 will produce a full collapsed tree by +# default. 0 is a special value representing an infinite number of entries +# and will result in a full expanded tree by default. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely +# identify the documentation publisher. This should be a reverse domain-name +# style string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) +# at top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. Since the tabs have the same information as the +# navigation tree you can set this option to NO if you already set +# GENERATE_TREEVIEW to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. +# Since the tree basically has the same information as the tab index you +# could consider to set DISABLE_INDEX to NO when enabling this option. + +GENERATE_TREEVIEW = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values +# (range [0,1..20]) that doxygen will group on one line in the generated HTML +# documentation. Note that a value of 0 will completely suppress the enum +# values from appearing in the overview section. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 300 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax +# (see http://www.mathjax.org) which uses client side Javascript for the +# rendering instead of using prerendered bitmaps. Use this if you do not +# have LaTeX installed or if you want to formulas look prettier in the HTML +# output. When enabled you may also need to install MathJax separately and +# configure the path to it using the MATHJAX_RELPATH option. + +USE_MATHJAX = NO + +# When MathJax is enabled you can set the default output format to be used for +# thA MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and +# SVG. The default value is HTML-CSS, which is slower, but has the best +# compatibility. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the +# HTML output directory using the MATHJAX_RELPATH option. The destination +# directory should contain the MathJax.js script. For instance, if the mathjax +# directory is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to +# the MathJax Content Delivery Network so you can quickly see the result without +# installing MathJax. +# However, it is strongly recommended to install a local +# copy of MathJax from http://www.mathjax.org before deployment. + +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest + +# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension +# names that should be enabled during MathJax rendering. + +MATHJAX_EXTENSIONS = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a web server instead of a web client using Javascript. +# There are two flavours of web server based search depending on the +# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for +# searching and an index file used by the script. When EXTERNAL_SEARCH is +# enabled the indexing and searching needs to be provided by external tools. +# See the manual for details. + +SERVER_BASED_SEARCH = NO + +# When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP +# script for searching. Instead the search results are written to an XML file +# which needs to be processed by an external indexer. Doxygen will invoke an +# external search engine pointed to by the SEARCHENGINE_URL option to obtain +# the search results. Doxygen ships with an example indexer (doxyindexer) and +# search engine (doxysearch.cgi) which are based on the open source search engine +# library Xapian. See the manual for configuration details. + +EXTERNAL_SEARCH = NO + +# The SEARCHENGINE_URL should point to a search engine hosted by a web server +# which will returned the search results when EXTERNAL_SEARCH is enabled. +# Doxygen ships with an example search engine (doxysearch) which is based on +# the open source search engine library Xapian. See the manual for configuration +# details. + +SEARCHENGINE_URL = + +# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed +# search data is written to a file for indexing by an external tool. With the +# SEARCHDATA_FILE tag the name of this file can be specified. + +SEARCHDATA_FILE = searchdata.xml + +# When SERVER_BASED_SEARCH AND EXTERNAL_SEARCH are both enabled the +# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is +# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple +# projects and redirect the results back to the right project. + +EXTERNAL_SEARCH_ID = + +# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen +# projects other than the one defined by this configuration file, but that are +# all added to the same external search index. Each project needs to have a +# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id +# of to a relative location where the documentation can be found. +# The format is: EXTRA_SEARCH_MAPPINGS = id1=loc1 id2=loc2 ... + +EXTRA_SEARCH_MAPPINGS = + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4 + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for +# the generated latex document. The footer should contain everything after +# the last chapter. If it is left blank doxygen will generate a +# standard footer. Notice: only use this tag if you know what you are doing! + +LATEX_FOOTER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +# The LATEX_BIB_STYLE tag can be used to specify the style to use for the +# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See +# http://en.wikipedia.org/wiki/BibTeX for more info. + +LATEX_BIB_STYLE = plain + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load style sheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. +# This is useful +# if you want to understand what is going on. +# On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = YES + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = YES + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# pointed to by INCLUDE_PATH will be searched when a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = GLFWAPI= \ + GLFW_EXPOSE_NATIVE_WIN32 \ + GLFW_EXPOSE_NATIVE_WGL \ + GLFW_EXPOSE_NATIVE_X11 \ + GLFW_EXPOSE_NATIVE_GLX \ + GLFW_EXPOSE_NATIVE_COCOA \ + GLFW_EXPOSE_NATIVE_NSGL \ + GLFW_EXPOSE_NATIVE_EGL + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition that +# overrules the definition found in the source code. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all references to function-like macros +# that are alone on a line, have an all uppercase name, and do not end with a +# semicolon, because these will confuse the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. For each +# tag file the location of the external documentation should be added. The +# format of a tag file without this location is as follows: +# +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths +# or URLs. Note that each tag file must have a unique name (where the name does +# NOT include the path). If a tag file is not located in the directory in which +# doxygen is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option also works with HAVE_DOT disabled, but it is recommended to +# install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will use the Helvetica font for all dot files that +# doxygen generates. When you want a differently looking font you can specify +# the font name using DOT_FONTNAME. You need to make sure dot is able to find +# the font, which can be done by putting it in a standard location or by setting +# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the +# directory containing the font. + +DOT_FONTNAME = Helvetica + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the Helvetica font. +# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to +# set the path where dot can find it. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If the UML_LOOK tag is enabled, the fields and methods are shown inside +# the class node. If there are many fields or methods and many nodes the +# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS +# threshold limits the number of items for each type to make the size more +# managable. Set this to 0 for no limit. Note that the threshold may be +# exceeded by 50% before the limit is enforced. + +UML_LIMIT_NUM_FIELDS = 10 + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will generate a graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are svg, png, jpg, or gif. +# If left blank png will be used. If you choose svg you need to set +# HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible in IE 9+ (other browsers do not have this requirement). + +DOT_IMAGE_FORMAT = png + +# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to +# enable generation of interactive SVG images that allow zooming and panning. +# Note that this requires a modern browser other than Internet Explorer. +# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you +# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible. Older versions of IE do not have SVG support. + +INTERACTIVE_SVG = NO + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the +# \mscfile command). + +MSCFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/testbed/glfw/docs/DoxygenLayout.xml b/testbed/glfw/docs/DoxygenLayout.xml new file mode 100644 index 00000000..7917f91e --- /dev/null +++ b/testbed/glfw/docs/DoxygenLayout.xml @@ -0,0 +1,188 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testbed/glfw/docs/build.dox b/testbed/glfw/docs/build.dox new file mode 100644 index 00000000..4ee79387 --- /dev/null +++ b/testbed/glfw/docs/build.dox @@ -0,0 +1,303 @@ +/*! + +@page build Building applications + +@tableofcontents + +This is about compiling and linking applications that use GLFW. For information on +how to write such applications, start with the [introductory tutorial](@ref quick). +For information on how to compile the GLFW library itself, see the @ref compile +guide. + +This is not a tutorial on compilation or linking. It assumes basic +understanding of how to compile and link a C program as well as how to use the +specific compiler of your chosen development environment. The compilation +and linking process should be explained in your C programming material and in +the documentation for your development environment. + +@section build_include Including the GLFW header file + +In the source files of your application where you use OpenGL or GLFW, you should +include the GLFW header file, i.e.: + +@code +#include +@endcode + +The GLFW header declares the GLFW API and by default also includes the OpenGL +header of your development environment, which in turn defines all the constants, +types and function prototypes of the OpenGL API. + +The GLFW header also defines everything necessary for your OpenGL header to +function. For example, under Windows you are normally required to include +`windows.h` before the OpenGL header, which would pollute your code namespace +with the entire Win32 API. + +Instead, the GLFW header takes care of this for you, not by including +`windows.h`, but by duplicating only the very few necessary parts of it. It +does this only when needed, so if `windows.h` _is_ included, the GLFW header +does not try to redefine those symbols. The reverse is not true, i.e. +`windows.h` cannot cope if any of its symbols have already been defined. + +In other words: + + - Do _not_ include the OpenGL headers yourself, as GLFW does this for you + - Do _not_ include `windows.h` or other platform-specific headers unless you + plan on using those APIs directly + - If you _do_ need to include such headers, do it _before_ including + the GLFW header and it will handle this + +If you are using an OpenGL extension loading library such as +[glad](https://github.com/Dav1dde/glad), the extension loader header should +either be included _before_ the GLFW one, or the `GLFW_INCLUDE_NONE` macro +(described below) should be defined. + + +@subsection build_macros GLFW header option macros + +These macros may be defined before the inclusion of the GLFW header and affect +its behavior. + +`GLFW_DLL` is required on Windows when using the GLFW DLL, to tell the compiler +that the GLFW functions are defined in a DLL. + +The following macros control which OpenGL or OpenGL ES API header is included. + +`GLFW_INCLUDE_GLCOREARB` makes the GLFW header include the modern +`GL/glcorearb.h` header (`OpenGL/gl3.h` on OS X) instead of the regular OpenGL +header. + +`GLFW_INCLUDE_ES1` makes the GLFW header include the OpenGL ES 1.x `GLES/gl.h` +header instead of the regular OpenGL header. + +`GLFW_INCLUDE_ES2` makes the GLFW header include the OpenGL ES 2.0 `GLES2/gl2.h` +header instead of the regular OpenGL header. + +`GLFW_INCLUDE_ES3` makes the GLFW header include the OpenGL ES 3.0 `GLES3/gl3.h` +header instead of the regular OpenGL header. + +`GLFW_INCLUDE_ES31` makes the GLFW header include the OpenGL ES 3.1 `GLES3/gl31.h` +header instead of the regular OpenGL header. + +`GLFW_INCLUDE_NONE` makes the GLFW header not include any OpenGL or OpenGL ES API +header. This is useful in combination with an extension loading library. + +If none of the above inclusion macros are defined, the standard OpenGL `GL/gl.h` +header (`OpenGL/gl.h` on OS X) is included. + +`GLFW_INCLUDE_GLEXT` makes the GLFW header include the appropriate extension +header for the OpenGL or OpenGL ES header selected above after and _in addition +to_ that header. + +`GLFW_INCLUDE_GLU` makes the header include the GLU header _in addition to_ the +header selected above. This should only be used with the standard OpenGL header +and only for legacy code. GLU has been deprecated and should not be used in new +code. + +@note GLFW does not provide any of the API headers mentioned above. They must +be provided by your development environment or your OpenGL or OpenGL ES SDK. + + +@section build_link Link with the right libraries + +GLFW is essentially a wrapper of various platform-specific APIs and therefore +needs to link against many different system libraries. If you are using GLFW as +a shared library / dynamic library / DLL then it takes care of these links. +However, if you are using GLFW as a static library then your executable will +need to link against these libraries. + +On Windows and OS X, the list of system libraries is static and can be +hard-coded into your build environment. See the section for your development +environment below. On Linux and other Unix-like operating systems, the list +varies but can be retrieved in various ways as described below. + +A good general introduction to linking is +[Beginner's Guide to Linkers](http://www.lurklurk.org/linkers/linkers.html) by +David Drysdale. + + +@subsection build_link_win32 With MinGW or Visual C++ on Windows + +The static version of the GLFW library is named `glfw3`. When using this +version, it is also necessary to link with some libraries that GLFW uses. + +When linking an application under Windows that uses the static version of GLFW, +you must link with `opengl32`. On some versions of MinGW, you must also +explicitly link with `gdi32`, while other versions of MinGW include it in the +set of default libraries along with other dependencies like `user32` and +`kernel32`. If you are using GLU, you must also link with `glu32`. + +The link library for the GLFW DLL is named `glfw3dll`. When compiling an +application that uses the DLL version of GLFW, you need to define the `GLFW_DLL` +macro _before_ any inclusion of the GLFW header. This can be done either with +a compiler switch or by defining it in your source code. + +An application using the GLFW DLL does not need to link against any of its +dependencies, but you still have to link against `opengl32` if your application +uses OpenGL and `glu32` if it uses GLU. + + +@subsection build_link_cmake_source With CMake and GLFW source + +With just a few changes to your `CMakeLists.txt` you can have the GLFW source +tree built along with your application. + +Firstly, add the root directory of the GLFW source tree to your project. This +will add the `glfw` target and the necessary cache variables to your project. + +@code{.cmake} +add_subdirectory(path/to/glfw) +@endcode + +To be able to include the GLFW header from your code, you need to tell the +compiler where to find it. + +@code{.cmake} +include_directories(path/to/glfw/include) +@endcode + +Once GLFW has been added to the project, the `GLFW_LIBRARIES` cache variable +contains all link-time dependencies of GLFW as it is currently configured. To +link against GLFW, link against them and the `glfw` target. + +@code{.cmake} +target_link_libraries(myapp glfw ${GLFW_LIBRARIES}) +@endcode + +Note that `GLFW_LIBRARIES` does not include GLU, as GLFW does not use it. If +your application needs GLU, you can add it to the list of dependencies with the +`OPENGL_glu_LIBRARY` cache variable, which is implicitly created when the GLFW +CMake files look for OpenGL. + +@code{.cmake} +target_link_libraries(myapp glfw ${OPENGL_glu_LIBRARY} ${GLFW_LIBRARIES}) +@endcode + + +@subsection build_link_cmake_pkgconfig With CMake on Unix and installed GLFW binaries + +CMake can import settings from pkg-config, which GLFW supports. When you +installed GLFW, the pkg-config file `glfw3.pc` was installed along with it. + +First you need to find the PkgConfig package. If this fails, you may need to +install the pkg-config package for your distribution. + +@code{.cmake} +find_package(PkgConfig REQUIRED) +@endcode + +This creates the CMake commands to find pkg-config packages. Then you need to +find the GLFW package. + +@code{.cmake} +pkg_search_module(GLFW REQUIRED glfw3) +@endcode + +This creates the CMake variables you need to use GLFW. To be able to include +the GLFW header, you need to tell your compiler where it is. + +@code{.cmake} +include_directories(${GLFW_INCLUDE_DIRS}) +@endcode + +You also need to link against the correct libraries. If you are using the +shared library version of GLFW, use the `GLFW_LIBRARIES` variable. + +@code{.cmake} +target_link_libraries(simple ${GLFW_LIBRARIES}) +@endcode + +If you are using the static library version of GLFW, use the +`GLFW_STATIC_LIBRARIES` variable instead. + +@code{.cmake} +target_link_libraries(simple ${GLFW_STATIC_LIBRARIES}) +@endcode + + +@subsection build_link_pkgconfig With pkg-config on OS X or other Unix + +GLFW supports [pkg-config](http://www.freedesktop.org/wiki/Software/pkg-config/), +and the `glfw3.pc` pkf-config file is generated when the GLFW library is built +and is installed along with it. A pkg-config file describes all necessary +compile-time and link-time flags and dependencies needed to use a library. When +they are updated or if they differ between systems, you will get the correct +ones automatically. + +A typical compile and link command-line when using the static version of the +GLFW library may look like this: + +@code{.sh} +cc `pkg-config --cflags glfw3` -o myprog myprog.c `pkg-config --static --libs glfw3` +@endcode + +If you are using the shared version of the GLFW library, simply omit the +`--static` flag. + +@code{.sh} +cc `pkg-config --cflags glfw3` -o myprog myprog.c `pkg-config --libs glfw3` +@endcode + +You can also use the `glfw3.pc` file without installing it first, by using the +`PKG_CONFIG_PATH` environment variable. + +@code{.sh} +env PKG_CONFIG_PATH=path/to/glfw/src cc `pkg-config --cflags glfw3` -o myprog myprog.c `pkg-config --libs glfw3` +@endcode + +The dependencies do not include GLU, as GLFW does not need it. On OS X, GLU is +built into the OpenGL framework, so if you need GLU you don't need to do +anything extra. If you need GLU and are using Linux or BSD, you should add the +`glu` pkg-config module. + +@code{.sh} +cc `pkg-config --cflags glfw3 glu` -o myprog myprog.c `pkg-config --libs glfw3 glu` +@endcode + +If you are using the static version of the GLFW library, make sure you don't link statically against GLU. + +@code{.sh} +cc `pkg-config --cflags glfw3 glu` -o myprog myprog.c `pkg-config --static --libs glfw3` `pkg-config --libs glu` +@endcode + + +@subsection build_link_xcode With Xcode on OS X + +If you are using the dynamic library version of GLFW, simply add it to the +project dependencies. + +If you are using the static library version of GLFW, add it and the Cocoa, +OpenGL, IOKit, CoreVideo and Carbon frameworks to the project as dependencies. +They can all be found in `/System/Library/Frameworks`. + +@note GLFW needs the Carbon framework only to access the current keyboard layout +via the Text Input Source Services. This is one of the non-deprecated parts of +the Carbon API and the only way to access this information on OS X. + + +@subsection build_link_osx With command-line on OS X + +It is recommended that you use [pkg-config](@ref build_link_pkgconfig) when +building from the command line on OS X. That way you will get any new +dependencies added automatically. If you still wish to build manually, you need +to add the required frameworks and libraries to your command-line yourself using +the `-l` and `-framework` switches. + +If you are using the dynamic GLFW library, which is named `libglfw.3.dylib`, do: + +@code{.sh} +cc -o myprog myprog.c -lglfw -framework Cocoa -framework OpenGL -framework IOKit -framework CoreVideo +@endcode + +If you are using the static library, named `libglfw3.a`, substitute `-lglfw3` +for `-lglfw`. + +Note that you do not add the `.framework` extension to a framework when linking +against it from the command-line. + +The OpenGL framework contains both the OpenGL and GLU APIs, so there is nothing +special to do when using GLU. Also note that even though your machine may have +`libGL`-style OpenGL libraries, they are for use with the X Window System and +will _not_ work with the OS X native version of GLFW. + +*/ diff --git a/testbed/glfw/docs/compat.dox b/testbed/glfw/docs/compat.dox new file mode 100644 index 00000000..7ff4ab04 --- /dev/null +++ b/testbed/glfw/docs/compat.dox @@ -0,0 +1,179 @@ +/*! + +@page compat Standards conformance + +@tableofcontents + +This guide describes the various API extensions used by this version of GLFW. +It lists what are essentially implementation details, but which are nonetheless +vital knowledge for developers intending to deploy their applications on a wide +range of machines. + +The information in this guide is not a part of GLFW API, but merely +preconditions for some parts of the library to function on a given machine. Any +part of this information may change in future versions of GLFW and that will not +be considered a breaking API change. + + +@section compat_x11 X11 extensions, protocols and IPC standards + +As GLFW uses Xlib directly, without any intervening toolkit +library, it has sole responsibility for interacting well with the many and +varied window managers in use on Unix-like systems. In order for applications +and window managers to work well together, a number of standards and +conventions have been developed that regulate behavior outside the scope of the +X11 API; most importantly the +[Inter-Client Communication Conventions Manual](http://www.tronche.com/gui/x/icccm/) +(ICCCM) and +[Extended Window Manager Hints](http://standards.freedesktop.org/wm-spec/wm-spec-latest.html) +(EWMH) standards. + +GLFW uses the `_MOTIF_WM_HINTS` window property to support borderless windows. +If the running window manager does not support this property, the +`GLFW_DECORATED` hint will have no effect. + +GLFW uses the ICCCM `WM_DELETE_WINDOW` protocol to intercept the user +attempting to close the GLFW window. If the running window manager does not +support this protocol, the close callback will never be called. + +GLFW uses the EWMH `_NET_WM_PING` protocol, allowing the window manager notify +the user when the application has stopped responding, i.e. when it has ceased to +process events. If the running window manager does not support this protocol, +the user will not be notified if the application locks up. + +GLFW uses the EWMH `_NET_WM_STATE_FULLSCREEN` window state to tell the window +manager to make the GLFW window full screen. If the running window manager does +not support this state, full screen windows may not work properly. GLFW has +a fallback code path in case this state is unavailable, but every window manager +behaves slightly differently in this regard. + +GLFW uses the EWMH `_NET_WM_BYPASS_COMPOSITOR` window property to tell a +compositing window manager to un-redirect full screen GLFW windows. If the +running window manager uses compositing but does not support this property then +additional copying may be performed for each buffer swap of full screen windows. + +GLFW uses the +[clipboard manager protocol](http://www.freedesktop.org/wiki/ClipboardManager/) +to push a clipboard string (i.e. selection) owned by a GLFW window about to be +destroyed to the clipboard manager. If there is no running clipboard manager, +the clipboard string will be unavailable once the window has been destroyed. + +GLFW uses the +[X drag-and-drop protocol](http://www.freedesktop.org/wiki/Specifications/XDND/) +to provide file drop events. If the application originating the drag does not +support this protocol, drag and drop will not work. + +GLFW uses the XInput 2 extension to provide sub-pixel cursor motion events. If +the running X server does not support this version of this extension, cursor +motion will be snapped to the pixel grid. + +GLFW uses the XRandR 1.3 extension to provide multi-monitor support. If the +running X server does not support this version of this extension, multi-monitor +support will not function and only a single, desktop-spanning monitor will be +reported. + +GLFW uses the XRandR 1.3 and Xf86vidmode extensions to provide gamma ramp +support. If the running X server does not support either or both of these +extensions, gamma ramp support will not function. + +GLFW uses the Xkb extension and detectable auto-repeat to provide keyboard +input. If the running X server does not support this extension, a non-Xkb +fallback path is used. + + +@section compat_glx GLX extensions + +The GLX API is the default API used to create OpenGL contexts on Unix-like +systems using the X Window System. + +GLFW uses the GLX 1.3 `GLXFBConfig` functions to enumerate and select framebuffer pixel +formats. If GLX 1.3 is not supported, @ref glfwInit will fail. + +GLFW uses the `GLX_MESA_swap_control,` `GLX_EXT_swap_control` and +`GLX_SGI_swap_control` extensions to provide vertical retrace synchronization +(or _vsync_), in that order of preference. Where none of these extension are +available, calling @ref glfwSwapInterval will have no effect. + +GLFW uses the `GLX_ARB_multisample` extension to create contexts with +multisampling anti-aliasing. Where this extension is unavailable, the +`GLFW_SAMPLES` hint will have no effect. + +GLFW uses the `GLX_ARB_create_context` extension when available, even when +creating OpenGL contexts of version 2.1 and below. Where this extension is +unavailable, the `GLFW_CONTEXT_VERSION_MAJOR` and `GLFW_CONTEXT_VERSION_MINOR` +hints will only be partially supported, the `GLFW_OPENGL_DEBUG_CONTEXT` hint +will have no effect, and setting the `GLFW_OPENGL_PROFILE` or +`GLFW_OPENGL_FORWARD_COMPAT` hints to `GL_TRUE` will cause @ref +glfwCreateWindow to fail. + +GLFW uses the `GLX_ARB_create_context_profile` extension to provide support for +context profiles. Where this extension is unavailable, setting the +`GLFW_OPENGL_PROFILE` hint to anything but `GLFW_OPENGL_ANY_PROFILE`, or setting +`GLFW_CLIENT_API` to anything but `GLFW_OPENGL_API` will cause @ref +glfwCreateWindow to fail. + +GLFW uses the `GLX_ARB_context_flush_control` extension to provide control over +whether a context is flushed when it is released (made non-current). Where this +extension is unavailable, the `GLFW_CONTEXT_RELEASE_BEHAVIOR` hint will have no +effect and the context will always be flushed when released. + +@section compat_wgl WGL extensions + +The WGL API is used to create OpenGL contexts on Microsoft Windows and other +implementations of the Win32 API, such as Wine. + +GLFW uses either the `WGL_EXT_extension_string` or the +`WGL_ARB_extension_string` extension to check for the presence of all other WGL +extensions listed below. If both are available, the EXT one is preferred. If +neither is available, no other extensions are used and many GLFW features +related to context creation will have no effect or cause errors when used. + +GLFW uses the `WGL_EXT_swap_control` extension to provide vertical retrace +synchronization (or _vsync_). Where this extension is unavailable, calling @ref +glfwSwapInterval will have no effect. + +GLFW uses the `WGL_ARB_pixel_format` and `WGL_ARB_multisample` extensions to +create contexts with multisampling anti-aliasing. Where these extensions are +unavailable, the `GLFW_SAMPLES` hint will have no effect. + +GLFW uses the `WGL_ARB_create_context` extension when available, even when +creating OpenGL contexts of version 2.1 and below. Where this extension is +unavailable, the `GLFW_CONTEXT_VERSION_MAJOR` and `GLFW_CONTEXT_VERSION_MINOR` +hints will only be partially supported, the `GLFW_OPENGL_DEBUG_CONTEXT` hint +will have no effect, and setting the `GLFW_OPENGL_PROFILE` or +`GLFW_OPENGL_FORWARD_COMPAT` hints to `GL_TRUE` will cause @ref +glfwCreateWindow to fail. + +GLFW uses the `WGL_ARB_create_context_profile` extension to provide support for +context profiles. Where this extension is unavailable, setting the +`GLFW_OPENGL_PROFILE` hint to anything but `GLFW_OPENGL_ANY_PROFILE` will cause +@ref glfwCreateWindow to fail. + +GLFW uses the `WGL_ARB_context_flush_control` extension to provide control over +whether a context is flushed when it is released (made non-current). Where this +extension is unavailable, the `GLFW_CONTEXT_RELEASE_BEHAVIOR` hint will have no +effect and the context will always be flushed when released. + +@section compat_osx OpenGL 3.2 and later on OS X + +Support for OpenGL 3.2 and above was introduced with OS X 10.7 and even then +only forward-compatible, core profile contexts are supported. Support for +OpenGL 4.1 was introduced with OS X 10.9, also limited to forward-compatible, +core profile contexts. There is also still no mechanism for requesting debug +contexts. Versions of Mac OS X earlier than 10.7 support at most OpenGL +version 2.1. + +Because of this, on OS X 10.7 and later, the `GLFW_CONTEXT_VERSION_MAJOR` and +`GLFW_CONTEXT_VERSION_MINOR` hints will cause @ref glfwCreateWindow to fail if +given version 3.0 or 3.1, the `GLFW_OPENGL_FORWARD_COMPAT` hint must be set to +`GL_TRUE` and the `GLFW_OPENGL_PROFILE` hint must be set to +`GLFW_OPENGL_CORE_PROFILE` when creating OpenGL 3.2 and later contexts and the +`GLFW_OPENGL_DEBUG_CONTEXT` hint is ignored. + +Also, on Mac OS X 10.6 and below, the `GLFW_CONTEXT_VERSION_MAJOR` and +`GLFW_CONTEXT_VERSION_MINOR` hints will fail if given a version above 2.1, +setting the `GLFW_OPENGL_PROFILE` or `GLFW_OPENGL_FORWARD_COMPAT` hints to +a non-default value will cause @ref glfwCreateWindow to fail and the +`GLFW_OPENGL_DEBUG_CONTEXT` hint is ignored. + +*/ diff --git a/testbed/glfw/docs/compile.dox b/testbed/glfw/docs/compile.dox new file mode 100644 index 00000000..c7b01e34 --- /dev/null +++ b/testbed/glfw/docs/compile.dox @@ -0,0 +1,315 @@ +/*! + +@page compile Compiling GLFW + +@tableofcontents + +This is about compiling the GLFW library itself. For information on how to +build applications that use GLFW, see the @ref build guide. + + +@section compile_cmake Using CMake + +GLFW uses [CMake](http://www.cmake.org/) to generate project files or makefiles +for a particular development environment. If you are on a Unix-like system such +as Linux or FreeBSD or have a package system like Fink, MacPorts, Cygwin or +Homebrew, you can simply install its CMake package. If not, you can download +installers for Windows and OS X from the [CMake website](http://www.cmake.org/). + +@note CMake only generates project files or makefiles. It does not compile the +actual GLFW library. To compile GLFW, first generate these files and then use +them in your chosen development environment to compile the actual GLFW library. + + +@subsection compile_deps Dependencies + +Once you have installed CMake, make sure that all other dependencies are +available. On some platforms, GLFW needs a few additional packages to be +installed. See the section for your chosen platform and development environment +below. + + +@subsubsection compile_deps_msvc Dependencies for Visual C++ on Windows + +The Microsoft Platform SDK that is installed along with Visual C++ already +contains all the necessary headers, link libraries and tools except for CMake. +Move on to @ref compile_generate. + + +@subsubsection compile_deps_mingw Dependencies for MinGW or MinGW-w64 on Windows + +Both the MinGW and the MinGW-w64 packages already contain all the necessary +headers, link libraries and tools except for CMake. Move on to @ref +compile_generate. + + +@subsubsection compile_deps_mingw_cross Dependencies for MinGW or MinGW-w64 cross-compilation + +Both Cygwin and many Linux distributions have MinGW or MinGW-w64 packages. For +example, Cygwin has the `mingw64-i686-gcc` and `mingw64-x86_64-gcc` packages +for 32- and 64-bit version of MinGW-w64, while Debian GNU/Linux and derivatives +like Ubuntu have the `mingw-w64` package for both. + +GLFW has CMake toolchain files in the `CMake/` directory that allow for easy +cross-compilation of Windows binaries. To use these files you need to add a +special parameter when generating the project files or makefiles: + +@code{.sh} +cmake -DCMAKE_TOOLCHAIN_FILE= . +@endcode + +The exact toolchain file to use depends on the prefix used by the MinGW or +MinGW-w64 binaries on your system. You can usually see this in the /usr +directory. For example, both the Debian/Ubuntu and Cygwin MinGW-w64 packages +have `/usr/x86_64-w64-mingw32` for the 64-bit compilers, so the correct +invocation would be: + +@code{.sh} +cmake -DCMAKE_TOOLCHAIN_FILE=CMake/x86_64-w64-mingw32.cmake . +@endcode + +For more details see the article +[CMake Cross Compiling](http://www.paraview.org/Wiki/CMake_Cross_Compiling) on +the CMake wiki. + +Once you have this set up, move on to @ref compile_generate. + + +@subsubsection compile_deps_xcode Dependencies for Xcode on OS X + +Xcode comes with all necessary tools except for CMake. The required headers +and libraries are included in the core OS X frameworks. Xcode can be downloaded +from the Mac App Store or from the ADC Member Center. + +Once you have Xcode installed, move on to @ref compile_generate. + + +@subsubsection compile_deps_x11 Dependencies for Linux and X11 + +To compile GLFW for X11, you need to have the X11 and OpenGL header packages +installed, as well as the basic development tools like GCC and make. For +example, on Ubuntu and other distributions based on Debian GNU/Linux, you need +to install the `xorg-dev` and `libglu1-mesa-dev` packages. The former pulls in +all X.org header packages and the latter pulls in the Mesa OpenGL and GLU +packages. GLFW itself doesn't need or use GLU, but some of the examples do. +Note that using header files and libraries from Mesa during compilation +_will not_ tie your binaries to the Mesa implementation of OpenGL. + +Once you have installed the necessary packages, move on to @ref +compile_generate. + + +@subsection compile_generate Generating build files with CMake + +Once you have all necessary dependencies it is time to generate the project +files or makefiles for your development environment. CMake needs to know two +paths for this: the path to the _root_ directory of the GLFW source tree (i.e. +_not_ the `src` subdirectory) and the target path for the generated files and +compiled binaries. If these are the same, it is called an in-tree build, +otherwise it is called an out-of-tree build. + +One of several advantages of out-of-tree builds is that you can generate files +and compile for different development environments using a single source tree. + +@note This section is about generating the project files or makefiles necessary +to compile the GLFW library, not about compiling the actual library. + + +@subsubsection compile_generate_cli Generating files with the CMake command-line tool + +To make an in-tree build, enter the _root_ directory of the GLFW source tree +(i.e. _not_ the `src` subdirectory) and run CMake. The current directory is +used as target path, while the path provided as an argument is used to find the +source tree. + +@code{.sh} +cd +cmake . +@endcode + +To make an out-of-tree build, make another directory, enter it and run CMake +with the (relative or absolute) path to the root of the source tree as an +argument. + +@code{.sh} +cd +mkdir build +cd build +cmake .. +@endcode + +Once you have generated the project files or makefiles for your chosen +development environment, move on to @ref compile_compile. + + +@subsubsection compile_generate_gui Generating files with the CMake GUI + +If you are using the GUI version, choose the root of the GLFW source tree as +source location and the same directory or another, empty directory as the +destination for binaries. Choose _Configure_, change any options you wish to, +_Configure_ again to let the changes take effect and then _Generate_. + +Once you have generated the project files or makefiles for your chosen +development environment, move on to @ref compile_compile. + + +@subsection compile_compile Compiling the library + +You should now have all required dependencies and the project files or makefiles +necessary to compile GLFW. Go ahead and compile the actual GLFW library with +these files, as you would with any other project. + +Once the GLFW library is compiled, you are ready to build your applications, +linking it to the GLFW library. See the @ref build guide for more information. + + +@subsection compile_options CMake options + +The CMake files for GLFW provide a number of options, although not all are +available on all supported platforms. Some of these are de facto standards +among projects using CMake and so have no `GLFW_` prefix. + +If you are using the GUI version of CMake, these are listed and can be changed +from there. If you are using the command-line version, use the `ccmake` tool. +Some package systems like Ubuntu and other distributions based on Debian +GNU/Linux have this tool in a separate `cmake-curses-gui` package. + + +@subsubsection compile_options_shared Shared CMake options + +`BUILD_SHARED_LIBS` determines whether GLFW is built as a static +library or as a DLL / shared library / dynamic library. + +`LIB_SUFFIX` affects where the GLFW shared /dynamic library is installed. If it +is empty, it is installed to `${CMAKE_INSTALL_PREFIX}/lib`. If it is set to +`64`, it is installed to `${CMAKE_INSTALL_PREFIX}/lib64`. + +`GLFW_CLIENT_LIBRARY` determines which client API library to use. If set to +`opengl` the OpenGL library is used, if set to `glesv1` for the OpenGL ES 1.x +library is used, or if set to `glesv2` the OpenGL ES 2.0 library is used. The +selected library and its header files must be present on the system for this to +work. + +`GLFW_BUILD_EXAMPLES` determines whether the GLFW examples are built +along with the library. + +`GLFW_BUILD_TESTS` determines whether the GLFW test programs are +built along with the library. + +`GLFW_BUILD_DOCS` determines whether the GLFW documentation is built along with +the library. + + +@subsubsection compile_options_osx OS X specific CMake options + +`GLFW_USE_CHDIR` determines whether `glfwInit` changes the current +directory of bundled applications to the `Contents/Resources` directory. + +`GLFW_USE_MENUBAR` determines whether the first call to +`glfwCreateWindow` sets up a minimal menu bar. + +`GLFW_USE_RETINA` determines whether windows will use the full resolution of +Retina displays. + +`GLFW_BUILD_UNIVERSAL` determines whether to build Universal Binaries. + + +@subsubsection compile_options_win32 Windows specific CMake options + +`USE_MSVC_RUNTIME_LIBRARY_DLL` determines whether to use the DLL version or the +static library version of the Visual C++ runtime library. If set to `ON`, the +DLL version of the Visual C++ library is used. It is recommended to set this to +`ON`, as this keeps the executable smaller and benefits from security and bug +fix updates of the Visual C++ runtime. + +`GLFW_USE_DWM_SWAP_INTERVAL` determines whether the swap interval is set even +when DWM compositing is enabled. If this is `ON`, the swap interval is set even +if DWM is enabled. It is recommended to set this to `OFF`, as doing otherwise +can lead to severe jitter. + +`GLFW_USE_OPTIMUS_HPG` determines whether to export the `NvOptimusEnablement` +symbol, which forces the use of the high-performance GPU on Nvidia Optimus +systems. This symbol needs to be exported by the EXE to be detected by the +driver, so the override will not work if GLFW is built as a DLL. See _Enabling +High Performance Graphics Rendering on Optimus Systems_ for more details. + + +@subsubsection compile_options_egl EGL specific CMake options + +`GLFW_USE_EGL` determines whether to use EGL instead of the platform-specific +context creation API. Note that EGL is not yet provided on all supported +platforms. + + +@section compile_manual Compiling GLFW manually + +If you wish to compile GLFW without its CMake build environment then you will +have to do at least some of the platform detection yourself. GLFW needs +a number of configuration macros to be defined in order to know what it's being +compiled for and has many optional, platform-specific ones for various features. + +When building with CMake, the `glfw_config.h` configuration header is generated +based on the current platform and CMake options. The GLFW CMake environment +defines `_GLFW_USE_CONFIG_H`, which causes this header to be included by +`internal.h`. Without this macro, GLFW will expect the necessary configuration +macros to be defined on the command-line. + +Three macros _must_ be defined when compiling GLFW: one selecting the window +creation API, one selecting the context creation API and one client library. +Exactly one of each kind must be defined for GLFW to compile and link. + +The window creation API is used to create windows, handle input, monitors, gamma +ramps and clipboard. The options are: + + - `_GLFW_COCOA` to use the Cocoa frameworks + - `_GLFW_WIN32` to use the Win32 API + - `_GLFW_X11` to use the X Window System + - `_GLFW_WAYLAND` to use the Wayland API (experimental and incomplete) + - `_GLFW_MIR` to use the Mir API (experimental and incomplete) + +The context creation API is used to enumerate pixel formats / framebuffer +configurations and to create contexts. The options are: + + - `_GLFW_NSGL` to use the Cocoa OpenGL framework + - `_GLFW_WGL` to use the Win32 WGL API + - `_GLFW_GLX` to use the X11 GLX API + - `_GLFW_EGL` to use the EGL API + +Wayland and Mir both require the EGL backend. + +The client library is the one providing the OpenGL or OpenGL ES API, which is +used by GLFW to probe the created context. This is not the same thing as the +client API, as many desktop OpenGL client libraries now expose the OpenGL ES API +through extensions. The options are: + + - `_GLFW_USE_OPENGL` for the desktop OpenGL (opengl32.dll, libGL.so or + OpenGL.framework) + - `_GLFW_USE_GLESV1` for OpenGL ES 1.x (experimental) + - `_GLFW_USE_GLESV2` for OpenGL ES 2.x (experimental) + +Note that `_GLFW_USE_GLESV1` and `_GLFW_USE_GLESV2` may only be used with EGL, +as the other context creation APIs do not interface with OpenGL ES client +libraries. + +If you are building GLFW as a shared library / dynamic library / DLL then you +must also define `_GLFW_BUILD_DLL`. Otherwise, you may not define it. + +If you are using the X11 window creation API then you _must_ also select an entry +point retrieval mechanism. + + - `_GLFW_HAS_GLXGETPROCADDRESS` to use `glXGetProcAddress` (recommended) + - `_GLFW_HAS_GLXGETPROCADDRESSARB` to use `glXGetProcAddressARB` (legacy) + - `_GLFW_HAS_GLXGETPROCADDRESSEXT` to use `glXGetProcAddressEXT` (legacy) + - `_GLFW_HAS_DLOPEN` to do manual retrieval with `dlopen` (fallback) + +If you are using the Cocoa window creation API, the following options are +available: + + - `_GLFW_USE_CHDIR` to `chdir` to the `Resources` subdirectory of the + application bundle during @ref glfwInit (recommended) + - `_GLFW_USE_MENUBAR` to create and populate the menu bar when the first window + is created (recommended) + - `_GLFW_USE_RETINA` to have windows use the full resolution of Retina displays + (recommended) + +*/ diff --git a/testbed/glfw/docs/context.dox b/testbed/glfw/docs/context.dox new file mode 100644 index 00000000..eaa754b8 --- /dev/null +++ b/testbed/glfw/docs/context.dox @@ -0,0 +1,329 @@ +/*! + +@page context Context guide + +@tableofcontents + +This guide introduces the OpenGL and OpenGL ES context related functions of +GLFW. There are also guides for the other areas of the GLFW API. + + - @ref intro + - @ref window + - @ref monitor + - @ref input + + +@section context_object Context objects + +A window object encapsulates both a top-level window and an OpenGL or OpenGL ES +context. It is created with @ref glfwCreateWindow and destroyed with @ref +glfwDestroyWindow or @ref glfwTerminate. See @ref window_creation for more +information. + +As the window and context are inseparably linked, the window object also serves +as the context handle. + +To test the creation of various kinds of contexts and see their properties, run +the `glfwinfo` test program. + + +@subsection context_hints Context creation hints + +There are a number of hints, specified using @ref glfwWindowHint, related to +what kind of context is created. See +[context related hints](@ref window_hints_ctx) in the window guide. + + +@subsection context_sharing Context object sharing + +When creating a window and its OpenGL or OpenGL ES context with @ref +glfwCreateWindow, you can specify another window whose context the new one +should share its objects (textures, vertex and element buffers, etc.) with. + +@code +GLFWwindow* second_window = glfwCreateWindow(640, 480, "Second Window", NULL, first_window); +@endcode + +Object sharing is implemented by the operating system and graphics driver. On +platforms where it is possible to choose which types of objects are shared, GLFW +requests that all types are shared. + +See the relevant chapter of the [OpenGL](https://www.opengl.org/registry/) or +[OpenGL ES](http://www.khronos.org/opengles/) reference documents for more +information. The name and number of this chapter unfortunately varies between +versions and APIs, but has at times been named _Shared Objects and Multiple +Contexts_. + +GLFW comes with a simple object sharing test program called `sharing`. + + +@subsection context_offscreen Offscreen contexts + +GLFW doesn't support creating contexts without an associated window. However, +contexts with hidden windows can be created with the +[GLFW_VISIBLE](@ref window_hints_wnd) window hint. + +@code +glfwWindowHint(GLFW_VISIBLE, GL_FALSE); + +GLFWwindow* offscreen_context = glfwCreateWindow(640, 480, "", NULL, NULL); +@endcode + +The window never needs to be shown and its context can be used as a plain +offscreen context. Depending on the window manager, the size of a hidden +window's framebuffer may not be usable or modifiable, so framebuffer +objects are recommended for rendering with such contexts. + +__OS X:__ The first time a window is created the menu bar is populated with +common commands like Hide, Quit and About. This is not desirable for example +when writing a command-line only application. The menu bar setup can be +disabled with a [compile-time option](@ref compile_options_osx). + + +@section context_current Current context + +Before you can make OpenGL or OpenGL ES calls, you need to have a current +context of the correct type. A context can only be current for a single thread +at a time, and a thread can only have a single context current at a time. + +The context of a window is made current with @ref glfwMakeContextCurrent. + +@code +glfwMakeContextCurrent(window); +@endcode + +The window of the current context is returned by @ref glfwGetCurrentContext. + +@code +GLFWwindow* window = glfwGetCurrentContext(); +@endcode + +The following GLFW functions require a context to be current. Calling any these +functions without a current context will generate a @ref GLFW_NO_CURRENT_CONTEXT +error. + + - @ref glfwSwapInterval + - @ref glfwExtensionSupported + - @ref glfwGetProcAddress + + +@section context_swap Buffer swapping + +Buffer swapping is part of the window and framebuffer, not the context. See +@ref buffer_swap. + + +@section context_glext OpenGL and OpenGL ES extensions + +One of the benefits of OpenGL and OpenGL ES are their extensibility. +Hardware vendors may include extensions in their implementations that extend the +API before that functionality is included in a new version of the OpenGL or +OpenGL ES specification, and some extensions are never included and remain +as extensions until they become obsolete. + +An extension is defined by: + +- An extension name (e.g. `GL_ARB_debug_output`) +- New OpenGL tokens (e.g. `GL_DEBUG_SEVERITY_HIGH_ARB`) +- New OpenGL functions (e.g. `glGetDebugMessageLogARB`) + +Note the `ARB` affix, which stands for Architecture Review Board and is used +for official extensions. The extension above was created by the ARB, but there +are many different affixes, like `NV` for Nvidia and `AMD` for, well, AMD. Any +group may also use the generic `EXT` affix. Lists of extensions, together with +their specifications, can be found at the +[OpenGL Registry](http://www.opengl.org/registry/) and +[OpenGL ES Registry](https://www.khronos.org/registry/gles/). + + +@subsection context_glext_auto Loading extension with a loader library + +An extension loader library is the easiest and best way to access both OpenGL and +OpenGL ES extensions and modern versions of the core OpenGL or OpenGL ES APIs. +They will take care of all the details of declaring and loading everything you +need. One such library is [glad](https://github.com/Dav1dde/glad) and there are +several others. + +The following example will use glad but all extension loader libraries work +similarly. + +First you need to generate the source files using the glad Python script. This +example generates a loader for any version of OpenGL, which is the default for +both GLFW and glad, but loaders for OpenGL ES, as well as loaders for specific +API versions and extension sets can be generated. The generated files are +written to the `output` directory. + +@code{.sh} +python main.py --generator c --no-loader --out-path output +@endcode + +The `--no-loader` option is added because GLFW already provides a function for +loading OpenGL and OpenGL ES function pointers and glad can call this instead of +having to implement its own. There are several other command-line options as +well. See the glad documentation for details. + +Add the generated `output/src/glad.c`, `output/include/glad/glad.h` and +`output/include/KHR/khrplatform.h` files to your build. Then you need to +include the glad header file, which will replace the OpenGL header of your +development environment. By including the glad header before the GLFW header, +it suppresses the development environment's OpenGL or OpenGL ES header. + +@code +#include +#include +@endcode + +Finally you need to initialize glad once you have a suitable current context. + +@code +window = glfwCreateWindow(640, 480, "My Window", NULL, NULL); +if (!window) +{ + ... +} + +glfwMakeContextCurrent(window); + +gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); +@endcode + +Once glad has been loaded, you have access to all OpenGL core and extension +functions supported by both the context you created and the glad loader you +generated and you are ready to start rendering. + +You can specify a minimum required OpenGL or OpenGL ES version with +[context hints](@ref window_hints_ctx). If your needs are more complex, you can +check the actual OpenGL or OpenGL ES version with +[context attributes](@ref window_attribs_ctx), or you can check whether +a specific version is supported by the current context with the +`GLAD_GL_VERSION_x_x` booleans. + +@code +if (GLAD_GL_VERSION_3_2) +{ + // Call OpenGL 3.2+ specific code +} +@endcode + +To check whether a specific extension is supported, use the `GLAD_GL_xxx` +booleans. + +@code +if (GLAD_GL_ARB_debug_output) +{ + // Use GL_ARB_debug_output +} +@endcode + + +@subsection context_glext_manual Loading extensions manually + +__Do not use this technique__ unless it is absolutely necessary. An +[extension loader library](@ref context_glext_auto) will save you a ton of +tedious, repetitive, error prone work. + +To use a certain extension, you must first check whether the context supports +that extension and then, if it introduces new functions, retrieve the pointers +to those functions. GLFW provides @ref glfwExtensionSupported and @ref +glfwGetProcAddress for manual loading of extensions and new API functions. + +This section will demonstrate manual loading of OpenGL extensions. The loading +of OpenGL ES extensions is identical except for the name of the extension header. + + +@subsubsection context_glext_header The glext.h header + +The `glext.h` extension header is a continually updated file that defines the +interfaces for all OpenGL extensions. The latest version of this can always be +found at the [OpenGL Registry](http://www.opengl.org/registry/). There are also +extension headers for the various versions of OpenGL ES at the +[OpenGL ES Registry](https://www.khronos.org/registry/gles/). It it strongly +recommended that you use your own copy of the extension header, as the one +included in your development environment may be several years out of date and +may not include the extensions you wish to use. + +The header defines function pointer types for all functions of all extensions it +supports. These have names like `PFNGLGETDEBUGMESSAGELOGARBPROC` (for +`glGetDebugMessageLogARB`), i.e. the name is made uppercase and `PFN` (pointer +to function) and `PROC` (procedure) are added to the ends. + +To include the extension header, define [GLFW_INCLUDE_GLEXT](@ref build_macros) +before including the GLFW header. + +@code +#define GLFW_INCLUDE_GLEXT +#include +@endcode + + +@subsubsection context_glext_string Checking for extensions + +A given machine may not actually support the extension (it may have older +drivers or a graphics card that lacks the necessary hardware features), so it +is necessary to check at run-time whether the context supports the extension. +This is done with @ref glfwExtensionSupported. + +@code +if (glfwExtensionSupported("GL_ARB_debug_output")) +{ + // The extension is supported by the current context +} +@endcode + +The argument is a null terminated ASCII string with the extension name. If the +extension is supported, @ref glfwExtensionSupported returns `GL_TRUE`, otherwise +it returns `GL_FALSE`. + + +@subsubsection context_glext_proc Fetching function pointers + +Many extensions, though not all, require the use of new OpenGL functions. +These functions often do not have entry points in the client API libraries of +your operating system, making it necessary to fetch them at run time. You can +retrieve pointers to these functions with @ref glfwGetProcAddress. + +@code +PFNGLGETDEBUGMESSAGELOGARBPROC pfnGetDebugMessageLog = glfwGetProcAddress("glGetDebugMessageLogARB"); +@endcode + +In general, you should avoid giving the function pointer variables the (exact) +same name as the function, as this may confuse your linker. Instead, you can +use a different prefix, like above, or some other naming scheme. + +Now that all the pieces have been introduced, here is what they might look like +when used together. + +@code +#define GLFW_INCLUDE_GLEXT +#include + +#define glGetDebugMessageLogARB pfnGetDebugMessageLog +PFNGLGETDEBUGMESSAGELOGARBPROC pfnGetDebugMessageLog; + +// Flag indicating whether the extension is supported +int has_ARB_debug_output = 0; + +void load_extensions(void) +{ + if (glfwExtensionSupported("GL_ARB_debug_output")) + { + pfnGetDebugMessageLog = (PFNGLGETDEBUGMESSAGELOGARBPROC) glfwGetProcAddress("glGetDebugMessageLogARB"); + if (pfnGetDebugMessageLog) + { + // Both the extension name and the function pointer are present + has_ARB_debug_output = 1; + } + } +} + +void some_function(void) +{ + if (has_ARB_debug_output) + { + // Now the extension function can be called as usual + glGetDebugMessageLogARB(...); + } +} +@endcode + +*/ diff --git a/testbed/glfw/docs/extra.css b/testbed/glfw/docs/extra.css new file mode 100644 index 00000000..e9896fae --- /dev/null +++ b/testbed/glfw/docs/extra.css @@ -0,0 +1 @@ +#navrow1,#navrow2,#navrow3,#navrow4,.tablist a,.tablist a:visited,.tablist a:hover,.tablist li,.tablist li.current a,.memdoc,dl.reflist dd,div.toc li,.ah,span.lineno,span.lineno a,span.lineno a:hover,.note code,.pre code,.post code,.invariant code,.warning code,.attention code,.deprecated code,.bug code,.todo code,.test code,.doxtable code{background:none}#titlearea,.footer,.contents,div.header,.memdoc,table.doxtable td,table.doxtable th,hr,.memSeparator{border:none}.tablist a,.tablist a:visited,.tablist a:hover,.tablist li,.tablist li.current a,.reflist dt a.el,.levels span,.directory .levels span{text-shadow:none}.memdoc,dl.reflist dd{box-shadow:none}div.headertitle,.note code,.pre code,.post code,.invariant code,.warning code,.attention code,.deprecated code,.bug code,.todo code,.test code,table.doxtable code{padding:0}#nav-path,.directory .levels,span.lineno{display:none}html,#titlearea,.footer,tr.even,.directory tr.even,.doxtable tr:nth-child(even),.mdescLeft,.mdescRight,.memItemLeft,.memItemRight,code{background:#f2f2f2}body{color:#4d4d4d}h1,h2,h2.groupheader,h3,div.toc h3,h4,h5,h6,strong,em{color:#1a1a1a;border-bottom:none}h1{padding-top:0.5em;font-size:180%}h2{padding-top:0.5em;margin-bottom:0;font-size:140%}h3{padding-top:0.5em;margin-bottom:0;font-size:110%}.glfwheader{font-size:16px;height:64px;max-width:920px;min-width:800px;padding:0 32px;margin:0 auto}#glfwhome{line-height:64px;padding-right:48px;color:#666;font-size:2.5em;background:url("http://www.glfw.org/css/arrow.png") no-repeat right}.glfwnavbar{list-style-type:none;margin:0 auto;float:right}#glfwhome,.glfwnavbar li{float:left}.glfwnavbar a,.glfwnavbar a:visited{line-height:64px;margin-left:2em;display:block;color:#666}#glfwhome,.glfwnavbar a,.glfwnavbar a:visited{transition:.35s ease}#titlearea,.footer{color:#666}address.footer{text-align:center;padding:2em;margin-top:3em}#top{background:#666}#navrow1,#navrow2,#navrow3,#navrow4{max-width:920px;min-width:800px;margin:0 auto;font-size:13px}.tablist{height:36px;display:block;position:relative}.tablist a,.tablist a:visited,.tablist a:hover,.tablist li,.tablist li.current a{color:#f2f2f2}.tablist li.current a{background:linear-gradient(to bottom, #ffa733 0, #f60 100%);box-shadow:inset 0 0 32px #f60;text-shadow:0 -1px 1px #b34700;color:#fff}.contents{min-height:590px}div.contents,div.header{max-width:920px;margin:0 auto;padding:0 32px;background:#fff none}table.doxtable th,dl.reflist dt{background:linear-gradient(to bottom, #ffa733 0, #f60 100%);box-shadow:inset 0 0 32px #f60;text-shadow:0 -1px 1px #b34700;color:#fff}dl.reflist dt a.el{color:#f60;padding:.2em;border-radius:4px;background-color:#ffe0cc}div.toc{float:none;width:auto}div.toc h3{font-size:1.17em}div.toc ul{padding-left:1.5em}div.toc li{font-size:1em;padding-left:0;list-style-type:disc}div.toc,.memproto,div.qindex,div.ah{background:linear-gradient(to bottom, #f2f2f2 0, #e6e6e6 100%);box-shadow:inset 0 0 32px #e6e6e6;text-shadow:0 1px 1px #fff;color:#1a1a1a;border:2px solid #e6e6e6;border-radius:4px}.paramname{color:#803300}dl.reflist dt{border:2px solid #f60;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom:none}dl.reflist dd{border:2px solid #f60;border-bottom-right-radius:4px;border-bottom-left-radius:4px;border-top:none}table.doxtable{border-collapse:inherit;border-spacing:0;border:2px solid #f60;border-radius:4px}a,a:hover,a:visited,a:visited:hover,.contents a:visited,.el,a.el:visited,#glfwhome:hover,.tablist a:hover,span.lineno a:hover{color:#f60;text-decoration:none}div.directory{border-collapse:inherit;border-spacing:0;border:2px solid #f60;border-radius:4px}hr,.memSeparator{height:2px;background:linear-gradient(to right, #f2f2f2 0, #d9d9d9 50%, #f2f2f2 100%)}dl.note,dl.pre,dl.post,dl.invariant{background:linear-gradient(to bottom, #ddfad1 0, #cbf7ba 100%);box-shadow:inset 0 0 32px #baf5a3;color:#1e5309;border:2px solid #afe599}dl.warning,dl.attention{background:linear-gradient(to bottom, #fae8d1 0, #f7ddba 100%);box-shadow:inset 0 0 32px #f5d1a3;color:#533309;border:2px solid #e5c499}dl.deprecated,dl.bug{background:linear-gradient(to bottom, #fad1e3 0, #f7bad6 100%);box-shadow:inset 0 0 32px #f5a3c8;color:#53092a;border:2px solid #e599bb}dl.todo,dl.test{background:linear-gradient(to bottom, #d1ecfa 0, #bae3f7 100%);box-shadow:inset 0 0 32px #a3daf5;color:#093a53;border:2px solid #99cce5}dl.note,dl.pre,dl.post,dl.invariant,dl.warning,dl.attention,dl.deprecated,dl.bug,dl.todo,dl.test{border-radius:4px;padding:1em;text-shadow:0 1px 1px #fff;margin:1em 0}.note a,.pre a,.post a,.invariant a,.warning a,.attention a,.deprecated a,.bug a,.todo a,.test a,.note a:visited,.pre a:visited,.post a:visited,.invariant a:visited,.warning a:visited,.attention a:visited,.deprecated a:visited,.bug a:visited,.todo a:visited,.test a:visited{color:inherit}div.line{line-height:inherit}div.fragment,pre.fragment{background:#f2f2f2;border-radius:4px;border:none;padding:1em;overflow:auto;border-left:4px solid #ccc;margin:1em 0}.lineno a,.lineno a:visited,.line,pre.fragment{color:#4d4d4d}span.preprocessor,span.comment{color:#007899}a.code,a.code:visited{color:#e64500}span.keyword,span.keywordtype,span.keywordflow{color:#404040;font-weight:bold}span.stringliteral{color:#360099}code{padding:.1em;border-radius:4px} diff --git a/testbed/glfw/docs/extra.less b/testbed/glfw/docs/extra.less new file mode 100644 index 00000000..9d0ce975 --- /dev/null +++ b/testbed/glfw/docs/extra.less @@ -0,0 +1,370 @@ +// NOTE: Please use this file to perform modifications on default style sheets. +// +// You need to install a few Ruby gems to generate extra.css from this file: +// gem install less therubyracer +// +// Run this command to regenerate extra.css after you're finished with changes: +// lessc --compress extra.less > extra.css +// +// Alternatively you can use online services to regenerate extra.css. + + +// Default text color for page contents +@default-text-color: hsl(0,0%,30%); + +// Page header, footer, table rows, inline codes and definition lists +@header-footer-background-color: hsl(0,0%,95%); + +// Page header, footer links and navigation bar background +@header-footer-link-color: hsl(0,0%,40%); + +// Doxygen navigation bar links +@navbar-link-color: @header-footer-background-color; + +// Page content background color +@content-background-color: hsl(0,0%,100%); + +// Bold, italic, h1, h2, ... and table of contents +@heading-color: hsl(0,0%,10%); + +// Function, enum and macro definition separator +@def-separator-color: @header-footer-background-color; + +// Base color hue +@base-hue: 24; + +// Default color used for links +@default-link-color: hsl(@base-hue,100%,50%); + +// Doxygen navigation bar active tab +@tab-text-color: hsl(0,0%,100%); +@tab-background-color1: @default-link-color; +@tab-background-color2: lighten(spin(@tab-background-color1, 10), 10%); + +// Table borders +@default-border-color: @default-link-color; + +// Table header +@table-text-color: @tab-text-color; +@table-background-color1: @tab-background-color1; +@table-background-color2: @tab-background-color2; + +// Table of contents, data structure index and prototypes +@toc-background-color1: hsl(0,0%,90%); +@toc-background-color2: lighten(@toc-background-color1, 5%); + +// Function prototype parameters color +@prototype-param-color: darken(@default-link-color, 25%); + +// Message box color: note, pre, post and invariant +@box-note-color: hsl(103,80%,85%); + +// Message box color: warning and attention +@box-warning-color: hsl(34,80%,85%); + +// Message box color: deprecated and bug +@box-bug-color: hsl(333,80%,85%); + +// Message box color: todo and test +@box-todo-color: hsl(200,80%,85%); + +// Message box helper function +.message-box(@base-color) { + background:linear-gradient(to bottom,lighten(@base-color, 5%) 0%,@base-color 100%); + box-shadow:inset 0 0 32px darken(@base-color, 5%); + color:darken(@base-color, 67%); + border:2px solid desaturate(darken(@base-color, 10%), 20%); +} + + +#navrow1,#navrow2,#navrow3,#navrow4,.tablist a,.tablist a:visited,.tablist a:hover,.tablist li,.tablist li.current a,.memdoc,dl.reflist dd,div.toc li,.ah,span.lineno,span.lineno a,span.lineno a:hover,.note code,.pre code,.post code,.invariant code,.warning code,.attention code,.deprecated code,.bug code,.todo code,.test code,.doxtable code { + background:none; +} + +#titlearea,.footer,.contents,div.header,.memdoc,table.doxtable td,table.doxtable th,hr,.memSeparator { + border:none; +} + +.tablist a,.tablist a:visited,.tablist a:hover,.tablist li,.tablist li.current a,.reflist dt a.el,.levels span,.directory .levels span { + text-shadow:none; +} + +.memdoc,dl.reflist dd { + box-shadow:none; +} + +div.headertitle,.note code,.pre code,.post code,.invariant code,.warning code,.attention code,.deprecated code,.bug code,.todo code,.test code,table.doxtable code { + padding:0; +} + +#nav-path,.directory .levels,span.lineno { + display:none; +} + +html,#titlearea,.footer,tr.even,.directory tr.even,.doxtable tr:nth-child(even),.mdescLeft,.mdescRight,.memItemLeft,.memItemRight,code { + background:@header-footer-background-color; +} + +body { + color:@default-text-color; +} + +h1,h2,h2.groupheader,h3,div.toc h3,h4,h5,h6,strong,em { + color:@heading-color; + border-bottom:none; +} + +h1 { + padding-top:0.5em; + font-size:180%; +} + +h2 { + padding-top:0.5em; + margin-bottom:0; + font-size:140%; +} + +h3 { + padding-top:0.5em; + margin-bottom:0; + font-size:110%; +} + +.glfwheader { + font-size:16px; + height:64px; + max-width:920px; + min-width:800px; + padding:0 32px; + margin:0 auto; +} + +#glfwhome { + line-height:64px; + padding-right:48px; + color:@header-footer-link-color; + font-size:2.5em; + background:url("http://www.glfw.org/css/arrow.png") no-repeat right; +} + +.glfwnavbar { + list-style-type:none; + margin:0 auto; + float:right; +} + +#glfwhome,.glfwnavbar li { + float:left; +} + +.glfwnavbar a,.glfwnavbar a:visited { + line-height:64px; + margin-left:2em; + display:block; + color:@header-footer-link-color; +} + +#glfwhome,.glfwnavbar a,.glfwnavbar a:visited { + transition:.35s ease; +} + +#titlearea,.footer { + color:@header-footer-link-color; +} + +address.footer { + text-align:center; + padding:2em; + margin-top:3em; +} + +#top { + background:@header-footer-link-color; +} + +#navrow1,#navrow2,#navrow3,#navrow4 { + max-width:920px; + min-width:800px; + margin:0 auto; + font-size:13px; +} + +.tablist { + height:36px; + display:block; + position:relative; +} + +.tablist a,.tablist a:visited,.tablist a:hover,.tablist li,.tablist li.current a { + color:@navbar-link-color; +} + +.tablist li.current a { + background:linear-gradient(to bottom,@tab-background-color2 0%,@tab-background-color1 100%); + box-shadow:inset 0 0 32px @tab-background-color1; + text-shadow:0 -1px 1px darken(@tab-background-color1, 15%); + color:@tab-text-color; +} + +.contents { + min-height:590px; +} + +div.contents,div.header { + max-width:920px; + margin:0 auto; + padding:0 32px; + background:@content-background-color none; +} + +table.doxtable th,dl.reflist dt { + background:linear-gradient(to bottom,@table-background-color2 0%,@table-background-color1 100%); + box-shadow:inset 0 0 32px @table-background-color1; + text-shadow:0 -1px 1px darken(@table-background-color1, 15%); + color:@table-text-color; +} + +dl.reflist dt a.el { + color:@default-link-color; + padding:.2em; + border-radius:4px; + background-color:lighten(@default-link-color, 40%); +} + +div.toc { + float:none; + width:auto; +} + +div.toc h3 { + font-size:1.17em; +} + +div.toc ul { + padding-left:1.5em; +} + +div.toc li { + font-size:1em; + padding-left:0; + list-style-type:disc; +} + +div.toc,.memproto,div.qindex,div.ah { + background:linear-gradient(to bottom,@toc-background-color2 0%,@toc-background-color1 100%); + box-shadow:inset 0 0 32px @toc-background-color1; + text-shadow:0 1px 1px lighten(@toc-background-color2, 10%); + color:@heading-color; + border:2px solid @toc-background-color1; + border-radius:4px; +} + +.paramname { + color:@prototype-param-color; +} + +dl.reflist dt { + border:2px solid @default-border-color; + border-top-left-radius:4px; + border-top-right-radius:4px; + border-bottom:none; +} + +dl.reflist dd { + border:2px solid @default-border-color; + border-bottom-right-radius:4px; + border-bottom-left-radius:4px; + border-top:none; +} + +table.doxtable { + border-collapse:inherit; + border-spacing:0; + border:2px solid @default-border-color; + border-radius:4px; +} + +a,a:hover,a:visited,a:visited:hover,.contents a:visited,.el,a.el:visited,#glfwhome:hover,.tablist a:hover,span.lineno a:hover { + color:@default-link-color; + text-decoration:none; +} + +div.directory { + border-collapse:inherit; + border-spacing:0; + border:2px solid @default-border-color; + border-radius:4px; +} + +hr,.memSeparator { + height:2px; + background:linear-gradient(to right,@def-separator-color 0%,darken(@def-separator-color, 10%) 50%,@def-separator-color 100%); +} + +dl.note,dl.pre,dl.post,dl.invariant { + .message-box(@box-note-color); +} + +dl.warning,dl.attention { + .message-box(@box-warning-color); +} + +dl.deprecated,dl.bug { + .message-box(@box-bug-color); +} + +dl.todo,dl.test { + .message-box(@box-todo-color); +} + +dl.note,dl.pre,dl.post,dl.invariant,dl.warning,dl.attention,dl.deprecated,dl.bug,dl.todo,dl.test { + border-radius:4px; + padding:1em; + text-shadow:0 1px 1px hsl(0,0%,100%); + margin:1em 0; +} + +.note a,.pre a,.post a,.invariant a,.warning a,.attention a,.deprecated a,.bug a,.todo a,.test a,.note a:visited,.pre a:visited,.post a:visited,.invariant a:visited,.warning a:visited,.attention a:visited,.deprecated a:visited,.bug a:visited,.todo a:visited,.test a:visited { + color:inherit; +} + +div.line { + line-height:inherit; +} + +div.fragment,pre.fragment { + background:hsl(0,0%,95%); + border-radius:4px; + border:none; + padding:1em; + overflow:auto; + border-left:4px solid hsl(0,0%,80%); + margin:1em 0; +} + +.lineno a,.lineno a:visited,.line,pre.fragment { + color:@default-text-color; +} + +span.preprocessor,span.comment { + color:hsl(193,100%,30%); +} + +a.code,a.code:visited { + color:hsl(18,100%,45%); +} + +span.keyword,span.keywordtype,span.keywordflow { + color:darken(@default-text-color, 5%); + font-weight:bold; +} + +span.stringliteral { + color:hsl(261,100%,30%); +} + +code { + padding:.1em; + border-radius:4px; +} diff --git a/testbed/glfw/docs/footer.html b/testbed/glfw/docs/footer.html new file mode 100644 index 00000000..b0434ca1 --- /dev/null +++ b/testbed/glfw/docs/footer.html @@ -0,0 +1,7 @@ + + + diff --git a/testbed/glfw/docs/header.html b/testbed/glfw/docs/header.html new file mode 100644 index 00000000..9759d8b0 --- /dev/null +++ b/testbed/glfw/docs/header.html @@ -0,0 +1,34 @@ + + + + + + +$projectname: $title +$title + + + +$treeview +$search +$mathjax + +$extrastylesheet + + +
+ + + + + diff --git a/testbed/glfw/docs/input.dox b/testbed/glfw/docs/input.dox new file mode 100644 index 00000000..fb38808b --- /dev/null +++ b/testbed/glfw/docs/input.dox @@ -0,0 +1,588 @@ +/*! + +@page input Input guide + +@tableofcontents + +This guide introduces the input related functions of GLFW. There are also +guides for the other areas of GLFW. + + - @ref intro + - @ref window + - @ref context + - @ref monitor + +GLFW provides many kinds of input. While some can only be polled, like time, or +only received via callbacks, like scrolling, there are those that provide both +callbacks and polling. Where a callback is provided, that is the recommended +way to receive that kind of input. The more you can use callbacks the less time +your users' machines will need to spend polling. + +All input callbacks receive a window handle. By using the +[window user pointer](@ref window_userptr), you can access non-global structures +or objects from your callbacks. + +To get a better feel for how the various events callbacks behave, run the +`events` test program. It register every callback supported by GLFW and prints +out all arguments provided for every event, along with time and sequence +information. + + +@section events Event processing + +GLFW needs to communicate regularly with the window system both in order to +receive events and to show that the application hasn't locked up. Event +processing must be done regularly while you have visible windows and is normally +done each frame after [buffer swapping](@ref buffer_swap). + +There are two functions for processing pending events. @ref glfwPollEvents, +processes only those events that have already been received and then returns +immediately. + +@code +glfwPollEvents(); +@endcode + +This is the best choice when rendering continually, like most games do. + +If you only need to update the contents of the window when you receive new +input, @ref glfwWaitEvents is a better choice. + +@code +glfwWaitEvents(); +@endcode + +It puts the thread to sleep until at least one event has been received and then +processes all received events. This saves a great deal of CPU cycles and is +useful for, for example, editing tools. There must be at least one GLFW window +for this function to sleep. + +If the main thread is sleeping in @ref glfwWaitEvents, you can wake it from +another thread by posting an empty event to the event queue with @ref +glfwPostEmptyEvent. + +@code +glfwPostEmptyEvent(); +@endcode + +Do not assume that callbacks will _only_ be called through either of the above +functions. While it is necessary to process events in the event queue, some +window systems will send some events directly to the application, which in turn +causes callbacks to be called outside of regular event processing. + + +@section input_keyboard Keyboard input + +GLFW divides keyboard input into two categories; key events and character +events. Key events relate to actual physical keyboard keys, whereas character +events relate to the Unicode code points generated by pressing some of them. + +Keys and characters do not map 1:1. A single key press may produce several +characters, and a single character may require several keys to produce. This +may not be the case on your machine, but your users are likely not all using the +same keyboard layout, input method or even operating system as you. + + +@subsection input_key Key input + +If you wish to be notified when a physical key is pressed or released or when it +repeats, set a key callback. + +@code +glfwSetKeyCallback(window, key_callback); +@endcode + +The callback function receives the [keyboard key](@ref keys), platform-specific +scancode, key action and [modifier bits](@ref mods). + +@code +void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + if (key == GLFW_KEY_E && action == GLFW_PRESS) + activate_airship(); +} +@endcode + +The action is one of `GLFW_PRESS`, `GLFW_REPEAT` or `GLFW_RELEASE`. The key +will be `GLFW_KEY_UNKNOWN` if GLFW lacks a key token for it. These keys still +have unique, if platform-specific scancodes. + +The scancode is unique for every key but is platform-specific, so a scancode +will map to different keys on different platforms. + +The key will be `GLFW_KEY_UNKNOWN` for special keys like _E-mail_ or _Play_ that +don't have a key token. Those keys will still have unique, if platform-specific +scancodes. + +Key states for [named keys](@ref keys) are also saved in per-window state arrays +that can be polled with @ref glfwGetKey. + +@code +int state = glfwGetKey(window, GLFW_KEY_E); +if (state == GLFW_PRESS) + activate_airship(); +@endcode + +The returned state is one of `GLFW_PRESS` or `GLFW_RELEASE`. + +This function only returns cached key event state. It does not poll the +system for the current state of the key. + +Whenever you poll state, you risk missing the state change you are looking for. +If a pressed key is released again before you poll its state, you will have +missed the key press. The recommended solution for this is to use a +key callback, but there is also the `GLFW_STICKY_KEYS` input mode. + +@code +glfwSetInputMode(window, GLFW_STICKY_KEYS, 1); +@endcode + +When sticky keys mode is enabled, the pollable state of a key will remain +`GLFW_PRESS` until the state of that key is polled with @ref glfwGetKey. Once +it has been polled, if a key release event had been processed in the meantime, +the state will reset to `GLFW_RELEASE`, otherwise it will remain `GLFW_PRESS`. + +The `GLFW_KEY_LAST` constant holds the highest value of any +[named key](@ref keys). + + +@subsection input_char Text input + +GLFW supports text input in the form of a stream of +[Unicode code points](https://en.wikipedia.org/wiki/Unicode), as produced by the +operating system text input system. Unlike key input, text input obeys keyboard +layouts and modifier keys and supports composing characters using +[dead keys](https://en.wikipedia.org/wiki/Dead_key). Once received, you can +encode the code points into +[UTF-8](https://en.wikipedia.org/wiki/UTF-8) or any other encoding you prefer. + +Because an `unsigned int` is 32 bits long on all platforms supported by GLFW, +you can treat the code point argument as native endian +[UTF-32](https://en.wikipedia.org/wiki/UTF-32). + +There are two callbacks for receiving Unicode code points. If you wish to +offer regular text input, set a character callback. + +@code +glfwSetCharCallback(window, character_callback); +@endcode + +The callback function receives Unicode code points for key events that would +have led to regular text input and generally behaves as a standard text field on +that platform. + +@code +void character_callback(GLFWwindow* window, unsigned int codepoint) +{ +} +@endcode + +If you wish to receive even those Unicode code points generated with modifier +key combinations that a plain text field would ignore, or just want to know +exactly what modifier keys were used, set a character with modifiers callback. + +@code +glfwSetCharModsCallback(window, charmods_callback); +@endcode + +The callback function receives Unicode code points and +[modifier bits](@ref mods). + +@code +void charmods_callback(GLFWwindow* window, unsigned int codepoint, int mods) +{ +} +@endcode + + +@section input_mouse Mouse input + +Mouse input comes in many forms, including cursor motion, button presses and +scrolling offsets. The cursor appearance can also be changed, either to +a custom image or a standard cursor shape from the system theme. + + +@subsection cursor_pos Cursor position + +If you wish to be notified when the cursor moves over the window, set a cursor +position callback. + +@code +glfwSetCursorPosCallback(window, cursor_pos_callback); +@endcode + +The callback functions receives the cursor position. On platforms that provide +it, the full sub-pixel cursor position is passed on. + +@code +static void cursor_position_callback(GLFWwindow* window, double xpos, double ypos) +{ +} +@endcode + +The cursor position is also saved per-window and can be polled with @ref +glfwGetCursorPos. + +@code +double xpos, ypos; +glfwGetCursorPos(window, &xpos, &ypos); +@endcode + + +@subsection cursor_mode Cursor modes + +The `GLFW_CURSOR` input mode provides several cursor modes for special forms of +mouse motion input. By default, the cursor mode is `GLFW_CURSOR_NORMAL`, +meaning the regular arrow cursor (or another cursor set with @ref glfwSetCursor) +is used and cursor motion is not limited. + +If you wish to implement mouse motion based camera controls or other input +schemes that require unlimited mouse movement, set the cursor mode to +`GLFW_CURSOR_DISABLED`. + +@code +glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); +@endcode + +This will hide the cursor and lock it to the specified window. GLFW will then +take care of all the details of cursor re-centering and offset calculation and +providing the application with a virtual cursor position. This virtual position +is provided normally via both the cursor position callback and through polling. + +@note You should not implement your own version of this functionality using +other features of GLFW. It is not supported and will not work as robustly as +`GLFW_CURSOR_DISABLED`. + +If you just wish the cursor to become hidden when it is over a window, set +the cursor mode to `GLFW_CURSOR_HIDDEN`. + +@code +glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); +@endcode + +This mode puts no limit on the motion of the cursor. + +To exit out of either of these special modes, restore the `GLFW_CURSOR_NORMAL` +cursor mode. + +@code +glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); +@endcode + + +@subsection cursor_object Cursor objects + +GLFW supports creating both custom and system theme cursor images, encapsulated +as @ref GLFWcursor objects. They are created with @ref glfwCreateCursor or @ref +glfwCreateStandardCursor and destroyed with @ref glfwDestroyCursor, or @ref +glfwTerminate, if any remain. + + +@subsubsection cursor_custom Custom cursor creation + +A custom cursor is created with @ref glfwCreateCursor, which returns a handle to +the created cursor object. For example, this creates a 16x16 white square +cursor with the hot-spot in the upper-left corner: + +@code +unsigned char pixels[16 * 16 * 4]; +memset(pixels, 0xff, sizeof(pixels)); + +GLFWimage image; +image.width = 16; +image.height = 16; +image.pixels = pixels; + +GLFWcursor* cursor = glfwCreateCursor(&image, 0, 0); +@endcode + +If cursor creation fails, `NULL` will be returned, so it is necessary to check +the return value. + +The image data is 32-bit RGBA, i.e. eight bits per channel. The pixels are +arranged canonically as sequential rows, starting from the top-left corner. + + +@subsubsection cursor_standard Standard cursor creation + +A cursor with a [standard shape](@ref shapes) from the current system cursor +theme can be can be created with @ref glfwCreateStandardCursor. + +@code +GLFWcursor* cursor = glfwCreateStandardCursor(GLFW_HRESIZE_CURSOR); +@endcode + +These cursor objects behave in the exact same way as those created with @ref +glfwCreateCursor except that the system cursor theme provides the actual image. + + +@subsubsection cursor_destruction Cursor destruction + +When a cursor is no longer needed, destroy it with @ref glfwDestroyCursor. + +@code +glfwDestroyCursor(cursor); +@endcode + +Cursor destruction always succeeds. All cursors remaining when @ref +glfwTerminate is called are destroyed as well. + + +@subsubsection cursor_set Cursor setting + +A cursor can be set as current for a window with @ref glfwSetCursor. + +@code +glfwSetCursor(window, cursor); +@endcode + +Once set, the cursor image will be used as long as the system cursor is over the +client area of the window and the [cursor mode](@ref cursor_mode) is set +to `GLFW_CURSOR_NORMAL`. + +A single cursor may be set for any number of windows. + +To remove a cursor from a window, set the cursor of that window to `NULL`. + +@code +glfwSetCursor(window, NULL); +@endcode + +When a cursor is destroyed, it is removed from any window where it is set. This +does not affect the cursor modes of those windows. + + +@subsection cursor_enter Cursor enter/leave events + +If you wish to be notified when the cursor enters or leaves the client area of +a window, set a cursor enter/leave callback. + +@code +glfwSetCursorEnterCallback(window, cursor_enter_callback); +@endcode + +The callback function receives the new classification of the cursor. + +@code +void cursor_enter_callback(GLFWwindow* window, int entered) +{ + if (entered) + { + // The cursor entered the client area of the window + } + else + { + // The cursor left the client area of the window + } +} +@endcode + + +@subsection input_mouse_button Mouse button input + +If you wish to be notified when a mouse button is pressed or released, set +a mouse button callback. + +@code +glfwSetMouseButtonCallback(window, mouse_button_callback); +@endcode + +The callback function receives the [mouse button](@ref buttons), button action +and [modifier bits](@ref mods). + +@code +void mouse_button_callback(GLFWwindow* window, int button, int action, int mods) +{ + if (button == GLFW_MOUSE_BUTTON_RIGHT && action == GLFW_PRESS) + popup_menu(); +} +@endcode + +The action is one of `GLFW_PRESS` or `GLFW_RELEASE`. + +Mouse button states for [named buttons](@ref buttons) are also saved in +per-window state arrays that can be polled with @ref glfwGetMouseButton. + +@code +int state = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT); +if (state == GLFW_PRESS) + upgrade_cow(); +@endcode + +The returned state is one of `GLFW_PRESS` or `GLFW_RELEASE`. + +This function only returns cached mouse button event state. It does not poll +the system for the current state of the mouse button. + +Whenever you poll state, you risk missing the state change you are looking for. +If a pressed mouse button is released again before you poll its state, you will have +missed the button press. The recommended solution for this is to use a +mouse button callback, but there is also the `GLFW_STICKY_MOUSE_BUTTONS` +input mode. + +@code +glfwSetInputMode(window, GLFW_STICKY_MOUSE_BUTTONS, 1); +@endcode + +When sticky mouse buttons mode is enabled, the pollable state of a mouse button +will remain `GLFW_PRESS` until the state of that button is polled with @ref +glfwGetMouseButton. Once it has been polled, if a mouse button release event +had been processed in the meantime, the state will reset to `GLFW_RELEASE`, +otherwise it will remain `GLFW_PRESS`. + +The `GLFW_MOUSE_BUTTON_LAST` constant holds the highest value of any +[named button](@ref buttons). + + +@subsection scrolling Scroll input + +If you wish to be notified when the user scrolls, whether with a mouse wheel or +touchpad gesture, set a scroll callback. + +@code +glfwSetScrollCallback(window, scroll_callback); +@endcode + +The callback function receives two-dimensional scroll offsets. + +@code +void scroll_callback(GLFWwindow* window, double xoffset, double yoffset) +{ +} +@endcode + +A simple mouse wheel, being vertical, provides offsets along the Y-axis. + + +@section joystick Joystick input + +The joystick functions expose connected joysticks and controllers, with both +referred to as joysticks. It supports up to sixteen joysticks, ranging from +`GLFW_JOYSTICK_1`, `GLFW_JOYSTICK_2` up to `GLFW_JOYSTICK_LAST`. You can test +whether a [joystick](@ref joysticks) is present with @ref glfwJoystickPresent. + +@code +int present = glfwJoystickPresent(GLFW_JOYSTICK_1); +@endcode + +When GLFW is initialized, detected joysticks are added to to the beginning of +the array, starting with `GLFW_JOYSTICK_1`. Once a joystick is detected, it +keeps its assigned index until it is disconnected, so as joysticks are connected +and disconnected, they will become spread out. + +Joystick state is updated as needed when a joystick function is called and does +not require a window to be created or @ref glfwPollEvents or @ref glfwWaitEvents +to be called. + + +@subsection joystick_axis Joystick axis states + +The positions of all axes of a joystick are returned by @ref +glfwGetJoystickAxes. See the reference documentation for the lifetime of the +returned array. + +@code +int count; +const float* axes = glfwGetJoystickAxes(GLFW_JOYSTICK_1, &count); +@endcode + +Each element in the returned array is a value between -1.0 and 1.0. + + +@subsection joystick_button Joystick button states + +The states of all buttons of a joystick are returned by @ref +glfwGetJoystickButtons. See the reference documentation for the lifetime of the +returned array. + +@code +int count; +const unsigned char* axes = glfwGetJoystickButtons(GLFW_JOYSTICK_1, &count); +@endcode + +Each element in the returned array is either `GLFW_PRESS` or `GLFW_RELEASE`. + + +@subsection joystick_name Joystick name + +The human-readable, UTF-8 encoded name of a joystick is returned by @ref +glfwGetJoystickName. See the reference documentation for the lifetime of the +returned string. + +@code +const char* name = glfwGetJoystickName(GLFW_JOYSTICK_1); +@endcode + +Joystick names are not guaranteed to be unique. Two joysticks of the same model +and make may have the same name. Only the [joystick token](@ref joysticks) is +guaranteed to be unique, and only until that joystick is disconnected. + + +@section time Time input + +GLFW provides high-resolution time input, in seconds, with @ref glfwGetTime. + +@code +double seconds = glfwGetTime(); +@endcode + +It returns the number of seconds since the timer was started when the library +was initialized with @ref glfwInit. The platform-specific time sources used +usually have micro- or nanosecond resolution. + +You can modify the reference time with @ref glfwSetTime. + +@code +glfwSetTime(4.0); +@endcode + +This sets the timer to the specified time, in seconds. + + +@section clipboard Clipboard input and output + +If the system clipboard contains a UTF-8 encoded string or if it can be +converted to one, you can retrieve it with @ref glfwGetClipboardString. See the +reference documentation for the lifetime of the returned string. + +@code +const char* clipboard = glfwGetClipboardString(window); +@endcode + +The contents of the system clipboard can be set to a UTF-8 encoded string with +@ref glfwSetClipboardString. + +@code +glfwSetClipboardString(window, "A string with words in it"); +@endcode + +The clipboard functions take a window handle argument because some window +systems require a window to communicate with the system clipboard. Any valid +window may be used. + + +@section path_drop Path drop input + +If you wish to receive the paths of files and/or directories dropped on +a window, set a file drop callback. + +@code +glfwSetDropCallback(window, drop_callback); +@endcode + +The callback function receives an array of paths encoded as UTF-8. + +@code +void drop_callback(GLFWwindow* window, int count, const char** paths) +{ + int i; + for (i = 0; i < count; i++) + handle_dropped_file(paths[i]); +} +@endcode + +The path array and its strings are only valid until the file drop callback +returns, as they may have been generated specifically for that event. You need +to make a deep copy of the array if you want to keep the paths. + +*/ diff --git a/testbed/glfw/docs/internal.dox b/testbed/glfw/docs/internal.dox new file mode 100644 index 00000000..0389af6e --- /dev/null +++ b/testbed/glfw/docs/internal.dox @@ -0,0 +1,116 @@ +/*! + +@page internals Internal structure + +@tableofcontents + +There are several interfaces inside GLFW. Each interface has its own area of +responsibility and its own naming conventions. + + +@section internals_public Public interface + +The most well-known is the public interface, described in the glfw3.h header +file. This is implemented in source files shared by all platforms and these +files contain no platform-specific code. This code usually ends up calling the +platform and internal interfaces to do the actual work. + +The public interface uses the OpenGL naming conventions except with GLFW and +glfw instead of GL and gl. For struct members, where OpenGL sets no precedent, +it use headless camel case. + +Examples: @ref glfwCreateWindow, @ref GLFWwindow, @ref GLFWvidmode.redBits, +`GLFW_RED_BITS` + + +@section internals_native Native interface + +The [native interface](@ref native) is a small set of publicly available +but platform-specific functions, described in the glfw3native.h header file and +used to gain access to the underlying window, context and (on some platforms) +display handles used by the platform interface. + +The function names of the native interface are similar to those of the public +interface, but embeds the name of the interface that the returned handle is +from. + +Examples: @ref glfwGetX11Window, @ref glfwGetWGLContext + + +@section internals_internal Internal interface + +The internal interface consists of utility functions used by all other +interfaces. It is shared code implemented in the same shared source files as +the public and event interfaces. The internal interface is described in the +internal.h header file. + +The internal interface is in charge of GLFW's global data, which it stores in +a `_GLFWlibrary` struct named `_glfw`. + +The internal interface uses the same style as the public interface, except all +global names have a leading underscore. + +Examples: @ref _glfwIsValidContextConfig, @ref _GLFWwindow, `_glfw.currentRamp` + + +@section internals_platform Platform interface + +The platform interface implements all platform-specific operations as a service +to the public interface. This includes event processing. The platform +interface is never directly called by application code and never directly calls +application-provided callbacks. It is also prohibited from modifying the +platform-independent part of the internal structs. Instead, it calls the event +interface when events interesting to GLFW are received. + +The platform interface mirrors those parts of the public interface that needs to +perform platform-specific operations on some or all platforms. The are also +named the same except that the glfw function prefix is replaced by +_glfwPlatform. + +Examples: @ref _glfwPlatformCreateWindow + +The platform interface also defines structs that contain platform-specific +global and per-object state. Their names mirror those of the internal +interface, except that an interface-specific suffix is added. + +Examples: `_GLFWwindowX11`, `_GLFWcontextWGL` + +These structs are incorporated as members into the internal interface structs +using special macros that name them after the specific interface used. This +prevents shared code from accidentally using these members. + +Examples: `window.win32.handle`, `_glfw.x11.display` + + +@section internals_event Event interface + +The event interface is implemented in the same shared source files as the public +interface and is responsible for delivering the events it receives to the +application, either via callbacks, via window state changes or both. + +The function names of the event interface use a `_glfwInput` prefix and the +ObjectEvent pattern. + +Examples: @ref _glfwInputWindowFocus, @ref _glfwInputCursorMotion + + +@section internals_static Static functions + +Static functions may be used by any interface and have no prefixes or suffixes. +These use headless camel case. + +Examples: `clearScrollOffsets` + + +@section internals_config Configuration macros + +GLFW uses a number of configuration macros to select at compile time which +interfaces and code paths to use. They are defined in the glfw_config.h header file, +which is generated from the `glfw_config.h.in` file by CMake. + +Configuration macros the same style as tokens in the public interface, except +with a leading underscore. + +Examples: `_GLFW_HAS_GLXGETPROCADDRESS` + +*/ diff --git a/testbed/glfw/docs/intro.dox b/testbed/glfw/docs/intro.dox new file mode 100644 index 00000000..7888e5fd --- /dev/null +++ b/testbed/glfw/docs/intro.dox @@ -0,0 +1,347 @@ +/*! + +@page intro Introduction to the API + +@tableofcontents + +This guide introduces the basic concepts of GLFW and describes initialization, +error handling and API guarantees and limitations. For a broad but shallow +tutorial, see @ref quick instead. There are also guides for the other areas of +GLFW. + + - @ref window + - @ref context + - @ref monitor + - @ref input + + +@section intro_init Initialization and termination + +Before most GLFW functions may be called, the library must be initialized. +This initialization checks what features are available on the machine, +enumerates monitors and joysticks, initializes the timer and performs any +required platform-specific initialization. + +Only the following functions may be called before the library has been +successfully initialized, and only from the main thread. + + - @ref glfwGetVersion + - @ref glfwGetVersionString + - @ref glfwSetErrorCallback + - @ref glfwInit + - @ref glfwTerminate + +Calling any other function before that time will cause a @ref +GLFW_NOT_INITIALIZED error. + + +@subsection intro_init_init Initializing GLFW + +The library is initialized with @ref glfwInit, which returns `GL_FALSE` if an +error occurred. + +@code +if (!glfwInit()) +{ + // Handle initialization failure +} +@endcode + +If any part of initialization fails, all remaining bits are terminated as if +@ref glfwTerminate was called. The library only needs to be initialized once +and additional calls to an already initialized library will simply return +`GL_TRUE` immediately. + +Once the library has been successfully initialized, it should be terminated +before the application exits. + + +@subsection intro_init_terminate Terminating GLFW + +Before your application exits, you should terminate the GLFW library if it has +been initialized. This is done with @ref glfwTerminate. + +@code +glfwTerminate(); +@endcode + +This will destroy any remaining window, monitor and cursor objects, restore any +modified gamma ramps, re-enable the screensaver if it had been disabled and free +any resources allocated by GLFW. + +Once the library is terminated, it is as if it had never been initialized and +you will need to initialize it again before being able to use GLFW. If the +library was not initialized or had already been terminated, it return +immediately. + + +@section error_handling Error handling + +Some GLFW functions have return values that indicate an error, but this is often +not very helpful when trying to figure out _why_ the error occurred. Some +functions also return otherwise valid values on error. Finally, far from all +GLFW functions have return values. + +This is where the error callback comes in. This callback is called whenever an +error occurs. It is set with @ref glfwSetErrorCallback, a function that may be +called regardless of whether GLFW is initialized. + +@code +glfwSetErrorCallback(error_callback); +@endcode + +The error callback receives a human-readable description of the error and (when +possible) its cause. The description encoded as UTF-8. The callback is also +provided with an [error code](@ref errors). + +@code +void error_callback(int error, const char* description) +{ + puts(description); +} +@endcode + +The error code indicates the general category of the error. Some error codes, +such as @ref GLFW_NOT_INITIALIZED has only a single meaning, whereas others like +@ref GLFW_PLATFORM_ERROR are used for many different errors. + +The description string is only valid until the error callback returns, as it may +have been generated specifically for that error. This lets GLFW provide much +more specific error descriptions but means you must make a copy if you want to +keep the description string. + + +@section coordinate_systems Coordinate systems + +GLFW has two primary coordinate systems: the _virtual screen_ and the window +_client area_ or _content area_. Both use the same unit: _virtual screen +coordinates_, or just _screen coordinates_, which don't necessarily correspond +to pixels. + + + +Both the virtual screen and the client area coordinate systems have the X-axis +pointing to the right and the Y-axis pointing down. + +Window and monitor positions are specified as the position of the upper-left +corners of their content areas relative to the virtual screen, while cursor +positions are specified relative to a window's client area. + +Because the origin of the window's client area coordinate system is also the +point from which the window position is specified, you can translate client area +coordinates to the virtual screen by adding the window position. The window +frame, when present, extends out from the client area but does not affect the +window position. + +Almost all positions and sizes in GLFW are measured in screen coordinates +relative to one of the two origins above. This includes cursor positions, +window positions and sizes, window frame sizes, monitor positions and video mode +resolutions. + +Two exceptions are the [monitor physical size](@ref monitor_size), which is +measured in millimetres, and [framebuffer size](@ref window_fbsize), which is +measured in pixels. + +Pixels and screen coordinates may map 1:1 on your machine, but they won't on +every other machine, for example on a Mac with a Retina display. The ratio +between screen coordinates and pixels may also change at run-time depending on +which monitor the window is currently considered to be on. + + +@section guarantees_limitations Guarantees and limitations + +This section describes the conditions under which GLFW can be expected to +function, barring bugs in the operating system or drivers. Use of GLFW outside +of these limits may work on some platforms, or on some machines, or some of the +time, or on some versions of GLFW, but it may break at any time and this will +not be considered a bug. + + +@subsection lifetime Pointer lifetimes + +GLFW will never free any pointer you provide to it and you must never free any +pointer it provides to you. + +Many GLFW functions return pointers to dynamically allocated structures, strings +or arrays, and some callbacks are provided with strings or arrays. These are +always managed by GLFW and should never be freed by the application. The +lifetime of these pointers is documented for each GLFW function and callback. +If you need to keep this data, you must copy it before its lifetime expires. + +Many GLFW functions accept pointers to structures or strings allocated by the +application. These are never freed by GLFW and are always the responsibility of +the application. If GLFW needs to keep the data in these structures or strings, +it is copied before the function returns. + +Pointer lifetimes are guaranteed not to be shortened in future minor or patch +releases. + + +@subsection reentrancy Reentrancy + +GLFW event processing and object creation and destruction are not reentrant. +This means that the following functions may not be called from any callback +function: + + - @ref glfwCreateWindow + - @ref glfwDestroyWindow + - @ref glfwCreateCursor + - @ref glfwCreateStandardCursor + - @ref glfwDestroyCursor + - @ref glfwPollEvents + - @ref glfwWaitEvents + - @ref glfwTerminate + +These functions may be made reentrant in future minor or patch releases, but +functions not on this list will not be made non-reentrant. + + +@subsection thread_safety Thread safety + +Most GLFW functions may only be called from the main thread, but some may be +called from any thread. However, no GLFW function may be called from any other +thread until GLFW has been successfully initialized on the main thread, +including functions that may called before initialization. + +The reference documentation for every GLFW function states whether it is limited +to the main thread. + +The following categories of functions are and will remain limited to the main +thread due to the limitations of one or several platforms: + + - Initialization and termination + - Event processing + - Creation and destruction of window, context and cursor objects + +Because event processing must be performed on the main thread, all callbacks +except for the error callback will only be called on that thread. The error +callback may be called on any thread, as any GLFW function may generate errors. + +The posting of empty events may be done from any thread. The window user +pointer and close flag may also be accessed and modified from any thread, but +this is not synchronized by GLFW. The following window related functions may +be called from any thread: + + - @ref glfwPostEmptyEvent + - @ref glfwGetWindowUserPointer + - @ref glfwSetWindowUserPointer + - @ref glfwWindowShouldClose + - @ref glfwSetWindowShouldClose + +Rendering may be done on any thread. The following context related functions +may be called from any thread: + + - @ref glfwMakeContextCurrent + - @ref glfwGetCurrentContext + - @ref glfwSwapBuffers + - @ref glfwSwapInterval + - @ref glfwExtensionSupported + - @ref glfwGetProcAddress + +The timer may be accessed from any thread, but this is not synchronized by GLFW. +The following timer related functions may be called from any thread: + + - @ref glfwGetTime + +Library version information may be queried from any thread. The following +version related functions may be called from any thread: + + - @ref glfwGetVersion + - @ref glfwGetVersionString + +GLFW uses no synchronization objects internally except for thread-local storage +to keep track of the current context for each thread. Synchronization is left +to the application. + +Functions that may currently be called from any thread will always remain so, +but functions that are currently limited to the main may be updated to allow +calls from any thread in future releases. + + +@subsection compatibility Version compatibility + +GLFW guarantees binary backward compatibility with earlier minor versions of the +API. This means that you can drop in a newer version of the GLFW DLL / shared +library / dynamic library and existing applications will continue to run. + +Once a function or constant has been added, the signature of that function or +value of that constant will remain unchanged until the next major version of +GLFW. No compatibility of any kind is guaranteed between major versions. + +Undocumented behavior, i.e. behavior that is not described in the documentation, +may change at any time until it is documented. + +If the reference documentation and the implementation differ, the reference +documentation is correct and the implementation will be fixed in the next +release. + + +@subsection event_order Event order + +The order of arrival of related events is not guaranteed to be consistent +across platforms. The exception is synthetic key and mouse button release +events, which are always delivered after the window defocus event. + + +@section intro_version Version management + +GLFW provides mechanisms for identifying what version of GLFW your application +was compiled against as well as what version it is currently running against. +If you are loading GLFW dynamically (not just linking dynamically), you can use +this to verify that the library binary is compatible with your application. + + +@subsection intro_version_compile Compile-time version + +The compile-time version of GLFW is provided by the GLFW header with the +`GLFW_VERSION_MAJOR`, `GLFW_VERSION_MINOR` and `GLFW_VERSION_REVISION` macros. + +@code +printf("Compiled against GLFW %i.%i.%i\n", + GLFW_VERSION_MAJOR, + GLFW_VERSION_MINOR, + GLFW_VERSION_REVISION); +@endcode + + +@subsection intro_version_runtime Run-time version + +The run-time version can be retrieved with @ref glfwGetVersion, a function that +may be called regardless of whether GLFW is initialized. + +@code +int major, minor, revision; +glfwGetVersion(&major, &minor, &revision); + +printf("Running against GLFW %i.%i.%i\n", major, minor, revision); +@endcode + + +@subsection intro_version_string Version string + +GLFW 3 also provides a compile-time generated version string that describes the +version, platform, compiler and any platform-specific compile-time options. +This is primarily intended for submitting bug reports, to allow developers to +see which code paths are enabled in a binary. + +The version string is returned by @ref glfwGetVersionString, a function that may +be called regardless of whether GLFW is initialized. + +__Do not use the version string__ to parse the GLFW library version. The @ref +glfwGetVersion function already provides the version of the running library +binary. + +The format of the string is as follows: + - The version of GLFW + - The name of the window system API + - The name of the context creation API + - Any additional options or APIs + +For example, when compiling GLFW 3.0 with MinGW using the Win32 and WGL +back ends, the version string may look something like this: + +@code +3.0.0 Win32 WGL MinGW +@endcode + +*/ diff --git a/testbed/glfw/docs/main.dox b/testbed/glfw/docs/main.dox new file mode 100644 index 00000000..e5caae0d --- /dev/null +++ b/testbed/glfw/docs/main.dox @@ -0,0 +1,47 @@ +/*! + +@mainpage notitle + +@section main_intro Introduction + +__GLFW__ is a free, Open Source, multi-platform library for creating windows +with OpenGL or OpenGL ES contexts and receiving many kinds of input. It is easy +to integrate into existing applications and does not lay claim to the main loop. + +See @ref news_31 for release highlights or the +[version history](http://www.glfw.org/changelog.html) for details. + +@ref quick is a guide for those new to GLFW. It takes you through how to write +a small but complete program. For people coming from GLFW 2, the @ref moving +guide explains what has changed and how to update existing code to use the new +API. + +There are guides for each of the various areas of the API. + + - @ref intro – initialization, error handling and high-level design + - @ref window – creating and working with windows and framebuffers + - @ref context – working with OpenGL and OpenGL ES contexts + - @ref monitor – enumerating and working with monitors and video modes + - @ref input – receiving events, polling and processing input + +Once you have written a program, see the @ref compile and @ref build guides. + +The [reference documentation](modules.html) provides more detailed information +about specific functions. + +There is a section on @ref guarantees_limitations for pointer lifetimes, +reentrancy, thread safety, event order and backward and forward compatibility. + +The @ref rift fills in the gaps for how to use LibOVR with GLFW. + +The [FAQ](http://www.glfw.org/faq.html) answers many common questions about the +design, implementation and use of GLFW. + +Finally, the @ref compat guide explains what APIs, standards and protocols GLFW +uses and what happens when they are not present on a given machine. + +This documentation was generated with Doxygen. The sources for it are available +in both the [source distribution](http://www.glfw.org/download.html) and +[GitHub repository](https://github.com/glfw/glfw). + +*/ diff --git a/testbed/glfw/docs/monitor.dox b/testbed/glfw/docs/monitor.dox new file mode 100644 index 00000000..8a5c5d90 --- /dev/null +++ b/testbed/glfw/docs/monitor.dox @@ -0,0 +1,204 @@ +/*! + +@page monitor Monitor guide + +@tableofcontents + +This guide introduces the monitor related functions of GLFW. There are also +guides for the other areas of GLFW. + + - @ref intro + - @ref window + - @ref context + - @ref input + + +@section monitor_object Monitor objects + +A monitor object represents a currently connected monitor and is represented as +a pointer to the [opaque](https://en.wikipedia.org/wiki/Opaque_data_type) type +@ref GLFWmonitor. Monitor objects cannot be created or destroyed by the +application and retain their addresses until the monitors they represent are +disconnected or until the library is [terminated](@ref intro_init_terminate). + +Each monitor has a current video mode, a list of supported video modes, +a virtual position, a human-readable name, an estimated physical size and +a gamma ramp. One of the monitors is the primary monitor. + +The virtual position of a monitor is in +[screen coordinates](@ref coordinate_systems) and, together with the current +video mode, describes the viewports that the connected monitors provide into the +virtual desktop that spans them. + +To see how GLFW views your monitor setup and its available video modes, run the +`modes` test program. + + +@subsection monitor_monitors Retrieving monitors + +The primary monitor is returned by @ref glfwGetPrimaryMonitor. It is the user's +preferred monitor and is usually the one with global UI elements like task bar +or menu bar. + +@code +GLFWmonitor* primary = glfwGetPrimaryMonitor(); +@endcode + +You can retrieve all currently connected monitors with @ref glfwGetMonitors. +See the reference documentation for the lifetime of the returned array. + +@code +int count; +GLFWmonitor** monitors = glfwGetMonitors(&count); +@endcode + +The primary monitor is always the first monitor in the returned array, but other +monitors may be moved to a different index when a monitor is connected or +disconnected. + + +@subsection monitor_event Monitor configuration changes + +If you wish to be notified when a monitor is connected or disconnected, set +a monitor callback. + +@code +glfwSetMonitorCallback(monitor_callback); +@endcode + +The callback function receives the handle for the monitor that has been +connected or disconnected and a monitor action. + +@code +void monitor_callback(GLFWmonitor* monitor, int event) +{ +} +@endcode + +The action is one of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`. + + +@section monitor_properties Monitor properties + +Each monitor has a current video mode, a list of supported video modes, +a virtual position, a human-readable name, an estimated physical size and +a gamma ramp. + + +@subsection monitor_modes Video modes + +GLFW generally does a good job selecting a suitable video mode when you create +a full screen window, but it is sometimes useful to know exactly which video +modes are supported. + +Video modes are represented as @ref GLFWvidmode structures. You can get an +array of the video modes supported by a monitor with @ref glfwGetVideoModes. +See the reference documentation for the lifetime of the returned array. + +@code +int count; +GLFWvidmode* modes = glfwGetVideoModes(monitor, &count); +@endcode + +To get the current video mode of a monitor call @ref glfwGetVideoMode. See the +reference documentation for the lifetime of the returned pointer. + +@code +const GLFWvidmode* mode = glfwGetVideoMode(monitor); +@endcode + +The resolution of a video mode is specified in +[screen coordinates](@ref coordinate_systems), not pixels. + + +@subsection monitor_size Physical size + +The physical size of a monitor in millimetres, or an estimation of it, can be +retrieved with @ref glfwGetMonitorPhysicalSize. This has no relation to its +current _resolution_, i.e. the width and height of its current +[video mode](@ref monitor_modes). + +@code +int widthMM, heightMM; +glfwGetMonitorPhysicalSize(monitor, &widthMM, &heightMM); +@endcode + +This can, for example, be used together with the current video mode to calculate +the DPI of a monitor. + +@code +const double dpi = mode->width / (widthMM / 25.4); +@endcode + + +@subsection monitor_pos Virtual position + +The position of the monitor on the virtual desktop, in +[screen coordinates](@ref coordinate_systems), can be retrieved with @ref +glfwGetMonitorPos. + +@code +int xpos, ypos; +glfwGetMonitorPos(monitor, &xpos, &ypos); +@endcode + + +@subsection monitor_name Human-readable name + +The human-readable, UTF-8 encoded name of a monitor is returned by @ref +glfwGetMonitorName. See the reference documentation for the lifetime of the +returned string. + +@code +const char* name = glfwGetMonitorName(monitor); +@endcode + +Monitor names are not guaranteed to be unique. Two monitors of the same model +and make may have the same name. Only the monitor handle is guaranteed to be +unique, and only until that monitor is disconnected. + + +@subsection monitor_gamma Gamma ramp + +The gamma ramp of a monitor can be set with @ref glfwSetGammaRamp, which accepts +a monitor handle and a pointer to a @ref GLFWgammaramp structure. + +@code +GLFWgammaramp ramp; +unsigned short red[256], green[256], blue[256]; + +ramp.size = 256; +ramp.red = red; +ramp.green = green; +ramp.blue = blue; + +for (i = 0; i < ramp.size; i++) +{ + // Fill out gamma ramp arrays as desired +} + +glfwSetGammaRamp(monitor, &ramp); +@endcode + +The gamma ramp data is copied before the function returns, so there is no need +to keep it around once the ramp has been set. + +@note It is recommended to use gamma ramps of size 256, as that is the size +supported by all graphics cards on all platforms. + +The current gamma ramp for a monitor is returned by @ref glfwGetGammaRamp. See +the reference documentation for the lifetime of the returned structure. + +@code +const GLFWgammaramp* ramp = glfwGetGammaRamp(monitor); +@endcode + +If you wish to set a regular gamma ramp, you can have GLFW calculate it for you +from the desired exponent with @ref glfwSetGamma, which in turn calls @ref +glfwSetGammaRamp with the resulting ramp. + +@code +glfwSetGamma(monitor, 1.0); +@endcode + +*/ diff --git a/testbed/glfw/docs/moving.dox b/testbed/glfw/docs/moving.dox new file mode 100644 index 00000000..0e7ed5e3 --- /dev/null +++ b/testbed/glfw/docs/moving.dox @@ -0,0 +1,494 @@ +/*! + +@page moving Moving from GLFW 2 to 3 + +@tableofcontents + +This is a transition guide for moving from GLFW 2 to 3. It describes what has +changed or been removed, but does _not_ include +[new features](@ref news) unless they are required when moving an existing code +base onto the new API. For example, the new multi-monitor functions are +required to create full screen windows with GLFW 3. + + +@section moving_removed Changed and removed features + +@subsection moving_renamed_files Renamed library and header file + +The GLFW 3 header is named @ref glfw3.h and moved to the `GLFW` directory, to +avoid collisions with the headers of other major versions. Similarly, the GLFW +3 library is named `glfw3,` except when it's installed as a shared library on +Unix-like systems, where it uses the +[soname](https://en.wikipedia.org/wiki/soname) `libglfw.so.3`. + +@par Old syntax +@code +#include +@endcode + +@par New syntax +@code +#include +@endcode + + +@subsection moving_threads Removal of threading functions + +The threading functions have been removed, including the per-thread sleep +function. They were fairly primitive, under-used, poorly integrated and took +time away from the focus of GLFW (i.e. context, input and window). There are +better threading libraries available and native threading support is available +in both [C++11](http://en.cppreference.com/w/cpp/thread) and +[C11](http://en.cppreference.com/w/c/thread), both of which are gaining +traction. + +If you wish to use the C++11 or C11 facilities but your compiler doesn't yet +support them, see the +[TinyThread++](https://gitorious.org/tinythread/tinythreadpp) and +[TinyCThread](https://github.com/tinycthread/tinycthread) projects created by +the original author of GLFW. These libraries implement a usable subset of the +threading APIs in C++11 and C11, and in fact some GLFW 3 test programs use +TinyCThread. + +However, GLFW 3 has better support for _use from multiple threads_ than GLFW +2 had. Contexts can be made current on any thread, although only a single +thread at a time, and the documentation explicitly states which functions may be +used from any thread and which may only be used from the main thread. + +@par Removed functions +`glfwSleep`, `glfwCreateThread`, `glfwDestroyThread`, `glfwWaitThread`, +`glfwGetThreadID`, `glfwCreateMutex`, `glfwDestroyMutex`, `glfwLockMutex`, +`glfwUnlockMutex`, `glfwCreateCond`, `glfwDestroyCond`, `glfwWaitCond`, +`glfwSignalCond`, `glfwBroadcastCond` and `glfwGetNumberOfProcessors`. + + +@subsection moving_image Removal of image and texture loading + +The image and texture loading functions have been removed. They only supported +the Targa image format, making them mostly useful for beginner level examples. +To become of sufficiently high quality to warrant keeping them in GLFW 3, they +would need not only to support other formats, but also modern extensions to +OpenGL texturing. This would either add a number of external +dependencies (libjpeg, libpng, etc.), or force GLFW to ship with inline versions +of these libraries. + +As there already are libraries doing this, it is unnecessary both to duplicate +the work and to tie the duplicate to GLFW. The resulting library would also be +platform-independent, as both OpenGL and stdio are available wherever GLFW is. + +@par Removed functions +`glfwReadImage`, `glfwReadMemoryImage`, `glfwFreeImage`, `glfwLoadTexture2D`, +`glfwLoadMemoryTexture2D` and `glfwLoadTextureImage2D`. + + +@subsection moving_stdcall Removal of GLFWCALL macro + +The `GLFWCALL` macro, which made callback functions use +[__stdcall](http://msdn.microsoft.com/en-us/library/zxk0tw93.aspx) on Windows, +has been removed. GLFW is written in C, not Pascal. Removing this macro means +there's one less thing for application programmers to remember, i.e. the +requirement to mark all callback functions with `GLFWCALL`. It also simplifies +the creation of DLLs and DLL link libraries, as there's no need to explicitly +disable `@n` entry point suffixes. + +@par Old syntax +@code +void GLFWCALL callback_function(...); +@endcode + +@par New syntax +@code +void callback_function(...); +@endcode + + +@subsection moving_window_handles Window handle parameters + +Because GLFW 3 supports multiple windows, window handle parameters have been +added to all window-related GLFW functions and callbacks. The handle of +a newly created window is returned by @ref glfwCreateWindow (formerly +`glfwOpenWindow`). Window handles are pointers to the +[opaque](https://en.wikipedia.org/wiki/Opaque_data_type) type @ref GLFWwindow. + +@par Old syntax +@code +glfwSetWindowTitle("New Window Title"); +@endcode + +@par New syntax +@code +glfwSetWindowTitle(window, "New Window Title"); +@endcode + + +@subsection moving_monitor Explicit monitor selection + +GLFW 3 provides support for multiple monitors. To request a full screen mode window, +instead of passing `GLFW_FULLSCREEN` you specify which monitor you wish the +window to use. The @ref glfwGetPrimaryMonitor function returns the monitor that +GLFW 2 would have selected, but there are many other +[monitor functions](@ref monitor). Monitor handles are pointers to the +[opaque](https://en.wikipedia.org/wiki/Opaque_data_type) type @ref GLFWmonitor. + +@par Old basic full screen +@code +glfwOpenWindow(640, 480, 8, 8, 8, 0, 24, 0, GLFW_FULLSCREEN); +@endcode + +@par New basic full screen +@code +window = glfwCreateWindow(640, 480, "My Window", glfwGetPrimaryMonitor(), NULL); +@endcode + +@note The framebuffer bit depth parameters of `glfwOpenWindow` have been turned +into [window hints](@ref window_hints), but as they have been given +[sane defaults](@ref window_hints_values) you rarely need to set these hints. + + +@subsection moving_autopoll Removal of automatic event polling + +GLFW 3 does not automatically poll for events in @ref glfwSwapBuffers, meaning +you need to call @ref glfwPollEvents or @ref glfwWaitEvents yourself. Unlike +buffer swap, which acts on a single window, the event processing functions act +on all windows at once. + +@par Old basic main loop +@code +while (...) +{ + // Process input + // Render output + glfwSwapBuffers(); +} +@endcode + +@par New basic main loop +@code +while (...) +{ + // Process input + // Render output + glfwSwapBuffers(window); + glfwPollEvents(); +} +@endcode + + +@subsection moving_context Explicit context management + +Each GLFW 3 window has its own OpenGL context and only you, the application +programmer, can know which context should be current on which thread at any +given time. Therefore, GLFW 3 leaves that decision to you. + +This means that you need to call @ref glfwMakeContextCurrent after creating +a window before you can call any OpenGL functions. + + +@subsection moving_hidpi Separation of window and framebuffer sizes + +Window positions and sizes now use screen coordinates, which may not be the same +as pixels on machines with high-DPI monitors. This is important as OpenGL uses +pixels, not screen coordinates. For example, the rectangle specified with +`glViewport` needs to use pixels. Therefore, framebuffer size functions have +been added. You can retrieve the size of the framebuffer of a window with @ref +glfwGetFramebufferSize function. A framebuffer size callback has also been +added, which can be set with @ref glfwSetFramebufferSizeCallback. + +@par Old basic viewport setup +@code +glfwGetWindowSize(&width, &height); +glViewport(0, 0, width, height); +@endcode + +@par New basic viewport setup +@code +glfwGetFramebufferSize(window, &width, &height); +glViewport(0, 0, width, height); +@endcode + + +@subsection moving_window_close Window closing changes + +The `GLFW_OPENED` window parameter has been removed. As long as the window has +not been destroyed, whether through @ref glfwDestroyWindow or @ref +glfwTerminate, the window is "open". + +A user attempting to close a window is now just an event like any other. Unlike +GLFW 2, windows and contexts created with GLFW 3 will never be destroyed unless +you choose them to be. Each window now has a close flag that is set to +`GL_TRUE` when the user attempts to close that window. By default, nothing else +happens and the window stays visible. It is then up to you to either destroy +the window, take some other action or simply ignore the request. + +You can query the close flag at any time with @ref glfwWindowShouldClose and set +it at any time with @ref glfwSetWindowShouldClose. + +@par Old basic main loop +@code +while (glfwGetWindowParam(GLFW_OPENED)) +{ + ... +} +@endcode + +@par New basic main loop +@code +while (!glfwWindowShouldClose(window)) +{ + ... +} +@endcode + +The close callback no longer returns a value. Instead, it is called after the +close flag has been set so it can override its value, if it chooses to, before +event processing completes. You may however not call @ref glfwDestroyWindow +from the close callback (or any other window related callback). + +@par Old syntax +@code +int GLFWCALL window_close_callback(void); +@endcode + +@par New syntax +@code +void window_close_callback(GLFWwindow* window); +@endcode + +@note GLFW never clears the close flag to `GL_FALSE`, meaning you can use it +for other reasons to close the window as well, for example the user choosing +Quit from an in-game menu. + + +@subsection moving_hints Persistent window hints + +The `glfwOpenWindowHint` function has been renamed to @ref glfwWindowHint. + +Window hints are no longer reset to their default values on window creation, but +instead retain their values until modified by @ref glfwWindowHint or @ref +glfwDefaultWindowHints, or until the library is terminated and re-initialized. + + +@subsection moving_video_modes Video mode enumeration + +Video mode enumeration is now per-monitor. The @ref glfwGetVideoModes function +now returns all available modes for a specific monitor instead of requiring you +to guess how large an array you need. The `glfwGetDesktopMode` function, which +had poorly defined behavior, has been replaced by @ref glfwGetVideoMode, which +returns the current mode of a monitor. + + +@subsection moving_char_up Removal of character actions + +The action parameter of the [character callback](@ref GLFWcharfun) has been +removed. This was an artefact of the origin of GLFW, i.e. being developed in +English by a Swede. However, many keyboard layouts require more than one key to +produce characters with diacritical marks. Even the Swedish keyboard layout +requires this for uncommon cases like ü. + +@par Old syntax +@code +void GLFWCALL character_callback(int character, int action); +@endcode + +@par New syntax +@code +void character_callback(GLFWwindow* window, int character); +@endcode + + +@subsection moving_cursorpos Cursor position changes + +The `glfwGetMousePos` function has been renamed to @ref glfwGetCursorPos, +`glfwSetMousePos` to @ref glfwSetCursorPos and `glfwSetMousePosCallback` to @ref +glfwSetCursorPosCallback. + +The cursor position is now `double` instead of `int`, both for the direct +functions and for the callback. Some platforms can provide sub-pixel cursor +movement and this data is now passed on to the application where available. On +platforms where this is not provided, the decimal part is zero. + +GLFW 3 only allows you to position the cursor within a window using @ref +glfwSetCursorPos (formerly `glfwSetMousePos`) when that window is active. +Unless the window is active, the function fails silently. + + +@subsection moving_wheel Wheel position replaced by scroll offsets + +The `glfwGetMouseWheel` function has been removed. Scrolling is the input of +offsets and has no absolute position. The mouse wheel callback has been +replaced by a [scroll callback](@ref GLFWscrollfun) that receives +two-dimensional floating point scroll offsets. This allows you to receive +precise scroll data from for example modern touchpads. + +@par Old syntax +@code +void GLFWCALL mouse_wheel_callback(int position); +@endcode + +@par New syntax +@code +void scroll_callback(GLFWwindow* window, double xoffset, double yoffset); +@endcode + +@par Removed functions +`glfwGetMouseWheel` + + +@subsection moving_repeat Key repeat action + +The `GLFW_KEY_REPEAT` enable has been removed and key repeat is always enabled +for both keys and characters. A new key action, `GLFW_REPEAT`, has been added +to allow the [key callback](@ref GLFWkeyfun) to distinguish an initial key press +from a repeat. Note that @ref glfwGetKey still returns only `GLFW_PRESS` or +`GLFW_RELEASE`. + + +@subsection moving_keys Physical key input + +GLFW 3 key tokens map to physical keys, unlike in GLFW 2 where they mapped to +the values generated by the current keyboard layout. The tokens are named +according to the values they would have using the standard US layout, but this +is only a convenience, as most programmers are assumed to know that layout. +This means that (for example) `GLFW_KEY_LEFT_BRACKET` is always a single key and +is the same key in the same place regardless of what keyboard layouts the users +of your program has. + +The key input facility was never meant for text input, although using it that +way worked slightly better in GLFW 2. If you were using it to input text, you +should be using the character callback instead, on both GLFW 2 and 3. This will +give you the characters being input, as opposed to the keys being pressed. + +GLFW 3 has key tokens for all keys on a standard 105 key keyboard, so instead of +having to remember whether to check for `'a'` or `'A'`, you now check for +`GLFW_KEY_A`. + + +@subsection moving_joystick Joystick function changes + +The `glfwGetJoystickPos` function has been renamed to @ref glfwGetJoystickAxes. + +The `glfwGetJoystickParam` function and the `GLFW_PRESENT`, `GLFW_AXES` and +`GLFW_BUTTONS` tokens have been replaced by the @ref glfwJoystickPresent +function as well as axis and button counts returned by the @ref +glfwGetJoystickAxes and @ref glfwGetJoystickButtons functions. + + +@subsection moving_mbcs Win32 MBCS support + +The Win32 port of GLFW 3 will not compile in +[MBCS mode](http://msdn.microsoft.com/en-us/library/5z097dxa.aspx). +However, because the use of the Unicode version of the Win32 API doesn't affect +the process as a whole, but only those windows created using it, it's perfectly +possible to call MBCS functions from other parts of the same application. +Therefore, even if an application using GLFW has MBCS mode code, there's no need +for GLFW itself to support it. + + +@subsection moving_windows Support for versions of Windows older than XP + +All explicit support for version of Windows older than XP has been removed. +There is no code that actively prevents GLFW 3 from running on these earlier +versions, but it uses Win32 functions that those versions lack. + +Windows XP was released in 2001, and by now (January 2015) it has not only +replaced almost all earlier versions of Windows, but is itself rapidly being +replaced by Windows 7 and 8. The MSDN library doesn't even provide +documentation for version older than Windows 2000, making it difficult to +maintain compatibility with these versions even if it was deemed worth the +effort. + +The Win32 API has also not stood still, and GLFW 3 uses many functions only +present on Windows XP or later. Even supporting an OS as new as XP (new +from the perspective of GLFW 2, which still supports Windows 95) requires +runtime checking for a number of functions that are present only on modern +version of Windows. + + +@subsection moving_syskeys Capture of system-wide hotkeys + +The ability to disable and capture system-wide hotkeys like Alt+Tab has been +removed. Modern applications, whether they're games, scientific visualisations +or something else, are nowadays expected to be good desktop citizens and allow +these hotkeys to function even when running in full screen mode. + + +@subsection moving_terminate Automatic termination + +GLFW 3 does not register @ref glfwTerminate with `atexit` at initialization, +because `exit` calls registered functions from the calling thread and while it +is permitted to call `exit` from any thread, @ref glfwTerminate may only be +called from the main thread. + +To release all resources allocated by GLFW, you should call @ref glfwTerminate +yourself, from the main thread, before the program terminates. Note that this +destroys all windows not already destroyed with @ref glfwDestroyWindow, +invalidating any window handles you may still have. + + +@subsection moving_glu GLU header inclusion + +GLFW 3 does not by default include the GLU header and GLU itself has been +deprecated by [Khronos](https://en.wikipedia.org/wiki/Khronos_Group). __New +projects should avoid using GLU__, but if you need to compile legacy code that +has been moved to GLFW 3, you can request that the GLFW header includes it by +defining `GLFW_INCLUDE_GLU` before the inclusion of the GLFW header. + +@par Old syntax +@code +#include +@endcode + +@par New syntax +@code +#define GLFW_INCLUDE_GLU +#include +@endcode + + +@section moving_tables Name change tables + + +@subsection moving_renamed_functions Renamed functions + +| GLFW 2 | GLFW 3 | Notes | +| --------------------------- | ----------------------------- | ----- | +| `glfwOpenWindow` | @ref glfwCreateWindow | All channel bit depths are now hints +| `glfwCloseWindow` | @ref glfwDestroyWindow | | +| `glfwOpenWindowHint` | @ref glfwWindowHint | Now accepts all `GLFW_*_BITS` tokens | +| `glfwEnable` | @ref glfwSetInputMode | | +| `glfwDisable` | @ref glfwSetInputMode | | +| `glfwGetMousePos` | @ref glfwGetCursorPos | | +| `glfwSetMousePos` | @ref glfwSetCursorPos | | +| `glfwSetMousePosCallback` | @ref glfwSetCursorPosCallback | | +| `glfwSetMouseWheelCallback` | @ref glfwSetScrollCallback | Accepts two-dimensional scroll offsets as doubles | +| `glfwGetJoystickPos` | @ref glfwGetJoystickAxes | | +| `glfwGetWindowParam` | @ref glfwGetWindowAttrib | | +| `glfwGetGLVersion` | @ref glfwGetWindowAttrib | Use `GLFW_CONTEXT_VERSION_MAJOR`, `GLFW_CONTEXT_VERSION_MINOR` and `GLFW_CONTEXT_REVISION` | +| `glfwGetDesktopMode` | @ref glfwGetVideoMode | Returns the current mode of a monitor | +| `glfwGetJoystickParam` | @ref glfwJoystickPresent | The axis and button counts are provided by @ref glfwGetJoystickAxes and @ref glfwGetJoystickButtons | + +@subsection moving_renamed_tokens Renamed tokens + +| GLFW 2 | GLFW 3 | Notes | +| --------------------------- | ---------------------------- | ----- | +| `GLFW_OPENGL_VERSION_MAJOR` | `GLFW_CONTEXT_VERSION_MAJOR` | Renamed as it applies to OpenGL ES as well | +| `GLFW_OPENGL_VERSION_MINOR` | `GLFW_CONTEXT_VERSION_MINOR` | Renamed as it applies to OpenGL ES as well | +| `GLFW_FSAA_SAMPLES` | `GLFW_SAMPLES` | Renamed to match the OpenGL API | +| `GLFW_ACTIVE` | `GLFW_FOCUSED` | Renamed to match the window focus callback | +| `GLFW_WINDOW_NO_RESIZE` | `GLFW_RESIZABLE` | The default has been inverted | +| `GLFW_MOUSE_CURSOR` | `GLFW_CURSOR` | Used with @ref glfwSetInputMode | +| `GLFW_KEY_ESC` | `GLFW_KEY_ESCAPE` | | +| `GLFW_KEY_DEL` | `GLFW_KEY_DELETE` | | +| `GLFW_KEY_PAGEUP` | `GLFW_KEY_PAGE_UP` | | +| `GLFW_KEY_PAGEDOWN` | `GLFW_KEY_PAGE_DOWN` | | +| `GLFW_KEY_KP_NUM_LOCK` | `GLFW_KEY_NUM_LOCK` | | +| `GLFW_KEY_LCTRL` | `GLFW_KEY_LEFT_CONTROL` | | +| `GLFW_KEY_LSHIFT` | `GLFW_KEY_LEFT_SHIFT` | | +| `GLFW_KEY_LALT` | `GLFW_KEY_LEFT_ALT` | | +| `GLFW_KEY_LSUPER` | `GLFW_KEY_LEFT_SUPER` | | +| `GLFW_KEY_RCTRL` | `GLFW_KEY_RIGHT_CONTROL` | | +| `GLFW_KEY_RSHIFT` | `GLFW_KEY_RIGHT_SHIFT` | | +| `GLFW_KEY_RALT` | `GLFW_KEY_RIGHT_ALT` | | +| `GLFW_KEY_RSUPER` | `GLFW_KEY_RIGHT_SUPER` | | + +*/ diff --git a/testbed/glfw/docs/news.dox b/testbed/glfw/docs/news.dox new file mode 100644 index 00000000..8ae36aa1 --- /dev/null +++ b/testbed/glfw/docs/news.dox @@ -0,0 +1,292 @@ +/*! + +@page news New features + +@section news_31 New features in 3.1 + +These are the release highlights. For a full list of changes see the +[version history](http://www.glfw.org/changelog.html). + + +@subsection news_31_cursor Custom mouse cursor images + +GLFW now supports creating and setting both custom cursor images and standard +cursor shapes. They are created with @ref glfwCreateCursor or @ref +glfwCreateStandardCursor, set with @ref glfwSetCursor and destroyed with @ref +glfwDestroyCursor. + +@see @ref cursor_object + + +@subsection news_31_drop Path drop event + +GLFW now provides a callback for receiving the paths of files and directories +dropped onto GLFW windows. The callback is set with @ref glfwSetDropCallback. + +@see @ref path_drop + + +@subsection news_31_emptyevent Main thread wake-up + +GLFW now provides the @ref glfwPostEmptyEvent function for posting an empty +event from another thread to the main thread event queue, causing @ref +glfwWaitEvents to return. + +@see @ref events + + +@subsection news_31_framesize Window frame size query + +GLFW now supports querying the size, on each side, of the frame around the +client area of a window, with @ref glfwGetWindowFrameSize. + +@see [Window size](@ref window_size) + + +@subsection news_31_autoiconify Simultaneous multi-monitor rendering + +GLFW now supports disabling auto-iconification of full screen windows with +the [GLFW_AUTO_ICONIFY](@ref window_hints_wnd) window hint. This is intended +for people building multi-monitor installations, where you need windows to stay +in full screen despite losing input focus. + + +@subsection news_31_floating Floating windows + +GLFW now supports floating windows, also called topmost or always on top, for +easier debugging with the [GLFW_FLOATING](@ref window_hints_wnd) window hint. + + +@subsection news_31_focused Initially unfocused windows + +GLFW now supports preventing a windowed mode window from gaining input focus on +creation, with the [GLFW_FOCUSED](@ref window_hints_wnd) window hint. + + +@subsection news_31_direct Direct access for window attributes and cursor position + +GLFW now queries the window input focus, visibility and iconification attributes +and the cursor position directly instead of returning cached data. + + +@subsection news_31_libovr Better interoperability with Oculus Rift + +GLFW now provides native access functions for the OS level handles corresponding +to monitor objects, as well as a [brief guide](@ref rift). It is also regularly +tested for compatibility with the latest version of LibOVR (0.4.4 on release). + + +@subsection news_31_charmods Character with modifiers callback + +GLFW now provides a callback for character events with modifier key bits. The +callback is set with @ref glfwSetCharModsCallback. Unlike the regular character +callback, this will report character events that will not result in a character +being input, for example if the Control key is held down. + +@see @ref input_char + + +@subsection news_31_single Single buffered framebuffers + +GLFW now supports the creation of single buffered windows, with the +[GLFW_DOUBLEBUFFER](@ref window_hints_fb) window hint. + + +@subsection news_31_glext Macro for including extension header + +GLFW now includes the extension header appropriate for the chosen OpenGL or +OpenGL ES header when [GLFW_INCLUDE_GLEXT](@ref build_macros) is defined. GLFW +does not provide these headers. They must be provided by your development +environment or your OpenGL or OpenGL ES SDK. + + +@subsection news_31_release Context release behaviors + +GLFW now supports controlling whether the pipeline is flushed when a context is +made non-current, with the +[GLFW_CONTEXT_RELEASE_BEHAVIOR](@ref window_hints_ctx) window hint, provided the +machine supports the `GL_KHR_context_flush_control` extension. + + +@subsection news_31_wayland (Experimental) Wayland support + +GLFW now has an _experimental_ Wayland display protocol backend that can be +selected on Linux with a CMake option. + + +@subsection news_31_mir (Experimental) Mir support + +GLFW now has an _experimental_ Mir display server backend that can be selected +on Linux with a CMake option. + + +@section news_30 New features in 3.0 + +These are the release highlights. For a full list of changes see the +[version history](http://www.glfw.org/changelog.html). + + +@subsection news_30_cmake CMake build system + +GLFW now uses the CMake build system instead of the various makefiles and +project files used by earlier versions. CMake is available for all platforms +supported by GLFW, is present in most package systems and can generate +makefiles and/or project files for most popular development environments. + +For more information on how to use CMake, see the +[CMake manual](http://cmake.org/cmake/help/documentation.html). + + +@subsection news_30_multiwnd Multi-window support + +GLFW now supports the creation of multiple windows, each with their own OpenGL +or OpenGL ES context, and all window functions now take a window handle. Event +callbacks are now per-window and are provided with the handle of the window that +received the event. The @ref glfwMakeContextCurrent function has been added to +select which context is current on a given thread. + + +@subsection news_30_multimon Multi-monitor support + +GLFW now explicitly supports multiple monitors. They can be enumerated with +@ref glfwGetMonitors, queried with @ref glfwGetVideoModes, @ref +glfwGetMonitorPos, @ref glfwGetMonitorName and @ref glfwGetMonitorPhysicalSize, +and specified at window creation to make the newly created window full screen on +that specific monitor. + + +@subsection news_30_unicode Unicode support + +All string arguments to GLFW functions and all strings returned by GLFW now use +the UTF-8 encoding. This includes the window title, error string, clipboard +text, monitor and joystick names as well as the extension function arguments (as +ASCII is a subset of UTF-8). + + +@subsection news_30_clipboard Clipboard text I/O + +GLFW now supports reading and writing plain text to and from the system +clipboard, with the @ref glfwGetClipboardString and @ref glfwSetClipboardString +functions. + + +@subsection news_30_gamma Gamma ramp support + +GLFW now supports setting and reading back the gamma ramp of monitors, with the +@ref glfwGetGammaRamp and @ref glfwSetGammaRamp functions. There is also @ref +glfwSetGamma, which generates a ramp from a gamma value and then sets it. + + +@subsection news_30_gles OpenGL ES support + +GLFW now supports the creation of OpenGL ES contexts, by setting the +`GLFW_CLIENT_API` window hint to `GLFW_OPENGL_ES_API`, where creation of such +contexts are supported. Note that GLFW _does not implement_ OpenGL ES, so your +driver must provide support in a way usable by GLFW. Modern Nvidia and Intel +drivers support creation of OpenGL ES context using the GLX and WGL APIs, while +AMD provides an EGL implementation instead. + + +@subsection news_30_egl (Experimental) EGL support + +GLFW now has an experimental EGL context creation back end that can be selected +through CMake options. + + +@subsection news_30_hidpi High-DPI support + +GLFW now supports high-DPI monitors on both Windows and OS X, giving windows full +resolution framebuffers where other UI elements are scaled up. To achieve this, +@ref glfwGetFramebufferSize and @ref glfwSetFramebufferSizeCallback have been +added. These work with pixels, while the rest of the GLFW API works with screen +coordinates. This is important as OpenGL uses pixels, not screen coordinates. + + +@subsection news_30_error Error callback + +GLFW now has an error callback, which can provide your application with much +more detailed diagnostics than was previously possible. The callback is passed +an error code and a description string. + + +@subsection news_30_wndptr Per-window user pointer + +Each window now has a user-defined pointer, retrieved with @ref +glfwGetWindowUserPointer and set with @ref glfwSetWindowUserPointer, to make it +easier to integrate GLFW into C++ code. + + +@subsection news_30_iconifyfun Window iconification callback + +Each window now has a callback for iconification and restoration events, +which is set with @ref glfwSetWindowIconifyCallback. + + +@subsection news_30_wndposfun Window position callback + +Each window now has a callback for position events, which is set with @ref +glfwSetWindowPosCallback. + + +@subsection news_30_wndpos Window position query + +The position of a window can now be retrieved using @ref glfwGetWindowPos. + + +@subsection news_30_focusfun Window focus callback + +Each windows now has a callback for focus events, which is set with @ref +glfwSetWindowFocusCallback. + + +@subsection news_30_enterleave Cursor enter/leave callback + +Each window now has a callback for when the mouse cursor enters or leaves its +client area, which is set with @ref glfwSetCursorEnterCallback. + + +@subsection news_30_wndtitle Initial window title + +The title of a window is now specified at creation time, as one of the arguments +to @ref glfwCreateWindow. + + +@subsection news_30_hidden Hidden windows + +Windows can now be hidden with @ref glfwHideWindow, shown using @ref +glfwShowWindow and created initially hidden with the `GLFW_VISIBLE` window hint. +This allows for off-screen rendering in a way compatible with most drivers, as +well as moving a window to a specific position before showing it. + + +@subsection news_30_undecorated Undecorated windows + +Windowed mode windows can now be created without decorations, i.e. things like +a frame, a title bar, with the `GLFW_DECORATED` window hint. This allows for +the creation of things like splash screens. + + +@subsection news_30_keymods Modifier key bit masks + +[Modifier key bit mask](@ref mods) parameters have been added to the +[mouse button](@ref GLFWmousebuttonfun) and [key](@ref GLFWkeyfun) callbacks. + + +@subsection news_30_scancode Platform-specific scancodes + +A scancode parameter has been added to the [key callback](@ref GLFWkeyfun). Keys +that don't have a [key token](@ref keys) still get passed on with the key +parameter set to `GLFW_KEY_UNKNOWN`. These scancodes will vary between machines +and are intended to be used for key bindings. + + +@subsection news_30_jsname Joystick names + +The name of a joystick can now be retrieved using @ref glfwGetJoystickName. + + +@subsection news_30_doxygen Doxygen documentation + +You are reading it. + +*/ diff --git a/testbed/glfw/docs/quick.dox b/testbed/glfw/docs/quick.dox new file mode 100644 index 00000000..12283a15 --- /dev/null +++ b/testbed/glfw/docs/quick.dox @@ -0,0 +1,328 @@ +/*! + +@page quick Getting started + +@tableofcontents + +This guide takes you through writing a simple application using GLFW 3. The +application will create a window and OpenGL context, render a rotating triangle +and exit when the user closes the window or presses Escape. This guide will +introduce a few of the most commonly used functions, but there are many more. + +This guide assumes no experience with earlier versions of GLFW. If you +have used GLFW 2 in the past, read the @ref moving guide, as some functions +behave differently in GLFW 3. + + +@section quick_steps Step by step + +@subsection quick_include Including the GLFW header + +In the source files of your application where you use OpenGL or GLFW, you need +to include the GLFW 3 header file. + +@code +#include +@endcode + +This defines all the constants, types and function prototypes of the GLFW API. +It also includes the OpenGL header, and defines all the constants and types +necessary for it to work on your platform. + +For example, under Windows you are normally required to include `windows.h` +before including `GL/gl.h`. This would make your source file tied to Windows +and pollute your code's namespace with the whole Win32 API. + +Instead, the GLFW header takes care of this for you, not by including +`windows.h`, but rather by itself duplicating only the necessary parts of it. +It does this only where needed, so if `windows.h` _is_ included, the GLFW header +does not try to redefine those symbols. + +In other words: + +- Do _not_ include the OpenGL headers yourself, as GLFW does this for you +- Do _not_ include `windows.h` or other platform-specific headers unless + you plan on using those APIs directly +- If you _do_ need to include such headers, do it _before_ including the + GLFW one and it will detect this + +Starting with version 3.0, the GLU header `glu.h` is no longer included by +default. If you wish to include it, define `GLFW_INCLUDE_GLU` before the +inclusion of the GLFW header. + +@code +#define GLFW_INCLUDE_GLU +#include +@endcode + + +@subsection quick_init_term Initializing and terminating GLFW + +Before you can use most GLFW functions, the library must be initialized. On +successful initialization, `GL_TRUE` is returned. If an error occurred, +`GL_FALSE` is returned. + +@code +if (!glfwInit()) + exit(EXIT_FAILURE); +@endcode + +When you are done using GLFW, typically just before the application exits, you +need to terminate GLFW. + +@code +glfwTerminate(); +@endcode + +This destroys any remaining windows and releases any other resources allocated by +GLFW. After this call, you must initialize GLFW again before using any GLFW +functions that require it. + + +@subsection quick_capture_error Setting an error callback + +Most events are reported through callbacks, whether it's a key being pressed, +a GLFW window being moved, or an error occurring. Callbacks are simply +C functions (or C++ static methods) that are called by GLFW with arguments +describing the event. + +In case a GLFW function fails, an error is reported to the GLFW error callback. +You can receive these reports with an error callback. This function must have +the signature below. This simple error callback just prints the error +description to `stderr`. + +@code +void error_callback(int error, const char* description) +{ + fputs(description, stderr); +} +@endcode + +Callback functions must be set, so GLFW knows to call them. The function to set +the error callback is one of the few GLFW functions that may be called before +initialization, which lets you be notified of errors both during and after +initialization. + +@code +glfwSetErrorCallback(error_callback); +@endcode + + +@subsection quick_create_window Creating a window and context + +The window and its OpenGL context are created with a single call, which returns +a handle to the created combined window and context object. For example, this +creates a 640 by 480 windowed mode window with an OpenGL context: + +@code +GLFWwindow* window = glfwCreateWindow(640, 480, "My Title", NULL, NULL); +@endcode + +If window or context creation fails, `NULL` will be returned, so it is necessary +to check the return value. + +@code +if (!window) +{ + glfwTerminate(); + exit(EXIT_FAILURE); +} +@endcode + +The window handle is passed to all window related functions and is provided to +along to all window related callbacks, so they can tell which window received +the event. + +When a window is no longer needed, destroy it. + +@code +glfwDestroyWindow(window); +@endcode + +Once this function is called, no more events will be delivered for that window +and its handle becomes invalid. + + +@subsection quick_context_current Making the OpenGL context current + +Before you can use the OpenGL API, you must have a current OpenGL context. + +@code +glfwMakeContextCurrent(window); +@endcode + +The context will remain current until you make another context current or until +the window owning the current context is destroyed. + + +@subsection quick_window_close Checking the window close flag + +Each window has a flag indicating whether the window should be closed. + +When the user attempts to close the window, either by pressing the close widget +in the title bar or using a key combination like Alt+F4, this flag is set to 1. +Note that __the window isn't actually closed__, so you are expected to monitor +this flag and either destroy the window or give some kind of feedback to the +user. + +@code +while (!glfwWindowShouldClose(window)) +{ + // Keep running +} +@endcode + +You can be notified when the user is attempting to close the window by setting +a close callback with @ref glfwSetWindowCloseCallback. The callback will be +called immediately after the close flag has been set. + +You can also set it yourself with @ref glfwSetWindowShouldClose. This can be +useful if you want to interpret other kinds of input as closing the window, like +for example pressing the escape key. + + +@subsection quick_key_input Receiving input events + +Each window has a large number of callbacks that can be set to receive all the +various kinds of events. To receive key press and release events, create a key +callback function. + +@code +static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) + glfwSetWindowShouldClose(window, GL_TRUE); +} +@endcode + +The key callback, like other window related callbacks, are set per-window. + +@code +glfwSetKeyCallback(window, key_callback); +@endcode + +In order for event callbacks to be called when events occur, you need to process +events as described below. + + +@subsection quick_render Rendering with OpenGL + +Once you have a current OpenGL context, you can use OpenGL normally. In this +tutorial, a multi-colored rotating triangle will be rendered. The framebuffer +size needs to be retrieved for `glViewport`. + +@code +int width, height; +glfwGetFramebufferSize(window, &width, &height); +glViewport(0, 0, width, height); +@endcode + +You can also set a framebuffer size callback using @ref +glfwSetFramebufferSizeCallback and call `glViewport` from there. + + +@subsection quick_timer Reading the timer + +To create smooth animation, a time source is needed. GLFW provides a timer that +returns the number of seconds since initialization. The time source used is the +most accurate on each platform and generally has micro- or nanosecond +resolution. + +@code +double time = glfwGetTime(); +@endcode + + +@subsection quick_swap_buffers Swapping buffers + +GLFW windows by default use double buffering. That means that each window has +two rendering buffers; a front buffer and a back buffer. The front buffer is +the one being displayed and the back buffer the one you render to. + +When the entire frame has been rendered, the buffers need to be swapped with one +another, so the back buffer becomes the front buffer and vice versa. + +@code +glfwSwapBuffers(window); +@endcode + +The swap interval indicates how many frames to wait until swapping the buffers, +commonly known as _vsync_. By default, the swap interval is zero, meaning +buffer swapping will occur immediately. On fast machines, many of those frames +will never be seen, as the screen is still only updated typically 60-75 times +per second, so this wastes a lot of CPU and GPU cycles. + +Also, because the buffers will be swapped in the middle the screen update, +leading to [screen tearing](https://en.wikipedia.org/wiki/Screen_tearing). + +For these reasons, applications will typically want to set the swap interval to +one. It can be set to higher values, but this is usually not recommended, +because of the input latency it leads to. + +@code +glfwSwapInterval(1); +@endcode + +This function acts on the current context and will fail unless a context is +current. + + +@subsection quick_process_events Processing events + +GLFW needs to communicate regularly with the window system both in order to +receive events and to show that the application hasn't locked up. Event +processing must be done regularly while you have visible windows and is normally +done each frame after buffer swapping. + +There are two methods for processing pending events; polling and waiting. This +example will use event polling, which processes only those events that have +already been received and then returns immediately. + +@code +glfwPollEvents(); +@endcode + +This is the best choice when rendering continually, like most games do. If +instead you only need to update your rendering once you have received new input, +@ref glfwWaitEvents is a better choice. It waits until at least one event has +been received, putting the thread to sleep in the meantime, and then processes +all received events. This saves a great deal of CPU cycles and is useful for, +for example, many kinds of editing tools. + + +@section quick_example Putting it together + +Now that you know how to initialize GLFW, create a window and poll for +keyboard input, it's possible to create a simple program. + +@snippet simple.c code + +This program creates a 640 by 480 windowed mode window and starts a loop that +clears the screen, renders a triangle and processes events until the user either +presses Escape or closes the window. + +This program uses only a few of the many functions GLFW provides. There are +guides for each of the areas covered by GLFW. Each guide will introduce all the +functions for that category. + + - @ref intro + - @ref window + - @ref context + - @ref monitor + - @ref input + + +@section quick_build Compiling and linking the program + +The complete program above can be found in the source distribution as +`examples/simple.c` and is compiled along with all other examples when you +build GLFW. That is, if you have compiled GLFW then you have already built this +as `simple.exe` on Windows, `simple` on Linux or `simple.app` on OS X. + +This tutorial ends here. Once you have written a program that uses GLFW, you +will need to compile and link it. How to do that depends on the development +environment you are using and is best explained by the documentation for that +environment. To learn about the details that are specific to GLFW, see +@ref build. + +*/ diff --git a/testbed/glfw/docs/rift.dox b/testbed/glfw/docs/rift.dox new file mode 100644 index 00000000..edf206f7 --- /dev/null +++ b/testbed/glfw/docs/rift.dox @@ -0,0 +1,199 @@ +/*! + +@page rift Oculus Rift guide + +@tableofcontents + +This guide is intended to fill in the gaps between the +[Oculus PC SDK documentation](https://developer.oculus.com/documentation/) and +the rest of the GLFW documentation and is not a replacement for either. It +requires you to use [native access](@ref native) and assumes a certain level of +proficiency with LibOVR, platform specific APIs and your chosen development +environment. + +While GLFW has no explicit support for LibOVR, it is tested with and tries to +interoperate well with it. + +@note Because of the speed of development of the Oculus SDK, this guide may +become outdated before the next release. If this is a local copy of the +documentation, you may want to check the GLFW website for updates. This +revision of the guide is written against version 0.4.4 of the SDK. + + +@section rift_include Including the LibOVR and GLFW header files + +Both the OpenGL LibOVR header and the GLFW native header need macros telling +them what OS you are building for. Because LibOVR only supports three major +desktop platforms, this can be solved with canonical predefined macros. + +@code +#if defined(_WIN32) + #define GLFW_EXPOSE_NATIVE_WIN32 + #define GLFW_EXPOSE_NATIVE_WGL + #define OVR_OS_WIN32 +#elif defined(__APPLE__) + #define GLFW_EXPOSE_NATIVE_COCOA + #define GLFW_EXPOSE_NATIVE_NSGL + #define OVR_OS_MAC +#elif defined(__linux__) + #define GLFW_EXPOSE_NATIVE_X11 + #define GLFW_EXPOSE_NATIVE_GLX + #define OVR_OS_LINUX +#endif + +#include +#include + +#include +@endcode + +Both the GLFW and LibOVR headers by default attempt to include the standard +OpenGL `GL/gl.h` header (`OpenGL/gl.h` on OS X). If you wish to use a different +standard header or an [extension loading library](@ref context_glext_auto), +include that header before these. + + +@section rift_init Initializing LibOVR and GLFW + +LibOVR needs to be initialized before GLFW. This means calling at least +`ovr_Initialize`, `ovrHmd_Create` and `ovrHmd_ConfigureTracking` before @ref +glfwInit. Similarly, LibOVR must be shut down after GLFW. This means calling +`ovrHmd_Destroy` and `ovr_Shutdown` after @ref glfwTerminate. + + +@section rift_direct Direct HMD mode + +Direct HMD mode is the recommended display mode for new applications, but the +Oculus Rift runtime currently (January 2015) only supports this mode on Windows. +In direct mode the HMD is not detectable as a GLFW monitor. + + +@subsection rift_direct_create Creating a window and context + +If the HMD is in direct mode you can use either a full screen or a windowed mode +window, but full screen is only recommended if there is a monitor that supports +the resolution of the HMD. Due to limitations in LibOVR, the size of the client +area of the window must equal the resolution of the HMD. + +If the resolution of the HMD is much larger than the regular monitor, the window +may be resized by the window manager on creation. One way to avoid this is to +make it undecorated with the [GLFW_DECORATED](@ref window_hints_wnd) window +hint. + + +@subsection rift_direct_attach Attaching the window to the HMD + +Once you have created the window and context, you need to attach the native +handle of the GLFW window to the HMD. + +@code +ovrHmd_AttachToWindow(hmd, glfwGetWin32Window(window), NULL, NULL); +@endcode + + +@section rift_extend Extend Desktop mode + +Extend desktop mode is a legacy display mode, but is still (January 2015) the +only available mode on OS X and Linux, as well as on Windows machines that for +technical reasons do not yet support direct HMD mode. + + +@subsection rift_extend_detect Detecting a HMD with GLFW + +If the HMD is in extend desktop mode you can deduce which GLFW monitor it +corresponds to and create a full screen window on that monitor. + +On Windows, the native display device name of a GLFW monitor corresponds to the +display device name of the detected HMD as stored, in the `DisplayDeviceName` +member of `ovrHmdDesc`. + +On OS X, the native display ID of a GLFW monitor corresponds to the display ID +of the detected HMD, as stored in the `DisplayId` member of `ovrHmdDesc`. + +At the time of writing (January 2015), the Oculus SDK does not support detecting +which monitor corresponds to the HMD in any sane fashion, but as long as the HMD +is set up and rotated properly it can be found via the screen position and +resolution provided by LibOVR. This method may instead find another monitor +that is mirroring the HMD, but this only matters if you intend to change its +video mode. + +@code +int i, count; +GLFWmonitor** monitors = glfwGetMonitors(&count); + +for (i = 0; i < count; i++) +{ +#if defined(_WIN32) + if (strcmp(glfwGetWin32Monitor(monitors[i]), hmd->DisplayDeviceName) == 0) + return monitors[i]; +#elif defined(__APPLE__) + if (glfwGetCocoaMonitor(monitors[i]) == hmd->DisplayId) + return monitors[i]; +#elif defined(__linux__) + int xpos, ypos; + const GLFWvidmode* mode = glfwGetVideoMode(monitors[i]); + glfwGetMonitorPos(monitors[i], &xpos, &ypos); + + if (hmd->WindowsPos.x == xpos && + hmd->WindowsPos.y == ypos && + hmd->Resolution.w == mode->width && + hmd->Resolution.h == mode->height) + { + return monitors[i]; + } +#endif +} +@endcode + + +@subsection rift_extend_create Creating a window and context + +The window is created as a regular full screen window on the found monitor. It +is usually a good idea to create a +[windowed full screen](@ref window_windowed_full_screen) window, as the HMD will +very likely already be set to the correct video mode. However, in extend +desktop mode it behaves like a regular monitor and any supported video mode can +be requested. + +If other monitors are mirroring the HMD and you request a different video mode, +all monitors in the mirroring set will get the new video mode. + + +@section rift_render Rendering to the HMD + +@subsection rift_render_sdk SDK distortion rendering + +If you wish to use SDK distortion rendering you will need some information from +GLFW to configure the renderer. Below are the parts of the `ovrGLConfig` union +that need to be filled with from GLFW. Note that there are other fields that +also need to be filled for `ovrHmd_ConfigureRendering` to succeed. + +Before configuring SDK distortion rendering you should make your context +current. + +@code + int width, height; + union ovrGLConfig config; + + glfwGetFramebufferSize(window, &width, &height); + + config.OGL.Header.BackBufferSize.w = width; + config.OGL.Header.BackBufferSize.h = height; +#if defined(_WIN32) + config.OGL.Window = glfwGetWin32Window(window); +#elif defined(__APPLE__) +#elif defined(__linux__) + config.OGL.Disp = glfwGetX11Display(); +#endif +@endcode + +When using SDK distortion rendering you should not swap the buffers yourself, as +the HMD is updated by `ovrHmd_EndFrame`. + + +@subsection rift_render_custom Client distortion rendering + +With client distortion rendering you are in full control of the contents of the +HMD and should render and swap the buffers normally. + +*/ diff --git a/testbed/glfw/docs/spaces.svg b/testbed/glfw/docs/spaces.svg new file mode 100644 index 00000000..562fa8be --- /dev/null +++ b/testbed/glfw/docs/spaces.svg @@ -0,0 +1,872 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testbed/glfw/docs/window.dox b/testbed/glfw/docs/window.dox new file mode 100644 index 00000000..9aae404e --- /dev/null +++ b/testbed/glfw/docs/window.dox @@ -0,0 +1,803 @@ +/*! + +@page window Window guide + +@tableofcontents + +This guide introduces the window related functions of GLFW. There are also +guides for the other areas of GLFW. + + - @ref intro + - @ref context + - @ref monitor + - @ref input + + +@section window_object Window objects + +The @ref GLFWwindow object encapsulates both a window and a context. They are +created with @ref glfwCreateWindow and destroyed with @ref glfwDestroyWindow, or +@ref glfwTerminate, if any remain. As the window and context are inseparably +linked, the object pointer is used as both a context and window handle. + +To see the event stream provided to the various window related callbacks, run +the `events` test program. + + +@subsection window_creation Window creation + +A window and its OpenGL or OpenGL ES context are created with @ref +glfwCreateWindow, which returns a handle to the created window object. For +example, this creates a 640 by 480 windowed mode window: + +@code +GLFWwindow* window = glfwCreateWindow(640, 480, "My Title", NULL, NULL); +@endcode + +If window creation fails, `NULL` will be returned, so it is necessary to check +the return value. + +The window handle is passed to all window related functions and is provided to +along with all input events, so event handlers can tell which window received +the event. + + +@subsubsection window_full_screen Full screen windows + +To create a full screen window, you need to specify which monitor the window +should use. In most cases, the user's primary monitor is a good choice. +For more information about retrieving monitors, see @ref monitor_monitors. + +@code +GLFWwindow* window = glfwCreateWindow(640, 480, "My Title", glfwGetPrimaryMonitor(), NULL); +@endcode + +Full screen windows cover the entire display area of a monitor, have no border +or decorations. + +Each field of the @ref GLFWvidmode structure corresponds to a function parameter +or window hint and combine to form the _desired video mode_ for that window. +The supported video mode most closely matching the desired video mode will be +set for the chosen monitor as long as the window has input focus. For more +information about retrieving video modes, see @ref monitor_modes. + +Video mode field | Corresponds to +----------------------- | ------------------------ +GLFWvidmode.width | `width` parameter +GLFWvidmode.height | `height` parameter +GLFWvidmode.redBits | `GLFW_RED_BITS` hint +GLFWvidmode.greenBits | `GLFW_GREEN_BITS` hint +GLFWvidmode.blueBits | `GLFW_BLUE_BITS` hint +GLFWvidmode.refreshRate | `GLFW_REFRESH_RATE` hint + +Once you have a full screen window, you can change its resolution with @ref +glfwSetWindowSize. The new video mode will be selected and set the same way as +the video mode chosen by @ref glfwCreateWindow. + +By default, the original video mode of the monitor will be restored and the +window iconified if it loses input focus, to allow the user to switch back to +the desktop. This behavior can be disabled with the `GLFW_AUTO_ICONIFY` window +hint, for example if you wish to simultaneously cover multiple windows with full +screen windows. + + +@subsubsection window_windowed_full_screen "Windowed full screen" windows + +To create a so called _windowed full screen_ or _borderless full screen_ window, +i.e. a full screen window that doesn't change the video mode of the monitor, you +need to request the current video mode of the chosen monitor. + +@code +const GLFWvidmode* mode = glfwGetVideoMode(monitor); + +glfwWindowHint(GLFW_RED_BITS, mode->redBits); +glfwWindowHint(GLFW_GREEN_BITS, mode->greenBits); +glfwWindowHint(GLFW_BLUE_BITS, mode->blueBits); +glfwWindowHint(GLFW_REFRESH_RATE, mode->refreshRate); + +GLFWwindow* window = glfwCreateWindow(mode->width, mode->height, "My Title", monitor, NULL); +@endcode + +GLFW will detect this and will not perform any mode setting for that window. + + +@subsection window_destruction Window destruction + +When a window is no longer needed, destroy it with @ref glfwDestroyWindow. + +@code +glfwDestroyWindow(window); +@endcode + +Window destruction always succeeds. Before the actual destruction, all +callbacks are removed so no further events will be delivered for the window. +All windows remaining when @ref glfwTerminate is called are destroyed as well. + +When a full screen window is destroyed, the original video mode of its monitor +is restored, but the gamma ramp is left untouched. + + +@subsection window_hints Window creation hints + +There are a number of hints that can be set before the creation of a window and +context. Some affect the window itself, others affect the framebuffer or +context. These hints are set to their default values each time the library is +initialized with @ref glfwInit, can be set individually with @ref glfwWindowHint +and reset all at once to their defaults with @ref glfwDefaultWindowHints. + +Note that hints need to be set _before_ the creation of the window and context +you wish to have the specified attributes. + + +@subsubsection window_hints_hard Hard and soft constraints + +Some window hints are hard constraints. These must match the available +capabilities _exactly_ for window and context creation to succeed. Hints +that are not hard constraints are matched as closely as possible, but the +resulting window and context may differ from what these hints requested. To +find out the actual attributes of the created window and context, use the +@ref glfwGetWindowAttrib function. + +The following hints are always hard constraints: +- `GLFW_STEREO` +- `GLFW_DOUBLEBUFFER` +- `GLFW_CLIENT_API` + +The following additional hints are hard constraints when requesting an OpenGL +context, but are ignored when requesting an OpenGL ES context: +- `GLFW_OPENGL_FORWARD_COMPAT` +- `GLFW_OPENGL_PROFILE` + + +@subsubsection window_hints_wnd Window related hints + +`GLFW_RESIZABLE` specifies whether the (windowed mode) window will be resizable +_by the user_. The window will still be resizable using the @ref +glfwSetWindowSize function. This hint is ignored for full screen windows. + +`GLFW_VISIBLE` specifies whether the (windowed mode) window will be initially +visible. This hint is ignored for full screen windows. + +`GLFW_DECORATED` specifies whether the (windowed mode) window will have window +decorations such as a border, a close widget, etc. This hint is ignored for +full screen windows. Note that even though a window may lack a close widget, it +is usually still possible for the user to generate close events. + +`GLFW_FOCUSED` specifies whether the (windowed mode) window will be given input +focus when created. This hint is ignored for full screen and initially hidden +windows. + +`GLFW_AUTO_ICONIFY` specifies whether the (full screen) window will +automatically iconify and restore the previous video mode on input focus loss. +This hint is ignored for windowed mode windows. + +`GLFW_FLOATING` specifies whether the window will be floating above other +regular windows, also called topmost or always-on-top. This is intended +primarily for debugging purposes and cannot be used to implement proper full +screen windows. This hint is ignored for full screen windows. + + +@subsubsection window_hints_fb Framebuffer related hints + +`GLFW_RED_BITS`, `GLFW_GREEN_BITS`, `GLFW_BLUE_BITS`, `GLFW_ALPHA_BITS`, +`GLFW_DEPTH_BITS` and `GLFW_STENCIL_BITS` specify the desired bit depths of the +various components of the default framebuffer. `GLFW_DONT_CARE` means the +application has no preference. + +`GLFW_ACCUM_RED_BITS`, `GLFW_ACCUM_GREEN_BITS`, `GLFW_ACCUM_BLUE_BITS` and +`GLFW_ACCUM_ALPHA_BITS` specify the desired bit depths of the various components +of the accumulation buffer. `GLFW_DONT_CARE` means the application has no +preference. + +@par +Accumulation buffers are a legacy OpenGL feature and should not be used in new +code. + +`GLFW_AUX_BUFFERS` specifies the desired number of auxiliary buffers. +`GLFW_DONT_CARE` means the application has no preference. + +@par +Auxiliary buffers are a legacy OpenGL feature and should not be used in new +code. + +`GLFW_STEREO` specifies whether to use stereoscopic rendering. This is a hard +constraint. + +`GLFW_SAMPLES` specifies the desired number of samples to use for multisampling. +Zero disables multisampling. `GLFW_DONT_CARE` means the application has no +preference. + +`GLFW_SRGB_CAPABLE` specifies whether the framebuffer should be sRGB capable. + +`GLFW_DOUBLEBUFFER` specifies whether the framebuffer should be double buffered. +You nearly always want to use double buffering. This is a hard constraint. + + +@subsubsection window_hints_mtr Monitor related hints + +`GLFW_REFRESH_RATE` specifies the desired refresh rate for full screen windows. +If set to `GLFW_DONT_CARE`, the highest available refresh rate will be used. +This hint is ignored for windowed mode windows. + + +@subsubsection window_hints_ctx Context related hints + +`GLFW_CLIENT_API` specifies which client API to create the context for. +Possible values are `GLFW_OPENGL_API` and `GLFW_OPENGL_ES_API`. This is a hard +constraint. + +`GLFW_CONTEXT_VERSION_MAJOR` and `GLFW_CONTEXT_VERSION_MINOR` specify the client +API version that the created context must be compatible with. The exact +behavior of these hints depend on the requested client API. + +@par +__OpenGL:__ `GLFW_CONTEXT_VERSION_MAJOR` and `GLFW_CONTEXT_VERSION_MINOR` are not hard +constraints, but creation will fail if the OpenGL version of the created context +is less than the one requested. It is therefore perfectly safe to use the +default of version 1.0 for legacy code and you may still get +backwards-compatible contexts of version 3.0 and above when available. + +@par +While there is no way to ask the driver for a context of the highest supported +version, GLFW will attempt to provide this when you ask for a version 1.0 +context, which is the default for these hints. + +@par +__OpenGL ES:__ `GLFW_CONTEXT_VERSION_MAJOR` and `GLFW_CONTEXT_VERSION_MINOR` are not hard +constraints, but creation will fail if the OpenGL ES version of the created +context is less than the one requested. Additionally, OpenGL ES 1.x cannot be +returned if 2.0 or later was requested, and vice versa. This is because OpenGL +ES 3.x is backward compatible with 2.0, but OpenGL ES 2.0 is not backward +compatible with 1.x. + +`GLFW_OPENGL_FORWARD_COMPAT` specifies whether the OpenGL context should be +forward-compatible, i.e. one where all functionality deprecated in the requested +version of OpenGL is removed. This may only be used if the requested OpenGL +version is 3.0 or above. If OpenGL ES is requested, this hint is ignored. + +@par +Forward-compatibility is described in detail in the +[OpenGL Reference Manual](https://www.opengl.org/registry/). + +`GLFW_OPENGL_DEBUG_CONTEXT` specifies whether to create a debug OpenGL context, +which may have additional error and performance issue reporting functionality. +If OpenGL ES is requested, this hint is ignored. + +`GLFW_OPENGL_PROFILE` specifies which OpenGL profile to create the context for. +Possible values are one of `GLFW_OPENGL_CORE_PROFILE` or +`GLFW_OPENGL_COMPAT_PROFILE`, or `GLFW_OPENGL_ANY_PROFILE` to not request +a specific profile. If requesting an OpenGL version below 3.2, +`GLFW_OPENGL_ANY_PROFILE` must be used. If another OpenGL ES is requested, +this hint is ignored. + +@par +OpenGL profiles are described in detail in the +[OpenGL Reference Manual](https://www.opengl.org/registry/). + +`GLFW_CONTEXT_ROBUSTNESS` specifies the robustness strategy to be used by the +context. This can be one of `GLFW_NO_RESET_NOTIFICATION` or +`GLFW_LOSE_CONTEXT_ON_RESET`, or `GLFW_NO_ROBUSTNESS` to not request +a robustness strategy. + +`GLFW_CONTEXT_RELEASE_BEHAVIOR` specifies the release behavior to be +used by the context. Possible values are one of `GLFW_ANY_RELEASE_BEHAVIOR`, +`GLFW_RELEASE_BEHAVIOR_FLUSH` or `GLFW_RELEASE_BEHAVIOR_NONE`. If the +behavior is `GLFW_ANY_RELEASE_BEHAVIOR`, the default behavior of the context +creation API will be used. If the behavior is `GLFW_RELEASE_BEHAVIOR_FLUSH`, +the pipeline will be flushed whenever the context is released from being the +current one. If the behavior is `GLFW_RELEASE_BEHAVIOR_NONE`, the pipeline will +not be flushed on release. + +@par +Context release behaviors are described in detail by the +[GL_KHR_context_flush_control](https://www.opengl.org/registry/specs/KHR/context_flush_control.txt) +extension. + + +@subsubsection window_hints_values Supported and default values + +Window hint | Default value | Supported values +------------------------------- | --------------------------- | ---------------- +`GLFW_RESIZABLE` | `GL_TRUE` | `GL_TRUE` or `GL_FALSE` +`GLFW_VISIBLE` | `GL_TRUE` | `GL_TRUE` or `GL_FALSE` +`GLFW_DECORATED` | `GL_TRUE` | `GL_TRUE` or `GL_FALSE` +`GLFW_FOCUSED` | `GL_TRUE` | `GL_TRUE` or `GL_FALSE` +`GLFW_AUTO_ICONIFY` | `GL_TRUE` | `GL_TRUE` or `GL_FALSE` +`GLFW_FLOATING` | `GL_FALSE` | `GL_TRUE` or `GL_FALSE` +`GLFW_RED_BITS` | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE` +`GLFW_GREEN_BITS` | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE` +`GLFW_BLUE_BITS` | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE` +`GLFW_ALPHA_BITS` | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE` +`GLFW_DEPTH_BITS` | 24 | 0 to `INT_MAX` or `GLFW_DONT_CARE` +`GLFW_STENCIL_BITS` | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE` +`GLFW_ACCUM_RED_BITS` | 0 | 0 to `INT_MAX` or `GLFW_DONT_CARE` +`GLFW_ACCUM_GREEN_BITS` | 0 | 0 to `INT_MAX` or `GLFW_DONT_CARE` +`GLFW_ACCUM_BLUE_BITS` | 0 | 0 to `INT_MAX` or `GLFW_DONT_CARE` +`GLFW_ACCUM_ALPHA_BITS` | 0 | 0 to `INT_MAX` or `GLFW_DONT_CARE` +`GLFW_AUX_BUFFERS` | 0 | 0 to `INT_MAX` or `GLFW_DONT_CARE` +`GLFW_SAMPLES` | 0 | 0 to `INT_MAX` or `GLFW_DONT_CARE` +`GLFW_REFRESH_RATE` | `GLFW_DONT_CARE` | 0 to `INT_MAX` or `GLFW_DONT_CARE` +`GLFW_STEREO` | `GL_FALSE` | `GL_TRUE` or `GL_FALSE` +`GLFW_SRGB_CAPABLE` | `GL_FALSE` | `GL_TRUE` or `GL_FALSE` +`GLFW_DOUBLEBUFFER` | `GL_TRUE` | `GL_TRUE` or `GL_FALSE` +`GLFW_CLIENT_API` | `GLFW_OPENGL_API` | `GLFW_OPENGL_API` or `GLFW_OPENGL_ES_API` +`GLFW_CONTEXT_VERSION_MAJOR` | 1 | Any valid major version number of the chosen client API +`GLFW_CONTEXT_VERSION_MINOR` | 0 | Any valid minor version number of the chosen client API +`GLFW_CONTEXT_ROBUSTNESS` | `GLFW_NO_ROBUSTNESS` | `GLFW_NO_ROBUSTNESS`, `GLFW_NO_RESET_NOTIFICATION` or `GLFW_LOSE_CONTEXT_ON_RESET` +`GLFW_CONTEXT_RELEASE_BEHAVIOR` | `GLFW_ANY_RELEASE_BEHAVIOR` | `GLFW_ANY_RELEASE_BEHAVIOR`, `GLFW_RELEASE_BEHAVIOR_FLUSH` or `GLFW_RELEASE_BEHAVIOR_NONE` +`GLFW_OPENGL_FORWARD_COMPAT` | `GL_FALSE` | `GL_TRUE` or `GL_FALSE` +`GLFW_OPENGL_DEBUG_CONTEXT` | `GL_FALSE` | `GL_TRUE` or `GL_FALSE` +`GLFW_OPENGL_PROFILE` | `GLFW_OPENGL_ANY_PROFILE` | `GLFW_OPENGL_ANY_PROFILE`, `GLFW_OPENGL_COMPAT_PROFILE` or `GLFW_OPENGL_CORE_PROFILE` + + +@section window_events Window event processing + +See @ref events. + + +@section window_properties Window properties and events + +@subsection window_userptr User pointer + +Each window has a user pointer that can be set with @ref +glfwSetWindowUserPointer and fetched with @ref glfwGetWindowUserPointer. This +can be used for any purpose you need and will not be modified by GLFW throughout +the life-time of the window. + +The initial value of the pointer is `NULL`. + + +@subsection window_close Window closing and close flag + +When the user attempts to close the window, for example by clicking the close +widget or using a key chord like Alt+F4, the _close flag_ of the window is set. +The window is however not actually destroyed and, unless you watch for this +state change, nothing further happens. + +The current state of the close flag is returned by @ref glfwWindowShouldClose +and can be set or cleared directly with @ref glfwSetWindowShouldClose. A common +pattern is to use the close flag as a main loop condition. + +@code +while (!glfwWindowShouldClose(window)) +{ + render(window); + + glfwSwapBuffers(window); + glfwPollEvents(); +} +@endcode + +If you wish to be notified when the user attempts to close a window, set a close +callback. + +@code +glfwSetWindowCloseCallback(window, window_close_callback); +@endcode + +The callback function is called directly _after_ the close flag has been set. +It can be used for example to filter close requests and clear the close flag +again unless certain conditions are met. + +@code +void window_close_callback(GLFWwindow* window) +{ + if (!time_to_close) + glfwSetWindowShouldClose(window, GL_FALSE); +} +@endcode + + +@subsection window_size Window size + +The size of a window can be changed with @ref glfwSetWindowSize. For windowed +mode windows, this sets the size, in +[screen coordinates](@ref coordinate_systems) of the _client area_ or _content +area_ of the window. The window system may impose limits on window size. + +@code +glfwSetWindowSize(window, 640, 480); +@endcode + +For full screen windows, the specified size becomes the new resolution of the +window's *desired video mode*. The video mode most closely matching the new +desired video mode is set immediately. The window is resized to fit the +resolution of the set video mode. + +If you wish to be notified when a window is resized, whether by the user or +the system, set a size callback. + +@code +glfwSetWindowSizeCallback(window, window_size_callback); +@endcode + +The callback function receives the new size, in screen coordinates, of the +client area of the window when it is resized. + +@code +void window_size_callback(GLFWwindow* window, int width, int height) +{ +} +@endcode + +There is also @ref glfwGetWindowSize for directly retrieving the current size of +a window. + +@code +int width, height; +glfwGetWindowSize(window, &width, &height); +@endcode + +@note Do not pass the window size to `glViewport` or other pixel-based OpenGL +calls. The window size is in screen coordinates, not pixels. Use the +[framebuffer size](@ref window_fbsize), which is in pixels, for pixel-based +calls. + +The above functions work with the size of the client area, but decorated windows +typically have title bars and window frames around this rectangle. You can +retrieve the extents of these with @ref glfwGetWindowFrameSize. + +@code +int left, top, right, bottom; +glfwGetWindowFrameSize(window, &left, &top, &right, &bottom); +@endcode + +The returned values are the distances, in screen coordinates, from the edges of +the client area to the corresponding edges of the full window. As they are +distances and not coordinates, they are always zero or positive. + + +@subsection window_fbsize Framebuffer size + +While the size of a window is measured in screen coordinates, OpenGL works with +pixels. The size you pass into `glViewport`, for example, should be in pixels. +On some machines screen coordinates and pixels are the same, but on others they +will not be. There is a second set of functions to retrieve the size, in +pixels, of the framebuffer of a window. + +If you wish to be notified when the framebuffer of a window is resized, whether +by the user or the system, set a size callback. + +@code +glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); +@endcode + +The callback function receives the new size of the framebuffer when it is +resized, which can for example be used to update the OpenGL viewport. + +@code +void framebuffer_size_callback(GLFWwindow* window, int width, int height) +{ + glViewport(0, 0, width, height); +} +@endcode + +There is also @ref glfwGetFramebufferSize for directly retrieving the current +size of the framebuffer of a window. + +@code +int width, height; +glfwGetFramebufferSize(window, &width, &height); +glViewport(0, 0, width, height); +@endcode + +The size of a framebuffer may change independently of the size of a window, for +example if the window is dragged between a regular monitor and a high-DPI one. + + +@subsection window_pos Window position + +The position of a windowed-mode window can be changed with @ref +glfwSetWindowPos. This moves the window so that the upper-left corner of its +client area has the specified [screen coordinates](@ref coordinate_systems). +The window system may put limitations on window placement. + +@code +glfwSetWindowPos(window, 100, 100); +@endcode + +If you wish to be notified when a window is moved, whether by the user, system +or your own code, set a position callback. + +@code +glfwSetWindowPosCallback(window, window_pos_callback); +@endcode + +The callback function receives the new position of the upper-left corner of the +client area when the window is moved. + +@code +void window_pos_callback(GLFWwindow* window, int xpos, int ypos) +{ +} +@endcode + +There is also @ref glfwGetWindowPos for directly retrieving the current position +of the client area of the window. + +@code +int xpos, ypos; +glfwGetWindowPos(window, &xpos, &ypos); +@endcode + + +@subsection window_title Window title + +All GLFW windows have a title, although undecorated or full screen windows may +not display it or only display it in a task bar or similar interface. You can +set a UTF-8 encoded window title with @ref glfwSetWindowTitle. + +@code +glfwSetWindowTitle(window, "My Window"); +@endcode + +The specified string is copied before the function returns, so there is no need +to keep it around. + +As long as your source file is encoded as UTF-8, you can use any Unicode +characters directly in the source. + +@code +glfwSetWindowTitle(window, "ヒカルの碁"); +@endcode + + +@subsection window_monitor Window monitor + +Full screen windows are associated with a specific monitor. You can get the +handle for this monitor with @ref glfwGetWindowMonitor. + +@code +GLFWmonitor* monitor = glfwGetWindowMonitor(window); +@endcode + +This monitor handle is one of those returned by @ref glfwGetMonitors. + +For windowed mode windows, this function returns `NULL`. This is the +recommended way to tell full screen windows from windowed mode windows. + + +@subsection window_iconify Window iconification + +Windows can be iconified (i.e. minimized) with @ref glfwIconifyWindow. + +@code +glfwIconifyWindow(window); +@endcode + +When a full screen window is iconified, the original video mode of its monitor +is restored until the user or application restores the window. + +Iconified windows can be restored with @ref glfwRestoreWindow. + +@code +glfwRestoreWindow(window); +@endcode + +When a full screen window is restored, the desired video mode is restored to its +monitor as well. + +If you wish to be notified when a window is iconified or restored, whether by +the user, system or your own code, set a iconify callback. + +@code +glfwSetWindowIconifyCallback(window, window_iconify_callback); +@endcode + +The callback function receives changes in the iconification state of the window. + +@code +void window_iconify_callback(GLFWwindow* window, int iconified) +{ + if (iconified) + { + // The window was iconified + } + else + { + // The window was restored + } +} +@endcode + +You can also get the current iconification state with @ref glfwGetWindowAttrib. + +@code +int iconified = glfwGetWindowAttrib(window, GLFW_ICONIFIED); +@endcode + + +@subsection window_hide Window visibility + +Windowed mode windows can be hidden with @ref glfwHideWindow. + +@code +glfwHideWindow(window); +@endcode + +This makes the window completely invisible to the user, including removing it +from the task bar, dock or window list. Full screen windows cannot be hidden +and calling @ref glfwHideWindow on a full screen window does nothing. + +Hidden windows can be shown with @ref glfwShowWindow. + +@code +glfwShowWindow(window); +@endcode + +Windowed mode windows can be created initially hidden with the `GLFW_VISIBLE` +[window hint](@ref window_hints_wnd). Windows created hidden are completely +invisible to the user until shown. This can be useful if you need to set up +your window further before showing it, for example moving it to a specific +location. + +You can also get the current visibility state with @ref glfwGetWindowAttrib. + +@code +int visible = glfwGetWindowAttrib(window, GLFW_VISIBLE); +@endcode + + +@subsection window_focus Window input focus + +If you wish to be notified when a window gains or loses input focus, whether by +the user, system or your own code, set a focus callback. + +@code +glfwSetWindowFocusCallback(window, window_focus_callback); +@endcode + +The callback function receives changes in the input focus state of the window. + +@code +void window_focus_callback(GLFWwindow* window, int focused) +{ + if (focused) + { + // The window gained input focus + } + else + { + // The window lost input focus + } +} +@endcode + +You can also get the current input focus state with @ref glfwGetWindowAttrib. + +@code +int focused = glfwGetWindowAttrib(window, GLFW_FOCUSED); +@endcode + + +@subsection window_refresh Window damage and refresh + +If you wish to be notified when the contents of a window is damaged and needs +to be refreshed, set a window refresh callback. + +@code +glfwSetWindowRefreshCallback(m_handle, window_refresh_callback); +@endcode + +The callback function is called when the contents of the window needs to be +refreshed. + +@code +void window_refresh_callback(GLFWwindow* window) +{ + draw_editor_ui(window); + glfwSwapBuffers(window); +} +@endcode + +@note On compositing window systems such as Aero, Compiz or Aqua, where the +window contents are saved off-screen, this callback might only be called when +the window or framebuffer is resized. + + +@subsection window_attribs Window attributes + +Windows have a number of attributes that can be returned using @ref +glfwGetWindowAttrib. Some reflect state that may change during the lifetime of +the window, while others reflect the corresponding hints and are fixed at the +time of creation. Some are related to the actual window and others to its +context. + +@code +if (glfwGetWindowAttrib(window, GLFW_FOCUSED)) +{ + // window has input focus +} +@endcode + + +@subsubsection window_attribs_wnd Window related attributes + +`GLFW_FOCUSED` indicates whether the specified window has input focus. Initial +input focus is controlled by the [window hint](@ref window_hints_wnd) with the +same name. + +`GLFW_ICONIFIED` indicates whether the specified window is iconified, whether by +the user or with @ref glfwIconifyWindow. + +`GLFW_VISIBLE` indicates whether the specified window is visible. Window +visibility can be controlled with @ref glfwShowWindow and @ref glfwHideWindow +and initial visibility is controlled by the [window hint](@ref window_hints_wnd) +with the same name. + +`GLFW_RESIZABLE` indicates whether the specified window is resizable _by the +user_. This is set on creation with the [window hint](@ref window_hints_wnd) + with the same name. + +`GLFW_DECORATED` indicates whether the specified window has decorations such as +a border, a close widget, etc. This is set on creation with the +[window hint](@ref window_hints_wnd) with the same name. + +`GLFW_FLOATING` indicates whether the specified window is floating, also called +topmost or always-on-top. This is controlled by the +[window hint](@ref window_hints_wnd) with the same name. + + +@subsubsection window_attribs_ctx Context related attributes + +`GLFW_CLIENT_API` indicates the client API provided by the window's context; +either `GLFW_OPENGL_API` or `GLFW_OPENGL_ES_API`. + +`GLFW_CONTEXT_VERSION_MAJOR`, `GLFW_CONTEXT_VERSION_MINOR` and +`GLFW_CONTEXT_REVISION` indicate the client API version of the window's context. + +`GLFW_OPENGL_FORWARD_COMPAT` is `GL_TRUE` if the window's context is an OpenGL +forward-compatible one, or `GL_FALSE` otherwise. + +`GLFW_OPENGL_DEBUG_CONTEXT` is `GL_TRUE` if the window's context is an OpenGL +debug context, or `GL_FALSE` otherwise. + +`GLFW_OPENGL_PROFILE` indicates the OpenGL profile used by the context. This is +`GLFW_OPENGL_CORE_PROFILE` or `GLFW_OPENGL_COMPAT_PROFILE` if the context uses +a known profile, or `GLFW_OPENGL_ANY_PROFILE` if the OpenGL profile is unknown +or the context is an OpenGL ES context. Note that the returned profile may not +match the profile bits of the context flags, as GLFW will try other means of +detecting the profile when no bits are set. + +`GLFW_CONTEXT_ROBUSTNESS` indicates the robustness strategy used by the context. +This is `GLFW_LOSE_CONTEXT_ON_RESET` or `GLFW_NO_RESET_NOTIFICATION` if the +window's context supports robustness, or `GLFW_NO_ROBUSTNESS` otherwise. + + +@section buffer_swap Buffer swapping + +GLFW windows are by default double buffered. That means that you have two +rendering buffers; a front buffer and a back buffer. The front buffer is +the one being displayed and the back buffer the one you render to. + +When the entire frame has been rendered, it is time to swap the back and the +front buffers in order to display what has been rendered and begin rendering +a new frame. This is done with @ref glfwSwapBuffers. + +@code +glfwSwapBuffers(window); +@endcode + +Sometimes it can be useful to select when the buffer swap will occur. With the +function @ref glfwSwapInterval it is possible to select the minimum number of +monitor refreshes the driver wait should from the time @ref glfwSwapBuffers was +called before swapping the buffers: + +@code +glfwSwapInterval(1); +@endcode + +If the interval is zero, the swap will take place immediately when @ref +glfwSwapBuffers is called without waiting for a refresh. Otherwise at least +interval retraces will pass between each buffer swap. Using a swap interval of +zero can be useful for benchmarking purposes, when it is not desirable to +measure the time it takes to wait for the vertical retrace. However, a swap +interval of one lets you avoid tearing. + +Note that this may not work on all machines, as some drivers have +user-controlled settings that override any swap interval the application +requests. It is also by default disabled on Windows Vista and later when using +DWM (Aero), as using it there sometimes leads to severe jitter. You can +forcibly enable it for machines using DWM using @ref compile_options_win32. + +*/ diff --git a/testbed/glfw/examples/CMakeLists.txt b/testbed/glfw/examples/CMakeLists.txt new file mode 100644 index 00000000..229c4a72 --- /dev/null +++ b/testbed/glfw/examples/CMakeLists.txt @@ -0,0 +1,80 @@ + +link_libraries(glfw "${OPENGL_glu_LIBRARY}") + +if (BUILD_SHARED_LIBS) + add_definitions(-DGLFW_DLL) + link_libraries("${OPENGL_gl_LIBRARY}" "${MATH_LIBRARY}") +else() + link_libraries(${glfw_LIBRARIES}) +endif() + +include_directories("${GLFW_SOURCE_DIR}/include" + "${GLFW_SOURCE_DIR}/deps") + +if ("${OPENGL_INCLUDE_DIR}") + include_directories("${OPENGL_INCLUDE_DIR}") +endif() + +set(GLAD "${GLFW_SOURCE_DIR}/deps/glad/glad.h" + "${GLFW_SOURCE_DIR}/deps/glad.c") +set(GETOPT "${GLFW_SOURCE_DIR}/deps/getopt.h" + "${GLFW_SOURCE_DIR}/deps/getopt.c") +set(TINYCTHREAD "${GLFW_SOURCE_DIR}/deps/tinycthread.h" + "${GLFW_SOURCE_DIR}/deps/tinycthread.c") + +if (APPLE) + # Set fancy names for bundles + add_executable(Boing MACOSX_BUNDLE boing.c) + add_executable(Gears MACOSX_BUNDLE gears.c) + add_executable(Heightmap MACOSX_BUNDLE heightmap.c ${GLAD}) + add_executable(Particles MACOSX_BUNDLE particles.c ${TINYCTHREAD}) + add_executable(Simple MACOSX_BUNDLE simple.c) + add_executable(SplitView MACOSX_BUNDLE splitview.c) + add_executable(Wave MACOSX_BUNDLE wave.c) + + set_target_properties(Boing PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Boing") + set_target_properties(Gears PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Gears") + set_target_properties(Heightmap PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Heightmap") + set_target_properties(Particles PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Particles") + set_target_properties(Simple PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Simple") + set_target_properties(SplitView PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Split View") + set_target_properties(Wave PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Wave") + + set_target_properties(Boing Gears Heightmap Particles Simple SplitView Wave PROPERTIES + FOLDER "GLFW3/Examples") +else() + # Set boring names for executables + add_executable(boing WIN32 boing.c) + add_executable(gears WIN32 gears.c) + add_executable(heightmap WIN32 heightmap.c ${GLAD}) + add_executable(particles WIN32 particles.c ${TINYCTHREAD} ${GETOPT}) + add_executable(simple WIN32 simple.c) + add_executable(splitview WIN32 splitview.c) + add_executable(wave WIN32 wave.c) + + set_target_properties(boing gears heightmap particles simple splitview wave PROPERTIES + FOLDER "GLFW3/Examples") +endif() + +if (APPLE) + target_link_libraries(Particles "${CMAKE_THREAD_LIBS_INIT}") +elseif (UNIX) + target_link_libraries(particles "${CMAKE_THREAD_LIBS_INIT}" "${RT_LIBRARY}") +endif() + +if (MSVC) + set(WINDOWS_BINARIES boing gears heightmap particles simple splitview wave) + + # Tell MSVC to use main instead of WinMain for Windows subsystem executables + set_target_properties(${WINDOWS_BINARIES} PROPERTIES + LINK_FLAGS "/ENTRY:mainCRTStartup") +endif() + +if (APPLE) + set(BUNDLE_BINARIES Boing Gears Heightmap Particles Simple SplitView Wave) + + set_target_properties(${BUNDLE_BINARIES} PROPERTIES + MACOSX_BUNDLE_SHORT_VERSION_STRING ${GLFW_VERSION} + MACOSX_BUNDLE_LONG_VERSION_STRING ${GLFW_VERSION_FULL}) +endif() + diff --git a/testbed/glfw/examples/boing.c b/testbed/glfw/examples/boing.c new file mode 100644 index 00000000..ec313596 --- /dev/null +++ b/testbed/glfw/examples/boing.c @@ -0,0 +1,669 @@ +/***************************************************************************** + * Title: GLBoing + * Desc: Tribute to Amiga Boing. + * Author: Jim Brooks + * Original Amiga authors were R.J. Mical and Dale Luck. + * GLFW conversion by Marcus Geelnard + * Notes: - 360' = 2*PI [radian] + * + * - Distances between objects are created by doing a relative + * Z translations. + * + * - Although OpenGL enticingly supports alpha-blending, + * the shadow of the original Boing didn't affect the color + * of the grid. + * + * - [Marcus] Changed timing scheme from interval driven to frame- + * time based animation steps (which results in much smoother + * movement) + * + * History of Amiga Boing: + * + * Boing was demonstrated on the prototype Amiga (codenamed "Lorraine") in + * 1985. According to legend, it was written ad-hoc in one night by + * R. J. Mical and Dale Luck. Because the bouncing ball animation was so fast + * and smooth, attendees did not believe the Amiga prototype was really doing + * the rendering. Suspecting a trick, they began looking around the booth for + * a hidden computer or VCR. + *****************************************************************************/ + +#include +#include +#include + +#define GLFW_INCLUDE_GLU +#include + + +/***************************************************************************** + * Various declarations and macros + *****************************************************************************/ + +/* Prototypes */ +void init( void ); +void display( void ); +void reshape( GLFWwindow* window, int w, int h ); +void key_callback( GLFWwindow* window, int key, int scancode, int action, int mods ); +void mouse_button_callback( GLFWwindow* window, int button, int action, int mods ); +void cursor_position_callback( GLFWwindow* window, double x, double y ); +void DrawBoingBall( void ); +void BounceBall( double dt ); +void DrawBoingBallBand( GLfloat long_lo, GLfloat long_hi ); +void DrawGrid( void ); + +#define RADIUS 70.f +#define STEP_LONGITUDE 22.5f /* 22.5 makes 8 bands like original Boing */ +#define STEP_LATITUDE 22.5f + +#define DIST_BALL (RADIUS * 2.f + RADIUS * 0.1f) + +#define VIEW_SCENE_DIST (DIST_BALL * 3.f + 200.f)/* distance from viewer to middle of boing area */ +#define GRID_SIZE (RADIUS * 4.5f) /* length (width) of grid */ +#define BOUNCE_HEIGHT (RADIUS * 2.1f) +#define BOUNCE_WIDTH (RADIUS * 2.1f) + +#define SHADOW_OFFSET_X -20.f +#define SHADOW_OFFSET_Y 10.f +#define SHADOW_OFFSET_Z 0.f + +#define WALL_L_OFFSET 0.f +#define WALL_R_OFFSET 5.f + +/* Animation speed (50.0 mimics the original GLUT demo speed) */ +#define ANIMATION_SPEED 50.f + +/* Maximum allowed delta time per physics iteration */ +#define MAX_DELTA_T 0.02f + +/* Draw ball, or its shadow */ +typedef enum { DRAW_BALL, DRAW_BALL_SHADOW } DRAW_BALL_ENUM; + +/* Vertex type */ +typedef struct {float x; float y; float z;} vertex_t; + +/* Global vars */ +int width, height; +GLfloat deg_rot_y = 0.f; +GLfloat deg_rot_y_inc = 2.f; +GLboolean override_pos = GL_FALSE; +GLfloat cursor_x = 0.f; +GLfloat cursor_y = 0.f; +GLfloat ball_x = -RADIUS; +GLfloat ball_y = -RADIUS; +GLfloat ball_x_inc = 1.f; +GLfloat ball_y_inc = 2.f; +DRAW_BALL_ENUM drawBallHow; +double t; +double t_old = 0.f; +double dt; + +/* Random number generator */ +#ifndef RAND_MAX + #define RAND_MAX 4095 +#endif + +/* PI */ +#ifndef M_PI + #define M_PI 3.1415926535897932384626433832795 +#endif + + +/***************************************************************************** + * Truncate a degree. + *****************************************************************************/ +GLfloat TruncateDeg( GLfloat deg ) +{ + if ( deg >= 360.f ) + return (deg - 360.f); + else + return deg; +} + +/***************************************************************************** + * Convert a degree (360-based) into a radian. + * 360' = 2 * PI + *****************************************************************************/ +double deg2rad( double deg ) +{ + return deg / 360 * (2 * M_PI); +} + +/***************************************************************************** + * 360' sin(). + *****************************************************************************/ +double sin_deg( double deg ) +{ + return sin( deg2rad( deg ) ); +} + +/***************************************************************************** + * 360' cos(). + *****************************************************************************/ +double cos_deg( double deg ) +{ + return cos( deg2rad( deg ) ); +} + +/***************************************************************************** + * Compute a cross product (for a normal vector). + * + * c = a x b + *****************************************************************************/ +void CrossProduct( vertex_t a, vertex_t b, vertex_t c, vertex_t *n ) +{ + GLfloat u1, u2, u3; + GLfloat v1, v2, v3; + + u1 = b.x - a.x; + u2 = b.y - a.y; + u3 = b.y - a.z; + + v1 = c.x - a.x; + v2 = c.y - a.y; + v3 = c.z - a.z; + + n->x = u2 * v3 - v2 * v3; + n->y = u3 * v1 - v3 * u1; + n->z = u1 * v2 - v1 * u2; +} + +/***************************************************************************** + * Calculate the angle to be passed to gluPerspective() so that a scene + * is visible. This function originates from the OpenGL Red Book. + * + * Parms : size + * The size of the segment when the angle is intersected at "dist" + * (ie at the outermost edge of the angle of vision). + * + * dist + * Distance from viewpoint to scene. + *****************************************************************************/ +GLfloat PerspectiveAngle( GLfloat size, + GLfloat dist ) +{ + GLfloat radTheta, degTheta; + + radTheta = 2.f * (GLfloat) atan2( size / 2.f, dist ); + degTheta = (180.f * radTheta) / (GLfloat) M_PI; + return degTheta; +} + + + +#define BOING_DEBUG 0 + + +/***************************************************************************** + * init() + *****************************************************************************/ +void init( void ) +{ + /* + * Clear background. + */ + glClearColor( 0.55f, 0.55f, 0.55f, 0.f ); + + glShadeModel( GL_FLAT ); +} + + +/***************************************************************************** + * display() + *****************************************************************************/ +void display(void) +{ + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + glPushMatrix(); + + drawBallHow = DRAW_BALL_SHADOW; + DrawBoingBall(); + + DrawGrid(); + + drawBallHow = DRAW_BALL; + DrawBoingBall(); + + glPopMatrix(); + glFlush(); +} + + +/***************************************************************************** + * reshape() + *****************************************************************************/ +void reshape( GLFWwindow* window, int w, int h ) +{ + glViewport( 0, 0, (GLsizei)w, (GLsizei)h ); + + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + + gluPerspective( PerspectiveAngle( RADIUS * 2, 200 ), + (GLfloat)w / (GLfloat)h, + 1.0, + VIEW_SCENE_DIST ); + + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + + gluLookAt( 0.0, 0.0, VIEW_SCENE_DIST,/* eye */ + 0.0, 0.0, 0.0, /* center of vision */ + 0.0, -1.0, 0.0 ); /* up vector */ +} + +void key_callback( GLFWwindow* window, int key, int scancode, int action, int mods ) +{ + if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) + glfwSetWindowShouldClose(window, GL_TRUE); +} + +static void set_ball_pos ( GLfloat x, GLfloat y ) +{ + ball_x = (width / 2) - x; + ball_y = y - (height / 2); +} + +void mouse_button_callback( GLFWwindow* window, int button, int action, int mods ) +{ + if (button != GLFW_MOUSE_BUTTON_LEFT) + return; + + if (action == GLFW_PRESS) + { + override_pos = GL_TRUE; + set_ball_pos(cursor_x, cursor_y); + } + else + { + override_pos = GL_FALSE; + } +} + +void cursor_position_callback( GLFWwindow* window, double x, double y ) +{ + cursor_x = (float) x; + cursor_y = (float) y; + + if ( override_pos ) + set_ball_pos(cursor_x, cursor_y); +} + +/***************************************************************************** + * Draw the Boing ball. + * + * The Boing ball is sphere in which each facet is a rectangle. + * Facet colors alternate between red and white. + * The ball is built by stacking latitudinal circles. Each circle is composed + * of a widely-separated set of points, so that each facet is noticably large. + *****************************************************************************/ +void DrawBoingBall( void ) +{ + GLfloat lon_deg; /* degree of longitude */ + double dt_total, dt2; + + glPushMatrix(); + glMatrixMode( GL_MODELVIEW ); + + /* + * Another relative Z translation to separate objects. + */ + glTranslatef( 0.0, 0.0, DIST_BALL ); + + /* Update ball position and rotation (iterate if necessary) */ + dt_total = dt; + while( dt_total > 0.0 ) + { + dt2 = dt_total > MAX_DELTA_T ? MAX_DELTA_T : dt_total; + dt_total -= dt2; + BounceBall( dt2 ); + deg_rot_y = TruncateDeg( deg_rot_y + deg_rot_y_inc*((float)dt2*ANIMATION_SPEED) ); + } + + /* Set ball position */ + glTranslatef( ball_x, ball_y, 0.0 ); + + /* + * Offset the shadow. + */ + if ( drawBallHow == DRAW_BALL_SHADOW ) + { + glTranslatef( SHADOW_OFFSET_X, + SHADOW_OFFSET_Y, + SHADOW_OFFSET_Z ); + } + + /* + * Tilt the ball. + */ + glRotatef( -20.0, 0.0, 0.0, 1.0 ); + + /* + * Continually rotate ball around Y axis. + */ + glRotatef( deg_rot_y, 0.0, 1.0, 0.0 ); + + /* + * Set OpenGL state for Boing ball. + */ + glCullFace( GL_FRONT ); + glEnable( GL_CULL_FACE ); + glEnable( GL_NORMALIZE ); + + /* + * Build a faceted latitude slice of the Boing ball, + * stepping same-sized vertical bands of the sphere. + */ + for ( lon_deg = 0; + lon_deg < 180; + lon_deg += STEP_LONGITUDE ) + { + /* + * Draw a latitude circle at this longitude. + */ + DrawBoingBallBand( lon_deg, + lon_deg + STEP_LONGITUDE ); + } + + glPopMatrix(); + + return; +} + + +/***************************************************************************** + * Bounce the ball. + *****************************************************************************/ +void BounceBall( double delta_t ) +{ + GLfloat sign; + GLfloat deg; + + if ( override_pos ) + return; + + /* Bounce on walls */ + if ( ball_x > (BOUNCE_WIDTH/2 + WALL_R_OFFSET ) ) + { + ball_x_inc = -0.5f - 0.75f * (GLfloat)rand() / (GLfloat)RAND_MAX; + deg_rot_y_inc = -deg_rot_y_inc; + } + if ( ball_x < -(BOUNCE_HEIGHT/2 + WALL_L_OFFSET) ) + { + ball_x_inc = 0.5f + 0.75f * (GLfloat)rand() / (GLfloat)RAND_MAX; + deg_rot_y_inc = -deg_rot_y_inc; + } + + /* Bounce on floor / roof */ + if ( ball_y > BOUNCE_HEIGHT/2 ) + { + ball_y_inc = -0.75f - 1.f * (GLfloat)rand() / (GLfloat)RAND_MAX; + } + if ( ball_y < -BOUNCE_HEIGHT/2*0.85 ) + { + ball_y_inc = 0.75f + 1.f * (GLfloat)rand() / (GLfloat)RAND_MAX; + } + + /* Update ball position */ + ball_x += ball_x_inc * ((float)delta_t*ANIMATION_SPEED); + ball_y += ball_y_inc * ((float)delta_t*ANIMATION_SPEED); + + /* + * Simulate the effects of gravity on Y movement. + */ + if ( ball_y_inc < 0 ) sign = -1.0; else sign = 1.0; + + deg = (ball_y + BOUNCE_HEIGHT/2) * 90 / BOUNCE_HEIGHT; + if ( deg > 80 ) deg = 80; + if ( deg < 10 ) deg = 10; + + ball_y_inc = sign * 4.f * (float) sin_deg( deg ); +} + + +/***************************************************************************** + * Draw a faceted latitude band of the Boing ball. + * + * Parms: long_lo, long_hi + * Low and high longitudes of slice, resp. + *****************************************************************************/ +void DrawBoingBallBand( GLfloat long_lo, + GLfloat long_hi ) +{ + vertex_t vert_ne; /* "ne" means south-east, so on */ + vertex_t vert_nw; + vertex_t vert_sw; + vertex_t vert_se; + vertex_t vert_norm; + GLfloat lat_deg; + static int colorToggle = 0; + + /* + * Iterate thru the points of a latitude circle. + * A latitude circle is a 2D set of X,Z points. + */ + for ( lat_deg = 0; + lat_deg <= (360 - STEP_LATITUDE); + lat_deg += STEP_LATITUDE ) + { + /* + * Color this polygon with red or white. + */ + if ( colorToggle ) + glColor3f( 0.8f, 0.1f, 0.1f ); + else + glColor3f( 0.95f, 0.95f, 0.95f ); +#if 0 + if ( lat_deg >= 180 ) + if ( colorToggle ) + glColor3f( 0.1f, 0.8f, 0.1f ); + else + glColor3f( 0.5f, 0.5f, 0.95f ); +#endif + colorToggle = ! colorToggle; + + /* + * Change color if drawing shadow. + */ + if ( drawBallHow == DRAW_BALL_SHADOW ) + glColor3f( 0.35f, 0.35f, 0.35f ); + + /* + * Assign each Y. + */ + vert_ne.y = vert_nw.y = (float) cos_deg(long_hi) * RADIUS; + vert_sw.y = vert_se.y = (float) cos_deg(long_lo) * RADIUS; + + /* + * Assign each X,Z with sin,cos values scaled by latitude radius indexed by longitude. + * Eg, long=0 and long=180 are at the poles, so zero scale is sin(longitude), + * while long=90 (sin(90)=1) is at equator. + */ + vert_ne.x = (float) cos_deg( lat_deg ) * (RADIUS * (float) sin_deg( long_lo + STEP_LONGITUDE )); + vert_se.x = (float) cos_deg( lat_deg ) * (RADIUS * (float) sin_deg( long_lo )); + vert_nw.x = (float) cos_deg( lat_deg + STEP_LATITUDE ) * (RADIUS * (float) sin_deg( long_lo + STEP_LONGITUDE )); + vert_sw.x = (float) cos_deg( lat_deg + STEP_LATITUDE ) * (RADIUS * (float) sin_deg( long_lo )); + + vert_ne.z = (float) sin_deg( lat_deg ) * (RADIUS * (float) sin_deg( long_lo + STEP_LONGITUDE )); + vert_se.z = (float) sin_deg( lat_deg ) * (RADIUS * (float) sin_deg( long_lo )); + vert_nw.z = (float) sin_deg( lat_deg + STEP_LATITUDE ) * (RADIUS * (float) sin_deg( long_lo + STEP_LONGITUDE )); + vert_sw.z = (float) sin_deg( lat_deg + STEP_LATITUDE ) * (RADIUS * (float) sin_deg( long_lo )); + + /* + * Draw the facet. + */ + glBegin( GL_POLYGON ); + + CrossProduct( vert_ne, vert_nw, vert_sw, &vert_norm ); + glNormal3f( vert_norm.x, vert_norm.y, vert_norm.z ); + + glVertex3f( vert_ne.x, vert_ne.y, vert_ne.z ); + glVertex3f( vert_nw.x, vert_nw.y, vert_nw.z ); + glVertex3f( vert_sw.x, vert_sw.y, vert_sw.z ); + glVertex3f( vert_se.x, vert_se.y, vert_se.z ); + + glEnd(); + +#if BOING_DEBUG + printf( "----------------------------------------------------------- \n" ); + printf( "lat = %f long_lo = %f long_hi = %f \n", lat_deg, long_lo, long_hi ); + printf( "vert_ne x = %.8f y = %.8f z = %.8f \n", vert_ne.x, vert_ne.y, vert_ne.z ); + printf( "vert_nw x = %.8f y = %.8f z = %.8f \n", vert_nw.x, vert_nw.y, vert_nw.z ); + printf( "vert_se x = %.8f y = %.8f z = %.8f \n", vert_se.x, vert_se.y, vert_se.z ); + printf( "vert_sw x = %.8f y = %.8f z = %.8f \n", vert_sw.x, vert_sw.y, vert_sw.z ); +#endif + + } + + /* + * Toggle color so that next band will opposite red/white colors than this one. + */ + colorToggle = ! colorToggle; + + /* + * This circular band is done. + */ + return; +} + + +/***************************************************************************** + * Draw the purple grid of lines, behind the Boing ball. + * When the Workbench is dropped to the bottom, Boing shows 12 rows. + *****************************************************************************/ +void DrawGrid( void ) +{ + int row, col; + const int rowTotal = 12; /* must be divisible by 2 */ + const int colTotal = rowTotal; /* must be same as rowTotal */ + const GLfloat widthLine = 2.0; /* should be divisible by 2 */ + const GLfloat sizeCell = GRID_SIZE / rowTotal; + const GLfloat z_offset = -40.0; + GLfloat xl, xr; + GLfloat yt, yb; + + glPushMatrix(); + glDisable( GL_CULL_FACE ); + + /* + * Another relative Z translation to separate objects. + */ + glTranslatef( 0.0, 0.0, DIST_BALL ); + + /* + * Draw vertical lines (as skinny 3D rectangles). + */ + for ( col = 0; col <= colTotal; col++ ) + { + /* + * Compute co-ords of line. + */ + xl = -GRID_SIZE / 2 + col * sizeCell; + xr = xl + widthLine; + + yt = GRID_SIZE / 2; + yb = -GRID_SIZE / 2 - widthLine; + + glBegin( GL_POLYGON ); + + glColor3f( 0.6f, 0.1f, 0.6f ); /* purple */ + + glVertex3f( xr, yt, z_offset ); /* NE */ + glVertex3f( xl, yt, z_offset ); /* NW */ + glVertex3f( xl, yb, z_offset ); /* SW */ + glVertex3f( xr, yb, z_offset ); /* SE */ + + glEnd(); + } + + /* + * Draw horizontal lines (as skinny 3D rectangles). + */ + for ( row = 0; row <= rowTotal; row++ ) + { + /* + * Compute co-ords of line. + */ + yt = GRID_SIZE / 2 - row * sizeCell; + yb = yt - widthLine; + + xl = -GRID_SIZE / 2; + xr = GRID_SIZE / 2 + widthLine; + + glBegin( GL_POLYGON ); + + glColor3f( 0.6f, 0.1f, 0.6f ); /* purple */ + + glVertex3f( xr, yt, z_offset ); /* NE */ + glVertex3f( xl, yt, z_offset ); /* NW */ + glVertex3f( xl, yb, z_offset ); /* SW */ + glVertex3f( xr, yb, z_offset ); /* SE */ + + glEnd(); + } + + glPopMatrix(); + + return; +} + + +/*======================================================================* + * main() + *======================================================================*/ + +int main( void ) +{ + GLFWwindow* window; + + /* Init GLFW */ + if( !glfwInit() ) + exit( EXIT_FAILURE ); + + glfwWindowHint(GLFW_DEPTH_BITS, 16); + + window = glfwCreateWindow( 400, 400, "Boing (classic Amiga demo)", NULL, NULL ); + if (!window) + { + glfwTerminate(); + exit( EXIT_FAILURE ); + } + + glfwSetFramebufferSizeCallback(window, reshape); + glfwSetKeyCallback(window, key_callback); + glfwSetMouseButtonCallback(window, mouse_button_callback); + glfwSetCursorPosCallback(window, cursor_position_callback); + + glfwMakeContextCurrent(window); + glfwSwapInterval( 1 ); + + glfwGetFramebufferSize(window, &width, &height); + reshape(window, width, height); + + glfwSetTime( 0.0 ); + + init(); + + /* Main loop */ + for (;;) + { + /* Timing */ + t = glfwGetTime(); + dt = t - t_old; + t_old = t; + + /* Draw one frame */ + display(); + + /* Swap buffers */ + glfwSwapBuffers(window); + glfwPollEvents(); + + /* Check if we are still running */ + if (glfwWindowShouldClose(window)) + break; + } + + glfwTerminate(); + exit( EXIT_SUCCESS ); +} + diff --git a/testbed/glfw/examples/gears.c b/testbed/glfw/examples/gears.c new file mode 100644 index 00000000..2d445964 --- /dev/null +++ b/testbed/glfw/examples/gears.c @@ -0,0 +1,372 @@ +/* + * 3-D gear wheels. This program is in the public domain. + * + * Command line options: + * -info print GL implementation information + * -exit automatically exit after 30 seconds + * + * + * Brian Paul + * + * + * Marcus Geelnard: + * - Conversion to GLFW + * - Time based rendering (frame rate independent) + * - Slightly modified camera that should work better for stereo viewing + * + * + * Camilla Berglund: + * - Removed FPS counter (this is not a benchmark) + * - Added a few comments + * - Enabled vsync + */ + + +#include +#include +#include +#include +#include + +#ifndef M_PI +#define M_PI 3.141592654 +#endif + +/* If non-zero, the program exits after that many seconds + */ +static int autoexit = 0; + +/** + + Draw a gear wheel. You'll probably want to call this function when + building a display list since we do a lot of trig here. + + Input: inner_radius - radius of hole at center + outer_radius - radius at center of teeth + width - width of gear teeth - number of teeth + tooth_depth - depth of tooth + + **/ + +static void +gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width, + GLint teeth, GLfloat tooth_depth) +{ + GLint i; + GLfloat r0, r1, r2; + GLfloat angle, da; + GLfloat u, v, len; + + r0 = inner_radius; + r1 = outer_radius - tooth_depth / 2.f; + r2 = outer_radius + tooth_depth / 2.f; + + da = 2.f * (float) M_PI / teeth / 4.f; + + glShadeModel(GL_FLAT); + + glNormal3f(0.f, 0.f, 1.f); + + /* draw front face */ + glBegin(GL_QUAD_STRIP); + for (i = 0; i <= teeth; i++) { + angle = i * 2.f * (float) M_PI / teeth; + glVertex3f(r0 * (float) cos(angle), r0 * (float) sin(angle), width * 0.5f); + glVertex3f(r1 * (float) cos(angle), r1 * (float) sin(angle), width * 0.5f); + if (i < teeth) { + glVertex3f(r0 * (float) cos(angle), r0 * (float) sin(angle), width * 0.5f); + glVertex3f(r1 * (float) cos(angle + 3 * da), r1 * (float) sin(angle + 3 * da), width * 0.5f); + } + } + glEnd(); + + /* draw front sides of teeth */ + glBegin(GL_QUADS); + da = 2.f * (float) M_PI / teeth / 4.f; + for (i = 0; i < teeth; i++) { + angle = i * 2.f * (float) M_PI / teeth; + + glVertex3f(r1 * (float) cos(angle), r1 * (float) sin(angle), width * 0.5f); + glVertex3f(r2 * (float) cos(angle + da), r2 * (float) sin(angle + da), width * 0.5f); + glVertex3f(r2 * (float) cos(angle + 2 * da), r2 * (float) sin(angle + 2 * da), width * 0.5f); + glVertex3f(r1 * (float) cos(angle + 3 * da), r1 * (float) sin(angle + 3 * da), width * 0.5f); + } + glEnd(); + + glNormal3f(0.0, 0.0, -1.0); + + /* draw back face */ + glBegin(GL_QUAD_STRIP); + for (i = 0; i <= teeth; i++) { + angle = i * 2.f * (float) M_PI / teeth; + glVertex3f(r1 * (float) cos(angle), r1 * (float) sin(angle), -width * 0.5f); + glVertex3f(r0 * (float) cos(angle), r0 * (float) sin(angle), -width * 0.5f); + if (i < teeth) { + glVertex3f(r1 * (float) cos(angle + 3 * da), r1 * (float) sin(angle + 3 * da), -width * 0.5f); + glVertex3f(r0 * (float) cos(angle), r0 * (float) sin(angle), -width * 0.5f); + } + } + glEnd(); + + /* draw back sides of teeth */ + glBegin(GL_QUADS); + da = 2.f * (float) M_PI / teeth / 4.f; + for (i = 0; i < teeth; i++) { + angle = i * 2.f * (float) M_PI / teeth; + + glVertex3f(r1 * (float) cos(angle + 3 * da), r1 * (float) sin(angle + 3 * da), -width * 0.5f); + glVertex3f(r2 * (float) cos(angle + 2 * da), r2 * (float) sin(angle + 2 * da), -width * 0.5f); + glVertex3f(r2 * (float) cos(angle + da), r2 * (float) sin(angle + da), -width * 0.5f); + glVertex3f(r1 * (float) cos(angle), r1 * (float) sin(angle), -width * 0.5f); + } + glEnd(); + + /* draw outward faces of teeth */ + glBegin(GL_QUAD_STRIP); + for (i = 0; i < teeth; i++) { + angle = i * 2.f * (float) M_PI / teeth; + + glVertex3f(r1 * (float) cos(angle), r1 * (float) sin(angle), width * 0.5f); + glVertex3f(r1 * (float) cos(angle), r1 * (float) sin(angle), -width * 0.5f); + u = r2 * (float) cos(angle + da) - r1 * (float) cos(angle); + v = r2 * (float) sin(angle + da) - r1 * (float) sin(angle); + len = (float) sqrt(u * u + v * v); + u /= len; + v /= len; + glNormal3f(v, -u, 0.0); + glVertex3f(r2 * (float) cos(angle + da), r2 * (float) sin(angle + da), width * 0.5f); + glVertex3f(r2 * (float) cos(angle + da), r2 * (float) sin(angle + da), -width * 0.5f); + glNormal3f((float) cos(angle), (float) sin(angle), 0.f); + glVertex3f(r2 * (float) cos(angle + 2 * da), r2 * (float) sin(angle + 2 * da), width * 0.5f); + glVertex3f(r2 * (float) cos(angle + 2 * da), r2 * (float) sin(angle + 2 * da), -width * 0.5f); + u = r1 * (float) cos(angle + 3 * da) - r2 * (float) cos(angle + 2 * da); + v = r1 * (float) sin(angle + 3 * da) - r2 * (float) sin(angle + 2 * da); + glNormal3f(v, -u, 0.f); + glVertex3f(r1 * (float) cos(angle + 3 * da), r1 * (float) sin(angle + 3 * da), width * 0.5f); + glVertex3f(r1 * (float) cos(angle + 3 * da), r1 * (float) sin(angle + 3 * da), -width * 0.5f); + glNormal3f((float) cos(angle), (float) sin(angle), 0.f); + } + + glVertex3f(r1 * (float) cos(0), r1 * (float) sin(0), width * 0.5f); + glVertex3f(r1 * (float) cos(0), r1 * (float) sin(0), -width * 0.5f); + + glEnd(); + + glShadeModel(GL_SMOOTH); + + /* draw inside radius cylinder */ + glBegin(GL_QUAD_STRIP); + for (i = 0; i <= teeth; i++) { + angle = i * 2.f * (float) M_PI / teeth; + glNormal3f(-(float) cos(angle), -(float) sin(angle), 0.f); + glVertex3f(r0 * (float) cos(angle), r0 * (float) sin(angle), -width * 0.5f); + glVertex3f(r0 * (float) cos(angle), r0 * (float) sin(angle), width * 0.5f); + } + glEnd(); + +} + + +static GLfloat view_rotx = 20.f, view_roty = 30.f, view_rotz = 0.f; +static GLint gear1, gear2, gear3; +static GLfloat angle = 0.f; + +/* OpenGL draw function & timing */ +static void draw(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + glRotatef(view_rotx, 1.0, 0.0, 0.0); + glRotatef(view_roty, 0.0, 1.0, 0.0); + glRotatef(view_rotz, 0.0, 0.0, 1.0); + + glPushMatrix(); + glTranslatef(-3.0, -2.0, 0.0); + glRotatef(angle, 0.0, 0.0, 1.0); + glCallList(gear1); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(3.1f, -2.f, 0.f); + glRotatef(-2.f * angle - 9.f, 0.f, 0.f, 1.f); + glCallList(gear2); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(-3.1f, 4.2f, 0.f); + glRotatef(-2.f * angle - 25.f, 0.f, 0.f, 1.f); + glCallList(gear3); + glPopMatrix(); + + glPopMatrix(); +} + + +/* update animation parameters */ +static void animate(void) +{ + angle = 100.f * (float) glfwGetTime(); +} + + +/* change view angle, exit upon ESC */ +void key( GLFWwindow* window, int k, int s, int action, int mods ) +{ + if( action != GLFW_PRESS ) return; + + switch (k) { + case GLFW_KEY_Z: + if( mods & GLFW_MOD_SHIFT ) + view_rotz -= 5.0; + else + view_rotz += 5.0; + break; + case GLFW_KEY_ESCAPE: + glfwSetWindowShouldClose(window, GL_TRUE); + break; + case GLFW_KEY_UP: + view_rotx += 5.0; + break; + case GLFW_KEY_DOWN: + view_rotx -= 5.0; + break; + case GLFW_KEY_LEFT: + view_roty += 5.0; + break; + case GLFW_KEY_RIGHT: + view_roty -= 5.0; + break; + default: + return; + } +} + + +/* new window size */ +void reshape( GLFWwindow* window, int width, int height ) +{ + GLfloat h = (GLfloat) height / (GLfloat) width; + GLfloat xmax, znear, zfar; + + znear = 5.0f; + zfar = 30.0f; + xmax = znear * 0.5f; + + glViewport( 0, 0, (GLint) width, (GLint) height ); + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + glFrustum( -xmax, xmax, -xmax*h, xmax*h, znear, zfar ); + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + glTranslatef( 0.0, 0.0, -20.0 ); +} + + +/* program & OpenGL initialization */ +static void init(int argc, char *argv[]) +{ + static GLfloat pos[4] = {5.f, 5.f, 10.f, 0.f}; + static GLfloat red[4] = {0.8f, 0.1f, 0.f, 1.f}; + static GLfloat green[4] = {0.f, 0.8f, 0.2f, 1.f}; + static GLfloat blue[4] = {0.2f, 0.2f, 1.f, 1.f}; + GLint i; + + glLightfv(GL_LIGHT0, GL_POSITION, pos); + glEnable(GL_CULL_FACE); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glEnable(GL_DEPTH_TEST); + + /* make the gears */ + gear1 = glGenLists(1); + glNewList(gear1, GL_COMPILE); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red); + gear(1.f, 4.f, 1.f, 20, 0.7f); + glEndList(); + + gear2 = glGenLists(1); + glNewList(gear2, GL_COMPILE); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green); + gear(0.5f, 2.f, 2.f, 10, 0.7f); + glEndList(); + + gear3 = glGenLists(1); + glNewList(gear3, GL_COMPILE); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue); + gear(1.3f, 2.f, 0.5f, 10, 0.7f); + glEndList(); + + glEnable(GL_NORMALIZE); + + for ( i=1; i +#include +#include +#include +#include + +#include +#include + +/* Map height updates */ +#define MAX_CIRCLE_SIZE (5.0f) +#define MAX_DISPLACEMENT (1.0f) +#define DISPLACEMENT_SIGN_LIMIT (0.3f) +#define MAX_ITER (200) +#define NUM_ITER_AT_A_TIME (1) + +/* Map general information */ +#define MAP_SIZE (10.0f) +#define MAP_NUM_VERTICES (80) +#define MAP_NUM_TOTAL_VERTICES (MAP_NUM_VERTICES*MAP_NUM_VERTICES) +#define MAP_NUM_LINES (3* (MAP_NUM_VERTICES - 1) * (MAP_NUM_VERTICES - 1) + \ + 2 * (MAP_NUM_VERTICES - 1)) + + +/********************************************************************** + * Default shader programs + *********************************************************************/ + +static const char* vertex_shader_text = +"#version 150\n" +"uniform mat4 project;\n" +"uniform mat4 modelview;\n" +"in float x;\n" +"in float y;\n" +"in float z;\n" +"\n" +"void main()\n" +"{\n" +" gl_Position = project * modelview * vec4(x, y, z, 1.0);\n" +"}\n"; + +static const char* fragment_shader_text = +"#version 150\n" +"out vec4 color;\n" +"void main()\n" +"{\n" +" color = vec4(0.2, 1.0, 0.2, 1.0); \n" +"}\n"; + +/********************************************************************** + * Values for shader uniforms + *********************************************************************/ + +/* Frustum configuration */ +static GLfloat view_angle = 45.0f; +static GLfloat aspect_ratio = 4.0f/3.0f; +static GLfloat z_near = 1.0f; +static GLfloat z_far = 100.f; + +/* Projection matrix */ +static GLfloat projection_matrix[16] = { + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f +}; + +/* Model view matrix */ +static GLfloat modelview_matrix[16] = { + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f +}; + +/********************************************************************** + * Heightmap vertex and index data + *********************************************************************/ + +static GLfloat map_vertices[3][MAP_NUM_TOTAL_VERTICES]; +static GLuint map_line_indices[2*MAP_NUM_LINES]; + +/* Store uniform location for the shaders + * Those values are setup as part of the process of creating + * the shader program. They should not be used before creating + * the program. + */ +static GLuint mesh; +static GLuint mesh_vbo[4]; + +/********************************************************************** + * OpenGL helper functions + *********************************************************************/ + +/* Creates a shader object of the specified type using the specified text + */ +static GLuint make_shader(GLenum type, const char* text) +{ + GLuint shader; + GLint shader_ok; + GLsizei log_length; + char info_log[8192]; + + shader = glCreateShader(type); + if (shader != 0) + { + glShaderSource(shader, 1, (const GLchar**)&text, NULL); + glCompileShader(shader); + glGetShaderiv(shader, GL_COMPILE_STATUS, &shader_ok); + if (shader_ok != GL_TRUE) + { + fprintf(stderr, "ERROR: Failed to compile %s shader\n", (type == GL_FRAGMENT_SHADER) ? "fragment" : "vertex" ); + glGetShaderInfoLog(shader, 8192, &log_length,info_log); + fprintf(stderr, "ERROR: \n%s\n\n", info_log); + glDeleteShader(shader); + shader = 0; + } + } + return shader; +} + +/* Creates a program object using the specified vertex and fragment text + */ +static GLuint make_shader_program(const char* vs_text, const char* fs_text) +{ + GLuint program = 0u; + GLint program_ok; + GLuint vertex_shader = 0u; + GLuint fragment_shader = 0u; + GLsizei log_length; + char info_log[8192]; + + vertex_shader = make_shader(GL_VERTEX_SHADER, vs_text); + if (vertex_shader != 0u) + { + fragment_shader = make_shader(GL_FRAGMENT_SHADER, fs_text); + if (fragment_shader != 0u) + { + /* make the program that connect the two shader and link it */ + program = glCreateProgram(); + if (program != 0u) + { + /* attach both shader and link */ + glAttachShader(program, vertex_shader); + glAttachShader(program, fragment_shader); + glLinkProgram(program); + glGetProgramiv(program, GL_LINK_STATUS, &program_ok); + + if (program_ok != GL_TRUE) + { + fprintf(stderr, "ERROR, failed to link shader program\n"); + glGetProgramInfoLog(program, 8192, &log_length, info_log); + fprintf(stderr, "ERROR: \n%s\n\n", info_log); + glDeleteProgram(program); + glDeleteShader(fragment_shader); + glDeleteShader(vertex_shader); + program = 0u; + } + } + } + else + { + fprintf(stderr, "ERROR: Unable to load fragment shader\n"); + glDeleteShader(vertex_shader); + } + } + else + { + fprintf(stderr, "ERROR: Unable to load vertex shader\n"); + } + return program; +} + +/********************************************************************** + * Geometry creation functions + *********************************************************************/ + +/* Generate vertices and indices for the heightmap + */ +static void init_map(void) +{ + int i; + int j; + int k; + GLfloat step = MAP_SIZE / (MAP_NUM_VERTICES - 1); + GLfloat x = 0.0f; + GLfloat z = 0.0f; + /* Create a flat grid */ + k = 0; + for (i = 0 ; i < MAP_NUM_VERTICES ; ++i) + { + for (j = 0 ; j < MAP_NUM_VERTICES ; ++j) + { + map_vertices[0][k] = x; + map_vertices[1][k] = 0.0f; + map_vertices[2][k] = z; + z += step; + ++k; + } + x += step; + z = 0.0f; + } +#if DEBUG_ENABLED + for (i = 0 ; i < MAP_NUM_TOTAL_VERTICES ; ++i) + { + printf ("Vertice %d (%f, %f, %f)\n", + i, map_vertices[0][i], map_vertices[1][i], map_vertices[2][i]); + + } +#endif + /* create indices */ + /* line fan based on i + * i+1 + * | / i + n + 1 + * | / + * |/ + * i --- i + n + */ + + /* close the top of the square */ + k = 0; + for (i = 0 ; i < MAP_NUM_VERTICES -1 ; ++i) + { + map_line_indices[k++] = (i + 1) * MAP_NUM_VERTICES -1; + map_line_indices[k++] = (i + 2) * MAP_NUM_VERTICES -1; + } + /* close the right of the square */ + for (i = 0 ; i < MAP_NUM_VERTICES -1 ; ++i) + { + map_line_indices[k++] = (MAP_NUM_VERTICES - 1) * MAP_NUM_VERTICES + i; + map_line_indices[k++] = (MAP_NUM_VERTICES - 1) * MAP_NUM_VERTICES + i + 1; + } + + for (i = 0 ; i < (MAP_NUM_VERTICES - 1) ; ++i) + { + for (j = 0 ; j < (MAP_NUM_VERTICES - 1) ; ++j) + { + int ref = i * (MAP_NUM_VERTICES) + j; + map_line_indices[k++] = ref; + map_line_indices[k++] = ref + 1; + + map_line_indices[k++] = ref; + map_line_indices[k++] = ref + MAP_NUM_VERTICES; + + map_line_indices[k++] = ref; + map_line_indices[k++] = ref + MAP_NUM_VERTICES + 1; + } + } + +#ifdef DEBUG_ENABLED + for (k = 0 ; k < 2 * MAP_NUM_LINES ; k += 2) + { + int beg, end; + beg = map_line_indices[k]; + end = map_line_indices[k+1]; + printf ("Line %d: %d -> %d (%f, %f, %f) -> (%f, %f, %f)\n", + k / 2, beg, end, + map_vertices[0][beg], map_vertices[1][beg], map_vertices[2][beg], + map_vertices[0][end], map_vertices[1][end], map_vertices[2][end]); + } +#endif +} + +static void generate_heightmap__circle(float* center_x, float* center_y, + float* size, float* displacement) +{ + float sign; + /* random value for element in between [0-1.0] */ + *center_x = (MAP_SIZE * rand()) / (1.0f * RAND_MAX); + *center_y = (MAP_SIZE * rand()) / (1.0f * RAND_MAX); + *size = (MAX_CIRCLE_SIZE * rand()) / (1.0f * RAND_MAX); + sign = (1.0f * rand()) / (1.0f * RAND_MAX); + sign = (sign < DISPLACEMENT_SIGN_LIMIT) ? -1.0f : 1.0f; + *displacement = (sign * (MAX_DISPLACEMENT * rand())) / (1.0f * RAND_MAX); +} + +/* Run the specified number of iterations of the generation process for the + * heightmap + */ +static void update_map(int num_iter) +{ + assert(num_iter > 0); + while(num_iter) + { + /* center of the circle */ + float center_x; + float center_z; + float circle_size; + float disp; + size_t ii; + generate_heightmap__circle(¢er_x, ¢er_z, &circle_size, &disp); + disp = disp / 2.0f; + for (ii = 0u ; ii < MAP_NUM_TOTAL_VERTICES ; ++ii) + { + GLfloat dx = center_x - map_vertices[0][ii]; + GLfloat dz = center_z - map_vertices[2][ii]; + GLfloat pd = (2.0f * sqrtf((dx * dx) + (dz * dz))) / circle_size; + if (fabs(pd) <= 1.0f) + { + /* tx,tz is within the circle */ + GLfloat new_height = disp + (float) (cos(pd*3.14f)*disp); + map_vertices[1][ii] += new_height; + } + } + --num_iter; + } +} + +/********************************************************************** + * OpenGL helper functions + *********************************************************************/ + +/* Create VBO, IBO and VAO objects for the heightmap geometry and bind them to + * the specified program object + */ +static void make_mesh(GLuint program) +{ + GLuint attrloc; + + glGenVertexArrays(1, &mesh); + glGenBuffers(4, mesh_vbo); + glBindVertexArray(mesh); + /* Prepare the data for drawing through a buffer inidices */ + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh_vbo[3]); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint)* MAP_NUM_LINES * 2, map_line_indices, GL_STATIC_DRAW); + + /* Prepare the attributes for rendering */ + attrloc = glGetAttribLocation(program, "x"); + glBindBuffer(GL_ARRAY_BUFFER, mesh_vbo[0]); + glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * MAP_NUM_TOTAL_VERTICES, &map_vertices[0][0], GL_STATIC_DRAW); + glEnableVertexAttribArray(attrloc); + glVertexAttribPointer(attrloc, 1, GL_FLOAT, GL_FALSE, 0, 0); + + attrloc = glGetAttribLocation(program, "z"); + glBindBuffer(GL_ARRAY_BUFFER, mesh_vbo[2]); + glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * MAP_NUM_TOTAL_VERTICES, &map_vertices[2][0], GL_STATIC_DRAW); + glEnableVertexAttribArray(attrloc); + glVertexAttribPointer(attrloc, 1, GL_FLOAT, GL_FALSE, 0, 0); + + attrloc = glGetAttribLocation(program, "y"); + glBindBuffer(GL_ARRAY_BUFFER, mesh_vbo[1]); + glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * MAP_NUM_TOTAL_VERTICES, &map_vertices[1][0], GL_DYNAMIC_DRAW); + glEnableVertexAttribArray(attrloc); + glVertexAttribPointer(attrloc, 1, GL_FLOAT, GL_FALSE, 0, 0); +} + +/* Update VBO vertices from source data + */ +static void update_mesh(void) +{ + glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(GLfloat) * MAP_NUM_TOTAL_VERTICES, &map_vertices[1][0]); +} + +/********************************************************************** + * GLFW callback functions + *********************************************************************/ + +static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + switch(key) + { + case GLFW_KEY_ESCAPE: + /* Exit program on Escape */ + glfwSetWindowShouldClose(window, GL_TRUE); + break; + } +} + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +int main(int argc, char** argv) +{ + GLFWwindow* window; + int iter; + double dt; + double last_update_time; + int frame; + float f; + GLint uloc_modelview; + GLint uloc_project; + + GLuint shader_program; + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); + + window = glfwCreateWindow(800, 600, "GLFW OpenGL3 Heightmap demo", NULL, NULL); + if (! window ) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + /* Register events callback */ + glfwSetKeyCallback(window, key_callback); + + glfwMakeContextCurrent(window); + gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); + + /* Prepare opengl resources for rendering */ + shader_program = make_shader_program(vertex_shader_text, fragment_shader_text); + + if (shader_program == 0u) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glUseProgram(shader_program); + uloc_project = glGetUniformLocation(shader_program, "project"); + uloc_modelview = glGetUniformLocation(shader_program, "modelview"); + + /* Compute the projection matrix */ + f = 1.0f / tanf(view_angle / 2.0f); + projection_matrix[0] = f / aspect_ratio; + projection_matrix[5] = f; + projection_matrix[10] = (z_far + z_near)/ (z_near - z_far); + projection_matrix[11] = -1.0f; + projection_matrix[14] = 2.0f * (z_far * z_near) / (z_near - z_far); + glUniformMatrix4fv(uloc_project, 1, GL_FALSE, projection_matrix); + + /* Set the camera position */ + modelview_matrix[12] = -5.0f; + modelview_matrix[13] = -5.0f; + modelview_matrix[14] = -20.0f; + glUniformMatrix4fv(uloc_modelview, 1, GL_FALSE, modelview_matrix); + + /* Create mesh data */ + init_map(); + make_mesh(shader_program); + + /* Create vao + vbo to store the mesh */ + /* Create the vbo to store all the information for the grid and the height */ + + /* setup the scene ready for rendering */ + glViewport(0, 0, 800, 600); + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + + /* main loop */ + frame = 0; + iter = 0; + last_update_time = glfwGetTime(); + + while (!glfwWindowShouldClose(window)) + { + ++frame; + /* render the next frame */ + glClear(GL_COLOR_BUFFER_BIT); + glDrawElements(GL_LINES, 2* MAP_NUM_LINES , GL_UNSIGNED_INT, 0); + + /* display and process events through callbacks */ + glfwSwapBuffers(window); + glfwPollEvents(); + /* Check the frame rate and update the heightmap if needed */ + dt = glfwGetTime(); + if ((dt - last_update_time) > 0.2) + { + /* generate the next iteration of the heightmap */ + if (iter < MAX_ITER) + { + update_map(NUM_ITER_AT_A_TIME); + update_mesh(); + iter += NUM_ITER_AT_A_TIME; + } + last_update_time = dt; + frame = 0; + } + } + + glfwTerminate(); + exit(EXIT_SUCCESS); +} + diff --git a/testbed/glfw/examples/particles.c b/testbed/glfw/examples/particles.c new file mode 100644 index 00000000..dc9e9fc8 --- /dev/null +++ b/testbed/glfw/examples/particles.c @@ -0,0 +1,1061 @@ +//======================================================================== +// A simple particle engine with threaded physics +// Copyright (c) Marcus Geelnard +// Copyright (c) Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include +#include +#include +#include +#include + +#include +#include + +#define GLFW_INCLUDE_GLU +#include + +// Define tokens for GL_EXT_separate_specular_color if not already defined +#ifndef GL_EXT_separate_specular_color +#define GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8 +#define GL_SINGLE_COLOR_EXT 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA +#endif // GL_EXT_separate_specular_color + +// Some 's do not define M_PI +#ifndef M_PI +#define M_PI 3.141592654 +#endif + + +//======================================================================== +// Type definitions +//======================================================================== + +typedef struct +{ + float x, y, z; +} Vec3; + +// This structure is used for interleaved vertex arrays (see the +// draw_particles function) +// +// NOTE: This structure SHOULD be packed on most systems. It uses 32-bit fields +// on 32-bit boundaries, and is a multiple of 64 bits in total (6x32=3x64). If +// it does not work, try using pragmas or whatever to force the structure to be +// packed. +typedef struct +{ + GLfloat s, t; // Texture coordinates + GLuint rgba; // Color (four ubytes packed into an uint) + GLfloat x, y, z; // Vertex coordinates +} Vertex; + + +//======================================================================== +// Program control global variables +//======================================================================== + +// Window dimensions +float aspect_ratio; + +// "wireframe" flag (true if we use wireframe view) +int wireframe; + +// Thread synchronization +struct { + double t; // Time (s) + float dt; // Time since last frame (s) + int p_frame; // Particle physics frame number + int d_frame; // Particle draw frame number + cnd_t p_done; // Condition: particle physics done + cnd_t d_done; // Condition: particle draw done + mtx_t particles_lock; // Particles data sharing mutex +} thread_sync; + + +//======================================================================== +// Texture declarations (we hard-code them into the source code, since +// they are so simple) +//======================================================================== + +#define P_TEX_WIDTH 8 // Particle texture dimensions +#define P_TEX_HEIGHT 8 +#define F_TEX_WIDTH 16 // Floor texture dimensions +#define F_TEX_HEIGHT 16 + +// Texture object IDs +GLuint particle_tex_id, floor_tex_id; + +// Particle texture (a simple spot) +const unsigned char particle_texture[ P_TEX_WIDTH * P_TEX_HEIGHT ] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x11, 0x22, 0x22, 0x11, 0x00, 0x00, + 0x00, 0x11, 0x33, 0x88, 0x77, 0x33, 0x11, 0x00, + 0x00, 0x22, 0x88, 0xff, 0xee, 0x77, 0x22, 0x00, + 0x00, 0x22, 0x77, 0xee, 0xff, 0x88, 0x22, 0x00, + 0x00, 0x11, 0x33, 0x77, 0x88, 0x33, 0x11, 0x00, + 0x00, 0x00, 0x11, 0x33, 0x22, 0x11, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +// Floor texture (your basic checkered floor) +const unsigned char floor_texture[ F_TEX_WIDTH * F_TEX_HEIGHT ] = { + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0xff, 0xf0, 0xcc, 0xf0, 0xf0, 0xf0, 0xff, 0xf0, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0xf0, 0xcc, 0xee, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 0x30, 0x66, 0x30, 0x30, 0x30, 0x20, 0x30, 0x30, + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xee, 0xf0, 0xf0, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0xf0, 0xf0, 0xf0, 0xf0, 0xcc, 0xf0, 0xf0, 0xf0, 0x30, 0x30, 0x55, 0x30, 0x30, 0x44, 0x30, 0x30, + 0xf0, 0xdd, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0x33, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xff, 0xf0, 0xf0, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x60, 0x30, + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0x33, 0x33, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, 0x30, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x20, 0x30, 0x30, 0xf0, 0xff, 0xf0, 0xf0, 0xdd, 0xf0, 0xf0, 0xff, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x55, 0x33, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xff, 0xf0, 0xf0, + 0x30, 0x44, 0x66, 0x30, 0x30, 0x30, 0x30, 0x30, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0xf0, 0xf0, 0xf0, 0xaa, 0xf0, 0xf0, 0xcc, 0xf0, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0xff, 0xf0, 0xf0, 0xf0, 0xff, 0xf0, 0xdd, 0xf0, + 0x30, 0x30, 0x30, 0x77, 0x30, 0x30, 0x30, 0x30, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, +}; + + +//======================================================================== +// These are fixed constants that control the particle engine. In a +// modular world, these values should be variables... +//======================================================================== + +// Maximum number of particles +#define MAX_PARTICLES 3000 + +// Life span of a particle (in seconds) +#define LIFE_SPAN 8.f + +// A new particle is born every [BIRTH_INTERVAL] second +#define BIRTH_INTERVAL (LIFE_SPAN/(float)MAX_PARTICLES) + +// Particle size (meters) +#define PARTICLE_SIZE 0.7f + +// Gravitational constant (m/s^2) +#define GRAVITY 9.8f + +// Base initial velocity (m/s) +#define VELOCITY 8.f + +// Bounce friction (1.0 = no friction, 0.0 = maximum friction) +#define FRICTION 0.75f + +// "Fountain" height (m) +#define FOUNTAIN_HEIGHT 3.f + +// Fountain radius (m) +#define FOUNTAIN_RADIUS 1.6f + +// Minimum delta-time for particle phisics (s) +#define MIN_DELTA_T (BIRTH_INTERVAL * 0.5f) + + +//======================================================================== +// Particle system global variables +//======================================================================== + +// This structure holds all state for a single particle +typedef struct { + float x,y,z; // Position in space + float vx,vy,vz; // Velocity vector + float r,g,b; // Color of particle + float life; // Life of particle (1.0 = newborn, < 0.0 = dead) + int active; // Tells if this particle is active +} PARTICLE; + +// Global vectors holding all particles. We use two vectors for double +// buffering. +static PARTICLE particles[MAX_PARTICLES]; + +// Global variable holding the age of the youngest particle +static float min_age; + +// Color of latest born particle (used for fountain lighting) +static float glow_color[4]; + +// Position of latest born particle (used for fountain lighting) +static float glow_pos[4]; + + +//======================================================================== +// Object material and fog configuration constants +//======================================================================== + +const GLfloat fountain_diffuse[4] = { 0.7f, 1.f, 1.f, 1.f }; +const GLfloat fountain_specular[4] = { 1.f, 1.f, 1.f, 1.f }; +const GLfloat fountain_shininess = 12.f; +const GLfloat floor_diffuse[4] = { 1.f, 0.6f, 0.6f, 1.f }; +const GLfloat floor_specular[4] = { 0.6f, 0.6f, 0.6f, 1.f }; +const GLfloat floor_shininess = 18.f; +const GLfloat fog_color[4] = { 0.1f, 0.1f, 0.1f, 1.f }; + + +//======================================================================== +// Print usage information +//======================================================================== + +static void usage(void) +{ + printf("Usage: particles [-bfhs]\n"); + printf("Options:\n"); + printf(" -f Run in full screen\n"); + printf(" -h Display this help\n"); + printf(" -s Run program as single thread (default is to use two threads)\n"); + printf("\n"); + printf("Program runtime controls:\n"); + printf(" W Toggle wireframe mode\n"); + printf(" Esc Exit program\n"); +} + + +//======================================================================== +// Initialize a new particle +//======================================================================== + +static void init_particle(PARTICLE *p, double t) +{ + float xy_angle, velocity; + + // Start position of particle is at the fountain blow-out + p->x = 0.f; + p->y = 0.f; + p->z = FOUNTAIN_HEIGHT; + + // Start velocity is up (Z)... + p->vz = 0.7f + (0.3f / 4096.f) * (float) (rand() & 4095); + + // ...and a randomly chosen X/Y direction + xy_angle = (2.f * (float) M_PI / 4096.f) * (float) (rand() & 4095); + p->vx = 0.4f * (float) cos(xy_angle); + p->vy = 0.4f * (float) sin(xy_angle); + + // Scale velocity vector according to a time-varying velocity + velocity = VELOCITY * (0.8f + 0.1f * (float) (sin(0.5 * t) + sin(1.31 * t))); + p->vx *= velocity; + p->vy *= velocity; + p->vz *= velocity; + + // Color is time-varying + p->r = 0.7f + 0.3f * (float) sin(0.34 * t + 0.1); + p->g = 0.6f + 0.4f * (float) sin(0.63 * t + 1.1); + p->b = 0.6f + 0.4f * (float) sin(0.91 * t + 2.1); + + // Store settings for fountain glow lighting + glow_pos[0] = 0.4f * (float) sin(1.34 * t); + glow_pos[1] = 0.4f * (float) sin(3.11 * t); + glow_pos[2] = FOUNTAIN_HEIGHT + 1.f; + glow_pos[3] = 1.f; + glow_color[0] = p->r; + glow_color[1] = p->g; + glow_color[2] = p->b; + glow_color[3] = 1.f; + + // The particle is new-born and active + p->life = 1.f; + p->active = 1; +} + + +//======================================================================== +// Update a particle +//======================================================================== + +#define FOUNTAIN_R2 (FOUNTAIN_RADIUS+PARTICLE_SIZE/2)*(FOUNTAIN_RADIUS+PARTICLE_SIZE/2) + +static void update_particle(PARTICLE *p, float dt) +{ + // If the particle is not active, we need not do anything + if (!p->active) + return; + + // The particle is getting older... + p->life -= dt * (1.f / LIFE_SPAN); + + // Did the particle die? + if (p->life <= 0.f) + { + p->active = 0; + return; + } + + // Apply gravity + p->vz = p->vz - GRAVITY * dt; + + // Update particle position + p->x = p->x + p->vx * dt; + p->y = p->y + p->vy * dt; + p->z = p->z + p->vz * dt; + + // Simple collision detection + response + if (p->vz < 0.f) + { + // Particles should bounce on the fountain (with friction) + if ((p->x * p->x + p->y * p->y) < FOUNTAIN_R2 && + p->z < (FOUNTAIN_HEIGHT + PARTICLE_SIZE / 2)) + { + p->vz = -FRICTION * p->vz; + p->z = FOUNTAIN_HEIGHT + PARTICLE_SIZE / 2 + + FRICTION * (FOUNTAIN_HEIGHT + + PARTICLE_SIZE / 2 - p->z); + } + + // Particles should bounce on the floor (with friction) + else if (p->z < PARTICLE_SIZE / 2) + { + p->vz = -FRICTION * p->vz; + p->z = PARTICLE_SIZE / 2 + + FRICTION * (PARTICLE_SIZE / 2 - p->z); + } + } +} + + +//======================================================================== +// The main frame for the particle engine. Called once per frame. +//======================================================================== + +static void particle_engine(double t, float dt) +{ + int i; + float dt2; + + // Update particles (iterated several times per frame if dt is too large) + while (dt > 0.f) + { + // Calculate delta time for this iteration + dt2 = dt < MIN_DELTA_T ? dt : MIN_DELTA_T; + + for (i = 0; i < MAX_PARTICLES; i++) + update_particle(&particles[i], dt2); + + min_age += dt2; + + // Should we create any new particle(s)? + while (min_age >= BIRTH_INTERVAL) + { + min_age -= BIRTH_INTERVAL; + + // Find a dead particle to replace with a new one + for (i = 0; i < MAX_PARTICLES; i++) + { + if (!particles[i].active) + { + init_particle(&particles[i], t + min_age); + update_particle(&particles[i], min_age); + break; + } + } + } + + dt -= dt2; + } +} + + +//======================================================================== +// Draw all active particles. We use OpenGL 1.1 vertex +// arrays for this in order to accelerate the drawing. +//======================================================================== + +#define BATCH_PARTICLES 70 // Number of particles to draw in each batch + // (70 corresponds to 7.5 KB = will not blow + // the L1 data cache on most CPUs) +#define PARTICLE_VERTS 4 // Number of vertices per particle + +static void draw_particles(GLFWwindow* window, double t, float dt) +{ + int i, particle_count; + Vertex vertex_array[BATCH_PARTICLES * PARTICLE_VERTS]; + Vertex* vptr; + float alpha; + GLuint rgba; + Vec3 quad_lower_left, quad_lower_right; + GLfloat mat[16]; + PARTICLE* pptr; + + // Here comes the real trick with flat single primitive objects (s.c. + // "billboards"): We must rotate the textured primitive so that it + // always faces the viewer (is coplanar with the view-plane). + // We: + // 1) Create the primitive around origo (0,0,0) + // 2) Rotate it so that it is coplanar with the view plane + // 3) Translate it according to the particle position + // Note that 1) and 2) is the same for all particles (done only once). + + // Get modelview matrix. We will only use the upper left 3x3 part of + // the matrix, which represents the rotation. + glGetFloatv(GL_MODELVIEW_MATRIX, mat); + + // 1) & 2) We do it in one swift step: + // Although not obvious, the following six lines represent two matrix/ + // vector multiplications. The matrix is the inverse 3x3 rotation + // matrix (i.e. the transpose of the same matrix), and the two vectors + // represent the lower left corner of the quad, PARTICLE_SIZE/2 * + // (-1,-1,0), and the lower right corner, PARTICLE_SIZE/2 * (1,-1,0). + // The upper left/right corners of the quad is always the negative of + // the opposite corners (regardless of rotation). + quad_lower_left.x = (-PARTICLE_SIZE / 2) * (mat[0] + mat[1]); + quad_lower_left.y = (-PARTICLE_SIZE / 2) * (mat[4] + mat[5]); + quad_lower_left.z = (-PARTICLE_SIZE / 2) * (mat[8] + mat[9]); + quad_lower_right.x = (PARTICLE_SIZE / 2) * (mat[0] - mat[1]); + quad_lower_right.y = (PARTICLE_SIZE / 2) * (mat[4] - mat[5]); + quad_lower_right.z = (PARTICLE_SIZE / 2) * (mat[8] - mat[9]); + + // Don't update z-buffer, since all particles are transparent! + glDepthMask(GL_FALSE); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + + // Select particle texture + if (!wireframe) + { + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, particle_tex_id); + } + + // Set up vertex arrays. We use interleaved arrays, which is easier to + // handle (in most situations) and it gives a linear memeory access + // access pattern (which may give better performance in some + // situations). GL_T2F_C4UB_V3F means: 2 floats for texture coords, + // 4 ubytes for color and 3 floats for vertex coord (in that order). + // Most OpenGL cards / drivers are optimized for this format. + glInterleavedArrays(GL_T2F_C4UB_V3F, 0, vertex_array); + + // Wait for particle physics thread to be done + mtx_lock(&thread_sync.particles_lock); + while (!glfwWindowShouldClose(window) && + thread_sync.p_frame <= thread_sync.d_frame) + { + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + ts.tv_nsec += 100000000; + cnd_timedwait(&thread_sync.p_done, &thread_sync.particles_lock, &ts); + } + + // Store the frame time and delta time for the physics thread + thread_sync.t = t; + thread_sync.dt = dt; + + // Update frame counter + thread_sync.d_frame++; + + // Loop through all particles and build vertex arrays. + particle_count = 0; + vptr = vertex_array; + pptr = particles; + + for (i = 0; i < MAX_PARTICLES; i++) + { + if (pptr->active) + { + // Calculate particle intensity (we set it to max during 75% + // of its life, then it fades out) + alpha = 4.f * pptr->life; + if (alpha > 1.f) + alpha = 1.f; + + // Convert color from float to 8-bit (store it in a 32-bit + // integer using endian independent type casting) + ((GLubyte*) &rgba)[0] = (GLubyte)(pptr->r * 255.f); + ((GLubyte*) &rgba)[1] = (GLubyte)(pptr->g * 255.f); + ((GLubyte*) &rgba)[2] = (GLubyte)(pptr->b * 255.f); + ((GLubyte*) &rgba)[3] = (GLubyte)(alpha * 255.f); + + // 3) Translate the quad to the correct position in modelview + // space and store its parameters in vertex arrays (we also + // store texture coord and color information for each vertex). + + // Lower left corner + vptr->s = 0.f; + vptr->t = 0.f; + vptr->rgba = rgba; + vptr->x = pptr->x + quad_lower_left.x; + vptr->y = pptr->y + quad_lower_left.y; + vptr->z = pptr->z + quad_lower_left.z; + vptr ++; + + // Lower right corner + vptr->s = 1.f; + vptr->t = 0.f; + vptr->rgba = rgba; + vptr->x = pptr->x + quad_lower_right.x; + vptr->y = pptr->y + quad_lower_right.y; + vptr->z = pptr->z + quad_lower_right.z; + vptr ++; + + // Upper right corner + vptr->s = 1.f; + vptr->t = 1.f; + vptr->rgba = rgba; + vptr->x = pptr->x - quad_lower_left.x; + vptr->y = pptr->y - quad_lower_left.y; + vptr->z = pptr->z - quad_lower_left.z; + vptr ++; + + // Upper left corner + vptr->s = 0.f; + vptr->t = 1.f; + vptr->rgba = rgba; + vptr->x = pptr->x - quad_lower_right.x; + vptr->y = pptr->y - quad_lower_right.y; + vptr->z = pptr->z - quad_lower_right.z; + vptr ++; + + // Increase count of drawable particles + particle_count ++; + } + + // If we have filled up one batch of particles, draw it as a set + // of quads using glDrawArrays. + if (particle_count >= BATCH_PARTICLES) + { + // The first argument tells which primitive type we use (QUAD) + // The second argument tells the index of the first vertex (0) + // The last argument is the vertex count + glDrawArrays(GL_QUADS, 0, PARTICLE_VERTS * particle_count); + particle_count = 0; + vptr = vertex_array; + } + + // Next particle + pptr++; + } + + // We are done with the particle data + mtx_unlock(&thread_sync.particles_lock); + cnd_signal(&thread_sync.d_done); + + // Draw final batch of particles (if any) + glDrawArrays(GL_QUADS, 0, PARTICLE_VERTS * particle_count); + + // Disable vertex arrays (Note: glInterleavedArrays implicitly called + // glEnableClientState for vertex, texture coord and color arrays) + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + + glDisable(GL_TEXTURE_2D); + glDisable(GL_BLEND); + + glDepthMask(GL_TRUE); +} + + +//======================================================================== +// Fountain geometry specification +//======================================================================== + +#define FOUNTAIN_SIDE_POINTS 14 +#define FOUNTAIN_SWEEP_STEPS 32 + +static const float fountain_side[FOUNTAIN_SIDE_POINTS * 2] = +{ + 1.2f, 0.f, 1.f, 0.2f, 0.41f, 0.3f, 0.4f, 0.35f, + 0.4f, 1.95f, 0.41f, 2.f, 0.8f, 2.2f, 1.2f, 2.4f, + 1.5f, 2.7f, 1.55f,2.95f, 1.6f, 3.f, 1.f, 3.f, + 0.5f, 3.f, 0.f, 3.f +}; + +static const float fountain_normal[FOUNTAIN_SIDE_POINTS * 2] = +{ + 1.0000f, 0.0000f, 0.6428f, 0.7660f, 0.3420f, 0.9397f, 1.0000f, 0.0000f, + 1.0000f, 0.0000f, 0.3420f,-0.9397f, 0.4226f,-0.9063f, 0.5000f,-0.8660f, + 0.7660f,-0.6428f, 0.9063f,-0.4226f, 0.0000f,1.00000f, 0.0000f,1.00000f, + 0.0000f,1.00000f, 0.0000f,1.00000f +}; + + +//======================================================================== +// Draw a fountain +//======================================================================== + +static void draw_fountain(void) +{ + static GLuint fountain_list = 0; + double angle; + float x, y; + int m, n; + + // The first time, we build the fountain display list + if (!fountain_list) + { + fountain_list = glGenLists(1); + glNewList(fountain_list, GL_COMPILE_AND_EXECUTE); + + glMaterialfv(GL_FRONT, GL_DIFFUSE, fountain_diffuse); + glMaterialfv(GL_FRONT, GL_SPECULAR, fountain_specular); + glMaterialf(GL_FRONT, GL_SHININESS, fountain_shininess); + + // Build fountain using triangle strips + for (n = 0; n < FOUNTAIN_SIDE_POINTS - 1; n++) + { + glBegin(GL_TRIANGLE_STRIP); + for (m = 0; m <= FOUNTAIN_SWEEP_STEPS; m++) + { + angle = (double) m * (2.0 * M_PI / (double) FOUNTAIN_SWEEP_STEPS); + x = (float) cos(angle); + y = (float) sin(angle); + + // Draw triangle strip + glNormal3f(x * fountain_normal[n * 2 + 2], + y * fountain_normal[n * 2 + 2], + fountain_normal[n * 2 + 3]); + glVertex3f(x * fountain_side[n * 2 + 2], + y * fountain_side[n * 2 + 2], + fountain_side[n * 2 +3 ]); + glNormal3f(x * fountain_normal[n * 2], + y * fountain_normal[n * 2], + fountain_normal[n * 2 + 1]); + glVertex3f(x * fountain_side[n * 2], + y * fountain_side[n * 2], + fountain_side[n * 2 + 1]); + } + + glEnd(); + } + + glEndList(); + } + else + glCallList(fountain_list); +} + + +//======================================================================== +// Recursive function for building variable tesselated floor +//======================================================================== + +static void tessellate_floor(float x1, float y1, float x2, float y2, int depth) +{ + float delta, x, y; + + // Last recursion? + if (depth >= 5) + delta = 999999.f; + else + { + x = (float) (fabs(x1) < fabs(x2) ? fabs(x1) : fabs(x2)); + y = (float) (fabs(y1) < fabs(y2) ? fabs(y1) : fabs(y2)); + delta = x*x + y*y; + } + + // Recurse further? + if (delta < 0.1f) + { + x = (x1 + x2) * 0.5f; + y = (y1 + y2) * 0.5f; + tessellate_floor(x1, y1, x, y, depth + 1); + tessellate_floor(x, y1, x2, y, depth + 1); + tessellate_floor(x1, y, x, y2, depth + 1); + tessellate_floor(x, y, x2, y2, depth + 1); + } + else + { + glTexCoord2f(x1 * 30.f, y1 * 30.f); + glVertex3f( x1 * 80.f, y1 * 80.f, 0.f); + glTexCoord2f(x2 * 30.f, y1 * 30.f); + glVertex3f( x2 * 80.f, y1 * 80.f, 0.f); + glTexCoord2f(x2 * 30.f, y2 * 30.f); + glVertex3f( x2 * 80.f, y2 * 80.f, 0.f); + glTexCoord2f(x1 * 30.f, y2 * 30.f); + glVertex3f( x1 * 80.f, y2 * 80.f, 0.f); + } +} + + +//======================================================================== +// Draw floor. We build the floor recursively and let the tessellation in the +// center (near x,y=0,0) be high, while the tessellation around the edges be +// low. +//======================================================================== + +static void draw_floor(void) +{ + static GLuint floor_list = 0; + + if (!wireframe) + { + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, floor_tex_id); + } + + // The first time, we build the floor display list + if (!floor_list) + { + floor_list = glGenLists(1); + glNewList(floor_list, GL_COMPILE_AND_EXECUTE); + + glMaterialfv(GL_FRONT, GL_DIFFUSE, floor_diffuse); + glMaterialfv(GL_FRONT, GL_SPECULAR, floor_specular); + glMaterialf(GL_FRONT, GL_SHININESS, floor_shininess); + + // Draw floor as a bunch of triangle strips (high tesselation + // improves lighting) + glNormal3f(0.f, 0.f, 1.f); + glBegin(GL_QUADS); + tessellate_floor(-1.f, -1.f, 0.f, 0.f, 0); + tessellate_floor( 0.f, -1.f, 1.f, 0.f, 0); + tessellate_floor( 0.f, 0.f, 1.f, 1.f, 0); + tessellate_floor(-1.f, 0.f, 0.f, 1.f, 0); + glEnd(); + + glEndList(); + } + else + glCallList(floor_list); + + glDisable(GL_TEXTURE_2D); + +} + + +//======================================================================== +// Position and configure light sources +//======================================================================== + +static void setup_lights(void) +{ + float l1pos[4], l1amb[4], l1dif[4], l1spec[4]; + float l2pos[4], l2amb[4], l2dif[4], l2spec[4]; + + // Set light source 1 parameters + l1pos[0] = 0.f; l1pos[1] = -9.f; l1pos[2] = 8.f; l1pos[3] = 1.f; + l1amb[0] = 0.2f; l1amb[1] = 0.2f; l1amb[2] = 0.2f; l1amb[3] = 1.f; + l1dif[0] = 0.8f; l1dif[1] = 0.4f; l1dif[2] = 0.2f; l1dif[3] = 1.f; + l1spec[0] = 1.f; l1spec[1] = 0.6f; l1spec[2] = 0.2f; l1spec[3] = 0.f; + + // Set light source 2 parameters + l2pos[0] = -15.f; l2pos[1] = 12.f; l2pos[2] = 1.5f; l2pos[3] = 1.f; + l2amb[0] = 0.f; l2amb[1] = 0.f; l2amb[2] = 0.f; l2amb[3] = 1.f; + l2dif[0] = 0.2f; l2dif[1] = 0.4f; l2dif[2] = 0.8f; l2dif[3] = 1.f; + l2spec[0] = 0.2f; l2spec[1] = 0.6f; l2spec[2] = 1.f; l2spec[3] = 0.f; + + glLightfv(GL_LIGHT1, GL_POSITION, l1pos); + glLightfv(GL_LIGHT1, GL_AMBIENT, l1amb); + glLightfv(GL_LIGHT1, GL_DIFFUSE, l1dif); + glLightfv(GL_LIGHT1, GL_SPECULAR, l1spec); + glLightfv(GL_LIGHT2, GL_POSITION, l2pos); + glLightfv(GL_LIGHT2, GL_AMBIENT, l2amb); + glLightfv(GL_LIGHT2, GL_DIFFUSE, l2dif); + glLightfv(GL_LIGHT2, GL_SPECULAR, l2spec); + glLightfv(GL_LIGHT3, GL_POSITION, glow_pos); + glLightfv(GL_LIGHT3, GL_DIFFUSE, glow_color); + glLightfv(GL_LIGHT3, GL_SPECULAR, glow_color); + + glEnable(GL_LIGHT1); + glEnable(GL_LIGHT2); + glEnable(GL_LIGHT3); +} + + +//======================================================================== +// Main rendering function +//======================================================================== + +static void draw_scene(GLFWwindow* window, double t) +{ + double xpos, ypos, zpos, angle_x, angle_y, angle_z; + static double t_old = 0.0; + float dt; + + // Calculate frame-to-frame delta time + dt = (float) (t - t_old); + t_old = t; + + glClearColor(0.1f, 0.1f, 0.1f, 1.f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(65.0, aspect_ratio, 1.0, 60.0); + + // Setup camera + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + // Rotate camera + angle_x = 90.0 - 10.0; + angle_y = 10.0 * sin(0.3 * t); + angle_z = 10.0 * t; + glRotated(-angle_x, 1.0, 0.0, 0.0); + glRotated(-angle_y, 0.0, 1.0, 0.0); + glRotated(-angle_z, 0.0, 0.0, 1.0); + + // Translate camera + xpos = 15.0 * sin((M_PI / 180.0) * angle_z) + + 2.0 * sin((M_PI / 180.0) * 3.1 * t); + ypos = -15.0 * cos((M_PI / 180.0) * angle_z) + + 2.0 * cos((M_PI / 180.0) * 2.9 * t); + zpos = 4.0 + 2.0 * cos((M_PI / 180.0) * 4.9 * t); + glTranslated(-xpos, -ypos, -zpos); + + glFrontFace(GL_CCW); + glCullFace(GL_BACK); + glEnable(GL_CULL_FACE); + + setup_lights(); + glEnable(GL_LIGHTING); + + glEnable(GL_FOG); + glFogi(GL_FOG_MODE, GL_EXP); + glFogf(GL_FOG_DENSITY, 0.05f); + glFogfv(GL_FOG_COLOR, fog_color); + + draw_floor(); + + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LEQUAL); + glDepthMask(GL_TRUE); + + draw_fountain(); + + glDisable(GL_LIGHTING); + glDisable(GL_FOG); + + // Particles must be drawn after all solid objects have been drawn + draw_particles(window, t, dt); + + // Z-buffer not needed anymore + glDisable(GL_DEPTH_TEST); +} + + +//======================================================================== +// Window resize callback function +//======================================================================== + +static void resize_callback(GLFWwindow* window, int width, int height) +{ + glViewport(0, 0, width, height); + aspect_ratio = height ? width / (float) height : 1.f; +} + + +//======================================================================== +// Key callback functions +//======================================================================== + +static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + if (action == GLFW_PRESS) + { + switch (key) + { + case GLFW_KEY_ESCAPE: + glfwSetWindowShouldClose(window, GL_TRUE); + break; + case GLFW_KEY_W: + wireframe = !wireframe; + glPolygonMode(GL_FRONT_AND_BACK, + wireframe ? GL_LINE : GL_FILL); + break; + default: + break; + } + } +} + + +//======================================================================== +// Thread for updating particle physics +//======================================================================== + +static int physics_thread_main(void* arg) +{ + GLFWwindow* window = arg; + + for (;;) + { + mtx_lock(&thread_sync.particles_lock); + + // Wait for particle drawing to be done + while (!glfwWindowShouldClose(window) && + thread_sync.p_frame > thread_sync.d_frame) + { + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + ts.tv_nsec += 100000000; + cnd_timedwait(&thread_sync.d_done, &thread_sync.particles_lock, &ts); + } + + if (glfwWindowShouldClose(window)) + break; + + // Update particles + particle_engine(thread_sync.t, thread_sync.dt); + + // Update frame counter + thread_sync.p_frame++; + + // Unlock mutex and signal drawing thread + mtx_unlock(&thread_sync.particles_lock); + cnd_signal(&thread_sync.p_done); + } + + return 0; +} + + +//======================================================================== +// main +//======================================================================== + +int main(int argc, char** argv) +{ + int ch, width, height; + thrd_t physics_thread = 0; + GLFWwindow* window; + GLFWmonitor* monitor = NULL; + + if (!glfwInit()) + { + fprintf(stderr, "Failed to initialize GLFW\n"); + exit(EXIT_FAILURE); + } + + while ((ch = getopt(argc, argv, "fh")) != -1) + { + switch (ch) + { + case 'f': + monitor = glfwGetPrimaryMonitor(); + break; + case 'h': + usage(); + exit(EXIT_SUCCESS); + } + } + + if (monitor) + { + const GLFWvidmode* mode = glfwGetVideoMode(monitor); + + glfwWindowHint(GLFW_RED_BITS, mode->redBits); + glfwWindowHint(GLFW_GREEN_BITS, mode->greenBits); + glfwWindowHint(GLFW_BLUE_BITS, mode->blueBits); + glfwWindowHint(GLFW_REFRESH_RATE, mode->refreshRate); + + width = mode->width; + height = mode->height; + } + else + { + width = 640; + height = 480; + } + + window = glfwCreateWindow(width, height, "Particle Engine", monitor, NULL); + if (!window) + { + fprintf(stderr, "Failed to create GLFW window\n"); + glfwTerminate(); + exit(EXIT_FAILURE); + } + + if (monitor) + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + + glfwMakeContextCurrent(window); + glfwSwapInterval(1); + + glfwSetWindowSizeCallback(window, resize_callback); + glfwSetKeyCallback(window, key_callback); + + // Set initial aspect ratio + glfwGetWindowSize(window, &width, &height); + resize_callback(window, width, height); + + // Upload particle texture + glGenTextures(1, &particle_tex_id); + glBindTexture(GL_TEXTURE_2D, particle_tex_id); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, P_TEX_WIDTH, P_TEX_HEIGHT, + 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, particle_texture); + + // Upload floor texture + glGenTextures(1, &floor_tex_id); + glBindTexture(GL_TEXTURE_2D, floor_tex_id); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, F_TEX_WIDTH, F_TEX_HEIGHT, + 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, floor_texture); + + if (glfwExtensionSupported("GL_EXT_separate_specular_color")) + { + glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL_EXT, + GL_SEPARATE_SPECULAR_COLOR_EXT); + } + + // Set filled polygon mode as default (not wireframe) + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + wireframe = 0; + + // Set initial times + thread_sync.t = 0.0; + thread_sync.dt = 0.001f; + thread_sync.p_frame = 0; + thread_sync.d_frame = 0; + + mtx_init(&thread_sync.particles_lock, mtx_timed); + cnd_init(&thread_sync.p_done); + cnd_init(&thread_sync.d_done); + + if (thrd_create(&physics_thread, physics_thread_main, window) != thrd_success) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glfwSetTime(0.0); + + while (!glfwWindowShouldClose(window)) + { + draw_scene(window, glfwGetTime()); + + glfwSwapBuffers(window); + glfwPollEvents(); + } + + thrd_join(physics_thread, NULL); + + glfwDestroyWindow(window); + glfwTerminate(); + + exit(EXIT_SUCCESS); +} + diff --git a/testbed/glfw/examples/simple.c b/testbed/glfw/examples/simple.c new file mode 100644 index 00000000..c39be574 --- /dev/null +++ b/testbed/glfw/examples/simple.c @@ -0,0 +1,102 @@ +//======================================================================== +// Simple GLFW example +// Copyright (c) Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== +//! [code] + +#include + +#include +#include + +static void error_callback(int error, const char* description) +{ + fputs(description, stderr); +} + +static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) + glfwSetWindowShouldClose(window, GL_TRUE); +} + +int main(void) +{ + GLFWwindow* window; + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + window = glfwCreateWindow(640, 480, "Simple example", NULL, NULL); + if (!window) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glfwMakeContextCurrent(window); + glfwSwapInterval(1); + + glfwSetKeyCallback(window, key_callback); + + while (!glfwWindowShouldClose(window)) + { + float ratio; + int width, height; + + glfwGetFramebufferSize(window, &width, &height); + ratio = width / (float) height; + + glViewport(0, 0, width, height); + glClear(GL_COLOR_BUFFER_BIT); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-ratio, ratio, -1.f, 1.f, 1.f, -1.f); + glMatrixMode(GL_MODELVIEW); + + glLoadIdentity(); + glRotatef((float) glfwGetTime() * 50.f, 0.f, 0.f, 1.f); + + glBegin(GL_TRIANGLES); + glColor3f(1.f, 0.f, 0.f); + glVertex3f(-0.6f, -0.4f, 0.f); + glColor3f(0.f, 1.f, 0.f); + glVertex3f(0.6f, -0.4f, 0.f); + glColor3f(0.f, 0.f, 1.f); + glVertex3f(0.f, 0.6f, 0.f); + glEnd(); + + glfwSwapBuffers(window); + glfwPollEvents(); + } + + glfwDestroyWindow(window); + + glfwTerminate(); + exit(EXIT_SUCCESS); +} + +//! [code] diff --git a/testbed/glfw/examples/splitview.c b/testbed/glfw/examples/splitview.c new file mode 100644 index 00000000..30b093b1 --- /dev/null +++ b/testbed/glfw/examples/splitview.c @@ -0,0 +1,511 @@ +//======================================================================== +// This is an example program for the GLFW library +// +// The program uses a "split window" view, rendering four views of the +// same scene in one window (e.g. uesful for 3D modelling software). This +// demo uses scissors to separete the four different rendering areas from +// each other. +// +// (If the code seems a little bit strange here and there, it may be +// because I am not a friend of orthogonal projections) +//======================================================================== + +#define GLFW_INCLUDE_GLU +#include + +#include +#include +#include + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + + +//======================================================================== +// Global variables +//======================================================================== + +// Mouse position +static double xpos = 0, ypos = 0; + +// Window size +static int width, height; + +// Active view: 0 = none, 1 = upper left, 2 = upper right, 3 = lower left, +// 4 = lower right +static int active_view = 0; + +// Rotation around each axis +static int rot_x = 0, rot_y = 0, rot_z = 0; + +// Do redraw? +static int do_redraw = 1; + + +//======================================================================== +// Draw a solid torus (use a display list for the model) +//======================================================================== + +#define TORUS_MAJOR 1.5 +#define TORUS_MINOR 0.5 +#define TORUS_MAJOR_RES 32 +#define TORUS_MINOR_RES 32 + +static void drawTorus(void) +{ + static GLuint torus_list = 0; + int i, j, k; + double s, t, x, y, z, nx, ny, nz, scale, twopi; + + if (!torus_list) + { + // Start recording displaylist + torus_list = glGenLists(1); + glNewList(torus_list, GL_COMPILE_AND_EXECUTE); + + // Draw torus + twopi = 2.0 * M_PI; + for (i = 0; i < TORUS_MINOR_RES; i++) + { + glBegin(GL_QUAD_STRIP); + for (j = 0; j <= TORUS_MAJOR_RES; j++) + { + for (k = 1; k >= 0; k--) + { + s = (i + k) % TORUS_MINOR_RES + 0.5; + t = j % TORUS_MAJOR_RES; + + // Calculate point on surface + x = (TORUS_MAJOR + TORUS_MINOR * cos(s * twopi / TORUS_MINOR_RES)) * cos(t * twopi / TORUS_MAJOR_RES); + y = TORUS_MINOR * sin(s * twopi / TORUS_MINOR_RES); + z = (TORUS_MAJOR + TORUS_MINOR * cos(s * twopi / TORUS_MINOR_RES)) * sin(t * twopi / TORUS_MAJOR_RES); + + // Calculate surface normal + nx = x - TORUS_MAJOR * cos(t * twopi / TORUS_MAJOR_RES); + ny = y; + nz = z - TORUS_MAJOR * sin(t * twopi / TORUS_MAJOR_RES); + scale = 1.0 / sqrt(nx*nx + ny*ny + nz*nz); + nx *= scale; + ny *= scale; + nz *= scale; + + glNormal3f((float) nx, (float) ny, (float) nz); + glVertex3f((float) x, (float) y, (float) z); + } + } + + glEnd(); + } + + // Stop recording displaylist + glEndList(); + } + else + { + // Playback displaylist + glCallList(torus_list); + } +} + + +//======================================================================== +// Draw the scene (a rotating torus) +//======================================================================== + +static void drawScene(void) +{ + const GLfloat model_diffuse[4] = {1.0f, 0.8f, 0.8f, 1.0f}; + const GLfloat model_specular[4] = {0.6f, 0.6f, 0.6f, 1.0f}; + const GLfloat model_shininess = 20.0f; + + glPushMatrix(); + + // Rotate the object + glRotatef((GLfloat) rot_x * 0.5f, 1.0f, 0.0f, 0.0f); + glRotatef((GLfloat) rot_y * 0.5f, 0.0f, 1.0f, 0.0f); + glRotatef((GLfloat) rot_z * 0.5f, 0.0f, 0.0f, 1.0f); + + // Set model color (used for orthogonal views, lighting disabled) + glColor4fv(model_diffuse); + + // Set model material (used for perspective view, lighting enabled) + glMaterialfv(GL_FRONT, GL_DIFFUSE, model_diffuse); + glMaterialfv(GL_FRONT, GL_SPECULAR, model_specular); + glMaterialf(GL_FRONT, GL_SHININESS, model_shininess); + + // Draw torus + drawTorus(); + + glPopMatrix(); +} + + +//======================================================================== +// Draw a 2D grid (used for orthogonal views) +//======================================================================== + +static void drawGrid(float scale, int steps) +{ + int i; + float x, y; + + glPushMatrix(); + + // Set background to some dark bluish grey + glClearColor(0.05f, 0.05f, 0.2f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT); + + // Setup modelview matrix (flat XY view) + glLoadIdentity(); + gluLookAt(0.0, 0.0, 1.0, + 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0); + + // We don't want to update the Z-buffer + glDepthMask(GL_FALSE); + + // Set grid color + glColor3f(0.0f, 0.5f, 0.5f); + + glBegin(GL_LINES); + + // Horizontal lines + x = scale * 0.5f * (float) (steps - 1); + y = -scale * 0.5f * (float) (steps - 1); + for (i = 0; i < steps; i++) + { + glVertex3f(-x, y, 0.0f); + glVertex3f(x, y, 0.0f); + y += scale; + } + + // Vertical lines + x = -scale * 0.5f * (float) (steps - 1); + y = scale * 0.5f * (float) (steps - 1); + for (i = 0; i < steps; i++) + { + glVertex3f(x, -y, 0.0f); + glVertex3f(x, y, 0.0f); + x += scale; + } + + glEnd(); + + // Enable Z-buffer writing again + glDepthMask(GL_TRUE); + + glPopMatrix(); +} + + +//======================================================================== +// Draw all views +//======================================================================== + +static void drawAllViews(void) +{ + const GLfloat light_position[4] = {0.0f, 8.0f, 8.0f, 1.0f}; + const GLfloat light_diffuse[4] = {1.0f, 1.0f, 1.0f, 1.0f}; + const GLfloat light_specular[4] = {1.0f, 1.0f, 1.0f, 1.0f}; + const GLfloat light_ambient[4] = {0.2f, 0.2f, 0.3f, 1.0f}; + double aspect; + + // Calculate aspect of window + if (height > 0) + aspect = (double) width / (double) height; + else + aspect = 1.0; + + // Clear screen + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // Enable scissor test + glEnable(GL_SCISSOR_TEST); + + // Enable depth test + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LEQUAL); + + // ** ORTHOGONAL VIEWS ** + + // For orthogonal views, use wireframe rendering + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + + // Enable line anti-aliasing + glEnable(GL_LINE_SMOOTH); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + // Setup orthogonal projection matrix + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-3.0 * aspect, 3.0 * aspect, -3.0, 3.0, 1.0, 50.0); + + // Upper left view (TOP VIEW) + glViewport(0, height / 2, width / 2, height / 2); + glScissor(0, height / 2, width / 2, height / 2); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + gluLookAt(0.0f, 10.0f, 1e-3f, // Eye-position (above) + 0.0f, 0.0f, 0.0f, // View-point + 0.0f, 1.0f, 0.0f); // Up-vector + drawGrid(0.5, 12); + drawScene(); + + // Lower left view (FRONT VIEW) + glViewport(0, 0, width / 2, height / 2); + glScissor(0, 0, width / 2, height / 2); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + gluLookAt(0.0f, 0.0f, 10.0f, // Eye-position (in front of) + 0.0f, 0.0f, 0.0f, // View-point + 0.0f, 1.0f, 0.0f); // Up-vector + drawGrid(0.5, 12); + drawScene(); + + // Lower right view (SIDE VIEW) + glViewport(width / 2, 0, width / 2, height / 2); + glScissor(width / 2, 0, width / 2, height / 2); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + gluLookAt(10.0f, 0.0f, 0.0f, // Eye-position (to the right) + 0.0f, 0.0f, 0.0f, // View-point + 0.0f, 1.0f, 0.0f); // Up-vector + drawGrid(0.5, 12); + drawScene(); + + // Disable line anti-aliasing + glDisable(GL_LINE_SMOOTH); + glDisable(GL_BLEND); + + // ** PERSPECTIVE VIEW ** + + // For perspective view, use solid rendering + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + + // Enable face culling (faster rendering) + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + glFrontFace(GL_CW); + + // Setup perspective projection matrix + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(65.0f, aspect, 1.0f, 50.0f); + + // Upper right view (PERSPECTIVE VIEW) + glViewport(width / 2, height / 2, width / 2, height / 2); + glScissor(width / 2, height / 2, width / 2, height / 2); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + gluLookAt(3.0f, 1.5f, 3.0f, // Eye-position + 0.0f, 0.0f, 0.0f, // View-point + 0.0f, 1.0f, 0.0f); // Up-vector + + // Configure and enable light source 1 + glLightfv(GL_LIGHT1, GL_POSITION, light_position); + glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient); + glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse); + glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular); + glEnable(GL_LIGHT1); + glEnable(GL_LIGHTING); + + // Draw scene + drawScene(); + + // Disable lighting + glDisable(GL_LIGHTING); + + // Disable face culling + glDisable(GL_CULL_FACE); + + // Disable depth test + glDisable(GL_DEPTH_TEST); + + // Disable scissor test + glDisable(GL_SCISSOR_TEST); + + // Draw a border around the active view + if (active_view > 0 && active_view != 2) + { + glViewport(0, 0, width, height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0.0, 2.0, 0.0, 2.0, 0.0, 1.0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef((GLfloat) ((active_view - 1) & 1), (GLfloat) (1 - (active_view - 1) / 2), 0.0f); + + glColor3f(1.0f, 1.0f, 0.6f); + + glBegin(GL_LINE_STRIP); + glVertex2i(0, 0); + glVertex2i(1, 0); + glVertex2i(1, 1); + glVertex2i(0, 1); + glVertex2i(0, 0); + glEnd(); + } +} + + +//======================================================================== +// Framebuffer size callback function +//======================================================================== + +static void framebufferSizeFun(GLFWwindow* window, int w, int h) +{ + width = w; + height = h > 0 ? h : 1; + do_redraw = 1; +} + + +//======================================================================== +// Window refresh callback function +//======================================================================== + +static void windowRefreshFun(GLFWwindow* window) +{ + do_redraw = 1; +} + + +//======================================================================== +// Mouse position callback function +//======================================================================== + +static void cursorPosFun(GLFWwindow* window, double x, double y) +{ + // Depending on which view was selected, rotate around different axes + switch (active_view) + { + case 1: + rot_x += (int) (y - ypos); + rot_z += (int) (x - xpos); + do_redraw = 1; + break; + case 3: + rot_x += (int) (y - ypos); + rot_y += (int) (x - xpos); + do_redraw = 1; + break; + case 4: + rot_y += (int) (x - xpos); + rot_z += (int) (y - ypos); + do_redraw = 1; + break; + default: + // Do nothing for perspective view, or if no view is selected + break; + } + + // Remember cursor position + xpos = x; + ypos = y; +} + + +//======================================================================== +// Mouse button callback function +//======================================================================== + +static void mouseButtonFun(GLFWwindow* window, int button, int action, int mods) +{ + if ((button == GLFW_MOUSE_BUTTON_LEFT) && action == GLFW_PRESS) + { + // Detect which of the four views was clicked + active_view = 1; + if (xpos >= width / 2) + active_view += 1; + if (ypos >= height / 2) + active_view += 2; + } + else if (button == GLFW_MOUSE_BUTTON_LEFT) + { + // Deselect any previously selected view + active_view = 0; + } + + do_redraw = 1; +} + +static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) + glfwSetWindowShouldClose(window, GL_TRUE); +} + + +//======================================================================== +// main +//======================================================================== + +int main(void) +{ + GLFWwindow* window; + + // Initialise GLFW + if (!glfwInit()) + { + fprintf(stderr, "Failed to initialize GLFW\n"); + exit(EXIT_FAILURE); + } + + // Open OpenGL window + window = glfwCreateWindow(500, 500, "Split view demo", NULL, NULL); + if (!window) + { + fprintf(stderr, "Failed to open GLFW window\n"); + + glfwTerminate(); + exit(EXIT_FAILURE); + } + + // Set callback functions + glfwSetFramebufferSizeCallback(window, framebufferSizeFun); + glfwSetWindowRefreshCallback(window, windowRefreshFun); + glfwSetCursorPosCallback(window, cursorPosFun); + glfwSetMouseButtonCallback(window, mouseButtonFun); + glfwSetKeyCallback(window, key_callback); + + // Enable vsync + glfwMakeContextCurrent(window); + glfwSwapInterval(1); + + glfwGetFramebufferSize(window, &width, &height); + framebufferSizeFun(window, width, height); + + // Main loop + for (;;) + { + // Only redraw if we need to + if (do_redraw) + { + // Draw all views + drawAllViews(); + + // Swap buffers + glfwSwapBuffers(window); + + do_redraw = 0; + } + + // Wait for new events + glfwWaitEvents(); + + // Check if the window should be closed + if (glfwWindowShouldClose(window)) + break; + } + + // Close OpenGL window and terminate GLFW + glfwTerminate(); + + exit(EXIT_SUCCESS); +} + diff --git a/testbed/glfw/examples/wave.c b/testbed/glfw/examples/wave.c new file mode 100644 index 00000000..bafe4652 --- /dev/null +++ b/testbed/glfw/examples/wave.c @@ -0,0 +1,452 @@ +/***************************************************************************** + * Wave Simulation in OpenGL + * (C) 2002 Jakob Thomsen + * http://home.in.tum.de/~thomsen + * Modified for GLFW by Sylvain Hellegouarch - sh@programmationworld.com + * Modified for variable frame rate by Marcus Geelnard + * 2003-Jan-31: Minor cleanups and speedups / MG + * 2010-10-24: Formatting and cleanup - Camilla Berglund + *****************************************************************************/ + +#include +#include +#include + +#define GLFW_INCLUDE_GLU +#include + +#ifndef M_PI + #define M_PI 3.1415926535897932384626433832795 +#endif + +// Maximum delta T to allow for differential calculations +#define MAX_DELTA_T 0.01 + +// Animation speed (10.0 looks good) +#define ANIMATION_SPEED 10.0 + +GLfloat alpha = 210.f, beta = -70.f; +GLfloat zoom = 2.f; + +double cursorX; +double cursorY; + +struct Vertex +{ + GLfloat x, y, z; + GLfloat r, g, b; +}; + +#define GRIDW 50 +#define GRIDH 50 +#define VERTEXNUM (GRIDW*GRIDH) + +#define QUADW (GRIDW - 1) +#define QUADH (GRIDH - 1) +#define QUADNUM (QUADW*QUADH) + +GLuint quad[4 * QUADNUM]; +struct Vertex vertex[VERTEXNUM]; + +/* The grid will look like this: + * + * 3 4 5 + * *---*---* + * | | | + * | 0 | 1 | + * | | | + * *---*---* + * 0 1 2 + */ + +//======================================================================== +// Initialize grid geometry +//======================================================================== + +void init_vertices(void) +{ + int x, y, p; + + // Place the vertices in a grid + for (y = 0; y < GRIDH; y++) + { + for (x = 0; x < GRIDW; x++) + { + p = y * GRIDW + x; + + vertex[p].x = (GLfloat) (x - GRIDW / 2) / (GLfloat) (GRIDW / 2); + vertex[p].y = (GLfloat) (y - GRIDH / 2) / (GLfloat) (GRIDH / 2); + vertex[p].z = 0; + + if ((x % 4 < 2) ^ (y % 4 < 2)) + vertex[p].r = 0.0; + else + vertex[p].r = 1.0; + + vertex[p].g = (GLfloat) y / (GLfloat) GRIDH; + vertex[p].b = 1.f - ((GLfloat) x / (GLfloat) GRIDW + (GLfloat) y / (GLfloat) GRIDH) / 2.f; + } + } + + for (y = 0; y < QUADH; y++) + { + for (x = 0; x < QUADW; x++) + { + p = 4 * (y * QUADW + x); + + quad[p + 0] = y * GRIDW + x; // Some point + quad[p + 1] = y * GRIDW + x + 1; // Neighbor at the right side + quad[p + 2] = (y + 1) * GRIDW + x + 1; // Upper right neighbor + quad[p + 3] = (y + 1) * GRIDW + x; // Upper neighbor + } + } +} + +double dt; +double p[GRIDW][GRIDH]; +double vx[GRIDW][GRIDH], vy[GRIDW][GRIDH]; +double ax[GRIDW][GRIDH], ay[GRIDW][GRIDH]; + +//======================================================================== +// Initialize grid +//======================================================================== + +void init_grid(void) +{ + int x, y; + double dx, dy, d; + + for (y = 0; y < GRIDH; y++) + { + for (x = 0; x < GRIDW; x++) + { + dx = (double) (x - GRIDW / 2); + dy = (double) (y - GRIDH / 2); + d = sqrt(dx * dx + dy * dy); + if (d < 0.1 * (double) (GRIDW / 2)) + { + d = d * 10.0; + p[x][y] = -cos(d * (M_PI / (double)(GRIDW * 4))) * 100.0; + } + else + p[x][y] = 0.0; + + vx[x][y] = 0.0; + vy[x][y] = 0.0; + } + } +} + + +//======================================================================== +// Draw scene +//======================================================================== + +void draw_scene(GLFWwindow* window) +{ + // Clear the color and depth buffers + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // We don't want to modify the projection matrix + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + // Move back + glTranslatef(0.0, 0.0, -zoom); + // Rotate the view + glRotatef(beta, 1.0, 0.0, 0.0); + glRotatef(alpha, 0.0, 0.0, 1.0); + + glDrawElements(GL_QUADS, 4 * QUADNUM, GL_UNSIGNED_INT, quad); + + glfwSwapBuffers(window); +} + + +//======================================================================== +// Initialize Miscellaneous OpenGL state +//======================================================================== + +void init_opengl(void) +{ + // Use Gouraud (smooth) shading + glShadeModel(GL_SMOOTH); + + // Switch on the z-buffer + glEnable(GL_DEPTH_TEST); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glVertexPointer(3, GL_FLOAT, sizeof(struct Vertex), vertex); + glColorPointer(3, GL_FLOAT, sizeof(struct Vertex), &vertex[0].r); // Pointer to the first color + + glPointSize(2.0); + + // Background color is black + glClearColor(0, 0, 0, 0); +} + + +//======================================================================== +// Modify the height of each vertex according to the pressure +//======================================================================== + +void adjust_grid(void) +{ + int pos; + int x, y; + + for (y = 0; y < GRIDH; y++) + { + for (x = 0; x < GRIDW; x++) + { + pos = y * GRIDW + x; + vertex[pos].z = (float) (p[x][y] * (1.0 / 50.0)); + } + } +} + + +//======================================================================== +// Calculate wave propagation +//======================================================================== + +void calc_grid(void) +{ + int x, y, x2, y2; + double time_step = dt * ANIMATION_SPEED; + + // Compute accelerations + for (x = 0; x < GRIDW; x++) + { + x2 = (x + 1) % GRIDW; + for(y = 0; y < GRIDH; y++) + ax[x][y] = p[x][y] - p[x2][y]; + } + + for (y = 0; y < GRIDH; y++) + { + y2 = (y + 1) % GRIDH; + for(x = 0; x < GRIDW; x++) + ay[x][y] = p[x][y] - p[x][y2]; + } + + // Compute speeds + for (x = 0; x < GRIDW; x++) + { + for (y = 0; y < GRIDH; y++) + { + vx[x][y] = vx[x][y] + ax[x][y] * time_step; + vy[x][y] = vy[x][y] + ay[x][y] * time_step; + } + } + + // Compute pressure + for (x = 1; x < GRIDW; x++) + { + x2 = x - 1; + for (y = 1; y < GRIDH; y++) + { + y2 = y - 1; + p[x][y] = p[x][y] + (vx[x2][y] - vx[x][y] + vy[x][y2] - vy[x][y]) * time_step; + } + } +} + + +//======================================================================== +// Print errors +//======================================================================== + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + + +//======================================================================== +// Handle key strokes +//======================================================================== + +void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + if (action != GLFW_PRESS) + return; + + switch (key) + { + case GLFW_KEY_ESCAPE: + glfwSetWindowShouldClose(window, GL_TRUE); + break; + case GLFW_KEY_SPACE: + init_grid(); + break; + case GLFW_KEY_LEFT: + alpha += 5; + break; + case GLFW_KEY_RIGHT: + alpha -= 5; + break; + case GLFW_KEY_UP: + beta -= 5; + break; + case GLFW_KEY_DOWN: + beta += 5; + break; + case GLFW_KEY_PAGE_UP: + zoom -= 0.25f; + if (zoom < 0.f) + zoom = 0.f; + break; + case GLFW_KEY_PAGE_DOWN: + zoom += 0.25f; + break; + default: + break; + } +} + + +//======================================================================== +// Callback function for mouse button events +//======================================================================== + +void mouse_button_callback(GLFWwindow* window, int button, int action, int mods) +{ + if (button != GLFW_MOUSE_BUTTON_LEFT) + return; + + if (action == GLFW_PRESS) + { + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + glfwGetCursorPos(window, &cursorX, &cursorY); + } + else + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); +} + + +//======================================================================== +// Callback function for cursor motion events +//======================================================================== + +void cursor_position_callback(GLFWwindow* window, double x, double y) +{ + if (glfwGetInputMode(window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED) + { + alpha += (GLfloat) (x - cursorX) / 10.f; + beta += (GLfloat) (y - cursorY) / 10.f; + + cursorX = x; + cursorY = y; + } +} + + +//======================================================================== +// Callback function for scroll events +//======================================================================== + +void scroll_callback(GLFWwindow* window, double x, double y) +{ + zoom += (float) y / 4.f; + if (zoom < 0) + zoom = 0; +} + + +//======================================================================== +// Callback function for framebuffer resize events +//======================================================================== + +void framebuffer_size_callback(GLFWwindow* window, int width, int height) +{ + float ratio = 1.f; + + if (height > 0) + ratio = (float) width / (float) height; + + // Setup viewport + glViewport(0, 0, width, height); + + // Change to the projection matrix and set our viewing volume + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(60.0, ratio, 1.0, 1024.0); +} + + +//======================================================================== +// main +//======================================================================== + +int main(int argc, char* argv[]) +{ + GLFWwindow* window; + double t, dt_total, t_old; + int width, height; + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + window = glfwCreateWindow(640, 480, "Wave Simulation", NULL, NULL); + if (!window) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glfwSetKeyCallback(window, key_callback); + glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); + glfwSetMouseButtonCallback(window, mouse_button_callback); + glfwSetCursorPosCallback(window, cursor_position_callback); + glfwSetScrollCallback(window, scroll_callback); + + glfwMakeContextCurrent(window); + glfwSwapInterval(1); + + glfwGetFramebufferSize(window, &width, &height); + framebuffer_size_callback(window, width, height); + + // Initialize OpenGL + init_opengl(); + + // Initialize simulation + init_vertices(); + init_grid(); + adjust_grid(); + + // Initialize timer + t_old = glfwGetTime() - 0.01; + + while (!glfwWindowShouldClose(window)) + { + t = glfwGetTime(); + dt_total = t - t_old; + t_old = t; + + // Safety - iterate if dt_total is too large + while (dt_total > 0.f) + { + // Select iteration time step + dt = dt_total > MAX_DELTA_T ? MAX_DELTA_T : dt_total; + dt_total -= dt; + + // Calculate wave propagation + calc_grid(); + } + + // Compute height of each vertex + adjust_grid(); + + // Draw wave grid to OpenGL display + draw_scene(window); + + glfwPollEvents(); + } + + exit(EXIT_SUCCESS); +} + diff --git a/testbed/glfw/include/GLFW/glfw3.h b/testbed/glfw/include/GLFW/glfw3.h new file mode 100644 index 00000000..89414491 --- /dev/null +++ b/testbed/glfw/include/GLFW/glfw3.h @@ -0,0 +1,3355 @@ +/************************************************************************* + * GLFW 3.1 - www.glfw.org + * A library for OpenGL, window and input + *------------------------------------------------------------------------ + * Copyright (c) 2002-2006 Marcus Geelnard + * Copyright (c) 2006-2010 Camilla Berglund + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would + * be appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not + * be misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + * + *************************************************************************/ + +#ifndef _glfw3_h_ +#define _glfw3_h_ + +#ifdef __cplusplus +extern "C" { +#endif + + +/************************************************************************* + * Doxygen documentation + *************************************************************************/ + +/*! @defgroup context Context handling + * + * This is the reference documentation for context related functions. For more + * information, see the @ref context. + */ +/*! @defgroup init Initialization, version and errors + * + * This is the reference documentation for initialization and termination of + * the library, version management and error handling. For more information, + * see the @ref intro. + */ +/*! @defgroup input Input handling + * + * This is the reference documentation for input related functions and types. + * For more information, see the @ref input. + */ +/*! @defgroup monitor Monitor handling + * + * This is the reference documentation for monitor related functions and types. + * For more information, see the @ref monitor. + */ +/*! @defgroup window Window handling + * + * This is the reference documentation for window related functions and types, + * including creation, deletion and event polling. For more information, see + * the @ref window. + */ + + +/************************************************************************* + * Global definitions + *************************************************************************/ + +/* ------------------- BEGIN SYSTEM/COMPILER SPECIFIC -------------------- */ + +/* Please report any problems that you find with your compiler, which may + * be solved in this section! There are several compilers that I have not + * been able to test this file with yet. + * + * First: If we are we on Windows, we want a single define for it (_WIN32) + * (Note: For Cygwin the compiler flag -mwin32 should be used, but to + * make sure that things run smoothly for Cygwin users, we add __CYGWIN__ + * to the list of "valid Win32 identifiers", which removes the need for + * -mwin32) + */ +#if !defined(_WIN32) && (defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__)) + #define _WIN32 +#endif /* _WIN32 */ + +/* In order for extension support to be portable, we need to define an + * OpenGL function call method. We use the keyword APIENTRY, which is + * defined for Win32. (Note: Windows also needs this for ) + */ +#ifndef APIENTRY + #ifdef _WIN32 + #define APIENTRY __stdcall + #else + #define APIENTRY + #endif +#endif /* APIENTRY */ + +/* The following three defines are here solely to make some Windows-based + * files happy. Theoretically we could include , but + * it has the major drawback of severely polluting our namespace. + */ + +/* Under Windows, we need WINGDIAPI defined */ +#if !defined(WINGDIAPI) && defined(_WIN32) + #if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__POCC__) + /* Microsoft Visual C++, Borland C++ Builder and Pelles C */ + #define WINGDIAPI __declspec(dllimport) + #elif defined(__LCC__) + /* LCC-Win32 */ + #define WINGDIAPI __stdcall + #else + /* Others (e.g. MinGW, Cygwin) */ + #define WINGDIAPI extern + #endif + #define GLFW_WINGDIAPI_DEFINED +#endif /* WINGDIAPI */ + +/* Some files also need CALLBACK defined */ +#if !defined(CALLBACK) && defined(_WIN32) + #if defined(_MSC_VER) + /* Microsoft Visual C++ */ + #if (defined(_M_MRX000) || defined(_M_IX86) || defined(_M_ALPHA) || defined(_M_PPC)) && !defined(MIDL_PASS) + #define CALLBACK __stdcall + #else + #define CALLBACK + #endif + #else + /* Other Windows compilers */ + #define CALLBACK __stdcall + #endif + #define GLFW_CALLBACK_DEFINED +#endif /* CALLBACK */ + +/* Most GL/glu.h variants on Windows need wchar_t + * OpenGL/gl.h blocks the definition of ptrdiff_t by glext.h on OS X */ +#if !defined(GLFW_INCLUDE_NONE) + #include +#endif + +/* Include the chosen client API headers. + */ +#if defined(__APPLE_CC__) + #if defined(GLFW_INCLUDE_GLCOREARB) + #include + #if defined(GLFW_INCLUDE_GLEXT) + #include + #endif + #elif !defined(GLFW_INCLUDE_NONE) + #if !defined(GLFW_INCLUDE_GLEXT) + #define GL_GLEXT_LEGACY + #endif + #include + #endif + #if defined(GLFW_INCLUDE_GLU) + #include + #endif +#else + #if defined(GLFW_INCLUDE_GLCOREARB) + #include + #elif defined(GLFW_INCLUDE_ES1) + #include + #if defined(GLFW_INCLUDE_GLEXT) + #include + #endif + #elif defined(GLFW_INCLUDE_ES2) + #include + #if defined(GLFW_INCLUDE_GLEXT) + #include + #endif + #elif defined(GLFW_INCLUDE_ES3) + #include + #if defined(GLFW_INCLUDE_GLEXT) + #include + #endif + #elif defined(GLFW_INCLUDE_ES31) + #include + #if defined(GLFW_INCLUDE_GLEXT) + #include + #endif + #elif !defined(GLFW_INCLUDE_NONE) + #include + #if defined(GLFW_INCLUDE_GLEXT) + #include + #endif + #endif + #if defined(GLFW_INCLUDE_GLU) + #include + #endif +#endif + +#if defined(GLFW_DLL) && defined(_GLFW_BUILD_DLL) + /* GLFW_DLL must be defined by applications that are linking against the DLL + * version of the GLFW library. _GLFW_BUILD_DLL is defined by the GLFW + * configuration header when compiling the DLL version of the library. + */ + #error "You must not have both GLFW_DLL and _GLFW_BUILD_DLL defined" +#endif + +/* GLFWAPI is used to declare public API functions for export + * from the DLL / shared library / dynamic library. + */ +#if defined(_WIN32) && defined(_GLFW_BUILD_DLL) + /* We are building GLFW as a Win32 DLL */ + #define GLFWAPI __declspec(dllexport) +#elif defined(_WIN32) && defined(GLFW_DLL) + /* We are calling GLFW as a Win32 DLL */ + #if defined(__LCC__) + #define GLFWAPI extern + #else + #define GLFWAPI __declspec(dllimport) + #endif +#elif defined(__GNUC__) && defined(_GLFW_BUILD_DLL) + /* We are building GLFW as a shared / dynamic library */ + #define GLFWAPI __attribute__((visibility("default"))) +#else + /* We are building or calling GLFW as a static library */ + #define GLFWAPI +#endif + +/* -------------------- END SYSTEM/COMPILER SPECIFIC --------------------- */ + + +/************************************************************************* + * GLFW API tokens + *************************************************************************/ + +/*! @name GLFW version macros + * @{ */ +/*! @brief The major version number of the GLFW library. + * + * This is incremented when the API is changed in non-compatible ways. + * @ingroup init + */ +#define GLFW_VERSION_MAJOR 3 +/*! @brief The minor version number of the GLFW library. + * + * This is incremented when features are added to the API but it remains + * backward-compatible. + * @ingroup init + */ +#define GLFW_VERSION_MINOR 1 +/*! @brief The revision number of the GLFW library. + * + * This is incremented when a bug fix release is made that does not contain any + * API changes. + * @ingroup init + */ +#define GLFW_VERSION_REVISION 0 +/*! @} */ + +/*! @name Key and button actions + * @{ */ +/*! @brief The key or mouse button was released. + * + * The key or mouse button was released. + * + * @ingroup input + */ +#define GLFW_RELEASE 0 +/*! @brief The key or mouse button was pressed. + * + * The key or mouse button was pressed. + * + * @ingroup input + */ +#define GLFW_PRESS 1 +/*! @brief The key was held down until it repeated. + * + * The key was held down until it repeated. + * + * @ingroup input + */ +#define GLFW_REPEAT 2 +/*! @} */ + +/*! @defgroup keys Keyboard keys + * + * See [key input](@ref input_key) for how these are used. + * + * These key codes are inspired by the _USB HID Usage Tables v1.12_ (p. 53-60), + * but re-arranged to map to 7-bit ASCII for printable keys (function keys are + * put in the 256+ range). + * + * The naming of the key codes follow these rules: + * - The US keyboard layout is used + * - Names of printable alpha-numeric characters are used (e.g. "A", "R", + * "3", etc.) + * - For non-alphanumeric characters, Unicode:ish names are used (e.g. + * "COMMA", "LEFT_SQUARE_BRACKET", etc.). Note that some names do not + * correspond to the Unicode standard (usually for brevity) + * - Keys that lack a clear US mapping are named "WORLD_x" + * - For non-printable keys, custom names are used (e.g. "F4", + * "BACKSPACE", etc.) + * + * @ingroup input + * @{ + */ + +/* The unknown key */ +#define GLFW_KEY_UNKNOWN -1 + +/* Printable keys */ +#define GLFW_KEY_SPACE 32 +#define GLFW_KEY_APOSTROPHE 39 /* ' */ +#define GLFW_KEY_COMMA 44 /* , */ +#define GLFW_KEY_MINUS 45 /* - */ +#define GLFW_KEY_PERIOD 46 /* . */ +#define GLFW_KEY_SLASH 47 /* / */ +#define GLFW_KEY_0 48 +#define GLFW_KEY_1 49 +#define GLFW_KEY_2 50 +#define GLFW_KEY_3 51 +#define GLFW_KEY_4 52 +#define GLFW_KEY_5 53 +#define GLFW_KEY_6 54 +#define GLFW_KEY_7 55 +#define GLFW_KEY_8 56 +#define GLFW_KEY_9 57 +#define GLFW_KEY_SEMICOLON 59 /* ; */ +#define GLFW_KEY_EQUAL 61 /* = */ +#define GLFW_KEY_A 65 +#define GLFW_KEY_B 66 +#define GLFW_KEY_C 67 +#define GLFW_KEY_D 68 +#define GLFW_KEY_E 69 +#define GLFW_KEY_F 70 +#define GLFW_KEY_G 71 +#define GLFW_KEY_H 72 +#define GLFW_KEY_I 73 +#define GLFW_KEY_J 74 +#define GLFW_KEY_K 75 +#define GLFW_KEY_L 76 +#define GLFW_KEY_M 77 +#define GLFW_KEY_N 78 +#define GLFW_KEY_O 79 +#define GLFW_KEY_P 80 +#define GLFW_KEY_Q 81 +#define GLFW_KEY_R 82 +#define GLFW_KEY_S 83 +#define GLFW_KEY_T 84 +#define GLFW_KEY_U 85 +#define GLFW_KEY_V 86 +#define GLFW_KEY_W 87 +#define GLFW_KEY_X 88 +#define GLFW_KEY_Y 89 +#define GLFW_KEY_Z 90 +#define GLFW_KEY_LEFT_BRACKET 91 /* [ */ +#define GLFW_KEY_BACKSLASH 92 /* \ */ +#define GLFW_KEY_RIGHT_BRACKET 93 /* ] */ +#define GLFW_KEY_GRAVE_ACCENT 96 /* ` */ +#define GLFW_KEY_WORLD_1 161 /* non-US #1 */ +#define GLFW_KEY_WORLD_2 162 /* non-US #2 */ + +/* Function keys */ +#define GLFW_KEY_ESCAPE 256 +#define GLFW_KEY_ENTER 257 +#define GLFW_KEY_TAB 258 +#define GLFW_KEY_BACKSPACE 259 +#define GLFW_KEY_INSERT 260 +#define GLFW_KEY_DELETE 261 +#define GLFW_KEY_RIGHT 262 +#define GLFW_KEY_LEFT 263 +#define GLFW_KEY_DOWN 264 +#define GLFW_KEY_UP 265 +#define GLFW_KEY_PAGE_UP 266 +#define GLFW_KEY_PAGE_DOWN 267 +#define GLFW_KEY_HOME 268 +#define GLFW_KEY_END 269 +#define GLFW_KEY_CAPS_LOCK 280 +#define GLFW_KEY_SCROLL_LOCK 281 +#define GLFW_KEY_NUM_LOCK 282 +#define GLFW_KEY_PRINT_SCREEN 283 +#define GLFW_KEY_PAUSE 284 +#define GLFW_KEY_F1 290 +#define GLFW_KEY_F2 291 +#define GLFW_KEY_F3 292 +#define GLFW_KEY_F4 293 +#define GLFW_KEY_F5 294 +#define GLFW_KEY_F6 295 +#define GLFW_KEY_F7 296 +#define GLFW_KEY_F8 297 +#define GLFW_KEY_F9 298 +#define GLFW_KEY_F10 299 +#define GLFW_KEY_F11 300 +#define GLFW_KEY_F12 301 +#define GLFW_KEY_F13 302 +#define GLFW_KEY_F14 303 +#define GLFW_KEY_F15 304 +#define GLFW_KEY_F16 305 +#define GLFW_KEY_F17 306 +#define GLFW_KEY_F18 307 +#define GLFW_KEY_F19 308 +#define GLFW_KEY_F20 309 +#define GLFW_KEY_F21 310 +#define GLFW_KEY_F22 311 +#define GLFW_KEY_F23 312 +#define GLFW_KEY_F24 313 +#define GLFW_KEY_F25 314 +#define GLFW_KEY_KP_0 320 +#define GLFW_KEY_KP_1 321 +#define GLFW_KEY_KP_2 322 +#define GLFW_KEY_KP_3 323 +#define GLFW_KEY_KP_4 324 +#define GLFW_KEY_KP_5 325 +#define GLFW_KEY_KP_6 326 +#define GLFW_KEY_KP_7 327 +#define GLFW_KEY_KP_8 328 +#define GLFW_KEY_KP_9 329 +#define GLFW_KEY_KP_DECIMAL 330 +#define GLFW_KEY_KP_DIVIDE 331 +#define GLFW_KEY_KP_MULTIPLY 332 +#define GLFW_KEY_KP_SUBTRACT 333 +#define GLFW_KEY_KP_ADD 334 +#define GLFW_KEY_KP_ENTER 335 +#define GLFW_KEY_KP_EQUAL 336 +#define GLFW_KEY_LEFT_SHIFT 340 +#define GLFW_KEY_LEFT_CONTROL 341 +#define GLFW_KEY_LEFT_ALT 342 +#define GLFW_KEY_LEFT_SUPER 343 +#define GLFW_KEY_RIGHT_SHIFT 344 +#define GLFW_KEY_RIGHT_CONTROL 345 +#define GLFW_KEY_RIGHT_ALT 346 +#define GLFW_KEY_RIGHT_SUPER 347 +#define GLFW_KEY_MENU 348 +#define GLFW_KEY_LAST GLFW_KEY_MENU + +/*! @} */ + +/*! @defgroup mods Modifier key flags + * + * See [key input](@ref input_key) for how these are used. + * + * @ingroup input + * @{ */ + +/*! @brief If this bit is set one or more Shift keys were held down. + */ +#define GLFW_MOD_SHIFT 0x0001 +/*! @brief If this bit is set one or more Control keys were held down. + */ +#define GLFW_MOD_CONTROL 0x0002 +/*! @brief If this bit is set one or more Alt keys were held down. + */ +#define GLFW_MOD_ALT 0x0004 +/*! @brief If this bit is set one or more Super keys were held down. + */ +#define GLFW_MOD_SUPER 0x0008 + +/*! @} */ + +/*! @defgroup buttons Mouse buttons + * + * See [mouse button input](@ref input_mouse_button) for how these are used. + * + * @ingroup input + * @{ */ +#define GLFW_MOUSE_BUTTON_1 0 +#define GLFW_MOUSE_BUTTON_2 1 +#define GLFW_MOUSE_BUTTON_3 2 +#define GLFW_MOUSE_BUTTON_4 3 +#define GLFW_MOUSE_BUTTON_5 4 +#define GLFW_MOUSE_BUTTON_6 5 +#define GLFW_MOUSE_BUTTON_7 6 +#define GLFW_MOUSE_BUTTON_8 7 +#define GLFW_MOUSE_BUTTON_LAST GLFW_MOUSE_BUTTON_8 +#define GLFW_MOUSE_BUTTON_LEFT GLFW_MOUSE_BUTTON_1 +#define GLFW_MOUSE_BUTTON_RIGHT GLFW_MOUSE_BUTTON_2 +#define GLFW_MOUSE_BUTTON_MIDDLE GLFW_MOUSE_BUTTON_3 +/*! @} */ + +/*! @defgroup joysticks Joysticks + * + * See [joystick input](@ref joystick) for how these are used. + * + * @ingroup input + * @{ */ +#define GLFW_JOYSTICK_1 0 +#define GLFW_JOYSTICK_2 1 +#define GLFW_JOYSTICK_3 2 +#define GLFW_JOYSTICK_4 3 +#define GLFW_JOYSTICK_5 4 +#define GLFW_JOYSTICK_6 5 +#define GLFW_JOYSTICK_7 6 +#define GLFW_JOYSTICK_8 7 +#define GLFW_JOYSTICK_9 8 +#define GLFW_JOYSTICK_10 9 +#define GLFW_JOYSTICK_11 10 +#define GLFW_JOYSTICK_12 11 +#define GLFW_JOYSTICK_13 12 +#define GLFW_JOYSTICK_14 13 +#define GLFW_JOYSTICK_15 14 +#define GLFW_JOYSTICK_16 15 +#define GLFW_JOYSTICK_LAST GLFW_JOYSTICK_16 +/*! @} */ + +/*! @defgroup errors Error codes + * + * See [error handling](@ref error_handling) for how these are used. + * + * @ingroup init + * @{ */ +/*! @brief GLFW has not been initialized. + * + * This occurs if a GLFW function was called that may not be called unless the + * library is [initialized](@ref intro_init). + * + * @par Analysis + * Application programmer error. Initialize GLFW before calling any function + * that requires initialization. + */ +#define GLFW_NOT_INITIALIZED 0x00010001 +/*! @brief No context is current for this thread. + * + * This occurs if a GLFW function was called that needs and operates on the + * current OpenGL or OpenGL ES context but no context is current on the calling + * thread. One such function is @ref glfwSwapInterval. + * + * @par Analysis + * Application programmer error. Ensure a context is current before calling + * functions that require a current context. + */ +#define GLFW_NO_CURRENT_CONTEXT 0x00010002 +/*! @brief One of the arguments to the function was an invalid enum value. + * + * One of the arguments to the function was an invalid enum value, for example + * requesting [GLFW_RED_BITS](@ref window_hints_fb) with @ref + * glfwGetWindowAttrib. + * + * @par Analysis + * Application programmer error. Fix the offending call. + */ +#define GLFW_INVALID_ENUM 0x00010003 +/*! @brief One of the arguments to the function was an invalid value. + * + * One of the arguments to the function was an invalid value, for example + * requesting a non-existent OpenGL or OpenGL ES version like 2.7. + * + * Requesting a valid but unavailable OpenGL or OpenGL ES version will instead + * result in a @ref GLFW_VERSION_UNAVAILABLE error. + * + * @par Analysis + * Application programmer error. Fix the offending call. + */ +#define GLFW_INVALID_VALUE 0x00010004 +/*! @brief A memory allocation failed. + * + * A memory allocation failed. + * + * @par Analysis + * A bug in GLFW or the underlying operating system. Report the bug to our + * [issue tracker](https://github.com/glfw/glfw/issues). + */ +#define GLFW_OUT_OF_MEMORY 0x00010005 +/*! @brief GLFW could not find support for the requested client API on the + * system. + * + * GLFW could not find support for the requested client API on the system. + * + * @par Analysis + * The installed graphics driver does not support the requested client API, or + * does not support it via the chosen context creation backend. Below are + * a few examples. + * + * @par + * Some pre-installed Windows graphics drivers do not support OpenGL. AMD only + * supports OpenGL ES via EGL, while Nvidia and Intel only supports it via + * a WGL or GLX extension. OS X does not provide OpenGL ES at all. The Mesa + * EGL, OpenGL and OpenGL ES libraries do not interface with the Nvidia binary + * driver. + */ +#define GLFW_API_UNAVAILABLE 0x00010006 +/*! @brief The requested OpenGL or OpenGL ES version is not available. + * + * The requested OpenGL or OpenGL ES version (including any requested profile + * or context option) is not available on this machine. + * + * @par Analysis + * The machine does not support your requirements. If your application is + * sufficiently flexible, downgrade your requirements and try again. + * Otherwise, inform the user that their machine does not match your + * requirements. + * + * @par + * Future invalid OpenGL and OpenGL ES versions, for example OpenGL 4.8 if 5.0 + * comes out before the 4.x series gets that far, also fail with this error and + * not @ref GLFW_INVALID_VALUE, because GLFW cannot know what future versions + * will exist. + */ +#define GLFW_VERSION_UNAVAILABLE 0x00010007 +/*! @brief A platform-specific error occurred that does not match any of the + * more specific categories. + * + * A platform-specific error occurred that does not match any of the more + * specific categories. + * + * @par Analysis + * A bug in GLFW or the underlying operating system. Report the bug to our + * [issue tracker](https://github.com/glfw/glfw/issues). + */ +#define GLFW_PLATFORM_ERROR 0x00010008 +/*! @brief The requested format is not supported or available. + * + * If emitted during window creation, the requested pixel format is not + * supported. + * + * If emitted when querying the clipboard, the contents of the clipboard could + * not be converted to the requested format. + * + * @par Analysis + * If emitted during window creation, one or more + * [hard constraints](@ref window_hints_hard) did not match any of the + * available pixel formats. If your application is sufficiently flexible, + * downgrade your requirements and try again. Otherwise, inform the user that + * their machine does not match your requirements. + * + * @par + * If emitted when querying the clipboard, ignore the error or report it to + * the user, as appropriate. + */ +#define GLFW_FORMAT_UNAVAILABLE 0x00010009 +/*! @} */ + +#define GLFW_FOCUSED 0x00020001 +#define GLFW_ICONIFIED 0x00020002 +#define GLFW_RESIZABLE 0x00020003 +#define GLFW_VISIBLE 0x00020004 +#define GLFW_DECORATED 0x00020005 +#define GLFW_AUTO_ICONIFY 0x00020006 +#define GLFW_FLOATING 0x00020007 + +#define GLFW_RED_BITS 0x00021001 +#define GLFW_GREEN_BITS 0x00021002 +#define GLFW_BLUE_BITS 0x00021003 +#define GLFW_ALPHA_BITS 0x00021004 +#define GLFW_DEPTH_BITS 0x00021005 +#define GLFW_STENCIL_BITS 0x00021006 +#define GLFW_ACCUM_RED_BITS 0x00021007 +#define GLFW_ACCUM_GREEN_BITS 0x00021008 +#define GLFW_ACCUM_BLUE_BITS 0x00021009 +#define GLFW_ACCUM_ALPHA_BITS 0x0002100A +#define GLFW_AUX_BUFFERS 0x0002100B +#define GLFW_STEREO 0x0002100C +#define GLFW_SAMPLES 0x0002100D +#define GLFW_SRGB_CAPABLE 0x0002100E +#define GLFW_REFRESH_RATE 0x0002100F +#define GLFW_DOUBLEBUFFER 0x00021010 + +#define GLFW_CLIENT_API 0x00022001 +#define GLFW_CONTEXT_VERSION_MAJOR 0x00022002 +#define GLFW_CONTEXT_VERSION_MINOR 0x00022003 +#define GLFW_CONTEXT_REVISION 0x00022004 +#define GLFW_CONTEXT_ROBUSTNESS 0x00022005 +#define GLFW_OPENGL_FORWARD_COMPAT 0x00022006 +#define GLFW_OPENGL_DEBUG_CONTEXT 0x00022007 +#define GLFW_OPENGL_PROFILE 0x00022008 +#define GLFW_CONTEXT_RELEASE_BEHAVIOR 0x00022009 + +#define GLFW_OPENGL_API 0x00030001 +#define GLFW_OPENGL_ES_API 0x00030002 + +#define GLFW_NO_ROBUSTNESS 0 +#define GLFW_NO_RESET_NOTIFICATION 0x00031001 +#define GLFW_LOSE_CONTEXT_ON_RESET 0x00031002 + +#define GLFW_OPENGL_ANY_PROFILE 0 +#define GLFW_OPENGL_CORE_PROFILE 0x00032001 +#define GLFW_OPENGL_COMPAT_PROFILE 0x00032002 + +#define GLFW_CURSOR 0x00033001 +#define GLFW_STICKY_KEYS 0x00033002 +#define GLFW_STICKY_MOUSE_BUTTONS 0x00033003 + +#define GLFW_CURSOR_NORMAL 0x00034001 +#define GLFW_CURSOR_HIDDEN 0x00034002 +#define GLFW_CURSOR_DISABLED 0x00034003 + +#define GLFW_ANY_RELEASE_BEHAVIOR 0 +#define GLFW_RELEASE_BEHAVIOR_FLUSH 0x00035001 +#define GLFW_RELEASE_BEHAVIOR_NONE 0x00035002 + +/*! @defgroup shapes Standard cursor shapes + * + * See [standard cursor creation](@ref cursor_standard) for how these are used. + * + * @ingroup input + * @{ */ + +/*! @brief The regular arrow cursor shape. + * + * The regular arrow cursor. + */ +#define GLFW_ARROW_CURSOR 0x00036001 +/*! @brief The text input I-beam cursor shape. + * + * The text input I-beam cursor shape. + */ +#define GLFW_IBEAM_CURSOR 0x00036002 +/*! @brief The crosshair shape. + * + * The crosshair shape. + */ +#define GLFW_CROSSHAIR_CURSOR 0x00036003 +/*! @brief The hand shape. + * + * The hand shape. + */ +#define GLFW_HAND_CURSOR 0x00036004 +/*! @brief The horizontal resize arrow shape. + * + * The horizontal resize arrow shape. + */ +#define GLFW_HRESIZE_CURSOR 0x00036005 +/*! @brief The vertical resize arrow shape. + * + * The vertical resize arrow shape. + */ +#define GLFW_VRESIZE_CURSOR 0x00036006 +/*! @} */ + +#define GLFW_CONNECTED 0x00040001 +#define GLFW_DISCONNECTED 0x00040002 + +#define GLFW_DONT_CARE -1 + + +/************************************************************************* + * GLFW API types + *************************************************************************/ + +/*! @brief Client API function pointer type. + * + * Generic function pointer used for returning client API function pointers + * without forcing a cast from a regular pointer. + * + * @ingroup context + */ +typedef void (*GLFWglproc)(void); + +/*! @brief Opaque monitor object. + * + * Opaque monitor object. + * + * @ingroup monitor + */ +typedef struct GLFWmonitor GLFWmonitor; + +/*! @brief Opaque window object. + * + * Opaque window object. + * + * @ingroup window + */ +typedef struct GLFWwindow GLFWwindow; + +/*! @brief Opaque cursor object. + * + * Opaque cursor object. + * + * @ingroup cursor + */ +typedef struct GLFWcursor GLFWcursor; + +/*! @brief The function signature for error callbacks. + * + * This is the function signature for error callback functions. + * + * @param[in] error An [error code](@ref errors). + * @param[in] description A UTF-8 encoded string describing the error. + * + * @sa glfwSetErrorCallback + * + * @ingroup init + */ +typedef void (* GLFWerrorfun)(int,const char*); + +/*! @brief The function signature for window position callbacks. + * + * This is the function signature for window position callback functions. + * + * @param[in] window The window that was moved. + * @param[in] xpos The new x-coordinate, in screen coordinates, of the + * upper-left corner of the client area of the window. + * @param[in] ypos The new y-coordinate, in screen coordinates, of the + * upper-left corner of the client area of the window. + * + * @sa glfwSetWindowPosCallback + * + * @ingroup window + */ +typedef void (* GLFWwindowposfun)(GLFWwindow*,int,int); + +/*! @brief The function signature for window resize callbacks. + * + * This is the function signature for window size callback functions. + * + * @param[in] window The window that was resized. + * @param[in] width The new width, in screen coordinates, of the window. + * @param[in] height The new height, in screen coordinates, of the window. + * + * @sa glfwSetWindowSizeCallback + * + * @ingroup window + */ +typedef void (* GLFWwindowsizefun)(GLFWwindow*,int,int); + +/*! @brief The function signature for window close callbacks. + * + * This is the function signature for window close callback functions. + * + * @param[in] window The window that the user attempted to close. + * + * @sa glfwSetWindowCloseCallback + * + * @ingroup window + */ +typedef void (* GLFWwindowclosefun)(GLFWwindow*); + +/*! @brief The function signature for window content refresh callbacks. + * + * This is the function signature for window refresh callback functions. + * + * @param[in] window The window whose content needs to be refreshed. + * + * @sa glfwSetWindowRefreshCallback + * + * @ingroup window + */ +typedef void (* GLFWwindowrefreshfun)(GLFWwindow*); + +/*! @brief The function signature for window focus/defocus callbacks. + * + * This is the function signature for window focus callback functions. + * + * @param[in] window The window that gained or lost input focus. + * @param[in] focused `GL_TRUE` if the window was given input focus, or + * `GL_FALSE` if it lost it. + * + * @sa glfwSetWindowFocusCallback + * + * @ingroup window + */ +typedef void (* GLFWwindowfocusfun)(GLFWwindow*,int); + +/*! @brief The function signature for window iconify/restore callbacks. + * + * This is the function signature for window iconify/restore callback + * functions. + * + * @param[in] window The window that was iconified or restored. + * @param[in] iconified `GL_TRUE` if the window was iconified, or `GL_FALSE` + * if it was restored. + * + * @sa glfwSetWindowIconifyCallback + * + * @ingroup window + */ +typedef void (* GLFWwindowiconifyfun)(GLFWwindow*,int); + +/*! @brief The function signature for framebuffer resize callbacks. + * + * This is the function signature for framebuffer resize callback + * functions. + * + * @param[in] window The window whose framebuffer was resized. + * @param[in] width The new width, in pixels, of the framebuffer. + * @param[in] height The new height, in pixels, of the framebuffer. + * + * @sa glfwSetFramebufferSizeCallback + * + * @ingroup window + */ +typedef void (* GLFWframebuffersizefun)(GLFWwindow*,int,int); + +/*! @brief The function signature for mouse button callbacks. + * + * This is the function signature for mouse button callback functions. + * + * @param[in] window The window that received the event. + * @param[in] button The [mouse button](@ref buttons) that was pressed or + * released. + * @param[in] action One of `GLFW_PRESS` or `GLFW_RELEASE`. + * @param[in] mods Bit field describing which [modifier keys](@ref mods) were + * held down. + * + * @sa glfwSetMouseButtonCallback + * + * @ingroup input + */ +typedef void (* GLFWmousebuttonfun)(GLFWwindow*,int,int,int); + +/*! @brief The function signature for cursor position callbacks. + * + * This is the function signature for cursor position callback functions. + * + * @param[in] window The window that received the event. + * @param[in] xpos The new x-coordinate, in screen coordinates, of the cursor. + * @param[in] ypos The new y-coordinate, in screen coordinates, of the cursor. + * + * @sa glfwSetCursorPosCallback + * + * @ingroup input + */ +typedef void (* GLFWcursorposfun)(GLFWwindow*,double,double); + +/*! @brief The function signature for cursor enter/leave callbacks. + * + * This is the function signature for cursor enter/leave callback functions. + * + * @param[in] window The window that received the event. + * @param[in] entered `GL_TRUE` if the cursor entered the window's client + * area, or `GL_FALSE` if it left it. + * + * @sa glfwSetCursorEnterCallback + * + * @ingroup input + */ +typedef void (* GLFWcursorenterfun)(GLFWwindow*,int); + +/*! @brief The function signature for scroll callbacks. + * + * This is the function signature for scroll callback functions. + * + * @param[in] window The window that received the event. + * @param[in] xoffset The scroll offset along the x-axis. + * @param[in] yoffset The scroll offset along the y-axis. + * + * @sa glfwSetScrollCallback + * + * @ingroup input + */ +typedef void (* GLFWscrollfun)(GLFWwindow*,double,double); + +/*! @brief The function signature for keyboard key callbacks. + * + * This is the function signature for keyboard key callback functions. + * + * @param[in] window The window that received the event. + * @param[in] key The [keyboard key](@ref keys) that was pressed or released. + * @param[in] scancode The system-specific scancode of the key. + * @param[in] action `GLFW_PRESS`, `GLFW_RELEASE` or `GLFW_REPEAT`. + * @param[in] mods Bit field describing which [modifier keys](@ref mods) were + * held down. + * + * @sa glfwSetKeyCallback + * + * @ingroup input + */ +typedef void (* GLFWkeyfun)(GLFWwindow*,int,int,int,int); + +/*! @brief The function signature for Unicode character callbacks. + * + * This is the function signature for Unicode character callback functions. + * + * @param[in] window The window that received the event. + * @param[in] codepoint The Unicode code point of the character. + * + * @sa glfwSetCharCallback + * + * @ingroup input + */ +typedef void (* GLFWcharfun)(GLFWwindow*,unsigned int); + +/*! @brief The function signature for Unicode character with modifiers + * callbacks. + * + * This is the function signature for Unicode character with modifiers callback + * functions. It is called for each input character, regardless of what + * modifier keys are held down. + * + * @param[in] window The window that received the event. + * @param[in] codepoint The Unicode code point of the character. + * @param[in] mods Bit field describing which [modifier keys](@ref mods) were + * held down. + * + * @sa glfwSetCharModsCallback + * + * @ingroup input + */ +typedef void (* GLFWcharmodsfun)(GLFWwindow*,unsigned int,int); + +/*! @brief The function signature for file drop callbacks. + * + * This is the function signature for file drop callbacks. + * + * @param[in] window The window that received the event. + * @param[in] count The number of dropped files. + * @param[in] names The UTF-8 encoded path names of the dropped files. + * + * @sa glfwSetDropCallback + * + * @ingroup input + */ +typedef void (* GLFWdropfun)(GLFWwindow*,int,const char**); + +/*! @brief The function signature for monitor configuration callbacks. + * + * This is the function signature for monitor configuration callback functions. + * + * @param[in] monitor The monitor that was connected or disconnected. + * @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`. + * + * @sa glfwSetMonitorCallback + * + * @ingroup monitor + */ +typedef void (* GLFWmonitorfun)(GLFWmonitor*,int); + +/*! @brief Video mode type. + * + * This describes a single video mode. + * + * @ingroup monitor + */ +typedef struct GLFWvidmode +{ + /*! The width, in screen coordinates, of the video mode. + */ + int width; + /*! The height, in screen coordinates, of the video mode. + */ + int height; + /*! The bit depth of the red channel of the video mode. + */ + int redBits; + /*! The bit depth of the green channel of the video mode. + */ + int greenBits; + /*! The bit depth of the blue channel of the video mode. + */ + int blueBits; + /*! The refresh rate, in Hz, of the video mode. + */ + int refreshRate; +} GLFWvidmode; + +/*! @brief Gamma ramp. + * + * This describes the gamma ramp for a monitor. + * + * @sa glfwGetGammaRamp glfwSetGammaRamp + * + * @ingroup monitor + */ +typedef struct GLFWgammaramp +{ + /*! An array of value describing the response of the red channel. + */ + unsigned short* red; + /*! An array of value describing the response of the green channel. + */ + unsigned short* green; + /*! An array of value describing the response of the blue channel. + */ + unsigned short* blue; + /*! The number of elements in each array. + */ + unsigned int size; +} GLFWgammaramp; + +/*! @brief Image data. + */ +typedef struct GLFWimage +{ + /*! The width, in pixels, of this image. + */ + int width; + /*! The height, in pixels, of this image. + */ + int height; + /*! The pixel data of this image, arranged left-to-right, top-to-bottom. + */ + unsigned char* pixels; +} GLFWimage; + + +/************************************************************************* + * GLFW API functions + *************************************************************************/ + +/*! @brief Initializes the GLFW library. + * + * This function initializes the GLFW library. Before most GLFW functions can + * be used, GLFW must be initialized, and before an application terminates GLFW + * should be terminated in order to free any resources allocated during or + * after initialization. + * + * If this function fails, it calls @ref glfwTerminate before returning. If it + * succeeds, you should call @ref glfwTerminate before the application exits. + * + * Additional calls to this function after successful initialization but before + * termination will return `GL_TRUE` immediately. + * + * @return `GL_TRUE` if successful, or `GL_FALSE` if an + * [error](@ref error_handling) occurred. + * + * @remarks __OS X:__ This function will change the current directory of the + * application to the `Contents/Resources` subdirectory of the application's + * bundle, if present. This can be disabled with a + * [compile-time option](@ref compile_options_osx). + * + * @remarks __X11:__ If the `LC_CTYPE` category of the current locale is set to + * `"C"` then the environment's locale will be applied to that category. This + * is done because character input will not function when `LC_CTYPE` is set to + * `"C"`. If another locale was set before this function was called, it will + * be left untouched. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref intro_init + * @sa glfwTerminate + * + * @since Added in GLFW 1.0. + * + * @ingroup init + */ +GLFWAPI int glfwInit(void); + +/*! @brief Terminates the GLFW library. + * + * This function destroys all remaining windows and cursors, restores any + * modified gamma ramps and frees any other allocated resources. Once this + * function is called, you must again call @ref glfwInit successfully before + * you will be able to use most GLFW functions. + * + * If GLFW has been successfully initialized, this function should be called + * before the application exits. If initialization fails, there is no need to + * call this function, as it is called by @ref glfwInit before it returns + * failure. + * + * @remarks This function may be called before @ref glfwInit. + * + * @warning No window's context may be current on another thread when this + * function is called. + * + * @par Reentrancy + * This function may not be called from a callback. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref intro_init + * @sa glfwInit + * + * @since Added in GLFW 1.0. + * + * @ingroup init + */ +GLFWAPI void glfwTerminate(void); + +/*! @brief Retrieves the version of the GLFW library. + * + * This function retrieves the major, minor and revision numbers of the GLFW + * library. It is intended for when you are using GLFW as a shared library and + * want to ensure that you are using the minimum required version. + * + * Any or all of the version arguments may be `NULL`. This function always + * succeeds. + * + * @param[out] major Where to store the major version number, or `NULL`. + * @param[out] minor Where to store the minor version number, or `NULL`. + * @param[out] rev Where to store the revision number, or `NULL`. + * + * @remarks This function may be called before @ref glfwInit. + * + * @par Thread Safety + * This function may be called from any thread. + * + * @sa @ref intro_version + * @sa glfwGetVersionString + * + * @since Added in GLFW 1.0. + * + * @ingroup init + */ +GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev); + +/*! @brief Returns a string describing the compile-time configuration. + * + * This function returns the compile-time generated + * [version string](@ref intro_version_string) of the GLFW library binary. It + * describes the version, platform, compiler and any platform-specific + * compile-time options. + * + * __Do not use the version string__ to parse the GLFW library version. The + * @ref glfwGetVersion function already provides the version of the running + * library binary. + * + * This function always succeeds. + * + * @return The GLFW version string. + * + * @remarks This function may be called before @ref glfwInit. + * + * @par Pointer Lifetime + * The returned string is static and compile-time generated. + * + * @par Thread Safety + * This function may be called from any thread. + * + * @sa @ref intro_version + * @sa glfwGetVersion + * + * @since Added in GLFW 3.0. + * + * @ingroup init + */ +GLFWAPI const char* glfwGetVersionString(void); + +/*! @brief Sets the error callback. + * + * This function sets the error callback, which is called with an error code + * and a human-readable description each time a GLFW error occurs. + * + * The error callback is called on the thread where the error occurred. If you + * are using GLFW from multiple threads, your error callback needs to be + * written accordingly. + * + * Because the description string may have been generated specifically for that + * error, it is not guaranteed to be valid after the callback has returned. If + * you wish to use it after the callback returns, you need to make a copy. + * + * Once set, the error callback remains set even after the library has been + * terminated. + * + * @param[in] cbfun The new callback, or `NULL` to remove the currently set + * callback. + * @return The previously set callback, or `NULL` if no callback was set. + * + * @remarks This function may be called before @ref glfwInit. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref error_handling + * + * @since Added in GLFW 3.0. + * + * @ingroup init + */ +GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun); + +/*! @brief Returns the currently connected monitors. + * + * This function returns an array of handles for all currently connected + * monitors. + * + * @param[out] count Where to store the number of monitors in the returned + * array. This is set to zero if an error occurred. + * @return An array of monitor handles, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @par Pointer Lifetime + * The returned array is allocated and freed by GLFW. You should not free it + * yourself. It is guaranteed to be valid only until the monitor configuration + * changes or the library is terminated. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref monitor_monitors + * @sa @ref monitor_event + * @sa glfwGetPrimaryMonitor + * + * @since Added in GLFW 3.0. + * + * @ingroup monitor + */ +GLFWAPI GLFWmonitor** glfwGetMonitors(int* count); + +/*! @brief Returns the primary monitor. + * + * This function returns the primary monitor. This is usually the monitor + * where elements like the Windows task bar or the OS X menu bar is located. + * + * @return The primary monitor, or `NULL` if an [error](@ref error_handling) + * occurred. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref monitor_monitors + * @sa glfwGetMonitors + * + * @since Added in GLFW 3.0. + * + * @ingroup monitor + */ +GLFWAPI GLFWmonitor* glfwGetPrimaryMonitor(void); + +/*! @brief Returns the position of the monitor's viewport on the virtual screen. + * + * This function returns the position, in screen coordinates, of the upper-left + * corner of the specified monitor. + * + * Any or all of the position arguments may be `NULL`. If an error occurs, all + * non-`NULL` position arguments will be set to zero. + * + * @param[in] monitor The monitor to query. + * @param[out] xpos Where to store the monitor x-coordinate, or `NULL`. + * @param[out] ypos Where to store the monitor y-coordinate, or `NULL`. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref monitor_properties + * + * @since Added in GLFW 3.0. + * + * @ingroup monitor + */ +GLFWAPI void glfwGetMonitorPos(GLFWmonitor* monitor, int* xpos, int* ypos); + +/*! @brief Returns the physical size of the monitor. + * + * This function returns the size, in millimetres, of the display area of the + * specified monitor. + * + * Some systems do not provide accurate monitor size information, either + * because the monitor + * [EDID](https://en.wikipedia.org/wiki/Extended_display_identification_data) + * data is incorrect or because the driver does not report it accurately. + * + * Any or all of the size arguments may be `NULL`. If an error occurs, all + * non-`NULL` size arguments will be set to zero. + * + * @param[in] monitor The monitor to query. + * @param[out] widthMM Where to store the width, in millimetres, of the + * monitor's display area, or `NULL`. + * @param[out] heightMM Where to store the height, in millimetres, of the + * monitor's display area, or `NULL`. + * + * @remarks __Windows:__ The OS calculates the returned physical size from the + * current resolution and system DPI instead of querying the monitor EDID data. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref monitor_properties + * + * @since Added in GLFW 3.0. + * + * @ingroup monitor + */ +GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* monitor, int* widthMM, int* heightMM); + +/*! @brief Returns the name of the specified monitor. + * + * This function returns a human-readable name, encoded as UTF-8, of the + * specified monitor. The name typically reflects the make and model of the + * monitor and is not guaranteed to be unique among the connected monitors. + * + * @param[in] monitor The monitor to query. + * @return The UTF-8 encoded name of the monitor, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @par Pointer Lifetime + * The returned string is allocated and freed by GLFW. You should not free it + * yourself. It is valid until the specified monitor is disconnected or the + * library is terminated. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref monitor_properties + * + * @since Added in GLFW 3.0. + * + * @ingroup monitor + */ +GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* monitor); + +/*! @brief Sets the monitor configuration callback. + * + * This function sets the monitor configuration callback, or removes the + * currently set callback. This is called when a monitor is connected to or + * disconnected from the system. + * + * @param[in] cbfun The new callback, or `NULL` to remove the currently set + * callback. + * @return The previously set callback, or `NULL` if no callback was set or the + * library had not been [initialized](@ref intro_init). + * + * @bug __X11:__ This callback is not yet called on monitor configuration + * changes. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref monitor_event + * + * @since Added in GLFW 3.0. + * + * @ingroup monitor + */ +GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun cbfun); + +/*! @brief Returns the available video modes for the specified monitor. + * + * This function returns an array of all video modes supported by the specified + * monitor. The returned array is sorted in ascending order, first by color + * bit depth (the sum of all channel depths) and then by resolution area (the + * product of width and height). + * + * @param[in] monitor The monitor to query. + * @param[out] count Where to store the number of video modes in the returned + * array. This is set to zero if an error occurred. + * @return An array of video modes, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @par Pointer Lifetime + * The returned array is allocated and freed by GLFW. You should not free it + * yourself. It is valid until the specified monitor is disconnected, this + * function is called again for that monitor or the library is terminated. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref monitor_modes + * @sa glfwGetVideoMode + * + * @since Added in GLFW 1.0. + * + * @par + * __GLFW 3:__ Changed to return an array of modes for a specific monitor. + * + * @ingroup monitor + */ +GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* monitor, int* count); + +/*! @brief Returns the current mode of the specified monitor. + * + * This function returns the current video mode of the specified monitor. If + * you have created a full screen window for that monitor, the return value + * will depend on whether that window is iconified. + * + * @param[in] monitor The monitor to query. + * @return The current mode of the monitor, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @par Pointer Lifetime + * The returned array is allocated and freed by GLFW. You should not free it + * yourself. It is valid until the specified monitor is disconnected or the + * library is terminated. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref monitor_modes + * @sa glfwGetVideoModes + * + * @since Added in GLFW 3.0. Replaces `glfwGetDesktopMode`. + * + * @ingroup monitor + */ +GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor); + +/*! @brief Generates a gamma ramp and sets it for the specified monitor. + * + * This function generates a 256-element gamma ramp from the specified exponent + * and then calls @ref glfwSetGammaRamp with it. + * + * @param[in] monitor The monitor whose gamma ramp to set. + * @param[in] gamma The desired exponent. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref monitor_gamma + * + * @since Added in GLFW 3.0. + * + * @ingroup monitor + */ +GLFWAPI void glfwSetGamma(GLFWmonitor* monitor, float gamma); + +/*! @brief Returns the current gamma ramp for the specified monitor. + * + * This function returns the current gamma ramp of the specified monitor. + * + * @param[in] monitor The monitor to query. + * @return The current gamma ramp, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @par Pointer Lifetime + * The returned structure and its arrays are allocated and freed by GLFW. You + * should not free them yourself. They are valid until the specified monitor + * is disconnected, this function is called again for that monitor or the + * library is terminated. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref monitor_gamma + * + * @since Added in GLFW 3.0. + * + * @ingroup monitor + */ +GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* monitor); + +/*! @brief Sets the current gamma ramp for the specified monitor. + * + * This function sets the current gamma ramp for the specified monitor. The + * original gamma ramp for that monitor is saved by GLFW the first time this + * function is called and is restored by @ref glfwTerminate. + * + * @param[in] monitor The monitor whose gamma ramp to set. + * @param[in] ramp The gamma ramp to use. + * + * @note Gamma ramp sizes other than 256 are not supported by all hardware. + * + * @par Pointer Lifetime + * The specified gamma ramp is copied before this function returns. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref monitor_gamma + * + * @since Added in GLFW 3.0. + * + * @ingroup monitor + */ +GLFWAPI void glfwSetGammaRamp(GLFWmonitor* monitor, const GLFWgammaramp* ramp); + +/*! @brief Resets all window hints to their default values. + * + * This function resets all window hints to their + * [default values](@ref window_hints_values). + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref window_hints + * @sa glfwWindowHint + * + * @since Added in GLFW 3.0. + * + * @ingroup window + */ +GLFWAPI void glfwDefaultWindowHints(void); + +/*! @brief Sets the specified window hint to the desired value. + * + * This function sets hints for the next call to @ref glfwCreateWindow. The + * hints, once set, retain their values until changed by a call to @ref + * glfwWindowHint or @ref glfwDefaultWindowHints, or until the library is + * terminated. + * + * @param[in] target The [window hint](@ref window_hints) to set. + * @param[in] hint The new value of the window hint. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref window_hints + * @sa glfwDefaultWindowHints + * + * @since Added in GLFW 3.0. Replaces `glfwOpenWindowHint`. + * + * @ingroup window + */ +GLFWAPI void glfwWindowHint(int target, int hint); + +/*! @brief Creates a window and its associated context. + * + * This function creates a window and its associated OpenGL or OpenGL ES + * context. Most of the options controlling how the window and its context + * should be created are specified with [window hints](@ref window_hints). + * + * Successful creation does not change which context is current. Before you + * can use the newly created context, you need to + * [make it current](@ref context_current). For information about the `share` + * parameter, see @ref context_sharing. + * + * The created window, framebuffer and context may differ from what you + * requested, as not all parameters and hints are + * [hard constraints](@ref window_hints_hard). This includes the size of the + * window, especially for full screen windows. To query the actual attributes + * of the created window, framebuffer and context, use queries like @ref + * glfwGetWindowAttrib and @ref glfwGetWindowSize. + * + * To create a full screen window, you need to specify the monitor the window + * will cover. If no monitor is specified, windowed mode will be used. Unless + * you have a way for the user to choose a specific monitor, it is recommended + * that you pick the primary monitor. For more information on how to query + * connected monitors, see @ref monitor_monitors. + * + * For full screen windows, the specified size becomes the resolution of the + * window's _desired video mode_. As long as a full screen window has input + * focus, the supported video mode most closely matching the desired video mode + * is set for the specified monitor. For more information about full screen + * windows, including the creation of so called _windowed full screen_ or + * _borderless full screen_ windows, see @ref window_windowed_full_screen. + * + * By default, newly created windows use the placement recommended by the + * window system. To create the window at a specific position, make it + * initially invisible using the [GLFW_VISIBLE](@ref window_hints_wnd) window + * hint, set its [position](@ref window_pos) and then [show](@ref window_hide) + * it. + * + * If a full screen window has input focus, the screensaver is prohibited from + * starting. + * + * Window systems put limits on window sizes. Very large or very small window + * dimensions may be overridden by the window system on creation. Check the + * actual [size](@ref window_size) after creation. + * + * The [swap interval](@ref buffer_swap) is not set during window creation and + * the initial value may vary depending on driver settings and defaults. + * + * @param[in] width The desired width, in screen coordinates, of the window. + * This must be greater than zero. + * @param[in] height The desired height, in screen coordinates, of the window. + * This must be greater than zero. + * @param[in] title The initial, UTF-8 encoded window title. + * @param[in] monitor The monitor to use for full screen mode, or `NULL` to use + * windowed mode. + * @param[in] share The window whose context to share resources with, or `NULL` + * to not share resources. + * @return The handle of the created window, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @remarks __Windows:__ Window creation will fail if the Microsoft GDI + * software OpenGL implementation is the only one available. + * + * @remarks __Windows:__ If the executable has an icon resource named + * `GLFW_ICON,` it will be set as the icon for the window. If no such icon is + * present, the `IDI_WINLOGO` icon will be used instead. + * + * @remarks __Windows:__ The context to share resources with may not be current + * on any other thread. + * + * @remarks __OS X:__ The GLFW window has no icon, as it is not a document + * window, but the dock icon will be the same as the application bundle's icon. + * For more information on bundles, see the + * [Bundle Programming Guide](https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/) + * in the Mac Developer Library. + * + * @remarks __OS X:__ The first time a window is created the menu bar is + * populated with common commands like Hide, Quit and About. The About entry + * opens a minimal about dialog with information from the application's bundle. + * The menu bar can be disabled with a + * [compile-time option](@ref compile_options_osx). + * + * @remarks __X11:__ There is no mechanism for setting the window icon yet. + * + * @remarks __X11:__ Some window managers will not respect the placement of + * initially hidden windows. + * + * @par Reentrancy + * This function may not be called from a callback. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref window_creation + * @sa glfwDestroyWindow + * + * @since Added in GLFW 3.0. Replaces `glfwOpenWindow`. + * + * @ingroup window + */ +GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, const char* title, GLFWmonitor* monitor, GLFWwindow* share); + +/*! @brief Destroys the specified window and its context. + * + * This function destroys the specified window and its context. On calling + * this function, no further callbacks will be called for that window. + * + * If the context of the specified window is current on the main thread, it is + * detached before being destroyed. + * + * @param[in] window The window to destroy. + * + * @note The context of the specified window must not be current on any other + * thread when this function is called. + * + * @par Reentrancy + * This function may not be called from a callback. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref window_creation + * @sa glfwCreateWindow + * + * @since Added in GLFW 3.0. Replaces `glfwCloseWindow`. + * + * @ingroup window + */ +GLFWAPI void glfwDestroyWindow(GLFWwindow* window); + +/*! @brief Checks the close flag of the specified window. + * + * This function returns the value of the close flag of the specified window. + * + * @param[in] window The window to query. + * @return The value of the close flag. + * + * @par Thread Safety + * This function may be called from any thread. Access is not synchronized. + * + * @sa @ref window_close + * + * @since Added in GLFW 3.0. + * + * @ingroup window + */ +GLFWAPI int glfwWindowShouldClose(GLFWwindow* window); + +/*! @brief Sets the close flag of the specified window. + * + * This function sets the value of the close flag of the specified window. + * This can be used to override the user's attempt to close the window, or + * to signal that it should be closed. + * + * @param[in] window The window whose flag to change. + * @param[in] value The new value. + * + * @par Thread Safety + * This function may be called from any thread. Access is not synchronized. + * + * @sa @ref window_close + * + * @since Added in GLFW 3.0. + * + * @ingroup window + */ +GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* window, int value); + +/*! @brief Sets the title of the specified window. + * + * This function sets the window title, encoded as UTF-8, of the specified + * window. + * + * @param[in] window The window whose title to change. + * @param[in] title The UTF-8 encoded window title. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref window_title + * + * @since Added in GLFW 1.0. + * + * @par + * __GLFW 3:__ Added window handle parameter. + * + * @ingroup window + */ +GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title); + +/*! @brief Retrieves the position of the client area of the specified window. + * + * This function retrieves the position, in screen coordinates, of the + * upper-left corner of the client area of the specified window. + * + * Any or all of the position arguments may be `NULL`. If an error occurs, all + * non-`NULL` position arguments will be set to zero. + * + * @param[in] window The window to query. + * @param[out] xpos Where to store the x-coordinate of the upper-left corner of + * the client area, or `NULL`. + * @param[out] ypos Where to store the y-coordinate of the upper-left corner of + * the client area, or `NULL`. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref window_pos + * @sa glfwSetWindowPos + * + * @since Added in GLFW 3.0. + * + * @ingroup window + */ +GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos); + +/*! @brief Sets the position of the client area of the specified window. + * + * This function sets the position, in screen coordinates, of the upper-left + * corner of the client area of the specified windowed mode window. If the + * window is a full screen window, this function does nothing. + * + * __Do not use this function__ to move an already visible window unless you + * have very good reasons for doing so, as it will confuse and annoy the user. + * + * The window manager may put limits on what positions are allowed. GLFW + * cannot and should not override these limits. + * + * @param[in] window The window to query. + * @param[in] xpos The x-coordinate of the upper-left corner of the client area. + * @param[in] ypos The y-coordinate of the upper-left corner of the client area. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref window_pos + * @sa glfwGetWindowPos + * + * @since Added in GLFW 1.0. + * + * @par + * __GLFW 3:__ Added window handle parameter. + * + * @ingroup window + */ +GLFWAPI void glfwSetWindowPos(GLFWwindow* window, int xpos, int ypos); + +/*! @brief Retrieves the size of the client area of the specified window. + * + * This function retrieves the size, in screen coordinates, of the client area + * of the specified window. If you wish to retrieve the size of the + * framebuffer of the window in pixels, see @ref glfwGetFramebufferSize. + * + * Any or all of the size arguments may be `NULL`. If an error occurs, all + * non-`NULL` size arguments will be set to zero. + * + * @param[in] window The window whose size to retrieve. + * @param[out] width Where to store the width, in screen coordinates, of the + * client area, or `NULL`. + * @param[out] height Where to store the height, in screen coordinates, of the + * client area, or `NULL`. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref window_size + * @sa glfwSetWindowSize + * + * @since Added in GLFW 1.0. + * + * @par + * __GLFW 3:__ Added window handle parameter. + * + * @ingroup window + */ +GLFWAPI void glfwGetWindowSize(GLFWwindow* window, int* width, int* height); + +/*! @brief Sets the size of the client area of the specified window. + * + * This function sets the size, in screen coordinates, of the client area of + * the specified window. + * + * For full screen windows, this function selects and switches to the resolution + * closest to the specified size, without affecting the window's context. As + * the context is unaffected, the bit depths of the framebuffer remain + * unchanged. + * + * The window manager may put limits on what sizes are allowed. GLFW cannot + * and should not override these limits. + * + * @param[in] window The window to resize. + * @param[in] width The desired width of the specified window. + * @param[in] height The desired height of the specified window. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref window_size + * @sa glfwGetWindowSize + * + * @since Added in GLFW 1.0. + * + * @par + * __GLFW 3:__ Added window handle parameter. + * + * @ingroup window + */ +GLFWAPI void glfwSetWindowSize(GLFWwindow* window, int width, int height); + +/*! @brief Retrieves the size of the framebuffer of the specified window. + * + * This function retrieves the size, in pixels, of the framebuffer of the + * specified window. If you wish to retrieve the size of the window in screen + * coordinates, see @ref glfwGetWindowSize. + * + * Any or all of the size arguments may be `NULL`. If an error occurs, all + * non-`NULL` size arguments will be set to zero. + * + * @param[in] window The window whose framebuffer to query. + * @param[out] width Where to store the width, in pixels, of the framebuffer, + * or `NULL`. + * @param[out] height Where to store the height, in pixels, of the framebuffer, + * or `NULL`. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref window_fbsize + * @sa glfwSetFramebufferSizeCallback + * + * @since Added in GLFW 3.0. + * + * @ingroup window + */ +GLFWAPI void glfwGetFramebufferSize(GLFWwindow* window, int* width, int* height); + +/*! @brief Retrieves the size of the frame of the window. + * + * This function retrieves the size, in screen coordinates, of each edge of the + * frame of the specified window. This size includes the title bar, if the + * window has one. The size of the frame may vary depending on the + * [window-related hints](@ref window_hints_wnd) used to create it. + * + * Because this function retrieves the size of each window frame edge and not + * the offset along a particular coordinate axis, the retrieved values will + * always be zero or positive. + * + * Any or all of the size arguments may be `NULL`. If an error occurs, all + * non-`NULL` size arguments will be set to zero. + * + * @param[in] window The window whose frame size to query. + * @param[out] left Where to store the size, in screen coordinates, of the left + * edge of the window frame, or `NULL`. + * @param[out] top Where to store the size, in screen coordinates, of the top + * edge of the window frame, or `NULL`. + * @param[out] right Where to store the size, in screen coordinates, of the + * right edge of the window frame, or `NULL`. + * @param[out] bottom Where to store the size, in screen coordinates, of the + * bottom edge of the window frame, or `NULL`. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref window_size + * + * @since Added in GLFW 3.1. + * + * @ingroup window + */ +GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* window, int* left, int* top, int* right, int* bottom); + +/*! @brief Iconifies the specified window. + * + * This function iconifies (minimizes) the specified window if it was + * previously restored. If the window is already iconified, this function does + * nothing. + * + * If the specified window is a full screen window, the original monitor + * resolution is restored until the window is restored. + * + * @param[in] window The window to iconify. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref window_iconify + * @sa glfwRestoreWindow + * + * @since Added in GLFW 2.1. + * + * @par + * __GLFW 3:__ Added window handle parameter. + * + * @ingroup window + */ +GLFWAPI void glfwIconifyWindow(GLFWwindow* window); + +/*! @brief Restores the specified window. + * + * This function restores the specified window if it was previously iconified + * (minimized). If the window is already restored, this function does nothing. + * + * If the specified window is a full screen window, the resolution chosen for + * the window is restored on the selected monitor. + * + * @param[in] window The window to restore. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref window_iconify + * @sa glfwIconifyWindow + * + * @since Added in GLFW 2.1. + * + * @par + * __GLFW 3:__ Added window handle parameter. + * + * @ingroup window + */ +GLFWAPI void glfwRestoreWindow(GLFWwindow* window); + +/*! @brief Makes the specified window visible. + * + * This function makes the specified window visible if it was previously + * hidden. If the window is already visible or is in full screen mode, this + * function does nothing. + * + * @param[in] window The window to make visible. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref window_hide + * @sa glfwHideWindow + * + * @since Added in GLFW 3.0. + * + * @ingroup window + */ +GLFWAPI void glfwShowWindow(GLFWwindow* window); + +/*! @brief Hides the specified window. + * + * This function hides the specified window if it was previously visible. If + * the window is already hidden or is in full screen mode, this function does + * nothing. + * + * @param[in] window The window to hide. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref window_hide + * @sa glfwShowWindow + * + * @since Added in GLFW 3.0. + * + * @ingroup window + */ +GLFWAPI void glfwHideWindow(GLFWwindow* window); + +/*! @brief Returns the monitor that the window uses for full screen mode. + * + * This function returns the handle of the monitor that the specified window is + * in full screen on. + * + * @param[in] window The window to query. + * @return The monitor, or `NULL` if the window is in windowed mode or an error + * occurred. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref window_monitor + * + * @since Added in GLFW 3.0. + * + * @ingroup window + */ +GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* window); + +/*! @brief Returns an attribute of the specified window. + * + * This function returns the value of an attribute of the specified window or + * its OpenGL or OpenGL ES context. + * + * @param[in] window The window to query. + * @param[in] attrib The [window attribute](@ref window_attribs) whose value to + * return. + * @return The value of the attribute, or zero if an + * [error](@ref error_handling) occurred. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref window_attribs + * + * @since Added in GLFW 3.0. Replaces `glfwGetWindowParam` and + * `glfwGetGLVersion`. + * + * @ingroup window + */ +GLFWAPI int glfwGetWindowAttrib(GLFWwindow* window, int attrib); + +/*! @brief Sets the user pointer of the specified window. + * + * This function sets the user-defined pointer of the specified window. The + * current value is retained until the window is destroyed. The initial value + * is `NULL`. + * + * @param[in] window The window whose pointer to set. + * @param[in] pointer The new value. + * + * @par Thread Safety + * This function may be called from any thread. Access is not synchronized. + * + * @sa @ref window_userptr + * @sa glfwGetWindowUserPointer + * + * @since Added in GLFW 3.0. + * + * @ingroup window + */ +GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* window, void* pointer); + +/*! @brief Returns the user pointer of the specified window. + * + * This function returns the current value of the user-defined pointer of the + * specified window. The initial value is `NULL`. + * + * @param[in] window The window whose pointer to return. + * + * @par Thread Safety + * This function may be called from any thread. Access is not synchronized. + * + * @sa @ref window_userptr + * @sa glfwSetWindowUserPointer + * + * @since Added in GLFW 3.0. + * + * @ingroup window + */ +GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* window); + +/*! @brief Sets the position callback for the specified window. + * + * This function sets the position callback of the specified window, which is + * called when the window is moved. The callback is provided with the screen + * position of the upper-left corner of the client area of the window. + * + * @param[in] window The window whose callback to set. + * @param[in] cbfun The new callback, or `NULL` to remove the currently set + * callback. + * @return The previously set callback, or `NULL` if no callback was set or the + * library had not been [initialized](@ref intro_init). + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref window_pos + * + * @since Added in GLFW 3.0. + * + * @ingroup window + */ +GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* window, GLFWwindowposfun cbfun); + +/*! @brief Sets the size callback for the specified window. + * + * This function sets the size callback of the specified window, which is + * called when the window is resized. The callback is provided with the size, + * in screen coordinates, of the client area of the window. + * + * @param[in] window The window whose callback to set. + * @param[in] cbfun The new callback, or `NULL` to remove the currently set + * callback. + * @return The previously set callback, or `NULL` if no callback was set or the + * library had not been [initialized](@ref intro_init). + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref window_size + * + * @since Added in GLFW 1.0. + * + * @par + * __GLFW 3:__ Added window handle parameter. Updated callback signature. + * + * @ingroup window + */ +GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* window, GLFWwindowsizefun cbfun); + +/*! @brief Sets the close callback for the specified window. + * + * This function sets the close callback of the specified window, which is + * called when the user attempts to close the window, for example by clicking + * the close widget in the title bar. + * + * The close flag is set before this callback is called, but you can modify it + * at any time with @ref glfwSetWindowShouldClose. + * + * The close callback is not triggered by @ref glfwDestroyWindow. + * + * @param[in] window The window whose callback to set. + * @param[in] cbfun The new callback, or `NULL` to remove the currently set + * callback. + * @return The previously set callback, or `NULL` if no callback was set or the + * library had not been [initialized](@ref intro_init). + * + * @remarks __OS X:__ Selecting Quit from the application menu will + * trigger the close callback for all windows. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref window_close + * + * @since Added in GLFW 2.5. + * + * @par + * __GLFW 3:__ Added window handle parameter. Updated callback signature. + * + * @ingroup window + */ +GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* window, GLFWwindowclosefun cbfun); + +/*! @brief Sets the refresh callback for the specified window. + * + * This function sets the refresh callback of the specified window, which is + * called when the client area of the window needs to be redrawn, for example + * if the window has been exposed after having been covered by another window. + * + * On compositing window systems such as Aero, Compiz or Aqua, where the window + * contents are saved off-screen, this callback may be called only very + * infrequently or never at all. + * + * @param[in] window The window whose callback to set. + * @param[in] cbfun The new callback, or `NULL` to remove the currently set + * callback. + * @return The previously set callback, or `NULL` if no callback was set or the + * library had not been [initialized](@ref intro_init). + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref window_refresh + * + * @since Added in GLFW 2.5. + * + * @par + * __GLFW 3:__ Added window handle parameter. Updated callback signature. + * + * @ingroup window + */ +GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* window, GLFWwindowrefreshfun cbfun); + +/*! @brief Sets the focus callback for the specified window. + * + * This function sets the focus callback of the specified window, which is + * called when the window gains or loses input focus. + * + * After the focus callback is called for a window that lost input focus, + * synthetic key and mouse button release events will be generated for all such + * that had been pressed. For more information, see @ref glfwSetKeyCallback + * and @ref glfwSetMouseButtonCallback. + * + * @param[in] window The window whose callback to set. + * @param[in] cbfun The new callback, or `NULL` to remove the currently set + * callback. + * @return The previously set callback, or `NULL` if no callback was set or the + * library had not been [initialized](@ref intro_init). + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref window_focus + * + * @since Added in GLFW 3.0. + * + * @ingroup window + */ +GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* window, GLFWwindowfocusfun cbfun); + +/*! @brief Sets the iconify callback for the specified window. + * + * This function sets the iconification callback of the specified window, which + * is called when the window is iconified or restored. + * + * @param[in] window The window whose callback to set. + * @param[in] cbfun The new callback, or `NULL` to remove the currently set + * callback. + * @return The previously set callback, or `NULL` if no callback was set or the + * library had not been [initialized](@ref intro_init). + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref window_iconify + * + * @since Added in GLFW 3.0. + * + * @ingroup window + */ +GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* window, GLFWwindowiconifyfun cbfun); + +/*! @brief Sets the framebuffer resize callback for the specified window. + * + * This function sets the framebuffer resize callback of the specified window, + * which is called when the framebuffer of the specified window is resized. + * + * @param[in] window The window whose callback to set. + * @param[in] cbfun The new callback, or `NULL` to remove the currently set + * callback. + * @return The previously set callback, or `NULL` if no callback was set or the + * library had not been [initialized](@ref intro_init). + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref window_fbsize + * + * @since Added in GLFW 3.0. + * + * @ingroup window + */ +GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* window, GLFWframebuffersizefun cbfun); + +/*! @brief Processes all pending events. + * + * This function processes only those events that are already in the event + * queue and then returns immediately. Processing events will cause the window + * and input callbacks associated with those events to be called. + * + * On some platforms, a window move, resize or menu operation will cause event + * processing to block. This is due to how event processing is designed on + * those platforms. You can use the + * [window refresh callback](@ref window_refresh) to redraw the contents of + * your window when necessary during such operations. + * + * On some platforms, certain events are sent directly to the application + * without going through the event queue, causing callbacks to be called + * outside of a call to one of the event processing functions. + * + * Event processing is not required for joystick input to work. + * + * @par Reentrancy + * This function may not be called from a callback. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref events + * @sa glfwWaitEvents + * + * @since Added in GLFW 1.0. + * + * @ingroup window + */ +GLFWAPI void glfwPollEvents(void); + +/*! @brief Waits until events are queued and processes them. + * + * This function puts the calling thread to sleep until at least one event is + * available in the event queue. Once one or more events are available, + * it behaves exactly like @ref glfwPollEvents, i.e. the events in the queue + * are processed and the function then returns immediately. Processing events + * will cause the window and input callbacks associated with those events to be + * called. + * + * Since not all events are associated with callbacks, this function may return + * without a callback having been called even if you are monitoring all + * callbacks. + * + * On some platforms, a window move, resize or menu operation will cause event + * processing to block. This is due to how event processing is designed on + * those platforms. You can use the + * [window refresh callback](@ref window_refresh) to redraw the contents of + * your window when necessary during such operations. + * + * On some platforms, certain callbacks may be called outside of a call to one + * of the event processing functions. + * + * If no windows exist, this function returns immediately. For synchronization + * of threads in applications that do not create windows, use your threading + * library of choice. + * + * Event processing is not required for joystick input to work. + * + * @par Reentrancy + * This function may not be called from a callback. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref events + * @sa glfwPollEvents + * + * @since Added in GLFW 2.5. + * + * @ingroup window + */ +GLFWAPI void glfwWaitEvents(void); + +/*! @brief Posts an empty event to the event queue. + * + * This function posts an empty event from the current thread to the event + * queue, causing @ref glfwWaitEvents to return. + * + * If no windows exist, this function returns immediately. For synchronization + * of threads in applications that do not create windows, use your threading + * library of choice. + * + * @par Thread Safety + * This function may be called from any thread. + * + * @sa @ref events + * @sa glfwWaitEvents + * + * @since Added in GLFW 3.1. + * + * @ingroup window + */ +GLFWAPI void glfwPostEmptyEvent(void); + +/*! @brief Returns the value of an input option for the specified window. + * + * This function returns the value of an input option for the specified window. + * The mode must be one of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or + * `GLFW_STICKY_MOUSE_BUTTONS`. + * + * @param[in] window The window to query. + * @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or + * `GLFW_STICKY_MOUSE_BUTTONS`. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa glfwSetInputMode + * + * @since Added in GLFW 3.0. + * + * @ingroup input + */ +GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode); + +/*! @brief Sets an input option for the specified window. + * + * This function sets an input mode option for the specified window. The mode + * must be one of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or + * `GLFW_STICKY_MOUSE_BUTTONS`. + * + * If the mode is `GLFW_CURSOR`, the value must be one of the following cursor + * modes: + * - `GLFW_CURSOR_NORMAL` makes the cursor visible and behaving normally. + * - `GLFW_CURSOR_HIDDEN` makes the cursor invisible when it is over the client + * area of the window but does not restrict the cursor from leaving. + * - `GLFW_CURSOR_DISABLED` hides and grabs the cursor, providing virtual + * and unlimited cursor movement. This is useful for implementing for + * example 3D camera controls. + * + * If the mode is `GLFW_STICKY_KEYS`, the value must be either `GL_TRUE` to + * enable sticky keys, or `GL_FALSE` to disable it. If sticky keys are + * enabled, a key press will ensure that @ref glfwGetKey returns `GLFW_PRESS` + * the next time it is called even if the key had been released before the + * call. This is useful when you are only interested in whether keys have been + * pressed but not when or in which order. + * + * If the mode is `GLFW_STICKY_MOUSE_BUTTONS`, the value must be either + * `GL_TRUE` to enable sticky mouse buttons, or `GL_FALSE` to disable it. If + * sticky mouse buttons are enabled, a mouse button press will ensure that @ref + * glfwGetMouseButton returns `GLFW_PRESS` the next time it is called even if + * the mouse button had been released before the call. This is useful when you + * are only interested in whether mouse buttons have been pressed but not when + * or in which order. + * + * @param[in] window The window whose input mode to set. + * @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or + * `GLFW_STICKY_MOUSE_BUTTONS`. + * @param[in] value The new value of the specified input mode. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa glfwGetInputMode + * + * @since Added in GLFW 3.0. Replaces `glfwEnable` and `glfwDisable`. + * + * @ingroup input + */ +GLFWAPI void glfwSetInputMode(GLFWwindow* window, int mode, int value); + +/*! @brief Returns the last reported state of a keyboard key for the specified + * window. + * + * This function returns the last state reported for the specified key to the + * specified window. The returned state is one of `GLFW_PRESS` or + * `GLFW_RELEASE`. The higher-level action `GLFW_REPEAT` is only reported to + * the key callback. + * + * If the `GLFW_STICKY_KEYS` input mode is enabled, this function returns + * `GLFW_PRESS` the first time you call it for a key that was pressed, even if + * that key has already been released. + * + * The key functions deal with physical keys, with [key tokens](@ref keys) + * named after their use on the standard US keyboard layout. If you want to + * input text, use the Unicode character callback instead. + * + * The [modifier key bit masks](@ref mods) are not key tokens and cannot be + * used with this function. + * + * @param[in] window The desired window. + * @param[in] key The desired [keyboard key](@ref keys). `GLFW_KEY_UNKNOWN` is + * not a valid key for this function. + * @return One of `GLFW_PRESS` or `GLFW_RELEASE`. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref input_key + * + * @since Added in GLFW 1.0. + * + * @par + * __GLFW 3:__ Added window handle parameter. + * + * @ingroup input + */ +GLFWAPI int glfwGetKey(GLFWwindow* window, int key); + +/*! @brief Returns the last reported state of a mouse button for the specified + * window. + * + * This function returns the last state reported for the specified mouse button + * to the specified window. The returned state is one of `GLFW_PRESS` or + * `GLFW_RELEASE`. + * + * If the `GLFW_STICKY_MOUSE_BUTTONS` input mode is enabled, this function + * `GLFW_PRESS` the first time you call it for a mouse button that was pressed, + * even if that mouse button has already been released. + * + * @param[in] window The desired window. + * @param[in] button The desired [mouse button](@ref buttons). + * @return One of `GLFW_PRESS` or `GLFW_RELEASE`. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref input_mouse_button + * + * @since Added in GLFW 1.0. + * + * @par + * __GLFW 3:__ Added window handle parameter. + * + * @ingroup input + */ +GLFWAPI int glfwGetMouseButton(GLFWwindow* window, int button); + +/*! @brief Retrieves the position of the cursor relative to the client area of + * the window. + * + * This function returns the position of the cursor, in screen coordinates, + * relative to the upper-left corner of the client area of the specified + * window. + * + * If the cursor is disabled (with `GLFW_CURSOR_DISABLED`) then the cursor + * position is unbounded and limited only by the minimum and maximum values of + * a `double`. + * + * The coordinate can be converted to their integer equivalents with the + * `floor` function. Casting directly to an integer type works for positive + * coordinates, but fails for negative ones. + * + * Any or all of the position arguments may be `NULL`. If an error occurs, all + * non-`NULL` position arguments will be set to zero. + * + * @param[in] window The desired window. + * @param[out] xpos Where to store the cursor x-coordinate, relative to the + * left edge of the client area, or `NULL`. + * @param[out] ypos Where to store the cursor y-coordinate, relative to the to + * top edge of the client area, or `NULL`. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref cursor_pos + * @sa glfwSetCursorPos + * + * @since Added in GLFW 3.0. Replaces `glfwGetMousePos`. + * + * @ingroup input + */ +GLFWAPI void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos); + +/*! @brief Sets the position of the cursor, relative to the client area of the + * window. + * + * This function sets the position, in screen coordinates, of the cursor + * relative to the upper-left corner of the client area of the specified + * window. The window must have input focus. If the window does not have + * input focus when this function is called, it fails silently. + * + * __Do not use this function__ to implement things like camera controls. GLFW + * already provides the `GLFW_CURSOR_DISABLED` cursor mode that hides the + * cursor, transparently re-centers it and provides unconstrained cursor + * motion. See @ref glfwSetInputMode for more information. + * + * If the cursor mode is `GLFW_CURSOR_DISABLED` then the cursor position is + * unconstrained and limited only by the minimum and maximum values of + * a `double`. + * + * @param[in] window The desired window. + * @param[in] xpos The desired x-coordinate, relative to the left edge of the + * client area. + * @param[in] ypos The desired y-coordinate, relative to the top edge of the + * client area. + * + * @remarks __X11:__ Due to the asynchronous nature of a modern X desktop, it + * may take a moment for the window focus event to arrive. This means you will + * not be able to set the cursor position directly after window creation. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref cursor_pos + * @sa glfwGetCursorPos + * + * @since Added in GLFW 3.0. Replaces `glfwSetMousePos`. + * + * @ingroup input + */ +GLFWAPI void glfwSetCursorPos(GLFWwindow* window, double xpos, double ypos); + +/*! @brief Creates a custom cursor. + * + * Creates a new custom cursor image that can be set for a window with @ref + * glfwSetCursor. The cursor can be destroyed with @ref glfwDestroyCursor. + * Any remaining cursors are destroyed by @ref glfwTerminate. + * + * The pixels are 32-bit little-endian RGBA, i.e. eight bits per channel. They + * are arranged canonically as packed sequential rows, starting from the + * top-left corner. + * + * The cursor hotspot is specified in pixels, relative to the upper-left corner + * of the cursor image. Like all other coordinate systems in GLFW, the X-axis + * points to the right and the Y-axis points down. + * + * @param[in] image The desired cursor image. + * @param[in] xhot The desired x-coordinate, in pixels, of the cursor hotspot. + * @param[in] yhot The desired y-coordinate, in pixels, of the cursor hotspot. + * + * @return The handle of the created cursor, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @par Pointer Lifetime + * The specified image data is copied before this function returns. + * + * @par Reentrancy + * This function may not be called from a callback. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref cursor_object + * @sa glfwDestroyCursor + * @sa glfwCreateStandardCursor + * + * @since Added in GLFW 3.1. + * + * @ingroup input + */ +GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot); + +/*! @brief Creates a cursor with a standard shape. + * + * Returns a cursor with a [standard shape](@ref shapes), that can be set for + * a window with @ref glfwSetCursor. + * + * @param[in] shape One of the [standard shapes](@ref shapes). + * + * @return A new cursor ready to use or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @par Reentrancy + * This function may not be called from a callback. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref cursor_object + * @sa glfwCreateCursor + * + * @since Added in GLFW 3.1. + * + * @ingroup input + */ +GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape); + +/*! @brief Destroys a cursor. + * + * This function destroys a cursor previously created with @ref + * glfwCreateCursor. Any remaining cursors will be destroyed by @ref + * glfwTerminate. + * + * @param[in] cursor The cursor object to destroy. + * + * @par Reentrancy + * This function may not be called from a callback. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref cursor_object + * @sa glfwCreateCursor + * + * @since Added in GLFW 3.1. + * + * @ingroup input + */ +GLFWAPI void glfwDestroyCursor(GLFWcursor* cursor); + +/*! @brief Sets the cursor for the window. + * + * This function sets the cursor image to be used when the cursor is over the + * client area of the specified window. The set cursor will only be visible + * when the [cursor mode](@ref cursor_mode) of the window is + * `GLFW_CURSOR_NORMAL`. + * + * On some platforms, the set cursor may not be visible unless the window also + * has input focus. + * + * @param[in] window The window to set the cursor for. + * @param[in] cursor The cursor to set, or `NULL` to switch back to the default + * arrow cursor. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref cursor_object + * + * @since Added in GLFW 3.1. + * + * @ingroup input + */ +GLFWAPI void glfwSetCursor(GLFWwindow* window, GLFWcursor* cursor); + +/*! @brief Sets the key callback. + * + * This function sets the key callback of the specified window, which is called + * when a key is pressed, repeated or released. + * + * The key functions deal with physical keys, with layout independent + * [key tokens](@ref keys) named after their values in the standard US keyboard + * layout. If you want to input text, use the + * [character callback](@ref glfwSetCharCallback) instead. + * + * When a window loses input focus, it will generate synthetic key release + * events for all pressed keys. You can tell these events from user-generated + * events by the fact that the synthetic ones are generated after the focus + * loss event has been processed, i.e. after the + * [window focus callback](@ref glfwSetWindowFocusCallback) has been called. + * + * The scancode of a key is specific to that platform or sometimes even to that + * machine. Scancodes are intended to allow users to bind keys that don't have + * a GLFW key token. Such keys have `key` set to `GLFW_KEY_UNKNOWN`, their + * state is not saved and so it cannot be queried with @ref glfwGetKey. + * + * Sometimes GLFW needs to generate synthetic key events, in which case the + * scancode may be zero. + * + * @param[in] window The window whose callback to set. + * @param[in] cbfun The new key callback, or `NULL` to remove the currently + * set callback. + * @return The previously set callback, or `NULL` if no callback was set or the + * library had not been [initialized](@ref intro_init). + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref input_key + * + * @since Added in GLFW 1.0. + * + * @par + * __GLFW 3:__ Added window handle parameter. Updated callback signature. + * + * @ingroup input + */ +GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* window, GLFWkeyfun cbfun); + +/*! @brief Sets the Unicode character callback. + * + * This function sets the character callback of the specified window, which is + * called when a Unicode character is input. + * + * The character callback is intended for Unicode text input. As it deals with + * characters, it is keyboard layout dependent, whereas the + * [key callback](@ref glfwSetKeyCallback) is not. Characters do not map 1:1 + * to physical keys, as a key may produce zero, one or more characters. If you + * want to know whether a specific physical key was pressed or released, see + * the key callback instead. + * + * The character callback behaves as system text input normally does and will + * not be called if modifier keys are held down that would prevent normal text + * input on that platform, for example a Super (Command) key on OS X or Alt key + * on Windows. There is a + * [character with modifiers callback](@ref glfwSetCharModsCallback) that + * receives these events. + * + * @param[in] window The window whose callback to set. + * @param[in] cbfun The new callback, or `NULL` to remove the currently set + * callback. + * @return The previously set callback, or `NULL` if no callback was set or the + * library had not been [initialized](@ref intro_init). + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref input_char + * + * @since Added in GLFW 2.4. + * + * @par + * __GLFW 3:__ Added window handle parameter. Updated callback signature. + * + * @ingroup input + */ +GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* window, GLFWcharfun cbfun); + +/*! @brief Sets the Unicode character with modifiers callback. + * + * This function sets the character with modifiers callback of the specified + * window, which is called when a Unicode character is input regardless of what + * modifier keys are used. + * + * The character with modifiers callback is intended for implementing custom + * Unicode character input. For regular Unicode text input, see the + * [character callback](@ref glfwSetCharCallback). Like the character + * callback, the character with modifiers callback deals with characters and is + * keyboard layout dependent. Characters do not map 1:1 to physical keys, as + * a key may produce zero, one or more characters. If you want to know whether + * a specific physical key was pressed or released, see the + * [key callback](@ref glfwSetKeyCallback) instead. + * + * @param[in] window The window whose callback to set. + * @param[in] cbfun The new callback, or `NULL` to remove the currently set + * callback. + * @return The previously set callback, or `NULL` if no callback was set or an + * error occurred. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref input_char + * + * @since Added in GLFW 3.1. + * + * @ingroup input + */ +GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* window, GLFWcharmodsfun cbfun); + +/*! @brief Sets the mouse button callback. + * + * This function sets the mouse button callback of the specified window, which + * is called when a mouse button is pressed or released. + * + * When a window loses input focus, it will generate synthetic mouse button + * release events for all pressed mouse buttons. You can tell these events + * from user-generated events by the fact that the synthetic ones are generated + * after the focus loss event has been processed, i.e. after the + * [window focus callback](@ref glfwSetWindowFocusCallback) has been called. + * + * @param[in] window The window whose callback to set. + * @param[in] cbfun The new callback, or `NULL` to remove the currently set + * callback. + * @return The previously set callback, or `NULL` if no callback was set or the + * library had not been [initialized](@ref intro_init). + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref input_mouse_button + * + * @since Added in GLFW 1.0. + * + * @par + * __GLFW 3:__ Added window handle parameter. Updated callback signature. + * + * @ingroup input + */ +GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* window, GLFWmousebuttonfun cbfun); + +/*! @brief Sets the cursor position callback. + * + * This function sets the cursor position callback of the specified window, + * which is called when the cursor is moved. The callback is provided with the + * position, in screen coordinates, relative to the upper-left corner of the + * client area of the window. + * + * @param[in] window The window whose callback to set. + * @param[in] cbfun The new callback, or `NULL` to remove the currently set + * callback. + * @return The previously set callback, or `NULL` if no callback was set or the + * library had not been [initialized](@ref intro_init). + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref cursor_pos + * + * @since Added in GLFW 3.0. Replaces `glfwSetMousePosCallback`. + * + * @ingroup input + */ +GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* window, GLFWcursorposfun cbfun); + +/*! @brief Sets the cursor enter/exit callback. + * + * This function sets the cursor boundary crossing callback of the specified + * window, which is called when the cursor enters or leaves the client area of + * the window. + * + * @param[in] window The window whose callback to set. + * @param[in] cbfun The new callback, or `NULL` to remove the currently set + * callback. + * @return The previously set callback, or `NULL` if no callback was set or the + * library had not been [initialized](@ref intro_init). + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref cursor_enter + * + * @since Added in GLFW 3.0. + * + * @ingroup input + */ +GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* window, GLFWcursorenterfun cbfun); + +/*! @brief Sets the scroll callback. + * + * This function sets the scroll callback of the specified window, which is + * called when a scrolling device is used, such as a mouse wheel or scrolling + * area of a touchpad. + * + * The scroll callback receives all scrolling input, like that from a mouse + * wheel or a touchpad scrolling area. + * + * @param[in] window The window whose callback to set. + * @param[in] cbfun The new scroll callback, or `NULL` to remove the currently + * set callback. + * @return The previously set callback, or `NULL` if no callback was set or the + * library had not been [initialized](@ref intro_init). + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref scrolling + * + * @since Added in GLFW 3.0. Replaces `glfwSetMouseWheelCallback`. + * + * @ingroup input + */ +GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* window, GLFWscrollfun cbfun); + +/*! @brief Sets the file drop callback. + * + * This function sets the file drop callback of the specified window, which is + * called when one or more dragged files are dropped on the window. + * + * Because the path array and its strings may have been generated specifically + * for that event, they are not guaranteed to be valid after the callback has + * returned. If you wish to use them after the callback returns, you need to + * make a deep copy. + * + * @param[in] window The window whose callback to set. + * @param[in] cbfun The new file drop callback, or `NULL` to remove the + * currently set callback. + * @return The previously set callback, or `NULL` if no callback was set or the + * library had not been [initialized](@ref intro_init). + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref path_drop + * + * @since Added in GLFW 3.1. + * + * @ingroup input + */ +GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* window, GLFWdropfun cbfun); + +/*! @brief Returns whether the specified joystick is present. + * + * This function returns whether the specified joystick is present. + * + * @param[in] joy The [joystick](@ref joysticks) to query. + * @return `GL_TRUE` if the joystick is present, or `GL_FALSE` otherwise. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref joystick + * + * @since Added in GLFW 3.0. Replaces `glfwGetJoystickParam`. + * + * @ingroup input + */ +GLFWAPI int glfwJoystickPresent(int joy); + +/*! @brief Returns the values of all axes of the specified joystick. + * + * This function returns the values of all axes of the specified joystick. + * Each element in the array is a value between -1.0 and 1.0. + * + * @param[in] joy The [joystick](@ref joysticks) to query. + * @param[out] count Where to store the number of axis values in the returned + * array. This is set to zero if an error occurred. + * @return An array of axis values, or `NULL` if the joystick is not present. + * + * @par Pointer Lifetime + * The returned array is allocated and freed by GLFW. You should not free it + * yourself. It is valid until the specified joystick is disconnected, this + * function is called again for that joystick or the library is terminated. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref joystick_axis + * + * @since Added in GLFW 3.0. Replaces `glfwGetJoystickPos`. + * + * @ingroup input + */ +GLFWAPI const float* glfwGetJoystickAxes(int joy, int* count); + +/*! @brief Returns the state of all buttons of the specified joystick. + * + * This function returns the state of all buttons of the specified joystick. + * Each element in the array is either `GLFW_PRESS` or `GLFW_RELEASE`. + * + * @param[in] joy The [joystick](@ref joysticks) to query. + * @param[out] count Where to store the number of button states in the returned + * array. This is set to zero if an error occurred. + * @return An array of button states, or `NULL` if the joystick is not present. + * + * @par Pointer Lifetime + * The returned array is allocated and freed by GLFW. You should not free it + * yourself. It is valid until the specified joystick is disconnected, this + * function is called again for that joystick or the library is terminated. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref joystick_button + * + * @since Added in GLFW 2.2. + * + * @par + * __GLFW 3:__ Changed to return a dynamic array. + * + * @ingroup input + */ +GLFWAPI const unsigned char* glfwGetJoystickButtons(int joy, int* count); + +/*! @brief Returns the name of the specified joystick. + * + * This function returns the name, encoded as UTF-8, of the specified joystick. + * The returned string is allocated and freed by GLFW. You should not free it + * yourself. + * + * @param[in] joy The [joystick](@ref joysticks) to query. + * @return The UTF-8 encoded name of the joystick, or `NULL` if the joystick + * is not present. + * + * @par Pointer Lifetime + * The returned string is allocated and freed by GLFW. You should not free it + * yourself. It is valid until the specified joystick is disconnected, this + * function is called again for that joystick or the library is terminated. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref joystick_name + * + * @since Added in GLFW 3.0. + * + * @ingroup input + */ +GLFWAPI const char* glfwGetJoystickName(int joy); + +/*! @brief Sets the clipboard to the specified string. + * + * This function sets the system clipboard to the specified, UTF-8 encoded + * string. + * + * @param[in] window The window that will own the clipboard contents. + * @param[in] string A UTF-8 encoded string. + * + * @par Pointer Lifetime + * The specified string is copied before this function returns. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref clipboard + * @sa glfwGetClipboardString + * + * @since Added in GLFW 3.0. + * + * @ingroup input + */ +GLFWAPI void glfwSetClipboardString(GLFWwindow* window, const char* string); + +/*! @brief Returns the contents of the clipboard as a string. + * + * This function returns the contents of the system clipboard, if it contains + * or is convertible to a UTF-8 encoded string. + * + * @param[in] window The window that will request the clipboard contents. + * @return The contents of the clipboard as a UTF-8 encoded string, or `NULL` + * if an [error](@ref error_handling) occurred. + * + * @par Pointer Lifetime + * The returned string is allocated and freed by GLFW. You should not free it + * yourself. It is valid until the next call to @ref + * glfwGetClipboardString or @ref glfwSetClipboardString, or until the library + * is terminated. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref clipboard + * @sa glfwSetClipboardString + * + * @since Added in GLFW 3.0. + * + * @ingroup input + */ +GLFWAPI const char* glfwGetClipboardString(GLFWwindow* window); + +/*! @brief Returns the value of the GLFW timer. + * + * This function returns the value of the GLFW timer. Unless the timer has + * been set using @ref glfwSetTime, the timer measures time elapsed since GLFW + * was initialized. + * + * The resolution of the timer is system dependent, but is usually on the order + * of a few micro- or nanoseconds. It uses the highest-resolution monotonic + * time source on each supported platform. + * + * @return The current value, in seconds, or zero if an + * [error](@ref error_handling) occurred. + * + * @par Thread Safety + * This function may be called from any thread. Access is not synchronized. + * + * @sa @ref time + * + * @since Added in GLFW 1.0. + * + * @ingroup input + */ +GLFWAPI double glfwGetTime(void); + +/*! @brief Sets the GLFW timer. + * + * This function sets the value of the GLFW timer. It then continues to count + * up from that value. + * + * @param[in] time The new value, in seconds. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref time + * + * @since Added in GLFW 2.2. + * + * @ingroup input + */ +GLFWAPI void glfwSetTime(double time); + +/*! @brief Makes the context of the specified window current for the calling + * thread. + * + * This function makes the OpenGL or OpenGL ES context of the specified window + * current on the calling thread. A context can only be made current on + * a single thread at a time and each thread can have only a single current + * context at a time. + * + * By default, making a context non-current implicitly forces a pipeline flush. + * On machines that support `GL_KHR_context_flush_control`, you can control + * whether a context performs this flush by setting the + * [GLFW_CONTEXT_RELEASE_BEHAVIOR](@ref window_hints_ctx) window hint. + * + * @param[in] window The window whose context to make current, or `NULL` to + * detach the current context. + * + * @par Thread Safety + * This function may be called from any thread. + * + * @sa @ref context_current + * @sa glfwGetCurrentContext + * + * @since Added in GLFW 3.0. + * + * @ingroup context + */ +GLFWAPI void glfwMakeContextCurrent(GLFWwindow* window); + +/*! @brief Returns the window whose context is current on the calling thread. + * + * This function returns the window whose OpenGL or OpenGL ES context is + * current on the calling thread. + * + * @return The window whose context is current, or `NULL` if no window's + * context is current. + * + * @par Thread Safety + * This function may be called from any thread. + * + * @sa @ref context_current + * @sa glfwMakeContextCurrent + * + * @since Added in GLFW 3.0. + * + * @ingroup context + */ +GLFWAPI GLFWwindow* glfwGetCurrentContext(void); + +/*! @brief Swaps the front and back buffers of the specified window. + * + * This function swaps the front and back buffers of the specified window. If + * the swap interval is greater than zero, the GPU driver waits the specified + * number of screen updates before swapping the buffers. + * + * @param[in] window The window whose buffers to swap. + * + * @par Thread Safety + * This function may be called from any thread. + * + * @sa @ref buffer_swap + * @sa glfwSwapInterval + * + * @since Added in GLFW 1.0. + * + * @par + * __GLFW 3:__ Added window handle parameter. + * + * @ingroup window + */ +GLFWAPI void glfwSwapBuffers(GLFWwindow* window); + +/*! @brief Sets the swap interval for the current context. + * + * This function sets the swap interval for the current context, i.e. the + * number of screen updates to wait from the time @ref glfwSwapBuffers was + * called before swapping the buffers and returning. This is sometimes called + * _vertical synchronization_, _vertical retrace synchronization_ or just + * _vsync_. + * + * Contexts that support either of the `WGL_EXT_swap_control_tear` and + * `GLX_EXT_swap_control_tear` extensions also accept negative swap intervals, + * which allow the driver to swap even if a frame arrives a little bit late. + * You can check for the presence of these extensions using @ref + * glfwExtensionSupported. For more information about swap tearing, see the + * extension specifications. + * + * A context must be current on the calling thread. Calling this function + * without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error. + * + * @param[in] interval The minimum number of screen updates to wait for + * until the buffers are swapped by @ref glfwSwapBuffers. + * + * @note This function is not called during window creation, leaving the swap + * interval set to whatever is the default on that platform. This is done + * because some swap interval extensions used by GLFW do not allow the swap + * interval to be reset to zero once it has been set to a non-zero value. + * + * @note Some GPU drivers do not honor the requested swap interval, either + * because of user settings that override the request or due to bugs in the + * driver. + * + * @par Thread Safety + * This function may be called from any thread. + * + * @sa @ref buffer_swap + * @sa glfwSwapBuffers + * + * @since Added in GLFW 1.0. + * + * @ingroup context + */ +GLFWAPI void glfwSwapInterval(int interval); + +/*! @brief Returns whether the specified extension is available. + * + * This function returns whether the specified + * [API extension](@ref context_glext) is supported by the current OpenGL or + * OpenGL ES context. It searches both for OpenGL and OpenGL ES extension and + * platform-specific context creation API extensions. + * + * A context must be current on the calling thread. Calling this function + * without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error. + * + * As this functions retrieves and searches one or more extension strings each + * call, it is recommended that you cache its results if it is going to be used + * frequently. The extension strings will not change during the lifetime of + * a context, so there is no danger in doing this. + * + * @param[in] extension The ASCII encoded name of the extension. + * @return `GL_TRUE` if the extension is available, or `GL_FALSE` otherwise. + * + * @par Thread Safety + * This function may be called from any thread. + * + * @sa @ref context_glext + * @sa glfwGetProcAddress + * + * @since Added in GLFW 1.0. + * + * @ingroup context + */ +GLFWAPI int glfwExtensionSupported(const char* extension); + +/*! @brief Returns the address of the specified function for the current + * context. + * + * This function returns the address of the specified + * [client API or extension function](@ref context_glext), if it is supported + * by the current context. + * + * A context must be current on the calling thread. Calling this function + * without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error. + * + * @param[in] procname The ASCII encoded name of the function. + * @return The address of the function, or `NULL` if the function is + * unavailable or an [error](@ref error_handling) occurred. + * + * @note The addresses of a given function is not guaranteed to be the same + * between contexts. + * + * @par Pointer Lifetime + * The returned function pointer is valid until the context is destroyed or the + * library is terminated. + * + * @par Thread Safety + * This function may be called from any thread. + * + * @sa @ref context_glext + * @sa glfwExtensionSupported + * + * @since Added in GLFW 1.0. + * + * @ingroup context + */ +GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname); + + +/************************************************************************* + * Global definition cleanup + *************************************************************************/ + +/* ------------------- BEGIN SYSTEM/COMPILER SPECIFIC -------------------- */ + +#ifdef GLFW_WINGDIAPI_DEFINED + #undef WINGDIAPI + #undef GLFW_WINGDIAPI_DEFINED +#endif + +#ifdef GLFW_CALLBACK_DEFINED + #undef CALLBACK + #undef GLFW_CALLBACK_DEFINED +#endif + +/* -------------------- END SYSTEM/COMPILER SPECIFIC --------------------- */ + + +#ifdef __cplusplus +} +#endif + +#endif /* _glfw3_h_ */ + diff --git a/testbed/glfw/include/GLFW/glfw3native.h b/testbed/glfw/include/GLFW/glfw3native.h new file mode 100644 index 00000000..b3ce7482 --- /dev/null +++ b/testbed/glfw/include/GLFW/glfw3native.h @@ -0,0 +1,356 @@ +/************************************************************************* + * GLFW 3.1 - www.glfw.org + * A library for OpenGL, window and input + *------------------------------------------------------------------------ + * Copyright (c) 2002-2006 Marcus Geelnard + * Copyright (c) 2006-2010 Camilla Berglund + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would + * be appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not + * be misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + * + *************************************************************************/ + +#ifndef _glfw3_native_h_ +#define _glfw3_native_h_ + +#ifdef __cplusplus +extern "C" { +#endif + + +/************************************************************************* + * Doxygen documentation + *************************************************************************/ + +/*! @defgroup native Native access + * + * **By using the native access functions you assert that you know what you're + * doing and how to fix problems caused by using them. If you don't, you + * shouldn't be using them.** + * + * Before the inclusion of @ref glfw3native.h, you must define exactly one + * window system API macro and exactly one context creation API macro. Failure + * to do this will cause a compile-time error. + * + * The available window API macros are: + * * `GLFW_EXPOSE_NATIVE_WIN32` + * * `GLFW_EXPOSE_NATIVE_COCOA` + * * `GLFW_EXPOSE_NATIVE_X11` + * + * The available context API macros are: + * * `GLFW_EXPOSE_NATIVE_WGL` + * * `GLFW_EXPOSE_NATIVE_NSGL` + * * `GLFW_EXPOSE_NATIVE_GLX` + * * `GLFW_EXPOSE_NATIVE_EGL` + * + * These macros select which of the native access functions that are declared + * and which platform-specific headers to include. It is then up your (by + * definition platform-specific) code to handle which of these should be + * defined. + */ + + +/************************************************************************* + * System headers and types + *************************************************************************/ + +#if defined(GLFW_EXPOSE_NATIVE_WIN32) + // This is a workaround for the fact that glfw3.h needs to export APIENTRY (for + // example to allow applications to correctly declare a GL_ARB_debug_output + // callback) but windows.h assumes no one will define APIENTRY before it does + #undef APIENTRY + #include +#elif defined(GLFW_EXPOSE_NATIVE_COCOA) + #include + #if defined(__OBJC__) + #import + #else + typedef void* id; + #endif +#elif defined(GLFW_EXPOSE_NATIVE_X11) + #include + #include +#else + #error "No window API selected" +#endif + +#if defined(GLFW_EXPOSE_NATIVE_WGL) + /* WGL is declared by windows.h */ +#elif defined(GLFW_EXPOSE_NATIVE_NSGL) + /* NSGL is declared by Cocoa.h */ +#elif defined(GLFW_EXPOSE_NATIVE_GLX) + #include +#elif defined(GLFW_EXPOSE_NATIVE_EGL) + #include +#else + #error "No context API selected" +#endif + + +/************************************************************************* + * Functions + *************************************************************************/ + +#if defined(GLFW_EXPOSE_NATIVE_WIN32) +/*! @brief Returns the adapter device name of the specified monitor. + * + * @return The UTF-8 encoded adapter device name (for example `\\.\DISPLAY1`) + * of the specified monitor, or `NULL` if an [error](@ref error_handling) + * occurred. + * + * @par Thread Safety + * This function may be called from any thread. Access is not synchronized. + * + * @par History + * Added in GLFW 3.1. + * + * @ingroup native + */ +GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* monitor); + +/*! @brief Returns the display device name of the specified monitor. + * + * @return The UTF-8 encoded display device name (for example + * `\\.\DISPLAY1\Monitor0`) of the specified monitor, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @par Thread Safety + * This function may be called from any thread. Access is not synchronized. + * + * @par History + * Added in GLFW 3.1. + * + * @ingroup native + */ +GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* monitor); + +/*! @brief Returns the `HWND` of the specified window. + * + * @return The `HWND` of the specified window, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @par Thread Safety + * This function may be called from any thread. Access is not synchronized. + * + * @par History + * Added in GLFW 3.0. + * + * @ingroup native + */ +GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window); +#endif + +#if defined(GLFW_EXPOSE_NATIVE_WGL) +/*! @brief Returns the `HGLRC` of the specified window. + * + * @return The `HGLRC` of the specified window, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @par Thread Safety + * This function may be called from any thread. Access is not synchronized. + * + * @par History + * Added in GLFW 3.0. + * + * @ingroup native + */ +GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* window); +#endif + +#if defined(GLFW_EXPOSE_NATIVE_COCOA) +/*! @brief Returns the `CGDirectDisplayID` of the specified monitor. + * + * @return The `CGDirectDisplayID` of the specified monitor, or + * `kCGNullDirectDisplay` if an [error](@ref error_handling) occurred. + * + * @par Thread Safety + * This function may be called from any thread. Access is not synchronized. + * + * @par History + * Added in GLFW 3.1. + * + * @ingroup native + */ +GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor); + +/*! @brief Returns the `NSWindow` of the specified window. + * + * @return The `NSWindow` of the specified window, or `nil` if an + * [error](@ref error_handling) occurred. + * + * @par Thread Safety + * This function may be called from any thread. Access is not synchronized. + * + * @par History + * Added in GLFW 3.0. + * + * @ingroup native + */ +GLFWAPI id glfwGetCocoaWindow(GLFWwindow* window); +#endif + +#if defined(GLFW_EXPOSE_NATIVE_NSGL) +/*! @brief Returns the `NSOpenGLContext` of the specified window. + * + * @return The `NSOpenGLContext` of the specified window, or `nil` if an + * [error](@ref error_handling) occurred. + * + * @par Thread Safety + * This function may be called from any thread. Access is not synchronized. + * + * @par History + * Added in GLFW 3.0. + * + * @ingroup native + */ +GLFWAPI id glfwGetNSGLContext(GLFWwindow* window); +#endif + +#if defined(GLFW_EXPOSE_NATIVE_X11) +/*! @brief Returns the `Display` used by GLFW. + * + * @return The `Display` used by GLFW, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @par Thread Safety + * This function may be called from any thread. Access is not synchronized. + * + * @par History + * Added in GLFW 3.0. + * + * @ingroup native + */ +GLFWAPI Display* glfwGetX11Display(void); + +/*! @brief Returns the `RRCrtc` of the specified monitor. + * + * @return The `RRCrtc` of the specified monitor, or `None` if an + * [error](@ref error_handling) occurred. + * + * @par Thread Safety + * This function may be called from any thread. Access is not synchronized. + * + * @par History + * Added in GLFW 3.1. + * + * @ingroup native + */ +GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* monitor); + +/*! @brief Returns the `RROutput` of the specified monitor. + * + * @return The `RROutput` of the specified monitor, or `None` if an + * [error](@ref error_handling) occurred. + * + * @par Thread Safety + * This function may be called from any thread. Access is not synchronized. + * + * @par History + * Added in GLFW 3.1. + * + * @ingroup native + */ +GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* monitor); + +/*! @brief Returns the `Window` of the specified window. + * + * @return The `Window` of the specified window, or `None` if an + * [error](@ref error_handling) occurred. + * + * @par Thread Safety + * This function may be called from any thread. Access is not synchronized. + * + * @par History + * Added in GLFW 3.0. + * + * @ingroup native + */ +GLFWAPI Window glfwGetX11Window(GLFWwindow* window); +#endif + +#if defined(GLFW_EXPOSE_NATIVE_GLX) +/*! @brief Returns the `GLXContext` of the specified window. + * + * @return The `GLXContext` of the specified window, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @par Thread Safety + * This function may be called from any thread. Access is not synchronized. + * + * @par History + * Added in GLFW 3.0. + * + * @ingroup native + */ +GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window); +#endif + +#if defined(GLFW_EXPOSE_NATIVE_EGL) +/*! @brief Returns the `EGLDisplay` used by GLFW. + * + * @return The `EGLDisplay` used by GLFW, or `EGL_NO_DISPLAY` if an + * [error](@ref error_handling) occurred. + * + * @par Thread Safety + * This function may be called from any thread. Access is not synchronized. + * + * @par History + * Added in GLFW 3.0. + * + * @ingroup native + */ +GLFWAPI EGLDisplay glfwGetEGLDisplay(void); + +/*! @brief Returns the `EGLContext` of the specified window. + * + * @return The `EGLContext` of the specified window, or `EGL_NO_CONTEXT` if an + * [error](@ref error_handling) occurred. + * + * @par Thread Safety + * This function may be called from any thread. Access is not synchronized. + * + * @par History + * Added in GLFW 3.0. + * + * @ingroup native + */ +GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window); + +/*! @brief Returns the `EGLSurface` of the specified window. + * + * @return The `EGLSurface` of the specified window, or `EGL_NO_SURFACE` if an + * [error](@ref error_handling) occurred. + * + * @par Thread Safety + * This function may be called from any thread. Access is not synchronized. + * + * @par History + * Added in GLFW 3.0. + * + * @ingroup native + */ +GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* window); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _glfw3_native_h_ */ + diff --git a/testbed/glfw/src/CMakeLists.txt b/testbed/glfw/src/CMakeLists.txt new file mode 100644 index 00000000..e247a5ba --- /dev/null +++ b/testbed/glfw/src/CMakeLists.txt @@ -0,0 +1,95 @@ + +include_directories("${GLFW_SOURCE_DIR}/src" + "${GLFW_BINARY_DIR}/src" + ${glfw_INCLUDE_DIRS}) + +add_definitions(-D_GLFW_USE_CONFIG_H) + +set(common_HEADERS internal.h + "${GLFW_BINARY_DIR}/src/glfw_config.h" + "${GLFW_SOURCE_DIR}/include/GLFW/glfw3.h" + "${GLFW_SOURCE_DIR}/include/GLFW/glfw3native.h") +set(common_SOURCES context.c init.c input.c monitor.c window.c) + +if (_GLFW_COCOA) + set(glfw_HEADERS ${common_HEADERS} cocoa_platform.h iokit_joystick.h + posix_tls.h) + set(glfw_SOURCES ${common_SOURCES} cocoa_init.m cocoa_monitor.m + cocoa_window.m iokit_joystick.m mach_time.c posix_tls.c) +elseif (_GLFW_WIN32) + set(glfw_HEADERS ${common_HEADERS} win32_platform.h win32_tls.h + winmm_joystick.h) + set(glfw_SOURCES ${common_SOURCES} win32_init.c win32_monitor.c win32_time.c + win32_tls.c win32_window.c winmm_joystick.c) +elseif (_GLFW_X11) + set(glfw_HEADERS ${common_HEADERS} x11_platform.h xkb_unicode.h + linux_joystick.h posix_time.h posix_tls.h) + set(glfw_SOURCES ${common_SOURCES} x11_init.c x11_monitor.c x11_window.c + xkb_unicode.c linux_joystick.c posix_time.c posix_tls.c) +elseif (_GLFW_WAYLAND) + set(glfw_HEADERS ${common_HEADERS} wl_platform.h linux_joystick.h + posix_time.h posix_tls.h xkb_unicode.h) + set(glfw_SOURCES ${common_SOURCES} wl_init.c wl_monitor.c wl_window.c + linux_joystick.c posix_time.c posix_tls.c xkb_unicode.c) +elseif (_GLFW_MIR) + set(glfw_HEADERS ${common_HEADERS} mir_platform.h linux_joystick.h + posix_time.h posix_tls.h xkb_unicode.h) + set(glfw_SOURCES ${common_SOURCES} mir_init.c mir_monitor.c mir_window.c + linux_joystick.c posix_time.c posix_tls.c xkb_unicode.c) +endif() + +if (_GLFW_EGL) + list(APPEND glfw_HEADERS ${common_HEADERS} egl_context.h) + list(APPEND glfw_SOURCES ${common_SOURCES} egl_context.c) +elseif (_GLFW_NSGL) + list(APPEND glfw_HEADERS ${common_HEADERS} nsgl_context.h) + list(APPEND glfw_SOURCES ${common_SOURCES} nsgl_context.m) +elseif (_GLFW_WGL) + list(APPEND glfw_HEADERS ${common_HEADERS} wgl_context.h) + list(APPEND glfw_SOURCES ${common_SOURCES} wgl_context.c) +elseif (_GLFW_X11) + list(APPEND glfw_HEADERS ${common_HEADERS} glx_context.h) + list(APPEND glfw_SOURCES ${common_SOURCES} glx_context.c) +endif() + +if (APPLE) + # For some reason, CMake doesn't know about .m + set_source_files_properties(${glfw_SOURCES} PROPERTIES LANGUAGE C) +endif() + +add_library(glfw ${glfw_SOURCES} ${glfw_HEADERS}) +set_target_properties(glfw PROPERTIES + OUTPUT_NAME "${GLFW_LIB_NAME}" + VERSION ${GLFW_VERSION} + SOVERSION ${GLFW_VERSION_MAJOR} + POSITION_INDEPENDENT_CODE ON + FOLDER "GLFW3") + +if (BUILD_SHARED_LIBS) + if (WIN32) + # The GLFW DLL needs a special compile-time macro and import library name + set_target_properties(glfw PROPERTIES PREFIX "" IMPORT_PREFIX "") + + if (MINGW) + set_target_properties(glfw PROPERTIES IMPORT_SUFFIX "dll.a") + else() + set_target_properties(glfw PROPERTIES IMPORT_SUFFIX "dll.lib") + endif() + elseif (APPLE) + # Append -fno-common to the compile flags to work around a bug in + # Apple's GCC + get_target_property(glfw_CFLAGS glfw COMPILE_FLAGS) + if (NOT glfw_CFLAGS) + set(glfw_CFLAGS "") + endif() + set_target_properties(glfw PROPERTIES + COMPILE_FLAGS "${glfw_CFLAGS} -fno-common" + INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}") + endif() + target_link_libraries(glfw ${glfw_LIBRARIES}) +endif() + +if (GLFW_INSTALL) + install(TARGETS glfw EXPORT glfwTargets DESTINATION lib${LIB_SUFFIX}) +endif() + diff --git a/testbed/glfw/src/cocoa_init.m b/testbed/glfw/src/cocoa_init.m new file mode 100644 index 00000000..8779cdfa --- /dev/null +++ b/testbed/glfw/src/cocoa_init.m @@ -0,0 +1,272 @@ +//======================================================================== +// GLFW 3.1 OS X - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2009-2010 Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include "internal.h" +#include // For MAXPATHLEN + + +#if defined(_GLFW_USE_CHDIR) + +// Change to our application bundle's resources directory, if present +// +static void changeToResourcesDirectory(void) +{ + char resourcesPath[MAXPATHLEN]; + + CFBundleRef bundle = CFBundleGetMainBundle(); + if (!bundle) + return; + + CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(bundle); + + CFStringRef last = CFURLCopyLastPathComponent(resourcesURL); + if (CFStringCompare(CFSTR("Resources"), last, 0) != kCFCompareEqualTo) + { + CFRelease(last); + CFRelease(resourcesURL); + return; + } + + CFRelease(last); + + if (!CFURLGetFileSystemRepresentation(resourcesURL, + true, + (UInt8*) resourcesPath, + MAXPATHLEN)) + { + CFRelease(resourcesURL); + return; + } + + CFRelease(resourcesURL); + + chdir(resourcesPath); +} + +#endif /* _GLFW_USE_CHDIR */ + +// Create key code translation tables +// +static void createKeyTables(void) +{ + memset(_glfw.ns.publicKeys, -1, sizeof(_glfw.ns.publicKeys)); + + _glfw.ns.publicKeys[0x1D] = GLFW_KEY_0; + _glfw.ns.publicKeys[0x12] = GLFW_KEY_1; + _glfw.ns.publicKeys[0x13] = GLFW_KEY_2; + _glfw.ns.publicKeys[0x14] = GLFW_KEY_3; + _glfw.ns.publicKeys[0x15] = GLFW_KEY_4; + _glfw.ns.publicKeys[0x17] = GLFW_KEY_5; + _glfw.ns.publicKeys[0x16] = GLFW_KEY_6; + _glfw.ns.publicKeys[0x1A] = GLFW_KEY_7; + _glfw.ns.publicKeys[0x1C] = GLFW_KEY_8; + _glfw.ns.publicKeys[0x19] = GLFW_KEY_9; + _glfw.ns.publicKeys[0x00] = GLFW_KEY_A; + _glfw.ns.publicKeys[0x0B] = GLFW_KEY_B; + _glfw.ns.publicKeys[0x08] = GLFW_KEY_C; + _glfw.ns.publicKeys[0x02] = GLFW_KEY_D; + _glfw.ns.publicKeys[0x0E] = GLFW_KEY_E; + _glfw.ns.publicKeys[0x03] = GLFW_KEY_F; + _glfw.ns.publicKeys[0x05] = GLFW_KEY_G; + _glfw.ns.publicKeys[0x04] = GLFW_KEY_H; + _glfw.ns.publicKeys[0x22] = GLFW_KEY_I; + _glfw.ns.publicKeys[0x26] = GLFW_KEY_J; + _glfw.ns.publicKeys[0x28] = GLFW_KEY_K; + _glfw.ns.publicKeys[0x25] = GLFW_KEY_L; + _glfw.ns.publicKeys[0x2E] = GLFW_KEY_M; + _glfw.ns.publicKeys[0x2D] = GLFW_KEY_N; + _glfw.ns.publicKeys[0x1F] = GLFW_KEY_O; + _glfw.ns.publicKeys[0x23] = GLFW_KEY_P; + _glfw.ns.publicKeys[0x0C] = GLFW_KEY_Q; + _glfw.ns.publicKeys[0x0F] = GLFW_KEY_R; + _glfw.ns.publicKeys[0x01] = GLFW_KEY_S; + _glfw.ns.publicKeys[0x11] = GLFW_KEY_T; + _glfw.ns.publicKeys[0x20] = GLFW_KEY_U; + _glfw.ns.publicKeys[0x09] = GLFW_KEY_V; + _glfw.ns.publicKeys[0x0D] = GLFW_KEY_W; + _glfw.ns.publicKeys[0x07] = GLFW_KEY_X; + _glfw.ns.publicKeys[0x10] = GLFW_KEY_Y; + _glfw.ns.publicKeys[0x06] = GLFW_KEY_Z; + + _glfw.ns.publicKeys[0x27] = GLFW_KEY_APOSTROPHE; + _glfw.ns.publicKeys[0x2A] = GLFW_KEY_BACKSLASH; + _glfw.ns.publicKeys[0x2B] = GLFW_KEY_COMMA; + _glfw.ns.publicKeys[0x18] = GLFW_KEY_EQUAL; + _glfw.ns.publicKeys[0x32] = GLFW_KEY_GRAVE_ACCENT; + _glfw.ns.publicKeys[0x21] = GLFW_KEY_LEFT_BRACKET; + _glfw.ns.publicKeys[0x1B] = GLFW_KEY_MINUS; + _glfw.ns.publicKeys[0x2F] = GLFW_KEY_PERIOD; + _glfw.ns.publicKeys[0x1E] = GLFW_KEY_RIGHT_BRACKET; + _glfw.ns.publicKeys[0x29] = GLFW_KEY_SEMICOLON; + _glfw.ns.publicKeys[0x2C] = GLFW_KEY_SLASH; + _glfw.ns.publicKeys[0x0A] = GLFW_KEY_WORLD_1; + + _glfw.ns.publicKeys[0x33] = GLFW_KEY_BACKSPACE; + _glfw.ns.publicKeys[0x39] = GLFW_KEY_CAPS_LOCK; + _glfw.ns.publicKeys[0x75] = GLFW_KEY_DELETE; + _glfw.ns.publicKeys[0x7D] = GLFW_KEY_DOWN; + _glfw.ns.publicKeys[0x77] = GLFW_KEY_END; + _glfw.ns.publicKeys[0x24] = GLFW_KEY_ENTER; + _glfw.ns.publicKeys[0x35] = GLFW_KEY_ESCAPE; + _glfw.ns.publicKeys[0x7A] = GLFW_KEY_F1; + _glfw.ns.publicKeys[0x78] = GLFW_KEY_F2; + _glfw.ns.publicKeys[0x63] = GLFW_KEY_F3; + _glfw.ns.publicKeys[0x76] = GLFW_KEY_F4; + _glfw.ns.publicKeys[0x60] = GLFW_KEY_F5; + _glfw.ns.publicKeys[0x61] = GLFW_KEY_F6; + _glfw.ns.publicKeys[0x62] = GLFW_KEY_F7; + _glfw.ns.publicKeys[0x64] = GLFW_KEY_F8; + _glfw.ns.publicKeys[0x65] = GLFW_KEY_F9; + _glfw.ns.publicKeys[0x6D] = GLFW_KEY_F10; + _glfw.ns.publicKeys[0x67] = GLFW_KEY_F11; + _glfw.ns.publicKeys[0x6F] = GLFW_KEY_F12; + _glfw.ns.publicKeys[0x69] = GLFW_KEY_F13; + _glfw.ns.publicKeys[0x6B] = GLFW_KEY_F14; + _glfw.ns.publicKeys[0x71] = GLFW_KEY_F15; + _glfw.ns.publicKeys[0x6A] = GLFW_KEY_F16; + _glfw.ns.publicKeys[0x40] = GLFW_KEY_F17; + _glfw.ns.publicKeys[0x4F] = GLFW_KEY_F18; + _glfw.ns.publicKeys[0x50] = GLFW_KEY_F19; + _glfw.ns.publicKeys[0x5A] = GLFW_KEY_F20; + _glfw.ns.publicKeys[0x73] = GLFW_KEY_HOME; + _glfw.ns.publicKeys[0x72] = GLFW_KEY_INSERT; + _glfw.ns.publicKeys[0x7B] = GLFW_KEY_LEFT; + _glfw.ns.publicKeys[0x3A] = GLFW_KEY_LEFT_ALT; + _glfw.ns.publicKeys[0x3B] = GLFW_KEY_LEFT_CONTROL; + _glfw.ns.publicKeys[0x38] = GLFW_KEY_LEFT_SHIFT; + _glfw.ns.publicKeys[0x37] = GLFW_KEY_LEFT_SUPER; + _glfw.ns.publicKeys[0x6E] = GLFW_KEY_MENU; + _glfw.ns.publicKeys[0x47] = GLFW_KEY_NUM_LOCK; + _glfw.ns.publicKeys[0x79] = GLFW_KEY_PAGE_DOWN; + _glfw.ns.publicKeys[0x74] = GLFW_KEY_PAGE_UP; + _glfw.ns.publicKeys[0x7C] = GLFW_KEY_RIGHT; + _glfw.ns.publicKeys[0x3D] = GLFW_KEY_RIGHT_ALT; + _glfw.ns.publicKeys[0x3E] = GLFW_KEY_RIGHT_CONTROL; + _glfw.ns.publicKeys[0x3C] = GLFW_KEY_RIGHT_SHIFT; + _glfw.ns.publicKeys[0x36] = GLFW_KEY_RIGHT_SUPER; + _glfw.ns.publicKeys[0x31] = GLFW_KEY_SPACE; + _glfw.ns.publicKeys[0x30] = GLFW_KEY_TAB; + _glfw.ns.publicKeys[0x7E] = GLFW_KEY_UP; + + _glfw.ns.publicKeys[0x52] = GLFW_KEY_KP_0; + _glfw.ns.publicKeys[0x53] = GLFW_KEY_KP_1; + _glfw.ns.publicKeys[0x54] = GLFW_KEY_KP_2; + _glfw.ns.publicKeys[0x55] = GLFW_KEY_KP_3; + _glfw.ns.publicKeys[0x56] = GLFW_KEY_KP_4; + _glfw.ns.publicKeys[0x57] = GLFW_KEY_KP_5; + _glfw.ns.publicKeys[0x58] = GLFW_KEY_KP_6; + _glfw.ns.publicKeys[0x59] = GLFW_KEY_KP_7; + _glfw.ns.publicKeys[0x5B] = GLFW_KEY_KP_8; + _glfw.ns.publicKeys[0x5C] = GLFW_KEY_KP_9; + _glfw.ns.publicKeys[0x45] = GLFW_KEY_KP_ADD; + _glfw.ns.publicKeys[0x41] = GLFW_KEY_KP_DECIMAL; + _glfw.ns.publicKeys[0x4B] = GLFW_KEY_KP_DIVIDE; + _glfw.ns.publicKeys[0x4C] = GLFW_KEY_KP_ENTER; + _glfw.ns.publicKeys[0x51] = GLFW_KEY_KP_EQUAL; + _glfw.ns.publicKeys[0x43] = GLFW_KEY_KP_MULTIPLY; + _glfw.ns.publicKeys[0x4E] = GLFW_KEY_KP_SUBTRACT; +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +int _glfwPlatformInit(void) +{ + _glfw.ns.autoreleasePool = [[NSAutoreleasePool alloc] init]; + +#if defined(_GLFW_USE_CHDIR) + changeToResourcesDirectory(); +#endif + + createKeyTables(); + + _glfw.ns.eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState); + if (!_glfw.ns.eventSource) + return GL_FALSE; + + CGEventSourceSetLocalEventsSuppressionInterval(_glfw.ns.eventSource, 0.0); + + if (!_glfwInitContextAPI()) + return GL_FALSE; + + _glfwInitTimer(); + _glfwInitJoysticks(); + + return GL_TRUE; +} + +void _glfwPlatformTerminate(void) +{ + if (_glfw.ns.eventSource) + { + CFRelease(_glfw.ns.eventSource); + _glfw.ns.eventSource = NULL; + } + + if (_glfw.ns.delegate) + { + [NSApp setDelegate:nil]; + [_glfw.ns.delegate release]; + _glfw.ns.delegate = nil; + } + + [_glfw.ns.autoreleasePool release]; + _glfw.ns.autoreleasePool = nil; + + [_glfw.ns.cursor release]; + _glfw.ns.cursor = nil; + + free(_glfw.ns.clipboardString); + + _glfwTerminateJoysticks(); + _glfwTerminateContextAPI(); +} + +const char* _glfwPlatformGetVersionString(void) +{ + const char* version = _GLFW_VERSION_NUMBER " Cocoa" +#if defined(_GLFW_NSGL) + " NSGL" +#endif +#if defined(_GLFW_USE_CHDIR) + " chdir" +#endif +#if defined(_GLFW_USE_MENUBAR) + " menubar" +#endif +#if defined(_GLFW_USE_RETINA) + " retina" +#endif +#if defined(_GLFW_BUILD_DLL) + " dynamic" +#endif + ; + + return version; +} + diff --git a/testbed/glfw/src/cocoa_monitor.m b/testbed/glfw/src/cocoa_monitor.m new file mode 100644 index 00000000..d518973a --- /dev/null +++ b/testbed/glfw/src/cocoa_monitor.m @@ -0,0 +1,439 @@ +//======================================================================== +// GLFW 3.1 OS X - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2010 Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include "internal.h" + +#include +#include +#include + +#include +#include +#include +#include +#include + + +// Get the name of the specified display +// +static char* getDisplayName(CGDirectDisplayID displayID) +{ + char* name; + CFDictionaryRef info, names; + CFStringRef value; + CFIndex size; + + // NOTE: This uses a deprecated function because Apple has + // (as of January 2015) not provided any alternative + info = IODisplayCreateInfoDictionary(CGDisplayIOServicePort(displayID), + kIODisplayOnlyPreferredName); + names = CFDictionaryGetValue(info, CFSTR(kDisplayProductName)); + + if (!names || !CFDictionaryGetValueIfPresent(names, CFSTR("en_US"), + (const void**) &value)) + { + // This may happen if a desktop Mac is running headless + _glfwInputError(GLFW_PLATFORM_ERROR, "Failed to retrieve display name"); + + CFRelease(info); + return strdup("Unknown"); + } + + size = CFStringGetMaximumSizeForEncoding(CFStringGetLength(value), + kCFStringEncodingUTF8); + name = calloc(size + 1, sizeof(char)); + CFStringGetCString(value, name, size, kCFStringEncodingUTF8); + + CFRelease(info); + + return name; +} + +// Check whether the display mode should be included in enumeration +// +static GLboolean modeIsGood(CGDisplayModeRef mode) +{ + uint32_t flags = CGDisplayModeGetIOFlags(mode); + if (!(flags & kDisplayModeValidFlag) || !(flags & kDisplayModeSafeFlag)) + return GL_FALSE; + + if (flags & kDisplayModeInterlacedFlag) + return GL_FALSE; + + if (flags & kDisplayModeStretchedFlag) + return GL_FALSE; + + CFStringRef format = CGDisplayModeCopyPixelEncoding(mode); + if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) && + CFStringCompare(format, CFSTR(IO32BitDirectPixels), 0)) + { + CFRelease(format); + return GL_FALSE; + } + + CFRelease(format); + return GL_TRUE; +} + +// Convert Core Graphics display mode to GLFW video mode +// +static GLFWvidmode vidmodeFromCGDisplayMode(CGDisplayModeRef mode, + CVDisplayLinkRef link) +{ + GLFWvidmode result; + result.width = (int) CGDisplayModeGetWidth(mode); + result.height = (int) CGDisplayModeGetHeight(mode); + result.refreshRate = (int) CGDisplayModeGetRefreshRate(mode); + + if (result.refreshRate == 0) + { + const CVTime time = CVDisplayLinkGetNominalOutputVideoRefreshPeriod(link); + if (!(time.flags & kCVTimeIsIndefinite)) + result.refreshRate = (int) (time.timeScale / (double) time.timeValue); + } + + CFStringRef format = CGDisplayModeCopyPixelEncoding(mode); + + if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) == 0) + { + result.redBits = 5; + result.greenBits = 5; + result.blueBits = 5; + } + else + { + result.redBits = 8; + result.greenBits = 8; + result.blueBits = 8; + } + + CFRelease(format); + return result; +} + +// Starts reservation for display fading +// +static CGDisplayFadeReservationToken beginFadeReservation(void) +{ + CGDisplayFadeReservationToken token = kCGDisplayFadeReservationInvalidToken; + + if (CGAcquireDisplayFadeReservation(5, &token) == kCGErrorSuccess) + CGDisplayFade(token, 0.3, kCGDisplayBlendNormal, kCGDisplayBlendSolidColor, 0.0, 0.0, 0.0, TRUE); + + return token; +} + +// Ends reservation for display fading +// +static void endFadeReservation(CGDisplayFadeReservationToken token) +{ + if (token != kCGDisplayFadeReservationInvalidToken) + { + CGDisplayFade(token, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0, FALSE); + CGReleaseDisplayFadeReservation(token); + } +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +// Change the current video mode +// +GLboolean _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired) +{ + CFArrayRef modes; + CFIndex count, i; + CVDisplayLinkRef link; + CGDisplayModeRef native = NULL; + GLFWvidmode current; + const GLFWvidmode* best; + + best = _glfwChooseVideoMode(monitor, desired); + _glfwPlatformGetVideoMode(monitor, ¤t); + if (_glfwCompareVideoModes(¤t, best) == 0) + return GL_TRUE; + + CVDisplayLinkCreateWithCGDisplay(monitor->ns.displayID, &link); + + modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL); + count = CFArrayGetCount(modes); + + for (i = 0; i < count; i++) + { + CGDisplayModeRef dm = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i); + if (!modeIsGood(dm)) + continue; + + const GLFWvidmode mode = vidmodeFromCGDisplayMode(dm, link); + if (_glfwCompareVideoModes(best, &mode) == 0) + { + native = dm; + break; + } + } + + if (native) + { + if (monitor->ns.previousMode == NULL) + monitor->ns.previousMode = CGDisplayCopyDisplayMode(monitor->ns.displayID); + + CGDisplayFadeReservationToken token = beginFadeReservation(); + CGDisplaySetDisplayMode(monitor->ns.displayID, native, NULL); + endFadeReservation(token); + } + + CFRelease(modes); + CVDisplayLinkRelease(link); + + if (!native) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Cocoa: Monitor mode list changed"); + return GL_FALSE; + } + + return GL_TRUE; +} + +// Restore the previously saved (original) video mode +// +void _glfwRestoreVideoMode(_GLFWmonitor* monitor) +{ + if (monitor->ns.previousMode) + { + CGDisplayFadeReservationToken token = beginFadeReservation(); + CGDisplaySetDisplayMode(monitor->ns.displayID, + monitor->ns.previousMode, NULL); + endFadeReservation(token); + + CGDisplayModeRelease(monitor->ns.previousMode); + monitor->ns.previousMode = NULL; + } +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +_GLFWmonitor** _glfwPlatformGetMonitors(int* count) +{ + uint32_t i, found = 0, displayCount; + _GLFWmonitor** monitors; + CGDirectDisplayID* displays; + + *count = 0; + + CGGetOnlineDisplayList(0, NULL, &displayCount); + + displays = calloc(displayCount, sizeof(CGDirectDisplayID)); + monitors = calloc(displayCount, sizeof(_GLFWmonitor*)); + + CGGetOnlineDisplayList(displayCount, displays, &displayCount); + + NSArray* screens = [NSScreen screens]; + + for (i = 0; i < displayCount; i++) + { + int j; + + if (CGDisplayIsAsleep(displays[i])) + continue; + + CGDirectDisplayID screenDisplayID = CGDisplayMirrorsDisplay(displays[i]); + if (screenDisplayID == kCGNullDirectDisplay) + screenDisplayID = displays[i]; + + const CGSize size = CGDisplayScreenSize(displays[i]); + char* name = getDisplayName(displays[i]); + + monitors[found] = _glfwAllocMonitor(name, size.width, size.height); + monitors[found]->ns.displayID = displays[i]; + + free(name); + + for (j = 0; j < [screens count]; j++) + { + NSScreen* screen = [screens objectAtIndex:j]; + NSDictionary* dictionary = [screen deviceDescription]; + NSNumber* number = [dictionary objectForKey:@"NSScreenNumber"]; + + if ([number unsignedIntegerValue] == screenDisplayID) + { + monitors[found]->ns.screen = screen; + break; + } + } + + if (monitors[found]->ns.screen) + found++; + else + { + _glfwFreeMonitor(monitors[found]); + monitors[found] = NULL; + } + } + + free(displays); + + *count = found; + return monitors; +} + +GLboolean _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second) +{ + return first->ns.displayID == second->ns.displayID; +} + +void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos) +{ + const CGRect bounds = CGDisplayBounds(monitor->ns.displayID); + + if (xpos) + *xpos = (int) bounds.origin.x; + if (ypos) + *ypos = (int) bounds.origin.y; +} + +GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found) +{ + CFArrayRef modes; + CFIndex count, i, j; + GLFWvidmode* result; + CVDisplayLinkRef link; + + CVDisplayLinkCreateWithCGDisplay(monitor->ns.displayID, &link); + + modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL); + count = CFArrayGetCount(modes); + + result = calloc(count, sizeof(GLFWvidmode)); + *found = 0; + + for (i = 0; i < count; i++) + { + CGDisplayModeRef dm = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i); + if (!modeIsGood(dm)) + continue; + + const GLFWvidmode mode = vidmodeFromCGDisplayMode(dm, link); + + for (j = 0; j < *found; j++) + { + if (_glfwCompareVideoModes(result + j, &mode) == 0) + break; + } + + if (i < *found) + { + // This is a duplicate, so skip it + continue; + } + + result[*found] = mode; + (*found)++; + } + + CFRelease(modes); + + CVDisplayLinkRelease(link); + return result; +} + +void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode *mode) +{ + CGDisplayModeRef displayMode; + CVDisplayLinkRef link; + + CVDisplayLinkCreateWithCGDisplay(monitor->ns.displayID, &link); + + displayMode = CGDisplayCopyDisplayMode(monitor->ns.displayID); + *mode = vidmodeFromCGDisplayMode(displayMode, link); + CGDisplayModeRelease(displayMode); + + CVDisplayLinkRelease(link); +} + +void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) +{ + uint32_t i, size = CGDisplayGammaTableCapacity(monitor->ns.displayID); + CGGammaValue* values = calloc(size * 3, sizeof(CGGammaValue)); + + CGGetDisplayTransferByTable(monitor->ns.displayID, + size, + values, + values + size, + values + size * 2, + &size); + + _glfwAllocGammaArrays(ramp, size); + + for (i = 0; i < size; i++) + { + ramp->red[i] = (unsigned short) (values[i] * 65535); + ramp->green[i] = (unsigned short) (values[i + size] * 65535); + ramp->blue[i] = (unsigned short) (values[i + size * 2] * 65535); + } + + free(values); +} + +void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) +{ + int i; + CGGammaValue* values = calloc(ramp->size * 3, sizeof(CGGammaValue)); + + for (i = 0; i < ramp->size; i++) + { + values[i] = ramp->red[i] / 65535.f; + values[i + ramp->size] = ramp->green[i] / 65535.f; + values[i + ramp->size * 2] = ramp->blue[i] / 65535.f; + } + + CGSetDisplayTransferByTable(monitor->ns.displayID, + ramp->size, + values, + values + ramp->size, + values + ramp->size * 2); + + free(values); +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW native API ////// +////////////////////////////////////////////////////////////////////////// + +GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* handle) +{ + _GLFWmonitor* monitor = (_GLFWmonitor*) handle; + _GLFW_REQUIRE_INIT_OR_RETURN(kCGNullDirectDisplay); + return monitor->ns.displayID; +} + diff --git a/testbed/glfw/src/cocoa_platform.h b/testbed/glfw/src/cocoa_platform.h new file mode 100644 index 00000000..7e131be6 --- /dev/null +++ b/testbed/glfw/src/cocoa_platform.h @@ -0,0 +1,124 @@ +//======================================================================== +// GLFW 3.1 OS X - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2009-2010 Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#ifndef _cocoa_platform_h_ +#define _cocoa_platform_h_ + + +#include + +#if defined(__OBJC__) +#import +#else +#include +typedef void* id; +#endif + +#include "posix_tls.h" + +#if defined(_GLFW_NSGL) + #include "nsgl_context.h" +#else + #error "No supported context creation API selected" +#endif + +#include "iokit_joystick.h" + +#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowNS ns +#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryNS ns +#define _GLFW_PLATFORM_LIBRARY_TIME_STATE _GLFWtimeNS ns_time +#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorNS ns +#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorNS ns + + +// Cocoa-specific per-window data +// +typedef struct _GLFWwindowNS +{ + id object; + id delegate; + id view; + unsigned int modifierFlags; + + // The total sum of the distances the cursor has been warped + // since the last cursor motion event was processed + // This is kept to counteract Cocoa doing the same internally + double warpDeltaX, warpDeltaY; + +} _GLFWwindowNS; + + +// Cocoa-specific global data +// +typedef struct _GLFWlibraryNS +{ + CGEventSourceRef eventSource; + id delegate; + id autoreleasePool; + id cursor; + + short int publicKeys[256]; + char* clipboardString; + +} _GLFWlibraryNS; + + +// Cocoa-specific per-monitor data +// +typedef struct _GLFWmonitorNS +{ + CGDirectDisplayID displayID; + CGDisplayModeRef previousMode; + id screen; + +} _GLFWmonitorNS; + + +// Cocoa-specific per-cursor data +// +typedef struct _GLFWcursorNS +{ + id object; + +} _GLFWcursorNS; + + +// Cocoa-specific global timer data +// +typedef struct _GLFWtimeNS +{ + double base; + double resolution; + +} _GLFWtimeNS; + + +void _glfwInitTimer(void); + +GLboolean _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired); +void _glfwRestoreVideoMode(_GLFWmonitor* monitor); + +#endif // _cocoa_platform_h_ diff --git a/testbed/glfw/src/cocoa_window.m b/testbed/glfw/src/cocoa_window.m new file mode 100644 index 00000000..9d182f42 --- /dev/null +++ b/testbed/glfw/src/cocoa_window.m @@ -0,0 +1,1284 @@ +//======================================================================== +// GLFW 3.1 OS X - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2009-2010 Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include "internal.h" + +#include + +// Needed for _NSGetProgname +#include + + +// Returns the specified standard cursor +// +static NSCursor* getStandardCursor(int shape) +{ + switch (shape) + { + case GLFW_ARROW_CURSOR: + return [NSCursor arrowCursor]; + case GLFW_IBEAM_CURSOR: + return [NSCursor IBeamCursor]; + case GLFW_CROSSHAIR_CURSOR: + return [NSCursor crosshairCursor]; + case GLFW_HAND_CURSOR: + return [NSCursor pointingHandCursor]; + case GLFW_HRESIZE_CURSOR: + return [NSCursor resizeLeftRightCursor]; + case GLFW_VRESIZE_CURSOR: + return [NSCursor resizeUpDownCursor]; + } + + return nil; +} + +// Center the cursor in the view of the window +// +static void centerCursor(_GLFWwindow *window) +{ + int width, height; + _glfwPlatformGetWindowSize(window, &width, &height); + _glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0); +} + +// Update the cursor to match the specified cursor mode +// +static void updateModeCursor(_GLFWwindow* window) +{ + if (window->cursorMode == GLFW_CURSOR_NORMAL) + { + if (window->cursor) + [(NSCursor*) window->cursor->ns.object set]; + else + [[NSCursor arrowCursor] set]; + } + else + [(NSCursor*) _glfw.ns.cursor set]; +} + +// Enter full screen mode +// +static GLboolean enterFullscreenMode(_GLFWwindow* window) +{ + GLboolean status; + + status = _glfwSetVideoMode(window->monitor, &window->videoMode); + + // NOTE: The window is resized despite mode setting failure to make + // glfwSetWindowSize more robust + [window->ns.object setFrame:[window->monitor->ns.screen frame] + display:YES]; + + return status; +} + +// Leave full screen mode +// +static void leaveFullscreenMode(_GLFWwindow* window) +{ + _glfwRestoreVideoMode(window->monitor); +} + +// Transforms the specified y-coordinate between the CG display and NS screen +// coordinate systems +// +static float transformY(float y) +{ + const float height = CGDisplayBounds(CGMainDisplayID()).size.height; + return height - y; +} + +// Returns the backing rect of the specified window +// +static NSRect convertRectToBacking(_GLFWwindow* window, NSRect contentRect) +{ +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 + if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) + return [window->ns.view convertRectToBacking:contentRect]; + else +#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ + return contentRect; +} + + +//------------------------------------------------------------------------ +// Delegate for window related notifications +//------------------------------------------------------------------------ + +@interface GLFWWindowDelegate : NSObject +{ + _GLFWwindow* window; +} + +- (id)initWithGlfwWindow:(_GLFWwindow *)initWindow; + +@end + +@implementation GLFWWindowDelegate + +- (id)initWithGlfwWindow:(_GLFWwindow *)initWindow +{ + self = [super init]; + if (self != nil) + window = initWindow; + + return self; +} + +- (BOOL)windowShouldClose:(id)sender +{ + _glfwInputWindowCloseRequest(window); + return NO; +} + +- (void)windowDidResize:(NSNotification *)notification +{ + if (_glfw.focusedWindow == window && + window->cursorMode == GLFW_CURSOR_DISABLED) + { + centerCursor(window); + } + + const NSRect contentRect = [window->ns.view frame]; + const NSRect fbRect = convertRectToBacking(window, contentRect); + + _glfwInputFramebufferSize(window, fbRect.size.width, fbRect.size.height); + _glfwInputWindowSize(window, contentRect.size.width, contentRect.size.height); + _glfwInputWindowDamage(window); +} + +- (void)windowDidMove:(NSNotification *)notification +{ + if (_glfw.focusedWindow == window && + window->cursorMode == GLFW_CURSOR_DISABLED) + { + centerCursor(window); + } + + int x, y; + _glfwPlatformGetWindowPos(window, &x, &y); + _glfwInputWindowPos(window, x, y); +} + +- (void)windowDidMiniaturize:(NSNotification *)notification +{ + _glfwInputWindowIconify(window, GL_TRUE); +} + +- (void)windowDidDeminiaturize:(NSNotification *)notification +{ + _glfwInputWindowIconify(window, GL_FALSE); +} + +- (void)windowDidBecomeKey:(NSNotification *)notification +{ + if (window->monitor) + enterFullscreenMode(window); + + if (_glfw.focusedWindow == window && + window->cursorMode == GLFW_CURSOR_DISABLED) + { + centerCursor(window); + } + + _glfwInputWindowFocus(window, GL_TRUE); + _glfwPlatformApplyCursorMode(window); +} + +- (void)windowDidResignKey:(NSNotification *)notification +{ + if (window->monitor) + leaveFullscreenMode(window); + + _glfwInputWindowFocus(window, GL_FALSE); +} + +@end + + +//------------------------------------------------------------------------ +// Delegate for application related notifications +//------------------------------------------------------------------------ + +@interface GLFWApplicationDelegate : NSObject +@end + +@implementation GLFWApplicationDelegate + +- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender +{ + _GLFWwindow* window; + + for (window = _glfw.windowListHead; window; window = window->next) + _glfwInputWindowCloseRequest(window); + + return NSTerminateCancel; +} + +- (void)applicationDidChangeScreenParameters:(NSNotification *) notification +{ + _glfwInputMonitorChange(); +} + +- (void)applicationDidFinishLaunching:(NSNotification *)notification +{ + [NSApp stop:nil]; + + _glfwPlatformPostEmptyEvent(); +} + +@end + +// Translates OS X key modifiers into GLFW ones +// +static int translateFlags(NSUInteger flags) +{ + int mods = 0; + + if (flags & NSShiftKeyMask) + mods |= GLFW_MOD_SHIFT; + if (flags & NSControlKeyMask) + mods |= GLFW_MOD_CONTROL; + if (flags & NSAlternateKeyMask) + mods |= GLFW_MOD_ALT; + if (flags & NSCommandKeyMask) + mods |= GLFW_MOD_SUPER; + + return mods; +} + +// Translates a OS X keycode to a GLFW keycode +// +static int translateKey(unsigned int key) +{ + if (key >= sizeof(_glfw.ns.publicKeys) / sizeof(_glfw.ns.publicKeys[0])) + return GLFW_KEY_UNKNOWN; + + return _glfw.ns.publicKeys[key]; +} + + +//------------------------------------------------------------------------ +// Content view class for the GLFW window +//------------------------------------------------------------------------ + +@interface GLFWContentView : NSOpenGLView +{ + _GLFWwindow* window; + NSTrackingArea* trackingArea; +} + +- (id)initWithGlfwWindow:(_GLFWwindow *)initWindow; + +@end + +@implementation GLFWContentView + ++ (void)initialize +{ + if (self == [GLFWContentView class]) + { + if (_glfw.ns.cursor == nil) + { + NSImage* data = [[NSImage alloc] initWithSize:NSMakeSize(16, 16)]; + _glfw.ns.cursor = [[NSCursor alloc] initWithImage:data + hotSpot:NSZeroPoint]; + [data release]; + } + } +} + +- (id)initWithGlfwWindow:(_GLFWwindow *)initWindow +{ + self = [super initWithFrame:NSMakeRect(0, 0, 1, 1) + pixelFormat:nil]; + if (self != nil) + { + window = initWindow; + trackingArea = nil; + + [self updateTrackingAreas]; + [self registerForDraggedTypes:[NSArray arrayWithObjects: + NSFilenamesPboardType, nil]]; + } + + return self; +} + +-(void)dealloc +{ + [trackingArea release]; + [super dealloc]; +} + +- (BOOL)isOpaque +{ + return YES; +} + +- (BOOL)canBecomeKeyView +{ + return YES; +} + +- (BOOL)acceptsFirstResponder +{ + return YES; +} + +- (void)cursorUpdate:(NSEvent *)event +{ + updateModeCursor(window); +} + +- (void)mouseDown:(NSEvent *)event +{ + _glfwInputMouseClick(window, + GLFW_MOUSE_BUTTON_LEFT, + GLFW_PRESS, + translateFlags([event modifierFlags])); +} + +- (void)mouseDragged:(NSEvent *)event +{ + [self mouseMoved:event]; +} + +- (void)mouseUp:(NSEvent *)event +{ + _glfwInputMouseClick(window, + GLFW_MOUSE_BUTTON_LEFT, + GLFW_RELEASE, + translateFlags([event modifierFlags])); +} + +- (void)mouseMoved:(NSEvent *)event +{ + if (window->cursorMode == GLFW_CURSOR_DISABLED) + { + _glfwInputCursorMotion(window, + [event deltaX] - window->ns.warpDeltaX, + [event deltaY] - window->ns.warpDeltaY); + } + else + { + const NSRect contentRect = [window->ns.view frame]; + const NSPoint pos = [event locationInWindow]; + + _glfwInputCursorMotion(window, pos.x, contentRect.size.height - pos.y); + } + + window->ns.warpDeltaX = 0; + window->ns.warpDeltaY = 0; +} + +- (void)rightMouseDown:(NSEvent *)event +{ + _glfwInputMouseClick(window, + GLFW_MOUSE_BUTTON_RIGHT, + GLFW_PRESS, + translateFlags([event modifierFlags])); +} + +- (void)rightMouseDragged:(NSEvent *)event +{ + [self mouseMoved:event]; +} + +- (void)rightMouseUp:(NSEvent *)event +{ + _glfwInputMouseClick(window, + GLFW_MOUSE_BUTTON_RIGHT, + GLFW_RELEASE, + translateFlags([event modifierFlags])); +} + +- (void)otherMouseDown:(NSEvent *)event +{ + _glfwInputMouseClick(window, + (int) [event buttonNumber], + GLFW_PRESS, + translateFlags([event modifierFlags])); +} + +- (void)otherMouseDragged:(NSEvent *)event +{ + [self mouseMoved:event]; +} + +- (void)otherMouseUp:(NSEvent *)event +{ + _glfwInputMouseClick(window, + (int) [event buttonNumber], + GLFW_RELEASE, + translateFlags([event modifierFlags])); +} + +- (void)mouseExited:(NSEvent *)event +{ + _glfwInputCursorEnter(window, GL_FALSE); +} + +- (void)mouseEntered:(NSEvent *)event +{ + _glfwInputCursorEnter(window, GL_TRUE); +} + +- (void)viewDidChangeBackingProperties +{ + const NSRect contentRect = [window->ns.view frame]; + const NSRect fbRect = convertRectToBacking(window, contentRect); + + _glfwInputFramebufferSize(window, fbRect.size.width, fbRect.size.height); + _glfwInputWindowDamage(window); +} + +- (void)updateTrackingAreas +{ + if (trackingArea != nil) + { + [self removeTrackingArea:trackingArea]; + [trackingArea release]; + } + + const NSTrackingAreaOptions options = NSTrackingMouseEnteredAndExited | + NSTrackingActiveInKeyWindow | + NSTrackingEnabledDuringMouseDrag | + NSTrackingCursorUpdate | + NSTrackingInVisibleRect | + NSTrackingAssumeInside; + + trackingArea = [[NSTrackingArea alloc] initWithRect:[self bounds] + options:options + owner:self + userInfo:nil]; + + [self addTrackingArea:trackingArea]; + [super updateTrackingAreas]; +} + +- (void)keyDown:(NSEvent *)event +{ + const int key = translateKey([event keyCode]); + const int mods = translateFlags([event modifierFlags]); + + _glfwInputKey(window, key, [event keyCode], GLFW_PRESS, mods); + + NSString* characters = [event characters]; + NSUInteger i, length = [characters length]; + const int plain = !(mods & GLFW_MOD_SUPER); + + for (i = 0; i < length; i++) + { + const unichar codepoint = [characters characterAtIndex:i]; + if ((codepoint & 0xff00) == 0xf700) + continue; + + _glfwInputChar(window, codepoint, mods, plain); + } +} + +- (void)flagsChanged:(NSEvent *)event +{ + int action; + const unsigned int modifierFlags = + [event modifierFlags] & NSDeviceIndependentModifierFlagsMask; + const int key = translateKey([event keyCode]); + const int mods = translateFlags(modifierFlags); + + if (modifierFlags == window->ns.modifierFlags) + { + if (window->keys[key] == GLFW_PRESS) + action = GLFW_RELEASE; + else + action = GLFW_PRESS; + } + else if (modifierFlags > window->ns.modifierFlags) + action = GLFW_PRESS; + else + action = GLFW_RELEASE; + + window->ns.modifierFlags = modifierFlags; + + _glfwInputKey(window, key, [event keyCode], action, mods); +} + +- (void)keyUp:(NSEvent *)event +{ + const int key = translateKey([event keyCode]); + const int mods = translateFlags([event modifierFlags]); + _glfwInputKey(window, key, [event keyCode], GLFW_RELEASE, mods); +} + +- (void)scrollWheel:(NSEvent *)event +{ + double deltaX, deltaY; + +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 + if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) + { + deltaX = [event scrollingDeltaX]; + deltaY = [event scrollingDeltaY]; + + if ([event hasPreciseScrollingDeltas]) + { + deltaX *= 0.1; + deltaY *= 0.1; + } + } + else +#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ + { + deltaX = [event deltaX]; + deltaY = [event deltaY]; + } + + if (fabs(deltaX) > 0.0 || fabs(deltaY) > 0.0) + _glfwInputScroll(window, deltaX, deltaY); +} + +- (NSDragOperation)draggingEntered:(id )sender +{ + if ((NSDragOperationGeneric & [sender draggingSourceOperationMask]) + == NSDragOperationGeneric) + { + [self setNeedsDisplay:YES]; + return NSDragOperationGeneric; + } + + return NSDragOperationNone; +} + +- (BOOL)prepareForDragOperation:(id )sender +{ + [self setNeedsDisplay:YES]; + return YES; +} + +- (BOOL)performDragOperation:(id )sender +{ + NSPasteboard* pasteboard = [sender draggingPasteboard]; + NSArray* files = [pasteboard propertyListForType:NSFilenamesPboardType]; + + const NSRect contentRect = [window->ns.view frame]; + _glfwInputCursorMotion(window, + [sender draggingLocation].x, + contentRect.size.height - [sender draggingLocation].y); + + const int count = [files count]; + if (count) + { + NSEnumerator* e = [files objectEnumerator]; + char** names = calloc(count, sizeof(char*)); + int i; + + for (i = 0; i < count; i++) + names[i] = strdup([[e nextObject] UTF8String]); + + _glfwInputDrop(window, count, (const char**) names); + + for (i = 0; i < count; i++) + free(names[i]); + free(names); + } + + return YES; +} + +- (void)concludeDragOperation:(id )sender +{ + [self setNeedsDisplay:YES]; +} + +@end + + +//------------------------------------------------------------------------ +// GLFW window class +//------------------------------------------------------------------------ + +@interface GLFWWindow : NSWindow {} +@end + +@implementation GLFWWindow + +- (BOOL)canBecomeKeyWindow +{ + // Required for NSBorderlessWindowMask windows + return YES; +} + +@end + + +//------------------------------------------------------------------------ +// GLFW application class +//------------------------------------------------------------------------ + +@interface GLFWApplication : NSApplication +@end + +@implementation GLFWApplication + +// From http://cocoadev.com/index.pl?GameKeyboardHandlingAlmost +// This works around an AppKit bug, where key up events while holding +// down the command key don't get sent to the key window. +- (void)sendEvent:(NSEvent *)event +{ + if ([event type] == NSKeyUp && ([event modifierFlags] & NSCommandKeyMask)) + [[self keyWindow] sendEvent:event]; + else + [super sendEvent:event]; +} + +@end + +#if defined(_GLFW_USE_MENUBAR) + +// Try to figure out what the calling application is called +// +static NSString* findAppName(void) +{ + size_t i; + NSDictionary* infoDictionary = [[NSBundle mainBundle] infoDictionary]; + + // Keys to search for as potential application names + NSString* GLFWNameKeys[] = + { + @"CFBundleDisplayName", + @"CFBundleName", + @"CFBundleExecutable", + }; + + for (i = 0; i < sizeof(GLFWNameKeys) / sizeof(GLFWNameKeys[0]); i++) + { + id name = [infoDictionary objectForKey:GLFWNameKeys[i]]; + if (name && + [name isKindOfClass:[NSString class]] && + ![name isEqualToString:@""]) + { + return name; + } + } + + char** progname = _NSGetProgname(); + if (progname && *progname) + return [NSString stringWithUTF8String:*progname]; + + // Really shouldn't get here + return @"GLFW Application"; +} + +// Set up the menu bar (manually) +// This is nasty, nasty stuff -- calls to undocumented semi-private APIs that +// could go away at any moment, lots of stuff that really should be +// localize(d|able), etc. Loading a nib would save us this horror, but that +// doesn't seem like a good thing to require of GLFW users. +// +static void createMenuBar(void) +{ + NSString* appName = findAppName(); + + NSMenu* bar = [[NSMenu alloc] init]; + [NSApp setMainMenu:bar]; + + NSMenuItem* appMenuItem = + [bar addItemWithTitle:@"" action:NULL keyEquivalent:@""]; + NSMenu* appMenu = [[NSMenu alloc] init]; + [appMenuItem setSubmenu:appMenu]; + + [appMenu addItemWithTitle:[NSString stringWithFormat:@"About %@", appName] + action:@selector(orderFrontStandardAboutPanel:) + keyEquivalent:@""]; + [appMenu addItem:[NSMenuItem separatorItem]]; + NSMenu* servicesMenu = [[NSMenu alloc] init]; + [NSApp setServicesMenu:servicesMenu]; + [[appMenu addItemWithTitle:@"Services" + action:NULL + keyEquivalent:@""] setSubmenu:servicesMenu]; + [appMenu addItem:[NSMenuItem separatorItem]]; + [appMenu addItemWithTitle:[NSString stringWithFormat:@"Hide %@", appName] + action:@selector(hide:) + keyEquivalent:@"h"]; + [[appMenu addItemWithTitle:@"Hide Others" + action:@selector(hideOtherApplications:) + keyEquivalent:@"h"] + setKeyEquivalentModifierMask:NSAlternateKeyMask | NSCommandKeyMask]; + [appMenu addItemWithTitle:@"Show All" + action:@selector(unhideAllApplications:) + keyEquivalent:@""]; + [appMenu addItem:[NSMenuItem separatorItem]]; + [appMenu addItemWithTitle:[NSString stringWithFormat:@"Quit %@", appName] + action:@selector(terminate:) + keyEquivalent:@"q"]; + + NSMenuItem* windowMenuItem = + [bar addItemWithTitle:@"" action:NULL keyEquivalent:@""]; + NSMenu* windowMenu = [[NSMenu alloc] initWithTitle:@"Window"]; + [NSApp setWindowsMenu:windowMenu]; + [windowMenuItem setSubmenu:windowMenu]; + + [windowMenu addItemWithTitle:@"Minimize" + action:@selector(performMiniaturize:) + keyEquivalent:@"m"]; + [windowMenu addItemWithTitle:@"Zoom" + action:@selector(performZoom:) + keyEquivalent:@""]; + [windowMenu addItem:[NSMenuItem separatorItem]]; + [windowMenu addItemWithTitle:@"Bring All to Front" + action:@selector(arrangeInFront:) + keyEquivalent:@""]; + +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 + if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) + { + // TODO: Make this appear at the bottom of the menu (for consistency) + + [windowMenu addItem:[NSMenuItem separatorItem]]; + [[windowMenu addItemWithTitle:@"Enter Full Screen" + action:@selector(toggleFullScreen:) + keyEquivalent:@"f"] + setKeyEquivalentModifierMask:NSControlKeyMask | NSCommandKeyMask]; + } +#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ + + // Prior to Snow Leopard, we need to use this oddly-named semi-private API + // to get the application menu working properly. + SEL setAppleMenuSelector = NSSelectorFromString(@"setAppleMenu:"); + [NSApp performSelector:setAppleMenuSelector withObject:appMenu]; +} + +#endif /* _GLFW_USE_MENUBAR */ + +// Initialize the Cocoa Application Kit +// +static GLboolean initializeAppKit(void) +{ + if (NSApp) + return GL_TRUE; + + // Implicitly create shared NSApplication instance + [GLFWApplication sharedApplication]; + + // In case we are unbundled, make us a proper UI application + [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; + +#if defined(_GLFW_USE_MENUBAR) + // Menu bar setup must go between sharedApplication above and + // finishLaunching below, in order to properly emulate the behavior + // of NSApplicationMain + createMenuBar(); +#endif + + // There can only be one application delegate, but we allocate it the + // first time a window is created to keep all window code in this file + _glfw.ns.delegate = [[GLFWApplicationDelegate alloc] init]; + if (_glfw.ns.delegate == nil) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Cocoa: Failed to create application delegate"); + return GL_FALSE; + } + + [NSApp setDelegate:_glfw.ns.delegate]; + [NSApp run]; + + return GL_TRUE; +} + +// Create the Cocoa window +// +static GLboolean createWindow(_GLFWwindow* window, + const _GLFWwndconfig* wndconfig) +{ + window->ns.delegate = [[GLFWWindowDelegate alloc] initWithGlfwWindow:window]; + if (window->ns.delegate == nil) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Cocoa: Failed to create window delegate"); + return GL_FALSE; + } + + unsigned int styleMask = 0; + + if (wndconfig->monitor || !wndconfig->decorated) + styleMask = NSBorderlessWindowMask; + else + { + styleMask = NSTitledWindowMask | NSClosableWindowMask | + NSMiniaturizableWindowMask; + + if (wndconfig->resizable) + styleMask |= NSResizableWindowMask; + } + + NSRect contentRect; + + if (wndconfig->monitor) + contentRect = [wndconfig->monitor->ns.screen frame]; + else + contentRect = NSMakeRect(0, 0, wndconfig->width, wndconfig->height); + + window->ns.object = [[GLFWWindow alloc] + initWithContentRect:contentRect + styleMask:styleMask + backing:NSBackingStoreBuffered + defer:NO]; + + if (window->ns.object == nil) + { + _glfwInputError(GLFW_PLATFORM_ERROR, "Cocoa: Failed to create window"); + return GL_FALSE; + } + +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 + if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) + { + if (wndconfig->resizable) + [window->ns.object setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; + } +#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ + + if (wndconfig->monitor) + { + [window->ns.object setLevel:NSMainMenuWindowLevel + 1]; + [window->ns.object setHidesOnDeactivate:YES]; + } + else + { + [window->ns.object center]; + + if (wndconfig->floating) + [window->ns.object setLevel:NSFloatingWindowLevel]; + } + + [window->ns.object setTitle:[NSString stringWithUTF8String:wndconfig->title]]; + [window->ns.object setDelegate:window->ns.delegate]; + [window->ns.object setAcceptsMouseMovedEvents:YES]; + +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 + if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) + [window->ns.object setRestorable:NO]; +#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ + + return GL_TRUE; +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +int _glfwPlatformCreateWindow(_GLFWwindow* window, + const _GLFWwndconfig* wndconfig, + const _GLFWctxconfig* ctxconfig, + const _GLFWfbconfig* fbconfig) +{ + if (!initializeAppKit()) + return GL_FALSE; + + if (!createWindow(window, wndconfig)) + return GL_FALSE; + + if (!_glfwCreateContext(window, ctxconfig, fbconfig)) + return GL_FALSE; + + window->ns.view = [[GLFWContentView alloc] initWithGlfwWindow:window]; + +#if defined(_GLFW_USE_RETINA) +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 + if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) + [window->ns.view setWantsBestResolutionOpenGLSurface:YES]; +#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ +#endif /*_GLFW_USE_RETINA*/ + + [window->ns.object setContentView:window->ns.view]; + // NOTE: If you set the pixel format before the context it creates another + // context, only to have it destroyed by the next line + // We cannot use the view to create the context because that interface + // does not support context resource sharing + [window->ns.view setOpenGLContext:window->nsgl.context]; + [window->ns.view setPixelFormat:window->nsgl.pixelFormat]; + [window->nsgl.context setView:window->ns.view]; + + if (wndconfig->monitor) + { + _glfwPlatformShowWindow(window); + if (!enterFullscreenMode(window)) + return GL_FALSE; + } + + return GL_TRUE; +} + +void _glfwPlatformDestroyWindow(_GLFWwindow* window) +{ + [window->ns.object orderOut:nil]; + + if (window->monitor) + leaveFullscreenMode(window); + + _glfwDestroyContext(window); + + [window->ns.object setDelegate:nil]; + [window->ns.delegate release]; + window->ns.delegate = nil; + + [window->ns.view release]; + window->ns.view = nil; + + [window->ns.object close]; + window->ns.object = nil; +} + +void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char *title) +{ + [window->ns.object setTitle:[NSString stringWithUTF8String:title]]; +} + +void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos) +{ + const NSRect contentRect = + [window->ns.object contentRectForFrameRect:[window->ns.object frame]]; + + if (xpos) + *xpos = contentRect.origin.x; + if (ypos) + *ypos = transformY(contentRect.origin.y + contentRect.size.height); +} + +void _glfwPlatformSetWindowPos(_GLFWwindow* window, int x, int y) +{ + const NSRect contentRect = [window->ns.view frame]; + const NSRect dummyRect = NSMakeRect(x, transformY(y + contentRect.size.height), 0, 0); + const NSRect frameRect = [window->ns.object frameRectForContentRect:dummyRect]; + [window->ns.object setFrameOrigin:frameRect.origin]; +} + +void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height) +{ + const NSRect contentRect = [window->ns.view frame]; + + if (width) + *width = contentRect.size.width; + if (height) + *height = contentRect.size.height; +} + +void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) +{ + [window->ns.object setContentSize:NSMakeSize(width, height)]; +} + +void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height) +{ + const NSRect contentRect = [window->ns.view frame]; + const NSRect fbRect = convertRectToBacking(window, contentRect); + + if (width) + *width = (int) fbRect.size.width; + if (height) + *height = (int) fbRect.size.height; +} + +void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, + int* left, int* top, + int* right, int* bottom) +{ + const NSRect contentRect = [window->ns.view frame]; + const NSRect frameRect = [window->ns.object frameRectForContentRect:contentRect]; + + if (left) + *left = contentRect.origin.x - frameRect.origin.x; + if (top) + *top = frameRect.origin.y + frameRect.size.height - + contentRect.origin.y - contentRect.size.height; + if (right) + *right = frameRect.origin.x + frameRect.size.width - + contentRect.origin.x - contentRect.size.width; + if (bottom) + *bottom = contentRect.origin.y - frameRect.origin.y; +} + +void _glfwPlatformIconifyWindow(_GLFWwindow* window) +{ + [window->ns.object miniaturize:nil]; +} + +void _glfwPlatformRestoreWindow(_GLFWwindow* window) +{ + [window->ns.object deminiaturize:nil]; +} + +void _glfwPlatformShowWindow(_GLFWwindow* window) +{ + // Make us the active application + // HACK: This has been moved here from initializeAppKit to prevent + // applications using only hidden windows from being activated, but + // should probably not be done every time any window is shown + [NSApp activateIgnoringOtherApps:YES]; + + [window->ns.object makeKeyAndOrderFront:nil]; +} + +void _glfwPlatformUnhideWindow(_GLFWwindow* window) +{ + [window->ns.object orderFront:nil]; +} + +void _glfwPlatformHideWindow(_GLFWwindow* window) +{ + [window->ns.object orderOut:nil]; +} + +int _glfwPlatformWindowFocused(_GLFWwindow* window) +{ + return [window->ns.object isKeyWindow]; +} + +int _glfwPlatformWindowIconified(_GLFWwindow* window) +{ + return [window->ns.object isMiniaturized]; +} + +int _glfwPlatformWindowVisible(_GLFWwindow* window) +{ + return [window->ns.object isVisible]; +} + +void _glfwPlatformPollEvents(void) +{ + for (;;) + { + NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask + untilDate:[NSDate distantPast] + inMode:NSDefaultRunLoopMode + dequeue:YES]; + if (event == nil) + break; + + [NSApp sendEvent:event]; + } + + [_glfw.ns.autoreleasePool drain]; + _glfw.ns.autoreleasePool = [[NSAutoreleasePool alloc] init]; +} + +void _glfwPlatformWaitEvents(void) +{ + // I wanted to pass NO to dequeue:, and rely on PollEvents to + // dequeue and send. For reasons not at all clear to me, passing + // NO to dequeue: causes this method never to return. + NSEvent *event = [NSApp nextEventMatchingMask:NSAnyEventMask + untilDate:[NSDate distantFuture] + inMode:NSDefaultRunLoopMode + dequeue:YES]; + [NSApp sendEvent:event]; + + _glfwPlatformPollEvents(); +} + +void _glfwPlatformPostEmptyEvent(void) +{ + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + NSEvent* event = [NSEvent otherEventWithType:NSApplicationDefined + location:NSMakePoint(0, 0) + modifierFlags:0 + timestamp:0 + windowNumber:0 + context:nil + subtype:0 + data1:0 + data2:0]; + [NSApp postEvent:event atStart:YES]; + [pool drain]; +} + +void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos) +{ + const NSRect contentRect = [window->ns.view frame]; + const NSPoint pos = [window->ns.object mouseLocationOutsideOfEventStream]; + + if (xpos) + *xpos = pos.x; + if (ypos) + *ypos = contentRect.size.height - pos.y - 1; +} + +void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y) +{ + updateModeCursor(window); + + const NSRect contentRect = [window->ns.view frame]; + const NSPoint pos = [window->ns.object mouseLocationOutsideOfEventStream]; + + window->ns.warpDeltaX += x - pos.x; + window->ns.warpDeltaY += y - contentRect.size.height + pos.y; + + if (window->monitor) + { + CGDisplayMoveCursorToPoint(window->monitor->ns.displayID, + CGPointMake(x, y)); + } + else + { + const NSPoint localPoint = NSMakePoint(x, contentRect.size.height - y - 1); + const NSPoint globalPoint = [window->ns.object convertBaseToScreen:localPoint]; + + CGWarpMouseCursorPosition(CGPointMake(globalPoint.x, + transformY(globalPoint.y))); + } +} + +void _glfwPlatformApplyCursorMode(_GLFWwindow* window) +{ + updateModeCursor(window); + + if (window->cursorMode == GLFW_CURSOR_DISABLED) + CGAssociateMouseAndMouseCursorPosition(false); + else + CGAssociateMouseAndMouseCursorPosition(true); +} + +int _glfwPlatformCreateCursor(_GLFWcursor* cursor, + const GLFWimage* image, + int xhot, int yhot) +{ + NSImage* native; + NSBitmapImageRep* rep; + + rep = [[NSBitmapImageRep alloc] + initWithBitmapDataPlanes:NULL + pixelsWide:image->width + pixelsHigh:image->height + bitsPerSample:8 + samplesPerPixel:4 + hasAlpha:YES + isPlanar:NO + colorSpaceName:NSCalibratedRGBColorSpace + bitmapFormat:NSAlphaNonpremultipliedBitmapFormat + bytesPerRow:image->width * 4 + bitsPerPixel:32]; + + if (rep == nil) + return GL_FALSE; + + memcpy([rep bitmapData], image->pixels, image->width * image->height * 4); + + native = [[NSImage alloc] initWithSize:NSMakeSize(image->width, image->height)]; + [native addRepresentation: rep]; + + cursor->ns.object = [[NSCursor alloc] initWithImage:native + hotSpot:NSMakePoint(xhot, yhot)]; + + [native release]; + [rep release]; + + if (cursor->ns.object == nil) + return GL_FALSE; + + return GL_TRUE; +} + +int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape) +{ + cursor->ns.object = getStandardCursor(shape); + if (!cursor->ns.object) + { + _glfwInputError(GLFW_INVALID_ENUM, "Cocoa: Invalid standard cursor"); + return GL_FALSE; + } + + [cursor->ns.object retain]; + return GL_TRUE; +} + +void _glfwPlatformDestroyCursor(_GLFWcursor* cursor) +{ + if (cursor->ns.object) + [(NSCursor*) cursor->ns.object release]; +} + +void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) +{ + const NSPoint pos = [window->ns.object mouseLocationOutsideOfEventStream]; + + if (window->cursorMode == GLFW_CURSOR_NORMAL && + [window->ns.view mouse:pos inRect:[window->ns.view frame]]) + { + if (cursor) + [(NSCursor*) cursor->ns.object set]; + else + [[NSCursor arrowCursor] set]; + } +} + +void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string) +{ + NSArray* types = [NSArray arrayWithObjects:NSStringPboardType, nil]; + + NSPasteboard* pasteboard = [NSPasteboard generalPasteboard]; + [pasteboard declareTypes:types owner:nil]; + [pasteboard setString:[NSString stringWithUTF8String:string] + forType:NSStringPboardType]; +} + +const char* _glfwPlatformGetClipboardString(_GLFWwindow* window) +{ + NSPasteboard* pasteboard = [NSPasteboard generalPasteboard]; + + if (![[pasteboard types] containsObject:NSStringPboardType]) + { + _glfwInputError(GLFW_FORMAT_UNAVAILABLE, NULL); + return NULL; + } + + NSString* object = [pasteboard stringForType:NSStringPboardType]; + if (!object) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Cocoa: Failed to retrieve object from pasteboard"); + return NULL; + } + + free(_glfw.ns.clipboardString); + _glfw.ns.clipboardString = strdup([object UTF8String]); + + return _glfw.ns.clipboardString; +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW native API ////// +////////////////////////////////////////////////////////////////////////// + +GLFWAPI id glfwGetCocoaWindow(GLFWwindow* handle) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + _GLFW_REQUIRE_INIT_OR_RETURN(nil); + return window->ns.object; +} + diff --git a/testbed/glfw/src/context.c b/testbed/glfw/src/context.c new file mode 100644 index 00000000..f8b80085 --- /dev/null +++ b/testbed/glfw/src/context.c @@ -0,0 +1,665 @@ +//======================================================================== +// GLFW 3.1 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2010 Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include "internal.h" + +#include +#include +#include +#include + + +// Parses the client API version string and extracts the version number +// +static GLboolean parseVersionString(int* api, int* major, int* minor, int* rev) +{ + int i; + const char* version; + const char* prefixes[] = + { + "OpenGL ES-CM ", + "OpenGL ES-CL ", + "OpenGL ES ", + NULL + }; + + *api = GLFW_OPENGL_API; + + version = (const char*) glGetString(GL_VERSION); + if (!version) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Failed to retrieve context version string"); + return GL_FALSE; + } + + for (i = 0; prefixes[i]; i++) + { + const size_t length = strlen(prefixes[i]); + + if (strncmp(version, prefixes[i], length) == 0) + { + version += length; + *api = GLFW_OPENGL_ES_API; + break; + } + } + + if (!sscanf(version, "%d.%d.%d", major, minor, rev)) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "No version found in context version string"); + return GL_FALSE; + } + + return GL_TRUE; +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +GLboolean _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig) +{ + if (ctxconfig->api != GLFW_OPENGL_API && + ctxconfig->api != GLFW_OPENGL_ES_API) + { + _glfwInputError(GLFW_INVALID_ENUM, "Invalid client API requested"); + return GL_FALSE; + } + + if (ctxconfig->api == GLFW_OPENGL_API) + { + if ((ctxconfig->major < 1 || ctxconfig->minor < 0) || + (ctxconfig->major == 1 && ctxconfig->minor > 5) || + (ctxconfig->major == 2 && ctxconfig->minor > 1) || + (ctxconfig->major == 3 && ctxconfig->minor > 3)) + { + // OpenGL 1.0 is the smallest valid version + // OpenGL 1.x series ended with version 1.5 + // OpenGL 2.x series ended with version 2.1 + // OpenGL 3.x series ended with version 3.3 + + _glfwInputError(GLFW_INVALID_VALUE, + "Invalid OpenGL version %i.%i requested", + ctxconfig->major, ctxconfig->minor); + return GL_FALSE; + } + else + { + // For now, let everything else through + } + + if (ctxconfig->profile) + { + if (ctxconfig->profile != GLFW_OPENGL_CORE_PROFILE && + ctxconfig->profile != GLFW_OPENGL_COMPAT_PROFILE) + { + _glfwInputError(GLFW_INVALID_ENUM, + "Invalid OpenGL profile requested"); + return GL_FALSE; + } + + if (ctxconfig->major < 3 || + (ctxconfig->major == 3 && ctxconfig->minor < 2)) + { + // Desktop OpenGL context profiles are only defined for version 3.2 + // and above + + _glfwInputError(GLFW_INVALID_VALUE, + "Context profiles only exist for " + "OpenGL version 3.2 and above"); + return GL_FALSE; + } + } + + if (ctxconfig->forward && ctxconfig->major < 3) + { + // Forward-compatible contexts are only defined for OpenGL version 3.0 and above + _glfwInputError(GLFW_INVALID_VALUE, + "Forward compatibility only exist for OpenGL " + "version 3.0 and above"); + return GL_FALSE; + } + } + else if (ctxconfig->api == GLFW_OPENGL_ES_API) + { + if (ctxconfig->major < 1 || ctxconfig->minor < 0 || + (ctxconfig->major == 1 && ctxconfig->minor > 1) || + (ctxconfig->major == 2 && ctxconfig->minor > 0)) + { + // OpenGL ES 1.0 is the smallest valid version + // OpenGL ES 1.x series ended with version 1.1 + // OpenGL ES 2.x series ended with version 2.0 + + _glfwInputError(GLFW_INVALID_VALUE, + "Invalid OpenGL ES version %i.%i requested", + ctxconfig->major, ctxconfig->minor); + return GL_FALSE; + } + else + { + // For now, let everything else through + } + + if (ctxconfig->profile) + { + // OpenGL ES does not support profiles + _glfwInputError(GLFW_INVALID_VALUE, + "Context profiles are not supported by OpenGL ES"); + return GL_FALSE; + } + + if (ctxconfig->forward) + { + // OpenGL ES does not support forward-compatibility + _glfwInputError(GLFW_INVALID_VALUE, + "Forward compatibility is not supported by OpenGL ES"); + return GL_FALSE; + } + } + + if (ctxconfig->robustness) + { + if (ctxconfig->robustness != GLFW_NO_RESET_NOTIFICATION && + ctxconfig->robustness != GLFW_LOSE_CONTEXT_ON_RESET) + { + _glfwInputError(GLFW_INVALID_VALUE, + "Invalid context robustness mode requested"); + return GL_FALSE; + } + } + + if (ctxconfig->release) + { + if (ctxconfig->release != GLFW_RELEASE_BEHAVIOR_NONE && + ctxconfig->release != GLFW_RELEASE_BEHAVIOR_FLUSH) + { + _glfwInputError(GLFW_INVALID_VALUE, + "Invalid context release behavior requested"); + return GL_FALSE; + } + } + + return GL_TRUE; +} + +const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired, + const _GLFWfbconfig* alternatives, + unsigned int count) +{ + unsigned int i; + unsigned int missing, leastMissing = UINT_MAX; + unsigned int colorDiff, leastColorDiff = UINT_MAX; + unsigned int extraDiff, leastExtraDiff = UINT_MAX; + const _GLFWfbconfig* current; + const _GLFWfbconfig* closest = NULL; + + for (i = 0; i < count; i++) + { + current = alternatives + i; + + if (desired->stereo > 0 && current->stereo == 0) + { + // Stereo is a hard constraint + continue; + } + + if (desired->doublebuffer != current->doublebuffer) + { + // Double buffering is a hard constraint + continue; + } + + // Count number of missing buffers + { + missing = 0; + + if (desired->alphaBits > 0 && current->alphaBits == 0) + missing++; + + if (desired->depthBits > 0 && current->depthBits == 0) + missing++; + + if (desired->stencilBits > 0 && current->stencilBits == 0) + missing++; + + if (desired->auxBuffers > 0 && + current->auxBuffers < desired->auxBuffers) + { + missing += desired->auxBuffers - current->auxBuffers; + } + + if (desired->samples > 0 && current->samples == 0) + { + // Technically, several multisampling buffers could be + // involved, but that's a lower level implementation detail and + // not important to us here, so we count them as one + missing++; + } + } + + // These polynomials make many small channel size differences matter + // less than one large channel size difference + + // Calculate color channel size difference value + { + colorDiff = 0; + + if (desired->redBits != GLFW_DONT_CARE) + { + colorDiff += (desired->redBits - current->redBits) * + (desired->redBits - current->redBits); + } + + if (desired->greenBits != GLFW_DONT_CARE) + { + colorDiff += (desired->greenBits - current->greenBits) * + (desired->greenBits - current->greenBits); + } + + if (desired->blueBits != GLFW_DONT_CARE) + { + colorDiff += (desired->blueBits - current->blueBits) * + (desired->blueBits - current->blueBits); + } + } + + // Calculate non-color channel size difference value + { + extraDiff = 0; + + if (desired->alphaBits != GLFW_DONT_CARE) + { + extraDiff += (desired->alphaBits - current->alphaBits) * + (desired->alphaBits - current->alphaBits); + } + + if (desired->depthBits != GLFW_DONT_CARE) + { + extraDiff += (desired->depthBits - current->depthBits) * + (desired->depthBits - current->depthBits); + } + + if (desired->stencilBits != GLFW_DONT_CARE) + { + extraDiff += (desired->stencilBits - current->stencilBits) * + (desired->stencilBits - current->stencilBits); + } + + if (desired->accumRedBits != GLFW_DONT_CARE) + { + extraDiff += (desired->accumRedBits - current->accumRedBits) * + (desired->accumRedBits - current->accumRedBits); + } + + if (desired->accumGreenBits != GLFW_DONT_CARE) + { + extraDiff += (desired->accumGreenBits - current->accumGreenBits) * + (desired->accumGreenBits - current->accumGreenBits); + } + + if (desired->accumBlueBits != GLFW_DONT_CARE) + { + extraDiff += (desired->accumBlueBits - current->accumBlueBits) * + (desired->accumBlueBits - current->accumBlueBits); + } + + if (desired->accumAlphaBits != GLFW_DONT_CARE) + { + extraDiff += (desired->accumAlphaBits - current->accumAlphaBits) * + (desired->accumAlphaBits - current->accumAlphaBits); + } + + if (desired->samples != GLFW_DONT_CARE) + { + extraDiff += (desired->samples - current->samples) * + (desired->samples - current->samples); + } + + if (desired->sRGB && !current->sRGB) + extraDiff++; + } + + // Figure out if the current one is better than the best one found so far + // Least number of missing buffers is the most important heuristic, + // then color buffer size match and lastly size match for other buffers + + if (missing < leastMissing) + closest = current; + else if (missing == leastMissing) + { + if ((colorDiff < leastColorDiff) || + (colorDiff == leastColorDiff && extraDiff < leastExtraDiff)) + { + closest = current; + } + } + + if (current == closest) + { + leastMissing = missing; + leastColorDiff = colorDiff; + leastExtraDiff = extraDiff; + } + } + + return closest; +} + +GLboolean _glfwRefreshContextAttribs(const _GLFWctxconfig* ctxconfig) +{ + _GLFWwindow* window = _glfwPlatformGetCurrentContext(); + + if (!parseVersionString(&window->context.api, + &window->context.major, + &window->context.minor, + &window->context.revision)) + { + return GL_FALSE; + } + +#if defined(_GLFW_USE_OPENGL) + if (window->context.major > 2) + { + // OpenGL 3.0+ uses a different function for extension string retrieval + // We cache it here instead of in glfwExtensionSupported mostly to alert + // users as early as possible that their build may be broken + + window->GetStringi = (PFNGLGETSTRINGIPROC) glfwGetProcAddress("glGetStringi"); + if (!window->GetStringi) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Entry point retrieval is broken"); + return GL_FALSE; + } + } + + if (window->context.api == GLFW_OPENGL_API) + { + // Read back context flags (OpenGL 3.0 and above) + if (window->context.major >= 3) + { + GLint flags; + glGetIntegerv(GL_CONTEXT_FLAGS, &flags); + + if (flags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT) + window->context.forward = GL_TRUE; + + if (flags & GL_CONTEXT_FLAG_DEBUG_BIT) + window->context.debug = GL_TRUE; + else if (glfwExtensionSupported("GL_ARB_debug_output") && + ctxconfig->debug) + { + // HACK: This is a workaround for older drivers (pre KHR_debug) + // not setting the debug bit in the context flags for + // debug contexts + window->context.debug = GL_TRUE; + } + } + + // Read back OpenGL context profile (OpenGL 3.2 and above) + if (window->context.major > 3 || + (window->context.major == 3 && window->context.minor >= 2)) + { + GLint mask; + glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &mask); + + if (mask & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) + window->context.profile = GLFW_OPENGL_COMPAT_PROFILE; + else if (mask & GL_CONTEXT_CORE_PROFILE_BIT) + window->context.profile = GLFW_OPENGL_CORE_PROFILE; + else if (glfwExtensionSupported("GL_ARB_compatibility")) + { + // HACK: This is a workaround for the compatibility profile bit + // not being set in the context flags if an OpenGL 3.2+ + // context was created without having requested a specific + // version + window->context.profile = GLFW_OPENGL_COMPAT_PROFILE; + } + } + + // Read back robustness strategy + if (glfwExtensionSupported("GL_ARB_robustness")) + { + // NOTE: We avoid using the context flags for detection, as they are + // only present from 3.0 while the extension applies from 1.1 + + GLint strategy; + glGetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_ARB, &strategy); + + if (strategy == GL_LOSE_CONTEXT_ON_RESET_ARB) + window->context.robustness = GLFW_LOSE_CONTEXT_ON_RESET; + else if (strategy == GL_NO_RESET_NOTIFICATION_ARB) + window->context.robustness = GLFW_NO_RESET_NOTIFICATION; + } + } + else + { + // Read back robustness strategy + if (glfwExtensionSupported("GL_EXT_robustness")) + { + // NOTE: The values of these constants match those of the OpenGL ARB + // one, so we can reuse them here + + GLint strategy; + glGetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_ARB, &strategy); + + if (strategy == GL_LOSE_CONTEXT_ON_RESET_ARB) + window->context.robustness = GLFW_LOSE_CONTEXT_ON_RESET; + else if (strategy == GL_NO_RESET_NOTIFICATION_ARB) + window->context.robustness = GLFW_NO_RESET_NOTIFICATION; + } + } + + if (glfwExtensionSupported("GL_KHR_context_flush_control")) + { + GLint behavior; + glGetIntegerv(GL_CONTEXT_RELEASE_BEHAVIOR, &behavior); + + if (behavior == GL_NONE) + window->context.release = GLFW_RELEASE_BEHAVIOR_NONE; + else if (behavior == GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH) + window->context.release = GLFW_RELEASE_BEHAVIOR_FLUSH; + } +#endif // _GLFW_USE_OPENGL + + return GL_TRUE; +} + +GLboolean _glfwIsValidContext(const _GLFWctxconfig* ctxconfig) +{ + _GLFWwindow* window = _glfwPlatformGetCurrentContext(); + + if (window->context.major < ctxconfig->major || + (window->context.major == ctxconfig->major && + window->context.minor < ctxconfig->minor)) + { + // The desired OpenGL version is greater than the actual version + // This only happens if the machine lacks {GLX|WGL}_ARB_create_context + // /and/ the user has requested an OpenGL version greater than 1.0 + + // For API consistency, we emulate the behavior of the + // {GLX|WGL}_ARB_create_context extension and fail here + + _glfwInputError(GLFW_VERSION_UNAVAILABLE, NULL); + return GL_FALSE; + } + + return GL_TRUE; +} + +int _glfwStringInExtensionString(const char* string, const GLubyte* extensions) +{ + const GLubyte* start; + GLubyte* where; + GLubyte* terminator; + + // It takes a bit of care to be fool-proof about parsing the + // OpenGL extensions string. Don't be fooled by sub-strings, + // etc. + start = extensions; + for (;;) + { + where = (GLubyte*) strstr((const char*) start, string); + if (!where) + return GL_FALSE; + + terminator = where + strlen(string); + if (where == start || *(where - 1) == ' ') + { + if (*terminator == ' ' || *terminator == '\0') + break; + } + + start = terminator; + } + + return GL_TRUE; +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW public API ////// +////////////////////////////////////////////////////////////////////////// + +GLFWAPI void glfwMakeContextCurrent(GLFWwindow* handle) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + + _GLFW_REQUIRE_INIT(); + + if (_glfwPlatformGetCurrentContext() == window) + return; + + _glfwPlatformMakeContextCurrent(window); +} + +GLFWAPI GLFWwindow* glfwGetCurrentContext(void) +{ + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + return (GLFWwindow*) _glfwPlatformGetCurrentContext(); +} + +GLFWAPI void glfwSwapBuffers(GLFWwindow* handle) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + _GLFW_REQUIRE_INIT(); + _glfwPlatformSwapBuffers(window); +} + +GLFWAPI void glfwSwapInterval(int interval) +{ + _GLFW_REQUIRE_INIT(); + + if (!_glfwPlatformGetCurrentContext()) + { + _glfwInputError(GLFW_NO_CURRENT_CONTEXT, NULL); + return; + } + + _glfwPlatformSwapInterval(interval); +} + +GLFWAPI int glfwExtensionSupported(const char* extension) +{ + _GLFWwindow* window; + + _GLFW_REQUIRE_INIT_OR_RETURN(GL_FALSE); + + window = _glfwPlatformGetCurrentContext(); + if (!window) + { + _glfwInputError(GLFW_NO_CURRENT_CONTEXT, NULL); + return GL_FALSE; + } + + if (*extension == '\0') + { + _glfwInputError(GLFW_INVALID_VALUE, NULL); + return GL_FALSE; + } + +#if defined(_GLFW_USE_OPENGL) + if (window->context.major >= 3) + { + int i; + GLint count; + + // Check if extension is in the modern OpenGL extensions string list + + glGetIntegerv(GL_NUM_EXTENSIONS, &count); + + for (i = 0; i < count; i++) + { + const char* en = (const char*) window->GetStringi(GL_EXTENSIONS, i); + if (!en) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Failed to retrieve extension string %i", i); + return GL_FALSE; + } + + if (strcmp(en, extension) == 0) + return GL_TRUE; + } + } + else +#endif // _GLFW_USE_OPENGL + { + // Check if extension is in the old style OpenGL extensions string + + const GLubyte* extensions = glGetString(GL_EXTENSIONS); + if (!extensions) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Failed to retrieve extension string"); + return GL_FALSE; + } + + if (_glfwStringInExtensionString(extension, extensions)) + return GL_TRUE; + } + + // Check if extension is in the platform-specific string + return _glfwPlatformExtensionSupported(extension); +} + +GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname) +{ + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + + if (!_glfwPlatformGetCurrentContext()) + { + _glfwInputError(GLFW_NO_CURRENT_CONTEXT, NULL); + return NULL; + } + + return _glfwPlatformGetProcAddress(procname); +} + diff --git a/testbed/glfw/src/egl_context.c b/testbed/glfw/src/egl_context.c new file mode 100644 index 00000000..e3335a53 --- /dev/null +++ b/testbed/glfw/src/egl_context.c @@ -0,0 +1,533 @@ +//======================================================================== +// GLFW 3.1 EGL - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2010 Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include "internal.h" + +#include +#include +#include + + +// Return a description of the specified EGL error +// +static const char* getErrorString(EGLint error) +{ + switch (error) + { + case EGL_SUCCESS: + return "Success"; + case EGL_NOT_INITIALIZED: + return "EGL is not or could not be initialized"; + case EGL_BAD_ACCESS: + return "EGL cannot access a requested resource"; + case EGL_BAD_ALLOC: + return "EGL failed to allocate resources for the requested operation"; + case EGL_BAD_ATTRIBUTE: + return "An unrecognized attribute or attribute value was passed " + "in the attribute list"; + case EGL_BAD_CONTEXT: + return "An EGLContext argument does not name a valid EGL " + "rendering context"; + case EGL_BAD_CONFIG: + return "An EGLConfig argument does not name a valid EGL frame " + "buffer configuration"; + case EGL_BAD_CURRENT_SURFACE: + return "The current surface of the calling thread is a window, pixel " + "buffer or pixmap that is no longer valid"; + case EGL_BAD_DISPLAY: + return "An EGLDisplay argument does not name a valid EGL display " + "connection"; + case EGL_BAD_SURFACE: + return "An EGLSurface argument does not name a valid surface " + "configured for GL rendering"; + case EGL_BAD_MATCH: + return "Arguments are inconsistent"; + case EGL_BAD_PARAMETER: + return "One or more argument values are invalid"; + case EGL_BAD_NATIVE_PIXMAP: + return "A NativePixmapType argument does not refer to a valid " + "native pixmap"; + case EGL_BAD_NATIVE_WINDOW: + return "A NativeWindowType argument does not refer to a valid " + "native window"; + case EGL_CONTEXT_LOST: + return "The application must destroy all contexts and reinitialise"; + } + + return "UNKNOWN EGL ERROR"; +} + +// Returns the specified attribute of the specified EGLConfig +// +static int getConfigAttrib(EGLConfig config, int attrib) +{ + int value; + eglGetConfigAttrib(_glfw.egl.display, config, attrib, &value); + return value; +} + +// Return a list of available and usable framebuffer configs +// +static GLboolean chooseFBConfigs(const _GLFWctxconfig* ctxconfig, + const _GLFWfbconfig* desired, + EGLConfig* result) +{ + EGLConfig* nativeConfigs; + _GLFWfbconfig* usableConfigs; + const _GLFWfbconfig* closest; + int i, nativeCount, usableCount; + + eglGetConfigs(_glfw.egl.display, NULL, 0, &nativeCount); + if (!nativeCount) + { + _glfwInputError(GLFW_API_UNAVAILABLE, "EGL: No EGLConfigs returned"); + return GL_FALSE; + } + + nativeConfigs = calloc(nativeCount, sizeof(EGLConfig)); + eglGetConfigs(_glfw.egl.display, nativeConfigs, nativeCount, &nativeCount); + + usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig)); + usableCount = 0; + + for (i = 0; i < nativeCount; i++) + { + const EGLConfig n = nativeConfigs[i]; + _GLFWfbconfig* u = usableConfigs + usableCount; + +#if defined(_GLFW_X11) + if (!getConfigAttrib(n, EGL_NATIVE_VISUAL_ID)) + { + // Only consider EGLConfigs with associated visuals + continue; + } +#endif // _GLFW_X11 + + if (!(getConfigAttrib(n, EGL_COLOR_BUFFER_TYPE) & EGL_RGB_BUFFER)) + { + // Only consider RGB(A) EGLConfigs + continue; + } + + if (!(getConfigAttrib(n, EGL_SURFACE_TYPE) & EGL_WINDOW_BIT)) + { + // Only consider window EGLConfigs + continue; + } + + if (ctxconfig->api == GLFW_OPENGL_ES_API) + { + if (ctxconfig->major == 1) + { + if (!(getConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES_BIT)) + continue; + } + else + { + if (!(getConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES2_BIT)) + continue; + } + } + else if (ctxconfig->api == GLFW_OPENGL_API) + { + if (!(getConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_BIT)) + continue; + } + + u->redBits = getConfigAttrib(n, EGL_RED_SIZE); + u->greenBits = getConfigAttrib(n, EGL_GREEN_SIZE); + u->blueBits = getConfigAttrib(n, EGL_BLUE_SIZE); + + u->alphaBits = getConfigAttrib(n, EGL_ALPHA_SIZE); + u->depthBits = getConfigAttrib(n, EGL_DEPTH_SIZE); + u->stencilBits = getConfigAttrib(n, EGL_STENCIL_SIZE); + + u->samples = getConfigAttrib(n, EGL_SAMPLES); + u->doublebuffer = GL_TRUE; + + u->egl = n; + usableCount++; + } + + closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount); + if (closest) + *result = closest->egl; + + free(nativeConfigs); + free(usableConfigs); + + return closest ? GL_TRUE : GL_FALSE; +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +// Initialize EGL +// +int _glfwInitContextAPI(void) +{ + if (!_glfwInitTLS()) + return GL_FALSE; + + _glfw.egl.display = eglGetDisplay((EGLNativeDisplayType)_GLFW_EGL_NATIVE_DISPLAY); + if (_glfw.egl.display == EGL_NO_DISPLAY) + { + _glfwInputError(GLFW_API_UNAVAILABLE, + "EGL: Failed to get EGL display: %s", + getErrorString(eglGetError())); + return GL_FALSE; + } + + if (!eglInitialize(_glfw.egl.display, + &_glfw.egl.versionMajor, + &_glfw.egl.versionMinor)) + { + _glfwInputError(GLFW_API_UNAVAILABLE, + "EGL: Failed to initialize EGL: %s", + getErrorString(eglGetError())); + return GL_FALSE; + } + + if (_glfwPlatformExtensionSupported("EGL_KHR_create_context")) + _glfw.egl.KHR_create_context = GL_TRUE; + + return GL_TRUE; +} + +// Terminate EGL +// +void _glfwTerminateContextAPI(void) +{ + eglTerminate(_glfw.egl.display); + + _glfwTerminateTLS(); +} + +#define setEGLattrib(attribName, attribValue) \ +{ \ + attribs[index++] = attribName; \ + attribs[index++] = attribValue; \ + assert((size_t) index < sizeof(attribs) / sizeof(attribs[0])); \ +} + +// Create the OpenGL or OpenGL ES context +// +int _glfwCreateContext(_GLFWwindow* window, + const _GLFWctxconfig* ctxconfig, + const _GLFWfbconfig* fbconfig) +{ + int attribs[40]; + EGLConfig config; + EGLContext share = NULL; + + if (ctxconfig->share) + share = ctxconfig->share->egl.context; + + if (!chooseFBConfigs(ctxconfig, fbconfig, &config)) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "EGL: Failed to find a suitable EGLConfig"); + return GL_FALSE; + } + +#if defined(_GLFW_X11) + // Retrieve the visual corresponding to the chosen EGL config + { + EGLint count = 0; + int mask; + EGLint redBits, greenBits, blueBits, alphaBits, visualID = 0; + XVisualInfo info; + + eglGetConfigAttrib(_glfw.egl.display, config, + EGL_NATIVE_VISUAL_ID, &visualID); + + info.screen = _glfw.x11.screen; + mask = VisualScreenMask; + + if (visualID) + { + // The X window visual must match the EGL config + info.visualid = visualID; + mask |= VisualIDMask; + } + else + { + // some EGL drivers don't implement the EGL_NATIVE_VISUAL_ID + // attribute, so attempt to find the closest match. + + eglGetConfigAttrib(_glfw.egl.display, config, + EGL_RED_SIZE, &redBits); + eglGetConfigAttrib(_glfw.egl.display, config, + EGL_GREEN_SIZE, &greenBits); + eglGetConfigAttrib(_glfw.egl.display, config, + EGL_BLUE_SIZE, &blueBits); + eglGetConfigAttrib(_glfw.egl.display, config, + EGL_ALPHA_SIZE, &alphaBits); + + info.depth = redBits + greenBits + blueBits + alphaBits; + mask |= VisualDepthMask; + } + + window->egl.visual = XGetVisualInfo(_glfw.x11.display, + mask, &info, &count); + if (!window->egl.visual) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "EGL: Failed to retrieve visual for EGLConfig"); + return GL_FALSE; + } + } +#endif // _GLFW_X11 + + if (ctxconfig->api == GLFW_OPENGL_ES_API) + { + if (!eglBindAPI(EGL_OPENGL_ES_API)) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "EGL: Failed to bind OpenGL ES: %s", + getErrorString(eglGetError())); + return GL_FALSE; + } + } + else + { + if (!eglBindAPI(EGL_OPENGL_API)) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "EGL: Failed to bind OpenGL: %s", + getErrorString(eglGetError())); + return GL_FALSE; + } + } + + if (_glfw.egl.KHR_create_context) + { + int index = 0, mask = 0, flags = 0, strategy = 0; + + if (ctxconfig->api == GLFW_OPENGL_API) + { + if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE) + mask |= EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR; + else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE) + mask |= EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR; + + if (ctxconfig->forward) + flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR; + + if (ctxconfig->debug) + flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR; + } + + if (ctxconfig->robustness) + { + if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION) + strategy = EGL_NO_RESET_NOTIFICATION_KHR; + else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET) + strategy = EGL_LOSE_CONTEXT_ON_RESET_KHR; + + flags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR; + } + + if (ctxconfig->major != 1 || ctxconfig->minor != 0) + { + setEGLattrib(EGL_CONTEXT_MAJOR_VERSION_KHR, ctxconfig->major); + setEGLattrib(EGL_CONTEXT_MINOR_VERSION_KHR, ctxconfig->minor); + } + + if (mask) + setEGLattrib(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, mask); + + if (flags) + setEGLattrib(EGL_CONTEXT_FLAGS_KHR, flags); + + if (strategy) + setEGLattrib(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR, strategy); + + setEGLattrib(EGL_NONE, EGL_NONE); + } + else + { + int index = 0; + + if (ctxconfig->api == GLFW_OPENGL_ES_API) + setEGLattrib(EGL_CONTEXT_CLIENT_VERSION, ctxconfig->major); + + setEGLattrib(EGL_NONE, EGL_NONE); + } + + // Context release behaviors (GL_KHR_context_flush_control) are not yet + // supported on EGL but are not a hard constraint, so ignore and continue + + window->egl.context = eglCreateContext(_glfw.egl.display, + config, share, attribs); + + if (window->egl.context == EGL_NO_CONTEXT) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "EGL: Failed to create context: %s", + getErrorString(eglGetError())); + return GL_FALSE; + } + + window->egl.config = config; + + return GL_TRUE; +} + +#undef setEGLattrib + +// Destroy the OpenGL context +// +void _glfwDestroyContext(_GLFWwindow* window) +{ +#if defined(_GLFW_X11) + if (window->egl.visual) + { + XFree(window->egl.visual); + window->egl.visual = NULL; + } +#endif // _GLFW_X11 + + if (window->egl.surface) + { + eglDestroySurface(_glfw.egl.display, window->egl.surface); + window->egl.surface = EGL_NO_SURFACE; + } + + if (window->egl.context) + { + eglDestroyContext(_glfw.egl.display, window->egl.context); + window->egl.context = EGL_NO_CONTEXT; + } +} + +// Analyzes the specified context for possible recreation +// +int _glfwAnalyzeContext(const _GLFWwindow* window, + const _GLFWctxconfig* ctxconfig, + const _GLFWfbconfig* fbconfig) +{ +#if defined(_GLFW_WIN32) + return _GLFW_RECREATION_NOT_NEEDED; +#else + return 0; +#endif +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +void _glfwPlatformMakeContextCurrent(_GLFWwindow* window) +{ + if (window) + { + if (window->egl.surface == EGL_NO_SURFACE) + { + window->egl.surface = eglCreateWindowSurface(_glfw.egl.display, + window->egl.config, + (EGLNativeWindowType)_GLFW_EGL_NATIVE_WINDOW, + NULL); + if (window->egl.surface == EGL_NO_SURFACE) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "EGL: Failed to create window surface: %s", + getErrorString(eglGetError())); + } + } + + eglMakeCurrent(_glfw.egl.display, + window->egl.surface, + window->egl.surface, + window->egl.context); + } + else + { + eglMakeCurrent(_glfw.egl.display, + EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + } + + _glfwSetCurrentContext(window); +} + +void _glfwPlatformSwapBuffers(_GLFWwindow* window) +{ + eglSwapBuffers(_glfw.egl.display, window->egl.surface); +} + +void _glfwPlatformSwapInterval(int interval) +{ + eglSwapInterval(_glfw.egl.display, interval); +} + +int _glfwPlatformExtensionSupported(const char* extension) +{ + const char* extensions; + + extensions = eglQueryString(_glfw.egl.display, EGL_EXTENSIONS); + if (extensions != NULL) + { + if (_glfwStringInExtensionString(extension, (unsigned char*) extensions)) + return GL_TRUE; + } + + return GL_FALSE; +} + +GLFWglproc _glfwPlatformGetProcAddress(const char* procname) +{ + return eglGetProcAddress(procname); +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW native API ////// +////////////////////////////////////////////////////////////////////////// + +GLFWAPI EGLDisplay glfwGetEGLDisplay(void) +{ + _GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_DISPLAY); + return _glfw.egl.display; +} + +GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* handle) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + _GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_CONTEXT); + return window->egl.context; +} + +GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* handle) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + _GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_SURFACE); + return window->egl.surface; +} + diff --git a/testbed/glfw/src/egl_context.h b/testbed/glfw/src/egl_context.h new file mode 100644 index 00000000..21d68527 --- /dev/null +++ b/testbed/glfw/src/egl_context.h @@ -0,0 +1,85 @@ +//======================================================================== +// GLFW 3.1 EGL - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2010 Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#ifndef _egl_context_h_ +#define _egl_context_h_ + +#include + +// This path may need to be changed if you build GLFW using your own setup +// We ship and use our own copy of eglext.h since GLFW uses fairly new +// extensions and not all operating systems come with an up-to-date version +#include "../deps/EGL/eglext.h" + +// Do we have support for dlopen/dlsym? +#if defined(_GLFW_HAS_DLOPEN) + #include +#endif + +#define _GLFW_PLATFORM_FBCONFIG EGLConfig egl +#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextEGL egl +#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryEGL egl + + +// EGL-specific per-context data +// +typedef struct _GLFWcontextEGL +{ + EGLConfig config; + EGLContext context; + EGLSurface surface; + +#if defined(_GLFW_X11) + XVisualInfo* visual; +#endif + +} _GLFWcontextEGL; + + +// EGL-specific global data +// +typedef struct _GLFWlibraryEGL +{ + EGLDisplay display; + EGLint versionMajor, versionMinor; + + GLboolean KHR_create_context; + +} _GLFWlibraryEGL; + + +int _glfwInitContextAPI(void); +void _glfwTerminateContextAPI(void); +int _glfwCreateContext(_GLFWwindow* window, + const _GLFWctxconfig* ctxconfig, + const _GLFWfbconfig* fbconfig); +void _glfwDestroyContext(_GLFWwindow* window); +int _glfwAnalyzeContext(const _GLFWwindow* window, + const _GLFWctxconfig* ctxconfig, + const _GLFWfbconfig* fbconfig); + +#endif // _egl_context_h_ diff --git a/testbed/glfw/src/glfw3.pc.in b/testbed/glfw/src/glfw3.pc.in new file mode 100644 index 00000000..f2e4d976 --- /dev/null +++ b/testbed/glfw/src/glfw3.pc.in @@ -0,0 +1,13 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=${prefix} +includedir=${prefix}/include +libdir=${exec_prefix}/lib@LIB_SUFFIX@ + +Name: GLFW +Description: A multi-platform library for OpenGL, window and input +Version: @GLFW_VERSION_FULL@ +URL: http://www.glfw.org/ +Requires.private: @GLFW_PKG_DEPS@ +Libs: -L${libdir} -l@GLFW_LIB_NAME@ +Libs.private: @GLFW_PKG_LIBS@ +Cflags: -I${includedir} diff --git a/testbed/glfw/src/glfw3Config.cmake.in b/testbed/glfw/src/glfw3Config.cmake.in new file mode 100644 index 00000000..d34df06f --- /dev/null +++ b/testbed/glfw/src/glfw3Config.cmake.in @@ -0,0 +1,15 @@ +# - Config file for the glfw3 package +# It defines the following variables +# GLFW3_INCLUDE_DIR, the path where GLFW headers are located +# GLFW3_LIBRARY_DIR, folder in which the GLFW library is located +# GLFW3_LIBRARY, library to link against to use GLFW + +set(GLFW3_VERSION "@GLFW_VERSION_FULL@") + +@PACKAGE_INIT@ + +set_and_check(GLFW3_INCLUDE_DIR "@PACKAGE_CMAKE_INSTALL_PREFIX@/include") +set_and_check(GLFW3_LIBRARY_DIR "@PACKAGE_CMAKE_INSTALL_PREFIX@/lib@LIB_SUFFIX@") + +find_library(GLFW3_LIBRARY "@GLFW_LIB_NAME@" HINTS ${GLFW3_LIBRARY_DIR}) + diff --git a/testbed/glfw/src/glfw_config.h.in b/testbed/glfw/src/glfw_config.h.in new file mode 100644 index 00000000..485cac58 --- /dev/null +++ b/testbed/glfw/src/glfw_config.h.in @@ -0,0 +1,87 @@ +//======================================================================== +// GLFW 3.1 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2010 Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== +// As glfw_config.h.in, this file is used by CMake to produce the +// glfw_config.h configuration header file. If you are adding a feature +// requiring conditional compilation, this is where to add the macro. +//======================================================================== +// As glfw_config.h, this file defines compile-time option macros for a +// specific platform and development environment. If you are using the +// GLFW CMake files, modify glfw_config.h.in instead of this file. If you +// are using your own build system, make this file define the appropriate +// macros in whatever way is suitable. +//======================================================================== + +// Define this to 1 if building GLFW for X11 +#cmakedefine _GLFW_X11 +// Define this to 1 if building GLFW for Win32 +#cmakedefine _GLFW_WIN32 +// Define this to 1 if building GLFW for Cocoa +#cmakedefine _GLFW_COCOA +// Define this to 1 if building GLFW for Wayland +#cmakedefine _GLFW_WAYLAND +// Define this to 1 if building GLFW for Mir +#cmakedefine _GLFW_MIR + +// Define this to 1 if building GLFW for EGL +#cmakedefine _GLFW_EGL +// Define this to 1 if building GLFW for GLX +#cmakedefine _GLFW_GLX +// Define this to 1 if building GLFW for WGL +#cmakedefine _GLFW_WGL +// Define this to 1 if building GLFW for NSGL +#cmakedefine _GLFW_NSGL + +// Define this to 1 if building as a shared library / dynamic library / DLL +#cmakedefine _GLFW_BUILD_DLL + +// Define this to 1 if glfwSwapInterval should ignore DWM compositing status +#cmakedefine _GLFW_USE_DWM_SWAP_INTERVAL +// Define this to 1 to force use of high-performance GPU on Optimus systems +#cmakedefine _GLFW_USE_OPTIMUS_HPG + +// Define this to 1 if glXGetProcAddress is available +#cmakedefine _GLFW_HAS_GLXGETPROCADDRESS +// Define this to 1 if glXGetProcAddressARB is available +#cmakedefine _GLFW_HAS_GLXGETPROCADDRESSARB +// Define this to 1 if glXGetProcAddressEXT is available +#cmakedefine _GLFW_HAS_GLXGETPROCADDRESSEXT +// Define this to 1 if dlopen is available +#cmakedefine _GLFW_HAS_DLOPEN + +// Define this to 1 if glfwInit should change the current directory +#cmakedefine _GLFW_USE_CHDIR +// Define this to 1 if glfwCreateWindow should populate the menu bar +#cmakedefine _GLFW_USE_MENUBAR +// Define this to 1 if windows should use full resolution on Retina displays +#cmakedefine _GLFW_USE_RETINA + +// Define this to 1 if using OpenGL as the client library +#cmakedefine _GLFW_USE_OPENGL +// Define this to 1 if using OpenGL ES 1.1 as the client library +#cmakedefine _GLFW_USE_GLESV1 +// Define this to 1 if using OpenGL ES 2.0 as the client library +#cmakedefine _GLFW_USE_GLESV2 + diff --git a/testbed/glfw/src/glx_context.c b/testbed/glfw/src/glx_context.c new file mode 100644 index 00000000..562abf7f --- /dev/null +++ b/testbed/glfw/src/glx_context.c @@ -0,0 +1,558 @@ +//======================================================================== +// GLFW 3.1 GLX - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2010 Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include "internal.h" + +#include +#include +#include + + +// This is the only glXGetProcAddress variant not declared by glxext.h +void (*glXGetProcAddressEXT(const GLubyte* procName))(); + + +#ifndef GLXBadProfileARB + #define GLXBadProfileARB 13 +#endif + + +// Returns the specified attribute of the specified GLXFBConfig +// +static int getFBConfigAttrib(GLXFBConfig fbconfig, int attrib) +{ + int value; + glXGetFBConfigAttrib(_glfw.x11.display, fbconfig, attrib, &value); + return value; +} + +// Return a list of available and usable framebuffer configs +// +static GLboolean chooseFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* result) +{ + GLXFBConfig* nativeConfigs; + _GLFWfbconfig* usableConfigs; + const _GLFWfbconfig* closest; + int i, nativeCount, usableCount; + const char* vendor; + GLboolean trustWindowBit = GL_TRUE; + + vendor = glXGetClientString(_glfw.x11.display, GLX_VENDOR); + if (strcmp(vendor, "Chromium") == 0) + { + // HACK: This is a (hopefully temporary) workaround for Chromium + // (VirtualBox GL) not setting the window bit on any GLXFBConfigs + trustWindowBit = GL_FALSE; + } + + nativeConfigs = glXGetFBConfigs(_glfw.x11.display, _glfw.x11.screen, + &nativeCount); + if (!nativeCount) + { + _glfwInputError(GLFW_API_UNAVAILABLE, "GLX: No GLXFBConfigs returned"); + return GL_FALSE; + } + + usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig)); + usableCount = 0; + + for (i = 0; i < nativeCount; i++) + { + const GLXFBConfig n = nativeConfigs[i]; + _GLFWfbconfig* u = usableConfigs + usableCount; + + if (!getFBConfigAttrib(n, GLX_VISUAL_ID)) + { + // Only consider GLXFBConfigs with associated visuals + continue; + } + + if (!(getFBConfigAttrib(n, GLX_RENDER_TYPE) & GLX_RGBA_BIT)) + { + // Only consider RGBA GLXFBConfigs + continue; + } + + if (!(getFBConfigAttrib(n, GLX_DRAWABLE_TYPE) & GLX_WINDOW_BIT)) + { + if (trustWindowBit) + { + // Only consider window GLXFBConfigs + continue; + } + } + + u->redBits = getFBConfigAttrib(n, GLX_RED_SIZE); + u->greenBits = getFBConfigAttrib(n, GLX_GREEN_SIZE); + u->blueBits = getFBConfigAttrib(n, GLX_BLUE_SIZE); + + u->alphaBits = getFBConfigAttrib(n, GLX_ALPHA_SIZE); + u->depthBits = getFBConfigAttrib(n, GLX_DEPTH_SIZE); + u->stencilBits = getFBConfigAttrib(n, GLX_STENCIL_SIZE); + + u->accumRedBits = getFBConfigAttrib(n, GLX_ACCUM_RED_SIZE); + u->accumGreenBits = getFBConfigAttrib(n, GLX_ACCUM_GREEN_SIZE); + u->accumBlueBits = getFBConfigAttrib(n, GLX_ACCUM_BLUE_SIZE); + u->accumAlphaBits = getFBConfigAttrib(n, GLX_ACCUM_ALPHA_SIZE); + + u->auxBuffers = getFBConfigAttrib(n, GLX_AUX_BUFFERS); + + if (getFBConfigAttrib(n, GLX_STEREO)) + u->stereo = GL_TRUE; + if (getFBConfigAttrib(n, GLX_DOUBLEBUFFER)) + u->doublebuffer = GL_TRUE; + + if (_glfw.glx.ARB_multisample) + u->samples = getFBConfigAttrib(n, GLX_SAMPLES); + + if (_glfw.glx.ARB_framebuffer_sRGB) + u->sRGB = getFBConfigAttrib(n, GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB); + + u->glx = n; + usableCount++; + } + + closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount); + if (closest) + *result = closest->glx; + + XFree(nativeConfigs); + free(usableConfigs); + + return closest ? GL_TRUE : GL_FALSE; +} + +// Create the OpenGL context using legacy API +// +static GLXContext createLegacyContext(_GLFWwindow* window, + GLXFBConfig fbconfig, + GLXContext share) +{ + return glXCreateNewContext(_glfw.x11.display, + fbconfig, + GLX_RGBA_TYPE, + share, + True); +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +// Initialize GLX +// +int _glfwInitContextAPI(void) +{ + if (!_glfwInitTLS()) + return GL_FALSE; + +#ifdef _GLFW_DLOPEN_LIBGL + _glfw.glx.libGL = dlopen("libGL.so.1", RTLD_LAZY | RTLD_GLOBAL); + if (!_glfw.glx.libGL) + { + _glfwInputError(GLFW_PLATFORM_ERROR, "GLX: Failed to find libGL"); + return GL_FALSE; + } +#endif + + if (!glXQueryExtension(_glfw.x11.display, + &_glfw.glx.errorBase, + &_glfw.glx.eventBase)) + { + _glfwInputError(GLFW_API_UNAVAILABLE, "GLX: GLX extension not found"); + return GL_FALSE; + } + + if (!glXQueryVersion(_glfw.x11.display, + &_glfw.glx.versionMajor, + &_glfw.glx.versionMinor)) + { + _glfwInputError(GLFW_API_UNAVAILABLE, + "GLX: Failed to query GLX version"); + return GL_FALSE; + } + + if (_glfw.glx.versionMajor == 1 && _glfw.glx.versionMinor < 3) + { + _glfwInputError(GLFW_API_UNAVAILABLE, + "GLX: GLX version 1.3 is required"); + return GL_FALSE; + } + + if (_glfwPlatformExtensionSupported("GLX_EXT_swap_control")) + { + _glfw.glx.SwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC) + _glfwPlatformGetProcAddress("glXSwapIntervalEXT"); + + if (_glfw.glx.SwapIntervalEXT) + _glfw.glx.EXT_swap_control = GL_TRUE; + } + + if (_glfwPlatformExtensionSupported("GLX_SGI_swap_control")) + { + _glfw.glx.SwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC) + _glfwPlatformGetProcAddress("glXSwapIntervalSGI"); + + if (_glfw.glx.SwapIntervalSGI) + _glfw.glx.SGI_swap_control = GL_TRUE; + } + + if (_glfwPlatformExtensionSupported("GLX_MESA_swap_control")) + { + _glfw.glx.SwapIntervalMESA = (PFNGLXSWAPINTERVALMESAPROC) + _glfwPlatformGetProcAddress("glXSwapIntervalMESA"); + + if (_glfw.glx.SwapIntervalMESA) + _glfw.glx.MESA_swap_control = GL_TRUE; + } + + if (_glfwPlatformExtensionSupported("GLX_ARB_multisample")) + _glfw.glx.ARB_multisample = GL_TRUE; + + if (_glfwPlatformExtensionSupported("GLX_ARB_framebuffer_sRGB")) + _glfw.glx.ARB_framebuffer_sRGB = GL_TRUE; + + if (_glfwPlatformExtensionSupported("GLX_ARB_create_context")) + { + _glfw.glx.CreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC) + _glfwPlatformGetProcAddress("glXCreateContextAttribsARB"); + + if (_glfw.glx.CreateContextAttribsARB) + _glfw.glx.ARB_create_context = GL_TRUE; + } + + if (_glfwPlatformExtensionSupported("GLX_ARB_create_context_robustness")) + _glfw.glx.ARB_create_context_robustness = GL_TRUE; + + if (_glfwPlatformExtensionSupported("GLX_ARB_create_context_profile")) + _glfw.glx.ARB_create_context_profile = GL_TRUE; + + if (_glfwPlatformExtensionSupported("GLX_EXT_create_context_es2_profile")) + _glfw.glx.EXT_create_context_es2_profile = GL_TRUE; + + if (_glfwPlatformExtensionSupported("GLX_ARB_context_flush_control")) + _glfw.glx.ARB_context_flush_control = GL_TRUE; + + return GL_TRUE; +} + +// Terminate GLX +// +void _glfwTerminateContextAPI(void) +{ + // Unload libGL.so if necessary +#ifdef _GLFW_DLOPEN_LIBGL + if (_glfw.glx.libGL != NULL) + { + dlclose(_glfw.glx.libGL); + _glfw.glx.libGL = NULL; + } +#endif + + _glfwTerminateTLS(); +} + +#define setGLXattrib(attribName, attribValue) \ +{ \ + attribs[index++] = attribName; \ + attribs[index++] = attribValue; \ + assert((size_t) index < sizeof(attribs) / sizeof(attribs[0])); \ +} + +// Create the OpenGL or OpenGL ES context +// +int _glfwCreateContext(_GLFWwindow* window, + const _GLFWctxconfig* ctxconfig, + const _GLFWfbconfig* fbconfig) +{ + int attribs[40]; + GLXFBConfig native; + GLXContext share = NULL; + + if (ctxconfig->share) + share = ctxconfig->share->glx.context; + + if (!chooseFBConfig(fbconfig, &native)) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "GLX: Failed to find a suitable GLXFBConfig"); + return GL_FALSE; + } + + // Retrieve the corresponding visual + window->glx.visual = glXGetVisualFromFBConfig(_glfw.x11.display, native); + if (!window->glx.visual) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "GLX: Failed to retrieve visual for GLXFBConfig"); + return GL_FALSE; + } + + if (ctxconfig->api == GLFW_OPENGL_ES_API) + { + if (!_glfw.glx.ARB_create_context || + !_glfw.glx.ARB_create_context_profile || + !_glfw.glx.EXT_create_context_es2_profile) + { + _glfwInputError(GLFW_API_UNAVAILABLE, + "GLX: OpenGL ES requested but " + "GLX_EXT_create_context_es2_profile is unavailable"); + return GL_FALSE; + } + } + + if (ctxconfig->forward) + { + if (!_glfw.glx.ARB_create_context) + { + _glfwInputError(GLFW_VERSION_UNAVAILABLE, + "GLX: Forward compatibility requested but " + "GLX_ARB_create_context_profile is unavailable"); + return GL_FALSE; + } + } + + if (ctxconfig->profile) + { + if (!_glfw.glx.ARB_create_context || + !_glfw.glx.ARB_create_context_profile) + { + _glfwInputError(GLFW_VERSION_UNAVAILABLE, + "GLX: An OpenGL profile requested but " + "GLX_ARB_create_context_profile is unavailable"); + return GL_FALSE; + } + } + + _glfwGrabXErrorHandler(); + + if (_glfw.glx.ARB_create_context) + { + int index = 0, mask = 0, flags = 0, strategy = 0; + + if (ctxconfig->api == GLFW_OPENGL_API) + { + if (ctxconfig->forward) + flags |= GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; + + if (ctxconfig->debug) + flags |= GLX_CONTEXT_DEBUG_BIT_ARB; + + if (ctxconfig->profile) + { + if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE) + mask |= GLX_CONTEXT_CORE_PROFILE_BIT_ARB; + else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE) + mask |= GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; + } + } + else + mask |= GLX_CONTEXT_ES2_PROFILE_BIT_EXT; + + if (ctxconfig->robustness) + { + if (_glfw.glx.ARB_create_context_robustness) + { + if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION) + strategy = GLX_NO_RESET_NOTIFICATION_ARB; + else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET) + strategy = GLX_LOSE_CONTEXT_ON_RESET_ARB; + + flags |= GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB; + } + } + + if (ctxconfig->release) + { + if (_glfw.glx.ARB_context_flush_control) + { + if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE) + { + setGLXattrib(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB, + GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB); + } + else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH) + { + setGLXattrib(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB, + GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB); + } + } + } + + if (ctxconfig->major != 1 || ctxconfig->minor != 0) + { + // NOTE: Only request an explicitly versioned context when + // necessary, as explicitly requesting version 1.0 does not + // always return the highest available version + + setGLXattrib(GLX_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major); + setGLXattrib(GLX_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor); + } + + if (mask) + setGLXattrib(GLX_CONTEXT_PROFILE_MASK_ARB, mask); + + if (flags) + setGLXattrib(GLX_CONTEXT_FLAGS_ARB, flags); + + if (strategy) + setGLXattrib(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, strategy); + + setGLXattrib(None, None); + + window->glx.context = + _glfw.glx.CreateContextAttribsARB(_glfw.x11.display, + native, + share, + True, + attribs); + + if (!window->glx.context) + { + // HACK: This is a fallback for the broken Mesa implementation of + // GLX_ARB_create_context_profile, which fails default 1.0 + // context creation with a GLXBadProfileARB error in violation + // of the extension spec + if (_glfw.x11.errorCode == _glfw.glx.errorBase + GLXBadProfileARB && + ctxconfig->api == GLFW_OPENGL_API && + ctxconfig->profile == GLFW_OPENGL_ANY_PROFILE && + ctxconfig->forward == GL_FALSE) + { + window->glx.context = createLegacyContext(window, native, share); + } + } + } + else + window->glx.context = createLegacyContext(window, native, share); + + _glfwReleaseXErrorHandler(); + + if (!window->glx.context) + { + _glfwInputXError(GLFW_PLATFORM_ERROR, "GLX: Failed to create context"); + return GL_FALSE; + } + + return GL_TRUE; +} + +#undef setGLXattrib + +// Destroy the OpenGL context +// +void _glfwDestroyContext(_GLFWwindow* window) +{ + if (window->glx.visual) + { + XFree(window->glx.visual); + window->glx.visual = NULL; + } + + if (window->glx.context) + { + glXDestroyContext(_glfw.x11.display, window->glx.context); + window->glx.context = NULL; + } +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +void _glfwPlatformMakeContextCurrent(_GLFWwindow* window) +{ + if (window) + { + glXMakeCurrent(_glfw.x11.display, + window->x11.handle, + window->glx.context); + } + else + glXMakeCurrent(_glfw.x11.display, None, NULL); + + _glfwSetCurrentContext(window); +} + +void _glfwPlatformSwapBuffers(_GLFWwindow* window) +{ + glXSwapBuffers(_glfw.x11.display, window->x11.handle); +} + +void _glfwPlatformSwapInterval(int interval) +{ + _GLFWwindow* window = _glfwPlatformGetCurrentContext(); + + if (_glfw.glx.EXT_swap_control) + { + _glfw.glx.SwapIntervalEXT(_glfw.x11.display, + window->x11.handle, + interval); + } + else if (_glfw.glx.MESA_swap_control) + _glfw.glx.SwapIntervalMESA(interval); + else if (_glfw.glx.SGI_swap_control) + { + if (interval > 0) + _glfw.glx.SwapIntervalSGI(interval); + } +} + +int _glfwPlatformExtensionSupported(const char* extension) +{ + const GLubyte* extensions; + + // Get list of GLX extensions + extensions = (const GLubyte*) glXQueryExtensionsString(_glfw.x11.display, + _glfw.x11.screen); + if (extensions != NULL) + { + if (_glfwStringInExtensionString(extension, extensions)) + return GL_TRUE; + } + + return GL_FALSE; +} + +GLFWglproc _glfwPlatformGetProcAddress(const char* procname) +{ + return _glfw_glXGetProcAddress((const GLubyte*) procname); +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW native API ////// +////////////////////////////////////////////////////////////////////////// + +GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* handle) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + return window->glx.context; +} + diff --git a/testbed/glfw/src/glx_context.h b/testbed/glfw/src/glx_context.h new file mode 100644 index 00000000..918ab000 --- /dev/null +++ b/testbed/glfw/src/glx_context.h @@ -0,0 +1,120 @@ +//======================================================================== +// GLFW 3.1 GLX - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2010 Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#ifndef _glx_context_h_ +#define _glx_context_h_ + +#define GLX_GLXEXT_LEGACY +#include + +// This path may need to be changed if you build GLFW using your own setup +// We ship and use our own copy of glxext.h since GLFW uses fairly new +// extensions and not all operating systems come with an up-to-date version +#include "../deps/GL/glxext.h" + +// Do we have support for dlopen/dlsym? +#if defined(_GLFW_HAS_DLOPEN) + #include +#endif + +// We support four different ways for getting addresses for GL/GLX +// extension functions: glXGetProcAddress, glXGetProcAddressARB, +// glXGetProcAddressEXT, and dlsym +#if defined(_GLFW_HAS_GLXGETPROCADDRESSARB) + #define _glfw_glXGetProcAddress(x) glXGetProcAddressARB(x) +#elif defined(_GLFW_HAS_GLXGETPROCADDRESS) + #define _glfw_glXGetProcAddress(x) glXGetProcAddress(x) +#elif defined(_GLFW_HAS_GLXGETPROCADDRESSEXT) + #define _glfw_glXGetProcAddress(x) glXGetProcAddressEXT(x) +#elif defined(_GLFW_HAS_DLOPEN) + #define _glfw_glXGetProcAddress(x) dlsym(_glfw.glx.libGL, x) + #define _GLFW_DLOPEN_LIBGL +#else + #error "No OpenGL entry point retrieval mechanism was enabled" +#endif + +#define _GLFW_PLATFORM_FBCONFIG GLXFBConfig glx +#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextGLX glx +#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryGLX glx + +#ifndef GLX_MESA_swap_control +typedef int (*PFNGLXSWAPINTERVALMESAPROC)(int); +#endif + + +// GLX-specific per-context data +// +typedef struct _GLFWcontextGLX +{ + // Rendering context + GLXContext context; + // Visual of selected GLXFBConfig + XVisualInfo* visual; + +} _GLFWcontextGLX; + + +// GLX-specific global data +// +typedef struct _GLFWlibraryGLX +{ + int versionMajor, versionMinor; + int eventBase; + int errorBase; + + // GLX extensions + PFNGLXSWAPINTERVALSGIPROC SwapIntervalSGI; + PFNGLXSWAPINTERVALEXTPROC SwapIntervalEXT; + PFNGLXSWAPINTERVALMESAPROC SwapIntervalMESA; + PFNGLXCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB; + GLboolean SGI_swap_control; + GLboolean EXT_swap_control; + GLboolean MESA_swap_control; + GLboolean ARB_multisample; + GLboolean ARB_framebuffer_sRGB; + GLboolean ARB_create_context; + GLboolean ARB_create_context_profile; + GLboolean ARB_create_context_robustness; + GLboolean EXT_create_context_es2_profile; + GLboolean ARB_context_flush_control; + +#if defined(_GLFW_DLOPEN_LIBGL) + // dlopen handle for libGL.so (for glfwGetProcAddress) + void* libGL; +#endif + +} _GLFWlibraryGLX; + + +int _glfwInitContextAPI(void); +void _glfwTerminateContextAPI(void); +int _glfwCreateContext(_GLFWwindow* window, + const _GLFWctxconfig* ctxconfig, + const _GLFWfbconfig* fbconfig); +void _glfwDestroyContext(_GLFWwindow* window); + +#endif // _glx_context_h_ diff --git a/testbed/glfw/src/init.c b/testbed/glfw/src/init.c new file mode 100644 index 00000000..4a044ed0 --- /dev/null +++ b/testbed/glfw/src/init.c @@ -0,0 +1,201 @@ +//======================================================================== +// GLFW 3.1 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2010 Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include "internal.h" + +#include +#include +#include +#include + + +// The three global variables below comprise all global data in GLFW, except for +// various static const translation tables. Any other global variable is a bug. + +// Global state shared between compilation units of GLFW +// These are documented in internal.h +// +GLboolean _glfwInitialized = GL_FALSE; +_GLFWlibrary _glfw; + +// This is outside of _glfw so it can be initialized and usable before +// glfwInit is called, which lets that function report errors +// +static GLFWerrorfun _glfwErrorCallback = NULL; + + +// Returns a generic string representation of the specified error +// +static const char* getErrorString(int error) +{ + switch (error) + { + case GLFW_NOT_INITIALIZED: + return "The GLFW library is not initialized"; + case GLFW_NO_CURRENT_CONTEXT: + return "There is no current context"; + case GLFW_INVALID_ENUM: + return "Invalid argument for enum parameter"; + case GLFW_INVALID_VALUE: + return "Invalid value for parameter"; + case GLFW_OUT_OF_MEMORY: + return "Out of memory"; + case GLFW_API_UNAVAILABLE: + return "The requested client API is unavailable"; + case GLFW_VERSION_UNAVAILABLE: + return "The requested client API version is unavailable"; + case GLFW_PLATFORM_ERROR: + return "A platform-specific error occurred"; + case GLFW_FORMAT_UNAVAILABLE: + return "The requested format is unavailable"; + } + + return "ERROR: UNKNOWN ERROR TOKEN PASSED TO glfwErrorString"; +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW event API ////// +////////////////////////////////////////////////////////////////////////// + +void _glfwInputError(int error, const char* format, ...) +{ + if (_glfwErrorCallback) + { + char buffer[16384]; + const char* description; + + if (format) + { + int count; + va_list vl; + + va_start(vl, format); + count = vsnprintf(buffer, sizeof(buffer), format, vl); + va_end(vl); + + if (count < 0) + buffer[sizeof(buffer) - 1] = '\0'; + + description = buffer; + } + else + description = getErrorString(error); + + _glfwErrorCallback(error, description); + } +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW public API ////// +////////////////////////////////////////////////////////////////////////// + +GLFWAPI int glfwInit(void) +{ + if (_glfwInitialized) + return GL_TRUE; + + memset(&_glfw, 0, sizeof(_glfw)); + + if (!_glfwPlatformInit()) + { + _glfwPlatformTerminate(); + return GL_FALSE; + } + + _glfw.monitors = _glfwPlatformGetMonitors(&_glfw.monitorCount); + if (!_glfw.monitorCount) + { + _glfwInputError(GLFW_PLATFORM_ERROR, "No monitors found"); + _glfwPlatformTerminate(); + return GL_FALSE; + } + + _glfwInitialized = GL_TRUE; + + // Not all window hints have zero as their default value + glfwDefaultWindowHints(); + + return GL_TRUE; +} + +GLFWAPI void glfwTerminate(void) +{ + int i; + + if (!_glfwInitialized) + return; + + memset(&_glfw.callbacks, 0, sizeof(_glfw.callbacks)); + + while (_glfw.windowListHead) + glfwDestroyWindow((GLFWwindow*) _glfw.windowListHead); + + while (_glfw.cursorListHead) + glfwDestroyCursor((GLFWcursor*) _glfw.cursorListHead); + + for (i = 0; i < _glfw.monitorCount; i++) + { + _GLFWmonitor* monitor = _glfw.monitors[i]; + if (monitor->originalRamp.size) + _glfwPlatformSetGammaRamp(monitor, &monitor->originalRamp); + } + + _glfwFreeMonitors(_glfw.monitors, _glfw.monitorCount); + _glfw.monitors = NULL; + _glfw.monitorCount = 0; + + _glfwPlatformTerminate(); + + memset(&_glfw, 0, sizeof(_glfw)); + _glfwInitialized = GL_FALSE; +} + +GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev) +{ + if (major != NULL) + *major = GLFW_VERSION_MAJOR; + + if (minor != NULL) + *minor = GLFW_VERSION_MINOR; + + if (rev != NULL) + *rev = GLFW_VERSION_REVISION; +} + +GLFWAPI const char* glfwGetVersionString(void) +{ + return _glfwPlatformGetVersionString(); +} + +GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun) +{ + _GLFW_SWAP_POINTERS(_glfwErrorCallback, cbfun); + return cbfun; +} + diff --git a/testbed/glfw/src/input.c b/testbed/glfw/src/input.c new file mode 100644 index 00000000..74a715c9 --- /dev/null +++ b/testbed/glfw/src/input.c @@ -0,0 +1,596 @@ +//======================================================================== +// GLFW 3.1 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2010 Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include "internal.h" + +#include +#if defined(_MSC_VER) + #include +#endif + +// Internal key state used for sticky keys +#define _GLFW_STICK 3 + + +// Sets the cursor mode for the specified window +// +static void setCursorMode(_GLFWwindow* window, int newMode) +{ + const int oldMode = window->cursorMode; + + if (newMode != GLFW_CURSOR_NORMAL && + newMode != GLFW_CURSOR_HIDDEN && + newMode != GLFW_CURSOR_DISABLED) + { + _glfwInputError(GLFW_INVALID_ENUM, NULL); + return; + } + + if (oldMode == newMode) + return; + + window->cursorMode = newMode; + + if (_glfw.focusedWindow == window) + { + if (oldMode == GLFW_CURSOR_DISABLED) + { + _glfwPlatformSetCursorPos(window, + _glfw.cursorPosX, + _glfw.cursorPosY); + } + else if (newMode == GLFW_CURSOR_DISABLED) + { + int width, height; + + _glfwPlatformGetCursorPos(window, + &_glfw.cursorPosX, + &_glfw.cursorPosY); + + window->cursorPosX = _glfw.cursorPosX; + window->cursorPosY = _glfw.cursorPosY; + + _glfwPlatformGetWindowSize(window, &width, &height); + _glfwPlatformSetCursorPos(window, width / 2, height / 2); + } + + _glfwPlatformApplyCursorMode(window); + } +} + +// Set sticky keys mode for the specified window +// +static void setStickyKeys(_GLFWwindow* window, int enabled) +{ + if (window->stickyKeys == enabled) + return; + + if (!enabled) + { + int i; + + // Release all sticky keys + for (i = 0; i <= GLFW_KEY_LAST; i++) + { + if (window->keys[i] == _GLFW_STICK) + window->keys[i] = GLFW_RELEASE; + } + } + + window->stickyKeys = enabled; +} + +// Set sticky mouse buttons mode for the specified window +// +static void setStickyMouseButtons(_GLFWwindow* window, int enabled) +{ + if (window->stickyMouseButtons == enabled) + return; + + if (!enabled) + { + int i; + + // Release all sticky mouse buttons + for (i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i++) + { + if (window->mouseButtons[i] == _GLFW_STICK) + window->mouseButtons[i] = GLFW_RELEASE; + } + } + + window->stickyMouseButtons = enabled; +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW event API ////// +////////////////////////////////////////////////////////////////////////// + +void _glfwInputKey(_GLFWwindow* window, int key, int scancode, int action, int mods) +{ + if (key >= 0 && key <= GLFW_KEY_LAST) + { + GLboolean repeated = GL_FALSE; + + if (action == GLFW_RELEASE && window->keys[key] == GLFW_RELEASE) + return; + + if (action == GLFW_PRESS && window->keys[key] == GLFW_PRESS) + repeated = GL_TRUE; + + if (action == GLFW_RELEASE && window->stickyKeys) + window->keys[key] = _GLFW_STICK; + else + window->keys[key] = (char) action; + + if (repeated) + action = GLFW_REPEAT; + } + + if (window->callbacks.key) + window->callbacks.key((GLFWwindow*) window, key, scancode, action, mods); +} + +void _glfwInputChar(_GLFWwindow* window, unsigned int codepoint, int mods, int plain) +{ + if (codepoint < 32 || (codepoint > 126 && codepoint < 160)) + return; + + if (window->callbacks.charmods) + window->callbacks.charmods((GLFWwindow*) window, codepoint, mods); + + if (plain) + { + if (window->callbacks.character) + window->callbacks.character((GLFWwindow*) window, codepoint); + } +} + +void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset) +{ + if (window->callbacks.scroll) + window->callbacks.scroll((GLFWwindow*) window, xoffset, yoffset); +} + +void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods) +{ + if (button < 0 || button > GLFW_MOUSE_BUTTON_LAST) + return; + + // Register mouse button action + if (action == GLFW_RELEASE && window->stickyMouseButtons) + window->mouseButtons[button] = _GLFW_STICK; + else + window->mouseButtons[button] = (char) action; + + if (window->callbacks.mouseButton) + window->callbacks.mouseButton((GLFWwindow*) window, button, action, mods); +} + +void _glfwInputCursorMotion(_GLFWwindow* window, double x, double y) +{ + if (window->cursorMode == GLFW_CURSOR_DISABLED) + { + if (x == 0.0 && y == 0.0) + return; + + window->cursorPosX += x; + window->cursorPosY += y; + + x = window->cursorPosX; + y = window->cursorPosY; + } + + if (window->callbacks.cursorPos) + window->callbacks.cursorPos((GLFWwindow*) window, x, y); +} + +void _glfwInputCursorEnter(_GLFWwindow* window, int entered) +{ + if (window->callbacks.cursorEnter) + window->callbacks.cursorEnter((GLFWwindow*) window, entered); +} + +void _glfwInputDrop(_GLFWwindow* window, int count, const char** names) +{ + if (window->callbacks.drop) + window->callbacks.drop((GLFWwindow*) window, count, names); +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW public API ////// +////////////////////////////////////////////////////////////////////////// + +GLFWAPI int glfwGetInputMode(GLFWwindow* handle, int mode) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + + _GLFW_REQUIRE_INIT_OR_RETURN(0); + + switch (mode) + { + case GLFW_CURSOR: + return window->cursorMode; + case GLFW_STICKY_KEYS: + return window->stickyKeys; + case GLFW_STICKY_MOUSE_BUTTONS: + return window->stickyMouseButtons; + default: + _glfwInputError(GLFW_INVALID_ENUM, NULL); + return 0; + } +} + +GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + + _GLFW_REQUIRE_INIT(); + + switch (mode) + { + case GLFW_CURSOR: + setCursorMode(window, value); + break; + case GLFW_STICKY_KEYS: + setStickyKeys(window, value ? GL_TRUE : GL_FALSE); + break; + case GLFW_STICKY_MOUSE_BUTTONS: + setStickyMouseButtons(window, value ? GL_TRUE : GL_FALSE); + break; + default: + _glfwInputError(GLFW_INVALID_ENUM, NULL); + break; + } +} + +GLFWAPI int glfwGetKey(GLFWwindow* handle, int key) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + + _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_RELEASE); + + if (key < 0 || key > GLFW_KEY_LAST) + { + _glfwInputError(GLFW_INVALID_ENUM, "The specified key is invalid"); + return GLFW_RELEASE; + } + + if (window->keys[key] == _GLFW_STICK) + { + // Sticky mode: release key now + window->keys[key] = GLFW_RELEASE; + return GLFW_PRESS; + } + + return (int) window->keys[key]; +} + +GLFWAPI int glfwGetMouseButton(GLFWwindow* handle, int button) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + + _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_RELEASE); + + if (button < 0 || button > GLFW_MOUSE_BUTTON_LAST) + { + _glfwInputError(GLFW_INVALID_ENUM, + "The specified mouse button is invalid"); + return GLFW_RELEASE; + } + + if (window->mouseButtons[button] == _GLFW_STICK) + { + // Sticky mode: release mouse button now + window->mouseButtons[button] = GLFW_RELEASE; + return GLFW_PRESS; + } + + return (int) window->mouseButtons[button]; +} + +GLFWAPI void glfwGetCursorPos(GLFWwindow* handle, double* xpos, double* ypos) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + + if (xpos) + *xpos = 0; + if (ypos) + *ypos = 0; + + _GLFW_REQUIRE_INIT(); + + if (window->cursorMode == GLFW_CURSOR_DISABLED) + { + if (xpos) + *xpos = window->cursorPosX; + if (ypos) + *ypos = window->cursorPosY; + } + else + _glfwPlatformGetCursorPos(window, xpos, ypos); +} + +GLFWAPI void glfwSetCursorPos(GLFWwindow* handle, double xpos, double ypos) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + + _GLFW_REQUIRE_INIT(); + + if (_glfw.focusedWindow != window) + return; + + if (window->cursorMode == GLFW_CURSOR_DISABLED) + { + // Only update the accumulated position if the cursor is disabled + window->cursorPosX = xpos; + window->cursorPosY = ypos; + } + else + { + // Update system cursor position + _glfwPlatformSetCursorPos(window, xpos, ypos); + } +} + +GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot) +{ + _GLFWcursor* cursor; + + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + + cursor = calloc(1, sizeof(_GLFWcursor)); + cursor->next = _glfw.cursorListHead; + _glfw.cursorListHead = cursor; + + if (!_glfwPlatformCreateCursor(cursor, image, xhot, yhot)) + { + glfwDestroyCursor((GLFWcursor*) cursor); + return NULL; + } + + return (GLFWcursor*) cursor; +} + +GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape) +{ + _GLFWcursor* cursor; + + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + + cursor = calloc(1, sizeof(_GLFWcursor)); + cursor->next = _glfw.cursorListHead; + _glfw.cursorListHead = cursor; + + if (!_glfwPlatformCreateStandardCursor(cursor, shape)) + { + glfwDestroyCursor((GLFWcursor*) cursor); + return NULL; + } + + return (GLFWcursor*) cursor; +} + +GLFWAPI void glfwDestroyCursor(GLFWcursor* handle) +{ + _GLFWcursor* cursor = (_GLFWcursor*) handle; + + _GLFW_REQUIRE_INIT(); + + if (cursor == NULL) + return; + + // Make sure the cursor is not being used by any window + { + _GLFWwindow* window; + + for (window = _glfw.windowListHead; window; window = window->next) + { + if (window->cursor == cursor) + glfwSetCursor((GLFWwindow*) window, NULL); + } + } + + _glfwPlatformDestroyCursor(cursor); + + // Unlink cursor from global linked list + { + _GLFWcursor** prev = &_glfw.cursorListHead; + + while (*prev != cursor) + prev = &((*prev)->next); + + *prev = cursor->next; + } + + free(cursor); +} + +GLFWAPI void glfwSetCursor(GLFWwindow* windowHandle, GLFWcursor* cursorHandle) +{ + _GLFWwindow* window = (_GLFWwindow*) windowHandle; + _GLFWcursor* cursor = (_GLFWcursor*) cursorHandle; + + _GLFW_REQUIRE_INIT(); + + _glfwPlatformSetCursor(window, cursor); + + window->cursor = cursor; +} + +GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* handle, GLFWkeyfun cbfun) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFW_SWAP_POINTERS(window->callbacks.key, cbfun); + return cbfun; +} + +GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* handle, GLFWcharfun cbfun) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFW_SWAP_POINTERS(window->callbacks.character, cbfun); + return cbfun; +} + +GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* handle, GLFWcharmodsfun cbfun) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFW_SWAP_POINTERS(window->callbacks.charmods, cbfun); + return cbfun; +} + +GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* handle, + GLFWmousebuttonfun cbfun) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFW_SWAP_POINTERS(window->callbacks.mouseButton, cbfun); + return cbfun; +} + +GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* handle, + GLFWcursorposfun cbfun) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFW_SWAP_POINTERS(window->callbacks.cursorPos, cbfun); + return cbfun; +} + +GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* handle, + GLFWcursorenterfun cbfun) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFW_SWAP_POINTERS(window->callbacks.cursorEnter, cbfun); + return cbfun; +} + +GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* handle, + GLFWscrollfun cbfun) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFW_SWAP_POINTERS(window->callbacks.scroll, cbfun); + return cbfun; +} + +GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* handle, GLFWdropfun cbfun) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFW_SWAP_POINTERS(window->callbacks.drop, cbfun); + return cbfun; +} + +GLFWAPI int glfwJoystickPresent(int joy) +{ + _GLFW_REQUIRE_INIT_OR_RETURN(0); + + if (joy < 0 || joy > GLFW_JOYSTICK_LAST) + { + _glfwInputError(GLFW_INVALID_ENUM, NULL); + return 0; + } + + return _glfwPlatformJoystickPresent(joy); +} + +GLFWAPI const float* glfwGetJoystickAxes(int joy, int* count) +{ + *count = 0; + + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + + if (joy < 0 || joy > GLFW_JOYSTICK_LAST) + { + _glfwInputError(GLFW_INVALID_ENUM, NULL); + return NULL; + } + + return _glfwPlatformGetJoystickAxes(joy, count); +} + +GLFWAPI const unsigned char* glfwGetJoystickButtons(int joy, int* count) +{ + *count = 0; + + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + + if (joy < 0 || joy > GLFW_JOYSTICK_LAST) + { + _glfwInputError(GLFW_INVALID_ENUM, NULL); + return NULL; + } + + return _glfwPlatformGetJoystickButtons(joy, count); +} + +GLFWAPI const char* glfwGetJoystickName(int joy) +{ + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + + if (joy < 0 || joy > GLFW_JOYSTICK_LAST) + { + _glfwInputError(GLFW_INVALID_ENUM, NULL); + return NULL; + } + + return _glfwPlatformGetJoystickName(joy); +} + +GLFWAPI void glfwSetClipboardString(GLFWwindow* handle, const char* string) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + _GLFW_REQUIRE_INIT(); + _glfwPlatformSetClipboardString(window, string); +} + +GLFWAPI const char* glfwGetClipboardString(GLFWwindow* handle) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + return _glfwPlatformGetClipboardString(window); +} + +GLFWAPI double glfwGetTime(void) +{ + _GLFW_REQUIRE_INIT_OR_RETURN(0.0); + return _glfwPlatformGetTime(); +} + +GLFWAPI void glfwSetTime(double time) +{ + _GLFW_REQUIRE_INIT(); + _glfwPlatformSetTime(time); +} + diff --git a/testbed/glfw/src/internal.h b/testbed/glfw/src/internal.h new file mode 100644 index 00000000..1e6977ff --- /dev/null +++ b/testbed/glfw/src/internal.h @@ -0,0 +1,886 @@ +//======================================================================== +// GLFW 3.1 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2010 Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#ifndef _internal_h_ +#define _internal_h_ + + +#if defined(_GLFW_USE_CONFIG_H) + #include "glfw_config.h" +#endif + +#define _GLFW_VERSION_NUMBER "3.1.0" + +#if defined(_GLFW_USE_OPENGL) + // This is the default for glfw3.h +#elif defined(_GLFW_USE_GLESV1) + #define GLFW_INCLUDE_ES1 +#elif defined(_GLFW_USE_GLESV2) + #define GLFW_INCLUDE_ES2 +#else + #error "No supported client library selected" +#endif + +// Disable the inclusion of the platform glext.h by gl.h to allow proper +// inclusion of our own, newer glext.h below +#define GL_GLEXT_LEGACY + +#include "../include/GLFW/glfw3.h" + +#if defined(_GLFW_USE_OPENGL) + // This path may need to be changed if you build GLFW using your own setup + // GLFW comes with its own copy of glext.h since it uses fairly new extensions + // and not all development environments come with an up-to-date version + #include "../deps/GL/glext.h" +#endif + +typedef struct _GLFWwndconfig _GLFWwndconfig; +typedef struct _GLFWctxconfig _GLFWctxconfig; +typedef struct _GLFWfbconfig _GLFWfbconfig; +typedef struct _GLFWwindow _GLFWwindow; +typedef struct _GLFWlibrary _GLFWlibrary; +typedef struct _GLFWmonitor _GLFWmonitor; +typedef struct _GLFWcursor _GLFWcursor; + +#if defined(_GLFW_COCOA) + #include "cocoa_platform.h" +#elif defined(_GLFW_WIN32) + #include "win32_platform.h" +#elif defined(_GLFW_X11) + #include "x11_platform.h" +#elif defined(_GLFW_WAYLAND) + #include "wl_platform.h" +#elif defined(_GLFW_MIR) + #include "mir_platform.h" +#else + #error "No supported window creation API selected" +#endif + + +//======================================================================== +// Doxygen group definitions +//======================================================================== + +/*! @defgroup platform Platform interface + * @brief The interface implemented by the platform-specific code. + * + * The platform API is the interface exposed by the platform-specific code for + * each platform and is called by the shared code of the public API It mirrors + * the public API except it uses objects instead of handles. + */ +/*! @defgroup event Event interface + * @brief The interface used by the platform-specific code to report events. + * + * The event API is used by the platform-specific code to notify the shared + * code of events that can be translated into state changes and/or callback + * calls. + */ +/*! @defgroup utility Utility functions + * @brief Various utility functions for internal use. + * + * These functions are shared code and may be used by any part of GLFW + * Each platform may add its own utility functions, but those may only be + * called by the platform-specific code + */ + + +//======================================================================== +// Helper macros +//======================================================================== + +// Checks for whether the library has been initialized +#define _GLFW_REQUIRE_INIT() \ + if (!_glfwInitialized) \ + { \ + _glfwInputError(GLFW_NOT_INITIALIZED, NULL); \ + return; \ + } +#define _GLFW_REQUIRE_INIT_OR_RETURN(x) \ + if (!_glfwInitialized) \ + { \ + _glfwInputError(GLFW_NOT_INITIALIZED, NULL); \ + return x; \ + } + +// Swaps the provided pointers +#define _GLFW_SWAP_POINTERS(x, y) \ + { \ + void* t; \ + t = x; \ + x = y; \ + y = t; \ + } + + +//======================================================================== +// Platform-independent structures +//======================================================================== + +/*! @brief Window configuration. + * + * Parameters relating to the creation of the window but not directly related + * to the framebuffer. This is used to pass window creation parameters from + * shared code to the platform API. + */ +struct _GLFWwndconfig +{ + int width; + int height; + const char* title; + GLboolean resizable; + GLboolean visible; + GLboolean decorated; + GLboolean focused; + GLboolean autoIconify; + GLboolean floating; + _GLFWmonitor* monitor; +}; + + +/*! @brief Context configuration. + * + * Parameters relating to the creation of the context but not directly related + * to the framebuffer. This is used to pass context creation parameters from + * shared code to the platform API. + */ +struct _GLFWctxconfig +{ + int api; + int major; + int minor; + GLboolean forward; + GLboolean debug; + int profile; + int robustness; + int release; + _GLFWwindow* share; +}; + + +/*! @brief Framebuffer configuration. + * + * This describes buffers and their sizes. It also contains + * a platform-specific ID used to map back to the backend API object. + * + * It is used to pass framebuffer parameters from shared code to the platform + * API and also to enumerate and select available framebuffer configs. + */ +struct _GLFWfbconfig +{ + int redBits; + int greenBits; + int blueBits; + int alphaBits; + int depthBits; + int stencilBits; + int accumRedBits; + int accumGreenBits; + int accumBlueBits; + int accumAlphaBits; + int auxBuffers; + int stereo; + int samples; + int sRGB; + int doublebuffer; + + // This is defined in the context API's context.h + _GLFW_PLATFORM_FBCONFIG; +}; + + +/*! @brief Window and context structure. + */ +struct _GLFWwindow +{ + struct _GLFWwindow* next; + + // Window settings and state + GLboolean resizable; + GLboolean decorated; + GLboolean autoIconify; + GLboolean floating; + GLboolean closed; + void* userPointer; + GLFWvidmode videoMode; + _GLFWmonitor* monitor; + _GLFWcursor* cursor; + + // Window input state + GLboolean stickyKeys; + GLboolean stickyMouseButtons; + double cursorPosX, cursorPosY; + int cursorMode; + char mouseButtons[GLFW_MOUSE_BUTTON_LAST + 1]; + char keys[GLFW_KEY_LAST + 1]; + + // OpenGL extensions and context attributes + struct { + int api; + int major, minor, revision; + GLboolean forward, debug; + int profile; + int robustness; + int release; + } context; + +#if defined(_GLFW_USE_OPENGL) + PFNGLGETSTRINGIPROC GetStringi; +#endif + + struct { + GLFWwindowposfun pos; + GLFWwindowsizefun size; + GLFWwindowclosefun close; + GLFWwindowrefreshfun refresh; + GLFWwindowfocusfun focus; + GLFWwindowiconifyfun iconify; + GLFWframebuffersizefun fbsize; + GLFWmousebuttonfun mouseButton; + GLFWcursorposfun cursorPos; + GLFWcursorenterfun cursorEnter; + GLFWscrollfun scroll; + GLFWkeyfun key; + GLFWcharfun character; + GLFWcharmodsfun charmods; + GLFWdropfun drop; + } callbacks; + + // This is defined in the window API's platform.h + _GLFW_PLATFORM_WINDOW_STATE; + // This is defined in the context API's context.h + _GLFW_PLATFORM_CONTEXT_STATE; +}; + + +/*! @brief Monitor structure. + */ +struct _GLFWmonitor +{ + char* name; + + // Physical dimensions in millimeters. + int widthMM, heightMM; + + GLFWvidmode* modes; + int modeCount; + GLFWvidmode currentMode; + + GLFWgammaramp originalRamp; + GLFWgammaramp currentRamp; + + // This is defined in the window API's platform.h + _GLFW_PLATFORM_MONITOR_STATE; +}; + + +/*! @brief Cursor structure + */ +struct _GLFWcursor +{ + _GLFWcursor* next; + + // This is defined in the window API's platform.h + _GLFW_PLATFORM_CURSOR_STATE; +}; + +/*! @brief Library global data. + */ +struct _GLFWlibrary +{ + struct { + int redBits; + int greenBits; + int blueBits; + int alphaBits; + int depthBits; + int stencilBits; + int accumRedBits; + int accumGreenBits; + int accumBlueBits; + int accumAlphaBits; + int auxBuffers; + int stereo; + int resizable; + int visible; + int decorated; + int focused; + int autoIconify; + int floating; + int samples; + int sRGB; + int refreshRate; + int doublebuffer; + int api; + int major; + int minor; + int forward; + int debug; + int profile; + int robustness; + int release; + } hints; + + double cursorPosX, cursorPosY; + + _GLFWcursor* cursorListHead; + + _GLFWwindow* windowListHead; + _GLFWwindow* focusedWindow; + + _GLFWmonitor** monitors; + int monitorCount; + + struct { + GLFWmonitorfun monitor; + } callbacks; + + // This is defined in the window API's platform.h + _GLFW_PLATFORM_LIBRARY_WINDOW_STATE; + // This is defined in the context API's context.h + _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE; + // This is defined in the platform's time.h + _GLFW_PLATFORM_LIBRARY_TIME_STATE; + // This is defined in the platform's joystick.h + _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE; + // This is defined in the platform's tls.h + _GLFW_PLATFORM_LIBRARY_TLS_STATE; +}; + + +//======================================================================== +// Global state shared between compilation units of GLFW +//======================================================================== + +/*! @brief Flag indicating whether GLFW has been successfully initialized. + */ +extern GLboolean _glfwInitialized; + +/*! @brief All global data protected by @ref _glfwInitialized. + * This should only be touched after a call to @ref glfwInit that has not been + * followed by a call to @ref glfwTerminate. + */ +extern _GLFWlibrary _glfw; + + +//======================================================================== +// Platform API functions +//======================================================================== + +/*! @brief Initializes the platform-specific part of the library. + * @return `GL_TRUE` if successful, or `GL_FALSE` if an error occurred. + * @ingroup platform + */ +int _glfwPlatformInit(void); + +/*! @brief Terminates the platform-specific part of the library. + * @ingroup platform + */ +void _glfwPlatformTerminate(void); + +/*! @copydoc glfwGetVersionString + * @ingroup platform + * + * @note The returned string must be available for the duration of the program. + * + * @note The returned string must not change for the duration of the program. + */ +const char* _glfwPlatformGetVersionString(void); + +/*! @copydoc glfwGetCursorPos + * @ingroup platform + */ +void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos); + +/*! @copydoc glfwSetCursorPos + * @ingroup platform + */ +void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos); + +/*! @brief Applies the cursor mode of the specified window to the system. + * @param[in] window The window whose cursor mode to apply. + * @ingroup platform + */ +void _glfwPlatformApplyCursorMode(_GLFWwindow* window); + +/*! @copydoc glfwGetMonitors + * @ingroup platform + */ +_GLFWmonitor** _glfwPlatformGetMonitors(int* count); + +/*! @brief Checks whether two monitor objects represent the same monitor. + * + * @param[in] first The first monitor. + * @param[in] second The second monitor. + * @return @c GL_TRUE if the monitor objects represent the same monitor, or @c + * GL_FALSE otherwise. + * @ingroup platform + */ +GLboolean _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second); + +/*! @copydoc glfwGetMonitorPos + * @ingroup platform + */ +void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos); + +/*! @copydoc glfwGetVideoModes + * @ingroup platform + */ +GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count); + +/*! @ingroup platform + */ +void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode); + +/*! @copydoc glfwGetGammaRamp + * @ingroup platform + */ +void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp); + +/*! @copydoc glfwSetGammaRamp + * @ingroup platform + */ +void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp); + +/*! @copydoc glfwSetClipboardString + * @ingroup platform + */ +void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string); + +/*! @copydoc glfwGetClipboardString + * @ingroup platform + * + * @note The returned string must be valid until the next call to @ref + * _glfwPlatformGetClipboardString or @ref _glfwPlatformSetClipboardString. + */ +const char* _glfwPlatformGetClipboardString(_GLFWwindow* window); + +/*! @copydoc glfwJoystickPresent + * @ingroup platform + */ +int _glfwPlatformJoystickPresent(int joy); + +/*! @copydoc glfwGetJoystickAxes + * @ingroup platform + */ +const float* _glfwPlatformGetJoystickAxes(int joy, int* count); + +/*! @copydoc glfwGetJoystickButtons + * @ingroup platform + */ +const unsigned char* _glfwPlatformGetJoystickButtons(int joy, int* count); + +/*! @copydoc glfwGetJoystickName + * @ingroup platform + */ +const char* _glfwPlatformGetJoystickName(int joy); + +/*! @copydoc glfwGetTime + * @ingroup platform + */ +double _glfwPlatformGetTime(void); + +/*! @copydoc glfwSetTime + * @ingroup platform + */ +void _glfwPlatformSetTime(double time); + +/*! @ingroup platform + */ +int _glfwPlatformCreateWindow(_GLFWwindow* window, + const _GLFWwndconfig* wndconfig, + const _GLFWctxconfig* ctxconfig, + const _GLFWfbconfig* fbconfig); + +/*! @ingroup platform + */ +void _glfwPlatformDestroyWindow(_GLFWwindow* window); + +/*! @copydoc glfwSetWindowTitle + * @ingroup platform + */ +void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title); + +/*! @copydoc glfwGetWindowPos + * @ingroup platform + */ +void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos); + +/*! @copydoc glfwSetWindowPos + * @ingroup platform + */ +void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos); + +/*! @copydoc glfwGetWindowSize + * @ingroup platform + */ +void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height); + +/*! @copydoc glfwSetWindowSize + * @ingroup platform + */ +void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height); + +/*! @copydoc glfwGetFramebufferSize + * @ingroup platform + */ +void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height); + +/*! @copydoc glfwGetWindowFrameSize + * @ingroup platform + */ +void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, int* left, int* top, int* right, int* bottom); + +/*! @copydoc glfwIconifyWindow + * @ingroup platform + */ +void _glfwPlatformIconifyWindow(_GLFWwindow* window); + +/*! @copydoc glfwRestoreWindow + * @ingroup platform + */ +void _glfwPlatformRestoreWindow(_GLFWwindow* window); + +/*! @copydoc glfwShowWindow + * @ingroup platform + */ +void _glfwPlatformShowWindow(_GLFWwindow* window); + +/*! @ingroup platform + */ +void _glfwPlatformUnhideWindow(_GLFWwindow* window); + +/*! @copydoc glfwHideWindow + * @ingroup platform + */ +void _glfwPlatformHideWindow(_GLFWwindow* window); + +/*! @brief Returns whether the window is focused. + * @ingroup platform + */ +int _glfwPlatformWindowFocused(_GLFWwindow* window); + +/*! @brief Returns whether the window is iconified. + * @ingroup platform + */ +int _glfwPlatformWindowIconified(_GLFWwindow* window); + +/*! @brief Returns whether the window is visible. + * @ingroup platform + */ +int _glfwPlatformWindowVisible(_GLFWwindow* window); + +/*! @copydoc glfwPollEvents + * @ingroup platform + */ +void _glfwPlatformPollEvents(void); + +/*! @copydoc glfwWaitEvents + * @ingroup platform + */ +void _glfwPlatformWaitEvents(void); + +/*! @copydoc glfwPostEmptyEvent + * @ingroup platform + */ +void _glfwPlatformPostEmptyEvent(void); + +/*! @copydoc glfwMakeContextCurrent + * @ingroup platform + */ +void _glfwPlatformMakeContextCurrent(_GLFWwindow* window); + +/*! @copydoc glfwGetCurrentContext + * @ingroup platform + */ +_GLFWwindow* _glfwPlatformGetCurrentContext(void); + +/*! @copydoc glfwSwapBuffers + * @ingroup platform + */ +void _glfwPlatformSwapBuffers(_GLFWwindow* window); + +/*! @copydoc glfwSwapInterval + * @ingroup platform + */ +void _glfwPlatformSwapInterval(int interval); + +/*! @copydoc glfwExtensionSupported + * @ingroup platform + */ +int _glfwPlatformExtensionSupported(const char* extension); + +/*! @copydoc glfwGetProcAddress + * @ingroup platform + */ +GLFWglproc _glfwPlatformGetProcAddress(const char* procname); + +/*! @copydoc glfwCreateCursor + * @ingroup platform + */ +int _glfwPlatformCreateCursor(_GLFWcursor* cursor, const GLFWimage* image, int xhot, int yhot); + +/*! @copydoc glfwCreateStandardCursor + * @ingroup platform + */ +int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape); + +/*! @copydoc glfwDestroyCursor + * @ingroup platform + */ +void _glfwPlatformDestroyCursor(_GLFWcursor* cursor); + +/*! @copydoc glfwSetCursor + * @ingroup platform + */ +void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor); + + +//======================================================================== +// Event API functions +//======================================================================== + +/*! @brief Notifies shared code of a window focus event. + * @param[in] window The window that received the event. + * @param[in] focused `GL_TRUE` if the window received focus, or `GL_FALSE` + * if it lost focus. + * @ingroup event + */ +void _glfwInputWindowFocus(_GLFWwindow* window, GLboolean focused); + +/*! @brief Notifies shared code of a window movement event. + * @param[in] window The window that received the event. + * @param[in] xpos The new x-coordinate of the client area of the window. + * @param[in] ypos The new y-coordinate of the client area of the window. + * @ingroup event + */ +void _glfwInputWindowPos(_GLFWwindow* window, int xpos, int ypos); + +/*! @brief Notifies shared code of a window resize event. + * @param[in] window The window that received the event. + * @param[in] width The new width of the client area of the window. + * @param[in] height The new height of the client area of the window. + * @ingroup event + */ +void _glfwInputWindowSize(_GLFWwindow* window, int width, int height); + +/*! @brief Notifies shared code of a framebuffer resize event. + * @param[in] window The window that received the event. + * @param[in] width The new width, in pixels, of the framebuffer. + * @param[in] height The new height, in pixels, of the framebuffer. + * @ingroup event + */ +void _glfwInputFramebufferSize(_GLFWwindow* window, int width, int height); + +/*! @brief Notifies shared code of a window iconification event. + * @param[in] window The window that received the event. + * @param[in] iconified `GL_TRUE` if the window was iconified, or `GL_FALSE` + * if it was restored. + * @ingroup event + */ +void _glfwInputWindowIconify(_GLFWwindow* window, int iconified); + +/*! @brief Notifies shared code of a window damage event. + * @param[in] window The window that received the event. + */ +void _glfwInputWindowDamage(_GLFWwindow* window); + +/*! @brief Notifies shared code of a window close request event + * @param[in] window The window that received the event. + * @ingroup event + */ +void _glfwInputWindowCloseRequest(_GLFWwindow* window); + +/*! @brief Notifies shared code of a physical key event. + * @param[in] window The window that received the event. + * @param[in] key The key that was pressed or released. + * @param[in] scancode The system-specific scan code of the key. + * @param[in] action @ref GLFW_PRESS or @ref GLFW_RELEASE. + * @param[in] mods The modifiers pressed when the event was generated. + * @ingroup event + */ +void _glfwInputKey(_GLFWwindow* window, int key, int scancode, int action, int mods); + +/*! @brief Notifies shared code of a Unicode character input event. + * @param[in] window The window that received the event. + * @param[in] codepoint The Unicode code point of the input character. + * @param[in] mods Bit field describing which modifier keys were held down. + * @param[in] plain `GL_TRUE` if the character is regular text input, or + * `GL_FALSE` otherwise. + * @ingroup event + */ +void _glfwInputChar(_GLFWwindow* window, unsigned int codepoint, int mods, int plain); + +/*! @brief Notifies shared code of a scroll event. + * @param[in] window The window that received the event. + * @param[in] x The scroll offset along the x-axis. + * @param[in] y The scroll offset along the y-axis. + * @ingroup event + */ +void _glfwInputScroll(_GLFWwindow* window, double x, double y); + +/*! @brief Notifies shared code of a mouse button click event. + * @param[in] window The window that received the event. + * @param[in] button The button that was pressed or released. + * @param[in] action @ref GLFW_PRESS or @ref GLFW_RELEASE. + * @ingroup event + */ +void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods); + +/*! @brief Notifies shared code of a cursor motion event. + * @param[in] window The window that received the event. + * @param[in] x The new x-coordinate of the cursor, relative to the left edge + * of the client area of the window. + * @param[in] y The new y-coordinate of the cursor, relative to the top edge + * of the client area of the window. + * @ingroup event + */ +void _glfwInputCursorMotion(_GLFWwindow* window, double x, double y); + +/*! @brief Notifies shared code of a cursor enter/leave event. + * @param[in] window The window that received the event. + * @param[in] entered `GL_TRUE` if the cursor entered the client area of the + * window, or `GL_FALSE` if it left it. + * @ingroup event + */ +void _glfwInputCursorEnter(_GLFWwindow* window, int entered); + +/*! @ingroup event + */ +void _glfwInputMonitorChange(void); + +/*! @brief Notifies shared code of an error. + * @param[in] error The error code most suitable for the error. + * @param[in] format The `printf` style format string of the error + * description. + * @ingroup event + */ +void _glfwInputError(int error, const char* format, ...); + +/*! @brief Notifies dropped object over window. + * @param[in] window The window that received the event. + * @param[in] count The number of dropped objects. + * @param[in] names The names of the dropped objects. + * @ingroup event + */ +void _glfwInputDrop(_GLFWwindow* window, int count, const char** names); + + +//======================================================================== +// Utility functions +//======================================================================== + +/*! @ingroup utility + */ +const GLFWvidmode* _glfwChooseVideoMode(_GLFWmonitor* monitor, + const GLFWvidmode* desired); + +/*! @brief Performs lexical comparison between two @ref GLFWvidmode structures. + * @ingroup utility + */ +int _glfwCompareVideoModes(const GLFWvidmode* first, const GLFWvidmode* second); + +/*! @brief Splits a color depth into red, green and blue bit depths. + * @ingroup utility + */ +void _glfwSplitBPP(int bpp, int* red, int* green, int* blue); + +/*! @brief Searches an extension string for the specified extension. + * @param[in] string The extension string to search. + * @param[in] extensions The extension to search for. + * @return `GL_TRUE` if the extension was found, or `GL_FALSE` otherwise. + * @ingroup utility + */ +int _glfwStringInExtensionString(const char* string, const GLubyte* extensions); + +/*! @brief Chooses the framebuffer config that best matches the desired one. + * @param[in] desired The desired framebuffer config. + * @param[in] alternatives The framebuffer configs supported by the system. + * @param[in] count The number of entries in the alternatives array. + * @return The framebuffer config most closely matching the desired one, or @c + * NULL if none fulfilled the hard constraints of the desired values. + * @ingroup utility + */ +const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired, + const _GLFWfbconfig* alternatives, + unsigned int count); + +/*! @brief Retrieves the attributes of the current context. + * @param[in] ctxconfig The desired context attributes. + * @return `GL_TRUE` if successful, or `GL_FALSE` if the context is unusable. + * @ingroup utility + */ +GLboolean _glfwRefreshContextAttribs(const _GLFWctxconfig* ctxconfig); + +/*! @brief Checks whether the desired context attributes are valid. + * @param[in] ctxconfig The context attributes to check. + * @return `GL_TRUE` if the context attributes are valid, or `GL_FALSE` + * otherwise. + * @ingroup utility + * + * This function checks things like whether the specified client API version + * exists and whether all relevant options have supported and non-conflicting + * values. + */ +GLboolean _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig); + +/*! @brief Checks whether the current context fulfils the specified hard + * constraints. + * @param[in] ctxconfig The desired context attributes. + * @return `GL_TRUE` if the context fulfils the hard constraints, or `GL_FALSE` + * otherwise. + * @ingroup utility + */ +GLboolean _glfwIsValidContext(const _GLFWctxconfig* ctxconfig); + +/*! @ingroup utility + */ +void _glfwAllocGammaArrays(GLFWgammaramp* ramp, unsigned int size); + +/*! @ingroup utility + */ +void _glfwFreeGammaArrays(GLFWgammaramp* ramp); + +/*! @brief Allocates and returns a monitor object with the specified name + * and dimensions. + * @param[in] name The name of the monitor. + * @param[in] widthMM The width, in mm, of the monitor's display area. + * @param[in] heightMM The height, in mm, of the monitor's display area. + * @return The newly created object. + * @ingroup utility + */ +_GLFWmonitor* _glfwAllocMonitor(const char* name, int widthMM, int heightMM); + +/*! @brief Frees a monitor object and any data associated with it. + * @ingroup utility + */ +void _glfwFreeMonitor(_GLFWmonitor* monitor); + +/*! @ingroup utility + */ +void _glfwFreeMonitors(_GLFWmonitor** monitors, int count); + +#endif // _internal_h_ diff --git a/testbed/glfw/src/iokit_joystick.h b/testbed/glfw/src/iokit_joystick.h new file mode 100644 index 00000000..c08809f2 --- /dev/null +++ b/testbed/glfw/src/iokit_joystick.h @@ -0,0 +1,61 @@ +//======================================================================== +// GLFW 3.1 IOKit - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2006-2014 Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#ifndef _iokit_joystick_h_ +#define _iokit_joystick_h_ + +#include +#include +#include +#include + +#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE \ + _GLFWjoystickIOKit iokit_js[GLFW_JOYSTICK_LAST + 1] + + +// IOKit-specific per-joystick data +// +typedef struct _GLFWjoystickIOKit +{ + int present; + char name[256]; + + IOHIDDeviceInterface** interface; + + CFMutableArrayRef axisElements; + CFMutableArrayRef buttonElements; + CFMutableArrayRef hatElements; + + float* axes; + unsigned char* buttons; + +} _GLFWjoystickIOKit; + + +void _glfwInitJoysticks(void); +void _glfwTerminateJoysticks(void); + +#endif // _iokit_joystick_h_ diff --git a/testbed/glfw/src/iokit_joystick.m b/testbed/glfw/src/iokit_joystick.m new file mode 100644 index 00000000..5ff67dd8 --- /dev/null +++ b/testbed/glfw/src/iokit_joystick.m @@ -0,0 +1,506 @@ +//======================================================================== +// GLFW 3.1 IOKit - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2009-2010 Camilla Berglund +// Copyright (c) 2012 Torsten Walluhn +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include "internal.h" + +#include +#include + +#include +#include + +#include +#include + + +//------------------------------------------------------------------------ +// Joystick element information +//------------------------------------------------------------------------ +typedef struct +{ + IOHIDElementCookie cookie; + + long min; + long max; + + long minReport; + long maxReport; + +} _GLFWjoyelement; + + +static void getElementsCFArrayHandler(const void* value, void* parameter); + + +// Adds an element to the specified joystick +// +static void addJoystickElement(_GLFWjoystickIOKit* joystick, CFTypeRef elementRef) +{ + long elementType, usagePage, usage; + CFMutableArrayRef elementsArray = NULL; + + CFNumberGetValue(CFDictionaryGetValue(elementRef, CFSTR(kIOHIDElementTypeKey)), + kCFNumberLongType, &elementType); + CFNumberGetValue(CFDictionaryGetValue(elementRef, CFSTR(kIOHIDElementUsagePageKey)), + kCFNumberLongType, &usagePage); + CFNumberGetValue(CFDictionaryGetValue(elementRef, CFSTR(kIOHIDElementUsageKey)), + kCFNumberLongType, &usage); + + if ((elementType == kIOHIDElementTypeInput_Axis) || + (elementType == kIOHIDElementTypeInput_Button) || + (elementType == kIOHIDElementTypeInput_Misc)) + { + switch (usagePage) + { + case kHIDPage_GenericDesktop: + { + switch (usage) + { + case kHIDUsage_GD_X: + case kHIDUsage_GD_Y: + case kHIDUsage_GD_Z: + case kHIDUsage_GD_Rx: + case kHIDUsage_GD_Ry: + case kHIDUsage_GD_Rz: + case kHIDUsage_GD_Slider: + case kHIDUsage_GD_Dial: + case kHIDUsage_GD_Wheel: + elementsArray = joystick->axisElements; + break; + case kHIDUsage_GD_Hatswitch: + elementsArray = joystick->hatElements; + break; + } + + break; + } + + case kHIDPage_Button: + elementsArray = joystick->buttonElements; + break; + default: + break; + } + + if (elementsArray) + { + long number; + CFTypeRef numberRef; + _GLFWjoyelement* element = calloc(1, sizeof(_GLFWjoyelement)); + + CFArrayAppendValue(elementsArray, element); + + numberRef = CFDictionaryGetValue(elementRef, CFSTR(kIOHIDElementCookieKey)); + if (numberRef && CFNumberGetValue(numberRef, kCFNumberLongType, &number)) + element->cookie = (IOHIDElementCookie) number; + + numberRef = CFDictionaryGetValue(elementRef, CFSTR(kIOHIDElementMinKey)); + if (numberRef && CFNumberGetValue(numberRef, kCFNumberLongType, &number)) + element->minReport = element->min = number; + + numberRef = CFDictionaryGetValue(elementRef, CFSTR(kIOHIDElementMaxKey)); + if (numberRef && CFNumberGetValue(numberRef, kCFNumberLongType, &number)) + element->maxReport = element->max = number; + } + } + else + { + CFTypeRef array = CFDictionaryGetValue(elementRef, CFSTR(kIOHIDElementKey)); + if (array) + { + if (CFGetTypeID(array) == CFArrayGetTypeID()) + { + CFRange range = { 0, CFArrayGetCount(array) }; + CFArrayApplyFunction(array, range, getElementsCFArrayHandler, joystick); + } + } + } +} + +// Adds an element to the specified joystick +// +static void getElementsCFArrayHandler(const void* value, void* parameter) +{ + if (CFGetTypeID(value) == CFDictionaryGetTypeID()) + addJoystickElement((_GLFWjoystickIOKit*) parameter, (CFTypeRef) value); +} + +// Returns the value of the specified element of the specified joystick +// +static long getElementValue(_GLFWjoystickIOKit* joystick, _GLFWjoyelement* element) +{ + IOReturn result = kIOReturnSuccess; + IOHIDEventStruct hidEvent; + hidEvent.value = 0; + + if (joystick && element && joystick->interface) + { + result = (*(joystick->interface))->getElementValue(joystick->interface, + element->cookie, + &hidEvent); + if (kIOReturnSuccess == result) + { + // Record min and max for auto calibration + if (hidEvent.value < element->minReport) + element->minReport = hidEvent.value; + if (hidEvent.value > element->maxReport) + element->maxReport = hidEvent.value; + } + } + + // Auto user scale + return (long) hidEvent.value; +} + +// Removes the specified joystick +// +static void removeJoystick(_GLFWjoystickIOKit* joystick) +{ + int i; + + if (!joystick->present) + return; + + for (i = 0; i < CFArrayGetCount(joystick->axisElements); i++) + free((void*) CFArrayGetValueAtIndex(joystick->axisElements, i)); + CFArrayRemoveAllValues(joystick->axisElements); + + for (i = 0; i < CFArrayGetCount(joystick->buttonElements); i++) + free((void*) CFArrayGetValueAtIndex(joystick->buttonElements, i)); + CFArrayRemoveAllValues(joystick->buttonElements); + + for (i = 0; i < CFArrayGetCount(joystick->hatElements); i++) + free((void*) CFArrayGetValueAtIndex(joystick->hatElements, i)); + CFArrayRemoveAllValues(joystick->hatElements); + + free(joystick->axes); + free(joystick->buttons); + + (*(joystick->interface))->close(joystick->interface); + (*(joystick->interface))->Release(joystick->interface); + + memset(joystick, 0, sizeof(_GLFWjoystickIOKit)); +} + +// Callback for user-initiated joystick removal +// +static void removalCallback(void* target, IOReturn result, void* refcon, void* sender) +{ + removeJoystick((_GLFWjoystickIOKit*) refcon); +} + +// Polls for joystick events and updates GLFW state +// +static void pollJoystickEvents(void) +{ + int joy; + + for (joy = 0; joy <= GLFW_JOYSTICK_LAST; joy++) + { + CFIndex i; + int buttonIndex = 0; + _GLFWjoystickIOKit* joystick = _glfw.iokit_js + joy; + + if (!joystick->present) + continue; + + for (i = 0; i < CFArrayGetCount(joystick->buttonElements); i++) + { + _GLFWjoyelement* button = + (_GLFWjoyelement*) CFArrayGetValueAtIndex(joystick->buttonElements, i); + + if (getElementValue(joystick, button)) + joystick->buttons[buttonIndex++] = GLFW_PRESS; + else + joystick->buttons[buttonIndex++] = GLFW_RELEASE; + } + + for (i = 0; i < CFArrayGetCount(joystick->axisElements); i++) + { + _GLFWjoyelement* axis = + (_GLFWjoyelement*) CFArrayGetValueAtIndex(joystick->axisElements, i); + + long value = getElementValue(joystick, axis); + long readScale = axis->maxReport - axis->minReport; + + if (readScale == 0) + joystick->axes[i] = value; + else + joystick->axes[i] = (2.f * (value - axis->minReport) / readScale) - 1.f; + } + + for (i = 0; i < CFArrayGetCount(joystick->hatElements); i++) + { + _GLFWjoyelement* hat = + (_GLFWjoyelement*) CFArrayGetValueAtIndex(joystick->hatElements, i); + + // Bit fields of button presses for each direction, including nil + const int directions[9] = { 1, 3, 2, 6, 4, 12, 8, 9, 0 }; + + long j, value = getElementValue(joystick, hat); + if (value < 0 || value > 8) + value = 8; + + for (j = 0; j < 4; j++) + { + if (directions[value] & (1 << j)) + joystick->buttons[buttonIndex++] = GLFW_PRESS; + else + joystick->buttons[buttonIndex++] = GLFW_RELEASE; + } + } + } +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +// Initialize joystick interface +// +void _glfwInitJoysticks(void) +{ + int joy = 0; + IOReturn result = kIOReturnSuccess; + mach_port_t masterPort = 0; + io_iterator_t objectIterator = 0; + CFMutableDictionaryRef hidMatchDictionary = NULL; + io_object_t ioHIDDeviceObject = 0; + + result = IOMasterPort(bootstrap_port, &masterPort); + hidMatchDictionary = IOServiceMatching(kIOHIDDeviceKey); + if (kIOReturnSuccess != result || !hidMatchDictionary) + { + if (hidMatchDictionary) + CFRelease(hidMatchDictionary); + + return; + } + + result = IOServiceGetMatchingServices(masterPort, + hidMatchDictionary, + &objectIterator); + if (result != kIOReturnSuccess) + return; + + if (!objectIterator) + { + // There are no joysticks + return; + } + + while ((ioHIDDeviceObject = IOIteratorNext(objectIterator))) + { + CFMutableDictionaryRef propsRef = NULL; + CFTypeRef valueRef = NULL; + kern_return_t result; + + IOCFPlugInInterface** ppPlugInInterface = NULL; + HRESULT plugInResult = S_OK; + SInt32 score = 0; + + long usagePage = 0; + long usage = 0; + + valueRef = IORegistryEntryCreateCFProperty(ioHIDDeviceObject, + CFSTR(kIOHIDPrimaryUsagePageKey), + kCFAllocatorDefault, kNilOptions); + if (valueRef) + { + CFNumberGetValue(valueRef, kCFNumberLongType, &usagePage); + CFRelease(valueRef); + } + + valueRef = IORegistryEntryCreateCFProperty(ioHIDDeviceObject, + CFSTR(kIOHIDPrimaryUsageKey), + kCFAllocatorDefault, kNilOptions); + if (valueRef) + { + CFNumberGetValue(valueRef, kCFNumberLongType, &usage); + CFRelease(valueRef); + } + + if (usagePage != kHIDPage_GenericDesktop) + { + // This device is not relevant to GLFW + continue; + } + + if ((usage != kHIDUsage_GD_Joystick && + usage != kHIDUsage_GD_GamePad && + usage != kHIDUsage_GD_MultiAxisController)) + { + // This device is not relevant to GLFW + continue; + } + + result = IORegistryEntryCreateCFProperties(ioHIDDeviceObject, + &propsRef, + kCFAllocatorDefault, + kNilOptions); + + if (result != kIOReturnSuccess) + continue; + + _GLFWjoystickIOKit* joystick = _glfw.iokit_js + joy; + joystick->present = GL_TRUE; + + result = IOCreatePlugInInterfaceForService(ioHIDDeviceObject, + kIOHIDDeviceUserClientTypeID, + kIOCFPlugInInterfaceID, + &ppPlugInInterface, + &score); + + if (kIOReturnSuccess != result) + { + CFRelease(propsRef); + return; + } + + plugInResult = (*ppPlugInInterface)->QueryInterface( + ppPlugInInterface, + CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID), + (void *) &(joystick->interface)); + + if (plugInResult != S_OK) + { + CFRelease(propsRef); + return; + } + + (*ppPlugInInterface)->Release(ppPlugInInterface); + + (*(joystick->interface))->open(joystick->interface, 0); + (*(joystick->interface))->setRemovalCallback(joystick->interface, + removalCallback, + joystick, + joystick); + + // Get product string + valueRef = CFDictionaryGetValue(propsRef, CFSTR(kIOHIDProductKey)); + if (valueRef) + { + CFStringGetCString(valueRef, + joystick->name, + sizeof(joystick->name), + kCFStringEncodingUTF8); + } + + joystick->axisElements = CFArrayCreateMutable(NULL, 0, NULL); + joystick->buttonElements = CFArrayCreateMutable(NULL, 0, NULL); + joystick->hatElements = CFArrayCreateMutable(NULL, 0, NULL); + + valueRef = CFDictionaryGetValue(propsRef, CFSTR(kIOHIDElementKey)); + if (CFGetTypeID(valueRef) == CFArrayGetTypeID()) + { + CFRange range = { 0, CFArrayGetCount(valueRef) }; + CFArrayApplyFunction(valueRef, + range, + getElementsCFArrayHandler, + (void*) joystick); + } + + CFRelease(propsRef); + + joystick->axes = calloc(CFArrayGetCount(joystick->axisElements), + sizeof(float)); + joystick->buttons = calloc(CFArrayGetCount(joystick->buttonElements) + + CFArrayGetCount(joystick->hatElements) * 4, 1); + + joy++; + if (joy > GLFW_JOYSTICK_LAST) + break; + } +} + +// Close all opened joystick handles +// +void _glfwTerminateJoysticks(void) +{ + int i; + + for (i = 0; i < GLFW_JOYSTICK_LAST + 1; i++) + { + _GLFWjoystickIOKit* joystick = &_glfw.iokit_js[i]; + removeJoystick(joystick); + + if (joystick->axisElements) + CFRelease(joystick->axisElements); + if (joystick->buttonElements) + CFRelease(joystick->buttonElements); + if (joystick->hatElements) + CFRelease(joystick->hatElements); + } +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +int _glfwPlatformJoystickPresent(int joy) +{ + pollJoystickEvents(); + + return _glfw.iokit_js[joy].present; +} + +const float* _glfwPlatformGetJoystickAxes(int joy, int* count) +{ + _GLFWjoystickIOKit* joystick = _glfw.iokit_js + joy; + + pollJoystickEvents(); + + if (!joystick->present) + return NULL; + + *count = (int) CFArrayGetCount(joystick->axisElements); + return joystick->axes; +} + +const unsigned char* _glfwPlatformGetJoystickButtons(int joy, int* count) +{ + _GLFWjoystickIOKit* joystick = _glfw.iokit_js + joy; + + pollJoystickEvents(); + + if (!joystick->present) + return NULL; + + *count = (int) CFArrayGetCount(joystick->buttonElements) + + (int) CFArrayGetCount(joystick->hatElements) * 4; + return joystick->buttons; +} + +const char* _glfwPlatformGetJoystickName(int joy) +{ + pollJoystickEvents(); + + return _glfw.iokit_js[joy].name; +} + diff --git a/testbed/glfw/src/linux_joystick.c b/testbed/glfw/src/linux_joystick.c new file mode 100644 index 00000000..5f46519b --- /dev/null +++ b/testbed/glfw/src/linux_joystick.c @@ -0,0 +1,322 @@ +//======================================================================== +// GLFW 3.1 Linux - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2010 Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include "internal.h" + +#if defined(__linux__) +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif // __linux__ + + +// Attempt to open the specified joystick device +// +static void openJoystickDevice(const char* path) +{ +#if defined(__linux__) + char axisCount, buttonCount; + char name[256]; + int joy, fd, version; + + for (joy = GLFW_JOYSTICK_1; joy <= GLFW_JOYSTICK_LAST; joy++) + { + if (!_glfw.linux_js.js[joy].present) + continue; + + if (strcmp(_glfw.linux_js.js[joy].path, path) == 0) + return; + } + + for (joy = GLFW_JOYSTICK_1; joy <= GLFW_JOYSTICK_LAST; joy++) + { + if (!_glfw.linux_js.js[joy].present) + break; + } + + if (joy > GLFW_JOYSTICK_LAST) + return; + + fd = open(path, O_RDONLY | O_NONBLOCK); + if (fd == -1) + return; + + _glfw.linux_js.js[joy].fd = fd; + + // Verify that the joystick driver version is at least 1.0 + ioctl(fd, JSIOCGVERSION, &version); + if (version < 0x010000) + { + // It's an old 0.x interface (we don't support it) + close(fd); + return; + } + + if (ioctl(fd, JSIOCGNAME(sizeof(name)), name) < 0) + strncpy(name, "Unknown", sizeof(name)); + + _glfw.linux_js.js[joy].name = strdup(name); + _glfw.linux_js.js[joy].path = strdup(path); + + ioctl(fd, JSIOCGAXES, &axisCount); + _glfw.linux_js.js[joy].axisCount = (int) axisCount; + + ioctl(fd, JSIOCGBUTTONS, &buttonCount); + _glfw.linux_js.js[joy].buttonCount = (int) buttonCount; + + _glfw.linux_js.js[joy].axes = calloc(axisCount, sizeof(float)); + _glfw.linux_js.js[joy].buttons = calloc(buttonCount, 1); + + _glfw.linux_js.js[joy].present = GL_TRUE; +#endif // __linux__ +} + +// Polls for and processes events for all present joysticks +// +static void pollJoystickEvents(void) +{ +#if defined(__linux__) + int i; + struct js_event e; + ssize_t offset = 0; + char buffer[16384]; + + const ssize_t size = read(_glfw.linux_js.inotify, buffer, sizeof(buffer)); + + while (size > offset) + { + regmatch_t match; + const struct inotify_event* e = (struct inotify_event*) (buffer + offset); + + if (regexec(&_glfw.linux_js.regex, e->name, 1, &match, 0) == 0) + { + char path[20]; + snprintf(path, sizeof(path), "/dev/input/%s", e->name); + openJoystickDevice(path); + } + + offset += sizeof(struct inotify_event) + e->len; + } + + for (i = 0; i <= GLFW_JOYSTICK_LAST; i++) + { + if (!_glfw.linux_js.js[i].present) + continue; + + // Read all queued events (non-blocking) + for (;;) + { + errno = 0; + if (read(_glfw.linux_js.js[i].fd, &e, sizeof(e)) < 0) + { + if (errno == ENODEV) + { + // The joystick was disconnected + + free(_glfw.linux_js.js[i].axes); + free(_glfw.linux_js.js[i].buttons); + free(_glfw.linux_js.js[i].name); + free(_glfw.linux_js.js[i].path); + + memset(&_glfw.linux_js.js[i], 0, sizeof(_glfw.linux_js.js[i])); + } + + break; + } + + // We don't care if it's an init event or not + e.type &= ~JS_EVENT_INIT; + + switch (e.type) + { + case JS_EVENT_AXIS: + _glfw.linux_js.js[i].axes[e.number] = + (float) e.value / 32767.0f; + break; + + case JS_EVENT_BUTTON: + _glfw.linux_js.js[i].buttons[e.number] = + e.value ? GLFW_PRESS : GLFW_RELEASE; + break; + + default: + break; + } + } + } +#endif // __linux__ +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +// Initialize joystick interface +// +int _glfwInitJoysticks(void) +{ +#if defined(__linux__) + const char* dirname = "/dev/input"; + DIR* dir; + + _glfw.linux_js.inotify = inotify_init1(IN_NONBLOCK | IN_CLOEXEC); + if (_glfw.linux_js.inotify == -1) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Linux: Failed to initialize inotify: %s", + strerror(errno)); + return GL_FALSE; + } + + // HACK: Register for IN_ATTRIB as well to get notified when udev is done + // This works well in practice but the true way is libudev + + _glfw.linux_js.watch = inotify_add_watch(_glfw.linux_js.inotify, + dirname, + IN_CREATE | IN_ATTRIB); + if (_glfw.linux_js.watch == -1) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Linux: Failed to watch for joystick connections in %s: %s", + dirname, + strerror(errno)); + // Continue without device connection notifications + } + + if (regcomp(&_glfw.linux_js.regex, "^js[0-9]\\+$", 0) != 0) + { + _glfwInputError(GLFW_PLATFORM_ERROR, "Linux: Failed to compile regex"); + return GL_FALSE; + } + + dir = opendir(dirname); + if (dir) + { + struct dirent* entry; + + while ((entry = readdir(dir))) + { + char path[20]; + regmatch_t match; + + if (regexec(&_glfw.linux_js.regex, entry->d_name, 1, &match, 0) != 0) + continue; + + snprintf(path, sizeof(path), "%s/%s", dirname, entry->d_name); + openJoystickDevice(path); + } + + closedir(dir); + } + else + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Linux: Failed to open joystick device directory %s: %s", + dirname, + strerror(errno)); + // Continue with no joysticks detected + } + +#endif // __linux__ + + return GL_TRUE; +} + +// Close all opened joystick handles +// +void _glfwTerminateJoysticks(void) +{ +#if defined(__linux__) + int i; + + for (i = 0; i <= GLFW_JOYSTICK_LAST; i++) + { + if (_glfw.linux_js.js[i].present) + { + close(_glfw.linux_js.js[i].fd); + free(_glfw.linux_js.js[i].axes); + free(_glfw.linux_js.js[i].buttons); + free(_glfw.linux_js.js[i].name); + free(_glfw.linux_js.js[i].path); + } + } + + regfree(&_glfw.linux_js.regex); + + if (_glfw.linux_js.watch > 0) + close(_glfw.linux_js.watch); + + if (_glfw.linux_js.inotify > 0) + close(_glfw.linux_js.inotify); +#endif // __linux__ +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +int _glfwPlatformJoystickPresent(int joy) +{ + pollJoystickEvents(); + + return _glfw.linux_js.js[joy].present; +} + +const float* _glfwPlatformGetJoystickAxes(int joy, int* count) +{ + pollJoystickEvents(); + + *count = _glfw.linux_js.js[joy].axisCount; + return _glfw.linux_js.js[joy].axes; +} + +const unsigned char* _glfwPlatformGetJoystickButtons(int joy, int* count) +{ + pollJoystickEvents(); + + *count = _glfw.linux_js.js[joy].buttonCount; + return _glfw.linux_js.js[joy].buttons; +} + +const char* _glfwPlatformGetJoystickName(int joy) +{ + pollJoystickEvents(); + + return _glfw.linux_js.js[joy].name; +} + diff --git a/testbed/glfw/src/linux_joystick.h b/testbed/glfw/src/linux_joystick.h new file mode 100644 index 00000000..163b07c5 --- /dev/null +++ b/testbed/glfw/src/linux_joystick.h @@ -0,0 +1,63 @@ +//======================================================================== +// GLFW 3.1 Linux - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2014 Jonas Ådahl +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#ifndef _linux_joystick_h_ +#define _linux_joystick_h_ + +#include + +#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE \ + _GLFWjoystickLinux linux_js + + +// Linux-specific joystick API data +// +typedef struct _GLFWjoystickLinux +{ + struct + { + int present; + int fd; + float* axes; + int axisCount; + unsigned char* buttons; + int buttonCount; + char* name; + char* path; + } js[GLFW_JOYSTICK_LAST + 1]; + +#if defined(__linux__) + int inotify; + int watch; + regex_t regex; +#endif /*__linux__*/ +} _GLFWjoystickLinux; + + +int _glfwInitJoysticks(void); +void _glfwTerminateJoysticks(void); + +#endif // _linux_joystick_h_ diff --git a/testbed/glfw/src/mach_time.c b/testbed/glfw/src/mach_time.c new file mode 100644 index 00000000..59916bb4 --- /dev/null +++ b/testbed/glfw/src/mach_time.c @@ -0,0 +1,71 @@ +//======================================================================== +// GLFW 3.1 OS X - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2009-2010 Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include "internal.h" + +#include + + +// Return raw time +// +static uint64_t getRawTime(void) +{ + return mach_absolute_time(); +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +// Initialise timer +// +void _glfwInitTimer(void) +{ + mach_timebase_info_data_t info; + mach_timebase_info(&info); + + _glfw.ns_time.resolution = (double) info.numer / (info.denom * 1.0e9); + _glfw.ns_time.base = getRawTime(); +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +double _glfwPlatformGetTime(void) +{ + return (double) (getRawTime() - _glfw.ns_time.base) * + _glfw.ns_time.resolution; +} + +void _glfwPlatformSetTime(double time) +{ + _glfw.ns_time.base = getRawTime() - + (uint64_t) (time / _glfw.ns_time.resolution); +} + diff --git a/testbed/glfw/src/mir_init.c b/testbed/glfw/src/mir_init.c new file mode 100644 index 00000000..a3c8de9f --- /dev/null +++ b/testbed/glfw/src/mir_init.c @@ -0,0 +1,101 @@ +//======================================================================== +// GLFW 3.1 Mir - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2014 Brandon Schaefer +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include "internal.h" + +#include +#include + + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +int _glfwPlatformInit(void) +{ + int error; + + _glfw.mir.connection = mir_connect_sync(NULL, __PRETTY_FUNCTION__); + + if (!mir_connection_is_valid(_glfw.mir.connection)) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Mir: Unable to connect to server: %s", + mir_connection_get_error_message(_glfw.mir.connection)); + + return GL_FALSE; + } + + _glfw.mir.display = + mir_connection_get_egl_native_display(_glfw.mir.connection); + + if (!_glfwInitContextAPI()) + return GL_FALSE; + + _glfwInitTimer(); + _glfwInitJoysticks(); + + _glfw.mir.event_queue = calloc(1, sizeof(EventQueue)); + _glfwInitEventQueue(_glfw.mir.event_queue); + + error = pthread_mutex_init(&_glfw.mir.event_mutex, NULL); + if (error) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Mir: Failed to create event mutex: %s\n", + strerror(error)); + return GL_FALSE; + } + + return GL_TRUE; +} + +void _glfwPlatformTerminate(void) +{ + _glfwTerminateContextAPI(); + _glfwTerminateJoysticks(); + + _glfwDeleteEventQueue(_glfw.mir.event_queue); + + pthread_mutex_destroy(&_glfw.mir.event_mutex); + + mir_connection_release(_glfw.mir.connection); +} + +const char* _glfwPlatformGetVersionString(void) +{ + const char* version = _GLFW_VERSION_NUMBER " Mir EGL" +#if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK) + " clock_gettime" +#endif +#if defined(_GLFW_BUILD_DLL) + " shared" +#endif + ; + + return version; +} + diff --git a/testbed/glfw/src/mir_monitor.c b/testbed/glfw/src/mir_monitor.c new file mode 100644 index 00000000..9776b10e --- /dev/null +++ b/testbed/glfw/src/mir_monitor.c @@ -0,0 +1,138 @@ +//======================================================================== +// GLFW 3.1 Mir - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2014 Brandon Schaefer +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include "internal.h" + +#include + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +_GLFWmonitor** _glfwPlatformGetMonitors(int* count) +{ + int i, found = 0; + _GLFWmonitor** monitors = NULL; + MirDisplayConfiguration* displayConfig = + mir_connection_create_display_config(_glfw.mir.connection); + + *count = 0; + + for (i = 0; i < displayConfig->num_outputs; i++) + { + const MirDisplayOutput* out = displayConfig->outputs + i; + + if (out->used && + out->connected && + out->num_modes && + out->current_mode < out->num_modes) + { + found++; + monitors = realloc(monitors, sizeof(_GLFWmonitor*) * found); + monitors[i] = _glfwAllocMonitor("Unknown", + out->physical_width_mm, + out->physical_height_mm); + + monitors[i]->mir.x = out->position_x; + monitors[i]->mir.y = out->position_y; + monitors[i]->mir.output_id = out->output_id; + monitors[i]->mir.cur_mode = out->current_mode; + + monitors[i]->modes = _glfwPlatformGetVideoModes(monitors[i], + &monitors[i]->modeCount); + } + } + + mir_display_config_destroy(displayConfig); + + *count = found; + return monitors; +} + +GLboolean _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second) +{ + return first->mir.output_id == second->mir.output_id; +} + +void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos) +{ + if (xpos) + *xpos = monitor->mir.x; + if (ypos) + *ypos = monitor->mir.y; +} + +GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found) +{ + int i; + GLFWvidmode* modes = NULL; + MirDisplayConfiguration* displayConfig = + mir_connection_create_display_config(_glfw.mir.connection); + + for (i = 0; i < displayConfig->num_outputs; i++) + { + const MirDisplayOutput* out = displayConfig->outputs + i; + if (out->output_id != monitor->mir.output_id) + continue; + + modes = calloc(out->num_modes, sizeof(GLFWvidmode)); + + for (*found = 0; *found < out->num_modes; (*found)++) + { + modes[*found].width = out->modes[*found].horizontal_resolution; + modes[*found].height = out->modes[*found].vertical_resolution; + modes[*found].refreshRate = out->modes[*found].refresh_rate; + modes[*found].redBits = 8; + modes[*found].greenBits = 8; + modes[*found].blueBits = 8; + } + + break; + } + + mir_display_config_destroy(displayConfig); + + return modes; +} + +void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) +{ + *mode = monitor->modes[monitor->mir.cur_mode]; +} + +void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) +{ + _glfwInputError(GLFW_PLATFORM_ERROR, + "Mir: Unsupported function %s!", __PRETTY_FUNCTION__); +} + +void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) +{ + _glfwInputError(GLFW_PLATFORM_ERROR, + "Mir: Unsupported function %s!", __PRETTY_FUNCTION__); +} + diff --git a/testbed/glfw/src/mir_platform.h b/testbed/glfw/src/mir_platform.h new file mode 100644 index 00000000..76399c2a --- /dev/null +++ b/testbed/glfw/src/mir_platform.h @@ -0,0 +1,110 @@ +//======================================================================== +// GLFW 3.1 Mir - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2014 Brandon Schaefer +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#ifndef _mir_platform_h_ +#define _mir_platform_h_ + +#include + +#include "posix_tls.h" +#include "posix_time.h" +#include "linux_joystick.h" + +#include + +#include + +#if defined(_GLFW_EGL) + #include "egl_context.h" +#else + #error "The Mir backend depends on EGL platform support" +#endif + +#define _GLFW_EGL_NATIVE_WINDOW window->mir.window +#define _GLFW_EGL_NATIVE_DISPLAY _glfw.mir.display + +#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowMir mir +#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorMir mir +#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryMir mir +#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorMir mir + +// Mir-specific Event Queue +// +typedef struct EventQueue +{ + TAILQ_HEAD(, EventNode) head; +} EventQueue; + +// Mir-specific per-window data +// +typedef struct _GLFWwindowMir +{ + MirSurface* surface; + int width; + int height; + MirEGLNativeWindowType window; + +} _GLFWwindowMir; + + +// Mir-specific per-monitor data +// +typedef struct _GLFWmonitorMir +{ + int cur_mode; + int output_id; + int x; + int y; + +} _GLFWmonitorMir; + + +// Mir-specific global data +// +typedef struct _GLFWlibraryMir +{ + MirConnection* connection; + MirEGLNativeDisplayType display; + EventQueue* event_queue; + + pthread_mutex_t event_mutex; + pthread_cond_t event_cond; + +} _GLFWlibraryMir; + + +// Mir-specific per-cursor data +// TODO: Only system cursors are implemented in Mir atm. Need to wait for support. +// +typedef struct _GLFWcursorMir +{ +} _GLFWcursorMir; + + +extern void _glfwInitEventQueue(EventQueue* queue); +extern void _glfwDeleteEventQueue(EventQueue* queue); + +#endif // _mir_platform_h_ diff --git a/testbed/glfw/src/mir_window.c b/testbed/glfw/src/mir_window.c new file mode 100644 index 00000000..f2890cbd --- /dev/null +++ b/testbed/glfw/src/mir_window.c @@ -0,0 +1,687 @@ +//======================================================================== +// GLFW 3.1 Mir - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2014 Brandon Schaefer +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include "internal.h" +#include "xkb_unicode.h" + +#include +#include +#include + + +typedef struct EventNode +{ + TAILQ_ENTRY(EventNode) entries; + MirEvent* event; + _GLFWwindow* window; +} EventNode; + +static void deleteNode(EventQueue* queue, EventNode* node) +{ + free(node->event); + free(node); +} + +static int emptyEventQueue(EventQueue* queue) +{ + return queue->head.tqh_first == NULL ? GL_TRUE : GL_FALSE; +} + +static EventNode* newEventNode(MirEvent const* event, _GLFWwindow* context) +{ + EventNode* new_node = calloc(1, sizeof(EventNode)); + new_node->event = calloc(1, sizeof(MirEvent)); + new_node->window = context; + + memcpy(new_node->event, event, sizeof(MirEvent)); + return new_node; +} + +static void enqueueEvent(MirEvent const* event, _GLFWwindow* context) +{ + pthread_mutex_lock(&_glfw.mir.event_mutex); + + EventNode* new_node = newEventNode(event, context); + TAILQ_INSERT_TAIL(&_glfw.mir.event_queue->head, new_node, entries); + + pthread_cond_signal(&_glfw.mir.event_cond); + + pthread_mutex_unlock(&_glfw.mir.event_mutex); +} + +static EventNode* dequeueEvent(EventQueue* queue) +{ + EventNode* node = NULL; + + pthread_mutex_lock(&_glfw.mir.event_mutex); + + node = queue->head.tqh_first; + + if (node) + TAILQ_REMOVE(&queue->head, node, entries); + + pthread_mutex_unlock(&_glfw.mir.event_mutex); + + return node; +} + +static MirPixelFormat findValidPixelFormat(void) +{ + unsigned int i, validFormats, mirPixelFormats = 32; + MirPixelFormat formats[mir_pixel_formats]; + + mir_connection_get_available_surface_formats(_glfw.mir.connection, formats, + mirPixelFormats, &validFormats); + + for (i = 0; i < validFormats; i++) + { + if (formats[i] == mir_pixel_format_abgr_8888 || + formats[i] == mir_pixel_format_xbgr_8888 || + formats[i] == mir_pixel_format_argb_8888 || + formats[i] == mir_pixel_format_xrgb_8888) + { + return formats[i]; + } + } + + return mir_pixel_format_invalid; +} + +static int mirModToGLFWMod(uint32_t mods) +{ + int publicMods = 0x0; + + if (mods & mir_key_modifier_alt) + publicMods |= GLFW_MOD_ALT; + else if (mods & mir_key_modifier_shift) + publicMods |= GLFW_MOD_SHIFT; + else if (mods & mir_key_modifier_ctrl) + publicMods |= GLFW_MOD_CONTROL; + else if (mods & mir_key_modifier_meta) + publicMods |= GLFW_MOD_SUPER; + + return publicMods; +} + +// Taken from wl_init.c +static int toGLFWKeyCode(uint32_t key) +{ + switch (key) + { + case KEY_GRAVE: return GLFW_KEY_GRAVE_ACCENT; + case KEY_1: return GLFW_KEY_1; + case KEY_2: return GLFW_KEY_2; + case KEY_3: return GLFW_KEY_3; + case KEY_4: return GLFW_KEY_4; + case KEY_5: return GLFW_KEY_5; + case KEY_6: return GLFW_KEY_6; + case KEY_7: return GLFW_KEY_7; + case KEY_8: return GLFW_KEY_8; + case KEY_9: return GLFW_KEY_9; + case KEY_0: return GLFW_KEY_0; + case KEY_MINUS: return GLFW_KEY_MINUS; + case KEY_EQUAL: return GLFW_KEY_EQUAL; + case KEY_Q: return GLFW_KEY_Q; + case KEY_W: return GLFW_KEY_W; + case KEY_E: return GLFW_KEY_E; + case KEY_R: return GLFW_KEY_R; + case KEY_T: return GLFW_KEY_T; + case KEY_Y: return GLFW_KEY_Y; + case KEY_U: return GLFW_KEY_U; + case KEY_I: return GLFW_KEY_I; + case KEY_O: return GLFW_KEY_O; + case KEY_P: return GLFW_KEY_P; + case KEY_LEFTBRACE: return GLFW_KEY_LEFT_BRACKET; + case KEY_RIGHTBRACE: return GLFW_KEY_RIGHT_BRACKET; + case KEY_A: return GLFW_KEY_A; + case KEY_S: return GLFW_KEY_S; + case KEY_D: return GLFW_KEY_D; + case KEY_F: return GLFW_KEY_F; + case KEY_G: return GLFW_KEY_G; + case KEY_H: return GLFW_KEY_H; + case KEY_J: return GLFW_KEY_J; + case KEY_K: return GLFW_KEY_K; + case KEY_L: return GLFW_KEY_L; + case KEY_SEMICOLON: return GLFW_KEY_SEMICOLON; + case KEY_APOSTROPHE: return GLFW_KEY_APOSTROPHE; + case KEY_Z: return GLFW_KEY_Z; + case KEY_X: return GLFW_KEY_X; + case KEY_C: return GLFW_KEY_C; + case KEY_V: return GLFW_KEY_V; + case KEY_B: return GLFW_KEY_B; + case KEY_N: return GLFW_KEY_N; + case KEY_M: return GLFW_KEY_M; + case KEY_COMMA: return GLFW_KEY_COMMA; + case KEY_DOT: return GLFW_KEY_PERIOD; + case KEY_SLASH: return GLFW_KEY_SLASH; + case KEY_BACKSLASH: return GLFW_KEY_BACKSLASH; + case KEY_ESC: return GLFW_KEY_ESCAPE; + case KEY_TAB: return GLFW_KEY_TAB; + case KEY_LEFTSHIFT: return GLFW_KEY_LEFT_SHIFT; + case KEY_RIGHTSHIFT: return GLFW_KEY_RIGHT_SHIFT; + case KEY_LEFTCTRL: return GLFW_KEY_LEFT_CONTROL; + case KEY_RIGHTCTRL: return GLFW_KEY_RIGHT_CONTROL; + case KEY_LEFTALT: return GLFW_KEY_LEFT_ALT; + case KEY_RIGHTALT: return GLFW_KEY_RIGHT_ALT; + case KEY_LEFTMETA: return GLFW_KEY_LEFT_SUPER; + case KEY_RIGHTMETA: return GLFW_KEY_RIGHT_SUPER; + case KEY_MENU: return GLFW_KEY_MENU; + case KEY_NUMLOCK: return GLFW_KEY_NUM_LOCK; + case KEY_CAPSLOCK: return GLFW_KEY_CAPS_LOCK; + case KEY_PRINT: return GLFW_KEY_PRINT_SCREEN; + case KEY_SCROLLLOCK: return GLFW_KEY_SCROLL_LOCK; + case KEY_PAUSE: return GLFW_KEY_PAUSE; + case KEY_DELETE: return GLFW_KEY_DELETE; + case KEY_BACKSPACE: return GLFW_KEY_BACKSPACE; + case KEY_ENTER: return GLFW_KEY_ENTER; + case KEY_HOME: return GLFW_KEY_HOME; + case KEY_END: return GLFW_KEY_END; + case KEY_PAGEUP: return GLFW_KEY_PAGE_UP; + case KEY_PAGEDOWN: return GLFW_KEY_PAGE_DOWN; + case KEY_INSERT: return GLFW_KEY_INSERT; + case KEY_LEFT: return GLFW_KEY_LEFT; + case KEY_RIGHT: return GLFW_KEY_RIGHT; + case KEY_DOWN: return GLFW_KEY_DOWN; + case KEY_UP: return GLFW_KEY_UP; + case KEY_F1: return GLFW_KEY_F1; + case KEY_F2: return GLFW_KEY_F2; + case KEY_F3: return GLFW_KEY_F3; + case KEY_F4: return GLFW_KEY_F4; + case KEY_F5: return GLFW_KEY_F5; + case KEY_F6: return GLFW_KEY_F6; + case KEY_F7: return GLFW_KEY_F7; + case KEY_F8: return GLFW_KEY_F8; + case KEY_F9: return GLFW_KEY_F9; + case KEY_F10: return GLFW_KEY_F10; + case KEY_F11: return GLFW_KEY_F11; + case KEY_F12: return GLFW_KEY_F12; + case KEY_F13: return GLFW_KEY_F13; + case KEY_F14: return GLFW_KEY_F14; + case KEY_F15: return GLFW_KEY_F15; + case KEY_F16: return GLFW_KEY_F16; + case KEY_F17: return GLFW_KEY_F17; + case KEY_F18: return GLFW_KEY_F18; + case KEY_F19: return GLFW_KEY_F19; + case KEY_F20: return GLFW_KEY_F20; + case KEY_F21: return GLFW_KEY_F21; + case KEY_F22: return GLFW_KEY_F22; + case KEY_F23: return GLFW_KEY_F23; + case KEY_F24: return GLFW_KEY_F24; + case KEY_KPSLASH: return GLFW_KEY_KP_DIVIDE; + case KEY_KPDOT: return GLFW_KEY_KP_MULTIPLY; + case KEY_KPMINUS: return GLFW_KEY_KP_SUBTRACT; + case KEY_KPPLUS: return GLFW_KEY_KP_ADD; + case KEY_KP0: return GLFW_KEY_KP_0; + case KEY_KP1: return GLFW_KEY_KP_1; + case KEY_KP2: return GLFW_KEY_KP_2; + case KEY_KP3: return GLFW_KEY_KP_3; + case KEY_KP4: return GLFW_KEY_KP_4; + case KEY_KP5: return GLFW_KEY_KP_5; + case KEY_KP6: return GLFW_KEY_KP_6; + case KEY_KP7: return GLFW_KEY_KP_7; + case KEY_KP8: return GLFW_KEY_KP_8; + case KEY_KP9: return GLFW_KEY_KP_9; + case KEY_KPCOMMA: return GLFW_KEY_KP_DECIMAL; + case KEY_KPEQUAL: return GLFW_KEY_KP_EQUAL; + case KEY_KPENTER: return GLFW_KEY_KP_ENTER; + default: return GLFW_KEY_UNKNOWN; + } +} + +static void handleKeyEvent(const MirKeyEvent key, _GLFWwindow* window) +{ + const int pressed = key.action == mir_key_action_up ? GLFW_RELEASE : GLFW_PRESS; + const int mods = mirModToGLFWMod(key.modifiers); + const long text = _glfwKeySym2Unicode(key.key_code); + const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT)); + + _glfwInputKey(window, toGLFWKeyCode(key.scan_code), key.scan_code, pressed, mods); + + if (text != -1) + _glfwInputChar(window, text, mods, plain); +} + +static void handleMouseButton(_GLFWwindow* window, + int pressed, int mods, MirMotionButton button) +{ + static int lastButton; + int publicButton; + const int publicMods = mirModToGLFWMod(mods); + + switch (button) + { + case mir_motion_button_primary: + publicButton = GLFW_MOUSE_BUTTON_LEFT; + break; + case mir_motion_button_secondary: + publicButton = GLFW_MOUSE_BUTTON_RIGHT; + break; + case mir_motion_button_tertiary: + publicButton = GLFW_MOUSE_BUTTON_MIDDLE; + break; + case mir_motion_button_forward: + // FIXME What is the forward button? + publicButton = GLFW_MOUSE_BUTTON_4; + break; + case mir_motion_button_back: + // FIXME What is the back button? + publicButton = GLFW_MOUSE_BUTTON_5; + break; + default: + publicButton = lastButton; + break; + } + + lastButton = publicButton; + + _glfwInputMouseClick(window, publicButton, pressed, publicMods); +} + +static void handleMouseMotion(_GLFWwindow* window, int x, int y) +{ + _glfwInputCursorMotion(window, x, y); +} + +static void handleMouseScroll(_GLFWwindow* window, int dx, int dy) +{ + _glfwInputScroll(window, dx, dy); +} + +static void handleMouseEvent(const MirMotionEvent motion, + int cord_index, + _GLFWwindow* window) +{ + switch (motion.action) + { + case mir_motion_action_down: + case mir_motion_action_pointer_down: + handleMouseButton(window, GLFW_PRESS, + motion.modifiers, motion.button_state); + break; + case mir_motion_action_up: + case mir_motion_action_pointer_up: + handleMouseButton(window, GLFW_RELEASE, + motion.modifiers, motion.button_state); + break; + case mir_motion_action_hover_move: + case mir_motion_action_move: + handleMouseMotion(window, + motion.pointer_coordinates[cord_index].x, + motion.pointer_coordinates[cord_index].y); + break; + case mir_motion_action_outside: + break; + case mir_motion_action_scroll: + handleMouseScroll(window, + motion.pointer_coordinates[cord_index].hscroll, + motion.pointer_coordinates[cord_index].vscroll); + break; + case mir_motion_action_cancel: + case mir_motion_action_hover_enter: + case mir_motion_action_hover_exit: + break; + default: + break; + + } +} + +static void handleMotionEvent(const MirMotionEvent motion, _GLFWwindow* window) +{ + int i; + for (i = 0; i < motion.pointer_count; i++) + handleMouseEvent(motion, i, window); +} + +static void handleInput(MirEvent const* event, _GLFWwindow* window) +{ + switch (event->type) + { + case mir_event_type_key: + handleKeyEvent(event->key, window); + break; + case mir_event_type_motion: + handleMotionEvent(event->motion, window); + break; + default: + break; + } +} + +static void addNewEvent(MirSurface* surface, MirEvent const* event, void* context) +{ + enqueueEvent(event, context); +} + +static int createSurface(_GLFWwindow* window) +{ + MirSurfaceParameters params = + { + .name = "MirSurface", + .width = window->mir.width, + .height = window->mir.height, + .pixel_format = mir_pixel_format_invalid, + .buffer_usage = mir_buffer_usage_hardware, + .output_id = mir_display_output_id_invalid + }; + + MirEventDelegate delegate = + { + addNewEvent, + window + }; + + params.pixel_format = findValidPixelFormat(); + if (params.pixel_format == mir_pixel_format_invalid) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Mir: Unable to find a correct pixel format"); + return GL_FALSE; + } + + window->mir.surface = + mir_connection_create_surface_sync(_glfw.mir.connection, ¶ms); + if (!mir_surface_is_valid(window->mir.surface)) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Mir: Unable to create surface: %s", + mir_surface_get_error_message(window->mir.surface)); + + return GL_FALSE; + } + + mir_surface_set_event_handler(window->mir.surface, &delegate); + + return GL_TRUE; +} + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +void _glfwInitEventQueue(EventQueue* queue) +{ + TAILQ_INIT(&queue->head); +} + +void _glfwDeleteEventQueue(EventQueue* queue) +{ + if (queue) + { + EventNode* node, *node_next; + node = queue->head.tqh_first; + + while (node != NULL) + { + node_next = node->entries.tqe_next; + + TAILQ_REMOVE(&queue->head, node, entries); + deleteNode(queue, node); + + node = node_next; + } + + free(queue); + } +} + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +int _glfwPlatformCreateWindow(_GLFWwindow* window, + const _GLFWwndconfig* wndconfig, + const _GLFWctxconfig* ctxconfig, + const _GLFWfbconfig* fbconfig) +{ + if (!_glfwCreateContext(window, ctxconfig, fbconfig)) + return GL_FALSE; + + if (wndconfig->monitor) + { + GLFWvidmode mode; + _glfwPlatformGetVideoMode(wndconfig->monitor, &mode); + + mir_surface_set_state(window->mir.surface, mir_surface_state_fullscreen); + + if (wndconfig->width > mode.width || wndconfig->height > mode.height) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Mir: Requested surface size is to large (%i %i)", + wndconfig->width, wndconfig->height); + + return GL_FALSE; + } + } + + window->mir.width = wndconfig->width; + window->mir.height = wndconfig->height; + + if (!createSurface(window)) + return GL_FALSE; + + window->mir.window = mir_surface_get_egl_native_window(window->mir.surface); + + return GL_TRUE; +} + +void _glfwPlatformDestroyWindow(_GLFWwindow* window) +{ + if (mir_surface_is_valid(window->mir.surface)) + { + mir_surface_release_sync(window->mir.surface); + window->mir.surface = NULL; + } + + _glfwDestroyContext(window); +} + +void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title) +{ + _glfwInputError(GLFW_PLATFORM_ERROR, + "Mir: Unsupported function %s!", __PRETTY_FUNCTION__); +} + +void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos) +{ + _glfwInputError(GLFW_PLATFORM_ERROR, + "Mir: Unsupported function %s!", __PRETTY_FUNCTION__); +} + +void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, + int* left, int* top, + int* right, int* bottom) +{ + _glfwInputError(GLFW_PLATFORM_ERROR, + "Mir: Unsupported function %s!", __PRETTY_FUNCTION__); +} + +void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos) +{ + _glfwInputError(GLFW_PLATFORM_ERROR, + "Mir: Unsupported function %s!", __PRETTY_FUNCTION__); +} + +void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) +{ + _glfwInputError(GLFW_PLATFORM_ERROR, + "Mir: Unsupported function %s!", __PRETTY_FUNCTION__); +} + +void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height) +{ + if (width) + *width = window->mir.width; + if (height) + *height = window->mir.height; +} + +void _glfwPlatformIconifyWindow(_GLFWwindow* window) +{ + mir_surface_set_state(window->mir.surface, mir_surface_state_minimized); +} + +void _glfwPlatformRestoreWindow(_GLFWwindow* window) +{ + mir_surface_set_state(window->mir.surface, mir_surface_state_restored); +} + +void _glfwPlatformHideWindow(_GLFWwindow* window) +{ + _glfwInputError(GLFW_PLATFORM_ERROR, + "Mir: Unsupported function %s!", __PRETTY_FUNCTION__); +} + +void _glfwPlatformShowWindow(_GLFWwindow* window) +{ + _glfwInputError(GLFW_PLATFORM_ERROR, + "Mir: Unsupported function %s!", __PRETTY_FUNCTION__); +} + +void _glfwPlatformUnhideWindow(_GLFWwindow* window) +{ + _glfwInputError(GLFW_PLATFORM_ERROR, + "Mir: Unsupported function %s!", __PRETTY_FUNCTION__); +} + +int _glfwPlatformWindowFocused(_GLFWwindow* window) +{ + _glfwInputError(GLFW_PLATFORM_ERROR, + "Mir: Unsupported function %s!", __PRETTY_FUNCTION__); + return GL_FALSE; +} + +int _glfwPlatformWindowIconified(_GLFWwindow* window) +{ + _glfwInputError(GLFW_PLATFORM_ERROR, + "Mir: Unsupported function %s!", __PRETTY_FUNCTION__); + return GL_FALSE; +} + +int _glfwPlatformWindowVisible(_GLFWwindow* window) +{ + _glfwInputError(GLFW_PLATFORM_ERROR, + "Mir: Unsupported function %s!", __PRETTY_FUNCTION__); + return GL_FALSE; +} + +void _glfwPlatformPollEvents(void) +{ + EventNode* node = NULL; + + while ((node = dequeueEvent(_glfw.mir.event_queue))) + { + handleInput(node->event, node->window); + deleteNode(_glfw.mir.event_queue, node); + } +} + +void _glfwPlatformWaitEvents(void) +{ + pthread_mutex_lock(&_glfw.mir.event_mutex); + + if (emptyEventQueue(_glfw.mir.event_queue)) + pthread_cond_wait(&_glfw.mir.event_cond, &_glfw.mir.event_mutex); + + pthread_mutex_unlock(&_glfw.mir.event_mutex); + + _glfwPlatformPollEvents(); +} + +void _glfwPlatformPostEmptyEvent(void) +{ +} + +void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height) +{ + if (width) + *width = window->mir.width; + if (height) + *height = window->mir.height; +} + +int _glfwPlatformCreateCursor(_GLFWcursor* cursor, + const GLFWimage* image, + int xhot, int yhot) +{ + _glfwInputError(GLFW_PLATFORM_ERROR, + "Mir: Unsupported function %s!", __PRETTY_FUNCTION__); + + return GL_FALSE; +} + +int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape) +{ + _glfwInputError(GLFW_PLATFORM_ERROR, + "Mir: Unsupported function %s!", __PRETTY_FUNCTION__); + + return GL_FALSE; +} + +void _glfwPlatformDestroyCursor(_GLFWcursor* cursor) +{ + _glfwInputError(GLFW_PLATFORM_ERROR, + "Mir: Unsupported function %s!", __PRETTY_FUNCTION__); +} + +void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) +{ + _glfwInputError(GLFW_PLATFORM_ERROR, + "Mir: Unsupported function %s!", __PRETTY_FUNCTION__); +} + +void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos) +{ + _glfwInputError(GLFW_PLATFORM_ERROR, + "Mir: Unsupported function %s!", __PRETTY_FUNCTION__); +} + +void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos) +{ + _glfwInputError(GLFW_PLATFORM_ERROR, + "Mir: Unsupported function %s!", __PRETTY_FUNCTION__); +} + +void _glfwPlatformApplyCursorMode(_GLFWwindow* window) +{ + _glfwInputError(GLFW_PLATFORM_ERROR, + "Mir: Unsupported function %s!", __PRETTY_FUNCTION__); +} + +void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string) +{ + _glfwInputError(GLFW_PLATFORM_ERROR, + "Mir: Unsupported function %s!", __PRETTY_FUNCTION__); +} + +const char* _glfwPlatformGetClipboardString(_GLFWwindow* window) +{ + _glfwInputError(GLFW_PLATFORM_ERROR, + "Mir: Unsupported function %s!", __PRETTY_FUNCTION__); + + return NULL; +} + diff --git a/testbed/glfw/src/monitor.c b/testbed/glfw/src/monitor.c new file mode 100644 index 00000000..1ab57489 --- /dev/null +++ b/testbed/glfw/src/monitor.c @@ -0,0 +1,442 @@ +//======================================================================== +// GLFW 3.1 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2010 Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include "internal.h" + +#include +#include +#include +#include + + +// Lexical comparison function for GLFW video modes, used by qsort +// +static int compareVideoModes(const void* firstPtr, const void* secondPtr) +{ + int firstBPP, secondBPP, firstSize, secondSize; + const GLFWvidmode* first = firstPtr; + const GLFWvidmode* second = secondPtr; + + // First sort on color bits per pixel + firstBPP = first->redBits + first->greenBits + first->blueBits; + secondBPP = second->redBits + second->greenBits + second->blueBits; + if (firstBPP != secondBPP) + return firstBPP - secondBPP; + + // Then sort on screen area, in pixels + firstSize = first->width * first->height; + secondSize = second->width * second->height; + if (firstSize != secondSize) + return firstSize - secondSize; + + // Lastly sort on refresh rate + return first->refreshRate - second->refreshRate; +} + +// Retrieves the available modes for the specified monitor +// +static int refreshVideoModes(_GLFWmonitor* monitor) +{ + int modeCount; + GLFWvidmode* modes; + + if (monitor->modes) + return GL_TRUE; + + modes = _glfwPlatformGetVideoModes(monitor, &modeCount); + if (!modes) + return GL_FALSE; + + qsort(modes, modeCount, sizeof(GLFWvidmode), compareVideoModes); + + free(monitor->modes); + monitor->modes = modes; + monitor->modeCount = modeCount; + + return GL_TRUE; +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW event API ////// +////////////////////////////////////////////////////////////////////////// + +void _glfwInputMonitorChange(void) +{ + int i, j, monitorCount = _glfw.monitorCount; + _GLFWmonitor** monitors = _glfw.monitors; + + _glfw.monitors = _glfwPlatformGetMonitors(&_glfw.monitorCount); + + // Re-use still connected monitor objects + + for (i = 0; i < _glfw.monitorCount; i++) + { + for (j = 0; j < monitorCount; j++) + { + if (_glfwPlatformIsSameMonitor(_glfw.monitors[i], monitors[j])) + { + _glfwFreeMonitor(_glfw.monitors[i]); + _glfw.monitors[i] = monitors[j]; + break; + } + } + } + + // Find and report disconnected monitors (not in the new list) + + for (i = 0; i < monitorCount; i++) + { + _GLFWwindow* window; + + for (j = 0; j < _glfw.monitorCount; j++) + { + if (monitors[i] == _glfw.monitors[j]) + break; + } + + if (j < _glfw.monitorCount) + continue; + + for (window = _glfw.windowListHead; window; window = window->next) + { + if (window->monitor == monitors[i]) + window->monitor = NULL; + } + + if (_glfw.callbacks.monitor) + _glfw.callbacks.monitor((GLFWmonitor*) monitors[i], GLFW_DISCONNECTED); + } + + // Find and report newly connected monitors (not in the old list) + // Re-used monitor objects are then removed from the old list to avoid + // having them destroyed at the end of this function + + for (i = 0; i < _glfw.monitorCount; i++) + { + for (j = 0; j < monitorCount; j++) + { + if (_glfw.monitors[i] == monitors[j]) + { + monitors[j] = NULL; + break; + } + } + + if (j < monitorCount) + continue; + + if (_glfw.callbacks.monitor) + _glfw.callbacks.monitor((GLFWmonitor*) _glfw.monitors[i], GLFW_CONNECTED); + } + + _glfwFreeMonitors(monitors, monitorCount); +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +_GLFWmonitor* _glfwAllocMonitor(const char* name, int widthMM, int heightMM) +{ + _GLFWmonitor* monitor = calloc(1, sizeof(_GLFWmonitor)); + monitor->name = strdup(name); + monitor->widthMM = widthMM; + monitor->heightMM = heightMM; + + return monitor; +} + +void _glfwFreeMonitor(_GLFWmonitor* monitor) +{ + if (monitor == NULL) + return; + + _glfwFreeGammaArrays(&monitor->originalRamp); + _glfwFreeGammaArrays(&monitor->currentRamp); + + free(monitor->modes); + free(monitor->name); + free(monitor); +} + +void _glfwAllocGammaArrays(GLFWgammaramp* ramp, unsigned int size) +{ + ramp->red = calloc(size, sizeof(unsigned short)); + ramp->green = calloc(size, sizeof(unsigned short)); + ramp->blue = calloc(size, sizeof(unsigned short)); + ramp->size = size; +} + +void _glfwFreeGammaArrays(GLFWgammaramp* ramp) +{ + free(ramp->red); + free(ramp->green); + free(ramp->blue); + + memset(ramp, 0, sizeof(GLFWgammaramp)); +} + +void _glfwFreeMonitors(_GLFWmonitor** monitors, int count) +{ + int i; + + for (i = 0; i < count; i++) + _glfwFreeMonitor(monitors[i]); + + free(monitors); +} + +const GLFWvidmode* _glfwChooseVideoMode(_GLFWmonitor* monitor, + const GLFWvidmode* desired) +{ + int i; + unsigned int sizeDiff, leastSizeDiff = UINT_MAX; + unsigned int rateDiff, leastRateDiff = UINT_MAX; + unsigned int colorDiff, leastColorDiff = UINT_MAX; + const GLFWvidmode* current; + const GLFWvidmode* closest = NULL; + + if (!refreshVideoModes(monitor)) + return NULL; + + for (i = 0; i < monitor->modeCount; i++) + { + current = monitor->modes + i; + + colorDiff = 0; + + if (desired->redBits != GLFW_DONT_CARE) + colorDiff += abs(current->redBits - desired->redBits); + if (desired->greenBits != GLFW_DONT_CARE) + colorDiff += abs(current->greenBits - desired->greenBits); + if (desired->blueBits != GLFW_DONT_CARE) + colorDiff += abs(current->blueBits - desired->blueBits); + + sizeDiff = abs((current->width - desired->width) * + (current->width - desired->width) + + (current->height - desired->height) * + (current->height - desired->height)); + + if (desired->refreshRate != GLFW_DONT_CARE) + rateDiff = abs(current->refreshRate - desired->refreshRate); + else + rateDiff = UINT_MAX - current->refreshRate; + + if ((colorDiff < leastColorDiff) || + (colorDiff == leastColorDiff && sizeDiff < leastSizeDiff) || + (colorDiff == leastColorDiff && sizeDiff == leastSizeDiff && rateDiff < leastRateDiff)) + { + closest = current; + leastSizeDiff = sizeDiff; + leastRateDiff = rateDiff; + leastColorDiff = colorDiff; + } + } + + return closest; +} + +int _glfwCompareVideoModes(const GLFWvidmode* first, const GLFWvidmode* second) +{ + return compareVideoModes(first, second); +} + +void _glfwSplitBPP(int bpp, int* red, int* green, int* blue) +{ + int delta; + + // We assume that by 32 the user really meant 24 + if (bpp == 32) + bpp = 24; + + // Convert "bits per pixel" to red, green & blue sizes + + *red = *green = *blue = bpp / 3; + delta = bpp - (*red * 3); + if (delta >= 1) + *green = *green + 1; + + if (delta == 2) + *red = *red + 1; +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW public API ////// +////////////////////////////////////////////////////////////////////////// + +GLFWAPI GLFWmonitor** glfwGetMonitors(int* count) +{ + *count = 0; + + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + + *count = _glfw.monitorCount; + return (GLFWmonitor**) _glfw.monitors; +} + +GLFWAPI GLFWmonitor* glfwGetPrimaryMonitor(void) +{ + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + return (GLFWmonitor*) _glfw.monitors[0]; +} + +GLFWAPI void glfwGetMonitorPos(GLFWmonitor* handle, int* xpos, int* ypos) +{ + _GLFWmonitor* monitor = (_GLFWmonitor*) handle; + + if (xpos) + *xpos = 0; + if (ypos) + *ypos = 0; + + _GLFW_REQUIRE_INIT(); + + _glfwPlatformGetMonitorPos(monitor, xpos, ypos); +} + +GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* handle, int* widthMM, int* heightMM) +{ + _GLFWmonitor* monitor = (_GLFWmonitor*) handle; + + if (widthMM) + *widthMM = 0; + if (heightMM) + *heightMM = 0; + + _GLFW_REQUIRE_INIT(); + + if (widthMM) + *widthMM = monitor->widthMM; + if (heightMM) + *heightMM = monitor->heightMM; +} + +GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* handle) +{ + _GLFWmonitor* monitor = (_GLFWmonitor*) handle; + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + return monitor->name; +} + +GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun cbfun) +{ + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFW_SWAP_POINTERS(_glfw.callbacks.monitor, cbfun); + return cbfun; +} + +GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* handle, int* count) +{ + _GLFWmonitor* monitor = (_GLFWmonitor*) handle; + + *count = 0; + + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + + if (!refreshVideoModes(monitor)) + return NULL; + + *count = monitor->modeCount; + return monitor->modes; +} + +GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* handle) +{ + _GLFWmonitor* monitor = (_GLFWmonitor*) handle; + + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + + _glfwPlatformGetVideoMode(monitor, &monitor->currentMode); + return &monitor->currentMode; +} + +GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma) +{ + int i; + unsigned short values[256]; + GLFWgammaramp ramp; + + _GLFW_REQUIRE_INIT(); + + if (gamma <= 0.f) + { + _glfwInputError(GLFW_INVALID_VALUE, + "Gamma value must be greater than zero"); + return; + } + + for (i = 0; i < 256; i++) + { + double value; + + // Calculate intensity + value = i / 255.0; + // Apply gamma curve + value = pow(value, 1.0 / gamma) * 65535.0 + 0.5; + + // Clamp to value range + if (value > 65535.0) + value = 65535.0; + + values[i] = (unsigned short) value; + } + + ramp.red = values; + ramp.green = values; + ramp.blue = values; + ramp.size = 256; + + glfwSetGammaRamp(handle, &ramp); +} + +GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle) +{ + _GLFWmonitor* monitor = (_GLFWmonitor*) handle; + + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + + _glfwFreeGammaArrays(&monitor->currentRamp); + _glfwPlatformGetGammaRamp(monitor, &monitor->currentRamp); + + return &monitor->currentRamp; +} + +GLFWAPI void glfwSetGammaRamp(GLFWmonitor* handle, const GLFWgammaramp* ramp) +{ + _GLFWmonitor* monitor = (_GLFWmonitor*) handle; + + _GLFW_REQUIRE_INIT(); + + if (!monitor->originalRamp.size) + _glfwPlatformGetGammaRamp(monitor, &monitor->originalRamp); + + _glfwPlatformSetGammaRamp(monitor, ramp); +} + diff --git a/testbed/glfw/src/nsgl_context.h b/testbed/glfw/src/nsgl_context.h new file mode 100644 index 00000000..fd045359 --- /dev/null +++ b/testbed/glfw/src/nsgl_context.h @@ -0,0 +1,62 @@ +//======================================================================== +// GLFW 3.1 OS X - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2009-2010 Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#ifndef _nsgl_context_h_ +#define _nsgl_context_h_ + +#define _GLFW_PLATFORM_FBCONFIG +#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextNSGL nsgl +#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryNSGL nsgl + + +// NSGL-specific per-context data +// +typedef struct _GLFWcontextNSGL +{ + id pixelFormat; + id context; + +} _GLFWcontextNSGL; + + +// NSGL-specific global data +// +typedef struct _GLFWlibraryNSGL +{ + // dlopen handle for OpenGL.framework (for glfwGetProcAddress) + void* framework; + +} _GLFWlibraryNSGL; + + +int _glfwInitContextAPI(void); +void _glfwTerminateContextAPI(void); +int _glfwCreateContext(_GLFWwindow* window, + const _GLFWctxconfig* ctxconfig, + const _GLFWfbconfig* fbconfig); +void _glfwDestroyContext(_GLFWwindow* window); + +#endif // _nsgl_context_h_ diff --git a/testbed/glfw/src/nsgl_context.m b/testbed/glfw/src/nsgl_context.m new file mode 100644 index 00000000..0f0fb86e --- /dev/null +++ b/testbed/glfw/src/nsgl_context.m @@ -0,0 +1,314 @@ +//======================================================================== +// GLFW 3.1 OS X - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2009-2010 Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include "internal.h" + + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +// Initialize OpenGL support +// +int _glfwInitContextAPI(void) +{ + if (!_glfwInitTLS()) + return GL_FALSE; + + _glfw.nsgl.framework = + CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl")); + if (_glfw.nsgl.framework == NULL) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "NSGL: Failed to locate OpenGL framework"); + return GL_FALSE; + } + + return GL_TRUE; +} + +// Terminate OpenGL support +// +void _glfwTerminateContextAPI(void) +{ + _glfwTerminateTLS(); +} + +// Create the OpenGL context +// +int _glfwCreateContext(_GLFWwindow* window, + const _GLFWctxconfig* ctxconfig, + const _GLFWfbconfig* fbconfig) +{ + unsigned int attributeCount = 0; + + if (ctxconfig->api == GLFW_OPENGL_ES_API) + { + _glfwInputError(GLFW_VERSION_UNAVAILABLE, + "NSGL: This API does not support OpenGL ES"); + return GL_FALSE; + } + +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 + if (ctxconfig->major == 3 && ctxconfig->minor < 2) + { + _glfwInputError(GLFW_VERSION_UNAVAILABLE, + "NSGL: The targeted version of OS X does not " + "support OpenGL 3.0 or 3.1"); + return GL_FALSE; + } + + if (ctxconfig->major > 2) + { + if (!ctxconfig->forward) + { + _glfwInputError(GLFW_VERSION_UNAVAILABLE, + "NSGL: The targeted version of OS X only " + "supports OpenGL 3.2 and later versions if they " + "are forward-compatible"); + return GL_FALSE; + } + + if (ctxconfig->profile != GLFW_OPENGL_CORE_PROFILE) + { + _glfwInputError(GLFW_VERSION_UNAVAILABLE, + "NSGL: The targeted version of OS X only " + "supports OpenGL 3.2 and later versions if they " + "use the core profile"); + return GL_FALSE; + } + } +#else + // Fail if OpenGL 3.0 or above was requested + if (ctxconfig->major > 2) + { + _glfwInputError(GLFW_VERSION_UNAVAILABLE, + "NSGL: The targeted version of OS X does not " + "support OpenGL version 3.0 or above"); + return GL_FALSE; + } +#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ + + // Context robustness modes (GL_KHR_robustness) are not yet supported on + // OS X but are not a hard constraint, so ignore and continue + + // Context release behaviors (GL_KHR_context_flush_control) are not yet + // supported on OS X but are not a hard constraint, so ignore and continue + +#define ADD_ATTR(x) { attributes[attributeCount++] = x; } +#define ADD_ATTR2(x, y) { ADD_ATTR(x); ADD_ATTR(y); } + + // Arbitrary array size here + NSOpenGLPixelFormatAttribute attributes[40]; + + ADD_ATTR(NSOpenGLPFAAccelerated); + ADD_ATTR(NSOpenGLPFAClosestPolicy); + +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101000 + if (ctxconfig->major >= 4) + { + ADD_ATTR2(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion4_1Core); + } + else +#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ + if (ctxconfig->major >= 3) + { + ADD_ATTR2(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core); + } +#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ + + if (ctxconfig->major <= 2) + { + if (fbconfig->auxBuffers != GLFW_DONT_CARE) + ADD_ATTR2(NSOpenGLPFAAuxBuffers, fbconfig->auxBuffers); + + if (fbconfig->accumRedBits != GLFW_DONT_CARE && + fbconfig->accumGreenBits != GLFW_DONT_CARE && + fbconfig->accumBlueBits != GLFW_DONT_CARE && + fbconfig->accumAlphaBits != GLFW_DONT_CARE) + { + const int accumBits = fbconfig->accumRedBits + + fbconfig->accumGreenBits + + fbconfig->accumBlueBits + + fbconfig->accumAlphaBits; + + ADD_ATTR2(NSOpenGLPFAAccumSize, accumBits); + } + } + + if (fbconfig->redBits != GLFW_DONT_CARE && + fbconfig->greenBits != GLFW_DONT_CARE && + fbconfig->blueBits != GLFW_DONT_CARE) + { + int colorBits = fbconfig->redBits + + fbconfig->greenBits + + fbconfig->blueBits; + + // OS X needs non-zero color size, so set reasonable values + if (colorBits == 0) + colorBits = 24; + else if (colorBits < 15) + colorBits = 15; + + ADD_ATTR2(NSOpenGLPFAColorSize, colorBits); + } + + if (fbconfig->alphaBits != GLFW_DONT_CARE) + ADD_ATTR2(NSOpenGLPFAAlphaSize, fbconfig->alphaBits); + + if (fbconfig->depthBits != GLFW_DONT_CARE) + ADD_ATTR2(NSOpenGLPFADepthSize, fbconfig->depthBits); + + if (fbconfig->stencilBits != GLFW_DONT_CARE) + ADD_ATTR2(NSOpenGLPFAStencilSize, fbconfig->stencilBits); + + if (fbconfig->stereo) + ADD_ATTR(NSOpenGLPFAStereo); + + if (fbconfig->doublebuffer) + ADD_ATTR(NSOpenGLPFADoubleBuffer); + + if (fbconfig->samples != GLFW_DONT_CARE) + { + if (fbconfig->samples == 0) + { + ADD_ATTR2(NSOpenGLPFASampleBuffers, 0); + } + else + { + ADD_ATTR2(NSOpenGLPFASampleBuffers, 1); + ADD_ATTR2(NSOpenGLPFASamples, fbconfig->samples); + } + } + + // NOTE: All NSOpenGLPixelFormats on the relevant cards support sRGB + // framebuffer, so there's no need (and no way) to request it + + ADD_ATTR(0); + +#undef ADD_ATTR +#undef ADD_ATTR2 + + window->nsgl.pixelFormat = + [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes]; + if (window->nsgl.pixelFormat == nil) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "NSGL: Failed to create OpenGL pixel format"); + return GL_FALSE; + } + + NSOpenGLContext* share = NULL; + + if (ctxconfig->share) + share = ctxconfig->share->nsgl.context; + + window->nsgl.context = + [[NSOpenGLContext alloc] initWithFormat:window->nsgl.pixelFormat + shareContext:share]; + if (window->nsgl.context == nil) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "NSGL: Failed to create OpenGL context"); + return GL_FALSE; + } + + return GL_TRUE; +} + +// Destroy the OpenGL context +// +void _glfwDestroyContext(_GLFWwindow* window) +{ + [window->nsgl.pixelFormat release]; + window->nsgl.pixelFormat = nil; + + [window->nsgl.context release]; + window->nsgl.context = nil; +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +void _glfwPlatformMakeContextCurrent(_GLFWwindow* window) +{ + if (window) + [window->nsgl.context makeCurrentContext]; + else + [NSOpenGLContext clearCurrentContext]; + + _glfwSetCurrentContext(window); +} + +void _glfwPlatformSwapBuffers(_GLFWwindow* window) +{ + // ARP appears to be unnecessary, but this is future-proof + [window->nsgl.context flushBuffer]; +} + +void _glfwPlatformSwapInterval(int interval) +{ + _GLFWwindow* window = _glfwPlatformGetCurrentContext(); + + GLint sync = interval; + [window->nsgl.context setValues:&sync forParameter:NSOpenGLCPSwapInterval]; +} + +int _glfwPlatformExtensionSupported(const char* extension) +{ + // There are no NSGL extensions + return GL_FALSE; +} + +GLFWglproc _glfwPlatformGetProcAddress(const char* procname) +{ + CFStringRef symbolName = CFStringCreateWithCString(kCFAllocatorDefault, + procname, + kCFStringEncodingASCII); + + GLFWglproc symbol = CFBundleGetFunctionPointerForName(_glfw.nsgl.framework, + symbolName); + + CFRelease(symbolName); + + return symbol; +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW native API ////// +////////////////////////////////////////////////////////////////////////// + +GLFWAPI id glfwGetNSGLContext(GLFWwindow* handle) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + _GLFW_REQUIRE_INIT_OR_RETURN(nil); + return window->nsgl.context; +} + diff --git a/testbed/glfw/src/posix_time.c b/testbed/glfw/src/posix_time.c new file mode 100644 index 00000000..53ea7949 --- /dev/null +++ b/testbed/glfw/src/posix_time.c @@ -0,0 +1,97 @@ +//======================================================================== +// GLFW 3.1 POSIX - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2010 Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include "internal.h" + +#include +#include + +// Return raw time +// +static uint64_t getRawTime(void) +{ +#if defined(CLOCK_MONOTONIC) + if (_glfw.posix_time.monotonic) + { + struct timespec ts; + + clock_gettime(CLOCK_MONOTONIC, &ts); + return (uint64_t) ts.tv_sec * (uint64_t) 1000000000 + (uint64_t) ts.tv_nsec; + } + else +#endif + { + struct timeval tv; + + gettimeofday(&tv, NULL); + return (uint64_t) tv.tv_sec * (uint64_t) 1000000 + (uint64_t) tv.tv_usec; + } +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +// Initialise timer +// +void _glfwInitTimer(void) +{ +#if defined(CLOCK_MONOTONIC) + struct timespec ts; + + if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) + { + _glfw.posix_time.monotonic = GL_TRUE; + _glfw.posix_time.resolution = 1e-9; + } + else +#endif + { + _glfw.posix_time.resolution = 1e-6; + } + + _glfw.posix_time.base = getRawTime(); +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +double _glfwPlatformGetTime(void) +{ + return (double) (getRawTime() - _glfw.posix_time.base) * + _glfw.posix_time.resolution; +} + +void _glfwPlatformSetTime(double time) +{ + _glfw.posix_time.base = getRawTime() - + (uint64_t) (time / _glfw.posix_time.resolution); +} + diff --git a/testbed/glfw/src/posix_time.h b/testbed/glfw/src/posix_time.h new file mode 100644 index 00000000..3e0955a1 --- /dev/null +++ b/testbed/glfw/src/posix_time.h @@ -0,0 +1,49 @@ +//======================================================================== +// GLFW 3.1 POSIX - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2010 Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#ifndef _posix_time_h_ +#define _posix_time_h_ + +#define _GLFW_PLATFORM_LIBRARY_TIME_STATE _GLFWtimePOSIX posix_time + +#include + + +// POSIX-specific global timer data +// +typedef struct _GLFWtimePOSIX +{ + GLboolean monotonic; + double resolution; + uint64_t base; + +} _GLFWtimePOSIX; + + +void _glfwInitTimer(void); + +#endif // _posix_time_h_ diff --git a/testbed/glfw/src/posix_tls.c b/testbed/glfw/src/posix_tls.c new file mode 100644 index 00000000..70fe19bb --- /dev/null +++ b/testbed/glfw/src/posix_tls.c @@ -0,0 +1,66 @@ +//======================================================================== +// GLFW 3.1 POSIX - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2010 Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include "internal.h" + + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +int _glfwInitTLS(void) +{ + if (pthread_key_create(&_glfw.posix_tls.context, NULL) != 0) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "POSIX: Failed to create context TLS"); + return GL_FALSE; + } + + return GL_TRUE; +} + +void _glfwTerminateTLS(void) +{ + pthread_key_delete(_glfw.posix_tls.context); +} + +void _glfwSetCurrentContext(_GLFWwindow* context) +{ + pthread_setspecific(_glfw.posix_tls.context, context); +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +_GLFWwindow* _glfwPlatformGetCurrentContext(void) +{ + return pthread_getspecific(_glfw.posix_tls.context); +} + diff --git a/testbed/glfw/src/posix_tls.h b/testbed/glfw/src/posix_tls.h new file mode 100644 index 00000000..d6fa000d --- /dev/null +++ b/testbed/glfw/src/posix_tls.h @@ -0,0 +1,49 @@ +//======================================================================== +// GLFW 3.1 POSIX - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2010 Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#ifndef _posix_tls_h_ +#define _posix_tls_h_ + +#include + +#define _GLFW_PLATFORM_LIBRARY_TLS_STATE _GLFWtlsPOSIX posix_tls + + +// POSIX-specific global TLS data +// +typedef struct _GLFWtlsPOSIX +{ + pthread_key_t context; + +} _GLFWtlsPOSIX; + + +int _glfwInitTLS(void); +void _glfwTerminateTLS(void); +void _glfwSetCurrentContext(_GLFWwindow* context); + +#endif // _posix_tls_h_ diff --git a/testbed/glfw/src/wgl_context.c b/testbed/glfw/src/wgl_context.c new file mode 100644 index 00000000..7b3b9c90 --- /dev/null +++ b/testbed/glfw/src/wgl_context.c @@ -0,0 +1,709 @@ +//======================================================================== +// GLFW 3.1 WGL - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2010 Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include "internal.h" + +#include +#include +#include + + +// Initialize WGL-specific extensions +// This function is called once before initial context creation, i.e. before +// any WGL extensions could be present. This is done in order to have both +// extension variable clearing and loading in the same place, hopefully +// decreasing the possibility of forgetting to add one without the other. +// +static void initWGLExtensions(_GLFWwindow* window) +{ + // This needs to include every function pointer loaded below + window->wgl.SwapIntervalEXT = NULL; + window->wgl.GetPixelFormatAttribivARB = NULL; + window->wgl.GetExtensionsStringARB = NULL; + window->wgl.GetExtensionsStringEXT = NULL; + window->wgl.CreateContextAttribsARB = NULL; + + // This needs to include every extension used below except for + // WGL_ARB_extensions_string and WGL_EXT_extensions_string + window->wgl.ARB_multisample = GL_FALSE; + window->wgl.ARB_framebuffer_sRGB = GL_FALSE; + window->wgl.ARB_create_context = GL_FALSE; + window->wgl.ARB_create_context_profile = GL_FALSE; + window->wgl.EXT_create_context_es2_profile = GL_FALSE; + window->wgl.ARB_create_context_robustness = GL_FALSE; + window->wgl.EXT_swap_control = GL_FALSE; + window->wgl.ARB_pixel_format = GL_FALSE; + window->wgl.ARB_context_flush_control = GL_FALSE; + + window->wgl.GetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC) + wglGetProcAddress("wglGetExtensionsStringEXT"); + if (!window->wgl.GetExtensionsStringEXT) + { + window->wgl.GetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC) + wglGetProcAddress("wglGetExtensionsStringARB"); + if (!window->wgl.GetExtensionsStringARB) + return; + } + + if (_glfwPlatformExtensionSupported("WGL_ARB_multisample")) + window->wgl.ARB_multisample = GL_TRUE; + + if (_glfwPlatformExtensionSupported("WGL_ARB_framebuffer_sRGB")) + window->wgl.ARB_framebuffer_sRGB = GL_TRUE; + + if (_glfwPlatformExtensionSupported("WGL_ARB_create_context")) + { + window->wgl.CreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC) + wglGetProcAddress("wglCreateContextAttribsARB"); + + if (window->wgl.CreateContextAttribsARB) + window->wgl.ARB_create_context = GL_TRUE; + } + + if (window->wgl.ARB_create_context) + { + if (_glfwPlatformExtensionSupported("WGL_ARB_create_context_profile")) + window->wgl.ARB_create_context_profile = GL_TRUE; + } + + if (window->wgl.ARB_create_context && + window->wgl.ARB_create_context_profile) + { + if (_glfwPlatformExtensionSupported("WGL_EXT_create_context_es2_profile")) + window->wgl.EXT_create_context_es2_profile = GL_TRUE; + } + + if (window->wgl.ARB_create_context) + { + if (_glfwPlatformExtensionSupported("WGL_ARB_create_context_robustness")) + window->wgl.ARB_create_context_robustness = GL_TRUE; + } + + if (_glfwPlatformExtensionSupported("WGL_EXT_swap_control")) + { + window->wgl.SwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC) + wglGetProcAddress("wglSwapIntervalEXT"); + + if (window->wgl.SwapIntervalEXT) + window->wgl.EXT_swap_control = GL_TRUE; + } + + if (_glfwPlatformExtensionSupported("WGL_ARB_pixel_format")) + { + window->wgl.GetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC) + wglGetProcAddress("wglGetPixelFormatAttribivARB"); + + if (window->wgl.GetPixelFormatAttribivARB) + window->wgl.ARB_pixel_format = GL_TRUE; + } + + if (_glfwPlatformExtensionSupported("WGL_ARB_context_flush_control")) + window->wgl.ARB_context_flush_control = GL_TRUE; +} + +// Returns the specified attribute of the specified pixel format +// NOTE: Do not call this unless we have found WGL_ARB_pixel_format +// +static int getPixelFormatAttrib(_GLFWwindow* window, int pixelFormat, int attrib) +{ + int value = 0; + + if (!window->wgl.GetPixelFormatAttribivARB(window->wgl.dc, + pixelFormat, + 0, 1, &attrib, &value)) + { + // NOTE: We should probably handle this error somehow + return 0; + } + + return value; +} + +// Return a list of available and usable framebuffer configs +// +static GLboolean choosePixelFormat(_GLFWwindow* window, + const _GLFWfbconfig* desired, + int* result) +{ + _GLFWfbconfig* usableConfigs; + const _GLFWfbconfig* closest; + int i, nativeCount, usableCount; + + if (window->wgl.ARB_pixel_format) + { + nativeCount = getPixelFormatAttrib(window, + 1, + WGL_NUMBER_PIXEL_FORMATS_ARB); + } + else + { + nativeCount = DescribePixelFormat(window->wgl.dc, + 1, + sizeof(PIXELFORMATDESCRIPTOR), + NULL); + } + + if (!nativeCount) + { + _glfwInputError(GLFW_API_UNAVAILABLE, "WGL: No pixel formats found"); + return GL_FALSE; + } + + usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig)); + usableCount = 0; + + for (i = 0; i < nativeCount; i++) + { + const int n = i + 1; + _GLFWfbconfig* u = usableConfigs + usableCount; + + if (window->wgl.ARB_pixel_format) + { + // Get pixel format attributes through WGL_ARB_pixel_format + if (!getPixelFormatAttrib(window, n, WGL_SUPPORT_OPENGL_ARB) || + !getPixelFormatAttrib(window, n, WGL_DRAW_TO_WINDOW_ARB)) + { + continue; + } + + if (getPixelFormatAttrib(window, n, WGL_PIXEL_TYPE_ARB) != + WGL_TYPE_RGBA_ARB) + { + continue; + } + + if (getPixelFormatAttrib(window, n, WGL_ACCELERATION_ARB) == + WGL_NO_ACCELERATION_ARB) + { + continue; + } + + u->redBits = getPixelFormatAttrib(window, n, WGL_RED_BITS_ARB); + u->greenBits = getPixelFormatAttrib(window, n, WGL_GREEN_BITS_ARB); + u->blueBits = getPixelFormatAttrib(window, n, WGL_BLUE_BITS_ARB); + u->alphaBits = getPixelFormatAttrib(window, n, WGL_ALPHA_BITS_ARB); + + u->depthBits = getPixelFormatAttrib(window, n, WGL_DEPTH_BITS_ARB); + u->stencilBits = getPixelFormatAttrib(window, n, WGL_STENCIL_BITS_ARB); + + u->accumRedBits = getPixelFormatAttrib(window, n, WGL_ACCUM_RED_BITS_ARB); + u->accumGreenBits = getPixelFormatAttrib(window, n, WGL_ACCUM_GREEN_BITS_ARB); + u->accumBlueBits = getPixelFormatAttrib(window, n, WGL_ACCUM_BLUE_BITS_ARB); + u->accumAlphaBits = getPixelFormatAttrib(window, n, WGL_ACCUM_ALPHA_BITS_ARB); + + u->auxBuffers = getPixelFormatAttrib(window, n, WGL_AUX_BUFFERS_ARB); + + if (getPixelFormatAttrib(window, n, WGL_STEREO_ARB)) + u->stereo = GL_TRUE; + if (getPixelFormatAttrib(window, n, WGL_DOUBLE_BUFFER_ARB)) + u->doublebuffer = GL_TRUE; + + if (window->wgl.ARB_multisample) + u->samples = getPixelFormatAttrib(window, n, WGL_SAMPLES_ARB); + + if (window->wgl.ARB_framebuffer_sRGB) + { + if (getPixelFormatAttrib(window, n, WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB)) + u->sRGB = GL_TRUE; + } + } + else + { + PIXELFORMATDESCRIPTOR pfd; + + // Get pixel format attributes through old-fashioned PFDs + + if (!DescribePixelFormat(window->wgl.dc, + n, + sizeof(PIXELFORMATDESCRIPTOR), + &pfd)) + { + continue; + } + + if (!(pfd.dwFlags & PFD_DRAW_TO_WINDOW) || + !(pfd.dwFlags & PFD_SUPPORT_OPENGL)) + { + continue; + } + + if (!(pfd.dwFlags & PFD_GENERIC_ACCELERATED) && + (pfd.dwFlags & PFD_GENERIC_FORMAT)) + { + continue; + } + + if (pfd.iPixelType != PFD_TYPE_RGBA) + continue; + + u->redBits = pfd.cRedBits; + u->greenBits = pfd.cGreenBits; + u->blueBits = pfd.cBlueBits; + u->alphaBits = pfd.cAlphaBits; + + u->depthBits = pfd.cDepthBits; + u->stencilBits = pfd.cStencilBits; + + u->accumRedBits = pfd.cAccumRedBits; + u->accumGreenBits = pfd.cAccumGreenBits; + u->accumBlueBits = pfd.cAccumBlueBits; + u->accumAlphaBits = pfd.cAccumAlphaBits; + + u->auxBuffers = pfd.cAuxBuffers; + + if (pfd.dwFlags & PFD_STEREO) + u->stereo = GL_TRUE; + if (pfd.dwFlags & PFD_DOUBLEBUFFER) + u->doublebuffer = GL_TRUE; + } + + u->wgl = n; + usableCount++; + } + + if (!usableCount) + { + _glfwInputError(GLFW_API_UNAVAILABLE, + "WGL: The driver does not appear to support OpenGL"); + + free(usableConfigs); + return GL_FALSE; + } + + closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount); + if (!closest) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "WGL: Failed to find a suitable pixel format"); + + free(usableConfigs); + return GL_FALSE; + } + + *result = closest->wgl; + free(usableConfigs); + + return GL_TRUE; +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +// Initialize WGL +// +int _glfwInitContextAPI(void) +{ + if (!_glfwInitTLS()) + return GL_FALSE; + + _glfw.wgl.opengl32.instance = LoadLibraryW(L"opengl32.dll"); + if (!_glfw.wgl.opengl32.instance) + { + _glfwInputError(GLFW_PLATFORM_ERROR, "Failed to load opengl32.dll"); + return GL_FALSE; + } + + return GL_TRUE; +} + +// Terminate WGL +// +void _glfwTerminateContextAPI(void) +{ + if (_glfw.wgl.opengl32.instance) + FreeLibrary(_glfw.wgl.opengl32.instance); + + _glfwTerminateTLS(); +} + +#define setWGLattrib(attribName, attribValue) \ +{ \ + attribs[index++] = attribName; \ + attribs[index++] = attribValue; \ + assert((size_t) index < sizeof(attribs) / sizeof(attribs[0])); \ +} + +// Create the OpenGL or OpenGL ES context +// +int _glfwCreateContext(_GLFWwindow* window, + const _GLFWctxconfig* ctxconfig, + const _GLFWfbconfig* fbconfig) +{ + int attribs[40]; + int pixelFormat = 0; + PIXELFORMATDESCRIPTOR pfd; + HGLRC share = NULL; + + if (ctxconfig->share) + share = ctxconfig->share->wgl.context; + + window->wgl.dc = GetDC(window->win32.handle); + if (!window->wgl.dc) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Win32: Failed to retrieve DC for window"); + return GL_FALSE; + } + + if (!choosePixelFormat(window, fbconfig, &pixelFormat)) + return GL_FALSE; + + if (!DescribePixelFormat(window->wgl.dc, pixelFormat, sizeof(pfd), &pfd)) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Win32: Failed to retrieve PFD for selected pixel " + "format"); + return GL_FALSE; + } + + if (!SetPixelFormat(window->wgl.dc, pixelFormat, &pfd)) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Win32: Failed to set selected pixel format"); + return GL_FALSE; + } + + if (window->wgl.ARB_create_context) + { + int index = 0, mask = 0, flags = 0, strategy = 0; + + if (ctxconfig->api == GLFW_OPENGL_API) + { + if (ctxconfig->forward) + flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; + + if (ctxconfig->debug) + flags |= WGL_CONTEXT_DEBUG_BIT_ARB; + + if (ctxconfig->profile) + { + if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE) + mask |= WGL_CONTEXT_CORE_PROFILE_BIT_ARB; + else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE) + mask |= WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; + } + } + else + mask |= WGL_CONTEXT_ES2_PROFILE_BIT_EXT; + + if (ctxconfig->robustness) + { + if (window->wgl.ARB_create_context_robustness) + { + if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION) + strategy = WGL_NO_RESET_NOTIFICATION_ARB; + else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET) + strategy = WGL_LOSE_CONTEXT_ON_RESET_ARB; + + flags |= WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB; + } + } + + if (ctxconfig->release) + { + if (window->wgl.ARB_context_flush_control) + { + if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE) + { + setWGLattrib(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB, + WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB); + } + else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH) + { + setWGLattrib(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB, + WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB); + } + } + } + + if (ctxconfig->major != 1 || ctxconfig->minor != 0) + { + // NOTE: Only request an explicitly versioned context when + // necessary, as explicitly requesting version 1.0 does not + // always return the highest available version + + setWGLattrib(WGL_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major); + setWGLattrib(WGL_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor); + } + + if (flags) + setWGLattrib(WGL_CONTEXT_FLAGS_ARB, flags); + + if (mask) + setWGLattrib(WGL_CONTEXT_PROFILE_MASK_ARB, mask); + + if (strategy) + setWGLattrib(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, strategy); + + setWGLattrib(0, 0); + + window->wgl.context = window->wgl.CreateContextAttribsARB(window->wgl.dc, + share, + attribs); + if (!window->wgl.context) + { + _glfwInputError(GLFW_VERSION_UNAVAILABLE, + "WGL: Failed to create OpenGL context"); + return GL_FALSE; + } + } + else + { + window->wgl.context = wglCreateContext(window->wgl.dc); + if (!window->wgl.context) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "WGL: Failed to create OpenGL context"); + return GL_FALSE; + } + + if (share) + { + if (!wglShareLists(share, window->wgl.context)) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "WGL: Failed to enable sharing with specified " + "OpenGL context"); + return GL_FALSE; + } + } + } + + _glfwPlatformMakeContextCurrent(window); + initWGLExtensions(window); + + return GL_TRUE; +} + +#undef setWGLattrib + +// Destroy the OpenGL context +// +void _glfwDestroyContext(_GLFWwindow* window) +{ + if (window->wgl.context) + { + wglDeleteContext(window->wgl.context); + window->wgl.context = NULL; + } + + if (window->wgl.dc) + { + ReleaseDC(window->win32.handle, window->wgl.dc); + window->wgl.dc = NULL; + } +} + +// Analyzes the specified context for possible recreation +// +int _glfwAnalyzeContext(const _GLFWwindow* window, + const _GLFWctxconfig* ctxconfig, + const _GLFWfbconfig* fbconfig) +{ + GLboolean required = GL_FALSE; + + if (ctxconfig->api == GLFW_OPENGL_API) + { + if (ctxconfig->forward) + { + if (!window->wgl.ARB_create_context) + { + _glfwInputError(GLFW_VERSION_UNAVAILABLE, + "WGL: A forward compatible OpenGL context " + "requested but WGL_ARB_create_context is " + "unavailable"); + return _GLFW_RECREATION_IMPOSSIBLE; + } + + required = GL_TRUE; + } + + if (ctxconfig->profile) + { + if (!window->wgl.ARB_create_context_profile) + { + _glfwInputError(GLFW_VERSION_UNAVAILABLE, + "WGL: OpenGL profile requested but " + "WGL_ARB_create_context_profile is unavailable"); + return _GLFW_RECREATION_IMPOSSIBLE; + } + + required = GL_TRUE; + } + + if (ctxconfig->release) + { + if (window->wgl.ARB_context_flush_control) + required = GL_TRUE; + } + } + else + { + if (!window->wgl.ARB_create_context || + !window->wgl.ARB_create_context_profile || + !window->wgl.EXT_create_context_es2_profile) + { + _glfwInputError(GLFW_API_UNAVAILABLE, + "WGL: OpenGL ES requested but " + "WGL_ARB_create_context_es2_profile is unavailable"); + return _GLFW_RECREATION_IMPOSSIBLE; + } + + required = GL_TRUE; + } + + if (ctxconfig->major != 1 || ctxconfig->minor != 0) + { + if (window->wgl.ARB_create_context) + required = GL_TRUE; + } + + if (ctxconfig->debug) + { + if (window->wgl.ARB_create_context) + required = GL_TRUE; + } + + if (fbconfig->samples > 0) + { + // We want FSAA, but can we get it? + // FSAA is not a hard constraint, so otherwise we just don't care + + if (window->wgl.ARB_multisample && window->wgl.ARB_pixel_format) + { + // We appear to have both the extension and the means to ask for it + required = GL_TRUE; + } + } + + if (fbconfig->sRGB) + { + // We want sRGB, but can we get it? + // sRGB is not a hard constraint, so otherwise we just don't care + + if (window->wgl.ARB_framebuffer_sRGB && window->wgl.ARB_pixel_format) + { + // We appear to have both the extension and the means to ask for it + required = GL_TRUE; + } + } + + if (required) + return _GLFW_RECREATION_REQUIRED; + + return _GLFW_RECREATION_NOT_NEEDED; +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +void _glfwPlatformMakeContextCurrent(_GLFWwindow* window) +{ + if (window) + wglMakeCurrent(window->wgl.dc, window->wgl.context); + else + wglMakeCurrent(NULL, NULL); + + _glfwSetCurrentContext(window); +} + +void _glfwPlatformSwapBuffers(_GLFWwindow* window) +{ + SwapBuffers(window->wgl.dc); +} + +void _glfwPlatformSwapInterval(int interval) +{ + _GLFWwindow* window = _glfwPlatformGetCurrentContext(); + +#if !defined(_GLFW_USE_DWM_SWAP_INTERVAL) + if (_glfwIsCompositionEnabled() && interval) + { + // Don't enabled vsync when desktop compositing is enabled, as it leads + // to frame jitter + return; + } +#endif + + if (window->wgl.EXT_swap_control) + window->wgl.SwapIntervalEXT(interval); +} + +int _glfwPlatformExtensionSupported(const char* extension) +{ + const GLubyte* extensions; + + _GLFWwindow* window = _glfwPlatformGetCurrentContext(); + + if (window->wgl.GetExtensionsStringEXT != NULL) + { + extensions = (GLubyte*) window->wgl.GetExtensionsStringEXT(); + if (extensions != NULL) + { + if (_glfwStringInExtensionString(extension, extensions)) + return GL_TRUE; + } + } + + if (window->wgl.GetExtensionsStringARB != NULL) + { + extensions = (GLubyte*) window->wgl.GetExtensionsStringARB(window->wgl.dc); + if (extensions != NULL) + { + if (_glfwStringInExtensionString(extension, extensions)) + return GL_TRUE; + } + } + + return GL_FALSE; +} + +GLFWglproc _glfwPlatformGetProcAddress(const char* procname) +{ + const GLFWglproc proc = (GLFWglproc) wglGetProcAddress(procname); + if (proc) + return proc; + + return (GLFWglproc) GetProcAddress(_glfw.wgl.opengl32.instance, procname); +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW native API ////// +////////////////////////////////////////////////////////////////////////// + +GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* handle) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + return window->wgl.context; +} + diff --git a/testbed/glfw/src/wgl_context.h b/testbed/glfw/src/wgl_context.h new file mode 100644 index 00000000..3fc29e72 --- /dev/null +++ b/testbed/glfw/src/wgl_context.h @@ -0,0 +1,89 @@ +//======================================================================== +// GLFW 3.1 WGL - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2010 Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#ifndef _wgl_context_h_ +#define _wgl_context_h_ + +// This path may need to be changed if you build GLFW using your own setup +// We ship and use our own copy of wglext.h since GLFW uses fairly new +// extensions and not all operating systems come with an up-to-date version +#include "../deps/GL/wglext.h" + +#define _GLFW_PLATFORM_FBCONFIG int wgl +#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextWGL wgl +#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryWGL wgl + + +// WGL-specific per-context data +// +typedef struct _GLFWcontextWGL +{ + HDC dc; // Private GDI device context + HGLRC context; // Permanent rendering context + + // WGL extensions (context specific) + PFNWGLSWAPINTERVALEXTPROC SwapIntervalEXT; + PFNWGLGETPIXELFORMATATTRIBIVARBPROC GetPixelFormatAttribivARB; + PFNWGLGETEXTENSIONSSTRINGEXTPROC GetExtensionsStringEXT; + PFNWGLGETEXTENSIONSSTRINGARBPROC GetExtensionsStringARB; + PFNWGLCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB; + GLboolean EXT_swap_control; + GLboolean ARB_multisample; + GLboolean ARB_framebuffer_sRGB; + GLboolean ARB_pixel_format; + GLboolean ARB_create_context; + GLboolean ARB_create_context_profile; + GLboolean EXT_create_context_es2_profile; + GLboolean ARB_create_context_robustness; + GLboolean ARB_context_flush_control; + +} _GLFWcontextWGL; + + +// WGL-specific global data +// +typedef struct _GLFWlibraryWGL +{ + // opengl32.dll (for glfwGetProcAddress) + struct { + HINSTANCE instance; + } opengl32; + +} _GLFWlibraryWGL; + + +int _glfwInitContextAPI(void); +void _glfwTerminateContextAPI(void); +int _glfwCreateContext(_GLFWwindow* window, + const _GLFWctxconfig* ctxconfig, + const _GLFWfbconfig* fbconfig); +void _glfwDestroyContext(_GLFWwindow* window); +int _glfwAnalyzeContext(const _GLFWwindow* window, + const _GLFWctxconfig* ctxconfig, + const _GLFWfbconfig* fbconfig); + +#endif // _wgl_context_h_ diff --git a/testbed/glfw/src/win32_init.c b/testbed/glfw/src/win32_init.c new file mode 100644 index 00000000..964b23aa --- /dev/null +++ b/testbed/glfw/src/win32_init.c @@ -0,0 +1,394 @@ +//======================================================================== +// GLFW 3.1 Win32 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2010 Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include "internal.h" + +#include +#include + +#ifdef __BORLANDC__ +// With the Borland C++ compiler, we want to disable FPU exceptions +#include +#endif // __BORLANDC__ + + +#if defined(_GLFW_USE_OPTIMUS_HPG) + +// Applications exporting this symbol with this value will be automatically +// directed to the high-performance GPU on Nvidia Optimus systems +// +__declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; + +#endif // _GLFW_USE_OPTIMUS_HPG + +#if defined(_GLFW_BUILD_DLL) + +// GLFW DLL entry point +// +BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) +{ + return TRUE; +} + +#endif // _GLFW_BUILD_DLL + +// Load necessary libraries (DLLs) +// +static GLboolean initLibraries(void) +{ + _glfw.win32.winmm.instance = LoadLibraryW(L"winmm.dll"); + if (!_glfw.win32.winmm.instance) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Win32: Failed to load winmm.dll"); + return GL_FALSE; + } + + _glfw.win32.winmm.joyGetDevCaps = (JOYGETDEVCAPS_T) + GetProcAddress(_glfw.win32.winmm.instance, "joyGetDevCapsW"); + _glfw.win32.winmm.joyGetPos = (JOYGETPOS_T) + GetProcAddress(_glfw.win32.winmm.instance, "joyGetPos"); + _glfw.win32.winmm.joyGetPosEx = (JOYGETPOSEX_T) + GetProcAddress(_glfw.win32.winmm.instance, "joyGetPosEx"); + _glfw.win32.winmm.timeGetTime = (TIMEGETTIME_T) + GetProcAddress(_glfw.win32.winmm.instance, "timeGetTime"); + + if (!_glfw.win32.winmm.joyGetDevCaps || + !_glfw.win32.winmm.joyGetPos || + !_glfw.win32.winmm.joyGetPosEx || + !_glfw.win32.winmm.timeGetTime) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Win32: Failed to load winmm functions"); + return GL_FALSE; + } + + _glfw.win32.user32.instance = LoadLibraryW(L"user32.dll"); + if (_glfw.win32.user32.instance) + { + _glfw.win32.user32.SetProcessDPIAware = (SETPROCESSDPIAWARE_T) + GetProcAddress(_glfw.win32.user32.instance, "SetProcessDPIAware"); + _glfw.win32.user32.ChangeWindowMessageFilterEx = (CHANGEWINDOWMESSAGEFILTEREX_T) + GetProcAddress(_glfw.win32.user32.instance, "ChangeWindowMessageFilterEx"); + } + + _glfw.win32.dwmapi.instance = LoadLibraryW(L"dwmapi.dll"); + if (_glfw.win32.dwmapi.instance) + { + _glfw.win32.dwmapi.DwmIsCompositionEnabled = (DWMISCOMPOSITIONENABLED_T) + GetProcAddress(_glfw.win32.dwmapi.instance, "DwmIsCompositionEnabled"); + } + + return GL_TRUE; +} + +// Unload used libraries (DLLs) +// +static void terminateLibraries(void) +{ + if (_glfw.win32.winmm.instance) + FreeLibrary(_glfw.win32.winmm.instance); + + if (_glfw.win32.user32.instance) + FreeLibrary(_glfw.win32.user32.instance); + + if (_glfw.win32.dwmapi.instance) + FreeLibrary(_glfw.win32.dwmapi.instance); +} + +// Create key code translation tables +// +static void createKeyTables(void) +{ + memset(_glfw.win32.publicKeys, -1, sizeof(_glfw.win32.publicKeys)); + + _glfw.win32.publicKeys[0x00B] = GLFW_KEY_0; + _glfw.win32.publicKeys[0x002] = GLFW_KEY_1; + _glfw.win32.publicKeys[0x003] = GLFW_KEY_2; + _glfw.win32.publicKeys[0x004] = GLFW_KEY_3; + _glfw.win32.publicKeys[0x005] = GLFW_KEY_4; + _glfw.win32.publicKeys[0x006] = GLFW_KEY_5; + _glfw.win32.publicKeys[0x007] = GLFW_KEY_6; + _glfw.win32.publicKeys[0x008] = GLFW_KEY_7; + _glfw.win32.publicKeys[0x009] = GLFW_KEY_8; + _glfw.win32.publicKeys[0x00A] = GLFW_KEY_9; + _glfw.win32.publicKeys[0x01E] = GLFW_KEY_A; + _glfw.win32.publicKeys[0x030] = GLFW_KEY_B; + _glfw.win32.publicKeys[0x02E] = GLFW_KEY_C; + _glfw.win32.publicKeys[0x020] = GLFW_KEY_D; + _glfw.win32.publicKeys[0x012] = GLFW_KEY_E; + _glfw.win32.publicKeys[0x021] = GLFW_KEY_F; + _glfw.win32.publicKeys[0x022] = GLFW_KEY_G; + _glfw.win32.publicKeys[0x023] = GLFW_KEY_H; + _glfw.win32.publicKeys[0x017] = GLFW_KEY_I; + _glfw.win32.publicKeys[0x024] = GLFW_KEY_J; + _glfw.win32.publicKeys[0x025] = GLFW_KEY_K; + _glfw.win32.publicKeys[0x026] = GLFW_KEY_L; + _glfw.win32.publicKeys[0x032] = GLFW_KEY_M; + _glfw.win32.publicKeys[0x031] = GLFW_KEY_N; + _glfw.win32.publicKeys[0x018] = GLFW_KEY_O; + _glfw.win32.publicKeys[0x019] = GLFW_KEY_P; + _glfw.win32.publicKeys[0x010] = GLFW_KEY_Q; + _glfw.win32.publicKeys[0x013] = GLFW_KEY_R; + _glfw.win32.publicKeys[0x01F] = GLFW_KEY_S; + _glfw.win32.publicKeys[0x014] = GLFW_KEY_T; + _glfw.win32.publicKeys[0x016] = GLFW_KEY_U; + _glfw.win32.publicKeys[0x02F] = GLFW_KEY_V; + _glfw.win32.publicKeys[0x011] = GLFW_KEY_W; + _glfw.win32.publicKeys[0x02D] = GLFW_KEY_X; + _glfw.win32.publicKeys[0x015] = GLFW_KEY_Y; + _glfw.win32.publicKeys[0x02C] = GLFW_KEY_Z; + + _glfw.win32.publicKeys[0x028] = GLFW_KEY_APOSTROPHE; + _glfw.win32.publicKeys[0x02B] = GLFW_KEY_BACKSLASH; + _glfw.win32.publicKeys[0x033] = GLFW_KEY_COMMA; + _glfw.win32.publicKeys[0x00D] = GLFW_KEY_EQUAL; + _glfw.win32.publicKeys[0x029] = GLFW_KEY_GRAVE_ACCENT; + _glfw.win32.publicKeys[0x01A] = GLFW_KEY_LEFT_BRACKET; + _glfw.win32.publicKeys[0x00C] = GLFW_KEY_MINUS; + _glfw.win32.publicKeys[0x034] = GLFW_KEY_PERIOD; + _glfw.win32.publicKeys[0x01B] = GLFW_KEY_RIGHT_BRACKET; + _glfw.win32.publicKeys[0x027] = GLFW_KEY_SEMICOLON; + _glfw.win32.publicKeys[0x035] = GLFW_KEY_SLASH; + _glfw.win32.publicKeys[0x056] = GLFW_KEY_WORLD_2; + + _glfw.win32.publicKeys[0x00E] = GLFW_KEY_BACKSPACE; + _glfw.win32.publicKeys[0x153] = GLFW_KEY_DELETE; + _glfw.win32.publicKeys[0x14F] = GLFW_KEY_END; + _glfw.win32.publicKeys[0x01C] = GLFW_KEY_ENTER; + _glfw.win32.publicKeys[0x001] = GLFW_KEY_ESCAPE; + _glfw.win32.publicKeys[0x147] = GLFW_KEY_HOME; + _glfw.win32.publicKeys[0x152] = GLFW_KEY_INSERT; + _glfw.win32.publicKeys[0x15D] = GLFW_KEY_MENU; + _glfw.win32.publicKeys[0x151] = GLFW_KEY_PAGE_DOWN; + _glfw.win32.publicKeys[0x149] = GLFW_KEY_PAGE_UP; + _glfw.win32.publicKeys[0x045] = GLFW_KEY_PAUSE; + _glfw.win32.publicKeys[0x039] = GLFW_KEY_SPACE; + _glfw.win32.publicKeys[0x00F] = GLFW_KEY_TAB; + _glfw.win32.publicKeys[0x03A] = GLFW_KEY_CAPS_LOCK; + _glfw.win32.publicKeys[0x145] = GLFW_KEY_NUM_LOCK; + _glfw.win32.publicKeys[0x046] = GLFW_KEY_SCROLL_LOCK; + _glfw.win32.publicKeys[0x03B] = GLFW_KEY_F1; + _glfw.win32.publicKeys[0x03C] = GLFW_KEY_F2; + _glfw.win32.publicKeys[0x03D] = GLFW_KEY_F3; + _glfw.win32.publicKeys[0x03E] = GLFW_KEY_F4; + _glfw.win32.publicKeys[0x03F] = GLFW_KEY_F5; + _glfw.win32.publicKeys[0x040] = GLFW_KEY_F6; + _glfw.win32.publicKeys[0x041] = GLFW_KEY_F7; + _glfw.win32.publicKeys[0x042] = GLFW_KEY_F8; + _glfw.win32.publicKeys[0x043] = GLFW_KEY_F9; + _glfw.win32.publicKeys[0x044] = GLFW_KEY_F10; + _glfw.win32.publicKeys[0x057] = GLFW_KEY_F11; + _glfw.win32.publicKeys[0x058] = GLFW_KEY_F12; + _glfw.win32.publicKeys[0x064] = GLFW_KEY_F13; + _glfw.win32.publicKeys[0x065] = GLFW_KEY_F14; + _glfw.win32.publicKeys[0x066] = GLFW_KEY_F15; + _glfw.win32.publicKeys[0x067] = GLFW_KEY_F16; + _glfw.win32.publicKeys[0x068] = GLFW_KEY_F17; + _glfw.win32.publicKeys[0x069] = GLFW_KEY_F18; + _glfw.win32.publicKeys[0x06A] = GLFW_KEY_F19; + _glfw.win32.publicKeys[0x06B] = GLFW_KEY_F20; + _glfw.win32.publicKeys[0x06C] = GLFW_KEY_F21; + _glfw.win32.publicKeys[0x06D] = GLFW_KEY_F22; + _glfw.win32.publicKeys[0x06E] = GLFW_KEY_F23; + _glfw.win32.publicKeys[0x076] = GLFW_KEY_F24; + _glfw.win32.publicKeys[0x038] = GLFW_KEY_LEFT_ALT; + _glfw.win32.publicKeys[0x01D] = GLFW_KEY_LEFT_CONTROL; + _glfw.win32.publicKeys[0x02A] = GLFW_KEY_LEFT_SHIFT; + _glfw.win32.publicKeys[0x15B] = GLFW_KEY_LEFT_SUPER; + _glfw.win32.publicKeys[0x137] = GLFW_KEY_PRINT_SCREEN; + _glfw.win32.publicKeys[0x138] = GLFW_KEY_RIGHT_ALT; + _glfw.win32.publicKeys[0x11D] = GLFW_KEY_RIGHT_CONTROL; + _glfw.win32.publicKeys[0x036] = GLFW_KEY_RIGHT_SHIFT; + _glfw.win32.publicKeys[0x15C] = GLFW_KEY_RIGHT_SUPER; + _glfw.win32.publicKeys[0x150] = GLFW_KEY_DOWN; + _glfw.win32.publicKeys[0x14B] = GLFW_KEY_LEFT; + _glfw.win32.publicKeys[0x14D] = GLFW_KEY_RIGHT; + _glfw.win32.publicKeys[0x148] = GLFW_KEY_UP; + + _glfw.win32.publicKeys[0x052] = GLFW_KEY_KP_0; + _glfw.win32.publicKeys[0x04F] = GLFW_KEY_KP_1; + _glfw.win32.publicKeys[0x050] = GLFW_KEY_KP_2; + _glfw.win32.publicKeys[0x051] = GLFW_KEY_KP_3; + _glfw.win32.publicKeys[0x04B] = GLFW_KEY_KP_4; + _glfw.win32.publicKeys[0x04C] = GLFW_KEY_KP_5; + _glfw.win32.publicKeys[0x04D] = GLFW_KEY_KP_6; + _glfw.win32.publicKeys[0x047] = GLFW_KEY_KP_7; + _glfw.win32.publicKeys[0x048] = GLFW_KEY_KP_8; + _glfw.win32.publicKeys[0x049] = GLFW_KEY_KP_9; + _glfw.win32.publicKeys[0x04E] = GLFW_KEY_KP_ADD; + _glfw.win32.publicKeys[0x053] = GLFW_KEY_KP_DECIMAL; + _glfw.win32.publicKeys[0x135] = GLFW_KEY_KP_DIVIDE; + _glfw.win32.publicKeys[0x11C] = GLFW_KEY_KP_ENTER; + _glfw.win32.publicKeys[0x037] = GLFW_KEY_KP_MULTIPLY; + _glfw.win32.publicKeys[0x04A] = GLFW_KEY_KP_SUBTRACT; +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +// Returns whether desktop compositing is enabled +// +BOOL _glfwIsCompositionEnabled(void) +{ + BOOL enabled; + + if (!_glfw_DwmIsCompositionEnabled) + return FALSE; + + if (_glfw_DwmIsCompositionEnabled(&enabled) != S_OK) + return FALSE; + + return enabled; +} + +// Returns a wide string version of the specified UTF-8 string +// +WCHAR* _glfwCreateWideStringFromUTF8(const char* source) +{ + WCHAR* target; + int length; + + length = MultiByteToWideChar(CP_UTF8, 0, source, -1, NULL, 0); + if (!length) + return NULL; + + target = calloc(length, sizeof(WCHAR)); + + if (!MultiByteToWideChar(CP_UTF8, 0, source, -1, target, length)) + { + free(target); + return NULL; + } + + return target; +} + +// Returns a UTF-8 string version of the specified wide string +// +char* _glfwCreateUTF8FromWideString(const WCHAR* source) +{ + char* target; + int length; + + length = WideCharToMultiByte(CP_UTF8, 0, source, -1, NULL, 0, NULL, NULL); + if (!length) + return NULL; + + target = calloc(length, sizeof(char)); + + if (!WideCharToMultiByte(CP_UTF8, 0, source, -1, target, length, NULL, NULL)) + { + free(target); + return NULL; + } + + return target; +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +int _glfwPlatformInit(void) +{ + // To make SetForegroundWindow work as we want, we need to fiddle + // with the FOREGROUNDLOCKTIMEOUT system setting (we do this as early + // as possible in the hope of still being the foreground process) + SystemParametersInfoW(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, + &_glfw.win32.foregroundLockTimeout, 0); + SystemParametersInfoW(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, UIntToPtr(0), + SPIF_SENDCHANGE); + + if (!initLibraries()) + return GL_FALSE; + + createKeyTables(); + + if (_glfw_SetProcessDPIAware) + _glfw_SetProcessDPIAware(); + +#ifdef __BORLANDC__ + // With the Borland C++ compiler, we want to disable FPU exceptions + // (this is recommended for OpenGL applications under Windows) + _control87(MCW_EM, MCW_EM); +#endif + + if (!_glfwRegisterWindowClass()) + return GL_FALSE; + + if (!_glfwInitContextAPI()) + return GL_FALSE; + + _glfwInitTimer(); + _glfwInitJoysticks(); + + return GL_TRUE; +} + +void _glfwPlatformTerminate(void) +{ + _glfwUnregisterWindowClass(); + + // Restore previous foreground lock timeout system setting + SystemParametersInfoW(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, + UIntToPtr(_glfw.win32.foregroundLockTimeout), + SPIF_SENDCHANGE); + + free(_glfw.win32.clipboardString); + + _glfwTerminateJoysticks(); + _glfwTerminateContextAPI(); + terminateLibraries(); +} + +const char* _glfwPlatformGetVersionString(void) +{ + const char* version = _GLFW_VERSION_NUMBER " Win32" +#if defined(_GLFW_WGL) + " WGL" +#elif defined(_GLFW_EGL) + " EGL" +#endif +#if defined(__MINGW32__) + " MinGW" +#elif defined(_MSC_VER) + " VisualC" +#elif defined(__BORLANDC__) + " BorlandC" +#endif +#if defined(_GLFW_BUILD_DLL) + " DLL" +#endif + ; + + return version; +} + diff --git a/testbed/glfw/src/win32_monitor.c b/testbed/glfw/src/win32_monitor.c new file mode 100644 index 00000000..0690dc1f --- /dev/null +++ b/testbed/glfw/src/win32_monitor.c @@ -0,0 +1,348 @@ +//======================================================================== +// GLFW 3.1 Win32 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2010 Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include "internal.h" + +#include +#include +#include +#include + +// These constants are missing on MinGW +#ifndef EDS_ROTATEDMODE + #define EDS_ROTATEDMODE 0x00000004 +#endif +#ifndef DISPLAY_DEVICE_ACTIVE + #define DISPLAY_DEVICE_ACTIVE 0x00000001 +#endif + + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +// Change the current video mode +// +GLboolean _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired) +{ + GLFWvidmode current; + const GLFWvidmode* best; + DEVMODEW dm; + + best = _glfwChooseVideoMode(monitor, desired); + _glfwPlatformGetVideoMode(monitor, ¤t); + if (_glfwCompareVideoModes(¤t, best) == 0) + return GL_TRUE; + + ZeroMemory(&dm, sizeof(dm)); + dm.dmSize = sizeof(DEVMODEW); + dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | + DM_DISPLAYFREQUENCY; + dm.dmPelsWidth = best->width; + dm.dmPelsHeight = best->height; + dm.dmBitsPerPel = best->redBits + best->greenBits + best->blueBits; + dm.dmDisplayFrequency = best->refreshRate; + + if (dm.dmBitsPerPel < 15 || dm.dmBitsPerPel >= 24) + dm.dmBitsPerPel = 32; + + if (ChangeDisplaySettingsExW(monitor->win32.adapterName, + &dm, + NULL, + CDS_FULLSCREEN, + NULL) != DISP_CHANGE_SUCCESSFUL) + { + _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to set video mode"); + return GL_FALSE; + } + + monitor->win32.modeChanged = GL_TRUE; + return GL_TRUE; +} + +// Restore the previously saved (original) video mode +// +void _glfwRestoreVideoMode(_GLFWmonitor* monitor) +{ + if (monitor->win32.modeChanged) + { + ChangeDisplaySettingsExW(monitor->win32.adapterName, + NULL, NULL, CDS_FULLSCREEN, NULL); + monitor->win32.modeChanged = GL_FALSE; + } +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +_GLFWmonitor** _glfwPlatformGetMonitors(int* count) +{ + int size = 0, found = 0; + _GLFWmonitor** monitors = NULL; + DWORD adapterIndex, displayIndex; + + *count = 0; + + for (adapterIndex = 0; ; adapterIndex++) + { + DISPLAY_DEVICEW adapter; + + ZeroMemory(&adapter, sizeof(DISPLAY_DEVICEW)); + adapter.cb = sizeof(DISPLAY_DEVICEW); + + if (!EnumDisplayDevicesW(NULL, adapterIndex, &adapter, 0)) + break; + + if (!(adapter.StateFlags & DISPLAY_DEVICE_ACTIVE)) + continue; + + for (displayIndex = 0; ; displayIndex++) + { + DISPLAY_DEVICEW display; + char* name; + HDC dc; + + ZeroMemory(&display, sizeof(DISPLAY_DEVICEW)); + display.cb = sizeof(DISPLAY_DEVICEW); + + if (!EnumDisplayDevicesW(adapter.DeviceName, displayIndex, &display, 0)) + break; + + if (found == size) + { + size += 4; + monitors = realloc(monitors, sizeof(_GLFWmonitor*) * size); + } + + name = _glfwCreateUTF8FromWideString(display.DeviceString); + if (!name) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Failed to convert string to UTF-8"); + continue; + } + + dc = CreateDCW(L"DISPLAY", adapter.DeviceName, NULL, NULL); + + monitors[found] = _glfwAllocMonitor(name, + GetDeviceCaps(dc, HORZSIZE), + GetDeviceCaps(dc, VERTSIZE)); + + DeleteDC(dc); + free(name); + + wcscpy(monitors[found]->win32.adapterName, adapter.DeviceName); + wcscpy(monitors[found]->win32.displayName, display.DeviceName); + + WideCharToMultiByte(CP_UTF8, 0, + adapter.DeviceName, -1, + monitors[found]->win32.publicAdapterName, + sizeof(monitors[found]->win32.publicAdapterName), + NULL, NULL); + + WideCharToMultiByte(CP_UTF8, 0, + display.DeviceName, -1, + monitors[found]->win32.publicDisplayName, + sizeof(monitors[found]->win32.publicDisplayName), + NULL, NULL); + + if (adapter.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE && + displayIndex == 0) + { + _GLFW_SWAP_POINTERS(monitors[0], monitors[found]); + } + + found++; + } + } + + *count = found; + return monitors; +} + +GLboolean _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second) +{ + return wcscmp(first->win32.displayName, second->win32.displayName) == 0; +} + +void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos) +{ + DEVMODEW settings; + ZeroMemory(&settings, sizeof(DEVMODEW)); + settings.dmSize = sizeof(DEVMODEW); + + EnumDisplaySettingsExW(monitor->win32.adapterName, + ENUM_CURRENT_SETTINGS, + &settings, + EDS_ROTATEDMODE); + + if (xpos) + *xpos = settings.dmPosition.x; + if (ypos) + *ypos = settings.dmPosition.y; +} + +GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found) +{ + int modeIndex = 0, count = 0; + GLFWvidmode* result = NULL; + + *found = 0; + + for (;;) + { + int i; + GLFWvidmode mode; + DEVMODEW dm; + + ZeroMemory(&dm, sizeof(DEVMODEW)); + dm.dmSize = sizeof(DEVMODEW); + + if (!EnumDisplaySettingsW(monitor->win32.adapterName, modeIndex, &dm)) + break; + + modeIndex++; + + if (dm.dmBitsPerPel < 15) + { + // Skip modes with less than 15 BPP + continue; + } + + mode.width = dm.dmPelsWidth; + mode.height = dm.dmPelsHeight; + mode.refreshRate = dm.dmDisplayFrequency; + _glfwSplitBPP(dm.dmBitsPerPel, + &mode.redBits, + &mode.greenBits, + &mode.blueBits); + + for (i = 0; i < *found; i++) + { + if (_glfwCompareVideoModes(result + i, &mode) == 0) + break; + } + + if (i < *found) + { + // This is a duplicate, so skip it + continue; + } + + if (*found == count) + { + if (count) + count *= 2; + else + count = 128; + + result = (GLFWvidmode*) realloc(result, count * sizeof(GLFWvidmode)); + } + + result[*found] = mode; + (*found)++; + } + + return result; +} + +void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) +{ + DEVMODEW dm; + + ZeroMemory(&dm, sizeof(DEVMODEW)); + dm.dmSize = sizeof(DEVMODEW); + + EnumDisplaySettingsW(monitor->win32.adapterName, ENUM_CURRENT_SETTINGS, &dm); + + mode->width = dm.dmPelsWidth; + mode->height = dm.dmPelsHeight; + mode->refreshRate = dm.dmDisplayFrequency; + _glfwSplitBPP(dm.dmBitsPerPel, + &mode->redBits, + &mode->greenBits, + &mode->blueBits); +} + +void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) +{ + HDC dc; + WORD values[768]; + + dc = CreateDCW(L"DISPLAY", monitor->win32.adapterName, NULL, NULL); + GetDeviceGammaRamp(dc, values); + DeleteDC(dc); + + _glfwAllocGammaArrays(ramp, 256); + + memcpy(ramp->red, values + 0, 256 * sizeof(unsigned short)); + memcpy(ramp->green, values + 256, 256 * sizeof(unsigned short)); + memcpy(ramp->blue, values + 512, 256 * sizeof(unsigned short)); +} + +void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) +{ + HDC dc; + WORD values[768]; + + if (ramp->size != 256) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Win32: Gamma ramp size must be 256"); + return; + } + + memcpy(values + 0, ramp->red, 256 * sizeof(unsigned short)); + memcpy(values + 256, ramp->green, 256 * sizeof(unsigned short)); + memcpy(values + 512, ramp->blue, 256 * sizeof(unsigned short)); + + dc = CreateDCW(L"DISPLAY", monitor->win32.adapterName, NULL, NULL); + SetDeviceGammaRamp(dc, values); + DeleteDC(dc); +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW native API ////// +////////////////////////////////////////////////////////////////////////// + +GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* handle) +{ + _GLFWmonitor* monitor = (_GLFWmonitor*) handle; + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + return monitor->win32.publicAdapterName; +} + +GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* handle) +{ + _GLFWmonitor* monitor = (_GLFWmonitor*) handle; + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + return monitor->win32.publicDisplayName; +} + diff --git a/testbed/glfw/src/win32_platform.h b/testbed/glfw/src/win32_platform.h new file mode 100644 index 00000000..861d2bc3 --- /dev/null +++ b/testbed/glfw/src/win32_platform.h @@ -0,0 +1,250 @@ +//======================================================================== +// GLFW 3.1 Win32 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2010 Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#ifndef _win32_platform_h_ +#define _win32_platform_h_ + + +// We don't need all the fancy stuff +#ifndef NOMINMAX + #define NOMINMAX +#endif + +#ifndef VC_EXTRALEAN + #define VC_EXTRALEAN +#endif + +#ifndef WIN32_LEAN_AND_MEAN + #define WIN32_LEAN_AND_MEAN +#endif + +// This is a workaround for the fact that glfw3.h needs to export APIENTRY (for +// example to allow applications to correctly declare a GL_ARB_debug_output +// callback) but windows.h assumes no one will define APIENTRY before it does +#undef APIENTRY + +// GLFW on Windows is Unicode only and does not work in MBCS mode +#ifndef UNICODE + #define UNICODE +#endif + +// GLFW requires Windows XP or later +#if WINVER < 0x0501 + #undef WINVER + #define WINVER 0x0501 +#endif +#if _WIN32_WINNT < 0x0501 + #undef _WIN32_WINNT + #define _WIN32_WINNT 0x0501 +#endif + +#include +#include +#include + +#if defined(_MSC_VER) + #include + #define strdup _strdup +#endif + + +// HACK: Define macros that some older windows.h variants don't + +#ifndef WM_MOUSEHWHEEL + #define WM_MOUSEHWHEEL 0x020E +#endif +#ifndef WM_DWMCOMPOSITIONCHANGED + #define WM_DWMCOMPOSITIONCHANGED 0x031E +#endif +#ifndef WM_COPYGLOBALDATA + #define WM_COPYGLOBALDATA 0x0049 +#endif +#ifndef WM_UNICHAR + #define WM_UNICHAR 0x0109 +#endif +#ifndef UNICODE_NOCHAR + #define UNICODE_NOCHAR 0xFFFF +#endif + +#if WINVER < 0x0601 +typedef struct tagCHANGEFILTERSTRUCT +{ + DWORD cbSize; + DWORD ExtStatus; + +} CHANGEFILTERSTRUCT, *PCHANGEFILTERSTRUCT; +#ifndef MSGFLT_ALLOW + #define MSGFLT_ALLOW 1 +#endif +#endif /*Windows 7*/ + + +// winmm.dll function pointer typedefs +typedef MMRESULT (WINAPI * JOYGETDEVCAPS_T)(UINT,LPJOYCAPS,UINT); +typedef MMRESULT (WINAPI * JOYGETPOS_T)(UINT,LPJOYINFO); +typedef MMRESULT (WINAPI * JOYGETPOSEX_T)(UINT,LPJOYINFOEX); +typedef DWORD (WINAPI * TIMEGETTIME_T)(void); +#define _glfw_joyGetDevCaps _glfw.win32.winmm.joyGetDevCaps +#define _glfw_joyGetPos _glfw.win32.winmm.joyGetPos +#define _glfw_joyGetPosEx _glfw.win32.winmm.joyGetPosEx +#define _glfw_timeGetTime _glfw.win32.winmm.timeGetTime + +// user32.dll function pointer typedefs +typedef BOOL (WINAPI * SETPROCESSDPIAWARE_T)(void); +typedef BOOL (WINAPI * CHANGEWINDOWMESSAGEFILTEREX_T)(HWND,UINT,DWORD,PCHANGEFILTERSTRUCT); +#define _glfw_SetProcessDPIAware _glfw.win32.user32.SetProcessDPIAware +#define _glfw_ChangeWindowMessageFilterEx _glfw.win32.user32.ChangeWindowMessageFilterEx + +// dwmapi.dll function pointer typedefs +typedef HRESULT (WINAPI * DWMISCOMPOSITIONENABLED_T)(BOOL*); +#define _glfw_DwmIsCompositionEnabled _glfw.win32.dwmapi.DwmIsCompositionEnabled + + +#define _GLFW_RECREATION_NOT_NEEDED 0 +#define _GLFW_RECREATION_REQUIRED 1 +#define _GLFW_RECREATION_IMPOSSIBLE 2 + + +#include "win32_tls.h" + +#if defined(_GLFW_WGL) + #include "wgl_context.h" +#elif defined(_GLFW_EGL) + #define _GLFW_EGL_NATIVE_WINDOW window->win32.handle + #define _GLFW_EGL_NATIVE_DISPLAY EGL_DEFAULT_DISPLAY + #include "egl_context.h" +#else + #error "No supported context creation API selected" +#endif + +#include "winmm_joystick.h" + +#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowWin32 win32 +#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryWin32 win32 +#define _GLFW_PLATFORM_LIBRARY_TIME_STATE _GLFWtimeWin32 win32_time +#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorWin32 win32 +#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorWin32 win32 + + +// Win32-specific per-window data +// +typedef struct _GLFWwindowWin32 +{ + HWND handle; + DWORD dwStyle; + DWORD dwExStyle; + + GLboolean cursorInside; + GLboolean iconified; + + // The last received cursor position, regardless of source + int cursorPosX, cursorPosY; + +} _GLFWwindowWin32; + + +// Win32-specific global data +// +typedef struct _GLFWlibraryWin32 +{ + DWORD foregroundLockTimeout; + char* clipboardString; + short int publicKeys[512]; + + // winmm.dll + struct { + HINSTANCE instance; + JOYGETDEVCAPS_T joyGetDevCaps; + JOYGETPOS_T joyGetPos; + JOYGETPOSEX_T joyGetPosEx; + TIMEGETTIME_T timeGetTime; + } winmm; + + // user32.dll + struct { + HINSTANCE instance; + SETPROCESSDPIAWARE_T SetProcessDPIAware; + CHANGEWINDOWMESSAGEFILTEREX_T ChangeWindowMessageFilterEx; + } user32; + + // dwmapi.dll + struct { + HINSTANCE instance; + DWMISCOMPOSITIONENABLED_T DwmIsCompositionEnabled; + } dwmapi; + +} _GLFWlibraryWin32; + + +// Win32-specific per-monitor data +// +typedef struct _GLFWmonitorWin32 +{ + // This size matches the static size of DISPLAY_DEVICE.DeviceName + WCHAR adapterName[32]; + WCHAR displayName[32]; + char publicAdapterName[64]; + char publicDisplayName[64]; + GLboolean modeChanged; + +} _GLFWmonitorWin32; + + +// Win32-specific per-cursor data +// +typedef struct _GLFWcursorWin32 +{ + HCURSOR handle; + +} _GLFWcursorWin32; + + +// Win32-specific global timer data +// +typedef struct _GLFWtimeWin32 +{ + GLboolean hasPC; + double resolution; + unsigned __int64 base; + +} _GLFWtimeWin32; + + +GLboolean _glfwRegisterWindowClass(void); +void _glfwUnregisterWindowClass(void); + +BOOL _glfwIsCompositionEnabled(void); + +WCHAR* _glfwCreateWideStringFromUTF8(const char* source); +char* _glfwCreateUTF8FromWideString(const WCHAR* source); + +void _glfwInitTimer(void); + +GLboolean _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired); +void _glfwRestoreVideoMode(_GLFWmonitor* monitor); + +#endif // _win32_platform_h_ diff --git a/testbed/glfw/src/win32_time.c b/testbed/glfw/src/win32_time.c new file mode 100644 index 00000000..5f7adf8f --- /dev/null +++ b/testbed/glfw/src/win32_time.c @@ -0,0 +1,86 @@ +//======================================================================== +// GLFW 3.1 Win32 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2010 Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include "internal.h" + + +// Return raw time +// +static unsigned __int64 getRawTime(void) +{ + if (_glfw.win32_time.hasPC) + { + unsigned __int64 time; + QueryPerformanceCounter((LARGE_INTEGER*) &time); + return time; + } + else + return (unsigned __int64) _glfw_timeGetTime(); +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +// Initialise timer +// +void _glfwInitTimer(void) +{ + unsigned __int64 frequency; + + if (QueryPerformanceFrequency((LARGE_INTEGER*) &frequency)) + { + _glfw.win32_time.hasPC = GL_TRUE; + _glfw.win32_time.resolution = 1.0 / (double) frequency; + } + else + { + _glfw.win32_time.hasPC = GL_FALSE; + _glfw.win32_time.resolution = 0.001; // winmm resolution is 1 ms + } + + _glfw.win32_time.base = getRawTime(); +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +double _glfwPlatformGetTime(void) +{ + return (double) (getRawTime() - _glfw.win32_time.base) * + _glfw.win32_time.resolution; +} + +void _glfwPlatformSetTime(double time) +{ + _glfw.win32_time.base = getRawTime() - + (unsigned __int64) (time / _glfw.win32_time.resolution); +} + diff --git a/testbed/glfw/src/win32_tls.c b/testbed/glfw/src/win32_tls.c new file mode 100644 index 00000000..088e25df --- /dev/null +++ b/testbed/glfw/src/win32_tls.c @@ -0,0 +1,69 @@ +//======================================================================== +// GLFW 3.1 Win32 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2010 Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include "internal.h" + + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +int _glfwInitTLS(void) +{ + _glfw.win32_tls.context = TlsAlloc(); + if (_glfw.win32_tls.context == TLS_OUT_OF_INDEXES) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Win32: Failed to allocate TLS index"); + return GL_FALSE; + } + + _glfw.win32_tls.allocated = GL_TRUE; + return GL_TRUE; +} + +void _glfwTerminateTLS(void) +{ + if (_glfw.win32_tls.allocated) + TlsFree(_glfw.win32_tls.context); +} + +void _glfwSetCurrentContext(_GLFWwindow* context) +{ + TlsSetValue(_glfw.win32_tls.context, context); +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +_GLFWwindow* _glfwPlatformGetCurrentContext(void) +{ + return TlsGetValue(_glfw.win32_tls.context); +} + diff --git a/testbed/glfw/src/win32_tls.h b/testbed/glfw/src/win32_tls.h new file mode 100644 index 00000000..3ffef725 --- /dev/null +++ b/testbed/glfw/src/win32_tls.h @@ -0,0 +1,48 @@ +//======================================================================== +// GLFW 3.1 Win32 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2010 Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#ifndef _win32_tls_h_ +#define _win32_tls_h_ + +#define _GLFW_PLATFORM_LIBRARY_TLS_STATE _GLFWtlsWin32 win32_tls + + +// Win32-specific global TLS data +// +typedef struct _GLFWtlsWin32 +{ + GLboolean allocated; + DWORD context; + +} _GLFWtlsWin32; + + +int _glfwInitTLS(void); +void _glfwTerminateTLS(void); +void _glfwSetCurrentContext(_GLFWwindow* context); + +#endif // _win32_tls_h_ diff --git a/testbed/glfw/src/win32_window.c b/testbed/glfw/src/win32_window.c new file mode 100644 index 00000000..176ed596 --- /dev/null +++ b/testbed/glfw/src/win32_window.c @@ -0,0 +1,1312 @@ +//======================================================================== +// GLFW 3.1 Win32 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2010 Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include "internal.h" + +#include +#include +#include +#include +#include + +#define _GLFW_KEY_INVALID -2 + +#define _GLFW_WNDCLASSNAME L"GLFW30" + + +// Updates the cursor clip rect +// +static void updateClipRect(_GLFWwindow* window) +{ + RECT clipRect; + GetClientRect(window->win32.handle, &clipRect); + ClientToScreen(window->win32.handle, (POINT*) &clipRect.left); + ClientToScreen(window->win32.handle, (POINT*) &clipRect.right); + ClipCursor(&clipRect); +} + +// Hide the mouse cursor +// +static void hideCursor(_GLFWwindow* window) +{ + POINT pos; + + ClipCursor(NULL); + + if (GetCursorPos(&pos)) + { + if (WindowFromPoint(pos) == window->win32.handle) + SetCursor(NULL); + } +} + +// Disable the mouse cursor +// +static void disableCursor(_GLFWwindow* window) +{ + POINT pos; + + updateClipRect(window); + + if (GetCursorPos(&pos)) + { + if (WindowFromPoint(pos) == window->win32.handle) + SetCursor(NULL); + } +} + +// Restores the mouse cursor +// +static void restoreCursor(_GLFWwindow* window) +{ + POINT pos; + + ClipCursor(NULL); + + if (GetCursorPos(&pos)) + { + if (WindowFromPoint(pos) == window->win32.handle) + { + if (window->cursor) + SetCursor(window->cursor->win32.handle); + else + SetCursor(LoadCursorW(NULL, IDC_ARROW)); + } + } +} + +// Translates a GLFW standard cursor to a resource ID +// +static LPWSTR translateCursorShape(int shape) +{ + switch (shape) + { + case GLFW_ARROW_CURSOR: + return IDC_ARROW; + case GLFW_IBEAM_CURSOR: + return IDC_IBEAM; + case GLFW_CROSSHAIR_CURSOR: + return IDC_CROSS; + case GLFW_HAND_CURSOR: + return IDC_HAND; + case GLFW_HRESIZE_CURSOR: + return IDC_SIZEWE; + case GLFW_VRESIZE_CURSOR: + return IDC_SIZENS; + } + + return NULL; +} + +// Retrieves and translates modifier keys +// +static int getKeyMods(void) +{ + int mods = 0; + + if (GetKeyState(VK_SHIFT) & (1 << 31)) + mods |= GLFW_MOD_SHIFT; + if (GetKeyState(VK_CONTROL) & (1 << 31)) + mods |= GLFW_MOD_CONTROL; + if (GetKeyState(VK_MENU) & (1 << 31)) + mods |= GLFW_MOD_ALT; + if ((GetKeyState(VK_LWIN) | GetKeyState(VK_RWIN)) & (1 << 31)) + mods |= GLFW_MOD_SUPER; + + return mods; +} + +// Retrieves and translates modifier keys +// +static int getAsyncKeyMods(void) +{ + int mods = 0; + + if (GetAsyncKeyState(VK_SHIFT) & (1 << 31)) + mods |= GLFW_MOD_SHIFT; + if (GetAsyncKeyState(VK_CONTROL) & (1 << 31)) + mods |= GLFW_MOD_CONTROL; + if (GetAsyncKeyState(VK_MENU) & (1 << 31)) + mods |= GLFW_MOD_ALT; + if ((GetAsyncKeyState(VK_LWIN) | GetAsyncKeyState(VK_RWIN)) & (1 << 31)) + mods |= GLFW_MOD_SUPER; + + return mods; +} + +// Translates a Windows key to the corresponding GLFW key +// +static int translateKey(WPARAM wParam, LPARAM lParam) +{ + if (wParam == VK_CONTROL) + { + // The CTRL keys require special handling + + MSG next; + DWORD time; + + // Is this an extended key (i.e. right key)? + if (lParam & 0x01000000) + return GLFW_KEY_RIGHT_CONTROL; + + // Here is a trick: "Alt Gr" sends LCTRL, then RALT. We only + // want the RALT message, so we try to see if the next message + // is a RALT message. In that case, this is a false LCTRL! + time = GetMessageTime(); + + if (PeekMessageW(&next, NULL, 0, 0, PM_NOREMOVE)) + { + if (next.message == WM_KEYDOWN || + next.message == WM_SYSKEYDOWN || + next.message == WM_KEYUP || + next.message == WM_SYSKEYUP) + { + if (next.wParam == VK_MENU && + (next.lParam & 0x01000000) && + next.time == time) + { + // Next message is a RALT down message, which + // means that this is not a proper LCTRL message + return _GLFW_KEY_INVALID; + } + } + } + + return GLFW_KEY_LEFT_CONTROL; + } + + return _glfw.win32.publicKeys[HIWORD(lParam) & 0x1FF]; +} + +// Enter full screen mode +// +static GLboolean enterFullscreenMode(_GLFWwindow* window) +{ + GLFWvidmode mode; + GLboolean status; + int xpos, ypos; + + status = _glfwSetVideoMode(window->monitor, &window->videoMode); + + _glfwPlatformGetVideoMode(window->monitor, &mode); + _glfwPlatformGetMonitorPos(window->monitor, &xpos, &ypos); + + SetWindowPos(window->win32.handle, HWND_TOPMOST, + xpos, ypos, mode.width, mode.height, SWP_NOCOPYBITS); + + return status; +} + +// Leave full screen mode +// +static void leaveFullscreenMode(_GLFWwindow* window) +{ + _glfwRestoreVideoMode(window->monitor); +} + +// Window callback function (handles window events) +// +static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, + WPARAM wParam, LPARAM lParam) +{ + _GLFWwindow* window = (_GLFWwindow*) GetWindowLongPtrW(hWnd, 0); + + switch (uMsg) + { + case WM_NCCREATE: + { + CREATESTRUCTW* cs = (CREATESTRUCTW*) lParam; + SetWindowLongPtrW(hWnd, 0, (LONG_PTR) cs->lpCreateParams); + break; + } + + case WM_SETFOCUS: + { + if (window->cursorMode != GLFW_CURSOR_NORMAL) + _glfwPlatformApplyCursorMode(window); + + if (window->monitor && window->autoIconify) + enterFullscreenMode(window); + + _glfwInputWindowFocus(window, GL_TRUE); + return 0; + } + + case WM_KILLFOCUS: + { + if (window->cursorMode != GLFW_CURSOR_NORMAL) + restoreCursor(window); + + if (window->monitor && window->autoIconify) + { + _glfwPlatformIconifyWindow(window); + leaveFullscreenMode(window); + } + + _glfwInputWindowFocus(window, GL_FALSE); + return 0; + } + + case WM_SYSCOMMAND: + { + switch (wParam & 0xfff0) + { + case SC_SCREENSAVE: + case SC_MONITORPOWER: + { + if (window->monitor) + { + // We are running in full screen mode, so disallow + // screen saver and screen blanking + return 0; + } + else + break; + } + + // User trying to access application menu using ALT? + case SC_KEYMENU: + return 0; + } + break; + } + + case WM_CLOSE: + { + _glfwInputWindowCloseRequest(window); + return 0; + } + + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + { + const int scancode = (lParam >> 16) & 0x1ff; + const int key = translateKey(wParam, lParam); + if (key == _GLFW_KEY_INVALID) + break; + + _glfwInputKey(window, key, scancode, GLFW_PRESS, getKeyMods()); + break; + } + + case WM_CHAR: + { + _glfwInputChar(window, (unsigned int) wParam, getKeyMods(), GL_TRUE); + return 0; + } + + case WM_SYSCHAR: + { + _glfwInputChar(window, (unsigned int) wParam, getKeyMods(), GL_FALSE); + return 0; + } + + case WM_UNICHAR: + { + // This message is not sent by Windows, but is sent by some + // third-party input method engines + + if (wParam == UNICODE_NOCHAR) + { + // Returning TRUE here announces support for this message + return TRUE; + } + + _glfwInputChar(window, (unsigned int) wParam, getKeyMods(), GL_TRUE); + return FALSE; + } + + case WM_KEYUP: + case WM_SYSKEYUP: + { + const int mods = getKeyMods(); + const int scancode = (lParam >> 16) & 0x1ff; + const int key = translateKey(wParam, lParam); + if (key == _GLFW_KEY_INVALID) + break; + + if (wParam == VK_SHIFT) + { + // Release both Shift keys on Shift up event, as only one event + // is sent even if both keys are released + _glfwInputKey(window, GLFW_KEY_LEFT_SHIFT, scancode, GLFW_RELEASE, mods); + _glfwInputKey(window, GLFW_KEY_RIGHT_SHIFT, scancode, GLFW_RELEASE, mods); + } + else if (wParam == VK_SNAPSHOT) + { + // Key down is not reported for the print screen key + _glfwInputKey(window, key, scancode, GLFW_PRESS, mods); + _glfwInputKey(window, key, scancode, GLFW_RELEASE, mods); + } + else + _glfwInputKey(window, key, scancode, GLFW_RELEASE, mods); + + break; + } + + case WM_LBUTTONDOWN: + case WM_RBUTTONDOWN: + case WM_MBUTTONDOWN: + case WM_XBUTTONDOWN: + { + const int mods = getKeyMods(); + + SetCapture(hWnd); + + if (uMsg == WM_LBUTTONDOWN) + _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS, mods); + else if (uMsg == WM_RBUTTONDOWN) + _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS, mods); + else if (uMsg == WM_MBUTTONDOWN) + _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_MIDDLE, GLFW_PRESS, mods); + else + { + if (HIWORD(wParam) == XBUTTON1) + _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_4, GLFW_PRESS, mods); + else if (HIWORD(wParam) == XBUTTON2) + _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_5, GLFW_PRESS, mods); + + return TRUE; + } + + return 0; + } + + case WM_LBUTTONUP: + case WM_RBUTTONUP: + case WM_MBUTTONUP: + case WM_XBUTTONUP: + { + const int mods = getKeyMods(); + + ReleaseCapture(); + + if (uMsg == WM_LBUTTONUP) + _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_RELEASE, mods); + else if (uMsg == WM_RBUTTONUP) + _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_RIGHT, GLFW_RELEASE, mods); + else if (uMsg == WM_MBUTTONUP) + _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_MIDDLE, GLFW_RELEASE, mods); + else + { + if (HIWORD(wParam) == XBUTTON1) + _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_4, GLFW_RELEASE, mods); + else if (HIWORD(wParam) == XBUTTON2) + _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_5, GLFW_RELEASE, mods); + + return TRUE; + } + + return 0; + } + + case WM_MOUSEMOVE: + { + const int x = GET_X_LPARAM(lParam); + const int y = GET_Y_LPARAM(lParam); + + if (window->cursorMode == GLFW_CURSOR_DISABLED) + { + if (_glfw.focusedWindow != window) + break; + + _glfwInputCursorMotion(window, + x - window->win32.cursorPosX, + y - window->win32.cursorPosY); + } + else + _glfwInputCursorMotion(window, x, y); + + window->win32.cursorPosX = x; + window->win32.cursorPosY = y; + + if (!window->win32.cursorInside) + { + TRACKMOUSEEVENT tme; + ZeroMemory(&tme, sizeof(tme)); + tme.cbSize = sizeof(tme); + tme.dwFlags = TME_LEAVE; + tme.hwndTrack = window->win32.handle; + TrackMouseEvent(&tme); + + window->win32.cursorInside = GL_TRUE; + _glfwInputCursorEnter(window, GL_TRUE); + } + + return 0; + } + + case WM_MOUSELEAVE: + { + window->win32.cursorInside = GL_FALSE; + _glfwInputCursorEnter(window, GL_FALSE); + return 0; + } + + case WM_MOUSEWHEEL: + { + _glfwInputScroll(window, 0.0, (SHORT) HIWORD(wParam) / (double) WHEEL_DELTA); + return 0; + } + + case WM_MOUSEHWHEEL: + { + // This message is only sent on Windows Vista and later + // NOTE: The X-axis is inverted for consistency with OS X and X11. + _glfwInputScroll(window, -((SHORT) HIWORD(wParam) / (double) WHEEL_DELTA), 0.0); + return 0; + } + + case WM_SIZE: + { + if (_glfw.focusedWindow == window) + { + if (window->cursorMode == GLFW_CURSOR_DISABLED) + updateClipRect(window); + } + + if (!window->win32.iconified && wParam == SIZE_MINIMIZED) + { + window->win32.iconified = GL_TRUE; + _glfwInputWindowIconify(window, GL_TRUE); + } + else if (window->win32.iconified && + (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED)) + { + window->win32.iconified = GL_FALSE; + _glfwInputWindowIconify(window, GL_FALSE); + } + + _glfwInputFramebufferSize(window, LOWORD(lParam), HIWORD(lParam)); + _glfwInputWindowSize(window, LOWORD(lParam), HIWORD(lParam)); + return 0; + } + + case WM_MOVE: + { + if (_glfw.focusedWindow == window) + { + if (window->cursorMode == GLFW_CURSOR_DISABLED) + updateClipRect(window); + } + + // NOTE: This cannot use LOWORD/HIWORD recommended by MSDN, as + // those macros do not handle negative window positions correctly + _glfwInputWindowPos(window, + GET_X_LPARAM(lParam), + GET_Y_LPARAM(lParam)); + return 0; + } + + case WM_PAINT: + { + _glfwInputWindowDamage(window); + break; + } + + case WM_ERASEBKGND: + { + return TRUE; + } + + case WM_SETCURSOR: + { + if (_glfw.focusedWindow == window && LOWORD(lParam) == HTCLIENT) + { + if (window->cursorMode == GLFW_CURSOR_HIDDEN || + window->cursorMode == GLFW_CURSOR_DISABLED) + { + SetCursor(NULL); + return TRUE; + } + else if (window->cursor) + { + SetCursor(window->cursor->win32.handle); + return TRUE; + } + } + + break; + } + + case WM_DEVICECHANGE: + { + if (DBT_DEVNODES_CHANGED == wParam) + { + _glfwInputMonitorChange(); + return TRUE; + } + break; + } + + case WM_DWMCOMPOSITIONCHANGED: + { + if (_glfwIsCompositionEnabled()) + { + _GLFWwindow* previous = _glfwPlatformGetCurrentContext(); + _glfwPlatformMakeContextCurrent(window); + _glfwPlatformSwapInterval(0); + _glfwPlatformMakeContextCurrent(previous); + } + + // TODO: Restore vsync if compositing was disabled + break; + } + + case WM_DROPFILES: + { + HDROP hDrop = (HDROP) wParam; + POINT pt; + int i; + + const int count = DragQueryFileW(hDrop, 0xffffffff, NULL, 0); + char** names = calloc(count, sizeof(char*)); + + // Move the mouse to the position of the drop + DragQueryPoint(hDrop, &pt); + _glfwInputCursorMotion(window, pt.x, pt.y); + + for (i = 0; i < count; i++) + { + const UINT length = DragQueryFileW(hDrop, i, NULL, 0); + WCHAR* buffer = calloc(length + 1, sizeof(WCHAR)); + + DragQueryFileW(hDrop, i, buffer, length + 1); + names[i] = _glfwCreateUTF8FromWideString(buffer); + + free(buffer); + } + + _glfwInputDrop(window, count, (const char**) names); + + for (i = 0; i < count; i++) + free(names[i]); + free(names); + + DragFinish(hDrop); + return 0; + } + } + + return DefWindowProc(hWnd, uMsg, wParam, lParam); +} + +// Translate client window size to full window size (including window borders) +// +static void getFullWindowSize(_GLFWwindow* window, + int clientWidth, int clientHeight, + int* fullWidth, int* fullHeight) +{ + RECT rect = { 0, 0, clientWidth, clientHeight }; + AdjustWindowRectEx(&rect, window->win32.dwStyle, + FALSE, window->win32.dwExStyle); + *fullWidth = rect.right - rect.left; + *fullHeight = rect.bottom - rect.top; +} + +// Creates the GLFW window and rendering context +// +static int createWindow(_GLFWwindow* window, + const _GLFWwndconfig* wndconfig, + const _GLFWctxconfig* ctxconfig, + const _GLFWfbconfig* fbconfig) +{ + int xpos, ypos, fullWidth, fullHeight; + WCHAR* wideTitle; + + window->win32.dwStyle = WS_CLIPSIBLINGS | WS_CLIPCHILDREN; + window->win32.dwExStyle = WS_EX_APPWINDOW; + + if (window->monitor) + { + window->win32.dwStyle |= WS_POPUP; + + // NOTE: This window placement is temporary and approximate, as the + // correct position and size cannot be known until the monitor + // video mode has been set + _glfwPlatformGetMonitorPos(wndconfig->monitor, &xpos, &ypos); + fullWidth = wndconfig->width; + fullHeight = wndconfig->height; + } + else + { + if (wndconfig->decorated) + { + window->win32.dwStyle |= WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX; + + if (wndconfig->resizable) + { + window->win32.dwStyle |= WS_MAXIMIZEBOX | WS_SIZEBOX; + window->win32.dwExStyle |= WS_EX_WINDOWEDGE; + } + } + else + window->win32.dwStyle |= WS_POPUP; + + xpos = CW_USEDEFAULT; + ypos = CW_USEDEFAULT; + + getFullWindowSize(window, + wndconfig->width, wndconfig->height, + &fullWidth, &fullHeight); + } + + wideTitle = _glfwCreateWideStringFromUTF8(wndconfig->title); + if (!wideTitle) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Win32: Failed to convert title to wide string"); + return GL_FALSE; + } + + window->win32.handle = CreateWindowExW(window->win32.dwExStyle, + _GLFW_WNDCLASSNAME, + wideTitle, + window->win32.dwStyle, + xpos, ypos, + fullWidth, fullHeight, + NULL, // No parent window + NULL, // No window menu + GetModuleHandleW(NULL), + window); // Pass object to WM_CREATE + + free(wideTitle); + + if (!window->win32.handle) + { + _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to create window"); + return GL_FALSE; + } + + if (_glfw_ChangeWindowMessageFilterEx) + { + _glfw_ChangeWindowMessageFilterEx(window->win32.handle, + WM_DROPFILES, MSGFLT_ALLOW, NULL); + _glfw_ChangeWindowMessageFilterEx(window->win32.handle, + WM_COPYDATA, MSGFLT_ALLOW, NULL); + _glfw_ChangeWindowMessageFilterEx(window->win32.handle, + WM_COPYGLOBALDATA, MSGFLT_ALLOW, NULL); + } + + if (wndconfig->floating && !wndconfig->monitor) + { + SetWindowPos(window->win32.handle, + HWND_TOPMOST, + 0, 0, 0, 0, + SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); + } + + DragAcceptFiles(window->win32.handle, TRUE); + + if (!_glfwCreateContext(window, ctxconfig, fbconfig)) + return GL_FALSE; + + return GL_TRUE; +} + +// Destroys the GLFW window and rendering context +// +static void destroyWindow(_GLFWwindow* window) +{ + _glfwDestroyContext(window); + + if (window->win32.handle) + { + DestroyWindow(window->win32.handle); + window->win32.handle = NULL; + } +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +// Registers the GLFW window class +// +GLboolean _glfwRegisterWindowClass(void) +{ + WNDCLASSW wc; + + wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; + wc.lpfnWndProc = (WNDPROC) windowProc; + wc.cbClsExtra = 0; // No extra class data + wc.cbWndExtra = sizeof(void*) + sizeof(int); // Make room for one pointer + wc.hInstance = GetModuleHandleW(NULL); + wc.hCursor = LoadCursorW(NULL, IDC_ARROW); + wc.hbrBackground = NULL; // No background + wc.lpszMenuName = NULL; // No menu + wc.lpszClassName = _GLFW_WNDCLASSNAME; + + // Load user-provided icon if available + wc.hIcon = LoadIconW(GetModuleHandleW(NULL), L"GLFW_ICON"); + if (!wc.hIcon) + { + // No user-provided icon found, load default icon + wc.hIcon = LoadIconW(NULL, IDI_WINLOGO); + } + + if (!RegisterClassW(&wc)) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Win32: Failed to register window class"); + return GL_FALSE; + } + + return GL_TRUE; +} + +// Unregisters the GLFW window class +// +void _glfwUnregisterWindowClass(void) +{ + UnregisterClassW(_GLFW_WNDCLASSNAME, GetModuleHandleW(NULL)); +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +int _glfwPlatformCreateWindow(_GLFWwindow* window, + const _GLFWwndconfig* wndconfig, + const _GLFWctxconfig* ctxconfig, + const _GLFWfbconfig* fbconfig) +{ + int status; + + if (!createWindow(window, wndconfig, ctxconfig, fbconfig)) + return GL_FALSE; + + status = _glfwAnalyzeContext(window, ctxconfig, fbconfig); + + if (status == _GLFW_RECREATION_IMPOSSIBLE) + return GL_FALSE; + + if (status == _GLFW_RECREATION_REQUIRED) + { + // Some window hints require us to re-create the context using WGL + // extensions retrieved through the current context, as we cannot check + // for WGL extensions or retrieve WGL entry points before we have a + // current context (actually until we have implicitly loaded the ICD) + + // Yes, this is strange, and yes, this is the proper way on Win32 + + // As Windows only allows you to set the pixel format once for a + // window, we need to destroy the current window and create a new one + // to be able to use the new pixel format + + // Technically, it may be possible to keep the old window around if + // we're just creating an OpenGL 3.0+ context with the same pixel + // format, but it's not worth the added code complexity + + // First we clear the current context (the one we just created) + // This is usually done by glfwDestroyWindow, but as we're not doing + // full GLFW window destruction, it's duplicated here + _glfwPlatformMakeContextCurrent(NULL); + + // Next destroy the Win32 window and WGL context (without resetting or + // destroying the GLFW window object) + destroyWindow(window); + + // ...and then create them again, this time with better APIs + if (!createWindow(window, wndconfig, ctxconfig, fbconfig)) + return GL_FALSE; + } + + if (window->monitor) + { + _glfwPlatformShowWindow(window); + if (!enterFullscreenMode(window)) + return GL_FALSE; + } + + return GL_TRUE; +} + +void _glfwPlatformDestroyWindow(_GLFWwindow* window) +{ + if (window->monitor) + leaveFullscreenMode(window); + + destroyWindow(window); +} + +void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title) +{ + WCHAR* wideTitle = _glfwCreateWideStringFromUTF8(title); + if (!wideTitle) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Win32: Failed to convert title to wide string"); + return; + } + + SetWindowTextW(window->win32.handle, wideTitle); + free(wideTitle); +} + +void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos) +{ + POINT pos = { 0, 0 }; + ClientToScreen(window->win32.handle, &pos); + + if (xpos) + *xpos = pos.x; + if (ypos) + *ypos = pos.y; +} + +void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos) +{ + RECT rect = { xpos, ypos, xpos, ypos }; + AdjustWindowRectEx(&rect, window->win32.dwStyle, + FALSE, window->win32.dwExStyle); + SetWindowPos(window->win32.handle, NULL, rect.left, rect.top, 0, 0, + SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE); +} + +void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height) +{ + RECT area; + GetClientRect(window->win32.handle, &area); + + if (width) + *width = area.right; + if (height) + *height = area.bottom; +} + +void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) +{ + if (window->monitor) + enterFullscreenMode(window); + else + { + int fullWidth, fullHeight; + getFullWindowSize(window, width, height, &fullWidth, &fullHeight); + + SetWindowPos(window->win32.handle, HWND_TOP, + 0, 0, fullWidth, fullHeight, + SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOZORDER); + } +} + +void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height) +{ + _glfwPlatformGetWindowSize(window, width, height); +} + +void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, + int* left, int* top, + int* right, int* bottom) +{ + RECT rect; + int width, height; + + _glfwPlatformGetWindowSize(window, &width, &height); + SetRect(&rect, 0, 0, width, height); + AdjustWindowRectEx(&rect, window->win32.dwStyle, + FALSE, window->win32.dwExStyle); + + if (left) + *left = -rect.left; + if (top) + *top = -rect.top; + if (right) + *right = rect.right - width; + if (bottom) + *bottom = rect.bottom - height; +} + +void _glfwPlatformIconifyWindow(_GLFWwindow* window) +{ + ShowWindow(window->win32.handle, SW_MINIMIZE); +} + +void _glfwPlatformRestoreWindow(_GLFWwindow* window) +{ + ShowWindow(window->win32.handle, SW_RESTORE); +} + +void _glfwPlatformShowWindow(_GLFWwindow* window) +{ + ShowWindow(window->win32.handle, SW_SHOW); + BringWindowToTop(window->win32.handle); + SetForegroundWindow(window->win32.handle); + SetFocus(window->win32.handle); +} + +void _glfwPlatformUnhideWindow(_GLFWwindow* window) +{ + ShowWindow(window->win32.handle, SW_SHOW); +} + +void _glfwPlatformHideWindow(_GLFWwindow* window) +{ + ShowWindow(window->win32.handle, SW_HIDE); +} + +int _glfwPlatformWindowFocused(_GLFWwindow* window) +{ + return window->win32.handle == GetActiveWindow(); +} + +int _glfwPlatformWindowIconified(_GLFWwindow* window) +{ + return IsIconic(window->win32.handle); +} + +int _glfwPlatformWindowVisible(_GLFWwindow* window) +{ + return IsWindowVisible(window->win32.handle); +} + +void _glfwPlatformPollEvents(void) +{ + MSG msg; + _GLFWwindow* window; + + while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) + { + if (msg.message == WM_QUIT) + { + // Treat WM_QUIT as a close on all windows + // While GLFW does not itself post WM_QUIT, other processes may post + // it to this one, for example Task Manager + + window = _glfw.windowListHead; + while (window) + { + _glfwInputWindowCloseRequest(window); + window = window->next; + } + } + else + { + TranslateMessage(&msg); + DispatchMessageW(&msg); + } + } + + window = _glfw.focusedWindow; + if (window) + { + // LSHIFT/RSHIFT fixup (keys tend to "stick" without this fix) + // This is the only async event handling in GLFW, but it solves some + // nasty problems + { + const int mods = getAsyncKeyMods(); + + // Get current state of left and right shift keys + const int lshiftDown = (GetAsyncKeyState(VK_LSHIFT) >> 15) & 1; + const int rshiftDown = (GetAsyncKeyState(VK_RSHIFT) >> 15) & 1; + + // See if this differs from our belief of what has happened + // (we only have to check for lost key up events) + if (!lshiftDown && window->keys[GLFW_KEY_LEFT_SHIFT] == 1) + _glfwInputKey(window, GLFW_KEY_LEFT_SHIFT, 0, GLFW_RELEASE, mods); + + if (!rshiftDown && window->keys[GLFW_KEY_RIGHT_SHIFT] == 1) + _glfwInputKey(window, GLFW_KEY_RIGHT_SHIFT, 0, GLFW_RELEASE, mods); + } + + // Did the cursor move in an focused window that has disabled the cursor + if (window->cursorMode == GLFW_CURSOR_DISABLED) + { + int width, height; + _glfwPlatformGetWindowSize(window, &width, &height); + _glfwPlatformSetCursorPos(window, width / 2, height / 2); + } + } +} + +void _glfwPlatformWaitEvents(void) +{ + WaitMessage(); + + _glfwPlatformPollEvents(); +} + +void _glfwPlatformPostEmptyEvent(void) +{ + _GLFWwindow* window = _glfw.windowListHead; + PostMessage(window->win32.handle, WM_NULL, 0, 0); +} + +void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos) +{ + POINT pos; + + if (GetCursorPos(&pos)) + { + ScreenToClient(window->win32.handle, &pos); + + if (xpos) + *xpos = pos.x; + if (ypos) + *ypos = pos.y; + } +} + +void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos) +{ + POINT pos = { (int) xpos, (int) ypos }; + + // Store the new position so it can be recognized later + window->win32.cursorPosX = pos.x; + window->win32.cursorPosY = pos.y; + + ClientToScreen(window->win32.handle, &pos); + SetCursorPos(pos.x, pos.y); +} + +void _glfwPlatformApplyCursorMode(_GLFWwindow* window) +{ + switch (window->cursorMode) + { + case GLFW_CURSOR_NORMAL: + restoreCursor(window); + break; + case GLFW_CURSOR_HIDDEN: + hideCursor(window); + break; + case GLFW_CURSOR_DISABLED: + disableCursor(window); + break; + } +} + +int _glfwPlatformCreateCursor(_GLFWcursor* cursor, + const GLFWimage* image, + int xhot, int yhot) +{ + HDC dc; + HBITMAP bitmap, mask; + BITMAPV5HEADER bi; + ICONINFO ii; + DWORD* target = 0; + BYTE* source = (BYTE*) image->pixels; + int i; + + ZeroMemory(&bi, sizeof(bi)); + bi.bV5Size = sizeof(BITMAPV5HEADER); + bi.bV5Width = image->width; + bi.bV5Height = -image->height; + bi.bV5Planes = 1; + bi.bV5BitCount = 32; + bi.bV5Compression = BI_BITFIELDS; + bi.bV5RedMask = 0x00ff0000; + bi.bV5GreenMask = 0x0000ff00; + bi.bV5BlueMask = 0x000000ff; + bi.bV5AlphaMask = 0xff000000; + + dc = GetDC(NULL); + bitmap = CreateDIBSection(dc, (BITMAPINFO*) &bi, DIB_RGB_COLORS, + (void**) &target, NULL, (DWORD) 0); + ReleaseDC(NULL, dc); + + if (!bitmap) + return GL_FALSE; + + mask = CreateBitmap(image->width, image->height, 1, 1, NULL); + if (!mask) + { + DeleteObject(bitmap); + return GL_FALSE; + } + + for (i = 0; i < image->width * image->height; i++, target++, source += 4) + { + *target = (source[3] << 24) | + (source[0] << 16) | + (source[1] << 8) | + source[2]; + } + + ZeroMemory(&ii, sizeof(ii)); + ii.fIcon = FALSE; + ii.xHotspot = xhot; + ii.yHotspot = yhot; + ii.hbmMask = mask; + ii.hbmColor = bitmap; + + cursor->win32.handle = (HCURSOR) CreateIconIndirect(&ii); + + DeleteObject(bitmap); + DeleteObject(mask); + + if (!cursor->win32.handle) + return GL_FALSE; + + return GL_TRUE; +} + +int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape) +{ + LPCWSTR native = translateCursorShape(shape); + if (!native) + { + _glfwInputError(GLFW_INVALID_ENUM, "Win32: Invalid standard cursor"); + return GL_FALSE; + } + + cursor->win32.handle = CopyCursor(LoadCursorW(NULL, native)); + if (!cursor->win32.handle) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Win32: Failed to retrieve shared cursor"); + return GL_FALSE; + } + + return GL_TRUE; +} + +void _glfwPlatformDestroyCursor(_GLFWcursor* cursor) +{ + if (cursor->win32.handle) + DestroyIcon((HICON) cursor->win32.handle); +} + +void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) +{ + // It should be guaranteed that the cursor is not being used by this window if + // the following condition is not met. That way it should be safe to destroy the + // cursor after calling glfwSetCursor(window, NULL) on all windows using the cursor. + + if (_glfw.focusedWindow == window && + window->cursorMode == GLFW_CURSOR_NORMAL && + window->win32.cursorInside) + { + if (cursor) + SetCursor(cursor->win32.handle); + else + SetCursor(LoadCursorW(NULL, IDC_ARROW)); + } +} + +void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string) +{ + WCHAR* wideString; + HANDLE stringHandle; + size_t wideSize; + + wideString = _glfwCreateWideStringFromUTF8(string); + if (!wideString) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Win32: Failed to convert clipboard string to " + "wide string"); + return; + } + + wideSize = (wcslen(wideString) + 1) * sizeof(WCHAR); + + stringHandle = GlobalAlloc(GMEM_MOVEABLE, wideSize); + if (!stringHandle) + { + free(wideString); + + _glfwInputError(GLFW_PLATFORM_ERROR, + "Win32: Failed to allocate global handle for clipboard"); + return; + } + + memcpy(GlobalLock(stringHandle), wideString, wideSize); + GlobalUnlock(stringHandle); + + if (!OpenClipboard(window->win32.handle)) + { + GlobalFree(stringHandle); + free(wideString); + + _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to open clipboard"); + return; + } + + EmptyClipboard(); + SetClipboardData(CF_UNICODETEXT, stringHandle); + CloseClipboard(); + + free(wideString); +} + +const char* _glfwPlatformGetClipboardString(_GLFWwindow* window) +{ + HANDLE stringHandle; + + if (!IsClipboardFormatAvailable(CF_UNICODETEXT)) + { + _glfwInputError(GLFW_FORMAT_UNAVAILABLE, NULL); + return NULL; + } + + if (!OpenClipboard(window->win32.handle)) + { + _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to open clipboard"); + return NULL; + } + + stringHandle = GetClipboardData(CF_UNICODETEXT); + if (!stringHandle) + { + CloseClipboard(); + + _glfwInputError(GLFW_PLATFORM_ERROR, + "Win32: Failed to retrieve clipboard data"); + return NULL; + } + + free(_glfw.win32.clipboardString); + _glfw.win32.clipboardString = + _glfwCreateUTF8FromWideString(GlobalLock(stringHandle)); + + GlobalUnlock(stringHandle); + CloseClipboard(); + + if (!_glfw.win32.clipboardString) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Win32: Failed to convert wide string to UTF-8"); + return NULL; + } + + return _glfw.win32.clipboardString; +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW native API ////// +////////////////////////////////////////////////////////////////////////// + +GLFWAPI HWND glfwGetWin32Window(GLFWwindow* handle) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + return window->win32.handle; +} + diff --git a/testbed/glfw/src/window.c b/testbed/glfw/src/window.c new file mode 100644 index 00000000..4a46a6e4 --- /dev/null +++ b/testbed/glfw/src/window.c @@ -0,0 +1,740 @@ +//======================================================================== +// GLFW 3.1 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2010 Camilla Berglund +// Copyright (c) 2012 Torsten Walluhn +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include "internal.h" + +#include +#include + + +////////////////////////////////////////////////////////////////////////// +////// GLFW event API ////// +////////////////////////////////////////////////////////////////////////// + +void _glfwInputWindowFocus(_GLFWwindow* window, GLboolean focused) +{ + if (focused) + { + _glfw.focusedWindow = window; + + if (window->callbacks.focus) + window->callbacks.focus((GLFWwindow*) window, focused); + } + else + { + int i; + + _glfw.focusedWindow = NULL; + + if (window->callbacks.focus) + window->callbacks.focus((GLFWwindow*) window, focused); + + // Release all pressed keyboard keys + for (i = 0; i <= GLFW_KEY_LAST; i++) + { + if (window->keys[i] == GLFW_PRESS) + _glfwInputKey(window, i, 0, GLFW_RELEASE, 0); + } + + // Release all pressed mouse buttons + for (i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i++) + { + if (window->mouseButtons[i] == GLFW_PRESS) + _glfwInputMouseClick(window, i, GLFW_RELEASE, 0); + } + } +} + +void _glfwInputWindowPos(_GLFWwindow* window, int x, int y) +{ + if (window->callbacks.pos) + window->callbacks.pos((GLFWwindow*) window, x, y); +} + +void _glfwInputWindowSize(_GLFWwindow* window, int width, int height) +{ + if (window->callbacks.size) + window->callbacks.size((GLFWwindow*) window, width, height); +} + +void _glfwInputWindowIconify(_GLFWwindow* window, int iconified) +{ + if (window->callbacks.iconify) + window->callbacks.iconify((GLFWwindow*) window, iconified); +} + +void _glfwInputFramebufferSize(_GLFWwindow* window, int width, int height) +{ + if (window->callbacks.fbsize) + window->callbacks.fbsize((GLFWwindow*) window, width, height); +} + +void _glfwInputWindowDamage(_GLFWwindow* window) +{ + if (window->callbacks.refresh) + window->callbacks.refresh((GLFWwindow*) window); +} + +void _glfwInputWindowCloseRequest(_GLFWwindow* window) +{ + window->closed = GL_TRUE; + + if (window->callbacks.close) + window->callbacks.close((GLFWwindow*) window); +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW public API ////// +////////////////////////////////////////////////////////////////////////// + +GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, + const char* title, + GLFWmonitor* monitor, + GLFWwindow* share) +{ + _GLFWfbconfig fbconfig; + _GLFWctxconfig ctxconfig; + _GLFWwndconfig wndconfig; + _GLFWwindow* window; + _GLFWwindow* previous; + + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + + if (width <= 0 || height <= 0) + { + _glfwInputError(GLFW_INVALID_VALUE, "Invalid window size"); + return NULL; + } + + // Set up desired framebuffer config + fbconfig.redBits = _glfw.hints.redBits; + fbconfig.greenBits = _glfw.hints.greenBits; + fbconfig.blueBits = _glfw.hints.blueBits; + fbconfig.alphaBits = _glfw.hints.alphaBits; + fbconfig.depthBits = _glfw.hints.depthBits; + fbconfig.stencilBits = _glfw.hints.stencilBits; + fbconfig.accumRedBits = _glfw.hints.accumRedBits; + fbconfig.accumGreenBits = _glfw.hints.accumGreenBits; + fbconfig.accumBlueBits = _glfw.hints.accumBlueBits; + fbconfig.accumAlphaBits = _glfw.hints.accumAlphaBits; + fbconfig.auxBuffers = _glfw.hints.auxBuffers; + fbconfig.stereo = _glfw.hints.stereo ? GL_TRUE : GL_FALSE; + fbconfig.samples = _glfw.hints.samples; + fbconfig.sRGB = _glfw.hints.sRGB; + fbconfig.doublebuffer = _glfw.hints.doublebuffer ? GL_TRUE : GL_FALSE; + + // Set up desired window config + wndconfig.width = width; + wndconfig.height = height; + wndconfig.title = title; + wndconfig.resizable = _glfw.hints.resizable ? GL_TRUE : GL_FALSE; + wndconfig.visible = _glfw.hints.visible ? GL_TRUE : GL_FALSE; + wndconfig.decorated = _glfw.hints.decorated ? GL_TRUE : GL_FALSE; + wndconfig.focused = _glfw.hints.focused ? GL_TRUE : GL_FALSE; + wndconfig.autoIconify = _glfw.hints.autoIconify ? GL_TRUE : GL_FALSE; + wndconfig.floating = _glfw.hints.floating ? GL_TRUE : GL_FALSE; + wndconfig.monitor = (_GLFWmonitor*) monitor; + + // Set up desired context config + ctxconfig.api = _glfw.hints.api; + ctxconfig.major = _glfw.hints.major; + ctxconfig.minor = _glfw.hints.minor; + ctxconfig.forward = _glfw.hints.forward ? GL_TRUE : GL_FALSE; + ctxconfig.debug = _glfw.hints.debug ? GL_TRUE : GL_FALSE; + ctxconfig.profile = _glfw.hints.profile; + ctxconfig.robustness = _glfw.hints.robustness; + ctxconfig.release = _glfw.hints.release; + ctxconfig.share = (_GLFWwindow*) share; + + // Check the OpenGL bits of the window config + if (!_glfwIsValidContextConfig(&ctxconfig)) + return NULL; + + window = calloc(1, sizeof(_GLFWwindow)); + window->next = _glfw.windowListHead; + _glfw.windowListHead = window; + + if (wndconfig.monitor) + { + wndconfig.resizable = GL_TRUE; + wndconfig.visible = GL_TRUE; + wndconfig.focused = GL_TRUE; + + // Set up desired video mode + window->videoMode.width = width; + window->videoMode.height = height; + window->videoMode.redBits = _glfw.hints.redBits; + window->videoMode.greenBits = _glfw.hints.greenBits; + window->videoMode.blueBits = _glfw.hints.blueBits; + window->videoMode.refreshRate = _glfw.hints.refreshRate; + } + + // Transfer window hints that are persistent settings and not + // just initial states + window->monitor = wndconfig.monitor; + window->resizable = wndconfig.resizable; + window->decorated = wndconfig.decorated; + window->autoIconify = wndconfig.autoIconify; + window->floating = wndconfig.floating; + window->cursorMode = GLFW_CURSOR_NORMAL; + + // Save the currently current context so it can be restored later + previous = _glfwPlatformGetCurrentContext(); + + // Open the actual window and create its context + if (!_glfwPlatformCreateWindow(window, &wndconfig, &ctxconfig, &fbconfig)) + { + glfwDestroyWindow((GLFWwindow*) window); + _glfwPlatformMakeContextCurrent(previous); + return NULL; + } + + _glfwPlatformMakeContextCurrent(window); + + // Retrieve the actual (as opposed to requested) context attributes + if (!_glfwRefreshContextAttribs(&ctxconfig)) + { + glfwDestroyWindow((GLFWwindow*) window); + _glfwPlatformMakeContextCurrent(previous); + return NULL; + } + + // Verify the context against the requested parameters + if (!_glfwIsValidContext(&ctxconfig)) + { + glfwDestroyWindow((GLFWwindow*) window); + _glfwPlatformMakeContextCurrent(previous); + return NULL; + } + + // Clearing the front buffer to black to avoid garbage pixels left over + // from previous uses of our bit of VRAM + glClear(GL_COLOR_BUFFER_BIT); + _glfwPlatformSwapBuffers(window); + + // Restore the previously current context (or NULL) + _glfwPlatformMakeContextCurrent(previous); + + if (wndconfig.monitor) + { + int width, height; + _glfwPlatformGetWindowSize(window, &width, &height); + + window->cursorPosX = width / 2; + window->cursorPosY = height / 2; + + _glfwPlatformSetCursorPos(window, window->cursorPosX, window->cursorPosY); + } + else + { + if (wndconfig.visible) + { + if (wndconfig.focused) + _glfwPlatformShowWindow(window); + else + _glfwPlatformUnhideWindow(window); + } + } + + return (GLFWwindow*) window; +} + +void glfwDefaultWindowHints(void) +{ + _GLFW_REQUIRE_INIT(); + + memset(&_glfw.hints, 0, sizeof(_glfw.hints)); + + // The default is OpenGL with minimum version 1.0 + _glfw.hints.api = GLFW_OPENGL_API; + _glfw.hints.major = 1; + _glfw.hints.minor = 0; + + // The default is a focused, visible, resizable window with decorations + _glfw.hints.resizable = GL_TRUE; + _glfw.hints.visible = GL_TRUE; + _glfw.hints.decorated = GL_TRUE; + _glfw.hints.focused = GL_TRUE; + _glfw.hints.autoIconify = GL_TRUE; + + // The default is to select the highest available refresh rate + _glfw.hints.refreshRate = GLFW_DONT_CARE; + + // The default is 24 bits of color, 24 bits of depth and 8 bits of stencil, + // double buffered + _glfw.hints.redBits = 8; + _glfw.hints.greenBits = 8; + _glfw.hints.blueBits = 8; + _glfw.hints.alphaBits = 8; + _glfw.hints.depthBits = 24; + _glfw.hints.stencilBits = 8; + _glfw.hints.doublebuffer = GL_TRUE; +} + +GLFWAPI void glfwWindowHint(int target, int hint) +{ + _GLFW_REQUIRE_INIT(); + + switch (target) + { + case GLFW_RED_BITS: + _glfw.hints.redBits = hint; + break; + case GLFW_GREEN_BITS: + _glfw.hints.greenBits = hint; + break; + case GLFW_BLUE_BITS: + _glfw.hints.blueBits = hint; + break; + case GLFW_ALPHA_BITS: + _glfw.hints.alphaBits = hint; + break; + case GLFW_DEPTH_BITS: + _glfw.hints.depthBits = hint; + break; + case GLFW_STENCIL_BITS: + _glfw.hints.stencilBits = hint; + break; + case GLFW_ACCUM_RED_BITS: + _glfw.hints.accumRedBits = hint; + break; + case GLFW_ACCUM_GREEN_BITS: + _glfw.hints.accumGreenBits = hint; + break; + case GLFW_ACCUM_BLUE_BITS: + _glfw.hints.accumBlueBits = hint; + break; + case GLFW_ACCUM_ALPHA_BITS: + _glfw.hints.accumAlphaBits = hint; + break; + case GLFW_AUX_BUFFERS: + _glfw.hints.auxBuffers = hint; + break; + case GLFW_STEREO: + _glfw.hints.stereo = hint; + break; + case GLFW_REFRESH_RATE: + _glfw.hints.refreshRate = hint; + break; + case GLFW_DOUBLEBUFFER: + _glfw.hints.doublebuffer = hint; + break; + case GLFW_RESIZABLE: + _glfw.hints.resizable = hint; + break; + case GLFW_DECORATED: + _glfw.hints.decorated = hint; + break; + case GLFW_FOCUSED: + _glfw.hints.focused = hint; + break; + case GLFW_AUTO_ICONIFY: + _glfw.hints.autoIconify = hint; + break; + case GLFW_FLOATING: + _glfw.hints.floating = hint; + break; + case GLFW_VISIBLE: + _glfw.hints.visible = hint; + break; + case GLFW_SAMPLES: + _glfw.hints.samples = hint; + break; + case GLFW_SRGB_CAPABLE: + _glfw.hints.sRGB = hint; + break; + case GLFW_CLIENT_API: + _glfw.hints.api = hint; + break; + case GLFW_CONTEXT_VERSION_MAJOR: + _glfw.hints.major = hint; + break; + case GLFW_CONTEXT_VERSION_MINOR: + _glfw.hints.minor = hint; + break; + case GLFW_CONTEXT_ROBUSTNESS: + _glfw.hints.robustness = hint; + break; + case GLFW_OPENGL_FORWARD_COMPAT: + _glfw.hints.forward = hint; + break; + case GLFW_OPENGL_DEBUG_CONTEXT: + _glfw.hints.debug = hint; + break; + case GLFW_OPENGL_PROFILE: + _glfw.hints.profile = hint; + break; + case GLFW_CONTEXT_RELEASE_BEHAVIOR: + _glfw.hints.release = hint; + break; + default: + _glfwInputError(GLFW_INVALID_ENUM, NULL); + break; + } +} + +GLFWAPI void glfwDestroyWindow(GLFWwindow* handle) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + + _GLFW_REQUIRE_INIT(); + + // Allow closing of NULL (to match the behavior of free) + if (window == NULL) + return; + + // Clear all callbacks to avoid exposing a half torn-down window object + memset(&window->callbacks, 0, sizeof(window->callbacks)); + + // The window's context must not be current on another thread when the + // window is destroyed + if (window == _glfwPlatformGetCurrentContext()) + _glfwPlatformMakeContextCurrent(NULL); + + // Clear the focused window pointer if this is the focused window + if (_glfw.focusedWindow == window) + _glfw.focusedWindow = NULL; + + _glfwPlatformDestroyWindow(window); + + // Unlink window from global linked list + { + _GLFWwindow** prev = &_glfw.windowListHead; + + while (*prev != window) + prev = &((*prev)->next); + + *prev = window->next; + } + + free(window); +} + +GLFWAPI int glfwWindowShouldClose(GLFWwindow* handle) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + _GLFW_REQUIRE_INIT_OR_RETURN(0); + return window->closed; +} + +GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* handle, int value) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + _GLFW_REQUIRE_INIT(); + window->closed = value; +} + +GLFWAPI void glfwSetWindowTitle(GLFWwindow* handle, const char* title) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + _GLFW_REQUIRE_INIT(); + _glfwPlatformSetWindowTitle(window, title); +} + +GLFWAPI void glfwGetWindowPos(GLFWwindow* handle, int* xpos, int* ypos) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + + if (xpos) + *xpos = 0; + if (ypos) + *ypos = 0; + + _GLFW_REQUIRE_INIT(); + _glfwPlatformGetWindowPos(window, xpos, ypos); +} + +GLFWAPI void glfwSetWindowPos(GLFWwindow* handle, int xpos, int ypos) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + + _GLFW_REQUIRE_INIT(); + + if (window->monitor) + { + _glfwInputError(GLFW_INVALID_VALUE, + "Full screen windows cannot be positioned"); + return; + } + + _glfwPlatformSetWindowPos(window, xpos, ypos); +} + +GLFWAPI void glfwGetWindowSize(GLFWwindow* handle, int* width, int* height) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + + if (width) + *width = 0; + if (height) + *height = 0; + + _GLFW_REQUIRE_INIT(); + _glfwPlatformGetWindowSize(window, width, height); +} + +GLFWAPI void glfwSetWindowSize(GLFWwindow* handle, int width, int height) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + + _GLFW_REQUIRE_INIT(); + + if (window->monitor) + { + window->videoMode.width = width; + window->videoMode.height = height; + } + + _glfwPlatformSetWindowSize(window, width, height); +} + +GLFWAPI void glfwGetFramebufferSize(GLFWwindow* handle, int* width, int* height) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + + if (width) + *width = 0; + if (height) + *height = 0; + + _GLFW_REQUIRE_INIT(); + _glfwPlatformGetFramebufferSize(window, width, height); +} + +GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* handle, + int* left, int* top, + int* right, int* bottom) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + + if (left) + *left = 0; + if (top) + *top = 0; + if (right) + *right = 0; + if (bottom) + *bottom = 0; + + _GLFW_REQUIRE_INIT(); + _glfwPlatformGetWindowFrameSize(window, left, top, right, bottom); +} + +GLFWAPI void glfwIconifyWindow(GLFWwindow* handle) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + _GLFW_REQUIRE_INIT(); + _glfwPlatformIconifyWindow(window); +} + +GLFWAPI void glfwRestoreWindow(GLFWwindow* handle) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + _GLFW_REQUIRE_INIT(); + _glfwPlatformRestoreWindow(window); +} + +GLFWAPI void glfwShowWindow(GLFWwindow* handle) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + + _GLFW_REQUIRE_INIT(); + + if (window->monitor) + return; + + _glfwPlatformShowWindow(window); +} + +GLFWAPI void glfwHideWindow(GLFWwindow* handle) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + + _GLFW_REQUIRE_INIT(); + + if (window->monitor) + return; + + _glfwPlatformHideWindow(window); +} + +GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + + _GLFW_REQUIRE_INIT_OR_RETURN(0); + + switch (attrib) + { + case GLFW_FOCUSED: + return _glfwPlatformWindowFocused(window); + case GLFW_ICONIFIED: + return _glfwPlatformWindowIconified(window); + case GLFW_VISIBLE: + return _glfwPlatformWindowVisible(window); + case GLFW_RESIZABLE: + return window->resizable; + case GLFW_DECORATED: + return window->decorated; + case GLFW_FLOATING: + return window->floating; + case GLFW_CLIENT_API: + return window->context.api; + case GLFW_CONTEXT_VERSION_MAJOR: + return window->context.major; + case GLFW_CONTEXT_VERSION_MINOR: + return window->context.minor; + case GLFW_CONTEXT_REVISION: + return window->context.revision; + case GLFW_CONTEXT_ROBUSTNESS: + return window->context.robustness; + case GLFW_OPENGL_FORWARD_COMPAT: + return window->context.forward; + case GLFW_OPENGL_DEBUG_CONTEXT: + return window->context.debug; + case GLFW_OPENGL_PROFILE: + return window->context.profile; + case GLFW_CONTEXT_RELEASE_BEHAVIOR: + return window->context.release; + } + + _glfwInputError(GLFW_INVALID_ENUM, NULL); + return 0; +} + +GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* handle) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + return (GLFWmonitor*) window->monitor; +} + +GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* handle, void* pointer) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + _GLFW_REQUIRE_INIT(); + window->userPointer = pointer; +} + +GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* handle) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + return window->userPointer; +} + +GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* handle, + GLFWwindowposfun cbfun) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFW_SWAP_POINTERS(window->callbacks.pos, cbfun); + return cbfun; +} + +GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* handle, + GLFWwindowsizefun cbfun) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFW_SWAP_POINTERS(window->callbacks.size, cbfun); + return cbfun; +} + +GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* handle, + GLFWwindowclosefun cbfun) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFW_SWAP_POINTERS(window->callbacks.close, cbfun); + return cbfun; +} + +GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* handle, + GLFWwindowrefreshfun cbfun) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFW_SWAP_POINTERS(window->callbacks.refresh, cbfun); + return cbfun; +} + +GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* handle, + GLFWwindowfocusfun cbfun) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFW_SWAP_POINTERS(window->callbacks.focus, cbfun); + return cbfun; +} + +GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* handle, + GLFWwindowiconifyfun cbfun) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFW_SWAP_POINTERS(window->callbacks.iconify, cbfun); + return cbfun; +} + +GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* handle, + GLFWframebuffersizefun cbfun) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFW_SWAP_POINTERS(window->callbacks.fbsize, cbfun); + return cbfun; +} + +GLFWAPI void glfwPollEvents(void) +{ + _GLFW_REQUIRE_INIT(); + _glfwPlatformPollEvents(); +} + +GLFWAPI void glfwWaitEvents(void) +{ + _GLFW_REQUIRE_INIT(); + + if (!_glfw.windowListHead) + return; + + _glfwPlatformWaitEvents(); +} + +GLFWAPI void glfwPostEmptyEvent(void) +{ + _GLFW_REQUIRE_INIT(); + + if (!_glfw.windowListHead) + return; + + _glfwPlatformPostEmptyEvent(); +} + diff --git a/testbed/glfw/src/winmm_joystick.c b/testbed/glfw/src/winmm_joystick.c new file mode 100644 index 00000000..fcf6d94e --- /dev/null +++ b/testbed/glfw/src/winmm_joystick.c @@ -0,0 +1,177 @@ +//======================================================================== +// GLFW 3.1 WinMM - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2010 Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include "internal.h" + +#include + + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +// Convert axis value to the [-1,1] range +// +static float normalizeAxis(DWORD pos, DWORD min, DWORD max) +{ + float fpos = (float) pos; + float fmin = (float) min; + float fmax = (float) max; + + return (2.f * (fpos - fmin) / (fmax - fmin)) - 1.f; +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +// Initialize joystick interface +// +void _glfwInitJoysticks(void) +{ +} + +// Close all opened joystick handles +// +void _glfwTerminateJoysticks(void) +{ + int i; + + for (i = 0; i < GLFW_JOYSTICK_LAST; i++) + free(_glfw.winmm_js[i].name); +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +int _glfwPlatformJoystickPresent(int joy) +{ + JOYINFO ji; + + if (_glfw_joyGetPos(joy, &ji) != JOYERR_NOERROR) + return GL_FALSE; + + return GL_TRUE; +} + +const float* _glfwPlatformGetJoystickAxes(int joy, int* count) +{ + JOYCAPS jc; + JOYINFOEX ji; + float* axes = _glfw.winmm_js[joy].axes; + + if (_glfw_joyGetDevCaps(joy, &jc, sizeof(JOYCAPS)) != JOYERR_NOERROR) + return NULL; + + ji.dwSize = sizeof(JOYINFOEX); + ji.dwFlags = JOY_RETURNX | JOY_RETURNY | JOY_RETURNZ | + JOY_RETURNR | JOY_RETURNU | JOY_RETURNV; + if (_glfw_joyGetPosEx(joy, &ji) != JOYERR_NOERROR) + return NULL; + + axes[(*count)++] = normalizeAxis(ji.dwXpos, jc.wXmin, jc.wXmax); + axes[(*count)++] = normalizeAxis(ji.dwYpos, jc.wYmin, jc.wYmax); + + if (jc.wCaps & JOYCAPS_HASZ) + axes[(*count)++] = normalizeAxis(ji.dwZpos, jc.wZmin, jc.wZmax); + + if (jc.wCaps & JOYCAPS_HASR) + axes[(*count)++] = normalizeAxis(ji.dwRpos, jc.wRmin, jc.wRmax); + + if (jc.wCaps & JOYCAPS_HASU) + axes[(*count)++] = normalizeAxis(ji.dwUpos, jc.wUmin, jc.wUmax); + + if (jc.wCaps & JOYCAPS_HASV) + axes[(*count)++] = normalizeAxis(ji.dwVpos, jc.wVmin, jc.wVmax); + + return axes; +} + +const unsigned char* _glfwPlatformGetJoystickButtons(int joy, int* count) +{ + JOYCAPS jc; + JOYINFOEX ji; + unsigned char* buttons = _glfw.winmm_js[joy].buttons; + + if (_glfw_joyGetDevCaps(joy, &jc, sizeof(JOYCAPS)) != JOYERR_NOERROR) + return NULL; + + ji.dwSize = sizeof(JOYINFOEX); + ji.dwFlags = JOY_RETURNBUTTONS | JOY_RETURNPOV; + if (_glfw_joyGetPosEx(joy, &ji) != JOYERR_NOERROR) + return NULL; + + while (*count < (int) jc.wNumButtons) + { + buttons[*count] = (unsigned char) + (ji.dwButtons & (1UL << *count) ? GLFW_PRESS : GLFW_RELEASE); + (*count)++; + } + + // Virtual buttons - Inject data from hats + // Each hat is exposed as 4 buttons which exposes 8 directions with + // concurrent button presses + // NOTE: this API exposes only one hat + + if ((jc.wCaps & JOYCAPS_HASPOV) && (jc.wCaps & JOYCAPS_POV4DIR)) + { + int i, value = ji.dwPOV / 100 / 45; + + // Bit fields of button presses for each direction, including nil + const int directions[9] = { 1, 3, 2, 6, 4, 12, 8, 9, 0 }; + + if (value < 0 || value > 8) + value = 8; + + for (i = 0; i < 4; i++) + { + if (directions[value] & (1 << i)) + buttons[(*count)++] = GLFW_PRESS; + else + buttons[(*count)++] = GLFW_RELEASE; + } + } + + return buttons; +} + +const char* _glfwPlatformGetJoystickName(int joy) +{ + JOYCAPS jc; + + if (_glfw_joyGetDevCaps(joy, &jc, sizeof(JOYCAPS)) != JOYERR_NOERROR) + return NULL; + + free(_glfw.winmm_js[joy].name); + _glfw.winmm_js[joy].name = _glfwCreateUTF8FromWideString(jc.szPname); + + return _glfw.winmm_js[joy].name; +} + diff --git a/testbed/glfw/src/winmm_joystick.h b/testbed/glfw/src/winmm_joystick.h new file mode 100644 index 00000000..608f1dc5 --- /dev/null +++ b/testbed/glfw/src/winmm_joystick.h @@ -0,0 +1,47 @@ +//======================================================================== +// GLFW 3.1 WinMM - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2006-2014 Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#ifndef _winmm_joystick_h_ +#define _winmm_joystick_h_ + +#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE \ + _GLFWjoystickWinMM winmm_js[GLFW_JOYSTICK_LAST + 1] + + +// WinMM-specific per-joystick data +// +typedef struct _GLFWjoystickWinMM +{ + float axes[6]; + unsigned char buttons[36]; // 32 buttons plus one hat + char* name; +} _GLFWjoystickWinMM; + + +void _glfwInitJoysticks(void); +void _glfwTerminateJoysticks(void); + +#endif // _winmm_joystick_h_ diff --git a/testbed/glfw/src/wl_init.c b/testbed/glfw/src/wl_init.c new file mode 100644 index 00000000..0269ee34 --- /dev/null +++ b/testbed/glfw/src/wl_init.c @@ -0,0 +1,630 @@ +//======================================================================== +// GLFW 3.1 Wayland - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2014 Jonas Ådahl +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include "internal.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "xkb_unicode.h" + +static void pointerHandleEnter(void* data, + struct wl_pointer* pointer, + uint32_t serial, + struct wl_surface* surface, + wl_fixed_t sx, + wl_fixed_t sy) +{ + _GLFWwindow* window = wl_surface_get_user_data(surface); + + _glfw.wl.pointerSerial = serial; + _glfw.wl.pointerFocus = window; + + _glfwPlatformSetCursor(window, window->wl.currentCursor); + _glfwInputCursorEnter(window, GL_TRUE); +} + +static void pointerHandleLeave(void* data, + struct wl_pointer* pointer, + uint32_t serial, + struct wl_surface* surface) +{ + _GLFWwindow* window = _glfw.wl.pointerFocus; + + if (!window) + return; + + _glfw.wl.pointerSerial = serial; + _glfw.wl.pointerFocus = NULL; + _glfwInputCursorEnter(window, GL_FALSE); +} + +static void pointerHandleMotion(void* data, + struct wl_pointer* pointer, + uint32_t time, + wl_fixed_t sx, + wl_fixed_t sy) +{ + _GLFWwindow* window = _glfw.wl.pointerFocus; + + if (!window) + return; + + if (window->cursorMode == GLFW_CURSOR_DISABLED) + { + /* TODO */ + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: GLFW_CURSOR_DISABLED not supported"); + return; + } + + _glfwInputCursorMotion(window, + wl_fixed_to_double(sx), + wl_fixed_to_double(sy)); +} + +static void pointerHandleButton(void* data, + struct wl_pointer* wl_pointer, + uint32_t serial, + uint32_t time, + uint32_t button, + uint32_t state) +{ + _GLFWwindow* window = _glfw.wl.pointerFocus; + int glfwButton; + + if (!window) + return; + + /* Makes left, right and middle 0, 1 and 2. Overall order follows evdev + * codes. */ + glfwButton = button - BTN_LEFT; + + _glfwInputMouseClick(window, + glfwButton, + state == WL_POINTER_BUTTON_STATE_PRESSED + ? GLFW_PRESS + : GLFW_RELEASE, + _glfw.wl.xkb.modifiers); +} + +static void pointerHandleAxis(void* data, + struct wl_pointer* wl_pointer, + uint32_t time, + uint32_t axis, + wl_fixed_t value) +{ + _GLFWwindow* window = _glfw.wl.pointerFocus; + double scroll_factor; + double x, y; + + if (!window) + return; + + /* Wayland scroll events are in pointer motion coordinate space (think + * two finger scroll). The factor 10 is commonly used to convert to + * "scroll step means 1.0. */ + scroll_factor = 1.0/10.0; + + switch (axis) + { + case WL_POINTER_AXIS_HORIZONTAL_SCROLL: + x = wl_fixed_to_double(value) * scroll_factor; + y = 0.0; + break; + case WL_POINTER_AXIS_VERTICAL_SCROLL: + x = 0.0; + y = wl_fixed_to_double(value) * scroll_factor; + break; + default: + break; + } + + _glfwInputScroll(window, x, y); +} + +static const struct wl_pointer_listener pointerListener = { + pointerHandleEnter, + pointerHandleLeave, + pointerHandleMotion, + pointerHandleButton, + pointerHandleAxis, +}; + +static void keyboardHandleKeymap(void* data, + struct wl_keyboard* keyboard, + uint32_t format, + int fd, + uint32_t size) +{ + struct xkb_keymap* keymap; + struct xkb_state* state; + char* mapStr; + + if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) + { + close(fd); + return; + } + + mapStr = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); + if (mapStr == MAP_FAILED) { + close(fd); + return; + } + + keymap = xkb_map_new_from_string(_glfw.wl.xkb.context, + mapStr, + XKB_KEYMAP_FORMAT_TEXT_V1, + 0); + munmap(mapStr, size); + close(fd); + + if (!keymap) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Failed to compile keymap"); + return; + } + + state = xkb_state_new(keymap); + if (!state) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Failed to create XKB state"); + xkb_map_unref(keymap); + return; + } + + xkb_keymap_unref(_glfw.wl.xkb.keymap); + xkb_state_unref(_glfw.wl.xkb.state); + _glfw.wl.xkb.keymap = keymap; + _glfw.wl.xkb.state = state; + + _glfw.wl.xkb.control_mask = + 1 << xkb_map_mod_get_index(_glfw.wl.xkb.keymap, "Control"); + _glfw.wl.xkb.alt_mask = + 1 << xkb_map_mod_get_index(_glfw.wl.xkb.keymap, "Mod1"); + _glfw.wl.xkb.shift_mask = + 1 << xkb_map_mod_get_index(_glfw.wl.xkb.keymap, "Shift"); + _glfw.wl.xkb.super_mask = + 1 << xkb_map_mod_get_index(_glfw.wl.xkb.keymap, "Mod4"); +} + +static void keyboardHandleEnter(void* data, + struct wl_keyboard* keyboard, + uint32_t serial, + struct wl_surface* surface, + struct wl_array* keys) +{ + _GLFWwindow* window = wl_surface_get_user_data(surface); + + _glfw.wl.keyboardFocus = window; + _glfwInputWindowFocus(window, GL_TRUE); +} + +static void keyboardHandleLeave(void* data, + struct wl_keyboard* keyboard, + uint32_t serial, + struct wl_surface* surface) +{ + _GLFWwindow* window = _glfw.wl.keyboardFocus; + + if (!window) + return; + + _glfw.wl.keyboardFocus = NULL; + _glfwInputWindowFocus(window, GL_FALSE); +} + +static int toGLFWKeyCode(uint32_t key) +{ + switch (key) + { + case KEY_GRAVE: return GLFW_KEY_GRAVE_ACCENT; + case KEY_1: return GLFW_KEY_1; + case KEY_2: return GLFW_KEY_2; + case KEY_3: return GLFW_KEY_3; + case KEY_4: return GLFW_KEY_4; + case KEY_5: return GLFW_KEY_5; + case KEY_6: return GLFW_KEY_6; + case KEY_7: return GLFW_KEY_7; + case KEY_8: return GLFW_KEY_8; + case KEY_9: return GLFW_KEY_9; + case KEY_0: return GLFW_KEY_0; + case KEY_MINUS: return GLFW_KEY_MINUS; + case KEY_EQUAL: return GLFW_KEY_EQUAL; + case KEY_Q: return GLFW_KEY_Q; + case KEY_W: return GLFW_KEY_W; + case KEY_E: return GLFW_KEY_E; + case KEY_R: return GLFW_KEY_R; + case KEY_T: return GLFW_KEY_T; + case KEY_Y: return GLFW_KEY_Y; + case KEY_U: return GLFW_KEY_U; + case KEY_I: return GLFW_KEY_I; + case KEY_O: return GLFW_KEY_O; + case KEY_P: return GLFW_KEY_P; + case KEY_LEFTBRACE: return GLFW_KEY_LEFT_BRACKET; + case KEY_RIGHTBRACE: return GLFW_KEY_RIGHT_BRACKET; + case KEY_A: return GLFW_KEY_A; + case KEY_S: return GLFW_KEY_S; + case KEY_D: return GLFW_KEY_D; + case KEY_F: return GLFW_KEY_F; + case KEY_G: return GLFW_KEY_G; + case KEY_H: return GLFW_KEY_H; + case KEY_J: return GLFW_KEY_J; + case KEY_K: return GLFW_KEY_K; + case KEY_L: return GLFW_KEY_L; + case KEY_SEMICOLON: return GLFW_KEY_SEMICOLON; + case KEY_APOSTROPHE: return GLFW_KEY_APOSTROPHE; + case KEY_Z: return GLFW_KEY_Z; + case KEY_X: return GLFW_KEY_X; + case KEY_C: return GLFW_KEY_C; + case KEY_V: return GLFW_KEY_V; + case KEY_B: return GLFW_KEY_B; + case KEY_N: return GLFW_KEY_N; + case KEY_M: return GLFW_KEY_M; + case KEY_COMMA: return GLFW_KEY_COMMA; + case KEY_DOT: return GLFW_KEY_PERIOD; + case KEY_SLASH: return GLFW_KEY_SLASH; + case KEY_BACKSLASH: return GLFW_KEY_BACKSLASH; + case KEY_ESC: return GLFW_KEY_ESCAPE; + case KEY_TAB: return GLFW_KEY_TAB; + case KEY_LEFTSHIFT: return GLFW_KEY_LEFT_SHIFT; + case KEY_RIGHTSHIFT: return GLFW_KEY_RIGHT_SHIFT; + case KEY_LEFTCTRL: return GLFW_KEY_LEFT_CONTROL; + case KEY_RIGHTCTRL: return GLFW_KEY_RIGHT_CONTROL; + case KEY_LEFTALT: return GLFW_KEY_LEFT_ALT; + case KEY_RIGHTALT: return GLFW_KEY_RIGHT_ALT; + case KEY_LEFTMETA: return GLFW_KEY_LEFT_SUPER; + case KEY_RIGHTMETA: return GLFW_KEY_RIGHT_SUPER; + case KEY_MENU: return GLFW_KEY_MENU; + case KEY_NUMLOCK: return GLFW_KEY_NUM_LOCK; + case KEY_CAPSLOCK: return GLFW_KEY_CAPS_LOCK; + case KEY_PRINT: return GLFW_KEY_PRINT_SCREEN; + case KEY_SCROLLLOCK: return GLFW_KEY_SCROLL_LOCK; + case KEY_PAUSE: return GLFW_KEY_PAUSE; + case KEY_DELETE: return GLFW_KEY_DELETE; + case KEY_BACKSPACE: return GLFW_KEY_BACKSPACE; + case KEY_ENTER: return GLFW_KEY_ENTER; + case KEY_HOME: return GLFW_KEY_HOME; + case KEY_END: return GLFW_KEY_END; + case KEY_PAGEUP: return GLFW_KEY_PAGE_UP; + case KEY_PAGEDOWN: return GLFW_KEY_PAGE_DOWN; + case KEY_INSERT: return GLFW_KEY_INSERT; + case KEY_LEFT: return GLFW_KEY_LEFT; + case KEY_RIGHT: return GLFW_KEY_RIGHT; + case KEY_DOWN: return GLFW_KEY_DOWN; + case KEY_UP: return GLFW_KEY_UP; + case KEY_F1: return GLFW_KEY_F1; + case KEY_F2: return GLFW_KEY_F2; + case KEY_F3: return GLFW_KEY_F3; + case KEY_F4: return GLFW_KEY_F4; + case KEY_F5: return GLFW_KEY_F5; + case KEY_F6: return GLFW_KEY_F6; + case KEY_F7: return GLFW_KEY_F7; + case KEY_F8: return GLFW_KEY_F8; + case KEY_F9: return GLFW_KEY_F9; + case KEY_F10: return GLFW_KEY_F10; + case KEY_F11: return GLFW_KEY_F11; + case KEY_F12: return GLFW_KEY_F12; + case KEY_F13: return GLFW_KEY_F13; + case KEY_F14: return GLFW_KEY_F14; + case KEY_F15: return GLFW_KEY_F15; + case KEY_F16: return GLFW_KEY_F16; + case KEY_F17: return GLFW_KEY_F17; + case KEY_F18: return GLFW_KEY_F18; + case KEY_F19: return GLFW_KEY_F19; + case KEY_F20: return GLFW_KEY_F20; + case KEY_F21: return GLFW_KEY_F21; + case KEY_F22: return GLFW_KEY_F22; + case KEY_F23: return GLFW_KEY_F23; + case KEY_F24: return GLFW_KEY_F24; + case KEY_KPSLASH: return GLFW_KEY_KP_DIVIDE; + case KEY_KPDOT: return GLFW_KEY_KP_MULTIPLY; + case KEY_KPMINUS: return GLFW_KEY_KP_SUBTRACT; + case KEY_KPPLUS: return GLFW_KEY_KP_ADD; + case KEY_KP0: return GLFW_KEY_KP_0; + case KEY_KP1: return GLFW_KEY_KP_1; + case KEY_KP2: return GLFW_KEY_KP_2; + case KEY_KP3: return GLFW_KEY_KP_3; + case KEY_KP4: return GLFW_KEY_KP_4; + case KEY_KP5: return GLFW_KEY_KP_5; + case KEY_KP6: return GLFW_KEY_KP_6; + case KEY_KP7: return GLFW_KEY_KP_7; + case KEY_KP8: return GLFW_KEY_KP_8; + case KEY_KP9: return GLFW_KEY_KP_9; + case KEY_KPCOMMA: return GLFW_KEY_KP_DECIMAL; + case KEY_KPEQUAL: return GLFW_KEY_KP_EQUAL; + case KEY_KPENTER: return GLFW_KEY_KP_ENTER; + default: return GLFW_KEY_UNKNOWN; + } +} + +static void keyboardHandleKey(void* data, + struct wl_keyboard* keyboard, + uint32_t serial, + uint32_t time, + uint32_t key, + uint32_t state) +{ + uint32_t code, num_syms; + long cp; + int keyCode; + int action; + const xkb_keysym_t *syms; + _GLFWwindow* window = _glfw.wl.keyboardFocus; + + if (!window) + return; + + keyCode = toGLFWKeyCode(key); + action = state == WL_KEYBOARD_KEY_STATE_PRESSED + ? GLFW_PRESS : GLFW_RELEASE; + + _glfwInputKey(window, keyCode, key, action, + _glfw.wl.xkb.modifiers); + + code = key + 8; + num_syms = xkb_key_get_syms(_glfw.wl.xkb.state, code, &syms); + + if (num_syms == 1) + { + cp = _glfwKeySym2Unicode(syms[0]); + if (cp != -1) + { + const int mods = _glfw.wl.xkb.modifiers; + const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT)); + _glfwInputChar(window, cp, mods, plain); + } + } +} + +static void keyboardHandleModifiers(void* data, + struct wl_keyboard* keyboard, + uint32_t serial, + uint32_t modsDepressed, + uint32_t modsLatched, + uint32_t modsLocked, + uint32_t group) +{ + xkb_mod_mask_t mask; + unsigned int modifiers = 0; + + if (!_glfw.wl.xkb.keymap) + return; + + xkb_state_update_mask(_glfw.wl.xkb.state, + modsDepressed, + modsLatched, + modsLocked, + 0, + 0, + group); + + mask = xkb_state_serialize_mods(_glfw.wl.xkb.state, + XKB_STATE_DEPRESSED | + XKB_STATE_LATCHED); + if (mask & _glfw.wl.xkb.control_mask) + modifiers |= GLFW_MOD_CONTROL; + if (mask & _glfw.wl.xkb.alt_mask) + modifiers |= GLFW_MOD_ALT; + if (mask & _glfw.wl.xkb.shift_mask) + modifiers |= GLFW_MOD_SHIFT; + if (mask & _glfw.wl.xkb.super_mask) + modifiers |= GLFW_MOD_SUPER; + _glfw.wl.xkb.modifiers = modifiers; +} + +static const struct wl_keyboard_listener keyboardListener = { + keyboardHandleKeymap, + keyboardHandleEnter, + keyboardHandleLeave, + keyboardHandleKey, + keyboardHandleModifiers, +}; + +static void seatHandleCapabilities(void* data, + struct wl_seat* seat, + enum wl_seat_capability caps) +{ + if ((caps & WL_SEAT_CAPABILITY_POINTER) && !_glfw.wl.pointer) + { + _glfw.wl.pointer = wl_seat_get_pointer(seat); + wl_pointer_add_listener(_glfw.wl.pointer, &pointerListener, NULL); + } + else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && _glfw.wl.pointer) + { + wl_pointer_destroy(_glfw.wl.pointer); + _glfw.wl.pointer = NULL; + } + + if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !_glfw.wl.keyboard) + { + _glfw.wl.keyboard = wl_seat_get_keyboard(seat); + wl_keyboard_add_listener(_glfw.wl.keyboard, &keyboardListener, NULL); + } + else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && _glfw.wl.keyboard) + { + wl_keyboard_destroy(_glfw.wl.keyboard); + _glfw.wl.keyboard = NULL; + } +} + +static const struct wl_seat_listener seatListener = { + seatHandleCapabilities +}; + +static void registryHandleGlobal(void* data, + struct wl_registry* registry, + uint32_t name, + const char* interface, + uint32_t version) +{ + if (strcmp(interface, "wl_compositor") == 0) + { + _glfw.wl.compositor = + wl_registry_bind(registry, name, &wl_compositor_interface, 1); + } + else if (strcmp(interface, "wl_shm") == 0) + { + _glfw.wl.shm = + wl_registry_bind(registry, name, &wl_shm_interface, 1); + } + else if (strcmp(interface, "wl_shell") == 0) + { + _glfw.wl.shell = + wl_registry_bind(registry, name, &wl_shell_interface, 1); + } + else if (strcmp(interface, "wl_output") == 0) + { + _glfwAddOutput(name, version); + } + else if (strcmp(interface, "wl_seat") == 0) + { + if (!_glfw.wl.seat) + { + _glfw.wl.seat = + wl_registry_bind(registry, name, &wl_seat_interface, 1); + wl_seat_add_listener(_glfw.wl.seat, &seatListener, NULL); + } + } +} + +static void registryHandleGlobalRemove(void *data, + struct wl_registry *registry, + uint32_t name) +{ +} + + +static const struct wl_registry_listener registryListener = { + registryHandleGlobal, + registryHandleGlobalRemove +}; + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +int _glfwPlatformInit(void) +{ + _glfw.wl.display = wl_display_connect(NULL); + if (!_glfw.wl.display) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Failed to connect to display"); + return GL_FALSE; + } + + _glfw.wl.registry = wl_display_get_registry(_glfw.wl.display); + wl_registry_add_listener(_glfw.wl.registry, ®istryListener, NULL); + + _glfw.wl.monitors = calloc(4, sizeof(_GLFWmonitor*)); + _glfw.wl.monitorsSize = 4; + + _glfw.wl.xkb.context = xkb_context_new(0); + if (!_glfw.wl.xkb.context) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Failed to initialize xkb context"); + return GL_FALSE; + } + + // Sync so we got all registry objects + wl_display_roundtrip(_glfw.wl.display); + + // Sync so we got all initial output events + wl_display_roundtrip(_glfw.wl.display); + + if (!_glfwInitContextAPI()) + return GL_FALSE; + + _glfwInitTimer(); + _glfwInitJoysticks(); + + if (_glfw.wl.pointer && _glfw.wl.shm) + { + _glfw.wl.cursorTheme = wl_cursor_theme_load(NULL, 32, _glfw.wl.shm); + if (!_glfw.wl.cursorTheme) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Unable to load default cursor theme\n"); + return GL_FALSE; + } + _glfw.wl.defaultCursor = + wl_cursor_theme_get_cursor(_glfw.wl.cursorTheme, "left_ptr"); + if (!_glfw.wl.defaultCursor) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Unable to load default left pointer\n"); + return GL_FALSE; + } + _glfw.wl.cursorSurface = + wl_compositor_create_surface(_glfw.wl.compositor); + } + + return GL_TRUE; +} + +void _glfwPlatformTerminate(void) +{ + _glfwTerminateContextAPI(); + _glfwTerminateJoysticks(); + + if (_glfw.wl.cursorTheme) + wl_cursor_theme_destroy(_glfw.wl.cursorTheme); + if (_glfw.wl.cursorSurface) + wl_surface_destroy(_glfw.wl.cursorSurface); + if (_glfw.wl.registry) + wl_registry_destroy(_glfw.wl.registry); + if (_glfw.wl.display) + wl_display_flush(_glfw.wl.display); + if (_glfw.wl.display) + wl_display_disconnect(_glfw.wl.display); +} + +const char* _glfwPlatformGetVersionString(void) +{ + const char* version = _GLFW_VERSION_NUMBER " Wayland EGL " +#if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK) + " clock_gettime" +#endif +#if defined(_GLFW_BUILD_DLL) + " shared" +#endif + ; + + return version; +} + diff --git a/testbed/glfw/src/wl_monitor.c b/testbed/glfw/src/wl_monitor.c new file mode 100644 index 00000000..fbcefd38 --- /dev/null +++ b/testbed/glfw/src/wl_monitor.c @@ -0,0 +1,250 @@ +//======================================================================== +// GLFW 3.1 Wayland - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2014 Jonas Ådahl +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include "internal.h" + +#include +#include +#include +#include + + +struct _GLFWvidmodeWayland +{ + GLFWvidmode base; + uint32_t flags; +}; + +static void geometry(void* data, + struct wl_output* output, + int32_t x, + int32_t y, + int32_t physicalWidth, + int32_t physicalHeight, + int32_t subpixel, + const char* make, + const char* model, + int32_t transform) +{ + struct _GLFWmonitor *monitor = data; + + monitor->wl.x = x; + monitor->wl.y = y; + monitor->widthMM = physicalWidth; + monitor->heightMM = physicalHeight; +} + +static void mode(void* data, + struct wl_output* output, + uint32_t flags, + int32_t width, + int32_t height, + int32_t refresh) +{ + struct _GLFWmonitor *monitor = data; + _GLFWvidmodeWayland mode = { { 0 }, }; + + mode.base.width = width; + mode.base.height = height; + mode.base.refreshRate = refresh; + mode.flags = flags; + + if (monitor->wl.modesCount + 1 >= monitor->wl.modesSize) + { + int size = monitor->wl.modesSize * 2; + _GLFWvidmodeWayland* modes = + realloc(monitor->wl.modes, + size * sizeof(_GLFWvidmodeWayland)); + monitor->wl.modes = modes; + monitor->wl.modesSize = size; + } + + monitor->wl.modes[monitor->wl.modesCount++] = mode; +} + +static void done(void* data, + struct wl_output* output) +{ + struct _GLFWmonitor *monitor = data; + + monitor->wl.done = GL_TRUE; +} + +static void scale(void* data, + struct wl_output* output, + int32_t factor) +{ +} + +static const struct wl_output_listener output_listener = { + geometry, + mode, + done, + scale, +}; + + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +void _glfwAddOutput(uint32_t name, uint32_t version) +{ + _GLFWmonitor *monitor; + struct wl_output *output; + char name_str[80]; + + memset(name_str, 0, 80 * sizeof(char)); + snprintf(name_str, 79, "wl_output@%u", name); + + if (version < 2) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Unsupported output interface version"); + return; + } + + monitor = _glfwAllocMonitor(name_str, 0, 0); + + output = wl_registry_bind(_glfw.wl.registry, + name, + &wl_output_interface, + 2); + if (!output) + { + _glfwFreeMonitor(monitor); + return; + } + + monitor->wl.modes = calloc(4, sizeof(_GLFWvidmodeWayland)); + monitor->wl.modesSize = 4; + + monitor->wl.output = output; + wl_output_add_listener(output, &output_listener, monitor); + + if (_glfw.wl.monitorsCount + 1 >= _glfw.wl.monitorsSize) + { + _GLFWmonitor** monitors = _glfw.wl.monitors; + int size = _glfw.wl.monitorsSize * 2; + + monitors = realloc(monitors, size * sizeof(_GLFWmonitor*)); + + _glfw.wl.monitors = monitors; + _glfw.wl.monitorsSize = size; + } + + _glfw.wl.monitors[_glfw.wl.monitorsCount++] = monitor; +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +_GLFWmonitor** _glfwPlatformGetMonitors(int* count) +{ + _GLFWmonitor** monitors; + _GLFWmonitor* monitor; + int i, monitorsCount = _glfw.wl.monitorsCount; + + if (_glfw.wl.monitorsCount == 0) + goto err; + + monitors = calloc(monitorsCount, sizeof(_GLFWmonitor*)); + + for (i = 0; i < monitorsCount; i++) + { + _GLFWmonitor* origMonitor = _glfw.wl.monitors[i]; + monitor = calloc(1, sizeof(_GLFWmonitor)); + + monitor->modes = + _glfwPlatformGetVideoModes(origMonitor, + &origMonitor->wl.modesCount); + *monitor = *_glfw.wl.monitors[i]; + monitors[i] = monitor; + } + + *count = monitorsCount; + return monitors; + +err: + *count = 0; + return NULL; +} + +GLboolean _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second) +{ + return first->wl.output == second->wl.output; +} + +void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos) +{ + if (xpos) + *xpos = monitor->wl.x; + if (ypos) + *ypos = monitor->wl.y; +} + +GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found) +{ + GLFWvidmode *modes; + int i, modesCount = monitor->wl.modesCount; + + modes = calloc(modesCount, sizeof(GLFWvidmode)); + + for (i = 0; i < modesCount; i++) + modes[i] = monitor->wl.modes[i].base; + + *found = modesCount; + return modes; +} + +void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) +{ + int i; + + for (i = 0; i < monitor->wl.modesCount; i++) + { + if (monitor->wl.modes[i].flags & WL_OUTPUT_MODE_CURRENT) + { + *mode = monitor->wl.modes[i].base; + return; + } + } +} + +void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) +{ + // TODO + fprintf(stderr, "_glfwPlatformGetGammaRamp not implemented yet\n"); +} + +void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) +{ + // TODO + fprintf(stderr, "_glfwPlatformSetGammaRamp not implemented yet\n"); +} + diff --git a/testbed/glfw/src/wl_platform.h b/testbed/glfw/src/wl_platform.h new file mode 100644 index 00000000..66736b56 --- /dev/null +++ b/testbed/glfw/src/wl_platform.h @@ -0,0 +1,140 @@ +//======================================================================== +// GLFW 3.1 Wayland - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2014 Jonas Ådahl +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#ifndef _wayland_platform_h_ +#define _wayland_platform_h_ + + +#include +#include + +#if defined(_GLFW_EGL) + #include "egl_context.h" +#else + #error "The Wayland backend depends on EGL platform support" +#endif + +#include "posix_tls.h" +#include "posix_time.h" +#include "linux_joystick.h" + +#define _GLFW_EGL_NATIVE_WINDOW window->wl.native +#define _GLFW_EGL_NATIVE_DISPLAY _glfw.wl.display + +#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowWayland wl +#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryWayland wl +#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorWayland wl +#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorWayland wl + + +// Wayland-specific video mode data +// +typedef struct _GLFWvidmodeWayland _GLFWvidmodeWayland; + + +// Wayland-specific per-window data +// +typedef struct _GLFWwindowWayland +{ + int width, height; + GLboolean visible; + struct wl_surface* surface; + struct wl_egl_window* native; + struct wl_shell_surface* shell_surface; + struct wl_callback* callback; + _GLFWcursor* currentCursor; +} _GLFWwindowWayland; + + +// Wayland-specific global data +// +typedef struct _GLFWlibraryWayland +{ + struct wl_display* display; + struct wl_registry* registry; + struct wl_compositor* compositor; + struct wl_shell* shell; + struct wl_shm* shm; + struct wl_seat* seat; + struct wl_pointer* pointer; + struct wl_keyboard* keyboard; + + struct wl_cursor_theme* cursorTheme; + struct wl_cursor* defaultCursor; + struct wl_surface* cursorSurface; + uint32_t pointerSerial; + + _GLFWmonitor** monitors; + int monitorsCount; + int monitorsSize; + + struct { + struct xkb_context* context; + struct xkb_keymap* keymap; + struct xkb_state* state; + xkb_mod_mask_t control_mask; + xkb_mod_mask_t alt_mask; + xkb_mod_mask_t shift_mask; + xkb_mod_mask_t super_mask; + unsigned int modifiers; + } xkb; + + _GLFWwindow* pointerFocus; + _GLFWwindow* keyboardFocus; + +} _GLFWlibraryWayland; + + +// Wayland-specific per-monitor data +// +typedef struct _GLFWmonitorWayland +{ + struct wl_output* output; + + _GLFWvidmodeWayland* modes; + int modesCount; + int modesSize; + GLboolean done; + + int x; + int y; + +} _GLFWmonitorWayland; + + +// Wayland-specific per-cursor data +// +typedef struct _GLFWcursorWayland +{ + struct wl_buffer* buffer; + int width, height; + int xhot, yhot; +} _GLFWcursorWayland; + + +void _glfwAddOutput(uint32_t name, uint32_t version); + +#endif // _wayland_platform_h_ diff --git a/testbed/glfw/src/wl_window.c b/testbed/glfw/src/wl_window.c new file mode 100644 index 00000000..bb2da473 --- /dev/null +++ b/testbed/glfw/src/wl_window.c @@ -0,0 +1,524 @@ +//======================================================================== +// GLFW 3.1 Wayland - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2014 Jonas Ådahl +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#define _GNU_SOURCE + +#include "internal.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + + +static void handlePing(void* data, + struct wl_shell_surface* shellSurface, + uint32_t serial) +{ + wl_shell_surface_pong(shellSurface, serial); +} + +static void handleConfigure(void* data, + struct wl_shell_surface* shellSurface, + uint32_t edges, + int32_t width, + int32_t height) +{ + _GLFWwindow* window = data; + _glfwInputFramebufferSize(window, width, height); + _glfwInputWindowSize(window, width, height); + _glfwPlatformSetWindowSize(window, width, height); + _glfwInputWindowDamage(window); +} + +static void handlePopupDone(void* data, + struct wl_shell_surface* shellSurface) +{ +} + +static const struct wl_shell_surface_listener shellSurfaceListener = { + handlePing, + handleConfigure, + handlePopupDone +}; + +static GLboolean createSurface(_GLFWwindow* window, + const _GLFWwndconfig* wndconfig) +{ + window->wl.surface = wl_compositor_create_surface(_glfw.wl.compositor); + if (!window->wl.surface) + return GL_FALSE; + + wl_surface_set_user_data(window->wl.surface, window); + + window->wl.native = wl_egl_window_create(window->wl.surface, + wndconfig->width, + wndconfig->height); + if (!window->wl.native) + return GL_FALSE; + + window->wl.shell_surface = wl_shell_get_shell_surface(_glfw.wl.shell, + window->wl.surface); + if (!window->wl.shell_surface) + return GL_FALSE; + + wl_shell_surface_add_listener(window->wl.shell_surface, + &shellSurfaceListener, + window); + + window->wl.width = wndconfig->width; + window->wl.height = wndconfig->height; + + return GL_TRUE; +} + +static int +createTmpfileCloexec(char* tmpname) +{ + int fd; + + fd = mkostemp(tmpname, O_CLOEXEC); + if (fd >= 0) + unlink(tmpname); + + return fd; +} + +/* + * Create a new, unique, anonymous file of the given size, and + * return the file descriptor for it. The file descriptor is set + * CLOEXEC. The file is immediately suitable for mmap()'ing + * the given size at offset zero. + * + * The file should not have a permanent backing store like a disk, + * but may have if XDG_RUNTIME_DIR is not properly implemented in OS. + * + * The file name is deleted from the file system. + * + * The file is suitable for buffer sharing between processes by + * transmitting the file descriptor over Unix sockets using the + * SCM_RIGHTS methods. + * + * posix_fallocate() is used to guarantee that disk space is available + * for the file at the given size. If disk space is insufficent, errno + * is set to ENOSPC. If posix_fallocate() is not supported, program may + * receive SIGBUS on accessing mmap()'ed file contents instead. + */ +int +createAnonymousFile(off_t size) +{ + static const char template[] = "/glfw-shared-XXXXXX"; + const char* path; + char* name; + int fd; + int ret; + + path = getenv("XDG_RUNTIME_DIR"); + if (!path) + { + errno = ENOENT; + return -1; + } + + name = malloc(strlen(path) + sizeof(template)); + strcpy(name, path); + strcat(name, template); + + fd = createTmpfileCloexec(name); + + free(name); + + if (fd < 0) + return -1; + ret = posix_fallocate(fd, 0, size); + if (ret != 0) + { + close(fd); + errno = ret; + return -1; + } + return fd; +} + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +int _glfwPlatformCreateWindow(_GLFWwindow* window, + const _GLFWwndconfig* wndconfig, + const _GLFWctxconfig* ctxconfig, + const _GLFWfbconfig* fbconfig) +{ + if (!_glfwCreateContext(window, ctxconfig, fbconfig)) + return GL_FALSE; + + if (!createSurface(window, wndconfig)) + return GL_FALSE; + + if (wndconfig->monitor) + { + wl_shell_surface_set_fullscreen( + window->wl.shell_surface, + WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, + 0, + wndconfig->monitor->wl.output); + } + else + { + wl_shell_surface_set_toplevel(window->wl.shell_surface); + } + + window->wl.currentCursor = NULL; + + return GL_TRUE; +} + +void _glfwPlatformDestroyWindow(_GLFWwindow* window) +{ + if (window == _glfw.wl.pointerFocus) + { + _glfw.wl.pointerFocus = NULL; + _glfwInputCursorEnter(window, GL_FALSE); + } + if (window == _glfw.wl.keyboardFocus) + { + _glfw.wl.keyboardFocus = NULL; + _glfwInputWindowFocus(window, GL_FALSE); + } + + _glfwDestroyContext(window); + + if (window->wl.native) + wl_egl_window_destroy(window->wl.native); + + if (window->wl.shell_surface) + wl_shell_surface_destroy(window->wl.shell_surface); + + if (window->wl.surface) + wl_surface_destroy(window->wl.surface); +} + +void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title) +{ + wl_shell_surface_set_title(window->wl.shell_surface, title); +} + +void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos) +{ + // A Wayland client is not aware of its position, so just warn and leave it + // as (0, 0) + + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Window position retrieval not supported"); +} + +void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos) +{ + // A Wayland client can not set its position, so just warn + + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Window position setting not supported"); +} + +void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height) +{ + if (width) + *width = window->wl.width; + if (height) + *height = window->wl.height; +} + +void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) +{ + wl_egl_window_resize(window->wl.native, width, height, 0, 0); + window->wl.width = width; + window->wl.height = height; +} + +void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height) +{ + _glfwPlatformGetWindowSize(window, width, height); +} + +void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, + int* left, int* top, + int* right, int* bottom) +{ + // TODO + fprintf(stderr, "_glfwPlatformGetWindowFrameSize not implemented yet\n"); +} + +void _glfwPlatformIconifyWindow(_GLFWwindow* window) +{ + // TODO + fprintf(stderr, "_glfwPlatformIconifyWindow not implemented yet\n"); +} + +void _glfwPlatformRestoreWindow(_GLFWwindow* window) +{ + // TODO + fprintf(stderr, "_glfwPlatformRestoreWindow not implemented yet\n"); +} + +void _glfwPlatformShowWindow(_GLFWwindow* window) +{ + wl_shell_surface_set_toplevel(window->wl.shell_surface); +} + +void _glfwPlatformUnhideWindow(_GLFWwindow* window) +{ + // TODO + fprintf(stderr, "_glfwPlatformUnhideWindow not implemented yet\n"); +} + +void _glfwPlatformHideWindow(_GLFWwindow* window) +{ + wl_surface_attach(window->wl.surface, NULL, 0, 0); + wl_surface_commit(window->wl.surface); +} + +int _glfwPlatformWindowFocused(_GLFWwindow* window) +{ + // TODO + return GL_FALSE; +} + +int _glfwPlatformWindowIconified(_GLFWwindow* window) +{ + // TODO + return GL_FALSE; +} + +int _glfwPlatformWindowVisible(_GLFWwindow* window) +{ + // TODO + return GL_FALSE; +} + +void _glfwPlatformPollEvents(void) +{ + struct wl_display* display = _glfw.wl.display; + struct pollfd fds[] = { + { wl_display_get_fd(display), POLLIN }, + }; + + while (wl_display_prepare_read(display) != 0) + wl_display_dispatch_pending(display); + wl_display_flush(display); + if (poll(fds, 1, 0) > 0) + { + wl_display_read_events(display); + wl_display_dispatch_pending(display); + } + else + { + wl_display_cancel_read(display); + } +} + +void _glfwPlatformWaitEvents(void) +{ + struct wl_display* display = _glfw.wl.display; + struct pollfd fds[] = { + { wl_display_get_fd(display), POLLIN }, + }; + + while (wl_display_prepare_read(display) != 0) + wl_display_dispatch_pending(display); + wl_display_flush(display); + if (poll(fds, 1, -1) > 0) + { + wl_display_read_events(display); + wl_display_dispatch_pending(display); + } + else + { + wl_display_cancel_read(display); + } +} + +void _glfwPlatformPostEmptyEvent(void) +{ + wl_display_sync(_glfw.wl.display); +} + +void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos) +{ + // TODO + fprintf(stderr, "_glfwPlatformGetCursorPos not implemented yet\n"); +} + +void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y) +{ + // A Wayland client can not set the cursor position + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Cursor position setting not supported"); +} + +void _glfwPlatformApplyCursorMode(_GLFWwindow* window) +{ + _glfwPlatformSetCursor(window, window->wl.currentCursor); +} + +int _glfwPlatformCreateCursor(_GLFWcursor* cursor, + const GLFWimage* image, + int xhot, int yhot) +{ + struct wl_shm_pool* pool; + int stride = image->width * 4; + int length = image->width * image->height * 4; + void* data; + int fd, i; + + fd = createAnonymousFile(length); + if (fd < 0) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Creating a buffer file for %d B failed: %m\n", + length); + return GL_FALSE; + } + + data = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (data == MAP_FAILED) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Cursor mmap failed: %m\n"); + close(fd); + return GL_FALSE; + } + + pool = wl_shm_create_pool(_glfw.wl.shm, fd, length); + + close(fd); + unsigned char* source = (unsigned char*) image->pixels; + unsigned char* target = data; + for (i = 0; i < image->width * image->height; i++, source += 4) + { + *target++ = source[2]; + *target++ = source[1]; + *target++ = source[0]; + *target++ = source[3]; + } + + cursor->wl.buffer = + wl_shm_pool_create_buffer(pool, 0, + image->width, + image->height, + stride, WL_SHM_FORMAT_ARGB8888); + munmap(data, length); + wl_shm_pool_destroy(pool); + + cursor->wl.width = image->width; + cursor->wl.height = image->height; + cursor->wl.xhot = xhot; + cursor->wl.yhot = yhot; + return GL_TRUE; +} + +int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape) +{ + // TODO + fprintf(stderr, "_glfwPlatformCreateStandardCursor not implemented yet\n"); + return GL_FALSE; +} + +void _glfwPlatformDestroyCursor(_GLFWcursor* cursor) +{ + wl_buffer_destroy(cursor->wl.buffer); +} + +void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) +{ + struct wl_buffer* buffer; + struct wl_cursor_image* image; + struct wl_surface* surface = _glfw.wl.cursorSurface; + + if (!_glfw.wl.pointer) + return; + + window->wl.currentCursor = cursor; + + // If we're not in the correct window just save the cursor + // the next time the pointer enters the window the cursor will change + if (window != _glfw.wl.pointerFocus) + return; + + if (window->cursorMode == GLFW_CURSOR_NORMAL) + { + if (cursor == NULL) + { + image = _glfw.wl.defaultCursor->images[0]; + buffer = wl_cursor_image_get_buffer(image); + if (!buffer) + return; + wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerSerial, + surface, + image->hotspot_x, + image->hotspot_y); + wl_surface_attach(surface, buffer, 0, 0); + wl_surface_damage(surface, 0, 0, + image->width, image->height); + wl_surface_commit(surface); + } + else + { + wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerSerial, + surface, + cursor->wl.xhot, + cursor->wl.yhot); + wl_surface_attach(surface, cursor->wl.buffer, 0, 0); + wl_surface_damage(surface, 0, 0, + cursor->wl.width, cursor->wl.height); + wl_surface_commit(surface); + } + } + else /* Cursor is hidden set cursor surface to NULL */ + { + wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerSerial, NULL, 0, 0); + } +} + +void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string) +{ + // TODO + fprintf(stderr, "_glfwPlatformSetClipboardString not implemented yet\n"); +} + +const char* _glfwPlatformGetClipboardString(_GLFWwindow* window) +{ + // TODO + fprintf(stderr, "_glfwPlatformGetClipboardString not implemented yet\n"); + return NULL; +} + diff --git a/testbed/glfw/src/x11_init.c b/testbed/glfw/src/x11_init.c new file mode 100644 index 00000000..388105ef --- /dev/null +++ b/testbed/glfw/src/x11_init.c @@ -0,0 +1,816 @@ +//======================================================================== +// GLFW 3.1 X11 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2010 Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include "internal.h" + +#include + +#include +#include +#include +#include +#include + + +// Translate an X11 key code to a GLFW key code. +// +static int translateKey(int scancode) +{ + int keySym; + + // Valid key code range is [8,255], according to the Xlib manual + if (scancode < 8 || scancode > 255) + return GLFW_KEY_UNKNOWN; + + if (_glfw.x11.xkb.available) + { + // Try secondary keysym, for numeric keypad keys + // Note: This way we always force "NumLock = ON", which is intentional + // since the returned key code should correspond to a physical + // location. + keySym = XkbKeycodeToKeysym(_glfw.x11.display, scancode, 0, 1); + switch (keySym) + { + case XK_KP_0: return GLFW_KEY_KP_0; + case XK_KP_1: return GLFW_KEY_KP_1; + case XK_KP_2: return GLFW_KEY_KP_2; + case XK_KP_3: return GLFW_KEY_KP_3; + case XK_KP_4: return GLFW_KEY_KP_4; + case XK_KP_5: return GLFW_KEY_KP_5; + case XK_KP_6: return GLFW_KEY_KP_6; + case XK_KP_7: return GLFW_KEY_KP_7; + case XK_KP_8: return GLFW_KEY_KP_8; + case XK_KP_9: return GLFW_KEY_KP_9; + case XK_KP_Separator: + case XK_KP_Decimal: return GLFW_KEY_KP_DECIMAL; + case XK_KP_Equal: return GLFW_KEY_KP_EQUAL; + case XK_KP_Enter: return GLFW_KEY_KP_ENTER; + default: break; + } + + // Now try primary keysym for function keys (non-printable keys). These + // should not be layout dependent (i.e. US layout and international + // layouts should give the same result). + keySym = XkbKeycodeToKeysym(_glfw.x11.display, scancode, 0, 0); + } + else + { + int dummy; + KeySym* keySyms; + + keySyms = XGetKeyboardMapping(_glfw.x11.display, scancode, 1, &dummy); + keySym = keySyms[0]; + XFree(keySyms); + } + + switch (keySym) + { + case XK_Escape: return GLFW_KEY_ESCAPE; + case XK_Tab: return GLFW_KEY_TAB; + case XK_Shift_L: return GLFW_KEY_LEFT_SHIFT; + case XK_Shift_R: return GLFW_KEY_RIGHT_SHIFT; + case XK_Control_L: return GLFW_KEY_LEFT_CONTROL; + case XK_Control_R: return GLFW_KEY_RIGHT_CONTROL; + case XK_Meta_L: + case XK_Alt_L: return GLFW_KEY_LEFT_ALT; + case XK_Mode_switch: // Mapped to Alt_R on many keyboards + case XK_ISO_Level3_Shift: // AltGr on at least some machines + case XK_Meta_R: + case XK_Alt_R: return GLFW_KEY_RIGHT_ALT; + case XK_Super_L: return GLFW_KEY_LEFT_SUPER; + case XK_Super_R: return GLFW_KEY_RIGHT_SUPER; + case XK_Menu: return GLFW_KEY_MENU; + case XK_Num_Lock: return GLFW_KEY_NUM_LOCK; + case XK_Caps_Lock: return GLFW_KEY_CAPS_LOCK; + case XK_Print: return GLFW_KEY_PRINT_SCREEN; + case XK_Scroll_Lock: return GLFW_KEY_SCROLL_LOCK; + case XK_Pause: return GLFW_KEY_PAUSE; + case XK_Delete: return GLFW_KEY_DELETE; + case XK_BackSpace: return GLFW_KEY_BACKSPACE; + case XK_Return: return GLFW_KEY_ENTER; + case XK_Home: return GLFW_KEY_HOME; + case XK_End: return GLFW_KEY_END; + case XK_Page_Up: return GLFW_KEY_PAGE_UP; + case XK_Page_Down: return GLFW_KEY_PAGE_DOWN; + case XK_Insert: return GLFW_KEY_INSERT; + case XK_Left: return GLFW_KEY_LEFT; + case XK_Right: return GLFW_KEY_RIGHT; + case XK_Down: return GLFW_KEY_DOWN; + case XK_Up: return GLFW_KEY_UP; + case XK_F1: return GLFW_KEY_F1; + case XK_F2: return GLFW_KEY_F2; + case XK_F3: return GLFW_KEY_F3; + case XK_F4: return GLFW_KEY_F4; + case XK_F5: return GLFW_KEY_F5; + case XK_F6: return GLFW_KEY_F6; + case XK_F7: return GLFW_KEY_F7; + case XK_F8: return GLFW_KEY_F8; + case XK_F9: return GLFW_KEY_F9; + case XK_F10: return GLFW_KEY_F10; + case XK_F11: return GLFW_KEY_F11; + case XK_F12: return GLFW_KEY_F12; + case XK_F13: return GLFW_KEY_F13; + case XK_F14: return GLFW_KEY_F14; + case XK_F15: return GLFW_KEY_F15; + case XK_F16: return GLFW_KEY_F16; + case XK_F17: return GLFW_KEY_F17; + case XK_F18: return GLFW_KEY_F18; + case XK_F19: return GLFW_KEY_F19; + case XK_F20: return GLFW_KEY_F20; + case XK_F21: return GLFW_KEY_F21; + case XK_F22: return GLFW_KEY_F22; + case XK_F23: return GLFW_KEY_F23; + case XK_F24: return GLFW_KEY_F24; + case XK_F25: return GLFW_KEY_F25; + + // Numeric keypad + case XK_KP_Divide: return GLFW_KEY_KP_DIVIDE; + case XK_KP_Multiply: return GLFW_KEY_KP_MULTIPLY; + case XK_KP_Subtract: return GLFW_KEY_KP_SUBTRACT; + case XK_KP_Add: return GLFW_KEY_KP_ADD; + + // These should have been detected in secondary keysym test above! + case XK_KP_Insert: return GLFW_KEY_KP_0; + case XK_KP_End: return GLFW_KEY_KP_1; + case XK_KP_Down: return GLFW_KEY_KP_2; + case XK_KP_Page_Down: return GLFW_KEY_KP_3; + case XK_KP_Left: return GLFW_KEY_KP_4; + case XK_KP_Right: return GLFW_KEY_KP_6; + case XK_KP_Home: return GLFW_KEY_KP_7; + case XK_KP_Up: return GLFW_KEY_KP_8; + case XK_KP_Page_Up: return GLFW_KEY_KP_9; + case XK_KP_Delete: return GLFW_KEY_KP_DECIMAL; + case XK_KP_Equal: return GLFW_KEY_KP_EQUAL; + case XK_KP_Enter: return GLFW_KEY_KP_ENTER; + + // Last resort: Check for printable keys (should not happen if the XKB + // extension is available). This will give a layout dependent mapping + // (which is wrong, and we may miss some keys, especially on non-US + // keyboards), but it's better than nothing... + case XK_a: return GLFW_KEY_A; + case XK_b: return GLFW_KEY_B; + case XK_c: return GLFW_KEY_C; + case XK_d: return GLFW_KEY_D; + case XK_e: return GLFW_KEY_E; + case XK_f: return GLFW_KEY_F; + case XK_g: return GLFW_KEY_G; + case XK_h: return GLFW_KEY_H; + case XK_i: return GLFW_KEY_I; + case XK_j: return GLFW_KEY_J; + case XK_k: return GLFW_KEY_K; + case XK_l: return GLFW_KEY_L; + case XK_m: return GLFW_KEY_M; + case XK_n: return GLFW_KEY_N; + case XK_o: return GLFW_KEY_O; + case XK_p: return GLFW_KEY_P; + case XK_q: return GLFW_KEY_Q; + case XK_r: return GLFW_KEY_R; + case XK_s: return GLFW_KEY_S; + case XK_t: return GLFW_KEY_T; + case XK_u: return GLFW_KEY_U; + case XK_v: return GLFW_KEY_V; + case XK_w: return GLFW_KEY_W; + case XK_x: return GLFW_KEY_X; + case XK_y: return GLFW_KEY_Y; + case XK_z: return GLFW_KEY_Z; + case XK_1: return GLFW_KEY_1; + case XK_2: return GLFW_KEY_2; + case XK_3: return GLFW_KEY_3; + case XK_4: return GLFW_KEY_4; + case XK_5: return GLFW_KEY_5; + case XK_6: return GLFW_KEY_6; + case XK_7: return GLFW_KEY_7; + case XK_8: return GLFW_KEY_8; + case XK_9: return GLFW_KEY_9; + case XK_0: return GLFW_KEY_0; + case XK_space: return GLFW_KEY_SPACE; + case XK_minus: return GLFW_KEY_MINUS; + case XK_equal: return GLFW_KEY_EQUAL; + case XK_bracketleft: return GLFW_KEY_LEFT_BRACKET; + case XK_bracketright: return GLFW_KEY_RIGHT_BRACKET; + case XK_backslash: return GLFW_KEY_BACKSLASH; + case XK_semicolon: return GLFW_KEY_SEMICOLON; + case XK_apostrophe: return GLFW_KEY_APOSTROPHE; + case XK_grave: return GLFW_KEY_GRAVE_ACCENT; + case XK_comma: return GLFW_KEY_COMMA; + case XK_period: return GLFW_KEY_PERIOD; + case XK_slash: return GLFW_KEY_SLASH; + case XK_less: return GLFW_KEY_WORLD_1; // At least in some layouts... + default: break; + } + + // No matching translation was found + return GLFW_KEY_UNKNOWN; +} + +// Create key code translation tables +// +static void createKeyTables(void) +{ + int scancode, key; + + memset(_glfw.x11.publicKeys, -1, sizeof(_glfw.x11.publicKeys)); + + if (_glfw.x11.xkb.available) + { + // Use XKB to determine physical key locations independently of the current + // keyboard layout + + char name[XkbKeyNameLength + 1]; + XkbDescPtr descr = XkbGetKeyboard(_glfw.x11.display, + XkbAllComponentsMask, + XkbUseCoreKbd); + + // Find the X11 key code -> GLFW key code mapping + for (scancode = descr->min_key_code; scancode <= descr->max_key_code; scancode++) + { + memcpy(name, descr->names->keys[scancode].name, XkbKeyNameLength); + name[XkbKeyNameLength] = 0; + + // Map the key name to a GLFW key code. Note: We only map printable + // keys here, and we use the US keyboard layout. The rest of the + // keys (function keys) are mapped using traditional KeySym + // translations. + if (strcmp(name, "TLDE") == 0) key = GLFW_KEY_GRAVE_ACCENT; + else if (strcmp(name, "AE01") == 0) key = GLFW_KEY_1; + else if (strcmp(name, "AE02") == 0) key = GLFW_KEY_2; + else if (strcmp(name, "AE03") == 0) key = GLFW_KEY_3; + else if (strcmp(name, "AE04") == 0) key = GLFW_KEY_4; + else if (strcmp(name, "AE05") == 0) key = GLFW_KEY_5; + else if (strcmp(name, "AE06") == 0) key = GLFW_KEY_6; + else if (strcmp(name, "AE07") == 0) key = GLFW_KEY_7; + else if (strcmp(name, "AE08") == 0) key = GLFW_KEY_8; + else if (strcmp(name, "AE09") == 0) key = GLFW_KEY_9; + else if (strcmp(name, "AE10") == 0) key = GLFW_KEY_0; + else if (strcmp(name, "AE11") == 0) key = GLFW_KEY_MINUS; + else if (strcmp(name, "AE12") == 0) key = GLFW_KEY_EQUAL; + else if (strcmp(name, "AD01") == 0) key = GLFW_KEY_Q; + else if (strcmp(name, "AD02") == 0) key = GLFW_KEY_W; + else if (strcmp(name, "AD03") == 0) key = GLFW_KEY_E; + else if (strcmp(name, "AD04") == 0) key = GLFW_KEY_R; + else if (strcmp(name, "AD05") == 0) key = GLFW_KEY_T; + else if (strcmp(name, "AD06") == 0) key = GLFW_KEY_Y; + else if (strcmp(name, "AD07") == 0) key = GLFW_KEY_U; + else if (strcmp(name, "AD08") == 0) key = GLFW_KEY_I; + else if (strcmp(name, "AD09") == 0) key = GLFW_KEY_O; + else if (strcmp(name, "AD10") == 0) key = GLFW_KEY_P; + else if (strcmp(name, "AD11") == 0) key = GLFW_KEY_LEFT_BRACKET; + else if (strcmp(name, "AD12") == 0) key = GLFW_KEY_RIGHT_BRACKET; + else if (strcmp(name, "AC01") == 0) key = GLFW_KEY_A; + else if (strcmp(name, "AC02") == 0) key = GLFW_KEY_S; + else if (strcmp(name, "AC03") == 0) key = GLFW_KEY_D; + else if (strcmp(name, "AC04") == 0) key = GLFW_KEY_F; + else if (strcmp(name, "AC05") == 0) key = GLFW_KEY_G; + else if (strcmp(name, "AC06") == 0) key = GLFW_KEY_H; + else if (strcmp(name, "AC07") == 0) key = GLFW_KEY_J; + else if (strcmp(name, "AC08") == 0) key = GLFW_KEY_K; + else if (strcmp(name, "AC09") == 0) key = GLFW_KEY_L; + else if (strcmp(name, "AC10") == 0) key = GLFW_KEY_SEMICOLON; + else if (strcmp(name, "AC11") == 0) key = GLFW_KEY_APOSTROPHE; + else if (strcmp(name, "AB01") == 0) key = GLFW_KEY_Z; + else if (strcmp(name, "AB02") == 0) key = GLFW_KEY_X; + else if (strcmp(name, "AB03") == 0) key = GLFW_KEY_C; + else if (strcmp(name, "AB04") == 0) key = GLFW_KEY_V; + else if (strcmp(name, "AB05") == 0) key = GLFW_KEY_B; + else if (strcmp(name, "AB06") == 0) key = GLFW_KEY_N; + else if (strcmp(name, "AB07") == 0) key = GLFW_KEY_M; + else if (strcmp(name, "AB08") == 0) key = GLFW_KEY_COMMA; + else if (strcmp(name, "AB09") == 0) key = GLFW_KEY_PERIOD; + else if (strcmp(name, "AB10") == 0) key = GLFW_KEY_SLASH; + else if (strcmp(name, "BKSL") == 0) key = GLFW_KEY_BACKSLASH; + else if (strcmp(name, "LSGT") == 0) key = GLFW_KEY_WORLD_1; + else key = GLFW_KEY_UNKNOWN; + + if ((scancode >= 0) && (scancode < 256)) + _glfw.x11.publicKeys[scancode] = key; + } + + XkbFreeKeyboard(descr, 0, True); + } + + // Translate the un-translated key codes using traditional X11 KeySym + // lookups + for (scancode = 0; scancode < 256; scancode++) + { + if (_glfw.x11.publicKeys[scancode] < 0) + _glfw.x11.publicKeys[scancode] = translateKey(scancode); + } +} + +// Check whether the IM has a usable style +// +static GLboolean hasUsableInputMethodStyle(void) +{ + unsigned int i; + GLboolean found = GL_FALSE; + XIMStyles* styles = NULL; + + if (XGetIMValues(_glfw.x11.im, XNQueryInputStyle, &styles, NULL) != NULL) + return GL_FALSE; + + for (i = 0; i < styles->count_styles; i++) + { + if (styles->supported_styles[i] == (XIMPreeditNothing | XIMStatusNothing)) + { + found = GL_TRUE; + break; + } + } + + XFree(styles); + return found; +} + +// Check whether the specified atom is supported +// +static Atom getSupportedAtom(Atom* supportedAtoms, + unsigned long atomCount, + const char* atomName) +{ + Atom atom = XInternAtom(_glfw.x11.display, atomName, True); + if (atom != None) + { + unsigned long i; + + for (i = 0; i < atomCount; i++) + { + if (supportedAtoms[i] == atom) + return atom; + } + } + + return None; +} + +// Check whether the running window manager is EWMH-compliant +// +static void detectEWMH(void) +{ + Window* windowFromRoot = NULL; + Window* windowFromChild = NULL; + + // First we need a couple of atoms, which should already be there + Atom supportingWmCheck = + XInternAtom(_glfw.x11.display, "_NET_SUPPORTING_WM_CHECK", True); + Atom wmSupported = + XInternAtom(_glfw.x11.display, "_NET_SUPPORTED", True); + if (supportingWmCheck == None || wmSupported == None) + return; + + // Then we look for the _NET_SUPPORTING_WM_CHECK property of the root window + if (_glfwGetWindowProperty(_glfw.x11.root, + supportingWmCheck, + XA_WINDOW, + (unsigned char**) &windowFromRoot) != 1) + { + if (windowFromRoot) + XFree(windowFromRoot); + return; + } + + _glfwGrabXErrorHandler(); + + // It should be the ID of a child window (of the root) + // Then we look for the same property on the child window + if (_glfwGetWindowProperty(*windowFromRoot, + supportingWmCheck, + XA_WINDOW, + (unsigned char**) &windowFromChild) != 1) + { + XFree(windowFromRoot); + if (windowFromChild) + XFree(windowFromChild); + return; + } + + _glfwReleaseXErrorHandler(); + + // It should be the ID of that same child window + if (*windowFromRoot != *windowFromChild) + { + XFree(windowFromRoot); + XFree(windowFromChild); + return; + } + + XFree(windowFromRoot); + XFree(windowFromChild); + + // We are now fairly sure that an EWMH-compliant window manager is running + + Atom* supportedAtoms; + unsigned long atomCount; + + // Now we need to check the _NET_SUPPORTED property of the root window + // It should be a list of supported WM protocol and state atoms + atomCount = _glfwGetWindowProperty(_glfw.x11.root, + wmSupported, + XA_ATOM, + (unsigned char**) &supportedAtoms); + + // See which of the atoms we support that are supported by the WM + _glfw.x11.NET_WM_STATE = + getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE"); + _glfw.x11.NET_WM_STATE_ABOVE = + getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_ABOVE"); + _glfw.x11.NET_WM_STATE_FULLSCREEN = + getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_FULLSCREEN"); + _glfw.x11.NET_WM_FULLSCREEN_MONITORS = + getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_FULLSCREEN_MONITORS"); + _glfw.x11.NET_WM_NAME = + getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_NAME"); + _glfw.x11.NET_WM_ICON_NAME = + getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_ICON_NAME"); + _glfw.x11.NET_WM_PID = + getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_PID"); + _glfw.x11.NET_WM_PING = + getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_PING"); + _glfw.x11.NET_ACTIVE_WINDOW = + getSupportedAtom(supportedAtoms, atomCount, "_NET_ACTIVE_WINDOW"); + _glfw.x11.NET_FRAME_EXTENTS = + getSupportedAtom(supportedAtoms, atomCount, "_NET_FRAME_EXTENTS"); + _glfw.x11.NET_REQUEST_FRAME_EXTENTS = + getSupportedAtom(supportedAtoms, atomCount, "_NET_REQUEST_FRAME_EXTENTS"); + _glfw.x11.NET_WM_BYPASS_COMPOSITOR = + getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_BYPASS_COMPOSITOR"); + + XFree(supportedAtoms); + + _glfw.x11.hasEWMH = GL_TRUE; +} + +// Initialize X11 display and look for supported X11 extensions +// +static GLboolean initExtensions(void) +{ + // Find or create window manager atoms + _glfw.x11.WM_PROTOCOLS = XInternAtom(_glfw.x11.display, + "WM_PROTOCOLS", + False); + _glfw.x11.WM_STATE = XInternAtom(_glfw.x11.display, "WM_STATE", False); + _glfw.x11.WM_DELETE_WINDOW = XInternAtom(_glfw.x11.display, + "WM_DELETE_WINDOW", + False); + _glfw.x11.MOTIF_WM_HINTS = XInternAtom(_glfw.x11.display, + "_MOTIF_WM_HINTS", + False); + + // Check for XF86VidMode extension + _glfw.x11.vidmode.available = + XF86VidModeQueryExtension(_glfw.x11.display, + &_glfw.x11.vidmode.eventBase, + &_glfw.x11.vidmode.errorBase); + + // Check for RandR extension + _glfw.x11.randr.available = + XRRQueryExtension(_glfw.x11.display, + &_glfw.x11.randr.eventBase, + &_glfw.x11.randr.errorBase); + + if (_glfw.x11.randr.available) + { + XRRScreenResources* sr; + + if (!XRRQueryVersion(_glfw.x11.display, + &_glfw.x11.randr.versionMajor, + &_glfw.x11.randr.versionMinor)) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "X11: Failed to query RandR version"); + return GL_FALSE; + } + + // The GLFW RandR path requires at least version 1.3 + if (_glfw.x11.randr.versionMajor == 1 && + _glfw.x11.randr.versionMinor < 3) + { + _glfw.x11.randr.available = GL_FALSE; + } + + sr = XRRGetScreenResources(_glfw.x11.display, _glfw.x11.root); + + if (!sr->ncrtc || !XRRGetCrtcGammaSize(_glfw.x11.display, sr->crtcs[0])) + { + // This is either a headless system or an older Nvidia binary driver + // with broken gamma support + // Flag it as useless and fall back to Xf86VidMode gamma, if + // available + _glfwInputError(GLFW_PLATFORM_ERROR, + "X11: RandR gamma ramp support seems broken"); + _glfw.x11.randr.gammaBroken = GL_TRUE; + } + + XRRFreeScreenResources(sr); + } + + if (XineramaQueryExtension(_glfw.x11.display, + &_glfw.x11.xinerama.versionMajor, + &_glfw.x11.xinerama.versionMinor)) + { + if (XineramaIsActive(_glfw.x11.display)) + _glfw.x11.xinerama.available = GL_TRUE; + } + + if (XQueryExtension(_glfw.x11.display, + "XInputExtension", + &_glfw.x11.xi.majorOpcode, + &_glfw.x11.xi.eventBase, + &_glfw.x11.xi.errorBase)) + { + _glfw.x11.xi.versionMajor = 2; + _glfw.x11.xi.versionMinor = 0; + + if (XIQueryVersion(_glfw.x11.display, + &_glfw.x11.xi.versionMajor, + &_glfw.x11.xi.versionMinor) != BadRequest) + { + _glfw.x11.xi.available = GL_TRUE; + } + } + + // Check if Xkb is supported on this display + _glfw.x11.xkb.versionMajor = 1; + _glfw.x11.xkb.versionMinor = 0; + _glfw.x11.xkb.available = + XkbQueryExtension(_glfw.x11.display, + &_glfw.x11.xkb.majorOpcode, + &_glfw.x11.xkb.eventBase, + &_glfw.x11.xkb.errorBase, + &_glfw.x11.xkb.versionMajor, + &_glfw.x11.xkb.versionMinor); + + if (_glfw.x11.xkb.available) + { + Bool supported; + + if (XkbSetDetectableAutoRepeat(_glfw.x11.display, True, &supported)) + { + if (supported) + _glfw.x11.xkb.detectable = GL_TRUE; + } + } + + // Update the key code LUT + // FIXME: We should listen to XkbMapNotify events to track changes to + // the keyboard mapping. + createKeyTables(); + + // Detect whether an EWMH-conformant window manager is running + detectEWMH(); + + // Find or create string format atoms + _glfw.x11._NULL = XInternAtom(_glfw.x11.display, "NULL", False); + _glfw.x11.UTF8_STRING = + XInternAtom(_glfw.x11.display, "UTF8_STRING", False); + _glfw.x11.COMPOUND_STRING = + XInternAtom(_glfw.x11.display, "COMPOUND_STRING", False); + _glfw.x11.ATOM_PAIR = XInternAtom(_glfw.x11.display, "ATOM_PAIR", False); + + // Find or create selection property atom + _glfw.x11.GLFW_SELECTION = + XInternAtom(_glfw.x11.display, "GLFW_SELECTION", False); + + // Find or create standard clipboard atoms + _glfw.x11.TARGETS = XInternAtom(_glfw.x11.display, "TARGETS", False); + _glfw.x11.MULTIPLE = XInternAtom(_glfw.x11.display, "MULTIPLE", False); + _glfw.x11.CLIPBOARD = XInternAtom(_glfw.x11.display, "CLIPBOARD", False); + + // Find or create clipboard manager atoms + _glfw.x11.CLIPBOARD_MANAGER = + XInternAtom(_glfw.x11.display, "CLIPBOARD_MANAGER", False); + _glfw.x11.SAVE_TARGETS = + XInternAtom(_glfw.x11.display, "SAVE_TARGETS", False); + + // Find Xdnd (drag and drop) atoms, if available + _glfw.x11.XdndAware = XInternAtom(_glfw.x11.display, "XdndAware", True); + _glfw.x11.XdndEnter = XInternAtom(_glfw.x11.display, "XdndEnter", True); + _glfw.x11.XdndPosition = XInternAtom(_glfw.x11.display, "XdndPosition", True); + _glfw.x11.XdndStatus = XInternAtom(_glfw.x11.display, "XdndStatus", True); + _glfw.x11.XdndActionCopy = XInternAtom(_glfw.x11.display, "XdndActionCopy", True); + _glfw.x11.XdndDrop = XInternAtom(_glfw.x11.display, "XdndDrop", True); + _glfw.x11.XdndLeave = XInternAtom(_glfw.x11.display, "XdndLeave", True); + _glfw.x11.XdndFinished = XInternAtom(_glfw.x11.display, "XdndFinished", True); + _glfw.x11.XdndSelection = XInternAtom(_glfw.x11.display, "XdndSelection", True); + + return GL_TRUE; +} + +// Create a blank cursor for hidden and disabled cursor modes +// +static Cursor createNULLCursor(void) +{ + unsigned char pixels[16 * 16 * 4]; + GLFWimage image = { 16, 16, pixels }; + + memset(pixels, 0, sizeof(pixels)); + + return _glfwCreateCursor(&image, 0, 0); +} + +// X error handler +// +static int errorHandler(Display *display, XErrorEvent* event) +{ + _glfw.x11.errorCode = event->error_code; + return 0; +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +// Sets the X error handler callback +// +void _glfwGrabXErrorHandler(void) +{ + _glfw.x11.errorCode = Success; + XSetErrorHandler(errorHandler); +} + +// Clears the X error handler callback +// +void _glfwReleaseXErrorHandler(void) +{ + // Synchronize to make sure all commands are processed + XSync(_glfw.x11.display, False); + XSetErrorHandler(NULL); +} + +// Reports the specified error, appending information about the last X error +// +void _glfwInputXError(int error, const char* message) +{ + char buffer[8192]; + XGetErrorText(_glfw.x11.display, _glfw.x11.errorCode, + buffer, sizeof(buffer)); + + _glfwInputError(error, "%s: %s", message, buffer); +} + +// Creates a native cursor object from the specified image and hotspot +// +Cursor _glfwCreateCursor(const GLFWimage* image, int xhot, int yhot) +{ + int i; + Cursor cursor; + + XcursorImage* native = XcursorImageCreate(image->width, image->height); + if (native == NULL) + return None; + + native->xhot = xhot; + native->yhot = yhot; + + unsigned char* source = (unsigned char*) image->pixels; + XcursorPixel* target = native->pixels; + + for (i = 0; i < image->width * image->height; i++, target++, source += 4) + { + *target = (source[3] << 24) | + (source[0] << 16) | + (source[1] << 8) | + source[2]; + } + + cursor = XcursorImageLoadCursor(_glfw.x11.display, native); + XcursorImageDestroy(native); + + return cursor; +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +int _glfwPlatformInit(void) +{ + if (strcmp(setlocale(LC_CTYPE, NULL), "C") == 0) + setlocale(LC_CTYPE, ""); + + XInitThreads(); + + _glfw.x11.display = XOpenDisplay(NULL); + if (!_glfw.x11.display) + { + _glfwInputError(GLFW_API_UNAVAILABLE, "X11: Failed to open X display"); + return GL_FALSE; + } + + _glfw.x11.screen = DefaultScreen(_glfw.x11.display); + _glfw.x11.root = RootWindow(_glfw.x11.display, _glfw.x11.screen); + _glfw.x11.context = XUniqueContext(); + + if (!initExtensions()) + return GL_FALSE; + + _glfw.x11.cursor = createNULLCursor(); + + if (XSupportsLocale()) + { + XSetLocaleModifiers(""); + + _glfw.x11.im = XOpenIM(_glfw.x11.display, 0, 0, 0); + if (_glfw.x11.im) + { + if (!hasUsableInputMethodStyle()) + { + XCloseIM(_glfw.x11.im); + _glfw.x11.im = NULL; + } + } + } + + if (!_glfwInitContextAPI()) + return GL_FALSE; + + if (!_glfwInitJoysticks()) + return GL_FALSE; + + _glfwInitTimer(); + + return GL_TRUE; +} + +void _glfwPlatformTerminate(void) +{ + if (_glfw.x11.cursor) + { + XFreeCursor(_glfw.x11.display, _glfw.x11.cursor); + _glfw.x11.cursor = (Cursor) 0; + } + + free(_glfw.x11.clipboardString); + + if (_glfw.x11.im) + { + XCloseIM(_glfw.x11.im); + _glfw.x11.im = NULL; + } + + _glfwTerminateJoysticks(); + _glfwTerminateContextAPI(); + + if (_glfw.x11.display) + { + XCloseDisplay(_glfw.x11.display); + _glfw.x11.display = NULL; + } +} + +const char* _glfwPlatformGetVersionString(void) +{ + const char* version = _GLFW_VERSION_NUMBER " X11" +#if defined(_GLFW_GLX) + " GLX" +#elif defined(_GLFW_EGL) + " EGL" +#endif +#if defined(_GLFW_HAS_GLXGETPROCADDRESS) + " glXGetProcAddress" +#elif defined(_GLFW_HAS_GLXGETPROCADDRESSARB) + " glXGetProcAddressARB" +#elif defined(_GLFW_HAS_GLXGETPROCADDRESSEXT) + " glXGetProcAddressEXT" +#elif defined(_GLFW_DLOPEN_LIBGL) + " dlsym(libGL)" +#endif +#if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK) + " clock_gettime" +#endif +#if defined(__linux__) + " /dev/js" +#endif +#if defined(_GLFW_BUILD_DLL) + " shared" +#endif + ; + + return version; +} + diff --git a/testbed/glfw/src/x11_monitor.c b/testbed/glfw/src/x11_monitor.c new file mode 100644 index 00000000..6265070f --- /dev/null +++ b/testbed/glfw/src/x11_monitor.c @@ -0,0 +1,490 @@ +//======================================================================== +// GLFW 3.1 X11 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2010 Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include "internal.h" + +#include +#include +#include + + +// Check whether the display mode should be included in enumeration +// +static GLboolean modeIsGood(const XRRModeInfo* mi) +{ + return (mi->modeFlags & RR_Interlace) == 0; +} + +// Calculates the refresh rate, in Hz, from the specified RandR mode info +// +static int calculateRefreshRate(const XRRModeInfo* mi) +{ + if (mi->hTotal && mi->vTotal) + return (int) ((double) mi->dotClock / ((double) mi->hTotal * (double) mi->vTotal)); + else + return 0; +} + +// Returns the mode info for a RandR mode XID +// +static const XRRModeInfo* getModeInfo(const XRRScreenResources* sr, RRMode id) +{ + int i; + + for (i = 0; i < sr->nmode; i++) + { + if (sr->modes[i].id == id) + return sr->modes + i; + } + + return NULL; +} + +// Convert RandR mode info to GLFW video mode +// +static GLFWvidmode vidmodeFromModeInfo(const XRRModeInfo* mi, + const XRRCrtcInfo* ci) +{ + GLFWvidmode mode; + + if (ci->rotation == RR_Rotate_90 || ci->rotation == RR_Rotate_270) + { + mode.width = mi->height; + mode.height = mi->width; + } + else + { + mode.width = mi->width; + mode.height = mi->height; + } + + mode.refreshRate = calculateRefreshRate(mi); + + _glfwSplitBPP(DefaultDepth(_glfw.x11.display, _glfw.x11.screen), + &mode.redBits, &mode.greenBits, &mode.blueBits); + + return mode; +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +// Set the current video mode for the specified monitor +// +GLboolean _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired) +{ + if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken) + { + XRRScreenResources* sr; + XRRCrtcInfo* ci; + XRROutputInfo* oi; + GLFWvidmode current; + const GLFWvidmode* best; + RRMode native = None; + int i; + + best = _glfwChooseVideoMode(monitor, desired); + _glfwPlatformGetVideoMode(monitor, ¤t); + if (_glfwCompareVideoModes(¤t, best) == 0) + return GL_TRUE; + + sr = XRRGetScreenResources(_glfw.x11.display, _glfw.x11.root); + ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc); + oi = XRRGetOutputInfo(_glfw.x11.display, sr, monitor->x11.output); + + for (i = 0; i < oi->nmode; i++) + { + const XRRModeInfo* mi = getModeInfo(sr, oi->modes[i]); + if (!modeIsGood(mi)) + continue; + + const GLFWvidmode mode = vidmodeFromModeInfo(mi, ci); + if (_glfwCompareVideoModes(best, &mode) == 0) + { + native = mi->id; + break; + } + } + + if (native) + { + if (monitor->x11.oldMode == None) + monitor->x11.oldMode = ci->mode; + + XRRSetCrtcConfig(_glfw.x11.display, + sr, monitor->x11.crtc, + CurrentTime, + ci->x, ci->y, + native, + ci->rotation, + ci->outputs, + ci->noutput); + } + + XRRFreeOutputInfo(oi); + XRRFreeCrtcInfo(ci); + XRRFreeScreenResources(sr); + + if (!native) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "X11: Monitor mode list changed"); + return GL_FALSE; + } + } + + return GL_TRUE; +} + +// Restore the saved (original) video mode for the specified monitor +// +void _glfwRestoreVideoMode(_GLFWmonitor* monitor) +{ + if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken) + { + XRRScreenResources* sr; + XRRCrtcInfo* ci; + + if (monitor->x11.oldMode == None) + return; + + sr = XRRGetScreenResources(_glfw.x11.display, _glfw.x11.root); + ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc); + + XRRSetCrtcConfig(_glfw.x11.display, + sr, monitor->x11.crtc, + CurrentTime, + ci->x, ci->y, + monitor->x11.oldMode, + ci->rotation, + ci->outputs, + ci->noutput); + + XRRFreeCrtcInfo(ci); + XRRFreeScreenResources(sr); + + monitor->x11.oldMode = None; + } +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +_GLFWmonitor** _glfwPlatformGetMonitors(int* count) +{ + int i, j, k, size = 0, found = 0; + _GLFWmonitor** monitors = NULL; + + *count = 0; + + if (_glfw.x11.randr.available) + { + int screenCount = 0; + XineramaScreenInfo* screens = NULL; + XRRScreenResources* sr = XRRGetScreenResources(_glfw.x11.display, + _glfw.x11.root); + RROutput primary = XRRGetOutputPrimary(_glfw.x11.display, + _glfw.x11.root); + + if (_glfw.x11.xinerama.available) + screens = XineramaQueryScreens(_glfw.x11.display, &screenCount); + + for (i = 0; i < sr->ncrtc; i++) + { + XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, + sr, sr->crtcs[i]); + + for (j = 0; j < ci->noutput; j++) + { + int widthMM, heightMM; + XRROutputInfo* oi = XRRGetOutputInfo(_glfw.x11.display, + sr, ci->outputs[j]); + if (oi->connection != RR_Connected) + { + XRRFreeOutputInfo(oi); + continue; + } + + if (found == size) + { + size += 4; + monitors = realloc(monitors, sizeof(_GLFWmonitor*) * size); + } + + if (ci->rotation == RR_Rotate_90 || ci->rotation == RR_Rotate_270) + { + widthMM = oi->mm_height; + heightMM = oi->mm_width; + } + else + { + widthMM = oi->mm_width; + heightMM = oi->mm_height; + } + + monitors[found] = _glfwAllocMonitor(oi->name, widthMM, heightMM); + monitors[found]->x11.output = ci->outputs[j]; + monitors[found]->x11.crtc = oi->crtc; + + for (k = 0; k < screenCount; k++) + { + if (screens[k].x_org == ci->x && + screens[k].y_org == ci->y && + screens[k].width == ci->width && + screens[k].height == ci->height) + { + monitors[found]->x11.index = k; + break; + } + } + + XRRFreeOutputInfo(oi); + + if (ci->outputs[j] == primary) + _GLFW_SWAP_POINTERS(monitors[0], monitors[found]); + + found++; + } + + XRRFreeCrtcInfo(ci); + } + + XRRFreeScreenResources(sr); + + if (screens) + XFree(screens); + + if (found == 0) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "X11: RandR monitor support seems broken"); + _glfw.x11.randr.monitorBroken = GL_TRUE; + } + } + + if (!monitors) + { + monitors = calloc(1, sizeof(_GLFWmonitor*)); + monitors[0] = _glfwAllocMonitor("Display", + DisplayWidthMM(_glfw.x11.display, + _glfw.x11.screen), + DisplayHeightMM(_glfw.x11.display, + _glfw.x11.screen)); + found = 1; + } + + *count = found; + return monitors; +} + +GLboolean _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second) +{ + return first->x11.crtc == second->x11.crtc; +} + +void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos) +{ + if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken) + { + XRRScreenResources* sr; + XRRCrtcInfo* ci; + + sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root); + ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc); + + if (xpos) + *xpos = ci->x; + if (ypos) + *ypos = ci->y; + + XRRFreeCrtcInfo(ci); + XRRFreeScreenResources(sr); + } +} + +GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found) +{ + GLFWvidmode* result; + + *found = 0; + + // Build array of available resolutions + + if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken) + { + int i, j; + XRRScreenResources* sr; + XRRCrtcInfo* ci; + XRROutputInfo* oi; + + sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root); + ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc); + oi = XRRGetOutputInfo(_glfw.x11.display, sr, monitor->x11.output); + + result = calloc(oi->nmode, sizeof(GLFWvidmode)); + + for (i = 0; i < oi->nmode; i++) + { + const XRRModeInfo* mi = getModeInfo(sr, oi->modes[i]); + if (!modeIsGood(mi)) + continue; + + const GLFWvidmode mode = vidmodeFromModeInfo(mi, ci); + + for (j = 0; j < *found; j++) + { + if (_glfwCompareVideoModes(result + j, &mode) == 0) + break; + } + + if (j < *found) + { + // This is a duplicate, so skip it + continue; + } + + result[*found] = mode; + (*found)++; + } + + XRRFreeOutputInfo(oi); + XRRFreeCrtcInfo(ci); + XRRFreeScreenResources(sr); + } + else + { + *found = 1; + result = calloc(1, sizeof(GLFWvidmode)); + _glfwPlatformGetVideoMode(monitor, result); + } + + return result; +} + +void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) +{ + if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken) + { + XRRScreenResources* sr; + XRRCrtcInfo* ci; + + sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root); + ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc); + + *mode = vidmodeFromModeInfo(getModeInfo(sr, ci->mode), ci); + + XRRFreeCrtcInfo(ci); + XRRFreeScreenResources(sr); + } + else + { + mode->width = DisplayWidth(_glfw.x11.display, _glfw.x11.screen); + mode->height = DisplayHeight(_glfw.x11.display, _glfw.x11.screen); + mode->refreshRate = 0; + + _glfwSplitBPP(DefaultDepth(_glfw.x11.display, _glfw.x11.screen), + &mode->redBits, &mode->greenBits, &mode->blueBits); + } +} + +void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) +{ + if (_glfw.x11.randr.available && !_glfw.x11.randr.gammaBroken) + { + const size_t size = XRRGetCrtcGammaSize(_glfw.x11.display, + monitor->x11.crtc); + XRRCrtcGamma* gamma = XRRGetCrtcGamma(_glfw.x11.display, + monitor->x11.crtc); + + _glfwAllocGammaArrays(ramp, size); + + memcpy(ramp->red, gamma->red, size * sizeof(unsigned short)); + memcpy(ramp->green, gamma->green, size * sizeof(unsigned short)); + memcpy(ramp->blue, gamma->blue, size * sizeof(unsigned short)); + + XRRFreeGamma(gamma); + } + else if (_glfw.x11.vidmode.available) + { + int size; + XF86VidModeGetGammaRampSize(_glfw.x11.display, _glfw.x11.screen, &size); + + _glfwAllocGammaArrays(ramp, size); + + XF86VidModeGetGammaRamp(_glfw.x11.display, + _glfw.x11.screen, + ramp->size, ramp->red, ramp->green, ramp->blue); + } +} + +void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) +{ + if (_glfw.x11.randr.available && !_glfw.x11.randr.gammaBroken) + { + XRRCrtcGamma* gamma = XRRAllocGamma(ramp->size); + + memcpy(gamma->red, ramp->red, ramp->size * sizeof(unsigned short)); + memcpy(gamma->green, ramp->green, ramp->size * sizeof(unsigned short)); + memcpy(gamma->blue, ramp->blue, ramp->size * sizeof(unsigned short)); + + XRRSetCrtcGamma(_glfw.x11.display, monitor->x11.crtc, gamma); + XRRFreeGamma(gamma); + } + else if (_glfw.x11.vidmode.available) + { + XF86VidModeSetGammaRamp(_glfw.x11.display, + _glfw.x11.screen, + ramp->size, + (unsigned short*) ramp->red, + (unsigned short*) ramp->green, + (unsigned short*) ramp->blue); + } +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW native API ////// +////////////////////////////////////////////////////////////////////////// + +GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* handle) +{ + _GLFWmonitor* monitor = (_GLFWmonitor*) handle; + _GLFW_REQUIRE_INIT_OR_RETURN(None); + return monitor->x11.crtc; +} + +GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* handle) +{ + _GLFWmonitor* monitor = (_GLFWmonitor*) handle; + _GLFW_REQUIRE_INIT_OR_RETURN(None); + return monitor->x11.output; +} + diff --git a/testbed/glfw/src/x11_platform.h b/testbed/glfw/src/x11_platform.h new file mode 100644 index 00000000..81d1bef1 --- /dev/null +++ b/testbed/glfw/src/x11_platform.h @@ -0,0 +1,259 @@ +//======================================================================== +// GLFW 3.1 X11 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2010 Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#ifndef _x11_platform_h_ +#define _x11_platform_h_ + +#include +#include +#include + +#include +#include +#include +#include + +// The Xf86VidMode extension provides fallback gamma control +#include + +// The XRandR extension provides mode setting and gamma control +#include + +// The XInput2 extension provides improved input events +#include + +// The Xkb extension provides improved keyboard support +#include + +// The Xinerama extension provides legacy monitor indices +#include + +#include "posix_tls.h" + +#if defined(_GLFW_GLX) + #define _GLFW_X11_CONTEXT_VISUAL window->glx.visual + #include "glx_context.h" +#elif defined(_GLFW_EGL) + #define _GLFW_X11_CONTEXT_VISUAL window->egl.visual + #define _GLFW_EGL_NATIVE_WINDOW window->x11.handle + #define _GLFW_EGL_NATIVE_DISPLAY _glfw.x11.display + #include "egl_context.h" +#else + #error "No supported context creation API selected" +#endif + +#include "posix_time.h" +#include "linux_joystick.h" +#include "xkb_unicode.h" + +#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowX11 x11 +#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryX11 x11 +#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorX11 x11 +#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorX11 x11 + + +// X11-specific per-window data +// +typedef struct _GLFWwindowX11 +{ + Colormap colormap; + Window handle; + XIC ic; + + GLboolean overrideRedirect; + + // Cached position and size used to filter out duplicate events + int width, height; + int xpos, ypos; + + // The last received cursor position, regardless of source + double cursorPosX, cursorPosY; + // The last position the cursor was warped to by GLFW + int warpPosX, warpPosY; + +} _GLFWwindowX11; + + +// X11-specific global data +// +typedef struct _GLFWlibraryX11 +{ + Display* display; + int screen; + Window root; + + // Invisible cursor for hidden cursor mode + Cursor cursor; + // Context for mapping window XIDs to _GLFWwindow pointers + XContext context; + // XIM input method + XIM im; + // True if window manager supports EWMH + GLboolean hasEWMH; + // Most recent error code received by X error handler + int errorCode; + // Clipboard string (while the selection is owned) + char* clipboardString; + // X11 keycode to GLFW key LUT + short int publicKeys[256]; + + // Window manager atoms + Atom WM_PROTOCOLS; + Atom WM_STATE; + Atom WM_DELETE_WINDOW; + Atom NET_WM_NAME; + Atom NET_WM_ICON_NAME; + Atom NET_WM_PID; + Atom NET_WM_PING; + Atom NET_WM_STATE; + Atom NET_WM_STATE_ABOVE; + Atom NET_WM_STATE_FULLSCREEN; + Atom NET_WM_BYPASS_COMPOSITOR; + Atom NET_WM_FULLSCREEN_MONITORS; + Atom NET_ACTIVE_WINDOW; + Atom NET_FRAME_EXTENTS; + Atom NET_REQUEST_FRAME_EXTENTS; + Atom MOTIF_WM_HINTS; + + // Xdnd (drag and drop) atoms + Atom XdndAware; + Atom XdndEnter; + Atom XdndPosition; + Atom XdndStatus; + Atom XdndActionCopy; + Atom XdndDrop; + Atom XdndLeave; + Atom XdndFinished; + Atom XdndSelection; + + // Selection (clipboard) atoms + Atom TARGETS; + Atom MULTIPLE; + Atom CLIPBOARD; + Atom CLIPBOARD_MANAGER; + Atom SAVE_TARGETS; + Atom _NULL; + Atom UTF8_STRING; + Atom COMPOUND_STRING; + Atom ATOM_PAIR; + Atom GLFW_SELECTION; + + struct { + GLboolean available; + int eventBase; + int errorBase; + } vidmode; + + struct { + GLboolean available; + int eventBase; + int errorBase; + int versionMajor; + int versionMinor; + GLboolean gammaBroken; + GLboolean monitorBroken; + } randr; + + struct { + GLboolean available; + GLboolean detectable; + int majorOpcode; + int eventBase; + int errorBase; + int versionMajor; + int versionMinor; + } xkb; + + struct { + GLboolean available; + int majorOpcode; + int eventBase; + int errorBase; + int versionMajor; + int versionMinor; + } xi; + + struct { + int count; + int timeout; + int interval; + int blanking; + int exposure; + } saver; + + struct { + Window source; + } xdnd; + + struct { + GLboolean available; + int versionMajor; + int versionMinor; + } xinerama; + +} _GLFWlibraryX11; + + +// X11-specific per-monitor data +// +typedef struct _GLFWmonitorX11 +{ + RROutput output; + RRCrtc crtc; + RRMode oldMode; + + // Index of corresponding Xinerama screen, + // for EWMH full screen window placement + int index; + +} _GLFWmonitorX11; + + +// X11-specific per-cursor data +// +typedef struct _GLFWcursorX11 +{ + Cursor handle; + +} _GLFWcursorX11; + + +GLboolean _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired); +void _glfwRestoreVideoMode(_GLFWmonitor* monitor); + +Cursor _glfwCreateCursor(const GLFWimage* image, int xhot, int yhot); + +unsigned long _glfwGetWindowProperty(Window window, + Atom property, + Atom type, + unsigned char** value); + +void _glfwGrabXErrorHandler(void); +void _glfwReleaseXErrorHandler(void); +void _glfwInputXError(int error, const char* message); + +#endif // _x11_platform_h_ diff --git a/testbed/glfw/src/x11_window.c b/testbed/glfw/src/x11_window.c new file mode 100644 index 00000000..0380b581 --- /dev/null +++ b/testbed/glfw/src/x11_window.c @@ -0,0 +1,1935 @@ +//======================================================================== +// GLFW 3.1 X11 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2010 Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include "internal.h" + +#include + +#include + +#include +#include +#include +#include + +// Action for EWMH client messages +#define _NET_WM_STATE_REMOVE 0 +#define _NET_WM_STATE_ADD 1 +#define _NET_WM_STATE_TOGGLE 2 + +// Additional mouse button names for XButtonEvent +#define Button6 6 +#define Button7 7 + +typedef struct +{ + unsigned long flags; + unsigned long functions; + unsigned long decorations; + long input_mode; + unsigned long status; +} MotifWmHints; + +#define MWM_HINTS_DECORATIONS (1L << 1) + + +// Returns whether the window is iconified +// +static int getWindowState(_GLFWwindow* window) +{ + int result = WithdrawnState; + struct { + CARD32 state; + Window icon; + } *state = NULL; + + if (_glfwGetWindowProperty(window->x11.handle, + _glfw.x11.WM_STATE, + _glfw.x11.WM_STATE, + (unsigned char**) &state) >= 2) + { + result = state->state; + } + + XFree(state); + return result; +} + +// Returns whether the event is a selection event +// +static Bool isFrameExtentsEvent(Display* display, XEvent* event, XPointer pointer) +{ + _GLFWwindow* window = (_GLFWwindow*) pointer; + return event->type == PropertyNotify && + event->xproperty.state == PropertyNewValue && + event->xproperty.window == window->x11.handle && + event->xproperty.atom == _glfw.x11.NET_FRAME_EXTENTS; +} + +// Translates a GLFW standard cursor to a font cursor shape +// +static int translateCursorShape(int shape) +{ + switch (shape) + { + case GLFW_ARROW_CURSOR: + return XC_arrow; + case GLFW_IBEAM_CURSOR: + return XC_xterm; + case GLFW_CROSSHAIR_CURSOR: + return XC_crosshair; + case GLFW_HAND_CURSOR: + return XC_hand1; + case GLFW_HRESIZE_CURSOR: + return XC_sb_h_double_arrow; + case GLFW_VRESIZE_CURSOR: + return XC_sb_v_double_arrow; + } + + return 0; +} + +// Translates an X event modifier state mask +// +static int translateState(int state) +{ + int mods = 0; + + if (state & ShiftMask) + mods |= GLFW_MOD_SHIFT; + if (state & ControlMask) + mods |= GLFW_MOD_CONTROL; + if (state & Mod1Mask) + mods |= GLFW_MOD_ALT; + if (state & Mod4Mask) + mods |= GLFW_MOD_SUPER; + + return mods; +} + +// Translates an X Window key to internal coding +// +static int translateKey(int scancode) +{ + // Use the pre-filled LUT (see createKeyTables() in x11_init.c) + if (scancode < 0 || scancode > 255) + return GLFW_KEY_UNKNOWN; + + return _glfw.x11.publicKeys[scancode]; +} + +// Return the GLFW window corresponding to the specified X11 window +// +static _GLFWwindow* findWindowByHandle(Window handle) +{ + _GLFWwindow* window; + + if (XFindContext(_glfw.x11.display, + handle, + _glfw.x11.context, + (XPointer*) &window) != 0) + { + return NULL; + } + + return window; +} + +// Adds or removes an EWMH state to a window +// +static void changeWindowState(_GLFWwindow* window, Atom state, int action) +{ + XEvent event; + memset(&event, 0, sizeof(event)); + + event.type = ClientMessage; + event.xclient.window = window->x11.handle; + event.xclient.format = 32; // Data is 32-bit longs + event.xclient.message_type = _glfw.x11.NET_WM_STATE; + event.xclient.data.l[0] = action; + event.xclient.data.l[1] = state; + event.xclient.data.l[2] = 0; // No secondary property + event.xclient.data.l[3] = 1; // Sender is a normal application + + XSendEvent(_glfw.x11.display, + _glfw.x11.root, + False, + SubstructureNotifyMask | SubstructureRedirectMask, + &event); +} + +// Splits and translates a text/uri-list into separate file paths +// +static char** parseUriList(char* text, int* count) +{ + const char* prefix = "file://"; + char** names = NULL; + char* line; + + *count = 0; + + while ((line = strtok(text, "\r\n"))) + { + text = NULL; + + if (*line == '#') + continue; + + if (strncmp(line, prefix, strlen(prefix)) == 0) + line += strlen(prefix); + + (*count)++; + + char* name = calloc(strlen(line) + 1, 1); + names = realloc(names, *count * sizeof(char*)); + names[*count - 1] = name; + + while (*line) + { + if (line[0] == '%' && line[1] && line[2]) + { + const char digits[3] = { line[1], line[2], '\0' }; + *name = strtol(digits, NULL, 16); + line += 2; + } + else + *name = *line; + + name++; + line++; + } + } + + return names; +} + +// Create the X11 window (and its colormap) +// +static GLboolean createWindow(_GLFWwindow* window, + const _GLFWwndconfig* wndconfig) +{ + unsigned long wamask; + XSetWindowAttributes wa; + XVisualInfo* visual = _GLFW_X11_CONTEXT_VISUAL; + + // Every window needs a colormap + // Create one based on the visual used by the current context + // TODO: Decouple this from context creation + + window->x11.colormap = XCreateColormap(_glfw.x11.display, + _glfw.x11.root, + visual->visual, + AllocNone); + + // Create the actual window + { + wamask = CWBorderPixel | CWColormap | CWEventMask; + + wa.colormap = window->x11.colormap; + wa.border_pixel = 0; + wa.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask | + PointerMotionMask | ButtonPressMask | ButtonReleaseMask | + ExposureMask | FocusChangeMask | VisibilityChangeMask | + EnterWindowMask | LeaveWindowMask | PropertyChangeMask; + + _glfwGrabXErrorHandler(); + + window->x11.handle = XCreateWindow(_glfw.x11.display, + _glfw.x11.root, + 0, 0, + wndconfig->width, wndconfig->height, + 0, // Border width + visual->depth, // Color depth + InputOutput, + visual->visual, + wamask, + &wa); + + _glfwReleaseXErrorHandler(); + + if (!window->x11.handle) + { + _glfwInputXError(GLFW_PLATFORM_ERROR, + "X11: Failed to create window"); + return GL_FALSE; + } + + if (!wndconfig->decorated) + { + MotifWmHints hints; + hints.flags = MWM_HINTS_DECORATIONS; + hints.decorations = 0; + + XChangeProperty(_glfw.x11.display, window->x11.handle, + _glfw.x11.MOTIF_WM_HINTS, + _glfw.x11.MOTIF_WM_HINTS, 32, + PropModeReplace, + (unsigned char*) &hints, + sizeof(MotifWmHints) / sizeof(long)); + } + + XSaveContext(_glfw.x11.display, + window->x11.handle, + _glfw.x11.context, + (XPointer) window); + } + + if (window->monitor && !_glfw.x11.hasEWMH) + { + // This is the butcher's way of removing window decorations + // Setting the override-redirect attribute on a window makes the window + // manager ignore the window completely (ICCCM, section 4) + // The good thing is that this makes undecorated full screen windows + // easy to do; the bad thing is that we have to do everything manually + // and some things (like iconify/restore) won't work at all, as those + // are tasks usually performed by the window manager + + XSetWindowAttributes attributes; + attributes.override_redirect = True; + XChangeWindowAttributes(_glfw.x11.display, + window->x11.handle, + CWOverrideRedirect, + &attributes); + + window->x11.overrideRedirect = GL_TRUE; + } + + // Declare the WM protocols supported by GLFW + { + int count = 0; + Atom protocols[2]; + + // The WM_DELETE_WINDOW ICCCM protocol + // Basic window close notification protocol + if (_glfw.x11.WM_DELETE_WINDOW) + protocols[count++] = _glfw.x11.WM_DELETE_WINDOW; + + // The _NET_WM_PING EWMH protocol + // Tells the WM to ping the GLFW window and flag the application as + // unresponsive if the WM doesn't get a reply within a few seconds + if (_glfw.x11.NET_WM_PING) + protocols[count++] = _glfw.x11.NET_WM_PING; + + if (count > 0) + { + XSetWMProtocols(_glfw.x11.display, window->x11.handle, + protocols, count); + } + } + + if (_glfw.x11.NET_WM_PID) + { + const pid_t pid = getpid(); + + XChangeProperty(_glfw.x11.display, window->x11.handle, + _glfw.x11.NET_WM_PID, XA_CARDINAL, 32, + PropModeReplace, + (unsigned char*) &pid, 1); + } + + // Set ICCCM WM_HINTS property + { + XWMHints* hints = XAllocWMHints(); + if (!hints) + { + _glfwInputError(GLFW_OUT_OF_MEMORY, + "X11: Failed to allocate WM hints"); + return GL_FALSE; + } + + hints->flags = StateHint; + hints->initial_state = NormalState; + + XSetWMHints(_glfw.x11.display, window->x11.handle, hints); + XFree(hints); + } + + // Set ICCCM WM_NORMAL_HINTS property (even if no parts are set) + { + XSizeHints* hints = XAllocSizeHints(); + hints->flags = 0; + + if (wndconfig->monitor) + { + hints->flags |= PPosition; + _glfwPlatformGetMonitorPos(wndconfig->monitor, &hints->x, &hints->y); + } + else + { + // HACK: Explicitly setting PPosition to any value causes some WMs, + // notably Compiz and Metacity, to honor the position of + // unmapped windows set by XMoveWindow + hints->flags |= PPosition; + hints->x = hints->y = 0; + } + + if (!wndconfig->resizable) + { + hints->flags |= (PMinSize | PMaxSize); + hints->min_width = hints->max_width = wndconfig->width; + hints->min_height = hints->max_height = wndconfig->height; + } + + XSetWMNormalHints(_glfw.x11.display, window->x11.handle, hints); + XFree(hints); + } + + // Set ICCCM WM_CLASS property + // HACK: Until a mechanism for specifying the application name is added, the + // initial window title is used as the window class name + if (strlen(wndconfig->title)) + { + XClassHint* hint = XAllocClassHint(); + hint->res_name = (char*) wndconfig->title; + hint->res_class = (char*) wndconfig->title; + + XSetClassHint(_glfw.x11.display, window->x11.handle, hint); + XFree(hint); + } + + if (_glfw.x11.xi.available) + { + // Select for XInput2 events + + XIEventMask eventmask; + unsigned char mask[] = { 0 }; + + eventmask.deviceid = 2; + eventmask.mask_len = sizeof(mask); + eventmask.mask = mask; + XISetMask(mask, XI_Motion); + + XISelectEvents(_glfw.x11.display, window->x11.handle, &eventmask, 1); + } + + if (_glfw.x11.XdndAware) + { + // Announce support for Xdnd (drag and drop) + const Atom version = 5; + XChangeProperty(_glfw.x11.display, window->x11.handle, + _glfw.x11.XdndAware, XA_ATOM, 32, + PropModeReplace, (unsigned char*) &version, 1); + } + + if (_glfw.x11.NET_REQUEST_FRAME_EXTENTS) + { + // Ensure _NET_FRAME_EXTENTS is set, allowing glfwGetWindowFrameSize to + // function before the window is mapped + + XEvent event; + memset(&event, 0, sizeof(event)); + + event.type = ClientMessage; + event.xclient.window = window->x11.handle; + event.xclient.format = 32; // Data is 32-bit longs + event.xclient.message_type = _glfw.x11.NET_REQUEST_FRAME_EXTENTS; + + XSendEvent(_glfw.x11.display, + _glfw.x11.root, + False, + SubstructureNotifyMask | SubstructureRedirectMask, + &event); + XIfEvent(_glfw.x11.display, &event, isFrameExtentsEvent, (XPointer) window); + } + + if (wndconfig->floating && !wndconfig->monitor) + { + if (_glfw.x11.NET_WM_STATE && _glfw.x11.NET_WM_STATE_ABOVE) + { + changeWindowState(window, + _glfw.x11.NET_WM_STATE_ABOVE, + _NET_WM_STATE_ADD); + } + } + + _glfwPlatformSetWindowTitle(window, wndconfig->title); + + XRRSelectInput(_glfw.x11.display, window->x11.handle, + RRScreenChangeNotifyMask); + + if (_glfw.x11.im) + { + window->x11.ic = XCreateIC(_glfw.x11.im, + XNInputStyle, + XIMPreeditNothing | XIMStatusNothing, + XNClientWindow, + window->x11.handle, + XNFocusWindow, + window->x11.handle, + NULL); + } + + _glfwPlatformGetWindowPos(window, &window->x11.xpos, &window->x11.ypos); + _glfwPlatformGetWindowSize(window, &window->x11.width, &window->x11.height); + + return GL_TRUE; +} + +// Hide the mouse cursor +// +static void hideCursor(_GLFWwindow* window) +{ + XUngrabPointer(_glfw.x11.display, CurrentTime); + XDefineCursor(_glfw.x11.display, window->x11.handle, _glfw.x11.cursor); +} + +// Disable the mouse cursor +// +static void disableCursor(_GLFWwindow* window) +{ + XGrabPointer(_glfw.x11.display, window->x11.handle, True, + ButtonPressMask | ButtonReleaseMask | PointerMotionMask, + GrabModeAsync, GrabModeAsync, + window->x11.handle, _glfw.x11.cursor, CurrentTime); +} + +// Restores the mouse cursor +// +static void restoreCursor(_GLFWwindow* window) +{ + XUngrabPointer(_glfw.x11.display, CurrentTime); + + if (window->cursor) + { + XDefineCursor(_glfw.x11.display, window->x11.handle, + window->cursor->x11.handle); + } + else + XUndefineCursor(_glfw.x11.display, window->x11.handle); +} + +// Returns whether the event is a selection event +// +static Bool isSelectionEvent(Display* display, XEvent* event, XPointer pointer) +{ + return event->type == SelectionRequest || + event->type == SelectionNotify || + event->type == SelectionClear; +} + +// Set the specified property to the selection converted to the requested target +// +static Atom writeTargetToProperty(const XSelectionRequestEvent* request) +{ + int i; + const Atom formats[] = { _glfw.x11.UTF8_STRING, + _glfw.x11.COMPOUND_STRING, + XA_STRING }; + const int formatCount = sizeof(formats) / sizeof(formats[0]); + + if (request->property == None) + { + // The requester is a legacy client (ICCCM section 2.2) + // We don't support legacy clients, so fail here + return None; + } + + if (request->target == _glfw.x11.TARGETS) + { + // The list of supported targets was requested + + const Atom targets[] = { _glfw.x11.TARGETS, + _glfw.x11.MULTIPLE, + _glfw.x11.UTF8_STRING, + _glfw.x11.COMPOUND_STRING, + XA_STRING }; + + XChangeProperty(_glfw.x11.display, + request->requestor, + request->property, + XA_ATOM, + 32, + PropModeReplace, + (unsigned char*) targets, + sizeof(targets) / sizeof(targets[0])); + + return request->property; + } + + if (request->target == _glfw.x11.MULTIPLE) + { + // Multiple conversions were requested + + Atom* targets; + unsigned long i, count; + + count = _glfwGetWindowProperty(request->requestor, + request->property, + _glfw.x11.ATOM_PAIR, + (unsigned char**) &targets); + + for (i = 0; i < count; i += 2) + { + int j; + + for (j = 0; j < formatCount; j++) + { + if (targets[i] == formats[j]) + break; + } + + if (j < formatCount) + { + XChangeProperty(_glfw.x11.display, + request->requestor, + targets[i + 1], + targets[i], + 8, + PropModeReplace, + (unsigned char*) _glfw.x11.clipboardString, + strlen(_glfw.x11.clipboardString)); + } + else + targets[i + 1] = None; + } + + XChangeProperty(_glfw.x11.display, + request->requestor, + request->property, + _glfw.x11.ATOM_PAIR, + 32, + PropModeReplace, + (unsigned char*) targets, + count); + + XFree(targets); + + return request->property; + } + + if (request->target == _glfw.x11.SAVE_TARGETS) + { + // The request is a check whether we support SAVE_TARGETS + // It should be handled as a no-op side effect target + + XChangeProperty(_glfw.x11.display, + request->requestor, + request->property, + _glfw.x11._NULL, + 32, + PropModeReplace, + NULL, + 0); + + return request->property; + } + + // Conversion to a data target was requested + + for (i = 0; i < formatCount; i++) + { + if (request->target == formats[i]) + { + // The requested target is one we support + + XChangeProperty(_glfw.x11.display, + request->requestor, + request->property, + request->target, + 8, + PropModeReplace, + (unsigned char*) _glfw.x11.clipboardString, + strlen(_glfw.x11.clipboardString)); + + return request->property; + } + } + + // The requested target is not supported + + return None; +} + +static void handleSelectionClear(XEvent* event) +{ + free(_glfw.x11.clipboardString); + _glfw.x11.clipboardString = NULL; +} + +static void handleSelectionRequest(XEvent* event) +{ + const XSelectionRequestEvent* request = &event->xselectionrequest; + + XEvent response; + memset(&response, 0, sizeof(response)); + + response.xselection.property = writeTargetToProperty(request); + response.xselection.type = SelectionNotify; + response.xselection.display = request->display; + response.xselection.requestor = request->requestor; + response.xselection.selection = request->selection; + response.xselection.target = request->target; + response.xselection.time = request->time; + + XSendEvent(_glfw.x11.display, request->requestor, False, 0, &response); +} + +static void pushSelectionToManager(_GLFWwindow* window) +{ + XConvertSelection(_glfw.x11.display, + _glfw.x11.CLIPBOARD_MANAGER, + _glfw.x11.SAVE_TARGETS, + None, + window->x11.handle, + CurrentTime); + + for (;;) + { + XEvent event; + + if (!XCheckIfEvent(_glfw.x11.display, &event, isSelectionEvent, NULL)) + continue; + + switch (event.type) + { + case SelectionRequest: + handleSelectionRequest(&event); + break; + + case SelectionClear: + handleSelectionClear(&event); + break; + + case SelectionNotify: + { + if (event.xselection.target == _glfw.x11.SAVE_TARGETS) + { + // This means one of two things; either the selection was + // not owned, which means there is no clipboard manager, or + // the transfer to the clipboard manager has completed + // In either case, it means we are done here + return; + } + + break; + } + } + } +} + +// Enter full screen mode +// +static void enterFullscreenMode(_GLFWwindow* window) +{ + if (_glfw.x11.saver.count == 0) + { + // Remember old screen saver settings + XGetScreenSaver(_glfw.x11.display, + &_glfw.x11.saver.timeout, + &_glfw.x11.saver.interval, + &_glfw.x11.saver.blanking, + &_glfw.x11.saver.exposure); + + // Disable screen saver + XSetScreenSaver(_glfw.x11.display, 0, 0, DontPreferBlanking, + DefaultExposures); + } + + _glfw.x11.saver.count++; + + _glfwSetVideoMode(window->monitor, &window->videoMode); + + if (_glfw.x11.NET_WM_BYPASS_COMPOSITOR) + { + const unsigned long value = 1; + + XChangeProperty(_glfw.x11.display, window->x11.handle, + _glfw.x11.NET_WM_BYPASS_COMPOSITOR, XA_CARDINAL, 32, + PropModeReplace, (unsigned char*) &value, 1); + } + + if (_glfw.x11.xinerama.available && _glfw.x11.NET_WM_FULLSCREEN_MONITORS) + { + XEvent event; + memset(&event, 0, sizeof(event)); + + event.type = ClientMessage; + event.xclient.window = window->x11.handle; + event.xclient.format = 32; // Data is 32-bit longs + event.xclient.message_type = _glfw.x11.NET_WM_FULLSCREEN_MONITORS; + event.xclient.data.l[0] = window->monitor->x11.index; + event.xclient.data.l[1] = window->monitor->x11.index; + event.xclient.data.l[2] = window->monitor->x11.index; + event.xclient.data.l[3] = window->monitor->x11.index; + + XSendEvent(_glfw.x11.display, + _glfw.x11.root, + False, + SubstructureNotifyMask | SubstructureRedirectMask, + &event); + } + + if (_glfw.x11.NET_WM_STATE && _glfw.x11.NET_WM_STATE_FULLSCREEN) + { + int x, y; + _glfwPlatformGetMonitorPos(window->monitor, &x, &y); + _glfwPlatformSetWindowPos(window, x, y); + + if (_glfw.x11.NET_ACTIVE_WINDOW) + { + // Ask the window manager to raise and focus the GLFW window + // Only focused windows with the _NET_WM_STATE_FULLSCREEN state end + // up on top of all other windows ("Stacking order" in EWMH spec) + + XEvent event; + memset(&event, 0, sizeof(event)); + + event.type = ClientMessage; + event.xclient.window = window->x11.handle; + event.xclient.format = 32; // Data is 32-bit longs + event.xclient.message_type = _glfw.x11.NET_ACTIVE_WINDOW; + event.xclient.data.l[0] = 1; // Sender is a normal application + event.xclient.data.l[1] = 0; // We don't really know the timestamp + + XSendEvent(_glfw.x11.display, + _glfw.x11.root, + False, + SubstructureNotifyMask | SubstructureRedirectMask, + &event); + } + + // Ask the window manager to make the GLFW window a full screen window + // Full screen windows are undecorated and, when focused, are kept + // on top of all other windows + + changeWindowState(window, + _glfw.x11.NET_WM_STATE_FULLSCREEN, + _NET_WM_STATE_ADD); + } + else if (window->x11.overrideRedirect) + { + // In override-redirect mode we have divorced ourselves from the + // window manager, so we need to do everything manually + int xpos, ypos; + GLFWvidmode mode; + + _glfwPlatformGetMonitorPos(window->monitor, &xpos, &ypos); + _glfwPlatformGetVideoMode(window->monitor, &mode); + + XRaiseWindow(_glfw.x11.display, window->x11.handle); + XSetInputFocus(_glfw.x11.display, window->x11.handle, + RevertToParent, CurrentTime); + XMoveWindow(_glfw.x11.display, window->x11.handle, xpos, ypos); + XResizeWindow(_glfw.x11.display, window->x11.handle, + mode.width, mode.height); + } +} + +// Leave full screen mode +// +static void leaveFullscreenMode(_GLFWwindow* window) +{ + _glfwRestoreVideoMode(window->monitor); + + _glfw.x11.saver.count--; + + if (_glfw.x11.saver.count == 0) + { + // Restore old screen saver settings + XSetScreenSaver(_glfw.x11.display, + _glfw.x11.saver.timeout, + _glfw.x11.saver.interval, + _glfw.x11.saver.blanking, + _glfw.x11.saver.exposure); + } + + if (_glfw.x11.NET_WM_BYPASS_COMPOSITOR) + { + const unsigned long value = 0; + + XChangeProperty(_glfw.x11.display, window->x11.handle, + _glfw.x11.NET_WM_BYPASS_COMPOSITOR, XA_CARDINAL, 32, + PropModeReplace, (unsigned char*) &value, 1); + } + + if (_glfw.x11.NET_WM_STATE && _glfw.x11.NET_WM_STATE_FULLSCREEN) + { + // Ask the window manager to make the GLFW window a normal window + // Normal windows usually have frames and other decorations + + changeWindowState(window, + _glfw.x11.NET_WM_STATE_FULLSCREEN, + _NET_WM_STATE_REMOVE); + } +} + +// Process the specified X event +// +static void processEvent(XEvent *event) +{ + _GLFWwindow* window = NULL; + + if (event->type != GenericEvent) + { + window = findWindowByHandle(event->xany.window); + if (window == NULL) + { + // This is an event for a window that has already been destroyed + return; + } + } + + switch (event->type) + { + case KeyPress: + { + const int key = translateKey(event->xkey.keycode); + const int mods = translateState(event->xkey.state); + const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT)); + + if (event->xkey.keycode) + _glfwInputKey(window, key, event->xkey.keycode, GLFW_PRESS, mods); + + if (window->x11.ic) + { + // Translate keys to characters with XIM input context + + int i; + Status status; + wchar_t buffer[16]; + + if (XFilterEvent(event, None)) + { + // Discard intermediary (dead key) events for character input + break; + } + + const int count = XwcLookupString(window->x11.ic, + &event->xkey, + buffer, sizeof(buffer), + NULL, &status); + + for (i = 0; i < count; i++) + _glfwInputChar(window, buffer[i], mods, plain); + } + else + { + // Translate keys to characters with fallback lookup table + + KeySym keysym; + XLookupString(&event->xkey, NULL, 0, &keysym, NULL); + + const long character = _glfwKeySym2Unicode(keysym); + if (character != -1) + _glfwInputChar(window, character, mods, plain); + } + + break; + } + + case KeyRelease: + { + const int key = translateKey(event->xkey.keycode); + const int mods = translateState(event->xkey.state); + + if (!_glfw.x11.xkb.detectable) + { + // HACK: Key repeat events will arrive as KeyRelease/KeyPress + // pairs with similar or identical time stamps + // The key repeat logic in _glfwInputKey expects only key + // presses to repeat, so detect and discard release events + if (XEventsQueued(_glfw.x11.display, QueuedAfterReading)) + { + XEvent nextEvent; + XPeekEvent(_glfw.x11.display, &nextEvent); + + if (nextEvent.type == KeyPress && + nextEvent.xkey.window == event->xkey.window && + nextEvent.xkey.keycode == event->xkey.keycode) + { + // HACK: Repeat events sometimes leak through due to + // some sort of time drift, so add an epsilon + // Toshiyuki Takahashi can press a button 16 times + // per second so it's fairly safe to assume that + // no human is pressing the key 50 times per + // second (value is ms) + if ((nextEvent.xkey.time - event->xkey.time) < 20) + { + // This is very likely a server-generated key repeat + // event, so ignore it + break; + } + } + } + } + + _glfwInputKey(window, key, event->xkey.keycode, GLFW_RELEASE, mods); + break; + } + + case ButtonPress: + { + const int mods = translateState(event->xbutton.state); + + if (event->xbutton.button == Button1) + _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS, mods); + else if (event->xbutton.button == Button2) + _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_MIDDLE, GLFW_PRESS, mods); + else if (event->xbutton.button == Button3) + _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS, mods); + + // Modern X provides scroll events as mouse button presses + else if (event->xbutton.button == Button4) + _glfwInputScroll(window, 0.0, 1.0); + else if (event->xbutton.button == Button5) + _glfwInputScroll(window, 0.0, -1.0); + else if (event->xbutton.button == Button6) + _glfwInputScroll(window, 1.0, 0.0); + else if (event->xbutton.button == Button7) + _glfwInputScroll(window, -1.0, 0.0); + + else + { + // Additional buttons after 7 are treated as regular buttons + // We subtract 4 to fill the gap left by scroll input above + _glfwInputMouseClick(window, + event->xbutton.button - 4, + GLFW_PRESS, + mods); + } + + break; + } + + case ButtonRelease: + { + const int mods = translateState(event->xbutton.state); + + if (event->xbutton.button == Button1) + { + _glfwInputMouseClick(window, + GLFW_MOUSE_BUTTON_LEFT, + GLFW_RELEASE, + mods); + } + else if (event->xbutton.button == Button2) + { + _glfwInputMouseClick(window, + GLFW_MOUSE_BUTTON_MIDDLE, + GLFW_RELEASE, + mods); + } + else if (event->xbutton.button == Button3) + { + _glfwInputMouseClick(window, + GLFW_MOUSE_BUTTON_RIGHT, + GLFW_RELEASE, + mods); + } + else if (event->xbutton.button > Button7) + { + // Additional buttons after 7 are treated as regular buttons + // We subtract 4 to fill the gap left by scroll input above + _glfwInputMouseClick(window, + event->xbutton.button - 4, + GLFW_RELEASE, + mods); + } + break; + } + + case EnterNotify: + { + _glfwInputCursorEnter(window, GL_TRUE); + break; + } + + case LeaveNotify: + { + _glfwInputCursorEnter(window, GL_FALSE); + break; + } + + case MotionNotify: + { + const int x = event->xmotion.x; + const int y = event->xmotion.y; + + if (x != window->x11.warpPosX || y != window->x11.warpPosY) + { + // The cursor was moved by something other than GLFW + + if (window->cursorMode == GLFW_CURSOR_DISABLED) + { + if (_glfw.focusedWindow != window) + break; + + _glfwInputCursorMotion(window, + x - window->x11.cursorPosX, + y - window->x11.cursorPosY); + } + else + _glfwInputCursorMotion(window, x, y); + } + + window->x11.cursorPosX = x; + window->x11.cursorPosY = y; + break; + } + + case ConfigureNotify: + { + if (event->xconfigure.width != window->x11.width || + event->xconfigure.height != window->x11.height) + { + _glfwInputFramebufferSize(window, + event->xconfigure.width, + event->xconfigure.height); + + _glfwInputWindowSize(window, + event->xconfigure.width, + event->xconfigure.height); + + window->x11.width = event->xconfigure.width; + window->x11.height = event->xconfigure.height; + } + + if (event->xconfigure.x != window->x11.xpos || + event->xconfigure.y != window->x11.ypos) + { + _glfwInputWindowPos(window, + event->xconfigure.x, + event->xconfigure.y); + + window->x11.xpos = event->xconfigure.x; + window->x11.ypos = event->xconfigure.y; + } + + break; + } + + case ClientMessage: + { + // Custom client message, probably from the window manager + + if (event->xclient.message_type == None) + break; + + if (event->xclient.message_type == _glfw.x11.WM_PROTOCOLS) + { + if (_glfw.x11.WM_DELETE_WINDOW && + (Atom) event->xclient.data.l[0] == _glfw.x11.WM_DELETE_WINDOW) + { + // The window manager was asked to close the window, for example by + // the user pressing a 'close' window decoration button + + _glfwInputWindowCloseRequest(window); + } + else if (_glfw.x11.NET_WM_PING && + (Atom) event->xclient.data.l[0] == _glfw.x11.NET_WM_PING) + { + // The window manager is pinging the application to ensure it's + // still responding to events + + event->xclient.window = _glfw.x11.root; + XSendEvent(_glfw.x11.display, + event->xclient.window, + False, + SubstructureNotifyMask | SubstructureRedirectMask, + event); + } + } + else if (event->xclient.message_type == _glfw.x11.XdndEnter) + { + // A drag operation has entered the window + // TODO: Check if UTF-8 string is supported by the source + } + else if (event->xclient.message_type == _glfw.x11.XdndDrop) + { + // The drag operation has finished dropping on + // the window, ask to convert it to a UTF-8 string + _glfw.x11.xdnd.source = event->xclient.data.l[0]; + XConvertSelection(_glfw.x11.display, + _glfw.x11.XdndSelection, + _glfw.x11.UTF8_STRING, + _glfw.x11.XdndSelection, + window->x11.handle, CurrentTime); + } + else if (event->xclient.message_type == _glfw.x11.XdndPosition) + { + // The drag operation has moved over the window + const int absX = (event->xclient.data.l[2] >> 16) & 0xFFFF; + const int absY = (event->xclient.data.l[2]) & 0xFFFF; + int x, y; + + _glfwPlatformGetWindowPos(window, &x, &y); + _glfwInputCursorMotion(window, absX - x, absY - y); + + // Reply that we are ready to copy the dragged data + XEvent reply; + memset(&reply, 0, sizeof(reply)); + + reply.type = ClientMessage; + reply.xclient.window = event->xclient.data.l[0]; + reply.xclient.message_type = _glfw.x11.XdndStatus; + reply.xclient.format = 32; + reply.xclient.data.l[0] = window->x11.handle; + reply.xclient.data.l[1] = 1; // Always accept the dnd with no rectangle + reply.xclient.data.l[2] = 0; // Specify an empty rectangle + reply.xclient.data.l[3] = 0; + reply.xclient.data.l[4] = _glfw.x11.XdndActionCopy; + + XSendEvent(_glfw.x11.display, event->xclient.data.l[0], + False, NoEventMask, &reply); + XFlush(_glfw.x11.display); + } + + break; + } + + case SelectionNotify: + { + if (event->xselection.property) + { + // The converted data from the drag operation has arrived + char* data; + const int result = + _glfwGetWindowProperty(event->xselection.requestor, + event->xselection.property, + event->xselection.target, + (unsigned char**) &data); + + if (result) + { + int i, count; + char** names = parseUriList(data, &count); + + _glfwInputDrop(window, count, (const char**) names); + + for (i = 0; i < count; i++) + free(names[i]); + free(names); + } + + XFree(data); + + XEvent reply; + memset(&reply, 0, sizeof(reply)); + + reply.type = ClientMessage; + reply.xclient.window = _glfw.x11.xdnd.source; + reply.xclient.message_type = _glfw.x11.XdndFinished; + reply.xclient.format = 32; + reply.xclient.data.l[0] = window->x11.handle; + reply.xclient.data.l[1] = result; + reply.xclient.data.l[2] = _glfw.x11.XdndActionCopy; + + // Reply that all is well + XSendEvent(_glfw.x11.display, _glfw.x11.xdnd.source, + False, NoEventMask, &reply); + XFlush(_glfw.x11.display); + } + + break; + } + + case FocusIn: + { + if (event->xfocus.mode == NotifyNormal) + { + _glfwInputWindowFocus(window, GL_TRUE); + + if (window->cursorMode == GLFW_CURSOR_DISABLED) + disableCursor(window); + } + + break; + } + + case FocusOut: + { + if (event->xfocus.mode == NotifyNormal) + { + _glfwInputWindowFocus(window, GL_FALSE); + + if (window->cursorMode == GLFW_CURSOR_DISABLED) + restoreCursor(window); + } + + break; + } + + case Expose: + { + _glfwInputWindowDamage(window); + break; + } + + case PropertyNotify: + { + if (event->xproperty.atom == _glfw.x11.WM_STATE && + event->xproperty.state == PropertyNewValue) + { + const int state = getWindowState(window); + if (state == IconicState) + _glfwInputWindowIconify(window, GL_TRUE); + else if (state == NormalState) + _glfwInputWindowIconify(window, GL_FALSE); + } + + break; + } + + case SelectionClear: + { + handleSelectionClear(event); + break; + } + + case SelectionRequest: + { + handleSelectionRequest(event); + break; + } + + case DestroyNotify: + return; + + case GenericEvent: + { + if (event->xcookie.extension == _glfw.x11.xi.majorOpcode && + XGetEventData(_glfw.x11.display, &event->xcookie)) + { + if (event->xcookie.evtype == XI_Motion) + { + XIDeviceEvent* data = (XIDeviceEvent*) event->xcookie.data; + + window = findWindowByHandle(data->event); + if (window) + { + if (data->event_x != window->x11.warpPosX || + data->event_y != window->x11.warpPosY) + { + // The cursor was moved by something other than GLFW + + double x, y; + + if (window->cursorMode == GLFW_CURSOR_DISABLED) + { + if (_glfw.focusedWindow != window) + break; + + x = data->event_x - window->x11.cursorPosX; + y = data->event_y - window->x11.cursorPosY; + } + else + { + x = data->event_x; + y = data->event_y; + } + + _glfwInputCursorMotion(window, x, y); + } + + window->x11.cursorPosX = data->event_x; + window->x11.cursorPosY = data->event_y; + } + } + } + + XFreeEventData(_glfw.x11.display, &event->xcookie); + break; + } + + default: + { + switch (event->type - _glfw.x11.randr.eventBase) + { + case RRScreenChangeNotify: + { + XRRUpdateConfiguration(event); + break; + } + } + + break; + } + } +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +// Retrieve a single window property of the specified type +// Inspired by fghGetWindowProperty from freeglut +// +unsigned long _glfwGetWindowProperty(Window window, + Atom property, + Atom type, + unsigned char** value) +{ + Atom actualType; + int actualFormat; + unsigned long itemCount, bytesAfter; + + XGetWindowProperty(_glfw.x11.display, + window, + property, + 0, + LONG_MAX, + False, + type, + &actualType, + &actualFormat, + &itemCount, + &bytesAfter, + value); + + if (type != AnyPropertyType && actualType != type) + return 0; + + return itemCount; +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +int _glfwPlatformCreateWindow(_GLFWwindow* window, + const _GLFWwndconfig* wndconfig, + const _GLFWctxconfig* ctxconfig, + const _GLFWfbconfig* fbconfig) +{ + if (!_glfwCreateContext(window, ctxconfig, fbconfig)) + return GL_FALSE; + + if (!createWindow(window, wndconfig)) + return GL_FALSE; + + if (wndconfig->monitor) + { + _glfwPlatformShowWindow(window); + enterFullscreenMode(window); + } + + return GL_TRUE; +} + +void _glfwPlatformDestroyWindow(_GLFWwindow* window) +{ + if (window->monitor) + leaveFullscreenMode(window); + + if (window->x11.ic) + { + XDestroyIC(window->x11.ic); + window->x11.ic = NULL; + } + + _glfwDestroyContext(window); + + if (window->x11.handle) + { + if (window->x11.handle == + XGetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD)) + { + pushSelectionToManager(window); + } + + XDeleteContext(_glfw.x11.display, window->x11.handle, _glfw.x11.context); + XUnmapWindow(_glfw.x11.display, window->x11.handle); + XDestroyWindow(_glfw.x11.display, window->x11.handle); + window->x11.handle = (Window) 0; + } + + if (window->x11.colormap) + { + XFreeColormap(_glfw.x11.display, window->x11.colormap); + window->x11.colormap = (Colormap) 0; + } + + XFlush(_glfw.x11.display); +} + +void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title) +{ +#if defined(X_HAVE_UTF8_STRING) + Xutf8SetWMProperties(_glfw.x11.display, + window->x11.handle, + title, title, + NULL, 0, + NULL, NULL, NULL); +#else + // This may be a slightly better fallback than using XStoreName and + // XSetIconName, which always store their arguments using STRING + XmbSetWMProperties(_glfw.x11.display, + window->x11.handle, + title, title, + NULL, 0, + NULL, NULL, NULL); +#endif + + if (_glfw.x11.NET_WM_NAME) + { + XChangeProperty(_glfw.x11.display, window->x11.handle, + _glfw.x11.NET_WM_NAME, _glfw.x11.UTF8_STRING, 8, + PropModeReplace, + (unsigned char*) title, strlen(title)); + } + + if (_glfw.x11.NET_WM_ICON_NAME) + { + XChangeProperty(_glfw.x11.display, window->x11.handle, + _glfw.x11.NET_WM_ICON_NAME, _glfw.x11.UTF8_STRING, 8, + PropModeReplace, + (unsigned char*) title, strlen(title)); + } + + XFlush(_glfw.x11.display); +} + +void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos) +{ + Window child; + int x, y; + + XTranslateCoordinates(_glfw.x11.display, window->x11.handle, _glfw.x11.root, + 0, 0, &x, &y, &child); + + if (child) + { + int left, top; + XTranslateCoordinates(_glfw.x11.display, window->x11.handle, child, + 0, 0, &left, &top, &child); + + x -= left; + y -= top; + } + + if (xpos) + *xpos = x; + if (ypos) + *ypos = y; +} + +void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos) +{ + XMoveWindow(_glfw.x11.display, window->x11.handle, xpos, ypos); + XFlush(_glfw.x11.display); +} + +void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height) +{ + XWindowAttributes attribs; + XGetWindowAttributes(_glfw.x11.display, window->x11.handle, &attribs); + + if (width) + *width = attribs.width; + if (height) + *height = attribs.height; +} + +void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) +{ + if (window->monitor) + { + _glfwSetVideoMode(window->monitor, &window->videoMode); + + if (window->x11.overrideRedirect) + { + GLFWvidmode mode; + _glfwPlatformGetVideoMode(window->monitor, &mode); + XResizeWindow(_glfw.x11.display, window->x11.handle, + mode.width, mode.height); + } + } + else + { + if (!window->resizable) + { + // Update window size restrictions to match new window size + + XSizeHints* hints = XAllocSizeHints(); + + hints->flags |= (PMinSize | PMaxSize); + hints->min_width = hints->max_width = width; + hints->min_height = hints->max_height = height; + + XSetWMNormalHints(_glfw.x11.display, window->x11.handle, hints); + XFree(hints); + } + + XResizeWindow(_glfw.x11.display, window->x11.handle, width, height); + } + + XFlush(_glfw.x11.display); +} + +void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height) +{ + _glfwPlatformGetWindowSize(window, width, height); +} + +void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, + int* left, int* top, + int* right, int* bottom) +{ + long* extents = NULL; + + if (_glfw.x11.NET_FRAME_EXTENTS == None) + return; + + if (_glfwGetWindowProperty(window->x11.handle, + _glfw.x11.NET_FRAME_EXTENTS, + XA_CARDINAL, + (unsigned char**) &extents) == 4) + { + if (left) + *left = extents[0]; + if (top) + *top = extents[2]; + if (right) + *right = extents[1]; + if (bottom) + *bottom = extents[3]; + } + + if (extents) + XFree(extents); +} + +void _glfwPlatformIconifyWindow(_GLFWwindow* window) +{ + if (window->x11.overrideRedirect) + { + // Override-redirect windows cannot be iconified or restored, as those + // tasks are performed by the window manager + _glfwInputError(GLFW_API_UNAVAILABLE, + "X11: Iconification of full screen windows requires " + "a WM that supports EWMH"); + return; + } + + XIconifyWindow(_glfw.x11.display, window->x11.handle, _glfw.x11.screen); + XFlush(_glfw.x11.display); +} + +void _glfwPlatformRestoreWindow(_GLFWwindow* window) +{ + if (window->x11.overrideRedirect) + { + // Override-redirect windows cannot be iconified or restored, as those + // tasks are performed by the window manager + _glfwInputError(GLFW_API_UNAVAILABLE, + "X11: Iconification of full screen windows requires " + "a WM that supports EWMH"); + return; + } + + XMapWindow(_glfw.x11.display, window->x11.handle); + XFlush(_glfw.x11.display); +} + +void _glfwPlatformShowWindow(_GLFWwindow* window) +{ + XMapRaised(_glfw.x11.display, window->x11.handle); + XFlush(_glfw.x11.display); +} + +void _glfwPlatformUnhideWindow(_GLFWwindow* window) +{ + XMapWindow(_glfw.x11.display, window->x11.handle); + XFlush(_glfw.x11.display); +} + +void _glfwPlatformHideWindow(_GLFWwindow* window) +{ + XUnmapWindow(_glfw.x11.display, window->x11.handle); + XFlush(_glfw.x11.display); +} + +int _glfwPlatformWindowFocused(_GLFWwindow* window) +{ + Window focused; + int state; + + XGetInputFocus(_glfw.x11.display, &focused, &state); + return window->x11.handle == focused; +} + +int _glfwPlatformWindowIconified(_GLFWwindow* window) +{ + return getWindowState(window) == IconicState; +} + +int _glfwPlatformWindowVisible(_GLFWwindow* window) +{ + XWindowAttributes wa; + XGetWindowAttributes(_glfw.x11.display, window->x11.handle, &wa); + return wa.map_state == IsViewable; +} + +void _glfwPlatformPollEvents(void) +{ + int count = XPending(_glfw.x11.display); + while (count--) + { + XEvent event; + XNextEvent(_glfw.x11.display, &event); + processEvent(&event); + } + + _GLFWwindow* window = _glfw.focusedWindow; + if (window && window->cursorMode == GLFW_CURSOR_DISABLED) + { + int width, height; + _glfwPlatformGetWindowSize(window, &width, &height); + _glfwPlatformSetCursorPos(window, width / 2, height / 2); + } +} + +void _glfwPlatformWaitEvents(void) +{ + if (!XPending(_glfw.x11.display)) + { + fd_set fds; + const int fd = ConnectionNumber(_glfw.x11.display); + + FD_ZERO(&fds); + FD_SET(fd, &fds); + + // select(1) is used instead of an X function like XNextEvent, as the + // wait inside those are guarded by the mutex protecting the display + // struct, locking out other threads from using X (including GLX) + if (select(fd + 1, &fds, NULL, NULL, NULL) < 0) + return; + } + + _glfwPlatformPollEvents(); +} + +void _glfwPlatformPostEmptyEvent(void) +{ + XEvent event; + _GLFWwindow* window = _glfw.windowListHead; + + memset(&event, 0, sizeof(event)); + event.type = ClientMessage; + event.xclient.window = window->x11.handle; + event.xclient.format = 32; // Data is 32-bit longs + event.xclient.message_type = _glfw.x11._NULL; + + XSendEvent(_glfw.x11.display, window->x11.handle, False, 0, &event); + XFlush(_glfw.x11.display); +} + +void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos) +{ + Window root, child; + int rootX, rootY, childX, childY; + unsigned int mask; + + XQueryPointer(_glfw.x11.display, window->x11.handle, + &root, &child, + &rootX, &rootY, &childX, &childY, + &mask); + + if (xpos) + *xpos = childX; + if (ypos) + *ypos = childY; +} + +void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y) +{ + // Store the new position so it can be recognized later + window->x11.warpPosX = (int) x; + window->x11.warpPosY = (int) y; + + XWarpPointer(_glfw.x11.display, None, window->x11.handle, + 0,0,0,0, (int) x, (int) y); +} + +void _glfwPlatformApplyCursorMode(_GLFWwindow* window) +{ + switch (window->cursorMode) + { + case GLFW_CURSOR_NORMAL: + restoreCursor(window); + break; + case GLFW_CURSOR_HIDDEN: + hideCursor(window); + break; + case GLFW_CURSOR_DISABLED: + disableCursor(window); + break; + } +} + +int _glfwPlatformCreateCursor(_GLFWcursor* cursor, + const GLFWimage* image, + int xhot, int yhot) +{ + cursor->x11.handle = _glfwCreateCursor(image, xhot, yhot); + if (!cursor->x11.handle) + return GL_FALSE; + + return GL_TRUE; +} + +int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape) +{ + const unsigned int native = translateCursorShape(shape); + if (!native) + { + _glfwInputError(GLFW_INVALID_ENUM, "X11: Invalid standard cursor"); + return GL_FALSE; + } + + cursor->x11.handle = XCreateFontCursor(_glfw.x11.display, native); + if (!cursor->x11.handle) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "X11: Failed to create standard cursor"); + return GL_FALSE; + } + + return GL_TRUE; +} + +void _glfwPlatformDestroyCursor(_GLFWcursor* cursor) +{ + if (cursor->x11.handle) + XFreeCursor(_glfw.x11.display, cursor->x11.handle); +} + +void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) +{ + if (window->cursorMode == GLFW_CURSOR_NORMAL) + { + if (cursor) + XDefineCursor(_glfw.x11.display, window->x11.handle, cursor->x11.handle); + else + XUndefineCursor(_glfw.x11.display, window->x11.handle); + + XFlush(_glfw.x11.display); + } +} + +void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string) +{ + free(_glfw.x11.clipboardString); + _glfw.x11.clipboardString = strdup(string); + + XSetSelectionOwner(_glfw.x11.display, + _glfw.x11.CLIPBOARD, + window->x11.handle, CurrentTime); + + if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD) != + window->x11.handle) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "X11: Failed to become owner of the clipboard selection"); + } +} + +const char* _glfwPlatformGetClipboardString(_GLFWwindow* window) +{ + size_t i; + const Atom formats[] = { _glfw.x11.UTF8_STRING, + _glfw.x11.COMPOUND_STRING, + XA_STRING }; + const size_t formatCount = sizeof(formats) / sizeof(formats[0]); + + if (findWindowByHandle(XGetSelectionOwner(_glfw.x11.display, + _glfw.x11.CLIPBOARD))) + { + // Instead of doing a large number of X round-trips just to put this + // string into a window property and then read it back, just return it + return _glfw.x11.clipboardString; + } + + free(_glfw.x11.clipboardString); + _glfw.x11.clipboardString = NULL; + + for (i = 0; i < formatCount; i++) + { + char* data; + XEvent event; + + XConvertSelection(_glfw.x11.display, + _glfw.x11.CLIPBOARD, + formats[i], + _glfw.x11.GLFW_SELECTION, + window->x11.handle, CurrentTime); + + // XCheckTypedEvent is used instead of XIfEvent in order not to lock + // other threads out from the display during the entire wait period + while (!XCheckTypedEvent(_glfw.x11.display, SelectionNotify, &event)) + ; + + if (event.xselection.property == None) + continue; + + if (_glfwGetWindowProperty(event.xselection.requestor, + event.xselection.property, + event.xselection.target, + (unsigned char**) &data)) + { + _glfw.x11.clipboardString = strdup(data); + } + + XFree(data); + + XDeleteProperty(_glfw.x11.display, + event.xselection.requestor, + event.xselection.property); + + if (_glfw.x11.clipboardString) + break; + } + + if (_glfw.x11.clipboardString == NULL) + { + _glfwInputError(GLFW_FORMAT_UNAVAILABLE, + "X11: Failed to convert selection to string"); + } + + return _glfw.x11.clipboardString; +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW native API ////// +////////////////////////////////////////////////////////////////////////// + +GLFWAPI Display* glfwGetX11Display(void) +{ + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + return _glfw.x11.display; +} + +GLFWAPI Window glfwGetX11Window(GLFWwindow* handle) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + _GLFW_REQUIRE_INIT_OR_RETURN(None); + return window->x11.handle; +} + diff --git a/testbed/glfw/src/xkb_unicode.c b/testbed/glfw/src/xkb_unicode.c new file mode 100644 index 00000000..fbc25a27 --- /dev/null +++ b/testbed/glfw/src/xkb_unicode.c @@ -0,0 +1,889 @@ +//======================================================================== +// GLFW 3.1 X11 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2010 Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include "internal.h" + + +/* + * Marcus: This code was originally written by Markus G. Kuhn. + * I have made some slight changes (trimmed it down a bit from >60 KB to + * 20 KB), but the functionality is the same. + */ + +/* + * This module converts keysym values into the corresponding ISO 10646 + * (UCS, Unicode) values. + * + * The array keysymtab[] contains pairs of X11 keysym values for graphical + * characters and the corresponding Unicode value. The function + * _glfwKeySym2Unicode() maps a keysym onto a Unicode value using a binary + * search, therefore keysymtab[] must remain SORTED by keysym value. + * + * We allow to represent any UCS character in the range U-00000000 to + * U-00FFFFFF by a keysym value in the range 0x01000000 to 0x01ffffff. + * This admittedly does not cover the entire 31-bit space of UCS, but + * it does cover all of the characters up to U-10FFFF, which can be + * represented by UTF-16, and more, and it is very unlikely that higher + * UCS codes will ever be assigned by ISO. So to get Unicode character + * U+ABCD you can directly use keysym 0x0100abcd. + * + * Original author: Markus G. Kuhn , University of + * Cambridge, April 2001 + * + * Special thanks to Richard Verhoeven for preparing + * an initial draft of the mapping table. + * + */ + + +//************************************************************************ +//**** KeySym to Unicode mapping table **** +//************************************************************************ + +static const struct codepair { + unsigned short keysym; + unsigned short ucs; +} keysymtab[] = { + { 0x01a1, 0x0104 }, + { 0x01a2, 0x02d8 }, + { 0x01a3, 0x0141 }, + { 0x01a5, 0x013d }, + { 0x01a6, 0x015a }, + { 0x01a9, 0x0160 }, + { 0x01aa, 0x015e }, + { 0x01ab, 0x0164 }, + { 0x01ac, 0x0179 }, + { 0x01ae, 0x017d }, + { 0x01af, 0x017b }, + { 0x01b1, 0x0105 }, + { 0x01b2, 0x02db }, + { 0x01b3, 0x0142 }, + { 0x01b5, 0x013e }, + { 0x01b6, 0x015b }, + { 0x01b7, 0x02c7 }, + { 0x01b9, 0x0161 }, + { 0x01ba, 0x015f }, + { 0x01bb, 0x0165 }, + { 0x01bc, 0x017a }, + { 0x01bd, 0x02dd }, + { 0x01be, 0x017e }, + { 0x01bf, 0x017c }, + { 0x01c0, 0x0154 }, + { 0x01c3, 0x0102 }, + { 0x01c5, 0x0139 }, + { 0x01c6, 0x0106 }, + { 0x01c8, 0x010c }, + { 0x01ca, 0x0118 }, + { 0x01cc, 0x011a }, + { 0x01cf, 0x010e }, + { 0x01d0, 0x0110 }, + { 0x01d1, 0x0143 }, + { 0x01d2, 0x0147 }, + { 0x01d5, 0x0150 }, + { 0x01d8, 0x0158 }, + { 0x01d9, 0x016e }, + { 0x01db, 0x0170 }, + { 0x01de, 0x0162 }, + { 0x01e0, 0x0155 }, + { 0x01e3, 0x0103 }, + { 0x01e5, 0x013a }, + { 0x01e6, 0x0107 }, + { 0x01e8, 0x010d }, + { 0x01ea, 0x0119 }, + { 0x01ec, 0x011b }, + { 0x01ef, 0x010f }, + { 0x01f0, 0x0111 }, + { 0x01f1, 0x0144 }, + { 0x01f2, 0x0148 }, + { 0x01f5, 0x0151 }, + { 0x01f8, 0x0159 }, + { 0x01f9, 0x016f }, + { 0x01fb, 0x0171 }, + { 0x01fe, 0x0163 }, + { 0x01ff, 0x02d9 }, + { 0x02a1, 0x0126 }, + { 0x02a6, 0x0124 }, + { 0x02a9, 0x0130 }, + { 0x02ab, 0x011e }, + { 0x02ac, 0x0134 }, + { 0x02b1, 0x0127 }, + { 0x02b6, 0x0125 }, + { 0x02b9, 0x0131 }, + { 0x02bb, 0x011f }, + { 0x02bc, 0x0135 }, + { 0x02c5, 0x010a }, + { 0x02c6, 0x0108 }, + { 0x02d5, 0x0120 }, + { 0x02d8, 0x011c }, + { 0x02dd, 0x016c }, + { 0x02de, 0x015c }, + { 0x02e5, 0x010b }, + { 0x02e6, 0x0109 }, + { 0x02f5, 0x0121 }, + { 0x02f8, 0x011d }, + { 0x02fd, 0x016d }, + { 0x02fe, 0x015d }, + { 0x03a2, 0x0138 }, + { 0x03a3, 0x0156 }, + { 0x03a5, 0x0128 }, + { 0x03a6, 0x013b }, + { 0x03aa, 0x0112 }, + { 0x03ab, 0x0122 }, + { 0x03ac, 0x0166 }, + { 0x03b3, 0x0157 }, + { 0x03b5, 0x0129 }, + { 0x03b6, 0x013c }, + { 0x03ba, 0x0113 }, + { 0x03bb, 0x0123 }, + { 0x03bc, 0x0167 }, + { 0x03bd, 0x014a }, + { 0x03bf, 0x014b }, + { 0x03c0, 0x0100 }, + { 0x03c7, 0x012e }, + { 0x03cc, 0x0116 }, + { 0x03cf, 0x012a }, + { 0x03d1, 0x0145 }, + { 0x03d2, 0x014c }, + { 0x03d3, 0x0136 }, + { 0x03d9, 0x0172 }, + { 0x03dd, 0x0168 }, + { 0x03de, 0x016a }, + { 0x03e0, 0x0101 }, + { 0x03e7, 0x012f }, + { 0x03ec, 0x0117 }, + { 0x03ef, 0x012b }, + { 0x03f1, 0x0146 }, + { 0x03f2, 0x014d }, + { 0x03f3, 0x0137 }, + { 0x03f9, 0x0173 }, + { 0x03fd, 0x0169 }, + { 0x03fe, 0x016b }, + { 0x047e, 0x203e }, + { 0x04a1, 0x3002 }, + { 0x04a2, 0x300c }, + { 0x04a3, 0x300d }, + { 0x04a4, 0x3001 }, + { 0x04a5, 0x30fb }, + { 0x04a6, 0x30f2 }, + { 0x04a7, 0x30a1 }, + { 0x04a8, 0x30a3 }, + { 0x04a9, 0x30a5 }, + { 0x04aa, 0x30a7 }, + { 0x04ab, 0x30a9 }, + { 0x04ac, 0x30e3 }, + { 0x04ad, 0x30e5 }, + { 0x04ae, 0x30e7 }, + { 0x04af, 0x30c3 }, + { 0x04b0, 0x30fc }, + { 0x04b1, 0x30a2 }, + { 0x04b2, 0x30a4 }, + { 0x04b3, 0x30a6 }, + { 0x04b4, 0x30a8 }, + { 0x04b5, 0x30aa }, + { 0x04b6, 0x30ab }, + { 0x04b7, 0x30ad }, + { 0x04b8, 0x30af }, + { 0x04b9, 0x30b1 }, + { 0x04ba, 0x30b3 }, + { 0x04bb, 0x30b5 }, + { 0x04bc, 0x30b7 }, + { 0x04bd, 0x30b9 }, + { 0x04be, 0x30bb }, + { 0x04bf, 0x30bd }, + { 0x04c0, 0x30bf }, + { 0x04c1, 0x30c1 }, + { 0x04c2, 0x30c4 }, + { 0x04c3, 0x30c6 }, + { 0x04c4, 0x30c8 }, + { 0x04c5, 0x30ca }, + { 0x04c6, 0x30cb }, + { 0x04c7, 0x30cc }, + { 0x04c8, 0x30cd }, + { 0x04c9, 0x30ce }, + { 0x04ca, 0x30cf }, + { 0x04cb, 0x30d2 }, + { 0x04cc, 0x30d5 }, + { 0x04cd, 0x30d8 }, + { 0x04ce, 0x30db }, + { 0x04cf, 0x30de }, + { 0x04d0, 0x30df }, + { 0x04d1, 0x30e0 }, + { 0x04d2, 0x30e1 }, + { 0x04d3, 0x30e2 }, + { 0x04d4, 0x30e4 }, + { 0x04d5, 0x30e6 }, + { 0x04d6, 0x30e8 }, + { 0x04d7, 0x30e9 }, + { 0x04d8, 0x30ea }, + { 0x04d9, 0x30eb }, + { 0x04da, 0x30ec }, + { 0x04db, 0x30ed }, + { 0x04dc, 0x30ef }, + { 0x04dd, 0x30f3 }, + { 0x04de, 0x309b }, + { 0x04df, 0x309c }, + { 0x05ac, 0x060c }, + { 0x05bb, 0x061b }, + { 0x05bf, 0x061f }, + { 0x05c1, 0x0621 }, + { 0x05c2, 0x0622 }, + { 0x05c3, 0x0623 }, + { 0x05c4, 0x0624 }, + { 0x05c5, 0x0625 }, + { 0x05c6, 0x0626 }, + { 0x05c7, 0x0627 }, + { 0x05c8, 0x0628 }, + { 0x05c9, 0x0629 }, + { 0x05ca, 0x062a }, + { 0x05cb, 0x062b }, + { 0x05cc, 0x062c }, + { 0x05cd, 0x062d }, + { 0x05ce, 0x062e }, + { 0x05cf, 0x062f }, + { 0x05d0, 0x0630 }, + { 0x05d1, 0x0631 }, + { 0x05d2, 0x0632 }, + { 0x05d3, 0x0633 }, + { 0x05d4, 0x0634 }, + { 0x05d5, 0x0635 }, + { 0x05d6, 0x0636 }, + { 0x05d7, 0x0637 }, + { 0x05d8, 0x0638 }, + { 0x05d9, 0x0639 }, + { 0x05da, 0x063a }, + { 0x05e0, 0x0640 }, + { 0x05e1, 0x0641 }, + { 0x05e2, 0x0642 }, + { 0x05e3, 0x0643 }, + { 0x05e4, 0x0644 }, + { 0x05e5, 0x0645 }, + { 0x05e6, 0x0646 }, + { 0x05e7, 0x0647 }, + { 0x05e8, 0x0648 }, + { 0x05e9, 0x0649 }, + { 0x05ea, 0x064a }, + { 0x05eb, 0x064b }, + { 0x05ec, 0x064c }, + { 0x05ed, 0x064d }, + { 0x05ee, 0x064e }, + { 0x05ef, 0x064f }, + { 0x05f0, 0x0650 }, + { 0x05f1, 0x0651 }, + { 0x05f2, 0x0652 }, + { 0x06a1, 0x0452 }, + { 0x06a2, 0x0453 }, + { 0x06a3, 0x0451 }, + { 0x06a4, 0x0454 }, + { 0x06a5, 0x0455 }, + { 0x06a6, 0x0456 }, + { 0x06a7, 0x0457 }, + { 0x06a8, 0x0458 }, + { 0x06a9, 0x0459 }, + { 0x06aa, 0x045a }, + { 0x06ab, 0x045b }, + { 0x06ac, 0x045c }, + { 0x06ae, 0x045e }, + { 0x06af, 0x045f }, + { 0x06b0, 0x2116 }, + { 0x06b1, 0x0402 }, + { 0x06b2, 0x0403 }, + { 0x06b3, 0x0401 }, + { 0x06b4, 0x0404 }, + { 0x06b5, 0x0405 }, + { 0x06b6, 0x0406 }, + { 0x06b7, 0x0407 }, + { 0x06b8, 0x0408 }, + { 0x06b9, 0x0409 }, + { 0x06ba, 0x040a }, + { 0x06bb, 0x040b }, + { 0x06bc, 0x040c }, + { 0x06be, 0x040e }, + { 0x06bf, 0x040f }, + { 0x06c0, 0x044e }, + { 0x06c1, 0x0430 }, + { 0x06c2, 0x0431 }, + { 0x06c3, 0x0446 }, + { 0x06c4, 0x0434 }, + { 0x06c5, 0x0435 }, + { 0x06c6, 0x0444 }, + { 0x06c7, 0x0433 }, + { 0x06c8, 0x0445 }, + { 0x06c9, 0x0438 }, + { 0x06ca, 0x0439 }, + { 0x06cb, 0x043a }, + { 0x06cc, 0x043b }, + { 0x06cd, 0x043c }, + { 0x06ce, 0x043d }, + { 0x06cf, 0x043e }, + { 0x06d0, 0x043f }, + { 0x06d1, 0x044f }, + { 0x06d2, 0x0440 }, + { 0x06d3, 0x0441 }, + { 0x06d4, 0x0442 }, + { 0x06d5, 0x0443 }, + { 0x06d6, 0x0436 }, + { 0x06d7, 0x0432 }, + { 0x06d8, 0x044c }, + { 0x06d9, 0x044b }, + { 0x06da, 0x0437 }, + { 0x06db, 0x0448 }, + { 0x06dc, 0x044d }, + { 0x06dd, 0x0449 }, + { 0x06de, 0x0447 }, + { 0x06df, 0x044a }, + { 0x06e0, 0x042e }, + { 0x06e1, 0x0410 }, + { 0x06e2, 0x0411 }, + { 0x06e3, 0x0426 }, + { 0x06e4, 0x0414 }, + { 0x06e5, 0x0415 }, + { 0x06e6, 0x0424 }, + { 0x06e7, 0x0413 }, + { 0x06e8, 0x0425 }, + { 0x06e9, 0x0418 }, + { 0x06ea, 0x0419 }, + { 0x06eb, 0x041a }, + { 0x06ec, 0x041b }, + { 0x06ed, 0x041c }, + { 0x06ee, 0x041d }, + { 0x06ef, 0x041e }, + { 0x06f0, 0x041f }, + { 0x06f1, 0x042f }, + { 0x06f2, 0x0420 }, + { 0x06f3, 0x0421 }, + { 0x06f4, 0x0422 }, + { 0x06f5, 0x0423 }, + { 0x06f6, 0x0416 }, + { 0x06f7, 0x0412 }, + { 0x06f8, 0x042c }, + { 0x06f9, 0x042b }, + { 0x06fa, 0x0417 }, + { 0x06fb, 0x0428 }, + { 0x06fc, 0x042d }, + { 0x06fd, 0x0429 }, + { 0x06fe, 0x0427 }, + { 0x06ff, 0x042a }, + { 0x07a1, 0x0386 }, + { 0x07a2, 0x0388 }, + { 0x07a3, 0x0389 }, + { 0x07a4, 0x038a }, + { 0x07a5, 0x03aa }, + { 0x07a7, 0x038c }, + { 0x07a8, 0x038e }, + { 0x07a9, 0x03ab }, + { 0x07ab, 0x038f }, + { 0x07ae, 0x0385 }, + { 0x07af, 0x2015 }, + { 0x07b1, 0x03ac }, + { 0x07b2, 0x03ad }, + { 0x07b3, 0x03ae }, + { 0x07b4, 0x03af }, + { 0x07b5, 0x03ca }, + { 0x07b6, 0x0390 }, + { 0x07b7, 0x03cc }, + { 0x07b8, 0x03cd }, + { 0x07b9, 0x03cb }, + { 0x07ba, 0x03b0 }, + { 0x07bb, 0x03ce }, + { 0x07c1, 0x0391 }, + { 0x07c2, 0x0392 }, + { 0x07c3, 0x0393 }, + { 0x07c4, 0x0394 }, + { 0x07c5, 0x0395 }, + { 0x07c6, 0x0396 }, + { 0x07c7, 0x0397 }, + { 0x07c8, 0x0398 }, + { 0x07c9, 0x0399 }, + { 0x07ca, 0x039a }, + { 0x07cb, 0x039b }, + { 0x07cc, 0x039c }, + { 0x07cd, 0x039d }, + { 0x07ce, 0x039e }, + { 0x07cf, 0x039f }, + { 0x07d0, 0x03a0 }, + { 0x07d1, 0x03a1 }, + { 0x07d2, 0x03a3 }, + { 0x07d4, 0x03a4 }, + { 0x07d5, 0x03a5 }, + { 0x07d6, 0x03a6 }, + { 0x07d7, 0x03a7 }, + { 0x07d8, 0x03a8 }, + { 0x07d9, 0x03a9 }, + { 0x07e1, 0x03b1 }, + { 0x07e2, 0x03b2 }, + { 0x07e3, 0x03b3 }, + { 0x07e4, 0x03b4 }, + { 0x07e5, 0x03b5 }, + { 0x07e6, 0x03b6 }, + { 0x07e7, 0x03b7 }, + { 0x07e8, 0x03b8 }, + { 0x07e9, 0x03b9 }, + { 0x07ea, 0x03ba }, + { 0x07eb, 0x03bb }, + { 0x07ec, 0x03bc }, + { 0x07ed, 0x03bd }, + { 0x07ee, 0x03be }, + { 0x07ef, 0x03bf }, + { 0x07f0, 0x03c0 }, + { 0x07f1, 0x03c1 }, + { 0x07f2, 0x03c3 }, + { 0x07f3, 0x03c2 }, + { 0x07f4, 0x03c4 }, + { 0x07f5, 0x03c5 }, + { 0x07f6, 0x03c6 }, + { 0x07f7, 0x03c7 }, + { 0x07f8, 0x03c8 }, + { 0x07f9, 0x03c9 }, + { 0x08a1, 0x23b7 }, + { 0x08a2, 0x250c }, + { 0x08a3, 0x2500 }, + { 0x08a4, 0x2320 }, + { 0x08a5, 0x2321 }, + { 0x08a6, 0x2502 }, + { 0x08a7, 0x23a1 }, + { 0x08a8, 0x23a3 }, + { 0x08a9, 0x23a4 }, + { 0x08aa, 0x23a6 }, + { 0x08ab, 0x239b }, + { 0x08ac, 0x239d }, + { 0x08ad, 0x239e }, + { 0x08ae, 0x23a0 }, + { 0x08af, 0x23a8 }, + { 0x08b0, 0x23ac }, + { 0x08bc, 0x2264 }, + { 0x08bd, 0x2260 }, + { 0x08be, 0x2265 }, + { 0x08bf, 0x222b }, + { 0x08c0, 0x2234 }, + { 0x08c1, 0x221d }, + { 0x08c2, 0x221e }, + { 0x08c5, 0x2207 }, + { 0x08c8, 0x223c }, + { 0x08c9, 0x2243 }, + { 0x08cd, 0x21d4 }, + { 0x08ce, 0x21d2 }, + { 0x08cf, 0x2261 }, + { 0x08d6, 0x221a }, + { 0x08da, 0x2282 }, + { 0x08db, 0x2283 }, + { 0x08dc, 0x2229 }, + { 0x08dd, 0x222a }, + { 0x08de, 0x2227 }, + { 0x08df, 0x2228 }, + { 0x08ef, 0x2202 }, + { 0x08f6, 0x0192 }, + { 0x08fb, 0x2190 }, + { 0x08fc, 0x2191 }, + { 0x08fd, 0x2192 }, + { 0x08fe, 0x2193 }, + { 0x09e0, 0x25c6 }, + { 0x09e1, 0x2592 }, + { 0x09e2, 0x2409 }, + { 0x09e3, 0x240c }, + { 0x09e4, 0x240d }, + { 0x09e5, 0x240a }, + { 0x09e8, 0x2424 }, + { 0x09e9, 0x240b }, + { 0x09ea, 0x2518 }, + { 0x09eb, 0x2510 }, + { 0x09ec, 0x250c }, + { 0x09ed, 0x2514 }, + { 0x09ee, 0x253c }, + { 0x09ef, 0x23ba }, + { 0x09f0, 0x23bb }, + { 0x09f1, 0x2500 }, + { 0x09f2, 0x23bc }, + { 0x09f3, 0x23bd }, + { 0x09f4, 0x251c }, + { 0x09f5, 0x2524 }, + { 0x09f6, 0x2534 }, + { 0x09f7, 0x252c }, + { 0x09f8, 0x2502 }, + { 0x0aa1, 0x2003 }, + { 0x0aa2, 0x2002 }, + { 0x0aa3, 0x2004 }, + { 0x0aa4, 0x2005 }, + { 0x0aa5, 0x2007 }, + { 0x0aa6, 0x2008 }, + { 0x0aa7, 0x2009 }, + { 0x0aa8, 0x200a }, + { 0x0aa9, 0x2014 }, + { 0x0aaa, 0x2013 }, + { 0x0aae, 0x2026 }, + { 0x0aaf, 0x2025 }, + { 0x0ab0, 0x2153 }, + { 0x0ab1, 0x2154 }, + { 0x0ab2, 0x2155 }, + { 0x0ab3, 0x2156 }, + { 0x0ab4, 0x2157 }, + { 0x0ab5, 0x2158 }, + { 0x0ab6, 0x2159 }, + { 0x0ab7, 0x215a }, + { 0x0ab8, 0x2105 }, + { 0x0abb, 0x2012 }, + { 0x0abc, 0x2329 }, + { 0x0abe, 0x232a }, + { 0x0ac3, 0x215b }, + { 0x0ac4, 0x215c }, + { 0x0ac5, 0x215d }, + { 0x0ac6, 0x215e }, + { 0x0ac9, 0x2122 }, + { 0x0aca, 0x2613 }, + { 0x0acc, 0x25c1 }, + { 0x0acd, 0x25b7 }, + { 0x0ace, 0x25cb }, + { 0x0acf, 0x25af }, + { 0x0ad0, 0x2018 }, + { 0x0ad1, 0x2019 }, + { 0x0ad2, 0x201c }, + { 0x0ad3, 0x201d }, + { 0x0ad4, 0x211e }, + { 0x0ad6, 0x2032 }, + { 0x0ad7, 0x2033 }, + { 0x0ad9, 0x271d }, + { 0x0adb, 0x25ac }, + { 0x0adc, 0x25c0 }, + { 0x0add, 0x25b6 }, + { 0x0ade, 0x25cf }, + { 0x0adf, 0x25ae }, + { 0x0ae0, 0x25e6 }, + { 0x0ae1, 0x25ab }, + { 0x0ae2, 0x25ad }, + { 0x0ae3, 0x25b3 }, + { 0x0ae4, 0x25bd }, + { 0x0ae5, 0x2606 }, + { 0x0ae6, 0x2022 }, + { 0x0ae7, 0x25aa }, + { 0x0ae8, 0x25b2 }, + { 0x0ae9, 0x25bc }, + { 0x0aea, 0x261c }, + { 0x0aeb, 0x261e }, + { 0x0aec, 0x2663 }, + { 0x0aed, 0x2666 }, + { 0x0aee, 0x2665 }, + { 0x0af0, 0x2720 }, + { 0x0af1, 0x2020 }, + { 0x0af2, 0x2021 }, + { 0x0af3, 0x2713 }, + { 0x0af4, 0x2717 }, + { 0x0af5, 0x266f }, + { 0x0af6, 0x266d }, + { 0x0af7, 0x2642 }, + { 0x0af8, 0x2640 }, + { 0x0af9, 0x260e }, + { 0x0afa, 0x2315 }, + { 0x0afb, 0x2117 }, + { 0x0afc, 0x2038 }, + { 0x0afd, 0x201a }, + { 0x0afe, 0x201e }, + { 0x0ba3, 0x003c }, + { 0x0ba6, 0x003e }, + { 0x0ba8, 0x2228 }, + { 0x0ba9, 0x2227 }, + { 0x0bc0, 0x00af }, + { 0x0bc2, 0x22a5 }, + { 0x0bc3, 0x2229 }, + { 0x0bc4, 0x230a }, + { 0x0bc6, 0x005f }, + { 0x0bca, 0x2218 }, + { 0x0bcc, 0x2395 }, + { 0x0bce, 0x22a4 }, + { 0x0bcf, 0x25cb }, + { 0x0bd3, 0x2308 }, + { 0x0bd6, 0x222a }, + { 0x0bd8, 0x2283 }, + { 0x0bda, 0x2282 }, + { 0x0bdc, 0x22a2 }, + { 0x0bfc, 0x22a3 }, + { 0x0cdf, 0x2017 }, + { 0x0ce0, 0x05d0 }, + { 0x0ce1, 0x05d1 }, + { 0x0ce2, 0x05d2 }, + { 0x0ce3, 0x05d3 }, + { 0x0ce4, 0x05d4 }, + { 0x0ce5, 0x05d5 }, + { 0x0ce6, 0x05d6 }, + { 0x0ce7, 0x05d7 }, + { 0x0ce8, 0x05d8 }, + { 0x0ce9, 0x05d9 }, + { 0x0cea, 0x05da }, + { 0x0ceb, 0x05db }, + { 0x0cec, 0x05dc }, + { 0x0ced, 0x05dd }, + { 0x0cee, 0x05de }, + { 0x0cef, 0x05df }, + { 0x0cf0, 0x05e0 }, + { 0x0cf1, 0x05e1 }, + { 0x0cf2, 0x05e2 }, + { 0x0cf3, 0x05e3 }, + { 0x0cf4, 0x05e4 }, + { 0x0cf5, 0x05e5 }, + { 0x0cf6, 0x05e6 }, + { 0x0cf7, 0x05e7 }, + { 0x0cf8, 0x05e8 }, + { 0x0cf9, 0x05e9 }, + { 0x0cfa, 0x05ea }, + { 0x0da1, 0x0e01 }, + { 0x0da2, 0x0e02 }, + { 0x0da3, 0x0e03 }, + { 0x0da4, 0x0e04 }, + { 0x0da5, 0x0e05 }, + { 0x0da6, 0x0e06 }, + { 0x0da7, 0x0e07 }, + { 0x0da8, 0x0e08 }, + { 0x0da9, 0x0e09 }, + { 0x0daa, 0x0e0a }, + { 0x0dab, 0x0e0b }, + { 0x0dac, 0x0e0c }, + { 0x0dad, 0x0e0d }, + { 0x0dae, 0x0e0e }, + { 0x0daf, 0x0e0f }, + { 0x0db0, 0x0e10 }, + { 0x0db1, 0x0e11 }, + { 0x0db2, 0x0e12 }, + { 0x0db3, 0x0e13 }, + { 0x0db4, 0x0e14 }, + { 0x0db5, 0x0e15 }, + { 0x0db6, 0x0e16 }, + { 0x0db7, 0x0e17 }, + { 0x0db8, 0x0e18 }, + { 0x0db9, 0x0e19 }, + { 0x0dba, 0x0e1a }, + { 0x0dbb, 0x0e1b }, + { 0x0dbc, 0x0e1c }, + { 0x0dbd, 0x0e1d }, + { 0x0dbe, 0x0e1e }, + { 0x0dbf, 0x0e1f }, + { 0x0dc0, 0x0e20 }, + { 0x0dc1, 0x0e21 }, + { 0x0dc2, 0x0e22 }, + { 0x0dc3, 0x0e23 }, + { 0x0dc4, 0x0e24 }, + { 0x0dc5, 0x0e25 }, + { 0x0dc6, 0x0e26 }, + { 0x0dc7, 0x0e27 }, + { 0x0dc8, 0x0e28 }, + { 0x0dc9, 0x0e29 }, + { 0x0dca, 0x0e2a }, + { 0x0dcb, 0x0e2b }, + { 0x0dcc, 0x0e2c }, + { 0x0dcd, 0x0e2d }, + { 0x0dce, 0x0e2e }, + { 0x0dcf, 0x0e2f }, + { 0x0dd0, 0x0e30 }, + { 0x0dd1, 0x0e31 }, + { 0x0dd2, 0x0e32 }, + { 0x0dd3, 0x0e33 }, + { 0x0dd4, 0x0e34 }, + { 0x0dd5, 0x0e35 }, + { 0x0dd6, 0x0e36 }, + { 0x0dd7, 0x0e37 }, + { 0x0dd8, 0x0e38 }, + { 0x0dd9, 0x0e39 }, + { 0x0dda, 0x0e3a }, + { 0x0ddf, 0x0e3f }, + { 0x0de0, 0x0e40 }, + { 0x0de1, 0x0e41 }, + { 0x0de2, 0x0e42 }, + { 0x0de3, 0x0e43 }, + { 0x0de4, 0x0e44 }, + { 0x0de5, 0x0e45 }, + { 0x0de6, 0x0e46 }, + { 0x0de7, 0x0e47 }, + { 0x0de8, 0x0e48 }, + { 0x0de9, 0x0e49 }, + { 0x0dea, 0x0e4a }, + { 0x0deb, 0x0e4b }, + { 0x0dec, 0x0e4c }, + { 0x0ded, 0x0e4d }, + { 0x0df0, 0x0e50 }, + { 0x0df1, 0x0e51 }, + { 0x0df2, 0x0e52 }, + { 0x0df3, 0x0e53 }, + { 0x0df4, 0x0e54 }, + { 0x0df5, 0x0e55 }, + { 0x0df6, 0x0e56 }, + { 0x0df7, 0x0e57 }, + { 0x0df8, 0x0e58 }, + { 0x0df9, 0x0e59 }, + { 0x0ea1, 0x3131 }, + { 0x0ea2, 0x3132 }, + { 0x0ea3, 0x3133 }, + { 0x0ea4, 0x3134 }, + { 0x0ea5, 0x3135 }, + { 0x0ea6, 0x3136 }, + { 0x0ea7, 0x3137 }, + { 0x0ea8, 0x3138 }, + { 0x0ea9, 0x3139 }, + { 0x0eaa, 0x313a }, + { 0x0eab, 0x313b }, + { 0x0eac, 0x313c }, + { 0x0ead, 0x313d }, + { 0x0eae, 0x313e }, + { 0x0eaf, 0x313f }, + { 0x0eb0, 0x3140 }, + { 0x0eb1, 0x3141 }, + { 0x0eb2, 0x3142 }, + { 0x0eb3, 0x3143 }, + { 0x0eb4, 0x3144 }, + { 0x0eb5, 0x3145 }, + { 0x0eb6, 0x3146 }, + { 0x0eb7, 0x3147 }, + { 0x0eb8, 0x3148 }, + { 0x0eb9, 0x3149 }, + { 0x0eba, 0x314a }, + { 0x0ebb, 0x314b }, + { 0x0ebc, 0x314c }, + { 0x0ebd, 0x314d }, + { 0x0ebe, 0x314e }, + { 0x0ebf, 0x314f }, + { 0x0ec0, 0x3150 }, + { 0x0ec1, 0x3151 }, + { 0x0ec2, 0x3152 }, + { 0x0ec3, 0x3153 }, + { 0x0ec4, 0x3154 }, + { 0x0ec5, 0x3155 }, + { 0x0ec6, 0x3156 }, + { 0x0ec7, 0x3157 }, + { 0x0ec8, 0x3158 }, + { 0x0ec9, 0x3159 }, + { 0x0eca, 0x315a }, + { 0x0ecb, 0x315b }, + { 0x0ecc, 0x315c }, + { 0x0ecd, 0x315d }, + { 0x0ece, 0x315e }, + { 0x0ecf, 0x315f }, + { 0x0ed0, 0x3160 }, + { 0x0ed1, 0x3161 }, + { 0x0ed2, 0x3162 }, + { 0x0ed3, 0x3163 }, + { 0x0ed4, 0x11a8 }, + { 0x0ed5, 0x11a9 }, + { 0x0ed6, 0x11aa }, + { 0x0ed7, 0x11ab }, + { 0x0ed8, 0x11ac }, + { 0x0ed9, 0x11ad }, + { 0x0eda, 0x11ae }, + { 0x0edb, 0x11af }, + { 0x0edc, 0x11b0 }, + { 0x0edd, 0x11b1 }, + { 0x0ede, 0x11b2 }, + { 0x0edf, 0x11b3 }, + { 0x0ee0, 0x11b4 }, + { 0x0ee1, 0x11b5 }, + { 0x0ee2, 0x11b6 }, + { 0x0ee3, 0x11b7 }, + { 0x0ee4, 0x11b8 }, + { 0x0ee5, 0x11b9 }, + { 0x0ee6, 0x11ba }, + { 0x0ee7, 0x11bb }, + { 0x0ee8, 0x11bc }, + { 0x0ee9, 0x11bd }, + { 0x0eea, 0x11be }, + { 0x0eeb, 0x11bf }, + { 0x0eec, 0x11c0 }, + { 0x0eed, 0x11c1 }, + { 0x0eee, 0x11c2 }, + { 0x0eef, 0x316d }, + { 0x0ef0, 0x3171 }, + { 0x0ef1, 0x3178 }, + { 0x0ef2, 0x317f }, + { 0x0ef3, 0x3181 }, + { 0x0ef4, 0x3184 }, + { 0x0ef5, 0x3186 }, + { 0x0ef6, 0x318d }, + { 0x0ef7, 0x318e }, + { 0x0ef8, 0x11eb }, + { 0x0ef9, 0x11f0 }, + { 0x0efa, 0x11f9 }, + { 0x0eff, 0x20a9 }, + { 0x13a4, 0x20ac }, + { 0x13bc, 0x0152 }, + { 0x13bd, 0x0153 }, + { 0x13be, 0x0178 }, + { 0x20ac, 0x20ac }, + // Numeric keypad with numlock on + { XK_KP_Space, ' ' }, + { XK_KP_Equal, '=' }, + { XK_KP_Multiply, '*' }, + { XK_KP_Add, '+' }, + { XK_KP_Separator, ',' }, + { XK_KP_Subtract, '-' }, + { XK_KP_Decimal, '.' }, + { XK_KP_Divide, '/' }, + { XK_KP_0, 0x0030 }, + { XK_KP_1, 0x0031 }, + { XK_KP_2, 0x0032 }, + { XK_KP_3, 0x0033 }, + { XK_KP_4, 0x0034 }, + { XK_KP_5, 0x0035 }, + { XK_KP_6, 0x0036 }, + { XK_KP_7, 0x0037 }, + { XK_KP_8, 0x0038 }, + { XK_KP_9, 0x0039 } +}; + + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +// Convert XKB KeySym to Unicode +// +long _glfwKeySym2Unicode(unsigned int keysym) +{ + int min = 0; + int max = sizeof(keysymtab) / sizeof(struct codepair) - 1; + int mid; + + // First check for Latin-1 characters (1:1 mapping) + if ((keysym >= 0x0020 && keysym <= 0x007e) || + (keysym >= 0x00a0 && keysym <= 0x00ff)) + { + return keysym; + } + + // Also check for directly encoded 24-bit UCS characters + if ((keysym & 0xff000000) == 0x01000000) + return keysym & 0x00ffffff; + + // Binary search in table + while (max >= min) + { + mid = (min + max) / 2; + if (keysymtab[mid].keysym < keysym) + min = mid + 1; + else if (keysymtab[mid].keysym > keysym) + max = mid - 1; + else + return keysymtab[mid].ucs; + } + + // No matching Unicode value found + return -1; +} + diff --git a/testbed/glfw/src/xkb_unicode.h b/testbed/glfw/src/xkb_unicode.h new file mode 100644 index 00000000..9772901d --- /dev/null +++ b/testbed/glfw/src/xkb_unicode.h @@ -0,0 +1,33 @@ +//======================================================================== +// GLFW 3.1 Linux - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2014 Jonas Ådahl +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#ifndef _xkb_unicode_h_ +#define _xkb_unicode_h_ + + +long _glfwKeySym2Unicode(unsigned int keysym); + +#endif // _xkb_unicode_h_ diff --git a/testbed/glfw/tests/CMakeLists.txt b/testbed/glfw/tests/CMakeLists.txt new file mode 100644 index 00000000..a5f52474 --- /dev/null +++ b/testbed/glfw/tests/CMakeLists.txt @@ -0,0 +1,81 @@ + +link_libraries(glfw "${OPENGL_glu_LIBRARY}") + +if (BUILD_SHARED_LIBS) + add_definitions(-DGLFW_DLL) + link_libraries("${OPENGL_gl_LIBRARY}" "${MATH_LIBRARY}") +else() + link_libraries(${glfw_LIBRARIES}) +endif() + +include_directories("${GLFW_SOURCE_DIR}/include" + "${GLFW_SOURCE_DIR}/deps") + +if ("${OPENGL_INCLUDE_DIR}") + include_directories("${OPENGL_INCLUDE_DIR}") +endif() + +set(GETOPT "${GLFW_SOURCE_DIR}/deps/getopt.h" + "${GLFW_SOURCE_DIR}/deps/getopt.c") +set(TINYCTHREAD "${GLFW_SOURCE_DIR}/deps/tinycthread.h" + "${GLFW_SOURCE_DIR}/deps/tinycthread.c") + +add_executable(clipboard clipboard.c ${GETOPT}) +add_executable(defaults defaults.c) +add_executable(events events.c ${GETOPT}) +add_executable(fsaa fsaa.c ${GETOPT}) +add_executable(gamma gamma.c ${GETOPT}) +add_executable(glfwinfo glfwinfo.c ${GETOPT}) +add_executable(iconify iconify.c ${GETOPT}) +add_executable(joysticks joysticks.c) +add_executable(modes modes.c ${GETOPT}) +add_executable(peter peter.c) +add_executable(reopen reopen.c) +add_executable(cursor cursor.c) + +add_executable(cursoranim WIN32 MACOSX_BUNDLE cursoranim.c) +set_target_properties(cursoranim PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Cursor animation") + +add_executable(accuracy WIN32 MACOSX_BUNDLE accuracy.c) +set_target_properties(accuracy PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Accuracy") + +add_executable(empty WIN32 MACOSX_BUNDLE empty.c ${TINYCTHREAD}) +set_target_properties(empty PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Empty Event") + +add_executable(sharing WIN32 MACOSX_BUNDLE sharing.c) +set_target_properties(sharing PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Sharing") + +add_executable(tearing WIN32 MACOSX_BUNDLE tearing.c) +set_target_properties(tearing PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Tearing") + +add_executable(threads WIN32 MACOSX_BUNDLE threads.c ${TINYCTHREAD}) +set_target_properties(threads PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Threads") + +add_executable(title WIN32 MACOSX_BUNDLE title.c) +set_target_properties(title PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Title") + +add_executable(windows WIN32 MACOSX_BUNDLE windows.c) +set_target_properties(windows PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Windows") + +target_link_libraries(empty "${CMAKE_THREAD_LIBS_INIT}" "${RT_LIBRARY}") +target_link_libraries(threads "${CMAKE_THREAD_LIBS_INIT}" "${RT_LIBRARY}") + +set(WINDOWS_BINARIES accuracy empty sharing tearing threads title windows cursoranim) +set(CONSOLE_BINARIES clipboard defaults events fsaa gamma glfwinfo + iconify joysticks modes peter reopen cursor) + +set_target_properties(${WINDOWS_BINARIES} ${CONSOLE_BINARIES} PROPERTIES + FOLDER "GLFW3/Tests") + +if (MSVC) + # Tell MSVC to use main instead of WinMain for Windows subsystem executables + set_target_properties(${WINDOWS_BINARIES} ${CONSOLE_BINARIES} PROPERTIES + LINK_FLAGS "/ENTRY:mainCRTStartup") +endif() + +if (APPLE) + set_target_properties(${WINDOWS_BINARIES} ${CONSOLE_BINARIES} PROPERTIES + MACOSX_BUNDLE_SHORT_VERSION_STRING ${GLFW_VERSION} + MACOSX_BUNDLE_LONG_VERSION_STRING ${GLFW_VERSION_FULL}) +endif() + diff --git a/testbed/glfw/tests/accuracy.c b/testbed/glfw/tests/accuracy.c new file mode 100644 index 00000000..6a63c889 --- /dev/null +++ b/testbed/glfw/tests/accuracy.c @@ -0,0 +1,128 @@ +//======================================================================== +// Mouse cursor accuracy test +// Copyright (c) Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== +// +// This test came about as the result of bug #1867804 +// +// No sign of said bug has so far been detected +// +//======================================================================== + +#include + +#include +#include + +static double cursor_x = 0.0, cursor_y = 0.0; +static int window_width = 640, window_height = 480; +static int swap_interval = 1; + +static void set_swap_interval(GLFWwindow* window, int interval) +{ + char title[256]; + + swap_interval = interval; + glfwSwapInterval(swap_interval); + + sprintf(title, "Cursor Inaccuracy Detector (interval %i)", swap_interval); + + glfwSetWindowTitle(window, title); +} + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +static void framebuffer_size_callback(GLFWwindow* window, int width, int height) +{ + window_width = width; + window_height = height; + + glViewport(0, 0, window_width, window_height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0.f, window_width, 0.f, window_height, 0.f, 1.f); +} + +static void cursor_position_callback(GLFWwindow* window, double x, double y) +{ + cursor_x = x; + cursor_y = y; +} + +static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + if (key == GLFW_KEY_SPACE && action == GLFW_PRESS) + set_swap_interval(window, 1 - swap_interval); +} + +int main(void) +{ + GLFWwindow* window; + int width, height; + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + window = glfwCreateWindow(window_width, window_height, "", NULL, NULL); + if (!window) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glfwSetCursorPosCallback(window, cursor_position_callback); + glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); + glfwSetKeyCallback(window, key_callback); + + glfwMakeContextCurrent(window); + + glfwGetFramebufferSize(window, &width, &height); + framebuffer_size_callback(window, width, height); + + set_swap_interval(window, swap_interval); + + while (!glfwWindowShouldClose(window)) + { + glClear(GL_COLOR_BUFFER_BIT); + + glBegin(GL_LINES); + glVertex2f(0.f, (GLfloat) (window_height - cursor_y)); + glVertex2f((GLfloat) window_width, (GLfloat) (window_height - cursor_y)); + glVertex2f((GLfloat) cursor_x, 0.f); + glVertex2f((GLfloat) cursor_x, (GLfloat) window_height); + glEnd(); + + glfwSwapBuffers(window); + glfwPollEvents(); + } + + glfwTerminate(); + exit(EXIT_SUCCESS); +} + diff --git a/testbed/glfw/tests/clipboard.c b/testbed/glfw/tests/clipboard.c new file mode 100644 index 00000000..43422845 --- /dev/null +++ b/testbed/glfw/tests/clipboard.c @@ -0,0 +1,149 @@ +//======================================================================== +// Clipboard test program +// Copyright (c) Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== +// +// This program is used to test the clipboard functionality. +// +//======================================================================== + +#include + +#include +#include + +#include "getopt.h" + +static void usage(void) +{ + printf("Usage: clipboard [-h]\n"); +} + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + if (action != GLFW_PRESS) + return; + + switch (key) + { + case GLFW_KEY_ESCAPE: + glfwSetWindowShouldClose(window, GL_TRUE); + break; + + case GLFW_KEY_V: + if (mods == GLFW_MOD_CONTROL) + { + const char* string; + + string = glfwGetClipboardString(window); + if (string) + printf("Clipboard contains \"%s\"\n", string); + else + printf("Clipboard does not contain a string\n"); + } + break; + + case GLFW_KEY_C: + if (mods == GLFW_MOD_CONTROL) + { + const char* string = "Hello GLFW World!"; + glfwSetClipboardString(window, string); + printf("Setting clipboard to \"%s\"\n", string); + } + break; + } +} + +static void framebuffer_size_callback(GLFWwindow* window, int width, int height) +{ + glViewport(0, 0, width, height); +} + +int main(int argc, char** argv) +{ + int ch; + GLFWwindow* window; + + while ((ch = getopt(argc, argv, "h")) != -1) + { + switch (ch) + { + case 'h': + usage(); + exit(EXIT_SUCCESS); + + default: + usage(); + exit(EXIT_FAILURE); + } + } + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + { + fprintf(stderr, "Failed to initialize GLFW\n"); + exit(EXIT_FAILURE); + } + + window = glfwCreateWindow(200, 200, "Clipboard Test", NULL, NULL); + if (!window) + { + glfwTerminate(); + + fprintf(stderr, "Failed to open GLFW window\n"); + exit(EXIT_FAILURE); + } + + glfwMakeContextCurrent(window); + glfwSwapInterval(1); + + glfwSetKeyCallback(window, key_callback); + glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); + + glMatrixMode(GL_PROJECTION); + glOrtho(-1.f, 1.f, -1.f, 1.f, -1.f, 1.f); + glMatrixMode(GL_MODELVIEW); + + glClearColor(0.5f, 0.5f, 0.5f, 0); + + while (!glfwWindowShouldClose(window)) + { + glClear(GL_COLOR_BUFFER_BIT); + + glColor3f(0.8f, 0.2f, 0.4f); + glRectf(-0.5f, -0.5f, 0.5f, 0.5f); + + glfwSwapBuffers(window); + glfwWaitEvents(); + } + + glfwTerminate(); + exit(EXIT_SUCCESS); +} + diff --git a/testbed/glfw/tests/cursor.c b/testbed/glfw/tests/cursor.c new file mode 100644 index 00000000..9b899266 --- /dev/null +++ b/testbed/glfw/tests/cursor.c @@ -0,0 +1,289 @@ +//======================================================================== +// Cursor & input mode tests +// Copyright (c) Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== +// +// System cursors and input modes tests. +// +//======================================================================== + +#define GLFW_INCLUDE_GLU +#include + +#include +#include + +static int W = 640; +static int H = 480; +static int delay = 0; + +static GLFWwindow* windows[2] = { NULL, NULL }; +static GLFWwindow* activeWindow = NULL; +static GLFWcursor* cursor = NULL; + +static struct +{ + int key; + double time; +} commands[] = { + {GLFW_KEY_H, 0}, + {GLFW_KEY_C, 0}, + {GLFW_KEY_D, 0}, + {GLFW_KEY_S, 0}, + {GLFW_KEY_N, 0}, + {GLFW_KEY_1, 0}, + {GLFW_KEY_2, 0}, + {GLFW_KEY_3, 0} +}; + +static int CommandCount = sizeof(commands) / sizeof(commands[0]); + +static struct +{ + int w, h; +} cursorSize[] = { + { 24, 24 }, { 13, 37 }, { 5, 53 }, { 43, 64 }, { 300, 300 } +}; + +static int SizeCount = sizeof(cursorSize) / sizeof(cursorSize[0]); +static int currentSize = 0; + +static void command_callback(int key) +{ + switch (key) + { + case GLFW_KEY_H: + { + printf("H: show this help\n"); + printf("C: call glfwCreateCursor()\n"); + printf("D: call glfwDestroyCursor()\n"); + printf("S: call glfwSetCursor()\n"); + printf("N: call glfwSetCursor() with NULL\n"); + printf("1: set GLFW_CURSOR_NORMAL\n"); + printf("2: set GLFW_CURSOR_HIDDEN\n"); + printf("3: set GLFW_CURSOR_DISABLED\n"); + printf("T: enable 3s delay for all previous commands\n"); + } + break; + + case GLFW_KEY_C: + { + int x, y; + GLFWimage image; + unsigned char* pixels; + + if (cursor) + break; + + image.width = cursorSize[currentSize].w; + image.height = cursorSize[currentSize].h; + + pixels = malloc(4 * image.width * image.height); + image.pixels = pixels; + + for (y = 0; y < image.height; y++) + { + for (x = 0; x < image.width; x++) + { + *pixels++ = 0xff; + *pixels++ = 0; + *pixels++ = 255 * y / image.height; + *pixels++ = 255 * x / image.width; + } + } + + cursor = glfwCreateCursor(&image, image.width / 2, image.height / 2); + currentSize = (currentSize + 1) % SizeCount; + free(image.pixels); + break; + } + + case GLFW_KEY_D: + { + if (cursor != NULL) + { + glfwDestroyCursor(cursor); + cursor = NULL; + } + + break; + } + + case GLFW_KEY_S: + { + if (cursor != NULL) + glfwSetCursor(activeWindow, cursor); + else + printf("The cursor is not created\n"); + + break; + } + + case GLFW_KEY_N: + glfwSetCursor(activeWindow, NULL); + break; + + case GLFW_KEY_1: + glfwSetInputMode(activeWindow, GLFW_CURSOR, GLFW_CURSOR_NORMAL); + break; + + case GLFW_KEY_2: + glfwSetInputMode(activeWindow, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); + break; + + case GLFW_KEY_3: + glfwSetInputMode(activeWindow, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + break; + } +} + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +static void framebuffer_size_callback(GLFWwindow* window, int width, int height) +{ + W = width; + H = height; + + glViewport(0, 0, W, H); +} + +static void refresh_callback(GLFWwindow* window) +{ + glfwMakeContextCurrent(window); + glClearColor(0.0f, window == activeWindow ? 0.8f : 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + glfwSwapBuffers(window); +} + +static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + if (action != GLFW_PRESS) + return; + + switch (key) + { + case GLFW_KEY_ESCAPE: + glfwSetWindowShouldClose(window, GL_TRUE); + break; + + case GLFW_KEY_T: + delay = !delay; + printf("Delay %s.\n", delay ? "enabled" : "disabled"); + break; + + default: + { + if (delay) + { + int i = 0; + + while (i < CommandCount && commands[i].key != key) + i++; + + if (i < CommandCount) + commands[i].time = glfwGetTime(); + } + else + { + command_callback(key); + } + } + break; + } +} + +static void focus_callback(GLFWwindow* window, int focused) +{ + if (focused) + { + activeWindow = window; + refresh_callback(windows[0]); + refresh_callback(windows[1]); + } +} + +int main(void) +{ + int i; + GLboolean running = GL_TRUE; + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + for (i = 0; i < 2; i++) + { + windows[i] = glfwCreateWindow(W, H, "Cursor testing", NULL, NULL); + + if (!windows[i]) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glfwSetWindowPos(windows[i], 100 + (i & 1) * (W + 50), 100); + + glfwSetWindowRefreshCallback(windows[i], refresh_callback); + glfwSetFramebufferSizeCallback(windows[i], framebuffer_size_callback); + glfwSetKeyCallback(windows[i], key_callback); + glfwSetWindowFocusCallback(windows[i], focus_callback); + + glfwMakeContextCurrent(windows[i]); + glClear(GL_COLOR_BUFFER_BIT); + glfwSwapBuffers(windows[i]); + } + + activeWindow = windows[0]; + + key_callback(NULL, GLFW_KEY_H, 0, GLFW_PRESS, 0); + + while (running) + { + if (delay) + { + int i; + double t = glfwGetTime(); + + for (i = 0; i < CommandCount; i++) + { + if (commands[i].time != 0 && t - commands[i].time >= 3.0) + { + command_callback(commands[i].key); + commands[i].time = 0; + } + } + } + + running = !(glfwWindowShouldClose(windows[0]) || glfwWindowShouldClose(windows[1])); + + glfwPollEvents(); + } + + glfwTerminate(); + exit(EXIT_SUCCESS); +} + diff --git a/testbed/glfw/tests/cursoranim.c b/testbed/glfw/tests/cursoranim.c new file mode 100644 index 00000000..39a229c8 --- /dev/null +++ b/testbed/glfw/tests/cursoranim.c @@ -0,0 +1,135 @@ +//======================================================================== +// Cursor animation +// Copyright (c) Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== +// +// Cursor animation test. +// +//======================================================================== + +#include + +#include +#include + +#ifdef min + #undef min +#endif +#ifdef max + #undef max +#endif + +#define SIZE 64 // cursor size (width & height) +#define N 60 // number of frames + +unsigned char buffer[4 * SIZE * SIZE]; + +static float max(float a, float b) { return a > b ? a : b; } +static float min(float a, float b) { return a < b ? a : b; } + +static float star(int x, int y, float t) +{ + float c = SIZE / 2.0f; + + float i = (0.25f * (float)sin(2.0f * 3.1415926f * t) + 0.75f); + float k = SIZE * 0.046875f * i; + + float dist = (float)sqrt((x - c) * (x - c) + (y - c) * (y - c)); + + float salpha = 1.0f - dist / c; + float xalpha = (float)x == c ? c : k / (float)fabs(x - c); + float yalpha = (float)y == c ? c : k / (float)fabs(y - c); + + return max(0.0f, min(1.0f, i * salpha * 0.2f + salpha * xalpha * yalpha)); +} + +static GLFWcursor* load_frame(float t) +{ + int i = 0, x, y; + const GLFWimage image = { SIZE, SIZE, buffer }; + + for (y = 0; y < image.width; y++) + { + for (x = 0; x < image.height; x++) + { + buffer[i++] = 255; + buffer[i++] = 255; + buffer[i++] = 255; + buffer[i++] = (unsigned char)(255 * star(x, y, t)); + } + } + + return glfwCreateCursor(&image, image.width / 2, image.height / 2); +} + +int main(void) +{ + int i; + double t0, t1, frameTime = 0.0; + + GLFWwindow* window; + GLFWcursor* frames[N]; + + if (!glfwInit()) + exit(EXIT_FAILURE); + + window = glfwCreateWindow(640, 480, "Cursor animation", NULL, NULL); + + if (!window) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glfwMakeContextCurrent(window); + glfwSwapInterval(1); + + for (i = 0; i < N; i++) + frames[i] = load_frame(i / (float)N); + + i = 0; + + t0 = glfwGetTime(); + + while (!glfwWindowShouldClose(window)) + { + glClear(GL_COLOR_BUFFER_BIT); + glfwSetCursor(window, frames[i]); + glfwSwapBuffers(window); + glfwPollEvents(); + + t1 = glfwGetTime(); + frameTime += t1 - t0; + t0 = t1; + + while (frameTime > 1.0 / (double)N) + { + i = (i + 1) % N; + frameTime -= 1.0 / (double)N; + } + } + + glfwTerminate(); + exit(EXIT_SUCCESS); +} + diff --git a/testbed/glfw/tests/defaults.c b/testbed/glfw/tests/defaults.c new file mode 100644 index 00000000..07ba5a45 --- /dev/null +++ b/testbed/glfw/tests/defaults.c @@ -0,0 +1,131 @@ +//======================================================================== +// Default window/context test +// Copyright (c) Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== +// +// This test creates a windowed mode window with all window hints set to +// default values and then reports the actual attributes of the created +// window and context +// +//======================================================================== + +#define GLFW_INCLUDE_GLEXT +#include + +#include +#include + +typedef struct +{ + int attrib; + const char* ext; + const char* name; +} AttribGL; + +typedef struct +{ + int attrib; + const char* name; +} AttribGLFW; + +static AttribGL gl_attribs[] = +{ + { GL_RED_BITS, NULL, "red bits" }, + { GL_GREEN_BITS, NULL, "green bits" }, + { GL_BLUE_BITS, NULL, "blue bits" }, + { GL_ALPHA_BITS, NULL, "alpha bits" }, + { GL_DEPTH_BITS, NULL, "depth bits" }, + { GL_STENCIL_BITS, NULL, "stencil bits" }, + { GL_STEREO, NULL, "stereo" }, + { GL_SAMPLES_ARB, "GL_ARB_multisample", "FSAA samples" }, + { 0, NULL, NULL } +}; + +static AttribGLFW glfw_attribs[] = +{ + { GLFW_CONTEXT_VERSION_MAJOR, "Context version major" }, + { GLFW_CONTEXT_VERSION_MINOR, "Context version minor" }, + { GLFW_OPENGL_FORWARD_COMPAT, "OpenGL forward compatible" }, + { GLFW_OPENGL_DEBUG_CONTEXT, "OpenGL debug context" }, + { GLFW_OPENGL_PROFILE, "OpenGL profile" }, + { 0, NULL } +}; + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +int main(void) +{ + int i, width, height; + GLFWwindow* window; + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + glfwWindowHint(GLFW_VISIBLE, GL_FALSE); + + window = glfwCreateWindow(640, 480, "Defaults", NULL, NULL); + if (!window) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glfwMakeContextCurrent(window); + glfwGetFramebufferSize(window, &width, &height); + + printf("framebuffer size: %ix%i\n", width, height); + + for (i = 0; glfw_attribs[i].name; i++) + { + printf("%s: %i\n", + glfw_attribs[i].name, + glfwGetWindowAttrib(window, glfw_attribs[i].attrib)); + } + + for (i = 0; gl_attribs[i].name; i++) + { + GLint value = 0; + + if (gl_attribs[i].ext) + { + if (!glfwExtensionSupported(gl_attribs[i].ext)) + continue; + } + + glGetIntegerv(gl_attribs[i].attrib, &value); + + printf("%s: %i\n", gl_attribs[i].name, value); + } + + glfwDestroyWindow(window); + window = NULL; + + glfwTerminate(); + exit(EXIT_SUCCESS); +} + diff --git a/testbed/glfw/tests/empty.c b/testbed/glfw/tests/empty.c new file mode 100644 index 00000000..a4534ae5 --- /dev/null +++ b/testbed/glfw/tests/empty.c @@ -0,0 +1,129 @@ +//======================================================================== +// Empty event test +// Copyright (c) Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== +// +// This test is intended to verify that posting of empty events works +// +//======================================================================== + +#include "tinycthread.h" + +#include + +#include +#include +#include + +static volatile GLboolean running = GL_TRUE; + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +static int thread_main(void* data) +{ + struct timespec time; + + while (running) + { + clock_gettime(CLOCK_REALTIME, &time); + time.tv_sec += 1; + thrd_sleep(&time, NULL); + + glfwPostEmptyEvent(); + } + + return 0; +} + +static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) + glfwSetWindowShouldClose(window, GL_TRUE); +} + +static float nrand(void) +{ + return (float) rand() / (float) RAND_MAX; +} + +int main(void) +{ + int result; + thrd_t thread; + GLFWwindow* window; + + srand((unsigned int) time(NULL)); + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + window = glfwCreateWindow(640, 480, "Empty Event Test", NULL, NULL); + if (!window) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glfwMakeContextCurrent(window); + glfwSetKeyCallback(window, key_callback); + + if (thrd_create(&thread, thread_main, NULL) != thrd_success) + { + fprintf(stderr, "Failed to create secondary thread\n"); + + glfwTerminate(); + exit(EXIT_FAILURE); + } + + while (running) + { + int width, height; + float r = nrand(), g = nrand(), b = nrand(); + float l = (float) sqrt(r * r + g * g + b * b); + + glfwGetFramebufferSize(window, &width, &height); + + glViewport(0, 0, width, height); + glClearColor(r / l, g / l, b / l, 1.f); + glClear(GL_COLOR_BUFFER_BIT); + glfwSwapBuffers(window); + + glfwWaitEvents(); + + if (glfwWindowShouldClose(window)) + running = GL_FALSE; + } + + glfwHideWindow(window); + thrd_join(thread, &result); + glfwDestroyWindow(window); + + glfwTerminate(); + exit(EXIT_SUCCESS); +} + diff --git a/testbed/glfw/tests/events.c b/testbed/glfw/tests/events.c new file mode 100644 index 00000000..fda68164 --- /dev/null +++ b/testbed/glfw/tests/events.c @@ -0,0 +1,581 @@ +//======================================================================== +// Event linter (event spewer) +// Copyright (c) Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== +// +// This test hooks every available callback and outputs their arguments +// +// Log messages go to stdout, error messages to stderr +// +// Every event also gets a (sequential) number to aid discussion of logs +// +//======================================================================== + +#include + +#include +#include +#include +#include +#include + +#include "getopt.h" + +// Event index +static unsigned int counter = 0; + +typedef struct +{ + GLFWwindow* window; + int number; + int closeable; +} Slot; + +static void usage(void) +{ + printf("Usage: events [-f] [-h] [-n WINDOWS]\n"); + printf("Options:\n"); + printf(" -f use full screen\n"); + printf(" -h show this help\n"); + printf(" -n the number of windows to create\n"); +} + +static const char* get_key_name(int key) +{ + switch (key) + { + // Printable keys + case GLFW_KEY_A: return "A"; + case GLFW_KEY_B: return "B"; + case GLFW_KEY_C: return "C"; + case GLFW_KEY_D: return "D"; + case GLFW_KEY_E: return "E"; + case GLFW_KEY_F: return "F"; + case GLFW_KEY_G: return "G"; + case GLFW_KEY_H: return "H"; + case GLFW_KEY_I: return "I"; + case GLFW_KEY_J: return "J"; + case GLFW_KEY_K: return "K"; + case GLFW_KEY_L: return "L"; + case GLFW_KEY_M: return "M"; + case GLFW_KEY_N: return "N"; + case GLFW_KEY_O: return "O"; + case GLFW_KEY_P: return "P"; + case GLFW_KEY_Q: return "Q"; + case GLFW_KEY_R: return "R"; + case GLFW_KEY_S: return "S"; + case GLFW_KEY_T: return "T"; + case GLFW_KEY_U: return "U"; + case GLFW_KEY_V: return "V"; + case GLFW_KEY_W: return "W"; + case GLFW_KEY_X: return "X"; + case GLFW_KEY_Y: return "Y"; + case GLFW_KEY_Z: return "Z"; + case GLFW_KEY_1: return "1"; + case GLFW_KEY_2: return "2"; + case GLFW_KEY_3: return "3"; + case GLFW_KEY_4: return "4"; + case GLFW_KEY_5: return "5"; + case GLFW_KEY_6: return "6"; + case GLFW_KEY_7: return "7"; + case GLFW_KEY_8: return "8"; + case GLFW_KEY_9: return "9"; + case GLFW_KEY_0: return "0"; + case GLFW_KEY_SPACE: return "SPACE"; + case GLFW_KEY_MINUS: return "MINUS"; + case GLFW_KEY_EQUAL: return "EQUAL"; + case GLFW_KEY_LEFT_BRACKET: return "LEFT BRACKET"; + case GLFW_KEY_RIGHT_BRACKET: return "RIGHT BRACKET"; + case GLFW_KEY_BACKSLASH: return "BACKSLASH"; + case GLFW_KEY_SEMICOLON: return "SEMICOLON"; + case GLFW_KEY_APOSTROPHE: return "APOSTROPHE"; + case GLFW_KEY_GRAVE_ACCENT: return "GRAVE ACCENT"; + case GLFW_KEY_COMMA: return "COMMA"; + case GLFW_KEY_PERIOD: return "PERIOD"; + case GLFW_KEY_SLASH: return "SLASH"; + case GLFW_KEY_WORLD_1: return "WORLD 1"; + case GLFW_KEY_WORLD_2: return "WORLD 2"; + + // Function keys + case GLFW_KEY_ESCAPE: return "ESCAPE"; + case GLFW_KEY_F1: return "F1"; + case GLFW_KEY_F2: return "F2"; + case GLFW_KEY_F3: return "F3"; + case GLFW_KEY_F4: return "F4"; + case GLFW_KEY_F5: return "F5"; + case GLFW_KEY_F6: return "F6"; + case GLFW_KEY_F7: return "F7"; + case GLFW_KEY_F8: return "F8"; + case GLFW_KEY_F9: return "F9"; + case GLFW_KEY_F10: return "F10"; + case GLFW_KEY_F11: return "F11"; + case GLFW_KEY_F12: return "F12"; + case GLFW_KEY_F13: return "F13"; + case GLFW_KEY_F14: return "F14"; + case GLFW_KEY_F15: return "F15"; + case GLFW_KEY_F16: return "F16"; + case GLFW_KEY_F17: return "F17"; + case GLFW_KEY_F18: return "F18"; + case GLFW_KEY_F19: return "F19"; + case GLFW_KEY_F20: return "F20"; + case GLFW_KEY_F21: return "F21"; + case GLFW_KEY_F22: return "F22"; + case GLFW_KEY_F23: return "F23"; + case GLFW_KEY_F24: return "F24"; + case GLFW_KEY_F25: return "F25"; + case GLFW_KEY_UP: return "UP"; + case GLFW_KEY_DOWN: return "DOWN"; + case GLFW_KEY_LEFT: return "LEFT"; + case GLFW_KEY_RIGHT: return "RIGHT"; + case GLFW_KEY_LEFT_SHIFT: return "LEFT SHIFT"; + case GLFW_KEY_RIGHT_SHIFT: return "RIGHT SHIFT"; + case GLFW_KEY_LEFT_CONTROL: return "LEFT CONTROL"; + case GLFW_KEY_RIGHT_CONTROL: return "RIGHT CONTROL"; + case GLFW_KEY_LEFT_ALT: return "LEFT ALT"; + case GLFW_KEY_RIGHT_ALT: return "RIGHT ALT"; + case GLFW_KEY_TAB: return "TAB"; + case GLFW_KEY_ENTER: return "ENTER"; + case GLFW_KEY_BACKSPACE: return "BACKSPACE"; + case GLFW_KEY_INSERT: return "INSERT"; + case GLFW_KEY_DELETE: return "DELETE"; + case GLFW_KEY_PAGE_UP: return "PAGE UP"; + case GLFW_KEY_PAGE_DOWN: return "PAGE DOWN"; + case GLFW_KEY_HOME: return "HOME"; + case GLFW_KEY_END: return "END"; + case GLFW_KEY_KP_0: return "KEYPAD 0"; + case GLFW_KEY_KP_1: return "KEYPAD 1"; + case GLFW_KEY_KP_2: return "KEYPAD 2"; + case GLFW_KEY_KP_3: return "KEYPAD 3"; + case GLFW_KEY_KP_4: return "KEYPAD 4"; + case GLFW_KEY_KP_5: return "KEYPAD 5"; + case GLFW_KEY_KP_6: return "KEYPAD 6"; + case GLFW_KEY_KP_7: return "KEYPAD 7"; + case GLFW_KEY_KP_8: return "KEYPAD 8"; + case GLFW_KEY_KP_9: return "KEYPAD 9"; + case GLFW_KEY_KP_DIVIDE: return "KEYPAD DIVIDE"; + case GLFW_KEY_KP_MULTIPLY: return "KEYPAD MULTPLY"; + case GLFW_KEY_KP_SUBTRACT: return "KEYPAD SUBTRACT"; + case GLFW_KEY_KP_ADD: return "KEYPAD ADD"; + case GLFW_KEY_KP_DECIMAL: return "KEYPAD DECIMAL"; + case GLFW_KEY_KP_EQUAL: return "KEYPAD EQUAL"; + case GLFW_KEY_KP_ENTER: return "KEYPAD ENTER"; + case GLFW_KEY_PRINT_SCREEN: return "PRINT SCREEN"; + case GLFW_KEY_NUM_LOCK: return "NUM LOCK"; + case GLFW_KEY_CAPS_LOCK: return "CAPS LOCK"; + case GLFW_KEY_SCROLL_LOCK: return "SCROLL LOCK"; + case GLFW_KEY_PAUSE: return "PAUSE"; + case GLFW_KEY_LEFT_SUPER: return "LEFT SUPER"; + case GLFW_KEY_RIGHT_SUPER: return "RIGHT SUPER"; + case GLFW_KEY_MENU: return "MENU"; + + default: return "UNKNOWN"; + } +} + +static const char* get_action_name(int action) +{ + switch (action) + { + case GLFW_PRESS: + return "pressed"; + case GLFW_RELEASE: + return "released"; + case GLFW_REPEAT: + return "repeated"; + } + + return "caused unknown action"; +} + +static const char* get_button_name(int button) +{ + switch (button) + { + case GLFW_MOUSE_BUTTON_LEFT: + return "left"; + case GLFW_MOUSE_BUTTON_RIGHT: + return "right"; + case GLFW_MOUSE_BUTTON_MIDDLE: + return "middle"; + default: + { + static char name[16]; + sprintf(name, "%i", button); + return name; + } + } +} + +static const char* get_mods_name(int mods) +{ + static char name[512]; + + if (mods == 0) + return " no mods"; + + name[0] = '\0'; + + if (mods & GLFW_MOD_SHIFT) + strcat(name, " shift"); + if (mods & GLFW_MOD_CONTROL) + strcat(name, " control"); + if (mods & GLFW_MOD_ALT) + strcat(name, " alt"); + if (mods & GLFW_MOD_SUPER) + strcat(name, " super"); + + return name; +} + +static const char* get_character_string(int codepoint) +{ + // This assumes UTF-8, which is stupid + static char result[6 + 1]; + + int length = wctomb(result, codepoint); + if (length == -1) + length = 0; + + result[length] = '\0'; + return result; +} + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +static void window_pos_callback(GLFWwindow* window, int x, int y) +{ + Slot* slot = glfwGetWindowUserPointer(window); + printf("%08x to %i at %0.3f: Window position: %i %i\n", + counter++, slot->number, glfwGetTime(), x, y); +} + +static void window_size_callback(GLFWwindow* window, int width, int height) +{ + Slot* slot = glfwGetWindowUserPointer(window); + printf("%08x to %i at %0.3f: Window size: %i %i\n", + counter++, slot->number, glfwGetTime(), width, height); +} + +static void framebuffer_size_callback(GLFWwindow* window, int width, int height) +{ + Slot* slot = glfwGetWindowUserPointer(window); + printf("%08x to %i at %0.3f: Framebuffer size: %i %i\n", + counter++, slot->number, glfwGetTime(), width, height); + + glViewport(0, 0, width, height); +} + +static void window_close_callback(GLFWwindow* window) +{ + Slot* slot = glfwGetWindowUserPointer(window); + printf("%08x to %i at %0.3f: Window close\n", + counter++, slot->number, glfwGetTime()); + + glfwSetWindowShouldClose(window, slot->closeable); +} + +static void window_refresh_callback(GLFWwindow* window) +{ + Slot* slot = glfwGetWindowUserPointer(window); + printf("%08x to %i at %0.3f: Window refresh\n", + counter++, slot->number, glfwGetTime()); + + glfwMakeContextCurrent(window); + glClear(GL_COLOR_BUFFER_BIT); + glfwSwapBuffers(window); +} + +static void window_focus_callback(GLFWwindow* window, int focused) +{ + Slot* slot = glfwGetWindowUserPointer(window); + printf("%08x to %i at %0.3f: Window %s\n", + counter++, slot->number, glfwGetTime(), + focused ? "focused" : "defocused"); +} + +static void window_iconify_callback(GLFWwindow* window, int iconified) +{ + Slot* slot = glfwGetWindowUserPointer(window); + printf("%08x to %i at %0.3f: Window was %s\n", + counter++, slot->number, glfwGetTime(), + iconified ? "iconified" : "restored"); +} + +static void mouse_button_callback(GLFWwindow* window, int button, int action, int mods) +{ + Slot* slot = glfwGetWindowUserPointer(window); + printf("%08x to %i at %0.3f: Mouse button %i (%s) (with%s) was %s\n", + counter++, slot->number, glfwGetTime(), button, + get_button_name(button), + get_mods_name(mods), + get_action_name(action)); +} + +static void cursor_position_callback(GLFWwindow* window, double x, double y) +{ + Slot* slot = glfwGetWindowUserPointer(window); + printf("%08x to %i at %0.3f: Cursor position: %f %f\n", + counter++, slot->number, glfwGetTime(), x, y); +} + +static void cursor_enter_callback(GLFWwindow* window, int entered) +{ + Slot* slot = glfwGetWindowUserPointer(window); + printf("%08x to %i at %0.3f: Cursor %s window\n", + counter++, slot->number, glfwGetTime(), + entered ? "entered" : "left"); +} + +static void scroll_callback(GLFWwindow* window, double x, double y) +{ + Slot* slot = glfwGetWindowUserPointer(window); + printf("%08x to %i at %0.3f: Scroll: %0.3f %0.3f\n", + counter++, slot->number, glfwGetTime(), x, y); +} + +static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + Slot* slot = glfwGetWindowUserPointer(window); + + printf("%08x to %i at %0.3f: Key 0x%04x Scancode 0x%04x (%s) (with%s) was %s\n", + counter++, slot->number, glfwGetTime(), key, scancode, + get_key_name(key), + get_mods_name(mods), + get_action_name(action)); + + if (action != GLFW_PRESS) + return; + + switch (key) + { + case GLFW_KEY_C: + { + slot->closeable = !slot->closeable; + + printf("(( closing %s ))\n", slot->closeable ? "enabled" : "disabled"); + break; + } + } +} + +static void char_callback(GLFWwindow* window, unsigned int codepoint) +{ + Slot* slot = glfwGetWindowUserPointer(window); + printf("%08x to %i at %0.3f: Character 0x%08x (%s) input\n", + counter++, slot->number, glfwGetTime(), codepoint, + get_character_string(codepoint)); +} + +static void char_mods_callback(GLFWwindow* window, unsigned int codepoint, int mods) +{ + Slot* slot = glfwGetWindowUserPointer(window); + printf("%08x to %i at %0.3f: Character 0x%08x (%s) with modifiers (with%s) input\n", + counter++, slot->number, glfwGetTime(), codepoint, + get_character_string(codepoint), + get_mods_name(mods)); +} + +static void drop_callback(GLFWwindow* window, int count, const char** names) +{ + int i; + Slot* slot = glfwGetWindowUserPointer(window); + + printf("%08x to %i at %0.3f: Drop input\n", + counter++, slot->number, glfwGetTime()); + + for (i = 0; i < count; i++) + printf(" %i: \"%s\"\n", i, names[i]); +} + +static void monitor_callback(GLFWmonitor* monitor, int event) +{ + if (event == GLFW_CONNECTED) + { + int x, y, widthMM, heightMM; + const GLFWvidmode* mode = glfwGetVideoMode(monitor); + + glfwGetMonitorPos(monitor, &x, &y); + glfwGetMonitorPhysicalSize(monitor, &widthMM, &heightMM); + + printf("%08x at %0.3f: Monitor %s (%ix%i at %ix%i, %ix%i mm) was connected\n", + counter++, + glfwGetTime(), + glfwGetMonitorName(monitor), + mode->width, mode->height, + x, y, + widthMM, heightMM); + } + else + { + printf("%08x at %0.3f: Monitor %s was disconnected\n", + counter++, + glfwGetTime(), + glfwGetMonitorName(monitor)); + } +} + +int main(int argc, char** argv) +{ + Slot* slots; + GLFWmonitor* monitor = NULL; + int ch, i, width, height, count = 1; + + setlocale(LC_ALL, ""); + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + printf("Library initialized\n"); + + glfwSetMonitorCallback(monitor_callback); + + while ((ch = getopt(argc, argv, "hfn:")) != -1) + { + switch (ch) + { + case 'h': + usage(); + exit(EXIT_SUCCESS); + + case 'f': + monitor = glfwGetPrimaryMonitor(); + break; + + case 'n': + count = (int) strtol(optarg, NULL, 10); + break; + + default: + usage(); + exit(EXIT_FAILURE); + } + } + + if (monitor) + { + const GLFWvidmode* mode = glfwGetVideoMode(monitor); + + glfwWindowHint(GLFW_REFRESH_RATE, mode->refreshRate); + glfwWindowHint(GLFW_RED_BITS, mode->redBits); + glfwWindowHint(GLFW_GREEN_BITS, mode->greenBits); + glfwWindowHint(GLFW_BLUE_BITS, mode->blueBits); + + width = mode->width; + height = mode->height; + } + else + { + width = 640; + height = 480; + } + + if (!count) + { + fprintf(stderr, "Invalid user\n"); + exit(EXIT_FAILURE); + } + + slots = calloc(count, sizeof(Slot)); + + for (i = 0; i < count; i++) + { + char title[128]; + + slots[i].closeable = GL_TRUE; + slots[i].number = i + 1; + + sprintf(title, "Event Linter (Window %i)", slots[i].number); + + if (monitor) + { + printf("Creating full screen window %i (%ix%i on %s)\n", + slots[i].number, + width, height, + glfwGetMonitorName(monitor)); + } + else + { + printf("Creating windowed mode window %i (%ix%i)\n", + slots[i].number, + width, height); + } + + slots[i].window = glfwCreateWindow(width, height, title, monitor, NULL); + if (!slots[i].window) + { + free(slots); + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glfwSetWindowUserPointer(slots[i].window, slots + i); + + glfwSetWindowPosCallback(slots[i].window, window_pos_callback); + glfwSetWindowSizeCallback(slots[i].window, window_size_callback); + glfwSetFramebufferSizeCallback(slots[i].window, framebuffer_size_callback); + glfwSetWindowCloseCallback(slots[i].window, window_close_callback); + glfwSetWindowRefreshCallback(slots[i].window, window_refresh_callback); + glfwSetWindowFocusCallback(slots[i].window, window_focus_callback); + glfwSetWindowIconifyCallback(slots[i].window, window_iconify_callback); + glfwSetMouseButtonCallback(slots[i].window, mouse_button_callback); + glfwSetCursorPosCallback(slots[i].window, cursor_position_callback); + glfwSetCursorEnterCallback(slots[i].window, cursor_enter_callback); + glfwSetScrollCallback(slots[i].window, scroll_callback); + glfwSetKeyCallback(slots[i].window, key_callback); + glfwSetCharCallback(slots[i].window, char_callback); + glfwSetCharModsCallback(slots[i].window, char_mods_callback); + glfwSetDropCallback(slots[i].window, drop_callback); + + glfwMakeContextCurrent(slots[i].window); + glfwSwapInterval(1); + } + + printf("Main loop starting\n"); + + for (;;) + { + for (i = 0; i < count; i++) + { + if (glfwWindowShouldClose(slots[i].window)) + break; + } + + if (i < count) + break; + + glfwWaitEvents(); + + // Workaround for an issue with msvcrt and mintty + fflush(stdout); + } + + free(slots); + glfwTerminate(); + exit(EXIT_SUCCESS); +} + diff --git a/testbed/glfw/tests/fsaa.c b/testbed/glfw/tests/fsaa.c new file mode 100644 index 00000000..b368745a --- /dev/null +++ b/testbed/glfw/tests/fsaa.c @@ -0,0 +1,162 @@ +//======================================================================== +// Full screen anti-aliasing test +// Copyright (c) Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== +// +// This test renders two high contrast, slowly rotating quads, one aliased +// and one (hopefully) anti-aliased, thus allowing for visual verification +// of whether FSAA is indeed enabled +// +//======================================================================== + +#define GLFW_INCLUDE_GLEXT +#include + +#include +#include + +#include "getopt.h" + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +static void framebuffer_size_callback(GLFWwindow* window, int width, int height) +{ + glViewport(0, 0, width, height); +} + +static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + if (action != GLFW_PRESS) + return; + + switch (key) + { + case GLFW_KEY_SPACE: + glfwSetTime(0.0); + break; + } +} + +static void usage(void) +{ + printf("Usage: fsaa [-h] [-s SAMPLES]\n"); +} + +int main(int argc, char** argv) +{ + int ch, samples = 4; + GLFWwindow* window; + + while ((ch = getopt(argc, argv, "hs:")) != -1) + { + switch (ch) + { + case 'h': + usage(); + exit(EXIT_SUCCESS); + case 's': + samples = atoi(optarg); + break; + default: + usage(); + exit(EXIT_FAILURE); + } + } + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + if (samples) + printf("Requesting FSAA with %i samples\n", samples); + else + printf("Requesting that FSAA not be available\n"); + + glfwWindowHint(GLFW_SAMPLES, samples); + glfwWindowHint(GLFW_VISIBLE, GL_FALSE); + + window = glfwCreateWindow(800, 400, "Aliasing Detector", NULL, NULL); + if (!window) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glfwSetKeyCallback(window, key_callback); + glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); + + glfwMakeContextCurrent(window); + glfwSwapInterval(1); + + if (!glfwExtensionSupported("GL_ARB_multisample")) + { + printf("GL_ARB_multisample extension not supported\n"); + + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glfwShowWindow(window); + + glGetIntegerv(GL_SAMPLES_ARB, &samples); + if (samples) + printf("Context reports FSAA is available with %i samples\n", samples); + else + printf("Context reports FSAA is unavailable\n"); + + glMatrixMode(GL_PROJECTION); + glOrtho(0.f, 1.f, 0.f, 0.5f, 0.f, 1.f); + glMatrixMode(GL_MODELVIEW); + + while (!glfwWindowShouldClose(window)) + { + GLfloat time = (GLfloat) glfwGetTime(); + + glClear(GL_COLOR_BUFFER_BIT); + + glLoadIdentity(); + glTranslatef(0.25f, 0.25f, 0.f); + glRotatef(time, 0.f, 0.f, 1.f); + + glDisable(GL_MULTISAMPLE_ARB); + glRectf(-0.15f, -0.15f, 0.15f, 0.15f); + + glLoadIdentity(); + glTranslatef(0.75f, 0.25f, 0.f); + glRotatef(time, 0.f, 0.f, 1.f); + + glEnable(GL_MULTISAMPLE_ARB); + glRectf(-0.15f, -0.15f, 0.15f, 0.15f); + + glfwSwapBuffers(window); + glfwPollEvents(); + } + + glfwTerminate(); + exit(EXIT_SUCCESS); +} + diff --git a/testbed/glfw/tests/gamma.c b/testbed/glfw/tests/gamma.c new file mode 100644 index 00000000..93a24e6f --- /dev/null +++ b/testbed/glfw/tests/gamma.c @@ -0,0 +1,181 @@ +//======================================================================== +// Gamma correction test program +// Copyright (c) Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== +// +// This program is used to test the gamma correction functionality for +// both full screen and windowed mode windows +// +//======================================================================== + +#include + +#include +#include + +#include "getopt.h" + +#define STEP_SIZE 0.1f + +static GLfloat gamma_value = 1.0f; + +static void usage(void) +{ + printf("Usage: gamma [-h] [-f]\n"); +} + +static void set_gamma(GLFWwindow* window, float value) +{ + GLFWmonitor* monitor = glfwGetWindowMonitor(window); + if (!monitor) + monitor = glfwGetPrimaryMonitor(); + + gamma_value = value; + printf("Gamma: %f\n", gamma_value); + glfwSetGamma(monitor, gamma_value); +} + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + if (action != GLFW_PRESS) + return; + + switch (key) + { + case GLFW_KEY_ESCAPE: + { + glfwSetWindowShouldClose(window, GL_TRUE); + break; + } + + case GLFW_KEY_KP_ADD: + case GLFW_KEY_Q: + { + set_gamma(window, gamma_value + STEP_SIZE); + break; + } + + case GLFW_KEY_KP_SUBTRACT: + case GLFW_KEY_W: + { + if (gamma_value - STEP_SIZE > 0.f) + set_gamma(window, gamma_value - STEP_SIZE); + + break; + } + } +} + +static void framebuffer_size_callback(GLFWwindow* window, int width, int height) +{ + glViewport(0, 0, width, height); +} + +int main(int argc, char** argv) +{ + int width, height, ch; + GLFWmonitor* monitor = NULL; + GLFWwindow* window; + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + while ((ch = getopt(argc, argv, "fh")) != -1) + { + switch (ch) + { + case 'h': + usage(); + exit(EXIT_SUCCESS); + + case 'f': + monitor = glfwGetPrimaryMonitor(); + break; + + default: + usage(); + exit(EXIT_FAILURE); + } + } + + if (monitor) + { + const GLFWvidmode* mode = glfwGetVideoMode(monitor); + + glfwWindowHint(GLFW_REFRESH_RATE, mode->refreshRate); + glfwWindowHint(GLFW_RED_BITS, mode->redBits); + glfwWindowHint(GLFW_GREEN_BITS, mode->greenBits); + glfwWindowHint(GLFW_BLUE_BITS, mode->blueBits); + + width = mode->width; + height = mode->height; + } + else + { + width = 200; + height = 200; + } + + window = glfwCreateWindow(width, height, "Gamma Test", monitor, NULL); + if (!window) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + set_gamma(window, 1.f); + + glfwMakeContextCurrent(window); + glfwSwapInterval(1); + + glfwSetKeyCallback(window, key_callback); + glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); + + glMatrixMode(GL_PROJECTION); + glOrtho(-1.f, 1.f, -1.f, 1.f, -1.f, 1.f); + glMatrixMode(GL_MODELVIEW); + + glClearColor(0.5f, 0.5f, 0.5f, 0); + + while (!glfwWindowShouldClose(window)) + { + glClear(GL_COLOR_BUFFER_BIT); + + glColor3f(0.8f, 0.2f, 0.4f); + glRectf(-0.5f, -0.5f, 0.5f, 0.5f); + + glfwSwapBuffers(window); + glfwWaitEvents(); + } + + glfwTerminate(); + exit(EXIT_SUCCESS); +} + diff --git a/testbed/glfw/tests/glfwinfo.c b/testbed/glfw/tests/glfwinfo.c new file mode 100644 index 00000000..f07d7006 --- /dev/null +++ b/testbed/glfw/tests/glfwinfo.c @@ -0,0 +1,429 @@ +//======================================================================== +// Version information dumper +// Copyright (c) Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== +// +// This test is a pale imitation of glxinfo(1), except not really +// +// It dumps GLFW and OpenGL version information +// +//======================================================================== + +#include +#include + +#include +#include +#include + +#include "getopt.h" + +#ifdef _MSC_VER +#define strcasecmp(x, y) _stricmp(x, y) +#endif + +#define API_OPENGL "gl" +#define API_OPENGL_ES "es" + +#define PROFILE_NAME_CORE "core" +#define PROFILE_NAME_COMPAT "compat" + +#define STRATEGY_NAME_NONE "none" +#define STRATEGY_NAME_LOSE "lose" + +#define BEHAVIOR_NAME_NONE "none" +#define BEHAVIOR_NAME_FLUSH "flush" + +static void usage(void) +{ + printf("Usage: glfwinfo [-h] [-a API] [-m MAJOR] [-n MINOR] [-d] [-l] [-f] [-p PROFILE] [-s STRATEGY] [-b BEHAVIOR]\n"); + printf("Options:\n"); + printf(" -a the client API to use (" API_OPENGL " or " API_OPENGL_ES ")\n"); + printf(" -b the release behavior to use (" BEHAVIOR_NAME_NONE " or " BEHAVIOR_NAME_FLUSH ")\n"); + printf(" -d request a debug context\n"); + printf(" -f require a forward-compatible context\n"); + printf(" -h show this help\n"); + printf(" -l list all client API extensions after context creation\n"); + printf(" -m the major number of the required client API version\n"); + printf(" -n the minor number of the required client API version\n"); + printf(" -p the OpenGL profile to use (" PROFILE_NAME_CORE " or " PROFILE_NAME_COMPAT ")\n"); + printf(" -s the robustness strategy to use (" STRATEGY_NAME_NONE " or " STRATEGY_NAME_LOSE ")\n"); +} + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +static const char* get_client_api_name(int api) +{ + if (api == GLFW_OPENGL_API) + return "OpenGL"; + else if (api == GLFW_OPENGL_ES_API) + return "OpenGL ES"; + + return "Unknown API"; +} + +static const char* get_profile_name_gl(GLint mask) +{ + if (mask & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) + return PROFILE_NAME_COMPAT; + if (mask & GL_CONTEXT_CORE_PROFILE_BIT) + return PROFILE_NAME_CORE; + + return "unknown"; +} + +static const char* get_profile_name_glfw(int profile) +{ + if (profile == GLFW_OPENGL_COMPAT_PROFILE) + return PROFILE_NAME_COMPAT; + if (profile == GLFW_OPENGL_CORE_PROFILE) + return PROFILE_NAME_CORE; + + return "unknown"; +} + +static const char* get_strategy_name_gl(GLint strategy) +{ + if (strategy == GL_LOSE_CONTEXT_ON_RESET_ARB) + return STRATEGY_NAME_LOSE; + if (strategy == GL_NO_RESET_NOTIFICATION_ARB) + return STRATEGY_NAME_NONE; + + return "unknown"; +} + +static const char* get_strategy_name_glfw(int strategy) +{ + if (strategy == GLFW_LOSE_CONTEXT_ON_RESET) + return STRATEGY_NAME_LOSE; + if (strategy == GLFW_NO_RESET_NOTIFICATION) + return STRATEGY_NAME_NONE; + + return "unknown"; +} + +static void list_extensions(int api, int major, int minor) +{ + int i; + GLint count; + const GLubyte* extensions; + + printf("%s context supported extensions:\n", get_client_api_name(api)); + + if (api == GLFW_OPENGL_API && major > 2) + { + PFNGLGETSTRINGIPROC glGetStringi = (PFNGLGETSTRINGIPROC) glfwGetProcAddress("glGetStringi"); + if (!glGetStringi) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glGetIntegerv(GL_NUM_EXTENSIONS, &count); + + for (i = 0; i < count; i++) + puts((const char*) glGetStringi(GL_EXTENSIONS, i)); + } + else + { + extensions = glGetString(GL_EXTENSIONS); + while (*extensions != '\0') + { + if (*extensions == ' ') + putchar('\n'); + else + putchar(*extensions); + + extensions++; + } + } + + putchar('\n'); +} + +static GLboolean valid_version(void) +{ + int major, minor, revision; + + glfwGetVersion(&major, &minor, &revision); + + printf("GLFW header version: %u.%u.%u\n", + GLFW_VERSION_MAJOR, + GLFW_VERSION_MINOR, + GLFW_VERSION_REVISION); + + printf("GLFW library version: %u.%u.%u\n", major, minor, revision); + + if (major != GLFW_VERSION_MAJOR) + { + printf("*** ERROR: GLFW major version mismatch! ***\n"); + return GL_FALSE; + } + + if (minor != GLFW_VERSION_MINOR || revision != GLFW_VERSION_REVISION) + printf("*** WARNING: GLFW version mismatch! ***\n"); + + printf("GLFW library version string: \"%s\"\n", glfwGetVersionString()); + return GL_TRUE; +} + +int main(int argc, char** argv) +{ + int ch, api = 0, profile = 0, strategy = 0, behavior = 0, major = 1, minor = 0, revision; + GLboolean debug = GL_FALSE, forward = GL_FALSE, list = GL_FALSE; + GLint flags, mask; + GLFWwindow* window; + + while ((ch = getopt(argc, argv, "a:b:dfhlm:n:p:s:")) != -1) + { + switch (ch) + { + case 'a': + if (strcasecmp(optarg, API_OPENGL) == 0) + api = GLFW_OPENGL_API; + else if (strcasecmp(optarg, API_OPENGL_ES) == 0) + api = GLFW_OPENGL_ES_API; + else + { + usage(); + exit(EXIT_FAILURE); + } + break; + case 'b': + if (strcasecmp(optarg, BEHAVIOR_NAME_NONE) == 0) + behavior = GLFW_RELEASE_BEHAVIOR_NONE; + else if (strcasecmp(optarg, BEHAVIOR_NAME_FLUSH) == 0) + behavior = GLFW_RELEASE_BEHAVIOR_FLUSH; + else + { + usage(); + exit(EXIT_FAILURE); + } + break; + case 'd': + debug = GL_TRUE; + break; + case 'f': + forward = GL_TRUE; + break; + case 'h': + usage(); + exit(EXIT_SUCCESS); + case 'l': + list = GL_TRUE; + break; + case 'm': + major = atoi(optarg); + break; + case 'n': + minor = atoi(optarg); + break; + case 'p': + if (strcasecmp(optarg, PROFILE_NAME_CORE) == 0) + profile = GLFW_OPENGL_CORE_PROFILE; + else if (strcasecmp(optarg, PROFILE_NAME_COMPAT) == 0) + profile = GLFW_OPENGL_COMPAT_PROFILE; + else + { + usage(); + exit(EXIT_FAILURE); + } + break; + case 's': + if (strcasecmp(optarg, STRATEGY_NAME_NONE) == 0) + strategy = GLFW_NO_RESET_NOTIFICATION; + else if (strcasecmp(optarg, STRATEGY_NAME_LOSE) == 0) + strategy = GLFW_LOSE_CONTEXT_ON_RESET; + else + { + usage(); + exit(EXIT_FAILURE); + } + break; + default: + usage(); + exit(EXIT_FAILURE); + } + } + + // Initialize GLFW and create window + + if (!valid_version()) + exit(EXIT_FAILURE); + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + if (major != 1 || minor != 0) + { + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, major); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, minor); + } + + if (api != 0) + glfwWindowHint(GLFW_CLIENT_API, api); + + if (debug) + glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE); + + if (forward) + glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); + + if (profile != 0) + glfwWindowHint(GLFW_OPENGL_PROFILE, profile); + + if (strategy) + glfwWindowHint(GLFW_CONTEXT_ROBUSTNESS, strategy); + + if (behavior) + glfwWindowHint(GLFW_CONTEXT_RELEASE_BEHAVIOR, behavior); + + glfwWindowHint(GLFW_RED_BITS, GLFW_DONT_CARE); + glfwWindowHint(GLFW_GREEN_BITS, GLFW_DONT_CARE); + glfwWindowHint(GLFW_BLUE_BITS, GLFW_DONT_CARE); + glfwWindowHint(GLFW_ALPHA_BITS, GLFW_DONT_CARE); + glfwWindowHint(GLFW_DEPTH_BITS, GLFW_DONT_CARE); + glfwWindowHint(GLFW_STENCIL_BITS, GLFW_DONT_CARE); + glfwWindowHint(GLFW_ACCUM_RED_BITS, GLFW_DONT_CARE); + glfwWindowHint(GLFW_ACCUM_GREEN_BITS, GLFW_DONT_CARE); + glfwWindowHint(GLFW_ACCUM_BLUE_BITS, GLFW_DONT_CARE); + glfwWindowHint(GLFW_ACCUM_ALPHA_BITS, GLFW_DONT_CARE); + glfwWindowHint(GLFW_AUX_BUFFERS, GLFW_DONT_CARE); + glfwWindowHint(GLFW_SAMPLES, GLFW_DONT_CARE); + glfwWindowHint(GLFW_SRGB_CAPABLE, GLFW_DONT_CARE); + + glfwWindowHint(GLFW_VISIBLE, GL_FALSE); + + window = glfwCreateWindow(200, 200, "Version", NULL, NULL); + if (!window) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glfwMakeContextCurrent(window); + + // Report client API version + + api = glfwGetWindowAttrib(window, GLFW_CLIENT_API); + major = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MAJOR); + minor = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MINOR); + revision = glfwGetWindowAttrib(window, GLFW_CONTEXT_REVISION); + + printf("%s context version string: \"%s\"\n", + get_client_api_name(api), + glGetString(GL_VERSION)); + + printf("%s context version parsed by GLFW: %u.%u.%u\n", + get_client_api_name(api), + major, minor, revision); + + // Report client API context properties + + if (api == GLFW_OPENGL_API) + { + if (major >= 3) + { + glGetIntegerv(GL_CONTEXT_FLAGS, &flags); + printf("%s context flags (0x%08x):", get_client_api_name(api), flags); + + if (flags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT) + printf(" forward-compatible"); + if (flags & GL_CONTEXT_FLAG_DEBUG_BIT) + printf(" debug"); + if (flags & GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB) + printf(" robustness"); + putchar('\n'); + + printf("%s context flags parsed by GLFW:", get_client_api_name(api)); + + if (glfwGetWindowAttrib(window, GLFW_OPENGL_FORWARD_COMPAT)) + printf(" forward-compatible"); + if (glfwGetWindowAttrib(window, GLFW_OPENGL_DEBUG_CONTEXT)) + printf(" debug"); + if (glfwGetWindowAttrib(window, GLFW_CONTEXT_ROBUSTNESS) != GLFW_NO_ROBUSTNESS) + printf(" robustness"); + putchar('\n'); + } + + if (major > 3 || (major == 3 && minor >= 2)) + { + int profile = glfwGetWindowAttrib(window, GLFW_OPENGL_PROFILE); + + glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &mask); + printf("%s profile mask (0x%08x): %s\n", + get_client_api_name(api), + mask, + get_profile_name_gl(mask)); + + printf("%s profile mask parsed by GLFW: %s\n", + get_client_api_name(api), + get_profile_name_glfw(profile)); + } + + if (glfwExtensionSupported("GL_ARB_robustness")) + { + int robustness; + GLint strategy; + glGetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_ARB, &strategy); + + printf("%s robustness strategy (0x%08x): %s\n", + get_client_api_name(api), + strategy, + get_strategy_name_gl(strategy)); + + robustness = glfwGetWindowAttrib(window, GLFW_CONTEXT_ROBUSTNESS); + + printf("%s robustness strategy parsed by GLFW: %s\n", + get_client_api_name(api), + get_strategy_name_glfw(robustness)); + } + } + + printf("%s context renderer string: \"%s\"\n", + get_client_api_name(api), + glGetString(GL_RENDERER)); + printf("%s context vendor string: \"%s\"\n", + get_client_api_name(api), + glGetString(GL_VENDOR)); + + if (major > 1) + { + printf("%s context shading language version: \"%s\"\n", + get_client_api_name(api), + glGetString(GL_SHADING_LANGUAGE_VERSION)); + } + + // Report client API extensions + if (list) + list_extensions(api, major, minor); + + glfwTerminate(); + exit(EXIT_SUCCESS); +} + diff --git a/testbed/glfw/tests/iconify.c b/testbed/glfw/tests/iconify.c new file mode 100644 index 00000000..037b85ac --- /dev/null +++ b/testbed/glfw/tests/iconify.c @@ -0,0 +1,254 @@ +//======================================================================== +// Iconify/restore test program +// Copyright (c) Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== +// +// This program is used to test the iconify/restore functionality for +// both full screen and windowed mode windows +// +//======================================================================== + +#include + +#include +#include + +#include "getopt.h" + +static void usage(void) +{ + printf("Usage: iconify [-h] [-f [-a] [-n]]\n"); + printf("Options:\n"); + printf(" -a create windows for all monitors\n"); + printf(" -f create full screen window(s)\n"); + printf(" -h show this help\n"); + printf(" -n no automatic iconification of full screen windows\n"); +} + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + printf("%0.2f Key %s\n", + glfwGetTime(), + action == GLFW_PRESS ? "pressed" : "released"); + + if (action != GLFW_PRESS) + return; + + switch (key) + { + case GLFW_KEY_SPACE: + glfwIconifyWindow(window); + break; + case GLFW_KEY_ESCAPE: + glfwSetWindowShouldClose(window, GL_TRUE); + break; + } +} + +static void window_size_callback(GLFWwindow* window, int width, int height) +{ + printf("%0.2f Window resized to %ix%i\n", glfwGetTime(), width, height); +} + +static void framebuffer_size_callback(GLFWwindow* window, int width, int height) +{ + printf("%0.2f Framebuffer resized to %ix%i\n", glfwGetTime(), width, height); + + glViewport(0, 0, width, height); +} + +static void window_focus_callback(GLFWwindow* window, int focused) +{ + printf("%0.2f Window %s\n", + glfwGetTime(), + focused ? "focused" : "defocused"); +} + +static void window_iconify_callback(GLFWwindow* window, int iconified) +{ + printf("%0.2f Window %s\n", + glfwGetTime(), + iconified ? "iconified" : "restored"); +} + +static void window_refresh_callback(GLFWwindow* window) +{ + int width, height; + glfwGetFramebufferSize(window, &width, &height); + + glfwMakeContextCurrent(window); + + glEnable(GL_SCISSOR_TEST); + + glScissor(0, 0, width, height); + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT); + + glScissor(0, 0, 640, 480); + glClearColor(1, 1, 1, 0); + glClear(GL_COLOR_BUFFER_BIT); + + glfwSwapBuffers(window); +} + +static GLFWwindow* create_window(GLFWmonitor* monitor) +{ + int width, height; + GLFWwindow* window; + + if (monitor) + { + const GLFWvidmode* mode = glfwGetVideoMode(monitor); + + glfwWindowHint(GLFW_REFRESH_RATE, mode->refreshRate); + glfwWindowHint(GLFW_RED_BITS, mode->redBits); + glfwWindowHint(GLFW_GREEN_BITS, mode->greenBits); + glfwWindowHint(GLFW_BLUE_BITS, mode->blueBits); + + width = mode->width; + height = mode->height; + } + else + { + width = 640; + height = 480; + } + + window = glfwCreateWindow(width, height, "Iconify", monitor, NULL); + if (!window) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + return window; +} + +int main(int argc, char** argv) +{ + int ch, i, window_count; + GLboolean auto_iconify = GL_TRUE, fullscreen = GL_FALSE, all_monitors = GL_FALSE; + GLFWwindow** windows; + + while ((ch = getopt(argc, argv, "afhn")) != -1) + { + switch (ch) + { + case 'a': + all_monitors = GL_TRUE; + break; + + case 'h': + usage(); + exit(EXIT_SUCCESS); + + case 'f': + fullscreen = GL_TRUE; + break; + + case 'n': + auto_iconify = GL_FALSE; + break; + + default: + usage(); + exit(EXIT_FAILURE); + } + } + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + glfwWindowHint(GLFW_AUTO_ICONIFY, auto_iconify); + + if (fullscreen && all_monitors) + { + int monitor_count; + GLFWmonitor** monitors = glfwGetMonitors(&monitor_count); + + window_count = monitor_count; + windows = calloc(window_count, sizeof(GLFWwindow*)); + + for (i = 0; i < monitor_count; i++) + { + windows[i] = create_window(monitors[i]); + if (!windows[i]) + break; + } + } + else + { + GLFWmonitor* monitor = NULL; + + if (fullscreen) + monitor = glfwGetPrimaryMonitor(); + + window_count = 1; + windows = calloc(window_count, sizeof(GLFWwindow*)); + windows[0] = create_window(monitor); + } + + for (i = 0; i < window_count; i++) + { + glfwSetKeyCallback(windows[i], key_callback); + glfwSetFramebufferSizeCallback(windows[i], framebuffer_size_callback); + glfwSetWindowSizeCallback(windows[i], window_size_callback); + glfwSetWindowFocusCallback(windows[i], window_focus_callback); + glfwSetWindowIconifyCallback(windows[i], window_iconify_callback); + glfwSetWindowRefreshCallback(windows[i], window_refresh_callback); + + window_refresh_callback(windows[i]); + + printf("Window is %s and %s\n", + glfwGetWindowAttrib(windows[i], GLFW_ICONIFIED) ? "iconified" : "restored", + glfwGetWindowAttrib(windows[i], GLFW_FOCUSED) ? "focused" : "defocused"); + } + + for (;;) + { + glfwPollEvents(); + + for (i = 0; i < window_count; i++) + { + if (glfwWindowShouldClose(windows[i])) + break; + } + + if (i < window_count) + break; + + // Workaround for an issue with msvcrt and mintty + fflush(stdout); + } + + glfwTerminate(); + exit(EXIT_SUCCESS); +} + diff --git a/testbed/glfw/tests/joysticks.c b/testbed/glfw/tests/joysticks.c new file mode 100644 index 00000000..a3a5cd7e --- /dev/null +++ b/testbed/glfw/tests/joysticks.c @@ -0,0 +1,234 @@ +//======================================================================== +// Joystick input test +// Copyright (c) Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== +// +// This test displays the state of every button and axis of every connected +// joystick and/or gamepad +// +//======================================================================== + +#include + +#include +#include +#include + +#ifdef _MSC_VER +#define strdup(x) _strdup(x) +#endif + +typedef struct Joystick +{ + GLboolean present; + char* name; + float* axes; + unsigned char* buttons; + int axis_count; + int button_count; +} Joystick; + +static Joystick joysticks[GLFW_JOYSTICK_LAST - GLFW_JOYSTICK_1 + 1]; +static int joystick_count = 0; + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +static void framebuffer_size_callback(GLFWwindow* window, int width, int height) +{ + glViewport(0, 0, width, height); +} + +static void draw_joystick(Joystick* j, int x, int y, int width, int height) +{ + int i; + const int axis_height = 3 * height / 4; + const int button_height = height / 4; + + if (j->axis_count) + { + const int axis_width = width / j->axis_count; + + for (i = 0; i < j->axis_count; i++) + { + float value = j->axes[i] / 2.f + 0.5f; + + glColor3f(0.3f, 0.3f, 0.3f); + glRecti(x + i * axis_width, + y, + x + (i + 1) * axis_width, + y + axis_height); + + glColor3f(1.f, 1.f, 1.f); + glRecti(x + i * axis_width, + y + (int) (value * (axis_height - 5)), + x + (i + 1) * axis_width, + y + 5 + (int) (value * (axis_height - 5))); + } + } + + if (j->button_count) + { + const int button_width = width / j->button_count; + + for (i = 0; i < j->button_count; i++) + { + if (j->buttons[i]) + glColor3f(1.f, 1.f, 1.f); + else + glColor3f(0.3f, 0.3f, 0.3f); + + glRecti(x + i * button_width, + y + axis_height, + x + (i + 1) * button_width, + y + axis_height + button_height); + } + } +} + +static void draw_joysticks(GLFWwindow* window) +{ + int i, width, height; + + glfwGetFramebufferSize(window, &width, &height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0.f, width, height, 0.f, 1.f, -1.f); + glMatrixMode(GL_MODELVIEW); + + for (i = 0; i < sizeof(joysticks) / sizeof(Joystick); i++) + { + Joystick* j = joysticks + i; + + if (j->present) + { + draw_joystick(j, + 0, i * height / joystick_count, + width, height / joystick_count); + } + } +} + +static void refresh_joysticks(void) +{ + int i; + + for (i = 0; i < sizeof(joysticks) / sizeof(Joystick); i++) + { + Joystick* j = joysticks + i; + + if (glfwJoystickPresent(GLFW_JOYSTICK_1 + i)) + { + const float* axes; + const unsigned char* buttons; + int axis_count, button_count; + + free(j->name); + j->name = strdup(glfwGetJoystickName(GLFW_JOYSTICK_1 + i)); + + axes = glfwGetJoystickAxes(GLFW_JOYSTICK_1 + i, &axis_count); + if (axis_count != j->axis_count) + { + j->axis_count = axis_count; + j->axes = realloc(j->axes, j->axis_count * sizeof(float)); + } + + memcpy(j->axes, axes, axis_count * sizeof(float)); + + buttons = glfwGetJoystickButtons(GLFW_JOYSTICK_1 + i, &button_count); + if (button_count != j->button_count) + { + j->button_count = button_count; + j->buttons = realloc(j->buttons, j->button_count); + } + + memcpy(j->buttons, buttons, button_count * sizeof(unsigned char)); + + if (!j->present) + { + printf("Found joystick %i named \'%s\' with %i axes, %i buttons\n", + i + 1, j->name, j->axis_count, j->button_count); + + joystick_count++; + } + + j->present = GL_TRUE; + } + else + { + if (j->present) + { + printf("Lost joystick %i named \'%s\'\n", i + 1, j->name); + + free(j->name); + free(j->axes); + free(j->buttons); + memset(j, 0, sizeof(Joystick)); + + joystick_count--; + } + } + } +} + +int main(void) +{ + GLFWwindow* window; + + memset(joysticks, 0, sizeof(joysticks)); + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + window = glfwCreateWindow(640, 480, "Joystick Test", NULL, NULL); + if (!window) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); + + glfwMakeContextCurrent(window); + glfwSwapInterval(1); + + while (!glfwWindowShouldClose(window)) + { + glClear(GL_COLOR_BUFFER_BIT); + + refresh_joysticks(); + draw_joysticks(window); + + glfwSwapBuffers(window); + glfwPollEvents(); + } + + glfwTerminate(); + exit(EXIT_SUCCESS); +} + diff --git a/testbed/glfw/tests/modes.c b/testbed/glfw/tests/modes.c new file mode 100644 index 00000000..58067e3e --- /dev/null +++ b/testbed/glfw/tests/modes.c @@ -0,0 +1,240 @@ +//======================================================================== +// Video mode test +// Copyright (c) Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== +// +// This test enumerates or verifies video modes +// +//======================================================================== + +#include + +#include +#include +#include + +#include "getopt.h" + +enum Mode +{ + LIST_MODE, + TEST_MODE +}; + +static void usage(void) +{ + printf("Usage: modes [-t]\n"); + printf(" modes -h\n"); +} + +static const char* format_mode(const GLFWvidmode* mode) +{ + static char buffer[512]; + + sprintf(buffer, + "%i x %i x %i (%i %i %i) %i Hz", + mode->width, mode->height, + mode->redBits + mode->greenBits + mode->blueBits, + mode->redBits, mode->greenBits, mode->blueBits, + mode->refreshRate); + + buffer[sizeof(buffer) - 1] = '\0'; + return buffer; +} + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +static void framebuffer_size_callback(GLFWwindow* window, int width, int height) +{ + printf("Framebuffer resized to %ix%i\n", width, height); + + glViewport(0, 0, width, height); +} + +static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + if (key == GLFW_KEY_ESCAPE) + glfwSetWindowShouldClose(window, GL_TRUE); +} + +static void list_modes(GLFWmonitor* monitor) +{ + int count, x, y, widthMM, heightMM, dpi, i; + const GLFWvidmode* mode = glfwGetVideoMode(monitor); + const GLFWvidmode* modes = glfwGetVideoModes(monitor, &count); + + glfwGetMonitorPos(monitor, &x, &y); + glfwGetMonitorPhysicalSize(monitor, &widthMM, &heightMM); + + printf("Name: %s (%s)\n", + glfwGetMonitorName(monitor), + glfwGetPrimaryMonitor() == monitor ? "primary" : "secondary"); + printf("Current mode: %s\n", format_mode(mode)); + printf("Virtual position: %i %i\n", x, y); + + dpi = (int) ((float) mode->width * 25.4f / (float) widthMM); + printf("Physical size: %i x %i mm (%i dpi)\n", widthMM, heightMM, dpi); + + printf("Modes:\n"); + + for (i = 0; i < count; i++) + { + printf("%3u: %s", (unsigned int) i, format_mode(modes + i)); + + if (memcmp(mode, modes + i, sizeof(GLFWvidmode)) == 0) + printf(" (current mode)"); + + putchar('\n'); + } +} + +static void test_modes(GLFWmonitor* monitor) +{ + int i, count; + GLFWwindow* window; + const GLFWvidmode* modes = glfwGetVideoModes(monitor, &count); + + for (i = 0; i < count; i++) + { + const GLFWvidmode* mode = modes + i; + GLFWvidmode current; + + glfwWindowHint(GLFW_RED_BITS, mode->redBits); + glfwWindowHint(GLFW_GREEN_BITS, mode->greenBits); + glfwWindowHint(GLFW_BLUE_BITS, mode->blueBits); + glfwWindowHint(GLFW_REFRESH_RATE, mode->refreshRate); + + printf("Testing mode %u on monitor %s: %s\n", + (unsigned int) i, + glfwGetMonitorName(monitor), + format_mode(mode)); + + window = glfwCreateWindow(mode->width, mode->height, + "Video Mode Test", + glfwGetPrimaryMonitor(), + NULL); + if (!window) + { + printf("Failed to enter mode %u: %s\n", + (unsigned int) i, + format_mode(mode)); + continue; + } + + glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); + glfwSetKeyCallback(window, key_callback); + + glfwMakeContextCurrent(window); + glfwSwapInterval(1); + + glfwSetTime(0.0); + + while (glfwGetTime() < 5.0) + { + glClear(GL_COLOR_BUFFER_BIT); + glfwSwapBuffers(window); + glfwPollEvents(); + + if (glfwWindowShouldClose(window)) + { + printf("User terminated program\n"); + + glfwTerminate(); + exit(EXIT_SUCCESS); + } + } + + glGetIntegerv(GL_RED_BITS, ¤t.redBits); + glGetIntegerv(GL_GREEN_BITS, ¤t.greenBits); + glGetIntegerv(GL_BLUE_BITS, ¤t.blueBits); + + glfwGetWindowSize(window, ¤t.width, ¤t.height); + + if (current.redBits != mode->redBits || + current.greenBits != mode->greenBits || + current.blueBits != mode->blueBits) + { + printf("*** Color bit mismatch: (%i %i %i) instead of (%i %i %i)\n", + current.redBits, current.greenBits, current.blueBits, + mode->redBits, mode->greenBits, mode->blueBits); + } + + if (current.width != mode->width || current.height != mode->height) + { + printf("*** Size mismatch: %ix%i instead of %ix%i\n", + current.width, current.height, + mode->width, mode->height); + } + + printf("Closing window\n"); + + glfwDestroyWindow(window); + window = NULL; + + glfwPollEvents(); + } +} + +int main(int argc, char** argv) +{ + int ch, i, count, mode = LIST_MODE; + GLFWmonitor** monitors; + + while ((ch = getopt(argc, argv, "th")) != -1) + { + switch (ch) + { + case 'h': + usage(); + exit(EXIT_SUCCESS); + case 't': + mode = TEST_MODE; + break; + default: + usage(); + exit(EXIT_FAILURE); + } + } + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + monitors = glfwGetMonitors(&count); + + for (i = 0; i < count; i++) + { + if (mode == LIST_MODE) + list_modes(monitors[i]); + else if (mode == TEST_MODE) + test_modes(monitors[i]); + } + + glfwTerminate(); + exit(EXIT_SUCCESS); +} + diff --git a/testbed/glfw/tests/peter.c b/testbed/glfw/tests/peter.c new file mode 100644 index 00000000..723167ad --- /dev/null +++ b/testbed/glfw/tests/peter.c @@ -0,0 +1,151 @@ +//======================================================================== +// Cursor mode test +// Copyright (c) Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== +// +// This test allows you to switch between the various cursor modes +// +//======================================================================== + +#include + +#include +#include + +static GLboolean reopen = GL_FALSE; +static double cursor_x; +static double cursor_y; + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +static void cursor_position_callback(GLFWwindow* window, double x, double y) +{ + printf("%0.3f: Cursor position: %f %f (%f %f)\n", + glfwGetTime(), + x, y, x - cursor_x, y - cursor_y); + + cursor_x = x; + cursor_y = y; +} + +static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + if (action != GLFW_PRESS) + return; + + switch (key) + { + case GLFW_KEY_D: + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + printf("(( cursor is disabled ))\n"); + break; + + case GLFW_KEY_H: + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); + printf("(( cursor is hidden ))\n"); + break; + + case GLFW_KEY_N: + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); + printf("(( cursor is normal ))\n"); + break; + + case GLFW_KEY_R: + reopen = GL_TRUE; + break; + } +} + +static void framebuffer_size_callback(GLFWwindow* window, int width, int height) +{ + glViewport(0, 0, width, height); +} + +static GLFWwindow* open_window(void) +{ + GLFWwindow* window = glfwCreateWindow(640, 480, "Peter Detector", NULL, NULL); + if (!window) + return NULL; + + glfwMakeContextCurrent(window); + glfwSwapInterval(1); + + glfwGetCursorPos(window, &cursor_x, &cursor_y); + printf("Cursor position: %f %f\n", cursor_x, cursor_y); + + glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); + glfwSetCursorPosCallback(window, cursor_position_callback); + glfwSetKeyCallback(window, key_callback); + + return window; +} + +int main(void) +{ + GLFWwindow* window; + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + window = open_window(); + if (!window) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glClearColor(0.f, 0.f, 0.f, 0.f); + + while (!glfwWindowShouldClose(window)) + { + glClear(GL_COLOR_BUFFER_BIT); + + glfwSwapBuffers(window); + glfwWaitEvents(); + + if (reopen) + { + glfwDestroyWindow(window); + window = open_window(); + if (!window) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + reopen = GL_FALSE; + } + + // Workaround for an issue with msvcrt and mintty + fflush(stdout); + } + + glfwTerminate(); + exit(EXIT_SUCCESS); +} + diff --git a/testbed/glfw/tests/reopen.c b/testbed/glfw/tests/reopen.c new file mode 100644 index 00000000..7af8e8a9 --- /dev/null +++ b/testbed/glfw/tests/reopen.c @@ -0,0 +1,177 @@ +//======================================================================== +// Window re-opener (open/close stress test) +// Copyright (c) Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== +// +// This test came about as the result of bug #1262773 +// +// It closes and re-opens the GLFW window every five seconds, alternating +// between windowed and full screen mode +// +// It also times and logs opening and closing actions and attempts to separate +// user initiated window closing from its own +// +//======================================================================== + +#include + +#include +#include +#include + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +static void framebuffer_size_callback(GLFWwindow* window, int width, int height) +{ + glViewport(0, 0, width, height); +} + +static void window_close_callback(GLFWwindow* window) +{ + printf("Close callback triggered\n"); +} + +static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + if (action != GLFW_PRESS) + return; + + switch (key) + { + case GLFW_KEY_Q: + case GLFW_KEY_ESCAPE: + glfwSetWindowShouldClose(window, GL_TRUE); + break; + } +} + +static GLFWwindow* open_window(int width, int height, GLFWmonitor* monitor) +{ + double base; + GLFWwindow* window; + + base = glfwGetTime(); + + window = glfwCreateWindow(width, height, "Window Re-opener", monitor, NULL); + if (!window) + return NULL; + + glfwMakeContextCurrent(window); + glfwSwapInterval(1); + + glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); + glfwSetWindowCloseCallback(window, window_close_callback); + glfwSetKeyCallback(window, key_callback); + + if (monitor) + { + printf("Opening full screen window on monitor %s took %0.3f seconds\n", + glfwGetMonitorName(monitor), + glfwGetTime() - base); + } + else + { + printf("Opening regular window took %0.3f seconds\n", + glfwGetTime() - base); + } + + return window; +} + +static void close_window(GLFWwindow* window) +{ + double base = glfwGetTime(); + glfwDestroyWindow(window); + printf("Closing window took %0.3f seconds\n", glfwGetTime() - base); +} + +int main(int argc, char** argv) +{ + int count = 0; + GLFWwindow* window; + + srand((unsigned int) time(NULL)); + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + for (;;) + { + GLFWmonitor* monitor = NULL; + + if (count % 2 == 0) + { + int monitorCount; + GLFWmonitor** monitors = glfwGetMonitors(&monitorCount); + monitor = monitors[rand() % monitorCount]; + } + + window = open_window(640, 480, monitor); + if (!window) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glMatrixMode(GL_PROJECTION); + glOrtho(-1.f, 1.f, -1.f, 1.f, 1.f, -1.f); + glMatrixMode(GL_MODELVIEW); + + glfwSetTime(0.0); + + while (glfwGetTime() < 5.0) + { + glClear(GL_COLOR_BUFFER_BIT); + + glPushMatrix(); + glRotatef((GLfloat) glfwGetTime() * 100.f, 0.f, 0.f, 1.f); + glRectf(-0.5f, -0.5f, 1.f, 1.f); + glPopMatrix(); + + glfwSwapBuffers(window); + glfwPollEvents(); + + if (glfwWindowShouldClose(window)) + { + close_window(window); + printf("User closed window\n"); + + glfwTerminate(); + exit(EXIT_SUCCESS); + } + } + + printf("Closing window\n"); + close_window(window); + + count++; + } + + glfwTerminate(); +} + diff --git a/testbed/glfw/tests/sharing.c b/testbed/glfw/tests/sharing.c new file mode 100644 index 00000000..54b15c81 --- /dev/null +++ b/testbed/glfw/tests/sharing.c @@ -0,0 +1,184 @@ +//======================================================================== +// Context sharing test program +// Copyright (c) Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== +// +// This program is used to test sharing of objects between contexts +// +//======================================================================== + +#include + +#include +#include + +#define WIDTH 400 +#define HEIGHT 400 +#define OFFSET 50 + +static GLFWwindow* windows[2]; + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + if (action == GLFW_PRESS && key == GLFW_KEY_ESCAPE) + glfwSetWindowShouldClose(window, GL_TRUE); +} + +static GLFWwindow* open_window(const char* title, GLFWwindow* share, int posX, int posY) +{ + GLFWwindow* window; + + glfwWindowHint(GLFW_VISIBLE, GL_FALSE); + window = glfwCreateWindow(WIDTH, HEIGHT, title, NULL, share); + if (!window) + return NULL; + + glfwMakeContextCurrent(window); + glfwSwapInterval(1); + glfwSetWindowPos(window, posX, posY); + glfwShowWindow(window); + + glfwSetKeyCallback(window, key_callback); + + return window; +} + +static GLuint create_texture(void) +{ + int x, y; + char pixels[256 * 256]; + GLuint texture; + + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + + for (y = 0; y < 256; y++) + { + for (x = 0; x < 256; x++) + pixels[y * 256 + x] = rand() % 256; + } + + glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 256, 256, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, pixels); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + return texture; +} + +static void draw_quad(GLuint texture) +{ + int width, height; + glfwGetFramebufferSize(glfwGetCurrentContext(), &width, &height); + + glViewport(0, 0, width, height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0.f, 1.f, 0.f, 1.f, 0.f, 1.f); + + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, texture); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + glBegin(GL_QUADS); + + glTexCoord2f(0.f, 0.f); + glVertex2f(0.f, 0.f); + + glTexCoord2f(1.f, 0.f); + glVertex2f(1.f, 0.f); + + glTexCoord2f(1.f, 1.f); + glVertex2f(1.f, 1.f); + + glTexCoord2f(0.f, 1.f); + glVertex2f(0.f, 1.f); + + glEnd(); +} + +int main(int argc, char** argv) +{ + int x, y, width; + GLuint texture; + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + windows[0] = open_window("First", NULL, OFFSET, OFFSET); + if (!windows[0]) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + // This is the one and only time we create a texture + // It is created inside the first context, created above + // It will then be shared with the second context, created below + texture = create_texture(); + + glfwGetWindowPos(windows[0], &x, &y); + glfwGetWindowSize(windows[0], &width, NULL); + + // Put the second window to the right of the first one + windows[1] = open_window("Second", windows[0], x + width + OFFSET, y); + if (!windows[1]) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + // Set drawing color for both contexts + glfwMakeContextCurrent(windows[0]); + glColor3f(0.6f, 0.f, 0.6f); + glfwMakeContextCurrent(windows[1]); + glColor3f(0.6f, 0.6f, 0.f); + + glfwMakeContextCurrent(windows[0]); + + while (!glfwWindowShouldClose(windows[0]) && + !glfwWindowShouldClose(windows[1])) + { + glfwMakeContextCurrent(windows[0]); + draw_quad(texture); + + glfwMakeContextCurrent(windows[1]); + draw_quad(texture); + + glfwSwapBuffers(windows[0]); + glfwSwapBuffers(windows[1]); + + glfwWaitEvents(); + } + + glfwTerminate(); + exit(EXIT_SUCCESS); +} + diff --git a/testbed/glfw/tests/tearing.c b/testbed/glfw/tests/tearing.c new file mode 100644 index 00000000..94865fab --- /dev/null +++ b/testbed/glfw/tests/tearing.c @@ -0,0 +1,130 @@ +//======================================================================== +// Vsync enabling test +// Copyright (c) Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== +// +// This test renders a high contrast, horizontally moving bar, allowing for +// visual verification of whether the set swap interval is indeed obeyed +// +//======================================================================== + +#include + +#include +#include +#include + +static int swap_interval; +static double frame_rate; + +static void update_window_title(GLFWwindow* window) +{ + char title[256]; + + sprintf(title, "Tearing detector (interval %i, %0.1f Hz)", + swap_interval, frame_rate); + + glfwSetWindowTitle(window, title); +} + +static void set_swap_interval(GLFWwindow* window, int interval) +{ + swap_interval = interval; + glfwSwapInterval(swap_interval); + update_window_title(window); +} + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +static void framebuffer_size_callback(GLFWwindow* window, int width, int height) +{ + glViewport(0, 0, width, height); +} + +static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + if (key == GLFW_KEY_SPACE && action == GLFW_PRESS) + set_swap_interval(window, 1 - swap_interval); +} + +int main(void) +{ + float position; + unsigned long frame_count = 0; + double last_time, current_time; + GLFWwindow* window; + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + window = glfwCreateWindow(640, 480, "", NULL, NULL); + if (!window) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glfwMakeContextCurrent(window); + set_swap_interval(window, 0); + + last_time = glfwGetTime(); + frame_rate = 0.0; + + glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); + glfwSetKeyCallback(window, key_callback); + + glMatrixMode(GL_PROJECTION); + glOrtho(-1.f, 1.f, -1.f, 1.f, 1.f, -1.f); + glMatrixMode(GL_MODELVIEW); + + while (!glfwWindowShouldClose(window)) + { + glClear(GL_COLOR_BUFFER_BIT); + + position = cosf((float) glfwGetTime() * 4.f) * 0.75f; + glRectf(position - 0.25f, -1.f, position + 0.25f, 1.f); + + glfwSwapBuffers(window); + glfwPollEvents(); + + frame_count++; + + current_time = glfwGetTime(); + if (current_time - last_time > 1.0) + { + frame_rate = frame_count / (current_time - last_time); + frame_count = 0; + last_time = current_time; + update_window_title(window); + } + } + + glfwTerminate(); + exit(EXIT_SUCCESS); +} + diff --git a/testbed/glfw/tests/threads.c b/testbed/glfw/tests/threads.c new file mode 100644 index 00000000..0a385787 --- /dev/null +++ b/testbed/glfw/tests/threads.c @@ -0,0 +1,135 @@ +//======================================================================== +// Multi-threading test +// Copyright (c) Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== +// +// This test is intended to verify whether the OpenGL context part of +// the GLFW API is able to be used from multiple threads +// +//======================================================================== + +#include "tinycthread.h" + +#include + +#include +#include +#include + +typedef struct +{ + GLFWwindow* window; + const char* title; + float r, g, b; + thrd_t id; +} Thread; + +static volatile GLboolean running = GL_TRUE; + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +static int thread_main(void* data) +{ + const Thread* thread = data; + + glfwMakeContextCurrent(thread->window); + glfwSwapInterval(1); + + while (running) + { + const float v = (float) fabs(sin(glfwGetTime() * 2.f)); + glClearColor(thread->r * v, thread->g * v, thread->b * v, 0.f); + + glClear(GL_COLOR_BUFFER_BIT); + glfwSwapBuffers(thread->window); + } + + glfwMakeContextCurrent(NULL); + return 0; +} + +int main(void) +{ + int i, result; + Thread threads[] = + { + { NULL, "Red", 1.f, 0.f, 0.f, 0 }, + { NULL, "Green", 0.f, 1.f, 0.f, 0 }, + { NULL, "Blue", 0.f, 0.f, 1.f, 0 } + }; + const int count = sizeof(threads) / sizeof(Thread); + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + glfwWindowHint(GLFW_VISIBLE, GL_FALSE); + + for (i = 0; i < count; i++) + { + threads[i].window = glfwCreateWindow(200, 200, + threads[i].title, + NULL, NULL); + if (!threads[i].window) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glfwSetWindowPos(threads[i].window, 200 + 250 * i, 200); + glfwShowWindow(threads[i].window); + + if (thrd_create(&threads[i].id, thread_main, threads + i) != + thrd_success) + { + fprintf(stderr, "Failed to create secondary thread\n"); + + glfwTerminate(); + exit(EXIT_FAILURE); + } + } + + while (running) + { + glfwWaitEvents(); + + for (i = 0; i < count; i++) + { + if (glfwWindowShouldClose(threads[i].window)) + running = GL_FALSE; + } + } + + for (i = 0; i < count; i++) + glfwHideWindow(threads[i].window); + + for (i = 0; i < count; i++) + thrd_join(threads[i].id, &result); + + exit(EXIT_SUCCESS); +} + diff --git a/testbed/glfw/tests/title.c b/testbed/glfw/tests/title.c new file mode 100644 index 00000000..15ddb83f --- /dev/null +++ b/testbed/glfw/tests/title.c @@ -0,0 +1,76 @@ +//======================================================================== +// UTF-8 window title test +// Copyright (c) Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== +// +// This test sets a UTF-8 window title +// +//======================================================================== + +#include + +#include +#include + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +static void framebuffer_size_callback(GLFWwindow* window, int width, int height) +{ + glViewport(0, 0, width, height); +} + +int main(void) +{ + GLFWwindow* window; + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + window = glfwCreateWindow(400, 400, "English 日本語 русский язык 官話", NULL, NULL); + if (!window) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glfwMakeContextCurrent(window); + glfwSwapInterval(1); + + glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); + + while (!glfwWindowShouldClose(window)) + { + glClear(GL_COLOR_BUFFER_BIT); + glfwSwapBuffers(window); + glfwWaitEvents(); + } + + glfwTerminate(); + exit(EXIT_SUCCESS); +} + diff --git a/testbed/glfw/tests/windows.c b/testbed/glfw/tests/windows.c new file mode 100644 index 00000000..164a298f --- /dev/null +++ b/testbed/glfw/tests/windows.c @@ -0,0 +1,117 @@ +//======================================================================== +// Simple multi-window test +// Copyright (c) Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== +// +// This test creates four windows and clears each in a different color +// +//======================================================================== + +#include + +#include +#include + +static const char* titles[4] = +{ + "Foo", + "Bar", + "Baz", + "Quux" +}; + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + if (key == GLFW_KEY_SPACE && action == GLFW_PRESS) + { + int xpos, ypos; + glfwGetWindowPos(window, &xpos, &ypos); + glfwSetWindowPos(window, xpos, ypos); + } +} + +int main(void) +{ + int i; + GLboolean running = GL_TRUE; + GLFWwindow* windows[4]; + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + glfwWindowHint(GLFW_VISIBLE, GL_FALSE); + + for (i = 0; i < 4; i++) + { + int left, top, right, bottom; + + windows[i] = glfwCreateWindow(200, 200, titles[i], NULL, NULL); + if (!windows[i]) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glfwSetKeyCallback(windows[i], key_callback); + + glfwMakeContextCurrent(windows[i]); + glClearColor((GLclampf) (i & 1), + (GLclampf) (i >> 1), + i ? 0.f : 1.f, + 0.f); + + glfwGetWindowFrameSize(windows[i], &left, &top, &right, &bottom); + glfwSetWindowPos(windows[i], + 100 + (i & 1) * (200 + left + right), + 100 + (i >> 1) * (200 + top + bottom)); + } + + for (i = 0; i < 4; i++) + glfwShowWindow(windows[i]); + + while (running) + { + for (i = 0; i < 4; i++) + { + glfwMakeContextCurrent(windows[i]); + glClear(GL_COLOR_BUFFER_BIT); + glfwSwapBuffers(windows[i]); + + if (glfwWindowShouldClose(windows[i])) + running = GL_FALSE; + } + + glfwPollEvents(); + } + + glfwTerminate(); + exit(EXIT_SUCCESS); +} + diff --git a/testbed/meshes/capsule.obj b/testbed/meshes/capsule.obj new file mode 100644 index 00000000..8479fb35 --- /dev/null +++ b/testbed/meshes/capsule.obj @@ -0,0 +1,1060 @@ +# Blender v2.66 (sub 0) OBJ File: '' +v -0.195090 1.481026 0.000000 +v -0.382683 1.424120 0.000000 +v -0.555570 1.331710 0.000000 +v -0.707107 1.207348 0.000000 +v -0.831470 1.055811 0.000000 +v -0.923880 0.882924 0.000000 +v -0.980785 0.695331 0.000000 +v -1.000000 0.500241 0.000000 +v -0.191342 1.481026 -0.038060 +v -0.375330 1.424120 -0.074658 +v -0.544895 1.331710 -0.108386 +v -0.693520 1.207348 -0.137950 +v -0.815493 1.055811 -0.162212 +v -0.906127 0.882924 -0.180240 +v -0.961940 0.695331 -0.191342 +v -0.980785 0.500241 -0.195090 +v -0.180240 1.481026 -0.074658 +v -0.353553 1.424120 -0.146447 +v -0.513280 1.331710 -0.212608 +v -0.653281 1.207348 -0.270598 +v -0.768178 1.055811 -0.318190 +v -0.853553 0.882924 -0.353553 +v -0.906127 0.695331 -0.375330 +v -0.923880 0.500241 -0.382684 +v -0.162212 1.481026 -0.108387 +v -0.318190 1.424120 -0.212608 +v -0.461940 1.331710 -0.308658 +v -0.587938 1.207348 -0.392848 +v -0.691342 1.055811 -0.461940 +v -0.768178 0.882924 -0.513280 +v -0.815493 0.695331 -0.544895 +v -0.831470 0.500241 -0.555570 +v -0.137950 1.481026 -0.137950 +v -0.270598 1.424120 -0.270598 +v -0.392847 1.331710 -0.392848 +v -0.500000 1.207348 -0.500000 +v -0.587938 1.055811 -0.587938 +v -0.653281 0.882924 -0.653282 +v -0.693520 0.695331 -0.693520 +v -0.707107 0.500241 -0.707107 +v -0.108386 1.481026 -0.162212 +v -0.212607 1.424120 -0.318190 +v -0.308658 1.331710 -0.461940 +v -0.392847 1.207348 -0.587938 +v -0.461939 1.055811 -0.691342 +v -0.513280 0.882924 -0.768178 +v -0.544895 0.695331 -0.815493 +v -0.555570 0.500241 -0.831470 +v -0.074658 1.481026 -0.180240 +v -0.146446 1.424120 -0.353554 +v -0.212607 1.331710 -0.513280 +v -0.270598 1.207348 -0.653282 +v -0.318189 1.055811 -0.768178 +v -0.353553 0.882924 -0.853554 +v -0.375330 0.695331 -0.906128 +v -0.382683 0.500241 -0.923880 +v -0.038060 1.481026 -0.191342 +v -0.074658 1.424120 -0.375331 +v -0.108386 1.331710 -0.544895 +v -0.137949 1.207348 -0.693520 +v -0.162211 1.055811 -0.815493 +v -0.180240 0.882924 -0.906128 +v -0.191341 0.695331 -0.961940 +v -0.195090 0.500241 -0.980785 +v 0.000000 1.481026 -0.195091 +v 0.000000 1.424120 -0.382684 +v 0.000000 1.331710 -0.555570 +v 0.000000 1.207348 -0.707107 +v 0.000000 1.055811 -0.831470 +v 0.000000 0.882924 -0.923880 +v 0.000000 0.695331 -0.980785 +v 0.000000 0.500241 -1.000000 +v 0.038061 1.481026 -0.191342 +v 0.074658 1.424120 -0.375330 +v 0.108387 1.331710 -0.544895 +v 0.137950 1.207348 -0.693520 +v 0.162212 1.055811 -0.815493 +v 0.180240 0.882924 -0.906128 +v 0.191342 0.695331 -0.961940 +v 0.195091 0.500241 -0.980785 +v 0.074658 1.481026 -0.180240 +v 0.146447 1.424120 -0.353554 +v 0.212608 1.331710 -0.513280 +v 0.270599 1.207348 -0.653282 +v 0.318190 1.055811 -0.768178 +v 0.353554 0.882924 -0.853553 +v 0.375331 0.695331 -0.906127 +v 0.382684 0.500241 -0.923880 +v 0.108387 1.481026 -0.162212 +v 0.212608 1.424120 -0.318190 +v 0.308659 1.331710 -0.461940 +v 0.392848 1.207348 -0.587938 +v 0.461940 1.055811 -0.691342 +v 0.513280 0.882924 -0.768178 +v 0.544895 0.695331 -0.815493 +v 0.555571 0.500241 -0.831470 +v 0.137950 1.481026 -0.137950 +v 0.270599 1.424120 -0.270598 +v 0.392848 1.331710 -0.392848 +v 0.500000 1.207348 -0.500000 +v 0.587938 1.055811 -0.587938 +v 0.653282 0.882924 -0.653281 +v 0.693520 0.695331 -0.693520 +v 0.707107 0.500241 -0.707107 +v 0.162212 1.481026 -0.108386 +v 0.318190 1.424120 -0.212608 +v 0.461940 1.331710 -0.308658 +v 0.587938 1.207348 -0.392847 +v 0.691342 1.055811 -0.461940 +v 0.768178 0.882924 -0.513280 +v 0.815493 0.695331 -0.544895 +v 0.831470 0.500241 -0.555570 +v 0.180240 1.481026 -0.074658 +v 0.353554 1.424120 -0.146447 +v 0.513280 1.331710 -0.212608 +v 0.653282 1.207348 -0.270598 +v 0.768178 1.055811 -0.318190 +v 0.853554 0.882924 -0.353553 +v 0.906128 0.695331 -0.375330 +v 0.923880 0.500241 -0.382683 +v 0.191342 1.481026 -0.038060 +v 0.375331 1.424120 -0.074658 +v 0.544896 1.331710 -0.108386 +v 0.693520 1.207348 -0.137950 +v 0.815493 1.055811 -0.162212 +v 0.906128 0.882924 -0.180240 +v 0.961940 0.695331 -0.191342 +v 0.980785 0.500241 -0.195090 +v 0.195091 1.481026 0.000000 +v 0.382684 1.424120 0.000000 +v 0.555571 1.331710 0.000000 +v 0.707107 1.207348 0.000000 +v 0.831470 1.055811 0.000000 +v 0.923880 0.882924 0.000000 +v 0.980785 0.695331 0.000000 +v 1.000000 0.500241 0.000000 +v 0.191342 1.481026 0.038060 +v 0.375331 1.424120 0.074658 +v 0.544896 1.331710 0.108386 +v 0.693520 1.207348 0.137950 +v 0.815493 1.055811 0.162212 +v 0.906128 0.882924 0.180240 +v 0.961940 0.695331 0.191342 +v 0.980785 0.500241 0.195090 +v 0.180240 1.481026 0.074658 +v 0.353554 1.424120 0.146447 +v 0.513280 1.331710 0.212608 +v 0.653282 1.207348 0.270598 +v 0.768178 1.055811 0.318190 +v 0.853554 0.882924 0.353554 +v 0.906128 0.695331 0.375330 +v 0.923880 0.500241 0.382683 +v 0.162212 1.481026 0.108387 +v 0.318190 1.424120 0.212608 +v 0.461940 1.331710 0.308658 +v 0.587938 1.207348 0.392848 +v 0.691342 1.055811 0.461940 +v 0.768178 0.882924 0.513280 +v 0.815493 0.695331 0.544895 +v 0.831470 0.500241 0.555570 +v 0.137950 1.481026 0.137950 +v 0.270598 1.424120 0.270598 +v 0.392848 1.331710 0.392848 +v 0.500000 1.207348 0.500000 +v 0.587938 1.055811 0.587938 +v 0.653282 0.882924 0.653282 +v 0.693520 0.695331 0.693520 +v 0.707107 0.500241 0.707107 +v 0.108387 1.481026 0.162212 +v 0.212608 1.424120 0.318190 +v 0.308659 1.331710 0.461940 +v 0.392848 1.207348 0.587938 +v 0.461940 1.055811 0.691342 +v 0.513280 0.882924 0.768178 +v 0.544895 0.695331 0.815493 +v 0.555570 0.500241 0.831469 +v 0.074658 1.481026 0.180240 +v 0.146447 1.424120 0.353554 +v 0.212608 1.331710 0.513280 +v 0.270598 1.207348 0.653281 +v 0.318190 1.055811 0.768178 +v 0.353554 0.882924 0.853553 +v 0.375330 0.695331 0.906127 +v 0.382683 0.500241 0.923879 +v 0.038061 1.481026 0.191342 +v 0.074658 1.424120 0.375330 +v 0.108387 1.331710 0.544895 +v 0.137950 1.207348 0.693520 +v 0.162212 1.055811 0.815493 +v 0.180240 0.882924 0.906127 +v 0.191342 0.695331 0.961940 +v 0.195090 0.500241 0.980785 +v 0.000000 1.481026 0.195090 +v 0.000000 1.424120 0.382684 +v 0.000000 1.331710 0.555570 +v 0.000000 1.207348 0.707107 +v 0.000000 1.055811 0.831469 +v 0.000000 0.882924 0.923879 +v 0.000000 0.695331 0.980785 +v 0.000000 0.500241 1.000000 +v -0.038060 1.481026 0.191342 +v -0.074658 1.424120 0.375330 +v -0.108386 1.331710 0.544895 +v -0.137949 1.207348 0.693520 +v -0.162211 1.055811 0.815493 +v -0.180240 0.882924 0.906127 +v -0.191342 0.695331 0.961939 +v -0.195090 0.500241 0.980785 +v -0.074658 1.481026 0.180240 +v -0.146446 1.424120 0.353553 +v -0.212607 1.331710 0.513280 +v -0.270598 1.207348 0.653281 +v -0.318189 1.055811 0.768177 +v -0.353553 0.882924 0.853553 +v -0.375330 0.695331 0.906127 +v -0.382683 0.500241 0.923879 +v -0.108386 1.481026 0.162212 +v -0.212607 1.424120 0.318190 +v -0.308658 1.331710 0.461940 +v -0.392847 1.207348 0.587938 +v -0.461939 1.055811 0.691341 +v -0.513280 0.882924 0.768178 +v -0.544895 0.695331 0.815493 +v -0.555570 0.500241 0.831469 +v -0.137949 1.481026 0.137950 +v -0.270598 1.424120 0.270598 +v -0.392847 1.331710 0.392847 +v -0.500000 1.207348 0.500000 +v -0.587937 1.055811 0.587937 +v -0.653281 0.882924 0.653281 +v -0.693519 0.695331 0.693519 +v -0.707106 0.500241 0.707106 +v 0.000000 1.500241 0.000000 +v -0.162211 1.481026 0.108386 +v -0.318189 1.424120 0.212608 +v -0.461939 1.331710 0.308658 +v -0.587937 1.207348 0.392847 +v -0.691341 1.055811 0.461939 +v -0.768177 0.882924 0.513280 +v -0.815493 0.695331 0.544895 +v -0.831469 0.500241 0.555570 +v -0.180240 1.481026 0.074658 +v -0.353553 1.424120 0.146447 +v -0.513280 1.331710 0.212607 +v -0.653281 1.207348 0.270598 +v -0.768177 1.055811 0.318189 +v -0.853553 0.882924 0.353553 +v -0.906127 0.695331 0.375330 +v -0.923879 0.500241 0.382683 +v -0.191341 1.481026 0.038060 +v -0.375330 1.424120 0.074658 +v -0.544895 1.331710 0.108386 +v -0.693520 1.207348 0.137950 +v -0.815492 1.055811 0.162211 +v -0.906127 0.882924 0.180240 +v -0.961939 0.695331 0.191341 +v -0.980784 0.500241 0.195090 +v -1.000000 -0.503485 0.000000 +v -0.980785 -0.698576 0.000000 +v -0.923880 -0.886169 0.000000 +v -0.831470 -1.059056 0.000000 +v -0.707107 -1.210592 0.000000 +v -0.555570 -1.334955 0.000000 +v -0.382683 -1.427365 0.000000 +v -0.195090 -1.484271 0.000000 +v -0.980785 -0.503485 -0.195090 +v -0.961940 -0.698576 -0.191342 +v -0.906127 -0.886169 -0.180240 +v -0.815493 -1.059056 -0.162212 +v -0.693520 -1.210592 -0.137950 +v -0.544895 -1.334955 -0.108386 +v -0.375330 -1.427365 -0.074658 +v -0.191341 -1.484271 -0.038060 +v -0.923880 -0.503485 -0.382684 +v -0.906127 -0.698576 -0.375330 +v -0.853553 -0.886169 -0.353554 +v -0.768178 -1.059056 -0.318190 +v -0.653281 -1.210592 -0.270598 +v -0.513280 -1.334955 -0.212608 +v -0.353553 -1.427365 -0.146447 +v -0.180240 -1.484271 -0.074658 +v -0.831470 -0.503485 -0.555570 +v -0.815493 -0.698576 -0.544895 +v -0.768178 -0.886169 -0.513280 +v -0.691342 -1.059056 -0.461940 +v -0.587938 -1.210592 -0.392848 +v -0.461940 -1.334955 -0.308658 +v -0.318189 -1.427365 -0.212608 +v -0.162211 -1.484271 -0.108386 +v -0.707107 -0.503485 -0.707107 +v -0.693520 -0.698576 -0.693520 +v -0.653281 -0.886169 -0.653282 +v -0.587938 -1.059056 -0.587938 +v -0.500000 -1.210592 -0.500000 +v -0.392847 -1.334955 -0.392848 +v -0.270598 -1.427365 -0.270598 +v -0.137949 -1.484271 -0.137950 +v -0.555570 -0.503485 -0.831470 +v -0.544895 -0.698576 -0.815493 +v -0.513280 -0.886169 -0.768178 +v -0.461939 -1.059056 -0.691342 +v -0.392847 -1.210592 -0.587938 +v -0.308658 -1.334955 -0.461940 +v -0.212607 -1.427365 -0.318190 +v -0.108386 -1.484271 -0.162212 +v -0.382683 -0.503485 -0.923880 +v -0.375330 -0.698576 -0.906128 +v -0.353553 -0.886169 -0.853554 +v -0.318189 -1.059056 -0.768178 +v -0.270598 -1.210592 -0.653282 +v -0.212607 -1.334955 -0.513280 +v -0.146446 -1.427365 -0.353554 +v -0.074658 -1.484271 -0.180240 +v -0.195090 -0.503485 -0.980785 +v -0.191341 -0.698576 -0.961940 +v -0.180240 -0.886169 -0.906128 +v -0.162211 -1.059056 -0.815493 +v -0.137949 -1.210592 -0.693520 +v -0.108386 -1.334955 -0.544895 +v -0.074658 -1.427365 -0.375330 +v -0.038060 -1.484271 -0.191342 +v 0.000000 -0.503485 -1.000000 +v 0.000000 -0.698576 -0.980785 +v 0.000000 -0.886169 -0.923880 +v 0.000000 -1.059056 -0.831470 +v 0.000000 -1.210592 -0.707107 +v 0.000000 -1.334955 -0.555570 +v 0.000000 -1.427365 -0.382684 +v 0.000000 -1.484271 -0.195090 +v 0.195091 -0.503485 -0.980785 +v 0.191342 -0.698576 -0.961940 +v 0.180240 -0.886169 -0.906128 +v 0.162212 -1.059056 -0.815493 +v 0.137950 -1.210592 -0.693520 +v 0.108387 -1.334955 -0.544895 +v 0.074658 -1.427365 -0.375330 +v 0.038061 -1.484271 -0.191342 +v 0.382684 -0.503485 -0.923880 +v 0.375331 -0.698576 -0.906127 +v 0.353554 -0.886169 -0.853554 +v 0.318190 -1.059056 -0.768178 +v 0.270599 -1.210592 -0.653282 +v 0.212608 -1.334955 -0.513280 +v 0.146447 -1.427365 -0.353553 +v 0.074658 -1.484271 -0.180240 +v 0.555571 -0.503485 -0.831470 +v 0.544895 -0.698576 -0.815493 +v 0.513280 -0.886169 -0.768178 +v 0.461940 -1.059056 -0.691342 +v 0.392848 -1.210592 -0.587938 +v 0.308659 -1.334955 -0.461940 +v 0.212608 -1.427365 -0.318190 +v 0.108387 -1.484271 -0.162212 +v 0.707107 -0.503485 -0.707107 +v 0.693520 -0.698576 -0.693520 +v 0.653282 -0.886169 -0.653282 +v 0.587938 -1.059056 -0.587938 +v 0.500000 -1.210592 -0.500000 +v 0.392848 -1.334955 -0.392847 +v 0.270598 -1.427365 -0.270598 +v 0.137950 -1.484271 -0.137950 +v 0.831470 -0.503485 -0.555570 +v 0.815493 -0.698576 -0.544895 +v 0.768178 -0.886169 -0.513280 +v 0.691342 -1.059056 -0.461940 +v 0.587938 -1.210592 -0.392847 +v 0.461940 -1.334955 -0.308658 +v 0.318190 -1.427365 -0.212608 +v 0.162212 -1.484271 -0.108386 +v 0.923880 -0.503485 -0.382683 +v 0.906128 -0.698576 -0.375330 +v 0.853554 -0.886169 -0.353553 +v 0.768178 -1.059056 -0.318190 +v 0.653282 -1.210592 -0.270598 +v 0.513280 -1.334955 -0.212607 +v 0.353554 -1.427365 -0.146447 +v 0.180240 -1.484271 -0.074658 +v 0.980785 -0.503485 -0.195090 +v 0.961940 -0.698576 -0.191342 +v 0.906128 -0.886169 -0.180240 +v 0.815493 -1.059056 -0.162212 +v 0.693520 -1.210592 -0.137950 +v 0.544895 -1.334955 -0.108386 +v 0.375331 -1.427365 -0.074658 +v 0.191342 -1.484271 -0.038060 +v 1.000000 -0.503485 0.000000 +v 0.980785 -0.698576 0.000000 +v 0.923880 -0.886169 0.000000 +v 0.831470 -1.059056 0.000000 +v 0.707107 -1.210592 0.000000 +v 0.555571 -1.334955 0.000000 +v 0.382684 -1.427365 0.000000 +v 0.195091 -1.484271 0.000000 +v 0.980785 -0.503485 0.195090 +v 0.961940 -0.698576 0.191342 +v 0.906128 -0.886169 0.180240 +v 0.815493 -1.059056 0.162212 +v 0.693520 -1.210592 0.137950 +v 0.544895 -1.334955 0.108386 +v 0.375331 -1.427365 0.074658 +v 0.191342 -1.484271 0.038060 +v 0.923880 -0.503485 0.382683 +v 0.906128 -0.698576 0.375330 +v 0.853554 -0.886169 0.353553 +v 0.768178 -1.059056 0.318190 +v 0.653282 -1.210592 0.270598 +v 0.513280 -1.334955 0.212608 +v 0.353554 -1.427365 0.146447 +v 0.180240 -1.484271 0.074658 +v 0.831470 -0.503485 0.555570 +v 0.815493 -0.698576 0.544895 +v 0.768178 -0.886169 0.513280 +v 0.691342 -1.059056 0.461940 +v 0.587938 -1.210592 0.392848 +v 0.461940 -1.334955 0.308658 +v 0.318190 -1.427365 0.212608 +v 0.162212 -1.484271 0.108386 +v 0.707107 -0.503485 0.707107 +v 0.693520 -0.698576 0.693520 +v 0.653282 -0.886169 0.653282 +v 0.587938 -1.059056 0.587938 +v 0.500000 -1.210592 0.500000 +v 0.392848 -1.334955 0.392848 +v 0.270598 -1.427365 0.270598 +v 0.137950 -1.484271 0.137950 +v 0.555570 -0.503485 0.831469 +v 0.544895 -0.698576 0.815493 +v 0.513280 -0.886169 0.768178 +v 0.461940 -1.059056 0.691342 +v 0.392848 -1.210592 0.587938 +v 0.308659 -1.334955 0.461940 +v 0.212608 -1.427365 0.318190 +v 0.108387 -1.484271 0.162212 +v 0.000000 -1.503485 0.000000 +v 0.382683 -0.503485 0.923879 +v 0.375330 -0.698576 0.906127 +v 0.353554 -0.886169 0.853553 +v 0.318190 -1.059056 0.768178 +v 0.270598 -1.210592 0.653281 +v 0.212608 -1.334955 0.513280 +v 0.146447 -1.427365 0.353553 +v 0.074658 -1.484271 0.180240 +v 0.195090 -0.503485 0.980785 +v 0.191342 -0.698576 0.961940 +v 0.180240 -0.886169 0.906128 +v 0.162212 -1.059056 0.815493 +v 0.137950 -1.210592 0.693520 +v 0.108387 -1.334955 0.544895 +v 0.074658 -1.427365 0.375330 +v 0.038061 -1.484271 0.191342 +v 0.000000 -0.503485 1.000000 +v 0.000000 -0.698576 0.980785 +v 0.000000 -0.886169 0.923880 +v 0.000000 -1.059056 0.831469 +v 0.000000 -1.210592 0.707107 +v 0.000000 -1.334955 0.555570 +v 0.000000 -1.427365 0.382683 +v 0.000000 -1.484271 0.195090 +v -0.195090 -0.503485 0.980785 +v -0.191342 -0.698576 0.961939 +v -0.180240 -0.886169 0.906127 +v -0.162211 -1.059056 0.815493 +v -0.137949 -1.210592 0.693520 +v -0.108386 -1.334955 0.544895 +v -0.074658 -1.427365 0.375330 +v -0.038060 -1.484271 0.191342 +v -0.382683 -0.503485 0.923879 +v -0.375330 -0.698576 0.906127 +v -0.353553 -0.886169 0.853553 +v -0.318189 -1.059056 0.768177 +v -0.270598 -1.210592 0.653281 +v -0.212607 -1.334955 0.513280 +v -0.146446 -1.427365 0.353553 +v -0.074657 -1.484271 0.180240 +v -0.555570 -0.503485 0.831469 +v -0.544895 -0.698576 0.815493 +v -0.513280 -0.886169 0.768178 +v -0.461939 -1.059056 0.691341 +v -0.392847 -1.210592 0.587938 +v -0.308658 -1.334955 0.461940 +v -0.212607 -1.427365 0.318190 +v -0.108386 -1.484271 0.162212 +v -0.707106 -0.503485 0.707106 +v -0.693519 -0.698576 0.693519 +v -0.653281 -0.886169 0.653281 +v -0.587937 -1.059056 0.587937 +v -0.500000 -1.210592 0.500000 +v -0.392847 -1.334955 0.392847 +v -0.270598 -1.427365 0.270598 +v -0.137949 -1.484271 0.137950 +v -0.831469 -0.503485 0.555570 +v -0.815493 -0.698576 0.544895 +v -0.768178 -0.886169 0.513280 +v -0.691341 -1.059056 0.461939 +v -0.587937 -1.210592 0.392847 +v -0.461939 -1.334955 0.308658 +v -0.318189 -1.427365 0.212608 +v -0.162211 -1.484271 0.108386 +v -0.923879 -0.503485 0.382683 +v -0.906127 -0.698576 0.375330 +v -0.853553 -0.886169 0.353553 +v -0.768177 -1.059056 0.318189 +v -0.653281 -1.210592 0.270598 +v -0.513280 -1.334955 0.212607 +v -0.353553 -1.427365 0.146447 +v -0.180240 -1.484271 0.074658 +v -0.980784 -0.503485 0.195090 +v -0.961939 -0.698576 0.191341 +v -0.906127 -0.886169 0.180240 +v -0.815492 -1.059056 0.162211 +v -0.693520 -1.210592 0.137950 +v -0.544895 -1.334955 0.108386 +v -0.375330 -1.427365 0.074658 +v -0.191341 -1.484271 0.038060 +s off +f 7 6 14 15 +f 8 7 15 16 +f 2 1 9 10 +f 3 2 10 11 +f 4 3 11 12 +f 5 4 12 13 +f 6 5 13 14 +f 11 10 18 19 +f 12 11 19 20 +f 13 12 20 21 +f 14 13 21 22 +f 15 14 22 23 +f 16 15 23 24 +f 10 9 17 18 +f 23 22 30 31 +f 24 23 31 32 +f 18 17 25 26 +f 19 18 26 27 +f 20 19 27 28 +f 21 20 28 29 +f 22 21 29 30 +f 29 28 36 37 +f 30 29 37 38 +f 31 30 38 39 +f 32 31 39 40 +f 26 25 33 34 +f 27 26 34 35 +f 28 27 35 36 +f 35 34 42 43 +f 36 35 43 44 +f 37 36 44 45 +f 38 37 45 46 +f 39 38 46 47 +f 40 39 47 48 +f 34 33 41 42 +f 47 46 54 55 +f 48 47 55 56 +f 42 41 49 50 +f 43 42 50 51 +f 44 43 51 52 +f 45 44 52 53 +f 46 45 53 54 +f 53 52 60 61 +f 54 53 61 62 +f 55 54 62 63 +f 56 55 63 64 +f 50 49 57 58 +f 51 50 58 59 +f 52 51 59 60 +f 58 57 65 66 +f 59 58 66 67 +f 60 59 67 68 +f 61 60 68 69 +f 62 61 69 70 +f 63 62 70 71 +f 64 63 71 72 +f 70 69 77 78 +f 71 70 78 79 +f 72 71 79 80 +f 66 65 73 74 +f 67 66 74 75 +f 68 67 75 76 +f 69 68 76 77 +f 76 75 83 84 +f 77 76 84 85 +f 78 77 85 86 +f 79 78 86 87 +f 80 79 87 88 +f 74 73 81 82 +f 75 74 82 83 +f 88 87 95 96 +f 82 81 89 90 +f 83 82 90 91 +f 84 83 91 92 +f 85 84 92 93 +f 86 85 93 94 +f 87 86 94 95 +f 94 93 101 102 +f 95 94 102 103 +f 96 95 103 104 +f 90 89 97 98 +f 91 90 98 99 +f 92 91 99 100 +f 93 92 100 101 +f 100 99 107 108 +f 101 100 108 109 +f 102 101 109 110 +f 103 102 110 111 +f 104 103 111 112 +f 98 97 105 106 +f 99 98 106 107 +f 112 111 119 120 +f 106 105 113 114 +f 107 106 114 115 +f 108 107 115 116 +f 109 108 116 117 +f 110 109 117 118 +f 111 110 118 119 +f 118 117 125 126 +f 119 118 126 127 +f 120 119 127 128 +f 114 113 121 122 +f 115 114 122 123 +f 116 115 123 124 +f 117 116 124 125 +f 124 123 131 132 +f 125 124 132 133 +f 126 125 133 134 +f 127 126 134 135 +f 128 127 135 136 +f 122 121 129 130 +f 123 122 130 131 +f 136 135 143 144 +f 130 129 137 138 +f 131 130 138 139 +f 132 131 139 140 +f 133 132 140 141 +f 134 133 141 142 +f 135 134 142 143 +f 141 140 148 149 +f 142 141 149 150 +f 143 142 150 151 +f 144 143 151 152 +f 138 137 145 146 +f 139 138 146 147 +f 140 139 147 148 +f 147 146 154 155 +f 148 147 155 156 +f 149 148 156 157 +f 150 149 157 158 +f 151 150 158 159 +f 152 151 159 160 +f 146 145 153 154 +f 159 158 166 167 +f 160 159 167 168 +f 154 153 161 162 +f 155 154 162 163 +f 156 155 163 164 +f 157 156 164 165 +f 158 157 165 166 +f 165 164 172 173 +f 166 165 173 174 +f 167 166 174 175 +f 168 167 175 176 +f 162 161 169 170 +f 163 162 170 171 +f 164 163 171 172 +f 171 170 178 179 +f 172 171 179 180 +f 173 172 180 181 +f 174 173 181 182 +f 175 174 182 183 +f 176 175 183 184 +f 170 169 177 178 +f 183 182 190 191 +f 184 183 191 192 +f 178 177 185 186 +f 179 178 186 187 +f 180 179 187 188 +f 181 180 188 189 +f 182 181 189 190 +f 189 188 196 197 +f 190 189 197 198 +f 191 190 198 199 +f 192 191 199 200 +f 186 185 193 194 +f 187 186 194 195 +f 188 187 195 196 +f 195 194 202 203 +f 196 195 203 204 +f 197 196 204 205 +f 198 197 205 206 +f 199 198 206 207 +f 200 199 207 208 +f 194 193 201 202 +f 207 206 214 215 +f 208 207 215 216 +f 202 201 209 210 +f 203 202 210 211 +f 204 203 211 212 +f 205 204 212 213 +f 206 205 213 214 +f 212 211 219 220 +f 213 212 220 221 +f 214 213 221 222 +f 215 214 222 223 +f 216 215 223 224 +f 210 209 217 218 +f 211 210 218 219 +f 224 223 231 232 +f 218 217 225 226 +f 219 218 226 227 +f 220 219 227 228 +f 221 220 228 229 +f 222 221 229 230 +f 223 222 230 231 +f 230 229 238 239 +f 231 230 239 240 +f 232 231 240 241 +f 226 225 234 235 +f 227 226 235 236 +f 228 227 236 237 +f 229 228 237 238 +f 237 236 244 245 +f 238 237 245 246 +f 239 238 246 247 +f 240 239 247 248 +f 241 240 248 249 +f 235 234 242 243 +f 236 235 243 244 +f 249 248 256 257 +f 243 242 250 251 +f 244 243 251 252 +f 245 244 252 253 +f 246 245 253 254 +f 247 246 254 255 +f 248 247 255 256 +f 1 233 9 +f 9 233 17 +f 17 233 25 +f 25 233 33 +f 33 233 41 +f 41 233 49 +f 49 233 57 +f 57 233 65 +f 65 233 73 +f 73 233 81 +f 81 233 89 +f 89 233 97 +f 97 233 105 +f 105 233 113 +f 113 233 121 +f 121 233 129 +f 129 233 137 +f 137 233 145 +f 145 233 153 +f 153 233 161 +f 161 233 169 +f 169 233 177 +f 177 233 185 +f 185 233 193 +f 193 233 201 +f 201 233 209 +f 209 233 217 +f 217 233 225 +f 225 233 234 +f 234 233 242 +f 242 233 250 +f 255 254 5 6 +f 256 255 6 7 +f 250 233 1 +f 257 256 7 8 +f 251 250 1 2 +f 252 251 2 3 +f 253 252 3 4 +f 254 253 4 5 +f 263 262 270 271 +f 264 263 271 272 +f 265 264 272 273 +f 259 258 266 267 +f 260 259 267 268 +f 261 260 268 269 +f 262 261 269 270 +f 273 272 280 281 +f 267 266 274 275 +f 268 267 275 276 +f 269 268 276 277 +f 270 269 277 278 +f 271 270 278 279 +f 272 271 279 280 +f 279 278 286 287 +f 280 279 287 288 +f 281 280 288 289 +f 275 274 282 283 +f 276 275 283 284 +f 277 276 284 285 +f 278 277 285 286 +f 285 284 292 293 +f 286 285 293 294 +f 287 286 294 295 +f 288 287 295 296 +f 289 288 296 297 +f 283 282 290 291 +f 284 283 291 292 +f 297 296 304 305 +f 291 290 298 299 +f 292 291 299 300 +f 293 292 300 301 +f 294 293 301 302 +f 295 294 302 303 +f 296 295 303 304 +f 303 302 310 311 +f 304 303 311 312 +f 305 304 312 313 +f 299 298 306 307 +f 300 299 307 308 +f 301 300 308 309 +f 302 301 309 310 +f 309 308 316 317 +f 310 309 317 318 +f 311 310 318 319 +f 312 311 319 320 +f 313 312 320 321 +f 307 306 314 315 +f 308 307 315 316 +f 321 320 328 329 +f 315 314 322 323 +f 316 315 323 324 +f 317 316 324 325 +f 318 317 325 326 +f 319 318 326 327 +f 320 319 327 328 +f 327 326 334 335 +f 328 327 335 336 +f 329 328 336 337 +f 323 322 330 331 +f 324 323 331 332 +f 325 324 332 333 +f 326 325 333 334 +f 332 331 339 340 +f 333 332 340 341 +f 334 333 341 342 +f 335 334 342 343 +f 336 335 343 344 +f 337 336 344 345 +f 331 330 338 339 +f 344 343 351 352 +f 345 344 352 353 +f 339 338 346 347 +f 340 339 347 348 +f 341 340 348 349 +f 342 341 349 350 +f 343 342 350 351 +f 350 349 357 358 +f 351 350 358 359 +f 352 351 359 360 +f 353 352 360 361 +f 347 346 354 355 +f 348 347 355 356 +f 349 348 356 357 +f 356 355 363 364 +f 357 356 364 365 +f 358 357 365 366 +f 359 358 366 367 +f 360 359 367 368 +f 361 360 368 369 +f 355 354 362 363 +f 368 367 375 376 +f 369 368 376 377 +f 363 362 370 371 +f 364 363 371 372 +f 365 364 372 373 +f 366 365 373 374 +f 367 366 374 375 +f 374 373 381 382 +f 375 374 382 383 +f 376 375 383 384 +f 377 376 384 385 +f 371 370 378 379 +f 372 371 379 380 +f 373 372 380 381 +f 380 379 387 388 +f 381 380 388 389 +f 382 381 389 390 +f 383 382 390 391 +f 384 383 391 392 +f 385 384 392 393 +f 379 378 386 387 +f 392 391 399 400 +f 393 392 400 401 +f 387 386 394 395 +f 388 387 395 396 +f 389 388 396 397 +f 390 389 397 398 +f 391 390 398 399 +f 398 397 405 406 +f 399 398 406 407 +f 400 399 407 408 +f 401 400 408 409 +f 395 394 402 403 +f 396 395 403 404 +f 397 396 404 405 +f 403 402 410 411 +f 404 403 411 412 +f 405 404 412 413 +f 406 405 413 414 +f 407 406 414 415 +f 408 407 415 416 +f 409 408 416 417 +f 415 414 422 423 +f 416 415 423 424 +f 417 416 424 425 +f 411 410 418 419 +f 412 411 419 420 +f 413 412 420 421 +f 414 413 421 422 +f 421 420 428 429 +f 422 421 429 430 +f 423 422 430 431 +f 424 423 431 432 +f 425 424 432 433 +f 419 418 426 427 +f 420 419 427 428 +f 433 432 441 442 +f 427 426 435 436 +f 428 427 436 437 +f 429 428 437 438 +f 430 429 438 439 +f 431 430 439 440 +f 432 431 440 441 +f 440 439 447 448 +f 441 440 448 449 +f 442 441 449 450 +f 436 435 443 444 +f 437 436 444 445 +f 438 437 445 446 +f 439 438 446 447 +f 446 445 453 454 +f 447 446 454 455 +f 448 447 455 456 +f 449 448 456 457 +f 450 449 457 458 +f 444 443 451 452 +f 445 444 452 453 +f 458 457 465 466 +f 452 451 459 460 +f 453 452 460 461 +f 454 453 461 462 +f 455 454 462 463 +f 456 455 463 464 +f 457 456 464 465 +f 464 463 471 472 +f 465 464 472 473 +f 466 465 473 474 +f 460 459 467 468 +f 461 460 468 469 +f 462 461 469 470 +f 463 462 470 471 +f 470 469 477 478 +f 471 470 478 479 +f 472 471 479 480 +f 473 472 480 481 +f 474 473 481 482 +f 468 467 475 476 +f 469 468 476 477 +f 482 481 489 490 +f 476 475 483 484 +f 477 476 484 485 +f 478 477 485 486 +f 479 478 486 487 +f 480 479 487 488 +f 481 480 488 489 +f 487 486 494 495 +f 488 487 495 496 +f 489 488 496 497 +f 490 489 497 498 +f 484 483 491 492 +f 485 484 492 493 +f 486 485 493 494 +f 493 492 500 501 +f 494 493 501 502 +f 495 494 502 503 +f 496 495 503 504 +f 497 496 504 505 +f 498 497 505 506 +f 492 491 499 500 +f 505 504 512 513 +f 506 505 513 514 +f 500 499 507 508 +f 501 500 508 509 +f 502 501 509 510 +f 503 502 510 511 +f 504 503 511 512 +f 434 265 273 +f 434 273 281 +f 434 281 289 +f 434 289 297 +f 434 297 305 +f 434 305 313 +f 434 313 321 +f 434 321 329 +f 434 329 337 +f 434 337 345 +f 434 345 353 +f 434 353 361 +f 434 361 369 +f 434 369 377 +f 434 377 385 +f 434 385 393 +f 434 393 401 +f 434 401 409 +f 434 409 417 +f 434 417 425 +f 434 425 433 +f 434 433 442 +f 434 442 450 +f 434 450 458 +f 434 458 466 +f 434 466 474 +f 434 474 482 +f 434 482 490 +f 434 490 498 +f 434 498 506 +f 434 506 514 +f 511 510 261 262 +f 512 511 262 263 +f 513 512 263 264 +f 514 513 264 265 +f 508 507 258 259 +f 434 514 265 +f 509 508 259 260 +f 510 509 260 261 +f 128 378 370 120 +f 120 370 362 112 +f 136 386 378 128 +f 144 394 386 136 +f 152 402 394 144 +f 402 152 160 410 +f 168 418 410 160 +f 176 426 418 168 +f 426 176 184 435 +f 192 443 435 184 +f 200 451 443 192 +f 451 200 208 459 +f 216 467 459 208 +f 224 475 467 216 +f 232 483 475 224 +f 241 491 483 232 +f 249 499 491 241 +f 257 507 499 249 +f 8 258 507 257 +f 16 266 258 8 +f 266 16 24 274 +f 32 282 274 24 +f 40 290 282 32 +f 290 40 48 298 +f 56 306 298 48 +f 64 314 306 56 +f 314 64 72 322 +f 80 330 322 72 +f 88 338 330 80 +f 96 346 338 88 +f 104 354 346 96 +f 112 362 354 104 diff --git a/testbed/meshes/cone.obj b/testbed/meshes/cone.obj new file mode 100644 index 00000000..da12486a --- /dev/null +++ b/testbed/meshes/cone.obj @@ -0,0 +1,101 @@ +# Blender v2.66 (sub 0) OBJ File: '' +# www.blender.org +v 0.000000 -0.500000 0.000000 +v 0.000000 -0.500000 -1.000000 +v 0.195090 -0.500000 -0.980785 +v 0.382683 -0.500000 -0.923880 +v 0.555570 -0.500000 -0.831470 +v 0.707107 -0.500000 -0.707107 +v 0.831470 -0.500000 -0.555570 +v 0.923880 -0.500000 -0.382683 +v 0.980785 -0.500000 -0.195090 +v 1.000000 -0.500000 -0.000000 +v 0.000000 0.500000 0.000000 +v 0.980785 -0.500000 0.195090 +v 0.923880 -0.500000 0.382683 +v 0.831470 -0.500000 0.555570 +v 0.707107 -0.500000 0.707107 +v 0.555570 -0.500000 0.831470 +v 0.382683 -0.500000 0.923880 +v 0.195090 -0.500000 0.980785 +v -0.000000 -0.500000 1.000000 +v -0.195091 -0.500000 0.980785 +v -0.382684 -0.500000 0.923879 +v -0.555571 -0.500000 0.831469 +v -0.707107 -0.500000 0.707106 +v -0.831470 -0.500000 0.555570 +v -0.923880 -0.500000 0.382683 +v -0.980785 -0.500000 0.195089 +v -1.000000 -0.500000 -0.000001 +v -0.980785 -0.500000 -0.195091 +v -0.923879 -0.500000 -0.382684 +v -0.831469 -0.500000 -0.555571 +v -0.707106 -0.500000 -0.707108 +v -0.555569 -0.500000 -0.831470 +v -0.382682 -0.500000 -0.923880 +v -0.195089 -0.500000 -0.980786 +s off +f 1 2 3 +f 1 3 4 +f 1 4 5 +f 1 5 6 +f 1 6 7 +f 1 7 8 +f 1 8 9 +f 1 9 10 +f 1 10 12 +f 1 12 13 +f 1 13 14 +f 1 14 15 +f 1 15 16 +f 1 16 17 +f 1 17 18 +f 1 18 19 +f 1 19 20 +f 1 20 21 +f 1 21 22 +f 1 22 23 +f 1 23 24 +f 1 24 25 +f 1 25 26 +f 1 26 27 +f 1 27 28 +f 1 28 29 +f 1 29 30 +f 1 30 31 +f 1 31 32 +f 1 32 33 +f 1 33 34 +f 1 34 2 +f 2 11 3 +f 3 11 4 +f 4 11 5 +f 5 11 6 +f 6 11 7 +f 7 11 8 +f 8 11 9 +f 9 11 10 +f 10 11 12 +f 12 11 13 +f 13 11 14 +f 14 11 15 +f 15 11 16 +f 16 11 17 +f 17 11 18 +f 18 11 19 +f 19 11 20 +f 20 11 21 +f 21 11 22 +f 22 11 23 +f 23 11 24 +f 24 11 25 +f 25 11 26 +f 26 11 27 +f 27 11 28 +f 28 11 29 +f 29 11 30 +f 30 11 31 +f 31 11 32 +f 32 11 33 +f 33 11 34 +f 34 11 2 diff --git a/testbed/meshes/convexmesh.obj b/testbed/meshes/convexmesh.obj new file mode 100644 index 00000000..7a194f13 --- /dev/null +++ b/testbed/meshes/convexmesh.obj @@ -0,0 +1,125 @@ +# Blender v2.66 (sub 0) OBJ File: '' +# www.blender.org +v 0.000000 -1.000000 0.000000 +v 0.723607 -0.447220 0.525725 +v -0.276388 -0.447220 0.850649 +v -0.894426 -0.447216 0.000000 +v -0.276388 -0.447220 -0.850649 +v 0.723607 -0.447220 -0.525725 +v 0.276388 0.447220 0.850649 +v -0.723607 0.447220 0.525725 +v -0.723607 0.447220 -0.525725 +v 0.276388 0.447220 -0.850649 +v 0.894426 0.447216 0.000000 +v 0.000000 1.000000 0.000000 +v 0.425323 -0.850654 0.309011 +v 0.262869 -0.525738 0.809012 +v -0.162456 -0.850654 0.499995 +v 0.425323 -0.850654 -0.309011 +v 0.850648 -0.525736 0.000000 +v -0.688189 -0.525736 0.499997 +v -0.525730 -0.850652 0.000000 +v -0.688189 -0.525736 -0.499997 +v -0.162456 -0.850654 -0.499995 +v 0.262869 -0.525738 -0.809012 +v 0.951058 0.000000 -0.309013 +v 0.951058 0.000000 0.309013 +v 0.587786 0.000000 0.809017 +v 0.000000 0.000000 1.000000 +v -0.587786 0.000000 0.809017 +v -0.951058 0.000000 0.309013 +v -0.951058 0.000000 -0.309013 +v -0.587786 0.000000 -0.809017 +v 0.000000 0.000000 -1.000000 +v 0.587786 0.000000 -0.809017 +v 0.688189 0.525736 0.499997 +v -0.262869 0.525738 0.809012 +v -0.850648 0.525736 0.000000 +v -0.262869 0.525738 -0.809012 +v 0.688189 0.525736 -0.499997 +v 0.525730 0.850652 0.000000 +v 0.162456 0.850654 0.499995 +v -0.425323 0.850654 0.309011 +v -0.425323 0.850654 -0.309011 +v 0.162456 0.850654 -0.499995 +s off +f 1 13 15 +f 2 13 17 +f 1 15 19 +f 1 19 21 +f 1 21 16 +f 2 17 24 +f 3 14 26 +f 4 18 28 +f 5 20 30 +f 6 22 32 +f 2 24 25 +f 3 26 27 +f 4 28 29 +f 5 30 31 +f 6 32 23 +f 7 33 39 +f 8 34 40 +f 9 35 41 +f 10 36 42 +f 11 37 38 +f 15 14 3 +f 15 13 14 +f 13 2 14 +f 17 16 6 +f 17 13 16 +f 13 1 16 +f 19 18 4 +f 19 15 18 +f 15 3 18 +f 21 20 5 +f 21 19 20 +f 19 4 20 +f 16 22 6 +f 16 21 22 +f 21 5 22 +f 24 23 11 +f 24 17 23 +f 17 6 23 +f 26 25 7 +f 26 14 25 +f 14 2 25 +f 28 27 8 +f 28 18 27 +f 18 3 27 +f 30 29 9 +f 30 20 29 +f 20 4 29 +f 32 31 10 +f 32 22 31 +f 22 5 31 +f 25 33 7 +f 25 24 33 +f 24 11 33 +f 27 34 8 +f 27 26 34 +f 26 7 34 +f 29 35 9 +f 29 28 35 +f 28 8 35 +f 31 36 10 +f 31 30 36 +f 30 9 36 +f 23 37 11 +f 23 32 37 +f 32 10 37 +f 39 38 12 +f 39 33 38 +f 33 11 38 +f 40 39 12 +f 40 34 39 +f 34 7 39 +f 41 40 12 +f 41 35 40 +f 35 8 40 +f 42 41 12 +f 42 36 41 +f 36 9 41 +f 38 42 12 +f 38 37 42 +f 37 10 42 diff --git a/testbed/meshes/cylinder.obj b/testbed/meshes/cylinder.obj new file mode 100644 index 00000000..4fb9c374 --- /dev/null +++ b/testbed/meshes/cylinder.obj @@ -0,0 +1,293 @@ +# Blender v2.66 (sub 0) OBJ File: '' +# www.blender.org +v 0.000000 -0.500000 0.000000 +v 0.000000 0.500000 0.000000 +v 0.000000 -0.500000 -1.000000 +v 0.000000 0.500000 -1.000000 +v 0.195090 -0.500000 -0.980785 +v 0.195090 0.500000 -0.980785 +v 0.382683 -0.500000 -0.923880 +v 0.382683 0.500000 -0.923880 +v 0.555570 -0.500000 -0.831470 +v 0.555570 0.500000 -0.831470 +v 0.707107 -0.500000 -0.707107 +v 0.707107 0.500000 -0.707107 +v 0.831470 -0.500000 -0.555570 +v 0.831470 0.500000 -0.555570 +v 0.923880 -0.500000 -0.382683 +v 0.923880 0.500000 -0.382683 +v 0.980785 -0.500000 -0.195090 +v 0.980785 0.500000 -0.195090 +v 1.000000 -0.500000 -0.000000 +v 1.000000 0.500000 -0.000000 +v 0.980785 -0.500000 0.195090 +v 0.980785 0.500000 0.195090 +v 0.923880 -0.500000 0.382683 +v 0.923880 0.500000 0.382683 +v 0.831470 -0.500000 0.555570 +v 0.831470 0.500000 0.555570 +v 0.707107 -0.500000 0.707107 +v 0.707107 0.500000 0.707107 +v 0.555570 -0.500000 0.831470 +v 0.555570 0.500000 0.831470 +v 0.382683 -0.500000 0.923880 +v 0.382683 0.500000 0.923880 +v 0.195090 -0.500000 0.980785 +v 0.195090 0.500000 0.980785 +v -0.000000 -0.500000 1.000000 +v -0.000000 0.500000 1.000000 +v -0.195091 -0.500000 0.980785 +v -0.195091 0.500000 0.980785 +v -0.382684 -0.500000 0.923879 +v -0.382684 0.500000 0.923879 +v -0.555571 -0.500000 0.831469 +v -0.555571 0.500000 0.831469 +v -0.707107 -0.500000 0.707106 +v -0.707107 0.500000 0.707106 +v -0.831470 -0.500000 0.555570 +v -0.831470 0.500000 0.555570 +v -0.923880 -0.500000 0.382683 +v -0.923880 0.500000 0.382683 +v -0.980785 -0.500000 0.195089 +v -0.980785 0.500000 0.195089 +v -1.000000 -0.500000 -0.000001 +v -1.000000 0.500000 -0.000001 +v -0.980785 -0.500000 -0.195091 +v -0.980785 0.500000 -0.195091 +v -0.923879 -0.500000 -0.382684 +v -0.923879 0.500000 -0.382684 +v -0.831469 -0.500000 -0.555571 +v -0.831469 0.500000 -0.555571 +v -0.707106 -0.500000 -0.707108 +v -0.707106 0.500000 -0.707108 +v -0.555569 -0.500000 -0.831470 +v -0.555569 0.500000 -0.831470 +v -0.382682 -0.500000 -0.923880 +v -0.382682 0.500000 -0.923880 +v -0.195089 -0.500000 -0.980786 +v -0.195089 0.500000 -0.980786 +v 0.000000 0.000000 -1.000000 +v 0.195090 0.000000 -0.980785 +v 0.382683 0.000000 -0.923880 +v 0.555570 0.000000 -0.831470 +v 0.707107 0.000000 -0.707107 +v 0.831470 0.000000 -0.555570 +v 0.923880 0.000000 -0.382683 +v 0.980785 0.000000 -0.195090 +v 1.000000 0.000000 -0.000000 +v 0.980785 0.000000 0.195090 +v 0.923880 0.000000 0.382683 +v 0.831470 0.000000 0.555570 +v 0.707107 0.000000 0.707107 +v 0.555570 0.000000 0.831470 +v 0.382683 0.000000 0.923880 +v 0.195090 0.000000 0.980785 +v -0.000000 0.000000 1.000000 +v -0.195091 0.000000 0.980785 +v -0.382684 0.000000 0.923879 +v -0.555571 0.000000 0.831469 +v -0.707107 0.000000 0.707106 +v -0.831470 0.000000 0.555570 +v -0.923880 0.000000 0.382683 +v -0.980785 0.000000 0.195089 +v -1.000000 0.000000 -0.000001 +v -0.980785 0.000000 -0.195091 +v -0.923879 0.000000 -0.382684 +v -0.831469 0.000000 -0.555571 +v -0.707106 0.000000 -0.707108 +v -0.555569 0.000000 -0.831470 +v -0.382682 0.000000 -0.923880 +v -0.195089 0.000000 -0.980786 +s off +f 1 3 5 +f 2 6 4 +f 67 4 6 +f 1 5 7 +f 2 8 6 +f 68 6 8 +f 1 7 9 +f 2 10 8 +f 69 8 10 +f 1 9 11 +f 2 12 10 +f 70 10 12 +f 1 11 13 +f 2 14 12 +f 71 12 14 +f 1 13 15 +f 2 16 14 +f 72 14 16 +f 1 15 17 +f 2 18 16 +f 73 16 18 +f 1 17 19 +f 2 20 18 +f 74 18 20 +f 1 19 21 +f 2 22 20 +f 75 20 22 +f 1 21 23 +f 2 24 22 +f 76 22 24 +f 1 23 25 +f 2 26 24 +f 77 24 26 +f 1 25 27 +f 2 28 26 +f 78 26 28 +f 1 27 29 +f 2 30 28 +f 79 28 30 +f 1 29 31 +f 2 32 30 +f 80 30 32 +f 1 31 33 +f 2 34 32 +f 81 32 34 +f 1 33 35 +f 2 36 34 +f 82 34 36 +f 1 35 37 +f 2 38 36 +f 83 36 38 +f 1 37 39 +f 2 40 38 +f 84 38 40 +f 1 39 41 +f 2 42 40 +f 85 40 42 +f 1 41 43 +f 2 44 42 +f 86 42 44 +f 1 43 45 +f 2 46 44 +f 87 44 46 +f 1 45 47 +f 2 48 46 +f 88 46 48 +f 1 47 49 +f 2 50 48 +f 89 48 50 +f 1 49 51 +f 2 52 50 +f 90 50 52 +f 1 51 53 +f 2 54 52 +f 91 52 54 +f 1 53 55 +f 2 56 54 +f 92 54 56 +f 1 55 57 +f 2 58 56 +f 93 56 58 +f 1 57 59 +f 2 60 58 +f 94 58 60 +f 1 59 61 +f 2 62 60 +f 95 60 62 +f 1 61 63 +f 2 64 62 +f 96 62 64 +f 1 63 65 +f 2 66 64 +f 97 64 66 +f 1 65 3 +f 2 4 66 +f 98 66 4 +f 3 67 68 +f 5 68 69 +f 7 69 70 +f 9 70 71 +f 11 71 72 +f 13 72 73 +f 15 73 74 +f 17 74 75 +f 19 75 76 +f 21 76 77 +f 23 77 78 +f 25 78 79 +f 27 79 80 +f 29 80 81 +f 31 81 82 +f 33 82 83 +f 35 83 84 +f 37 84 85 +f 39 85 86 +f 41 86 87 +f 43 87 88 +f 45 88 89 +f 47 89 90 +f 49 90 91 +f 51 91 92 +f 53 92 93 +f 55 93 94 +f 57 94 95 +f 59 95 96 +f 61 96 97 +f 63 97 98 +f 65 98 67 +f 86 85 42 +f 87 86 44 +f 88 87 46 +f 43 41 87 +f 45 43 88 +f 80 79 30 +f 81 80 32 +f 82 81 34 +f 83 82 36 +f 84 83 38 +f 85 84 40 +f 29 27 80 +f 31 29 81 +f 33 31 82 +f 35 33 83 +f 37 35 84 +f 39 37 85 +f 41 39 86 +f 68 67 6 +f 69 68 8 +f 70 69 10 +f 71 70 12 +f 72 71 14 +f 73 72 16 +f 74 73 18 +f 75 74 20 +f 76 75 22 +f 77 76 24 +f 78 77 26 +f 79 78 28 +f 89 88 48 +f 90 89 50 +f 91 90 52 +f 92 91 54 +f 93 92 56 +f 94 93 58 +f 95 94 60 +f 96 95 62 +f 97 96 64 +f 98 97 66 +f 67 98 4 +f 5 3 68 +f 7 5 69 +f 9 7 70 +f 11 9 71 +f 13 11 72 +f 15 13 73 +f 17 15 74 +f 19 17 75 +f 21 19 76 +f 23 21 77 +f 25 23 78 +f 27 25 79 +f 47 45 89 +f 49 47 90 +f 51 49 91 +f 53 51 92 +f 55 53 93 +f 57 55 94 +f 59 57 95 +f 61 59 96 +f 63 61 97 +f 65 63 98 +f 3 65 67 diff --git a/testbed/meshes/dumbbell.obj b/testbed/meshes/dumbbell.obj new file mode 100644 index 00000000..43099a93 --- /dev/null +++ b/testbed/meshes/dumbbell.obj @@ -0,0 +1,1396 @@ +#### +# +# OBJ File Generated by Meshlab +# +#### +# Object dumbbell.obj +# +# Vertices: 464 +# Faces: 916 +# +#### +v -0.429342 4.000000 1.439240 +v -0.823902 4.000000 1.261880 +v -1.151714 4.000000 0.982291 +v -1.386221 4.000000 0.623122 +v -1.508424 4.000000 0.213472 +v -1.508424 4.000000 -0.213472 +v -1.386221 4.000000 -0.623123 +v -1.151714 4.000000 -0.982291 +v -0.823902 4.000000 -1.261880 +v -0.429342 4.000000 -1.439240 +v -0.410268 4.126197 1.439240 +v -0.787298 4.242170 1.261880 +v -1.100546 4.338524 0.982291 +v -1.324635 4.407454 0.623122 +v -1.441409 4.443373 0.213472 +v -1.441409 4.443373 -0.213472 +v -1.324635 4.407454 -0.623123 +v -1.100546 4.338524 -0.982291 +v -0.787298 4.242170 -1.261880 +v -0.410268 4.126197 -1.439240 +v -0.354739 4.241181 1.439240 +v -0.680740 4.462823 1.261880 +v -0.951591 4.646970 0.982291 +v -1.145349 4.778703 0.623122 +v -1.246319 4.847349 0.213472 +v -1.246319 4.847349 -0.213472 +v -1.145349 4.778703 -0.623123 +v -0.951590 4.646970 -0.982291 +v -0.680740 4.462823 -1.261880 +v -0.354739 4.241181 -1.439240 +v -0.267691 4.334735 1.439240 +v -0.513694 4.642351 1.261880 +v -0.718082 4.897928 0.982291 +v -0.864294 5.080761 0.623122 +v -0.940487 5.176036 0.213472 +v -0.940487 5.176036 -0.213472 +v -0.864295 5.080761 -0.623123 +v -0.718082 4.897928 -0.982291 +v -0.513694 4.642351 -1.261880 +v -0.267691 4.334735 -1.439240 +v -0.156856 4.398545 1.439240 +v -0.301005 4.764804 1.261880 +v -0.420768 5.069102 0.982291 +v -0.506443 5.286788 0.623122 +v -0.551089 5.400227 0.213472 +v -0.551089 5.400227 -0.213472 +v -0.506443 5.286788 -0.623123 +v -0.420768 5.069102 -0.982291 +v -0.301005 4.764804 -1.261880 +v -0.156856 4.398545 -1.439240 +v -0.032085 4.426945 1.439240 +v -0.061570 4.819301 1.261880 +v -0.086068 5.145282 0.982291 +v -0.103592 5.378479 0.623122 +v -0.112725 5.500000 0.213472 +v -0.112725 5.500000 -0.213472 +v -0.103593 5.378479 -0.623123 +v -0.086068 5.145282 -0.982291 +v -0.061570 4.819301 -1.261880 +v -0.032085 4.426945 -1.439240 +v 0.095537 4.417407 1.439240 +v 0.183335 4.800999 1.261880 +v 0.256280 5.119698 0.982291 +v 0.308463 5.347686 0.623122 +v 0.335656 5.466493 0.213472 +v 0.335656 5.466493 -0.213472 +v 0.308463 5.347686 -0.623123 +v 0.256280 5.119698 -0.982291 +v 0.183335 4.800999 -1.261880 +v 0.095537 4.417407 -1.439240 +v 0.214671 4.370781 1.439240 +v 0.411951 4.711524 1.261880 +v 0.575857 4.994623 0.982291 +v 0.693110 5.197145 0.623122 +v 0.754212 5.302681 0.213472 +v 0.754212 5.302681 -0.213472 +v 0.693110 5.197145 -0.623123 +v 0.575857 4.994623 -0.982291 +v 0.411951 4.711524 -1.261880 +v 0.214671 4.370781 -1.439240 +v 0.000000 4.000000 1.500000 +v 0.314730 4.291210 1.439240 +v 0.603963 4.558828 1.261880 +v 0.844266 4.781174 0.982291 +v 1.016171 4.940232 0.623122 +v 1.105753 5.023119 0.213472 +v 1.105753 5.023119 -0.213472 +v 1.016171 4.940232 -0.623123 +v 0.844265 4.781174 -0.982291 +v 0.603963 4.558828 -1.261880 +v 0.314730 4.291210 -1.439240 +v 0.000000 4.000000 -1.500000 +v 0.386824 4.185763 1.439240 +v 0.742310 4.356478 1.261880 +v 1.037658 4.498313 0.982291 +v 1.248941 4.599776 0.623122 +v 1.359043 4.652650 0.213472 +v 1.359043 4.652650 -0.213472 +v 1.248941 4.599776 -0.623123 +v 1.037657 4.498311 -0.982291 +v 0.742310 4.356478 -1.261880 +v 0.386824 4.185763 -1.439240 +v 0.424547 4.063811 1.439240 +v 0.814699 4.122453 1.261880 +v 1.138849 4.171173 0.982291 +v 1.370737 4.206027 0.623122 +v 1.491576 4.224190 0.213472 +v 1.491576 4.224190 -0.213472 +v 1.370737 4.206027 -0.623123 +v 1.138849 4.171173 -0.982291 +v 0.814699 4.122453 -1.261880 +v 0.424547 4.063811 -1.439240 +v 0.424546 3.936189 1.439240 +v 0.814699 3.877547 1.261880 +v 1.138849 3.828825 0.982291 +v 1.370737 3.793972 0.623122 +v 1.491575 3.775809 0.213472 +v 1.491575 3.775809 -0.213472 +v 1.370737 3.793972 -0.623123 +v 1.138849 3.828825 -0.982291 +v 0.814699 3.877547 -1.261880 +v 0.424547 3.936189 -1.439240 +v 0.386824 3.814236 1.439240 +v 0.742309 3.643522 1.261880 +v 1.037657 3.501688 0.982291 +v 1.248941 3.400223 0.623122 +v 1.359042 3.347349 0.213472 +v 1.359042 3.347349 -0.213472 +v 1.248941 3.400223 -0.623123 +v 1.037657 3.501688 -0.982291 +v 0.742309 3.643522 -1.261880 +v 0.386824 3.814236 -1.439240 +v 0.314730 3.708790 1.439240 +v 0.603962 3.441171 1.261880 +v 0.844265 3.218826 0.982291 +v 1.016171 3.059767 0.623122 +v 1.105752 2.976880 0.213472 +v 1.105752 2.976880 -0.213472 +v 1.016171 3.059767 -0.623123 +v 0.844265 3.218826 -0.982291 +v 0.603962 3.441171 -1.261880 +v 0.314730 3.708790 -1.439240 +v 0.214671 3.629218 1.439240 +v 0.411950 3.288475 1.261880 +v 0.575856 3.005375 0.982291 +v 0.693109 2.802855 0.623122 +v 0.754211 2.697319 0.213472 +v 0.754211 2.697319 -0.213472 +v 0.693109 2.802855 -0.623123 +v 0.575856 3.005376 -0.982291 +v 0.411950 3.288475 -1.261880 +v 0.214671 3.629218 -1.439240 +v 0.095537 3.582592 1.439240 +v 0.183335 3.199001 1.261880 +v 0.256280 2.880302 0.982291 +v 0.308462 2.652314 0.623122 +v 0.335655 2.533507 0.213472 +v 0.335655 2.533507 -0.213472 +v 0.308462 2.652314 -0.623123 +v 0.256280 2.880302 -0.982291 +v 0.183335 3.199001 -1.261880 +v 0.095537 3.582592 -1.439240 +v -0.032085 3.573055 1.439240 +v -0.061571 3.180699 1.261880 +v -0.086068 2.854718 0.982291 +v -0.103593 2.621521 0.623122 +v -0.112726 2.500000 0.213472 +v -0.112726 2.500000 -0.213472 +v -0.103593 2.621521 -0.623123 +v -0.086068 2.854718 -0.982291 +v -0.061571 3.180699 -1.261880 +v -0.032085 3.573055 -1.439240 +v -0.156857 3.601454 1.439240 +v -0.301005 3.235196 1.261880 +v -0.420769 2.930898 0.982291 +v -0.506444 2.713212 0.623122 +v -0.551090 2.599774 0.213472 +v -0.551090 2.599774 -0.213472 +v -0.506444 2.713212 -0.623123 +v -0.420769 2.930898 -0.982291 +v -0.301005 3.235196 -1.261880 +v -0.156857 3.601454 -1.439240 +v -0.267691 3.665266 1.439240 +v -0.513695 3.357649 1.261880 +v -0.718082 3.102072 0.982291 +v -0.864295 2.919240 0.623122 +v -0.940488 2.823965 0.213472 +v -0.940488 2.823965 -0.213472 +v -0.864295 2.919240 -0.623123 +v -0.718082 3.102072 -0.982291 +v -0.513695 3.357649 -1.261880 +v -0.267691 3.665266 -1.439240 +v -0.354739 3.758819 1.439240 +v -0.680740 3.537178 1.261880 +v -0.951591 3.353031 0.982291 +v -1.145349 3.221298 0.623122 +v -1.246319 3.152651 0.213472 +v -1.246319 3.152651 -0.213472 +v -1.145349 3.221298 -0.623123 +v -0.951591 3.353031 -0.982291 +v -0.680740 3.537178 -1.261880 +v -0.354739 3.758819 -1.439240 +v -0.410268 3.873803 1.439240 +v -0.787298 3.757830 1.261880 +v -1.100546 3.661476 0.982291 +v -1.324635 3.592547 0.623122 +v -1.441409 3.556628 0.213472 +v -1.441409 3.556628 -0.213472 +v -1.324635 3.592547 -0.623123 +v -1.100546 3.661476 -0.982291 +v -0.787298 3.757830 -1.261880 +v -0.410268 3.873803 -1.439240 +v -0.039595 2.492897 0.497466 +v -0.039595 -2.507103 0.497462 +v 0.114914 2.492897 0.472994 +v 0.114914 -2.507103 0.472991 +v 0.254298 2.492897 0.401974 +v 0.254298 -2.507103 0.401971 +v 0.364914 2.492897 0.291358 +v 0.364914 -2.507103 0.291355 +v 0.435934 2.492897 0.151974 +v 0.435934 -2.507103 0.151971 +v 0.460405 2.492897 -0.002534 +v 0.460405 -2.507103 -0.002538 +v 0.435934 2.492897 -0.157043 +v 0.435934 -2.507103 -0.157046 +v 0.364914 2.492897 -0.296427 +v 0.364914 -2.507103 -0.296430 +v 0.254298 2.492897 -0.407043 +v 0.254298 -2.507103 -0.407046 +v 0.114914 2.492897 -0.478063 +v 0.114914 -2.507103 -0.478066 +v -0.039595 2.492897 -0.502534 +v -0.039595 -2.507103 -0.502538 +v -0.194103 2.492897 -0.478063 +v -0.194103 -2.507103 -0.478066 +v -0.333487 2.492897 -0.407043 +v -0.333487 -2.507103 -0.407046 +v -0.444103 2.492897 -0.296427 +v -0.444103 -2.507103 -0.296430 +v -0.515123 2.492897 -0.157042 +v -0.515123 -2.507103 -0.157046 +v -0.539595 2.492897 -0.002534 +v -0.539595 -2.507103 -0.002537 +v -0.515123 2.492897 0.151975 +v -0.515123 -2.507103 0.151971 +v -0.444103 2.492897 0.291359 +v -0.444103 -2.507103 0.291356 +v -0.333487 2.492897 0.401975 +v -0.333487 -2.507103 0.401971 +v -0.194102 2.492897 0.472994 +v -0.194102 -2.507103 0.472991 +v -0.429342 -4.000000 1.439240 +v -0.823902 -4.000000 1.261880 +v -1.151714 -4.000000 0.982291 +v -1.386221 -4.000000 0.623122 +v -1.508424 -4.000000 0.213472 +v -1.508424 -4.000000 -0.213472 +v -1.386221 -4.000000 -0.623123 +v -1.151714 -4.000000 -0.982291 +v -0.823902 -4.000000 -1.261880 +v -0.429342 -4.000000 -1.439240 +v -0.410268 -3.873803 1.439240 +v -0.787298 -3.757830 1.261880 +v -1.100546 -3.661476 0.982291 +v -1.324635 -3.592547 0.623122 +v -1.441409 -3.556627 0.213472 +v -1.441409 -3.556627 -0.213472 +v -1.324635 -3.592547 -0.623123 +v -1.100546 -3.661476 -0.982291 +v -0.787298 -3.757830 -1.261880 +v -0.410268 -3.873803 -1.439240 +v -0.354739 -3.758819 1.439240 +v -0.680740 -3.537177 1.261880 +v -0.951591 -3.353031 0.982291 +v -1.145349 -3.221298 0.623122 +v -1.246319 -3.152650 0.213472 +v -1.246319 -3.152650 -0.213472 +v -1.145349 -3.221298 -0.623123 +v -0.951590 -3.353031 -0.982291 +v -0.680740 -3.537177 -1.261880 +v -0.354739 -3.758819 -1.439240 +v -0.267691 -3.665265 1.439240 +v -0.513694 -3.357649 1.261880 +v -0.718082 -3.102072 0.982291 +v -0.864294 -2.919240 0.623122 +v -0.940487 -2.823964 0.213472 +v -0.940487 -2.823964 -0.213472 +v -0.864295 -2.919240 -0.623123 +v -0.718082 -3.102072 -0.982291 +v -0.513694 -3.357649 -1.261880 +v -0.267691 -3.665265 -1.439240 +v -0.156856 -3.601454 1.439240 +v -0.301005 -3.235196 1.261880 +v -0.420768 -2.930898 0.982291 +v -0.506443 -2.713212 0.623122 +v -0.551089 -2.599774 0.213472 +v -0.551089 -2.599774 -0.213472 +v -0.506443 -2.713212 -0.623123 +v -0.420768 -2.930898 -0.982291 +v -0.301005 -3.235196 -1.261880 +v -0.156856 -3.601454 -1.439240 +v -0.032085 -3.573056 1.439240 +v -0.061570 -3.180699 1.261880 +v -0.086068 -2.854718 0.982291 +v -0.103592 -2.621521 0.623122 +v -0.112725 -2.500000 0.213472 +v -0.112725 -2.500000 -0.213472 +v -0.103593 -2.621521 -0.623123 +v -0.086068 -2.854718 -0.982291 +v -0.061570 -3.180699 -1.261880 +v -0.032085 -3.573056 -1.439240 +v 0.095537 -3.582593 1.439240 +v 0.183335 -3.199001 1.261880 +v 0.256280 -2.880302 0.982291 +v 0.308463 -2.652314 0.623122 +v 0.335656 -2.533507 0.213472 +v 0.335656 -2.533507 -0.213472 +v 0.308463 -2.652314 -0.623123 +v 0.256280 -2.880302 -0.982291 +v 0.183335 -3.199001 -1.261880 +v 0.095537 -3.582593 -1.439240 +v 0.214671 -3.629219 1.439240 +v 0.411951 -3.288476 1.261880 +v 0.575857 -3.005376 0.982291 +v 0.693110 -2.802855 0.623122 +v 0.754212 -2.697320 0.213472 +v 0.754212 -2.697320 -0.213472 +v 0.693110 -2.802855 -0.623123 +v 0.575857 -3.005376 -0.982291 +v 0.411951 -3.288476 -1.261880 +v 0.214671 -3.629218 -1.439240 +v 0.000000 -4.000000 1.500000 +v 0.314730 -3.708790 1.439240 +v 0.603963 -3.441172 1.261880 +v 0.844266 -3.218827 0.982291 +v 1.016171 -3.059767 0.623122 +v 1.105753 -2.976881 0.213472 +v 1.105753 -2.976881 -0.213472 +v 1.016171 -3.059767 -0.623123 +v 0.844265 -3.218827 -0.982291 +v 0.603963 -3.441172 -1.261880 +v 0.314730 -3.708790 -1.439240 +v 0.000000 -4.000000 -1.500000 +v 0.386824 -3.814236 1.439240 +v 0.742310 -3.643522 1.261880 +v 1.037658 -3.501688 0.982291 +v 1.248941 -3.400224 0.623122 +v 1.359043 -3.347350 0.213472 +v 1.359043 -3.347350 -0.213472 +v 1.248941 -3.400223 -0.623123 +v 1.037657 -3.501688 -0.982291 +v 0.742310 -3.643522 -1.261880 +v 0.386824 -3.814236 -1.439240 +v 0.424547 -3.936189 1.439240 +v 0.814699 -3.877548 1.261880 +v 1.138849 -3.828826 0.982291 +v 1.370737 -3.793973 0.623122 +v 1.491576 -3.775810 0.213472 +v 1.491576 -3.775810 -0.213472 +v 1.370737 -3.793972 -0.623123 +v 1.138849 -3.828826 -0.982291 +v 0.814699 -3.877548 -1.261880 +v 0.424547 -3.936189 -1.439240 +v 0.424546 -4.063811 1.439240 +v 0.814699 -4.122453 1.261880 +v 1.138849 -4.171175 0.982291 +v 1.370737 -4.206028 0.623122 +v 1.491575 -4.224191 0.213472 +v 1.491575 -4.224191 -0.213472 +v 1.370737 -4.206028 -0.623123 +v 1.138849 -4.171175 -0.982291 +v 0.814699 -4.122453 -1.261880 +v 0.424547 -4.063811 -1.439240 +v 0.386824 -4.185764 1.439240 +v 0.742309 -4.356478 1.261880 +v 1.037657 -4.498313 0.982291 +v 1.248941 -4.599777 0.623122 +v 1.359042 -4.652651 0.213472 +v 1.359042 -4.652651 -0.213472 +v 1.248941 -4.599777 -0.623123 +v 1.037657 -4.498313 -0.982291 +v 0.742309 -4.356478 -1.261880 +v 0.386824 -4.185764 -1.439240 +v 0.314730 -4.291210 1.439240 +v 0.603962 -4.558829 1.261880 +v 0.844265 -4.781174 0.982291 +v 1.016171 -4.940233 0.623122 +v 1.105752 -5.023120 0.213472 +v 1.105752 -5.023120 -0.213472 +v 1.016171 -4.940233 -0.623123 +v 0.844265 -4.781174 -0.982291 +v 0.603962 -4.558829 -1.261880 +v 0.314730 -4.291210 -1.439240 +v 0.214671 -4.370781 1.439240 +v 0.411950 -4.711525 1.261880 +v 0.575856 -4.994625 0.982291 +v 0.693109 -5.197145 0.623122 +v 0.754211 -5.302681 0.213472 +v 0.754211 -5.302681 -0.213472 +v 0.693109 -5.197145 -0.623123 +v 0.575856 -4.994624 -0.982291 +v 0.411950 -4.711525 -1.261880 +v 0.214671 -4.370781 -1.439240 +v 0.095537 -4.417407 1.439240 +v 0.183335 -4.800999 1.261880 +v 0.256280 -5.119698 0.982291 +v 0.308462 -5.347686 0.623122 +v 0.335655 -5.466493 0.213472 +v 0.335655 -5.466493 -0.213472 +v 0.308462 -5.347686 -0.623123 +v 0.256280 -5.119698 -0.982291 +v 0.183335 -4.800999 -1.261880 +v 0.095537 -4.417408 -1.439240 +v -0.032085 -4.426944 1.439240 +v -0.061571 -4.819301 1.261880 +v -0.086068 -5.145282 0.982291 +v -0.103593 -5.378479 0.623122 +v -0.112726 -5.500000 0.213472 +v -0.112726 -5.500000 -0.213472 +v -0.103593 -5.378479 -0.623123 +v -0.086068 -5.145282 -0.982291 +v -0.061571 -4.819301 -1.261880 +v -0.032085 -4.426945 -1.439240 +v -0.156857 -4.398546 1.439240 +v -0.301005 -4.764804 1.261880 +v -0.420769 -5.069102 0.982291 +v -0.506444 -5.286788 0.623122 +v -0.551090 -5.400226 0.213472 +v -0.551090 -5.400226 -0.213472 +v -0.506444 -5.286788 -0.623123 +v -0.420769 -5.069102 -0.982291 +v -0.301005 -4.764804 -1.261880 +v -0.156857 -4.398546 -1.439240 +v -0.267691 -4.334734 1.439240 +v -0.513695 -4.642351 1.261880 +v -0.718082 -4.897928 0.982291 +v -0.864295 -5.080760 0.623122 +v -0.940488 -5.176035 0.213472 +v -0.940488 -5.176035 -0.213472 +v -0.864295 -5.080760 -0.623123 +v -0.718082 -4.897928 -0.982291 +v -0.513695 -4.642351 -1.261880 +v -0.267691 -4.334734 -1.439240 +v -0.354739 -4.241180 1.439240 +v -0.680740 -4.462822 1.261880 +v -0.951591 -4.646969 0.982291 +v -1.145349 -4.778702 0.623122 +v -1.246319 -4.847349 0.213472 +v -1.246319 -4.847349 -0.213472 +v -1.145349 -4.778702 -0.623123 +v -0.951591 -4.646969 -0.982291 +v -0.680740 -4.462822 -1.261880 +v -0.354739 -4.241180 -1.439240 +v -0.410268 -4.126197 1.439240 +v -0.787298 -4.242170 1.261880 +v -1.100546 -4.338524 0.982291 +v -1.324635 -4.407453 0.623122 +v -1.441409 -4.443372 0.213472 +v -1.441409 -4.443372 -0.213472 +v -1.324635 -4.407453 -0.623123 +v -1.100546 -4.338524 -0.982291 +v -0.787298 -4.242170 -1.261880 +v -0.410268 -4.126197 -1.439240 +# 464 vertices, 0 vertices normals + +f 10 9 19 +f 10 19 20 +f 9 8 18 +f 9 18 19 +f 8 7 17 +f 8 17 18 +f 7 6 16 +f 7 16 17 +f 6 5 15 +f 6 15 16 +f 5 4 14 +f 5 14 15 +f 4 3 13 +f 4 13 14 +f 3 2 12 +f 3 12 13 +f 2 1 11 +f 2 11 12 +f 20 19 29 +f 20 29 30 +f 19 18 28 +f 19 28 29 +f 18 17 27 +f 18 27 28 +f 17 16 26 +f 17 26 27 +f 16 15 25 +f 16 25 26 +f 15 14 24 +f 15 24 25 +f 14 13 23 +f 14 23 24 +f 13 12 22 +f 13 22 23 +f 12 11 21 +f 12 21 22 +f 30 29 39 +f 30 39 40 +f 29 28 38 +f 29 38 39 +f 28 27 37 +f 28 37 38 +f 27 26 36 +f 27 36 37 +f 26 25 35 +f 26 35 36 +f 25 24 34 +f 25 34 35 +f 24 23 33 +f 24 33 34 +f 23 22 32 +f 23 32 33 +f 22 21 31 +f 22 31 32 +f 40 39 49 +f 40 49 50 +f 39 38 48 +f 39 48 49 +f 38 37 47 +f 38 47 48 +f 37 36 46 +f 37 46 47 +f 36 35 45 +f 36 45 46 +f 35 34 44 +f 35 44 45 +f 34 33 43 +f 34 43 44 +f 33 32 42 +f 33 42 43 +f 32 31 41 +f 32 41 42 +f 50 49 59 +f 50 59 60 +f 49 48 58 +f 49 58 59 +f 48 47 57 +f 48 57 58 +f 47 46 56 +f 47 56 57 +f 46 45 55 +f 46 55 56 +f 45 44 54 +f 45 54 55 +f 44 43 53 +f 44 53 54 +f 43 42 52 +f 43 52 53 +f 42 41 51 +f 42 51 52 +f 60 59 69 +f 60 69 70 +f 59 58 68 +f 59 68 69 +f 58 57 67 +f 58 67 68 +f 57 56 66 +f 57 66 67 +f 56 55 65 +f 56 65 66 +f 55 54 64 +f 55 64 65 +f 54 53 63 +f 54 63 64 +f 53 52 62 +f 53 62 63 +f 52 51 61 +f 52 61 62 +f 70 69 79 +f 70 79 80 +f 69 68 78 +f 69 78 79 +f 68 67 77 +f 68 77 78 +f 67 66 76 +f 67 76 77 +f 66 65 75 +f 66 75 76 +f 65 64 74 +f 65 74 75 +f 64 63 73 +f 64 73 74 +f 63 62 72 +f 63 72 73 +f 62 61 71 +f 62 71 72 +f 80 79 90 +f 80 90 91 +f 79 78 89 +f 79 89 90 +f 78 77 88 +f 78 88 89 +f 77 76 87 +f 77 87 88 +f 76 75 86 +f 76 86 87 +f 75 74 85 +f 75 85 86 +f 74 73 84 +f 74 84 85 +f 73 72 83 +f 73 83 84 +f 72 71 82 +f 72 82 83 +f 91 90 101 +f 91 101 102 +f 90 89 100 +f 90 100 101 +f 89 88 99 +f 89 99 100 +f 88 87 98 +f 88 98 99 +f 87 86 97 +f 87 97 98 +f 86 85 96 +f 86 96 97 +f 85 84 95 +f 85 95 96 +f 84 83 94 +f 84 94 95 +f 83 82 93 +f 83 93 94 +f 102 101 111 +f 102 111 112 +f 101 100 110 +f 101 110 111 +f 100 99 109 +f 100 109 110 +f 99 98 108 +f 99 108 109 +f 98 97 107 +f 98 107 108 +f 97 96 106 +f 97 106 107 +f 96 95 105 +f 96 105 106 +f 95 94 104 +f 95 104 105 +f 94 93 103 +f 94 103 104 +f 112 111 121 +f 112 121 122 +f 111 110 120 +f 111 120 121 +f 110 109 119 +f 110 119 120 +f 109 108 118 +f 109 118 119 +f 108 107 117 +f 108 117 118 +f 107 106 116 +f 107 116 117 +f 106 105 115 +f 106 115 116 +f 105 104 114 +f 105 114 115 +f 104 103 113 +f 104 113 114 +f 122 121 131 +f 122 131 132 +f 121 120 130 +f 121 130 131 +f 120 119 129 +f 120 129 130 +f 119 118 128 +f 119 128 129 +f 118 117 127 +f 118 127 128 +f 117 116 126 +f 117 126 127 +f 116 115 125 +f 116 125 126 +f 115 114 124 +f 115 124 125 +f 114 113 123 +f 114 123 124 +f 132 131 141 +f 132 141 142 +f 131 130 140 +f 131 140 141 +f 130 129 139 +f 130 139 140 +f 129 128 138 +f 129 138 139 +f 128 127 137 +f 128 137 138 +f 127 126 136 +f 127 136 137 +f 126 125 135 +f 126 135 136 +f 125 124 134 +f 125 134 135 +f 124 123 133 +f 124 133 134 +f 142 141 151 +f 142 151 152 +f 141 140 150 +f 141 150 151 +f 140 139 149 +f 140 149 150 +f 139 138 148 +f 139 148 149 +f 138 137 147 +f 138 147 148 +f 137 136 146 +f 137 146 147 +f 136 135 145 +f 136 145 146 +f 135 134 144 +f 135 144 145 +f 134 133 143 +f 134 143 144 +f 152 151 161 +f 152 161 162 +f 151 150 160 +f 151 160 161 +f 150 149 159 +f 150 159 160 +f 149 148 158 +f 149 158 159 +f 148 147 157 +f 148 157 158 +f 147 146 156 +f 147 156 157 +f 146 145 155 +f 146 155 156 +f 145 144 154 +f 145 154 155 +f 144 143 153 +f 144 153 154 +f 162 161 171 +f 162 171 172 +f 161 160 170 +f 161 170 171 +f 160 159 169 +f 160 169 170 +f 159 158 168 +f 159 168 169 +f 158 157 167 +f 158 167 168 +f 157 156 166 +f 157 166 167 +f 156 155 165 +f 156 165 166 +f 155 154 164 +f 155 164 165 +f 154 153 163 +f 154 163 164 +f 172 171 181 +f 172 181 182 +f 171 170 180 +f 171 180 181 +f 170 169 179 +f 170 179 180 +f 169 168 178 +f 169 178 179 +f 168 167 177 +f 168 177 178 +f 167 166 176 +f 167 176 177 +f 166 165 175 +f 166 175 176 +f 165 164 174 +f 165 174 175 +f 164 163 173 +f 164 173 174 +f 182 181 191 +f 182 191 192 +f 181 180 190 +f 181 190 191 +f 180 179 189 +f 180 189 190 +f 179 178 188 +f 179 188 189 +f 178 177 187 +f 178 187 188 +f 177 176 186 +f 177 186 187 +f 176 175 185 +f 176 185 186 +f 175 174 184 +f 175 184 185 +f 174 173 183 +f 174 183 184 +f 192 191 201 +f 192 201 202 +f 191 190 200 +f 191 200 201 +f 190 189 199 +f 190 199 200 +f 189 188 198 +f 189 198 199 +f 188 187 197 +f 188 197 198 +f 187 186 196 +f 187 196 197 +f 186 185 195 +f 186 195 196 +f 185 184 194 +f 185 194 195 +f 184 183 193 +f 184 193 194 +f 202 201 211 +f 202 211 212 +f 201 200 210 +f 201 210 211 +f 200 199 209 +f 200 209 210 +f 199 198 208 +f 199 208 209 +f 198 197 207 +f 198 207 208 +f 197 196 206 +f 197 206 207 +f 196 195 205 +f 196 205 206 +f 195 194 204 +f 195 204 205 +f 194 193 203 +f 194 203 204 +f 92 10 20 +f 1 81 11 +f 92 20 30 +f 11 81 21 +f 92 30 40 +f 21 81 31 +f 92 40 50 +f 31 81 41 +f 92 50 60 +f 41 81 51 +f 92 60 70 +f 51 81 61 +f 92 70 80 +f 61 81 71 +f 92 80 91 +f 71 81 82 +f 92 91 102 +f 82 81 93 +f 92 102 112 +f 93 81 103 +f 92 112 122 +f 103 81 113 +f 92 122 132 +f 113 81 123 +f 92 132 142 +f 123 81 133 +f 92 142 152 +f 133 81 143 +f 92 152 162 +f 143 81 153 +f 92 162 172 +f 153 81 163 +f 92 172 182 +f 163 81 173 +f 92 182 192 +f 173 81 183 +f 92 192 202 +f 183 81 193 +f 92 202 212 +f 193 81 203 +f 92 212 10 +f 212 211 9 +f 212 9 10 +f 211 210 8 +f 211 8 9 +f 210 209 7 +f 210 7 8 +f 209 208 6 +f 209 6 7 +f 208 207 5 +f 208 5 6 +f 207 206 4 +f 207 4 5 +f 206 205 3 +f 206 3 4 +f 205 204 2 +f 205 2 3 +f 204 203 1 +f 204 1 2 +f 203 81 1 +f 213 214 216 +f 213 216 215 +f 215 216 218 +f 215 218 217 +f 217 218 220 +f 217 220 219 +f 219 220 222 +f 219 222 221 +f 221 222 224 +f 221 224 223 +f 223 224 226 +f 223 226 225 +f 225 226 228 +f 225 228 227 +f 227 228 230 +f 227 230 229 +f 229 230 232 +f 229 232 231 +f 231 232 234 +f 231 234 233 +f 233 234 236 +f 233 236 235 +f 235 236 238 +f 235 238 237 +f 237 238 240 +f 237 240 239 +f 239 240 242 +f 239 242 241 +f 241 242 244 +f 241 244 243 +f 243 244 246 +f 243 246 245 +f 245 246 248 +f 245 248 247 +f 247 248 250 +f 247 250 249 +f 216 214 252 +f 216 252 250 +f 216 250 248 +f 216 248 246 +f 216 246 244 +f 216 244 242 +f 216 242 240 +f 216 240 238 +f 216 238 236 +f 216 236 234 +f 216 234 232 +f 216 232 230 +f 216 230 228 +f 216 228 226 +f 216 226 224 +f 216 224 222 +f 216 222 220 +f 216 220 218 +f 251 252 214 +f 251 214 213 +f 249 250 252 +f 249 252 251 +f 213 215 217 +f 213 217 219 +f 213 219 221 +f 213 221 223 +f 213 223 225 +f 213 225 227 +f 213 227 229 +f 213 229 231 +f 213 231 233 +f 213 233 235 +f 213 235 237 +f 213 237 239 +f 213 239 241 +f 213 241 243 +f 213 243 245 +f 213 245 247 +f 213 247 249 +f 213 249 251 +f 262 261 271 +f 262 271 272 +f 261 260 270 +f 261 270 271 +f 260 259 269 +f 260 269 270 +f 259 258 268 +f 259 268 269 +f 258 257 267 +f 258 267 268 +f 257 256 266 +f 257 266 267 +f 256 255 265 +f 256 265 266 +f 255 254 264 +f 255 264 265 +f 254 253 263 +f 254 263 264 +f 272 271 281 +f 272 281 282 +f 271 270 280 +f 271 280 281 +f 270 269 279 +f 270 279 280 +f 269 268 278 +f 269 278 279 +f 268 267 277 +f 268 277 278 +f 267 266 276 +f 267 276 277 +f 266 265 275 +f 266 275 276 +f 265 264 274 +f 265 274 275 +f 264 263 273 +f 264 273 274 +f 282 281 291 +f 282 291 292 +f 281 280 290 +f 281 290 291 +f 280 279 289 +f 280 289 290 +f 279 278 288 +f 279 288 289 +f 278 277 287 +f 278 287 288 +f 277 276 286 +f 277 286 287 +f 276 275 285 +f 276 285 286 +f 275 274 284 +f 275 284 285 +f 274 273 283 +f 274 283 284 +f 292 291 301 +f 292 301 302 +f 291 290 300 +f 291 300 301 +f 290 289 299 +f 290 299 300 +f 289 288 298 +f 289 298 299 +f 288 287 297 +f 288 297 298 +f 287 286 296 +f 287 296 297 +f 286 285 295 +f 286 295 296 +f 285 284 294 +f 285 294 295 +f 284 283 293 +f 284 293 294 +f 302 301 311 +f 302 311 312 +f 301 300 310 +f 301 310 311 +f 300 299 309 +f 300 309 310 +f 299 298 308 +f 299 308 309 +f 298 297 307 +f 298 307 308 +f 297 296 306 +f 297 306 307 +f 296 295 305 +f 296 305 306 +f 295 294 304 +f 295 304 305 +f 294 293 303 +f 294 303 304 +f 312 311 321 +f 312 321 322 +f 311 310 320 +f 311 320 321 +f 310 309 319 +f 310 319 320 +f 309 308 318 +f 309 318 319 +f 308 307 317 +f 308 317 318 +f 307 306 316 +f 307 316 317 +f 306 305 315 +f 306 315 316 +f 305 304 314 +f 305 314 315 +f 304 303 313 +f 304 313 314 +f 322 321 331 +f 322 331 332 +f 321 320 330 +f 321 330 331 +f 320 319 329 +f 320 329 330 +f 319 318 328 +f 319 328 329 +f 318 317 327 +f 318 327 328 +f 317 316 326 +f 317 326 327 +f 316 315 325 +f 316 325 326 +f 315 314 324 +f 315 324 325 +f 314 313 323 +f 314 323 324 +f 332 331 342 +f 332 342 343 +f 331 330 341 +f 331 341 342 +f 330 329 340 +f 330 340 341 +f 329 328 339 +f 329 339 340 +f 328 327 338 +f 328 338 339 +f 327 326 337 +f 327 337 338 +f 326 325 336 +f 326 336 337 +f 325 324 335 +f 325 335 336 +f 324 323 334 +f 324 334 335 +f 343 342 353 +f 343 353 354 +f 342 341 352 +f 342 352 353 +f 341 340 351 +f 341 351 352 +f 340 339 350 +f 340 350 351 +f 339 338 349 +f 339 349 350 +f 338 337 348 +f 338 348 349 +f 337 336 347 +f 337 347 348 +f 336 335 346 +f 336 346 347 +f 335 334 345 +f 335 345 346 +f 354 353 363 +f 354 363 364 +f 353 352 362 +f 353 362 363 +f 352 351 361 +f 352 361 362 +f 351 350 360 +f 351 360 361 +f 350 349 359 +f 350 359 360 +f 349 348 358 +f 349 358 359 +f 348 347 357 +f 348 357 358 +f 347 346 356 +f 347 356 357 +f 346 345 355 +f 346 355 356 +f 364 363 373 +f 364 373 374 +f 363 362 372 +f 363 372 373 +f 362 361 371 +f 362 371 372 +f 361 360 370 +f 361 370 371 +f 360 359 369 +f 360 369 370 +f 359 358 368 +f 359 368 369 +f 358 357 367 +f 358 367 368 +f 357 356 366 +f 357 366 367 +f 356 355 365 +f 356 365 366 +f 374 373 383 +f 374 383 384 +f 373 372 382 +f 373 382 383 +f 372 371 381 +f 372 381 382 +f 371 370 380 +f 371 380 381 +f 370 369 379 +f 370 379 380 +f 369 368 378 +f 369 378 379 +f 368 367 377 +f 368 377 378 +f 367 366 376 +f 367 376 377 +f 366 365 375 +f 366 375 376 +f 384 383 393 +f 384 393 394 +f 383 382 392 +f 383 392 393 +f 382 381 391 +f 382 391 392 +f 381 380 390 +f 381 390 391 +f 380 379 389 +f 380 389 390 +f 379 378 388 +f 379 388 389 +f 378 377 387 +f 378 387 388 +f 377 376 386 +f 377 386 387 +f 376 375 385 +f 376 385 386 +f 394 393 403 +f 394 403 404 +f 393 392 402 +f 393 402 403 +f 392 391 401 +f 392 401 402 +f 391 390 400 +f 391 400 401 +f 390 389 399 +f 390 399 400 +f 389 388 398 +f 389 398 399 +f 388 387 397 +f 388 397 398 +f 387 386 396 +f 387 396 397 +f 386 385 395 +f 386 395 396 +f 404 403 413 +f 404 413 414 +f 403 402 412 +f 403 412 413 +f 402 401 411 +f 402 411 412 +f 401 400 410 +f 401 410 411 +f 400 399 409 +f 400 409 410 +f 399 398 408 +f 399 408 409 +f 398 397 407 +f 398 407 408 +f 397 396 406 +f 397 406 407 +f 396 395 405 +f 396 405 406 +f 414 413 423 +f 414 423 424 +f 413 412 422 +f 413 422 423 +f 412 411 421 +f 412 421 422 +f 411 410 420 +f 411 420 421 +f 410 409 419 +f 410 419 420 +f 409 408 418 +f 409 418 419 +f 408 407 417 +f 408 417 418 +f 407 406 416 +f 407 416 417 +f 406 405 415 +f 406 415 416 +f 424 423 433 +f 424 433 434 +f 423 422 432 +f 423 432 433 +f 422 421 431 +f 422 431 432 +f 421 420 430 +f 421 430 431 +f 420 419 429 +f 420 429 430 +f 419 418 428 +f 419 428 429 +f 418 417 427 +f 418 427 428 +f 417 416 426 +f 417 426 427 +f 416 415 425 +f 416 425 426 +f 434 433 443 +f 434 443 444 +f 433 432 442 +f 433 442 443 +f 432 431 441 +f 432 441 442 +f 431 430 440 +f 431 440 441 +f 430 429 439 +f 430 439 440 +f 429 428 438 +f 429 438 439 +f 428 427 437 +f 428 437 438 +f 427 426 436 +f 427 436 437 +f 426 425 435 +f 426 435 436 +f 444 443 453 +f 444 453 454 +f 443 442 452 +f 443 452 453 +f 442 441 451 +f 442 451 452 +f 441 440 450 +f 441 450 451 +f 440 439 449 +f 440 449 450 +f 439 438 448 +f 439 448 449 +f 438 437 447 +f 438 447 448 +f 437 436 446 +f 437 446 447 +f 436 435 445 +f 436 445 446 +f 454 453 463 +f 454 463 464 +f 453 452 462 +f 453 462 463 +f 452 451 461 +f 452 461 462 +f 451 450 460 +f 451 460 461 +f 450 449 459 +f 450 459 460 +f 449 448 458 +f 449 458 459 +f 448 447 457 +f 448 457 458 +f 447 446 456 +f 447 456 457 +f 446 445 455 +f 446 455 456 +f 344 262 272 +f 253 333 263 +f 344 272 282 +f 263 333 273 +f 344 282 292 +f 273 333 283 +f 344 292 302 +f 283 333 293 +f 344 302 312 +f 293 333 303 +f 344 312 322 +f 303 333 313 +f 344 322 332 +f 313 333 323 +f 344 332 343 +f 323 333 334 +f 344 343 354 +f 334 333 345 +f 344 354 364 +f 345 333 355 +f 344 364 374 +f 355 333 365 +f 344 374 384 +f 365 333 375 +f 344 384 394 +f 375 333 385 +f 344 394 404 +f 385 333 395 +f 344 404 414 +f 395 333 405 +f 344 414 424 +f 405 333 415 +f 344 424 434 +f 415 333 425 +f 344 434 444 +f 425 333 435 +f 344 444 454 +f 435 333 445 +f 344 454 464 +f 445 333 455 +f 344 464 262 +f 464 463 261 +f 464 261 262 +f 463 462 260 +f 463 260 261 +f 462 461 259 +f 462 259 260 +f 461 460 258 +f 461 258 259 +f 460 459 257 +f 460 257 258 +f 459 458 256 +f 459 256 257 +f 458 457 255 +f 458 255 256 +f 457 456 254 +f 457 254 255 +f 456 455 253 +f 456 253 254 +f 455 333 253 +# 916 faces, 0 coords texture + +# End of File diff --git a/testbed/meshes/sphere.obj b/testbed/meshes/sphere.obj new file mode 100644 index 00000000..def1c1b5 --- /dev/null +++ b/testbed/meshes/sphere.obj @@ -0,0 +1,997 @@ +# Blender v2.66 (sub 0) OBJ File: '' +# www.blender.org +v -0.195090 0.980785 0.000000 +v -0.382683 0.923880 0.000000 +v -0.555570 0.831470 0.000000 +v -0.707107 0.707107 0.000000 +v -0.831470 0.555570 0.000000 +v -0.923880 0.382683 0.000000 +v -0.980785 0.195090 0.000000 +v -1.000000 0.000000 0.000000 +v -0.980785 -0.195090 0.000000 +v -0.923880 -0.382683 0.000000 +v -0.831470 -0.555570 0.000000 +v -0.707107 -0.707107 0.000000 +v -0.555570 -0.831470 0.000000 +v -0.382683 -0.923880 0.000000 +v -0.195090 -0.980785 0.000000 +v -0.191342 0.980785 -0.038060 +v -0.375330 0.923880 -0.074658 +v -0.544895 0.831470 -0.108386 +v -0.693520 0.707107 -0.137950 +v -0.815493 0.555570 -0.162212 +v -0.906127 0.382683 -0.180240 +v -0.961940 0.195090 -0.191342 +v -0.980785 0.000000 -0.195090 +v -0.961940 -0.195090 -0.191342 +v -0.906127 -0.382683 -0.180240 +v -0.815493 -0.555570 -0.162212 +v -0.693520 -0.707107 -0.137950 +v -0.544895 -0.831470 -0.108386 +v -0.375330 -0.923880 -0.074658 +v -0.191341 -0.980785 -0.038060 +v -0.180240 0.980785 -0.074658 +v -0.353553 0.923880 -0.146447 +v -0.513280 0.831470 -0.212608 +v -0.653281 0.707107 -0.270598 +v -0.768178 0.555570 -0.318190 +v -0.853553 0.382683 -0.353553 +v -0.906127 0.195090 -0.375330 +v -0.923880 0.000000 -0.382684 +v -0.906127 -0.195090 -0.375330 +v -0.853553 -0.382683 -0.353554 +v -0.768178 -0.555570 -0.318190 +v -0.653281 -0.707107 -0.270598 +v -0.513280 -0.831470 -0.212608 +v -0.353553 -0.923880 -0.146447 +v -0.180240 -0.980785 -0.074658 +v -0.162212 0.980785 -0.108387 +v -0.318190 0.923880 -0.212608 +v -0.461940 0.831470 -0.308658 +v -0.587938 0.707107 -0.392848 +v -0.691342 0.555570 -0.461940 +v -0.768178 0.382683 -0.513280 +v -0.815493 0.195090 -0.544895 +v -0.831470 0.000000 -0.555570 +v -0.815493 -0.195090 -0.544895 +v -0.768178 -0.382683 -0.513280 +v -0.691342 -0.555570 -0.461940 +v -0.587938 -0.707107 -0.392848 +v -0.461940 -0.831470 -0.308658 +v -0.318189 -0.923880 -0.212608 +v -0.162211 -0.980785 -0.108386 +v -0.137950 0.980785 -0.137950 +v -0.270598 0.923880 -0.270598 +v -0.392847 0.831470 -0.392848 +v -0.500000 0.707107 -0.500000 +v -0.587938 0.555570 -0.587938 +v -0.653281 0.382683 -0.653282 +v -0.693520 0.195090 -0.693520 +v -0.707107 0.000000 -0.707107 +v -0.693520 -0.195090 -0.693520 +v -0.653281 -0.382683 -0.653282 +v -0.587938 -0.555570 -0.587938 +v -0.500000 -0.707107 -0.500000 +v -0.392847 -0.831470 -0.392848 +v -0.270598 -0.923880 -0.270598 +v -0.137949 -0.980785 -0.137950 +v -0.108386 0.980785 -0.162212 +v -0.212607 0.923880 -0.318190 +v -0.308658 0.831470 -0.461940 +v -0.392847 0.707107 -0.587938 +v -0.461939 0.555570 -0.691342 +v -0.513280 0.382683 -0.768178 +v -0.544895 0.195090 -0.815493 +v -0.555570 0.000000 -0.831470 +v -0.544895 -0.195090 -0.815493 +v -0.513280 -0.382683 -0.768178 +v -0.461939 -0.555570 -0.691342 +v -0.392847 -0.707107 -0.587938 +v -0.308658 -0.831470 -0.461940 +v -0.212607 -0.923880 -0.318190 +v -0.108386 -0.980785 -0.162212 +v -0.074658 0.980785 -0.180240 +v -0.146446 0.923880 -0.353554 +v -0.212607 0.831470 -0.513280 +v -0.270598 0.707107 -0.653282 +v -0.318189 0.555570 -0.768178 +v -0.353553 0.382683 -0.853554 +v -0.375330 0.195090 -0.906128 +v -0.382683 0.000000 -0.923880 +v -0.375330 -0.195090 -0.906128 +v -0.353553 -0.382683 -0.853554 +v -0.318189 -0.555570 -0.768178 +v -0.270598 -0.707107 -0.653282 +v -0.212607 -0.831470 -0.513280 +v -0.146446 -0.923880 -0.353554 +v -0.074658 -0.980785 -0.180240 +v -0.038060 0.980785 -0.191342 +v -0.074658 0.923880 -0.375331 +v -0.108386 0.831470 -0.544895 +v -0.137949 0.707107 -0.693520 +v -0.162211 0.555570 -0.815493 +v -0.180240 0.382683 -0.906128 +v -0.191341 0.195090 -0.961940 +v -0.195090 0.000000 -0.980785 +v -0.191341 -0.195090 -0.961940 +v -0.180240 -0.382683 -0.906128 +v -0.162211 -0.555570 -0.815493 +v -0.137949 -0.707107 -0.693520 +v -0.108386 -0.831470 -0.544895 +v -0.074658 -0.923880 -0.375330 +v -0.038060 -0.980785 -0.191342 +v 0.000000 0.980785 -0.195091 +v 0.000000 0.923880 -0.382684 +v 0.000000 0.831470 -0.555570 +v 0.000000 0.707107 -0.707107 +v 0.000000 0.555570 -0.831470 +v 0.000000 0.382683 -0.923880 +v 0.000000 0.195090 -0.980785 +v 0.000000 0.000000 -1.000000 +v 0.000000 -0.195090 -0.980785 +v 0.000000 -0.382683 -0.923880 +v 0.000000 -0.555570 -0.831470 +v 0.000000 -0.707107 -0.707107 +v 0.000000 -0.831470 -0.555570 +v 0.000000 -0.923880 -0.382684 +v 0.000000 -0.980785 -0.195090 +v 0.038061 0.980785 -0.191342 +v 0.074658 0.923880 -0.375330 +v 0.108387 0.831470 -0.544895 +v 0.137950 0.707107 -0.693520 +v 0.162212 0.555570 -0.815493 +v 0.180240 0.382683 -0.906128 +v 0.191342 0.195090 -0.961940 +v 0.195091 0.000000 -0.980785 +v 0.191342 -0.195090 -0.961940 +v 0.180240 -0.382683 -0.906128 +v 0.162212 -0.555570 -0.815493 +v 0.137950 -0.707107 -0.693520 +v 0.108387 -0.831470 -0.544895 +v 0.074658 -0.923880 -0.375330 +v 0.038061 -0.980785 -0.191342 +v 0.074658 0.980785 -0.180240 +v 0.146447 0.923880 -0.353554 +v 0.212608 0.831470 -0.513280 +v 0.270599 0.707107 -0.653282 +v 0.318190 0.555570 -0.768178 +v 0.353554 0.382683 -0.853553 +v 0.375331 0.195090 -0.906127 +v 0.382684 0.000000 -0.923880 +v 0.375331 -0.195090 -0.906127 +v 0.353554 -0.382683 -0.853554 +v 0.318190 -0.555570 -0.768178 +v 0.270599 -0.707107 -0.653282 +v 0.212608 -0.831470 -0.513280 +v 0.146447 -0.923880 -0.353553 +v 0.074658 -0.980785 -0.180240 +v 0.108387 0.980785 -0.162212 +v 0.212608 0.923880 -0.318190 +v 0.308659 0.831470 -0.461940 +v 0.392848 0.707107 -0.587938 +v 0.461940 0.555570 -0.691342 +v 0.513280 0.382683 -0.768178 +v 0.544895 0.195090 -0.815493 +v 0.555571 0.000000 -0.831470 +v 0.544895 -0.195090 -0.815493 +v 0.513280 -0.382683 -0.768178 +v 0.461940 -0.555570 -0.691342 +v 0.392848 -0.707107 -0.587938 +v 0.308659 -0.831470 -0.461940 +v 0.212608 -0.923880 -0.318190 +v 0.108387 -0.980785 -0.162212 +v 0.137950 0.980785 -0.137950 +v 0.270599 0.923880 -0.270598 +v 0.392848 0.831470 -0.392848 +v 0.500000 0.707107 -0.500000 +v 0.587938 0.555570 -0.587938 +v 0.653282 0.382683 -0.653281 +v 0.693520 0.195090 -0.693520 +v 0.707107 0.000000 -0.707107 +v 0.693520 -0.195090 -0.693520 +v 0.653282 -0.382683 -0.653282 +v 0.587938 -0.555570 -0.587938 +v 0.500000 -0.707107 -0.500000 +v 0.392848 -0.831470 -0.392847 +v 0.270598 -0.923880 -0.270598 +v 0.137950 -0.980785 -0.137950 +v 0.162212 0.980785 -0.108386 +v 0.318190 0.923880 -0.212608 +v 0.461940 0.831470 -0.308658 +v 0.587938 0.707107 -0.392847 +v 0.691342 0.555570 -0.461940 +v 0.768178 0.382683 -0.513280 +v 0.815493 0.195090 -0.544895 +v 0.831470 0.000000 -0.555570 +v 0.815493 -0.195090 -0.544895 +v 0.768178 -0.382683 -0.513280 +v 0.691342 -0.555570 -0.461940 +v 0.587938 -0.707107 -0.392847 +v 0.461940 -0.831470 -0.308658 +v 0.318190 -0.923880 -0.212608 +v 0.162212 -0.980785 -0.108386 +v 0.180240 0.980785 -0.074658 +v 0.353554 0.923880 -0.146447 +v 0.513280 0.831470 -0.212608 +v 0.653282 0.707107 -0.270598 +v 0.768178 0.555570 -0.318190 +v 0.853554 0.382683 -0.353553 +v 0.906128 0.195090 -0.375330 +v 0.923880 0.000000 -0.382683 +v 0.906128 -0.195090 -0.375330 +v 0.853554 -0.382683 -0.353553 +v 0.768178 -0.555570 -0.318190 +v 0.653282 -0.707107 -0.270598 +v 0.513280 -0.831470 -0.212607 +v 0.353554 -0.923880 -0.146447 +v 0.180240 -0.980785 -0.074658 +v 0.191342 0.980785 -0.038060 +v 0.375331 0.923880 -0.074658 +v 0.544896 0.831470 -0.108386 +v 0.693520 0.707107 -0.137950 +v 0.815493 0.555570 -0.162212 +v 0.906128 0.382683 -0.180240 +v 0.961940 0.195090 -0.191342 +v 0.980785 0.000000 -0.195090 +v 0.961940 -0.195090 -0.191342 +v 0.906128 -0.382683 -0.180240 +v 0.815493 -0.555570 -0.162212 +v 0.693520 -0.707107 -0.137950 +v 0.544895 -0.831470 -0.108386 +v 0.375331 -0.923880 -0.074658 +v 0.191342 -0.980785 -0.038060 +v 0.195091 0.980785 0.000000 +v 0.382684 0.923880 0.000000 +v 0.555571 0.831470 0.000000 +v 0.707107 0.707107 0.000000 +v 0.831470 0.555570 0.000000 +v 0.923880 0.382683 0.000000 +v 0.980785 0.195090 0.000000 +v 1.000000 0.000000 0.000000 +v 0.980785 -0.195090 0.000000 +v 0.923880 -0.382683 0.000000 +v 0.831470 -0.555570 0.000000 +v 0.707107 -0.707107 0.000000 +v 0.555571 -0.831470 0.000000 +v 0.382684 -0.923880 0.000000 +v 0.195091 -0.980785 0.000000 +v 0.191342 0.980785 0.038060 +v 0.375331 0.923880 0.074658 +v 0.544896 0.831470 0.108386 +v 0.693520 0.707107 0.137950 +v 0.815493 0.555570 0.162212 +v 0.906128 0.382683 0.180240 +v 0.961940 0.195090 0.191342 +v 0.980785 0.000000 0.195090 +v 0.961940 -0.195090 0.191342 +v 0.906128 -0.382683 0.180240 +v 0.815493 -0.555570 0.162212 +v 0.693520 -0.707107 0.137950 +v 0.544895 -0.831470 0.108386 +v 0.375331 -0.923880 0.074658 +v 0.191342 -0.980785 0.038060 +v 0.180240 0.980785 0.074658 +v 0.353554 0.923880 0.146447 +v 0.513280 0.831470 0.212608 +v 0.653282 0.707107 0.270598 +v 0.768178 0.555570 0.318190 +v 0.853554 0.382683 0.353554 +v 0.906128 0.195090 0.375330 +v 0.923880 0.000000 0.382683 +v 0.906128 -0.195090 0.375330 +v 0.853554 -0.382683 0.353553 +v 0.768178 -0.555570 0.318190 +v 0.653282 -0.707107 0.270598 +v 0.513280 -0.831470 0.212608 +v 0.353554 -0.923880 0.146447 +v 0.180240 -0.980785 0.074658 +v 0.162212 0.980785 0.108387 +v 0.318190 0.923880 0.212608 +v 0.461940 0.831470 0.308658 +v 0.587938 0.707107 0.392848 +v 0.691342 0.555570 0.461940 +v 0.768178 0.382683 0.513280 +v 0.815493 0.195090 0.544895 +v 0.831470 0.000000 0.555570 +v 0.815493 -0.195090 0.544895 +v 0.768178 -0.382683 0.513280 +v 0.691342 -0.555570 0.461940 +v 0.587938 -0.707107 0.392848 +v 0.461940 -0.831470 0.308658 +v 0.318190 -0.923880 0.212608 +v 0.162212 -0.980785 0.108386 +v 0.137950 0.980785 0.137950 +v 0.270598 0.923880 0.270598 +v 0.392848 0.831470 0.392848 +v 0.500000 0.707107 0.500000 +v 0.587938 0.555570 0.587938 +v 0.653282 0.382683 0.653282 +v 0.693520 0.195090 0.693520 +v 0.707107 0.000000 0.707107 +v 0.693520 -0.195090 0.693520 +v 0.653282 -0.382683 0.653282 +v 0.587938 -0.555570 0.587938 +v 0.500000 -0.707107 0.500000 +v 0.392848 -0.831470 0.392848 +v 0.270598 -0.923880 0.270598 +v 0.137950 -0.980785 0.137950 +v 0.108387 0.980785 0.162212 +v 0.212608 0.923880 0.318190 +v 0.308659 0.831470 0.461940 +v 0.392848 0.707107 0.587938 +v 0.461940 0.555570 0.691342 +v 0.513280 0.382683 0.768178 +v 0.544895 0.195090 0.815493 +v 0.555570 0.000000 0.831469 +v 0.544895 -0.195090 0.815493 +v 0.513280 -0.382683 0.768178 +v 0.461940 -0.555570 0.691342 +v 0.392848 -0.707107 0.587938 +v 0.308659 -0.831470 0.461940 +v 0.212608 -0.923880 0.318190 +v 0.108387 -0.980785 0.162212 +v 0.000000 -1.000000 0.000000 +v 0.074658 0.980785 0.180240 +v 0.146447 0.923880 0.353554 +v 0.212608 0.831470 0.513280 +v 0.270598 0.707107 0.653281 +v 0.318190 0.555570 0.768178 +v 0.353554 0.382683 0.853553 +v 0.375330 0.195090 0.906127 +v 0.382683 0.000000 0.923879 +v 0.375330 -0.195090 0.906127 +v 0.353554 -0.382683 0.853553 +v 0.318190 -0.555570 0.768178 +v 0.270598 -0.707107 0.653281 +v 0.212608 -0.831470 0.513280 +v 0.146447 -0.923880 0.353553 +v 0.074658 -0.980785 0.180240 +v 0.038061 0.980785 0.191342 +v 0.074658 0.923880 0.375330 +v 0.108387 0.831470 0.544895 +v 0.137950 0.707107 0.693520 +v 0.162212 0.555570 0.815493 +v 0.180240 0.382683 0.906127 +v 0.191342 0.195090 0.961940 +v 0.195090 0.000000 0.980785 +v 0.191342 -0.195090 0.961940 +v 0.180240 -0.382683 0.906128 +v 0.162212 -0.555570 0.815493 +v 0.137950 -0.707107 0.693520 +v 0.108387 -0.831470 0.544895 +v 0.074658 -0.923880 0.375330 +v 0.038061 -0.980785 0.191342 +v 0.000000 0.980785 0.195090 +v 0.000000 0.923880 0.382684 +v 0.000000 0.831470 0.555570 +v 0.000000 0.707107 0.707107 +v 0.000000 0.555570 0.831469 +v 0.000000 0.382683 0.923879 +v 0.000000 0.195090 0.980785 +v 0.000000 0.000000 1.000000 +v 0.000000 -0.195090 0.980785 +v 0.000000 -0.382683 0.923880 +v 0.000000 -0.555570 0.831469 +v 0.000000 -0.707107 0.707107 +v 0.000000 -0.831470 0.555570 +v 0.000000 -0.923880 0.382683 +v 0.000000 -0.980785 0.195090 +v -0.038060 0.980785 0.191342 +v -0.074658 0.923880 0.375330 +v -0.108386 0.831470 0.544895 +v -0.137949 0.707107 0.693520 +v -0.162211 0.555570 0.815493 +v -0.180240 0.382683 0.906127 +v -0.191342 0.195090 0.961939 +v -0.195090 0.000000 0.980785 +v -0.191342 -0.195090 0.961939 +v -0.180240 -0.382683 0.906127 +v -0.162211 -0.555570 0.815493 +v -0.137949 -0.707107 0.693520 +v -0.108386 -0.831470 0.544895 +v -0.074658 -0.923880 0.375330 +v -0.038060 -0.980785 0.191342 +v -0.074658 0.980785 0.180240 +v -0.146446 0.923880 0.353553 +v -0.212607 0.831470 0.513280 +v -0.270598 0.707107 0.653281 +v -0.318189 0.555570 0.768177 +v -0.353553 0.382683 0.853553 +v -0.375330 0.195090 0.906127 +v -0.382683 0.000000 0.923879 +v -0.375330 -0.195090 0.906127 +v -0.353553 -0.382683 0.853553 +v -0.318189 -0.555570 0.768177 +v -0.270598 -0.707107 0.653281 +v -0.212607 -0.831470 0.513280 +v -0.146446 -0.923880 0.353553 +v -0.074657 -0.980785 0.180240 +v -0.108386 0.980785 0.162212 +v -0.212607 0.923880 0.318190 +v -0.308658 0.831470 0.461940 +v -0.392847 0.707107 0.587938 +v -0.461939 0.555570 0.691341 +v -0.513280 0.382683 0.768178 +v -0.544895 0.195090 0.815493 +v -0.555570 0.000000 0.831469 +v -0.544895 -0.195090 0.815493 +v -0.513280 -0.382683 0.768178 +v -0.461939 -0.555570 0.691341 +v -0.392847 -0.707107 0.587938 +v -0.308658 -0.831470 0.461940 +v -0.212607 -0.923880 0.318190 +v -0.108386 -0.980785 0.162212 +v -0.137949 0.980785 0.137950 +v -0.270598 0.923880 0.270598 +v -0.392847 0.831470 0.392847 +v -0.500000 0.707107 0.500000 +v -0.587937 0.555570 0.587937 +v -0.653281 0.382683 0.653281 +v -0.693519 0.195090 0.693519 +v -0.707106 0.000000 0.707106 +v -0.693519 -0.195090 0.693519 +v -0.653281 -0.382683 0.653281 +v -0.587937 -0.555570 0.587937 +v -0.500000 -0.707107 0.500000 +v -0.392847 -0.831470 0.392847 +v -0.270598 -0.923880 0.270598 +v -0.137949 -0.980785 0.137950 +v 0.000000 1.000000 0.000000 +v -0.162211 0.980785 0.108386 +v -0.318189 0.923880 0.212608 +v -0.461939 0.831470 0.308658 +v -0.587937 0.707107 0.392847 +v -0.691341 0.555570 0.461939 +v -0.768177 0.382683 0.513280 +v -0.815493 0.195090 0.544895 +v -0.831469 0.000000 0.555570 +v -0.815493 -0.195090 0.544895 +v -0.768178 -0.382683 0.513280 +v -0.691341 -0.555570 0.461939 +v -0.587937 -0.707107 0.392847 +v -0.461939 -0.831470 0.308658 +v -0.318189 -0.923880 0.212608 +v -0.162211 -0.980785 0.108386 +v -0.180240 0.980785 0.074658 +v -0.353553 0.923880 0.146447 +v -0.513280 0.831470 0.212607 +v -0.653281 0.707107 0.270598 +v -0.768177 0.555570 0.318189 +v -0.853553 0.382683 0.353553 +v -0.906127 0.195090 0.375330 +v -0.923879 0.000000 0.382683 +v -0.906127 -0.195090 0.375330 +v -0.853553 -0.382683 0.353553 +v -0.768177 -0.555570 0.318189 +v -0.653281 -0.707107 0.270598 +v -0.513280 -0.831470 0.212607 +v -0.353553 -0.923880 0.146447 +v -0.180240 -0.980785 0.074658 +v -0.191341 0.980785 0.038060 +v -0.375330 0.923880 0.074658 +v -0.544895 0.831470 0.108386 +v -0.693520 0.707107 0.137950 +v -0.815492 0.555570 0.162211 +v -0.906127 0.382683 0.180240 +v -0.961939 0.195090 0.191341 +v -0.980784 0.000000 0.195090 +v -0.961939 -0.195090 0.191341 +v -0.906127 -0.382683 0.180240 +v -0.815492 -0.555570 0.162211 +v -0.693520 -0.707107 0.137950 +v -0.544895 -0.831470 0.108386 +v -0.375330 -0.923880 0.074658 +v -0.191341 -0.980785 0.038060 +s off +f 13 12 27 28 +f 7 6 21 22 +f 14 13 28 29 +f 8 7 22 23 +f 2 1 16 17 +f 15 14 29 30 +f 9 8 23 24 +f 3 2 17 18 +f 10 9 24 25 +f 4 3 18 19 +f 11 10 25 26 +f 5 4 19 20 +f 12 11 26 27 +f 6 5 20 21 +f 30 29 44 45 +f 24 23 38 39 +f 18 17 32 33 +f 25 24 39 40 +f 19 18 33 34 +f 26 25 40 41 +f 20 19 34 35 +f 27 26 41 42 +f 21 20 35 36 +f 28 27 42 43 +f 22 21 36 37 +f 29 28 43 44 +f 23 22 37 38 +f 17 16 31 32 +f 43 42 57 58 +f 37 36 51 52 +f 44 43 58 59 +f 38 37 52 53 +f 32 31 46 47 +f 45 44 59 60 +f 39 38 53 54 +f 33 32 47 48 +f 40 39 54 55 +f 34 33 48 49 +f 41 40 55 56 +f 35 34 49 50 +f 42 41 56 57 +f 36 35 50 51 +f 56 55 70 71 +f 50 49 64 65 +f 57 56 71 72 +f 51 50 65 66 +f 58 57 72 73 +f 52 51 66 67 +f 59 58 73 74 +f 53 52 67 68 +f 47 46 61 62 +f 60 59 74 75 +f 54 53 68 69 +f 48 47 62 63 +f 55 54 69 70 +f 49 48 63 64 +f 75 74 89 90 +f 69 68 83 84 +f 63 62 77 78 +f 70 69 84 85 +f 64 63 78 79 +f 71 70 85 86 +f 65 64 79 80 +f 72 71 86 87 +f 66 65 80 81 +f 73 72 87 88 +f 67 66 81 82 +f 74 73 88 89 +f 68 67 82 83 +f 62 61 76 77 +f 88 87 102 103 +f 82 81 96 97 +f 89 88 103 104 +f 83 82 97 98 +f 77 76 91 92 +f 90 89 104 105 +f 84 83 98 99 +f 78 77 92 93 +f 85 84 99 100 +f 79 78 93 94 +f 86 85 100 101 +f 80 79 94 95 +f 87 86 101 102 +f 81 80 95 96 +f 94 93 108 109 +f 101 100 115 116 +f 95 94 109 110 +f 102 101 116 117 +f 96 95 110 111 +f 103 102 117 118 +f 97 96 111 112 +f 104 103 118 119 +f 98 97 112 113 +f 92 91 106 107 +f 105 104 119 120 +f 99 98 113 114 +f 93 92 107 108 +f 100 99 114 115 +f 113 112 127 128 +f 107 106 121 122 +f 120 119 134 135 +f 114 113 128 129 +f 108 107 122 123 +f 115 114 129 130 +f 109 108 123 124 +f 116 115 130 131 +f 110 109 124 125 +f 117 116 131 132 +f 111 110 125 126 +f 118 117 132 133 +f 112 111 126 127 +f 119 118 133 134 +f 132 131 146 147 +f 126 125 140 141 +f 133 132 147 148 +f 127 126 141 142 +f 134 133 148 149 +f 128 127 142 143 +f 122 121 136 137 +f 135 134 149 150 +f 129 128 143 144 +f 123 122 137 138 +f 130 129 144 145 +f 124 123 138 139 +f 131 130 145 146 +f 125 124 139 140 +f 145 144 159 160 +f 139 138 153 154 +f 146 145 160 161 +f 140 139 154 155 +f 147 146 161 162 +f 141 140 155 156 +f 148 147 162 163 +f 142 141 156 157 +f 149 148 163 164 +f 143 142 157 158 +f 137 136 151 152 +f 150 149 164 165 +f 144 143 158 159 +f 138 137 152 153 +f 164 163 178 179 +f 158 157 172 173 +f 152 151 166 167 +f 165 164 179 180 +f 159 158 173 174 +f 153 152 167 168 +f 160 159 174 175 +f 154 153 168 169 +f 161 160 175 176 +f 155 154 169 170 +f 162 161 176 177 +f 156 155 170 171 +f 163 162 177 178 +f 157 156 171 172 +f 177 176 191 192 +f 171 170 185 186 +f 178 177 192 193 +f 172 171 186 187 +f 179 178 193 194 +f 173 172 187 188 +f 167 166 181 182 +f 180 179 194 195 +f 174 173 188 189 +f 168 167 182 183 +f 175 174 189 190 +f 169 168 183 184 +f 176 175 190 191 +f 170 169 184 185 +f 190 189 204 205 +f 184 183 198 199 +f 191 190 205 206 +f 185 184 199 200 +f 192 191 206 207 +f 186 185 200 201 +f 193 192 207 208 +f 187 186 201 202 +f 194 193 208 209 +f 188 187 202 203 +f 182 181 196 197 +f 195 194 209 210 +f 189 188 203 204 +f 183 182 197 198 +f 209 208 223 224 +f 203 202 217 218 +f 197 196 211 212 +f 210 209 224 225 +f 204 203 218 219 +f 198 197 212 213 +f 205 204 219 220 +f 199 198 213 214 +f 206 205 220 221 +f 200 199 214 215 +f 207 206 221 222 +f 201 200 215 216 +f 208 207 222 223 +f 202 201 216 217 +f 222 221 236 237 +f 216 215 230 231 +f 223 222 237 238 +f 217 216 231 232 +f 224 223 238 239 +f 218 217 232 233 +f 212 211 226 227 +f 225 224 239 240 +f 219 218 233 234 +f 213 212 227 228 +f 220 219 234 235 +f 214 213 228 229 +f 221 220 235 236 +f 215 214 229 230 +f 228 227 242 243 +f 235 234 249 250 +f 229 228 243 244 +f 236 235 250 251 +f 230 229 244 245 +f 237 236 251 252 +f 231 230 245 246 +f 238 237 252 253 +f 232 231 246 247 +f 239 238 253 254 +f 233 232 247 248 +f 227 226 241 242 +f 240 239 254 255 +f 234 233 248 249 +f 247 246 261 262 +f 254 253 268 269 +f 248 247 262 263 +f 242 241 256 257 +f 255 254 269 270 +f 249 248 263 264 +f 243 242 257 258 +f 250 249 264 265 +f 244 243 258 259 +f 251 250 265 266 +f 245 244 259 260 +f 252 251 266 267 +f 246 245 260 261 +f 253 252 267 268 +f 266 265 280 281 +f 260 259 274 275 +f 267 266 281 282 +f 261 260 275 276 +f 268 267 282 283 +f 262 261 276 277 +f 269 268 283 284 +f 263 262 277 278 +f 257 256 271 272 +f 270 269 284 285 +f 264 263 278 279 +f 258 257 272 273 +f 265 264 279 280 +f 259 258 273 274 +f 285 284 299 300 +f 279 278 293 294 +f 273 272 287 288 +f 280 279 294 295 +f 274 273 288 289 +f 281 280 295 296 +f 275 274 289 290 +f 282 281 296 297 +f 276 275 290 291 +f 283 282 297 298 +f 277 276 291 292 +f 284 283 298 299 +f 278 277 292 293 +f 272 271 286 287 +f 298 297 312 313 +f 292 291 306 307 +f 299 298 313 314 +f 293 292 307 308 +f 287 286 301 302 +f 300 299 314 315 +f 294 293 308 309 +f 288 287 302 303 +f 295 294 309 310 +f 289 288 303 304 +f 296 295 310 311 +f 290 289 304 305 +f 297 296 311 312 +f 291 290 305 306 +f 311 310 325 326 +f 305 304 319 320 +f 312 311 326 327 +f 306 305 320 321 +f 313 312 327 328 +f 307 306 321 322 +f 314 313 328 329 +f 308 307 322 323 +f 302 301 316 317 +f 315 314 329 330 +f 309 308 323 324 +f 303 302 317 318 +f 310 309 324 325 +f 304 303 318 319 +f 330 329 345 346 +f 324 323 339 340 +f 318 317 333 334 +f 325 324 340 341 +f 319 318 334 335 +f 326 325 341 342 +f 320 319 335 336 +f 327 326 342 343 +f 321 320 336 337 +f 328 327 343 344 +f 322 321 337 338 +f 329 328 344 345 +f 323 322 338 339 +f 317 316 332 333 +f 344 343 358 359 +f 338 337 352 353 +f 345 344 359 360 +f 339 338 353 354 +f 333 332 347 348 +f 346 345 360 361 +f 340 339 354 355 +f 334 333 348 349 +f 341 340 355 356 +f 335 334 349 350 +f 342 341 356 357 +f 336 335 350 351 +f 343 342 357 358 +f 337 336 351 352 +f 357 356 371 372 +f 351 350 365 366 +f 358 357 372 373 +f 352 351 366 367 +f 359 358 373 374 +f 353 352 367 368 +f 360 359 374 375 +f 354 353 368 369 +f 348 347 362 363 +f 361 360 375 376 +f 355 354 369 370 +f 349 348 363 364 +f 356 355 370 371 +f 350 349 364 365 +f 363 362 377 378 +f 376 375 390 391 +f 370 369 384 385 +f 364 363 378 379 +f 371 370 385 386 +f 365 364 379 380 +f 372 371 386 387 +f 366 365 380 381 +f 373 372 387 388 +f 367 366 381 382 +f 374 373 388 389 +f 368 367 382 383 +f 375 374 389 390 +f 369 368 383 384 +f 382 381 396 397 +f 389 388 403 404 +f 383 382 397 398 +f 390 389 404 405 +f 384 383 398 399 +f 378 377 392 393 +f 391 390 405 406 +f 385 384 399 400 +f 379 378 393 394 +f 386 385 400 401 +f 380 379 394 395 +f 387 386 401 402 +f 381 380 395 396 +f 388 387 402 403 +f 401 400 415 416 +f 395 394 409 410 +f 402 401 416 417 +f 396 395 410 411 +f 403 402 417 418 +f 397 396 411 412 +f 404 403 418 419 +f 398 397 412 413 +f 405 404 419 420 +f 399 398 413 414 +f 393 392 407 408 +f 406 405 420 421 +f 400 399 414 415 +f 394 393 408 409 +f 420 419 434 435 +f 414 413 428 429 +f 408 407 422 423 +f 421 420 435 436 +f 415 414 429 430 +f 409 408 423 424 +f 416 415 430 431 +f 410 409 424 425 +f 417 416 431 432 +f 411 410 425 426 +f 418 417 432 433 +f 412 411 426 427 +f 419 418 433 434 +f 413 412 427 428 +f 433 432 448 449 +f 427 426 442 443 +f 434 433 449 450 +f 428 427 443 444 +f 435 434 450 451 +f 429 428 444 445 +f 423 422 438 439 +f 436 435 451 452 +f 430 429 445 446 +f 424 423 439 440 +f 431 430 446 447 +f 425 424 440 441 +f 432 431 447 448 +f 426 425 441 442 +f 447 446 461 462 +f 441 440 455 456 +f 448 447 462 463 +f 442 441 456 457 +f 449 448 463 464 +f 443 442 457 458 +f 450 449 464 465 +f 444 443 458 459 +f 451 450 465 466 +f 445 444 459 460 +f 439 438 453 454 +f 452 451 466 467 +f 446 445 460 461 +f 440 439 454 455 +f 466 465 480 481 +f 460 459 474 475 +f 454 453 468 469 +f 467 466 481 482 +f 461 460 475 476 +f 455 454 469 470 +f 462 461 476 477 +f 456 455 470 471 +f 463 462 477 478 +f 457 456 471 472 +f 464 463 478 479 +f 458 457 472 473 +f 465 464 479 480 +f 459 458 473 474 +f 1 437 16 +f 331 15 30 +f 331 30 45 +f 16 437 31 +f 31 437 46 +f 331 45 60 +f 46 437 61 +f 331 60 75 +f 331 75 90 +f 61 437 76 +f 76 437 91 +f 331 90 105 +f 91 437 106 +f 331 105 120 +f 331 120 135 +f 106 437 121 +f 121 437 136 +f 331 135 150 +f 331 150 165 +f 136 437 151 +f 331 165 180 +f 151 437 166 +f 166 437 181 +f 331 180 195 +f 331 195 210 +f 181 437 196 +f 331 210 225 +f 196 437 211 +f 211 437 226 +f 331 225 240 +f 331 240 255 +f 226 437 241 +f 241 437 256 +f 331 255 270 +f 256 437 271 +f 331 270 285 +f 331 285 300 +f 271 437 286 +f 286 437 301 +f 331 300 315 +f 301 437 316 +f 331 315 330 +f 331 330 346 +f 316 437 332 +f 332 437 347 +f 331 346 361 +f 347 437 362 +f 331 361 376 +f 331 376 391 +f 362 437 377 +f 377 437 392 +f 331 391 406 +f 392 437 407 +f 331 406 421 +f 331 421 436 +f 407 437 422 +f 422 437 438 +f 331 436 452 +f 331 452 467 +f 438 437 453 +f 331 467 482 +f 453 437 468 +f 479 478 11 12 +f 473 472 5 6 +f 480 479 12 13 +f 474 473 6 7 +f 468 437 1 +f 481 480 13 14 +f 475 474 7 8 +f 469 468 1 2 +f 482 481 14 15 +f 476 475 8 9 +f 470 469 2 3 +f 331 482 15 +f 477 476 9 10 +f 471 470 3 4 +f 478 477 10 11 +f 472 471 4 5 diff --git a/testbed/opengl-framework/CMakeLists.txt b/testbed/opengl-framework/CMakeLists.txt new file mode 100644 index 00000000..e10ae781 --- /dev/null +++ b/testbed/opengl-framework/CMakeLists.txt @@ -0,0 +1,84 @@ +# Minimum cmake version required +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) + +# Project configuration +PROJECT(OPENGLFRAMEWORK) + +# Options +OPTION(USE_JPEG_TEXTURES "Select this if you want to use jpeg textures (libjpeg required)" OFF) + +# Where to find the module to find special packages/libraries +SET(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/") + +# Find OpenGL +FIND_PACKAGE(OpenGL REQUIRED) +IF(OPENGL_FOUND) + MESSAGE("OpenGL found") +ELSE() + MESSAGE("OpenGL not found") +ENDIF() + +# Find the GLEW library +FIND_PACKAGE(GLEW REQUIRED) +IF(GLEW_FOUND) + MESSAGE("GLEW found") +ELSE() + MESSAGE("GLEW not found") +ENDIF() + +# If the user wants to use JPEG textures +IF(USE_JPEG_TEXTURES) + + # Find the LIBJPEG library + FIND_PACKAGE(JPEG REQUIRED) + IF(JPEG_FOUND) + MESSAGE("LIBJPEG found") + ELSE() + MESSAGE("LIBJPEG not found") + ENDIF() +ENDIF() + +# Headers +INCLUDE_DIRECTORIES(src ${OPENGL_INCLUDE_DIR} ${GLEW_INCLUDE_PATH} ${JPEG_INCLUDE_DIR}) + +# Source files +SET(OPENGL_FRAMEWORK_SOURCES + "src/maths/Color.h" + "src/maths/Matrix3.h" + "src/maths/Matrix4.h" + "src/maths/Vector2.h" + "src/maths/Vector3.h" + "src/maths/Vector4.h" + "src/Camera.cpp" + "src/Camera.h" + "src/definitions.h" + "src/FrameBufferObject.cpp" + "src/FrameBufferObject.h" + "src/Light.h" + "src/Light.cpp" + "src/Mesh.h" + "src/Mesh.cpp" + "src/MeshReaderWriter.h" + "src/MeshReaderWriter.cpp" + "src/Object3D.h" + "src/Object3D.cpp" + "src/openglframework.h" + "src/Shader.h" + "src/Shader.cpp" + "src/Texture2D.h" + "src/Texture2D.cpp" + "src/TextureReaderWriter.h" + "src/TextureReaderWriter.cpp" + "src/VertexBufferObject.h" + "src/VertexBufferObject.cpp" +) + +IF(USE_JPEG_TEXTURES) + ADD_DEFINITIONS(-DUSE_JPEG_TEXTURE) +ENDIF() + +# Create the library +ADD_LIBRARY (openglframework STATIC ${OPENGL_FRAMEWORK_SOURCES}) + +# Link with others libraries +TARGET_LINK_LIBRARIES(openglframework ${GLEW_LIBRARIES} ${OPENGL_LIBRARY}) diff --git a/testbed/opengl-framework/cmake/FindFREEGLUT.cmake b/testbed/opengl-framework/cmake/FindFREEGLUT.cmake new file mode 100644 index 00000000..0ca4821e --- /dev/null +++ b/testbed/opengl-framework/cmake/FindFREEGLUT.cmake @@ -0,0 +1,32 @@ +# This module is used to try to find the Freeglut library and include files + +IF(WIN32) + FIND_PATH(FREEGLUT_INCLUDE_DIR NAMES GL/freeglut.h) + FIND_LIBRARY(FREEGLUT_LIBRARY NAMES freeglut freeglut_static + PATHS ${OPENGL_LIBRARY_DIR}) +ELSE(WIN32) + + IF(APPLE) + # Do nothing, we do not want to use freeglut on Mac OS X + ELSE(APPLE) + FIND_PATH(FREEGLUT_INCLUDE_DIR GL/freeglut.h /usr/include/GL + /usr/openwin/share/include + /usr/openwin/include + /opt/graphics/OpenGL/include + /opt/graphics/OpenGL/contrib/libglut) + + FIND_LIBRARY(FREEGLUT_LIBRARY NAMES glut freeglut freeglut_static PATHS /usr/openwin/lib) + FIND_LIBRARY(Xi_LIBRARY Xi /usr/openwin/lib) + FIND_LIBRARY(Xmu_LIBRARY Xmu /usr/openwin/lib) + ENDIF(APPLE) +ENDIF(WIN32) + +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(FREEGLUT REQUIRED_VARS FREEGLUT_LIBRARY FREEGLUT_INCLUDE_DIR) + +IF(FREEGLUT_FOUND) + SET(FREEGLUT_LIBRARIES ${FREEGLUT_LIBRARY} ${Xi_LIBRARY} ${Xmu_LIBRARY}) + SET(FREEGLUT_LIBRARY ${FREEGLUT_LIBRARIES}) +ENDIF(FREEGLUT_FOUND) + +MARK_AS_ADVANCED(FREEGLUT_INCLUDE_DIR FREEGLUT_LIBRARY Xi_LIBRARY Xmu_LIBRARY) diff --git a/testbed/opengl-framework/cmake/FindGLEW.cmake b/testbed/opengl-framework/cmake/FindGLEW.cmake new file mode 100644 index 00000000..c29c4eb2 --- /dev/null +++ b/testbed/opengl-framework/cmake/FindGLEW.cmake @@ -0,0 +1,65 @@ +# +# Try to find GLEW library and include path. +# Once done this will define +# +# GLEW_FOUND +# GLEW_INCLUDE_PATH +# GLEW_LIBRARY +# + +IF (WIN32) +FIND_PATH( GLEW_INCLUDE_PATH GL/glew.h +$ENV{PROGRAMFILES}/GLEW/include +${GLEW_ROOT_DIR}/include +DOC "The directory where GL/glew.h resides") + +IF (NV_SYSTEM_PROCESSOR STREQUAL "AMD64") +FIND_LIBRARY( GLEW_LIBRARY +NAMES glew64 glew64s +PATHS +$ENV{PROGRAMFILES}/GLEW/lib +${PROJECT_SOURCE_DIR}/src/nvgl/glew/bin +${PROJECT_SOURCE_DIR}/src/nvgl/glew/lib +DOC "The GLEW library (64-bit)" +) +ELSE(NV_SYSTEM_PROCESSOR STREQUAL "AMD64") +FIND_LIBRARY( GLEW_LIBRARY +NAMES glew GLEW glew32 glew32s +PATHS +$ENV{PROGRAMFILES}/GLEW/lib +${PROJECT_SOURCE_DIR}/src/nvgl/glew/bin +${PROJECT_SOURCE_DIR}/src/nvgl/glew/lib +DOC "The GLEW library" +) +ENDIF(NV_SYSTEM_PROCESSOR STREQUAL "AMD64") +ELSE (WIN32) +FIND_PATH( GLEW_INCLUDE_PATH GL/glew.h +/usr/include +/usr/local/include +/sw/include +/opt/local/include +${GLEW_ROOT_DIR}/include +DOC "The directory where GL/glew.h resides") + +FIND_LIBRARY( GLEW_LIBRARY +NAMES GLEW glew +PATHS +/usr/lib64 +/usr/lib +/usr/local/lib64 +/usr/local/lib +/sw/lib +/opt/local/lib +${GLEW_ROOT_DIR}/lib +DOC "The GLEW library") +ENDIF (WIN32) + +SET(GLEW_FOUND "NO") +IF (GLEW_INCLUDE_PATH AND GLEW_LIBRARY) +SET(GLEW_LIBRARIES ${GLEW_LIBRARY}) +SET(GLEW_FOUND "YES") +ENDIF (GLEW_INCLUDE_PATH AND GLEW_LIBRARY) + + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(GLEW DEFAULT_MSG GLEW_LIBRARY GLEW_INCLUDE_PATH) \ No newline at end of file diff --git a/testbed/opengl-framework/src/Camera.cpp b/testbed/opengl-framework/src/Camera.cpp new file mode 100644 index 00000000..a032a046 --- /dev/null +++ b/testbed/opengl-framework/src/Camera.cpp @@ -0,0 +1,97 @@ +/******************************************************************************** +* OpenGL-Framework * +* Copyright (c) 2013 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + + +// Libraries +#include "Camera.h" +#include "definitions.h" +#include + +// Namespaces +using namespace openglframework; + +// Constructor +Camera::Camera() : Object3D() { + + // Set default values + mFieldOfView = 45.0f; + mSceneRadius = 1.0f; + mNearPlane = 0.1f; + mFarPlane = 10.0f; + mWidth = 1; + mHeight = 1; + + // Update the projection matrix + updateProjectionMatrix(); +} + +// Destructor +Camera::~Camera() { + +} + +// Update the projection matrix +void Camera::updateProjectionMatrix() { + + // Compute the aspect ratio + float aspect = float(mWidth) / float(mHeight); + + float top = mNearPlane * tan((mFieldOfView / 2.0f) * (float(PI) / 180.0f)); + float bottom = -top; + float left = bottom * aspect; + float right = top * aspect; + + float fx = 2.0f * mNearPlane / (right - left); + float fy = 2.0f * mNearPlane / (top - bottom); + float fz = -(mFarPlane + mNearPlane) / (mFarPlane - mNearPlane); + float fw = -2.0f * mFarPlane * mNearPlane / (mFarPlane - mNearPlane); + + // Recompute the projection matrix + mProjectionMatrix = Matrix4(fx, 0, 0, 0, + 0, fy, 0, 0, + 0, 0, fz, fw, + 0, 0, -1, 0); +} + +// Translate the camera go a given point using the dx, dy fraction +void Camera::translateCamera(float dx, float dy, const Vector3& worldPoint) { + + // Transform the world point into camera coordinates + Vector3 pointCamera = mTransformMatrix.getInverse() * worldPoint; + + // Get the depth + float z = -pointCamera.z; + + // Find the scaling of dx and dy from windows coordinates to near plane coordinates + // and from there to camera coordinates at the object's depth + float aspect = float(mWidth) / float(mHeight); + float top = mNearPlane * tan(mFieldOfView * PI / 360.0f); + float right = top * aspect; + + // Translate the camera + translateLocal(Vector3(2.0f * dx * right / mNearPlane * z, + -2.0f * dy * top / mNearPlane * z, + 0.0f)); +} diff --git a/testbed/opengl-framework/src/Camera.h b/testbed/opengl-framework/src/Camera.h new file mode 100644 index 00000000..108c363f --- /dev/null +++ b/testbed/opengl-framework/src/Camera.h @@ -0,0 +1,181 @@ +/******************************************************************************** +* OpenGL-Framework * +* Copyright (c) 2013 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +#ifndef CAMERA_H +#define CAMERA_H + +// Libraries +#include "Object3D.h" +#include "definitions.h" + +namespace openglframework { + +// Class Camera +class Camera : public Object3D { + + protected : + + // ------------------- Attributes ------------------- // + + // Field of view + float mFieldOfView; + + // Radius of the scene + float mSceneRadius; + + // Near plane + float mNearPlane; + + // Far plane + float mFarPlane; + + // Width of the camera + uint mWidth; + + // Height of the camera + uint mHeight; + + // Projection matrix + Matrix4 mProjectionMatrix; + + // ------------------- Methods ------------------- // + + // Update the projection matrix + void updateProjectionMatrix(); + + public: + + // ------------------- Methods ------------------- // + + // Constructor + Camera(); + + // Destructor + ~Camera(); + + // Get the projection matrix + const Matrix4& getProjectionMatrix() const; + + // Set the dimensions of the camera + void setDimensions(uint width, uint height); + + // Get the radius of the scene the camera should capture + float getSceneRadius() const; + + // Set the radius of the scene the camera should capture + // This will update the clipping planes accordingly + void setSceneRadius(float radius); + + // Set the clipping planes + void setClippingPlanes(float near, float far); + + // Set the field of view + void setFieldOfView(float fov); + + // Set the zoom of the camera (a fraction between 0 and 1) + void setZoom(float fraction); + + // Translate the camera go a given point using the dx, dy fraction + void translateCamera(float dx, float dy, const Vector3& worldPoint); + + // Get the near clipping plane + float getNearClippingPlane() const; + + // Get the far clipping plane + float getFarClippingPlane() const; + + // Get the width + uint getWidth() const; + + // Get the height + uint getHeight() const; +}; + +// Get the projection matrix +inline const Matrix4& Camera::getProjectionMatrix() const { + return mProjectionMatrix; +} + +// Set the dimensions of the camera +inline void Camera::setDimensions(uint width, uint height) { + mWidth = width; + mHeight = height; + updateProjectionMatrix(); +} + +// Get the radius of the scene the camera should capture +inline float Camera::getSceneRadius() const { + return mSceneRadius; +} + +// Set the radius of the scene the camera should capture +// This will update the clipping planes accordingly +inline void Camera::setSceneRadius(float radius) { + mSceneRadius = radius; + setClippingPlanes(0.01f * radius, 10.0f * radius); +} + +// Set the clipping planes +inline void Camera::setClippingPlanes(float near, float far) { + mNearPlane = near; + mFarPlane = far; + updateProjectionMatrix(); +} + +// Set the field of view +inline void Camera::setFieldOfView(float fov) { + mFieldOfView = fov; + updateProjectionMatrix(); +} + +// Set the zoom of the camera (a fraction between 0 and 1) +inline void Camera::setZoom(float fraction) { + Vector3 zoomVector(0, 0, mSceneRadius * fraction); + translateLocal(zoomVector); +} + +// Get the near clipping plane +inline float Camera::getNearClippingPlane() const { + return mNearPlane; +} + +// Get the far clipping plane +inline float Camera::getFarClippingPlane() const { + return mFarPlane; +} + +// Get the width +inline uint Camera::getWidth() const { + return mWidth; +} + +// Get the height +inline uint Camera::getHeight() const { + return mHeight; +} + +} + +#endif diff --git a/testbed/opengl-framework/src/FrameBufferObject.cpp b/testbed/opengl-framework/src/FrameBufferObject.cpp new file mode 100644 index 00000000..5f67be23 --- /dev/null +++ b/testbed/opengl-framework/src/FrameBufferObject.cpp @@ -0,0 +1,115 @@ +/******************************************************************************** +* OpenGL-Framework * +* Copyright (c) 2013 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Libraries +#include "FrameBufferObject.h" +#include + +using namespace openglframework; +using namespace std; + +// Constructor +FrameBufferObject::FrameBufferObject() : mFrameBufferID(0), mRenderBufferID (0) { + +} + +// Destructor +FrameBufferObject::~FrameBufferObject() { + +} + +// Create the frame buffer object +bool FrameBufferObject::create(uint width, uint height, bool needRenderBuffer) { + + // Destroy the current FBO + destroy(); + + // Check that the needed OpenGL extensions are available + bool isExtensionOK = checkOpenGLExtensions(); + if (!isExtensionOK) { + std::cerr << "Error : Impossible to use Framebuffer Object on this platform" << std::endl; + assert(false); + return false; + } + + // Generate a new FBO + glGenFramebuffersEXT(1, &mFrameBufferID); + assert(mFrameBufferID != 0); + + // If we also need to create a render buffer + if (needRenderBuffer) { + + // Generate the render buffer + glGenRenderbuffers(1, &mRenderBufferID); + assert(mRenderBufferID != 0); + + glBindRenderbuffer(GL_RENDERBUFFER, mRenderBufferID); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT32, width, height); + glBindFramebuffer(GL_FRAMEBUFFER, mFrameBufferID); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, + mRenderBufferID); + glBindRenderbuffer(GL_RENDERBUFFER, 0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + } + + // Check the FBO status + GLenum statusFBO = glCheckFramebufferStatus(GL_FRAMEBUFFER); + if(statusFBO != GL_FRAMEBUFFER_COMPLETE) { + std::cerr << "Error : An error occured while creating the Frame Buffer Object !" << endl; + assert(false); + return false; + } + + return true; +} + +// Destroy the FBO +void FrameBufferObject::destroy() { + + // Delete the frame buffer object + if (mFrameBufferID) { + glDeleteFramebuffers(1, &mFrameBufferID); + mFrameBufferID = 0; + } + + // Delete the render buffer + if (mRenderBufferID) { + glDeleteRenderbuffers(1, &mRenderBufferID); + } +} + +// Attach a texture to the frame buffer object +void FrameBufferObject::attachTexture(uint position, uint textureID) { + assert(mFrameBufferID); + + // Bind the current FBO + glBindFramebuffer(GL_FRAMEBUFFER, mFrameBufferID); + + // Bind the texture + glFramebufferTexture2D(GL_FRAMEBUFFER, position, GL_TEXTURE_2D, textureID, 0); + + // Unbind the current FBO + glBindFramebuffer(GL_FRAMEBUFFER, 0); +} diff --git a/testbed/opengl-framework/src/FrameBufferObject.h b/testbed/opengl-framework/src/FrameBufferObject.h new file mode 100644 index 00000000..a76951c7 --- /dev/null +++ b/testbed/opengl-framework/src/FrameBufferObject.h @@ -0,0 +1,105 @@ +/******************************************************************************** +* OpenGL-Framework * +* Copyright (c) 2013 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +#ifndef FRAME_BUFFER_OBJECT_H +#define FRAME_BUFFER_OBJECT_H + +// Libraries +#include "definitions.h" +#include +#include +#include + +namespace openglframework { + + +// Class FrameBufferObject +class FrameBufferObject { + + private: + + // -------------------- Attributes -------------------- // + + // Frame buffer ID + uint mFrameBufferID; + + // Render buffer ID + uint mRenderBufferID; + + public: + + // -------------------- Methods -------------------- // + + // Constructor + FrameBufferObject(); + + // Destructor + ~FrameBufferObject(); + + // Create the frame buffer object + bool create(uint width, uint height, bool needRenderBuffer = true); + + // Attach a texture to the frame buffer object + void attachTexture(uint position, uint textureID); + + // Bind the FBO + void bind(uint position) const; + + // Unbind the FBO + void unbind() const; + + // Return true if the needed OpenGL extensions are available for FBO + static bool checkOpenGLExtensions(); + + // Destroy the FBO + void destroy(); +}; + +// Bind the FBO +inline void FrameBufferObject::bind(uint position) const { + assert(mFrameBufferID != 0); + glBindFramebuffer(GL_FRAMEBUFFER, mFrameBufferID); + glDrawBuffer(position); + glReadBuffer(position); +} + +// Unbind the FBO +inline void FrameBufferObject::unbind() const { + assert(mFrameBufferID != 0); + glDrawBuffer(GL_NONE); + glReadBuffer(GL_NONE); + glBindFramebuffer(GL_FRAMEBUFFER, 0); +} + +// Return true if the needed OpenGL extensions are available for FBO +inline bool FrameBufferObject::checkOpenGLExtensions() { + + // Check that OpenGL version is at least 3.0 or there the framebuffer object extension exists + return (GLEW_VERSION_3_0 || GLEW_ARB_framebuffer_object); +} + +} + +#endif diff --git a/testbed/opengl-framework/src/Light.cpp b/testbed/opengl-framework/src/Light.cpp new file mode 100644 index 00000000..cd1831eb --- /dev/null +++ b/testbed/opengl-framework/src/Light.cpp @@ -0,0 +1,100 @@ +/******************************************************************************** +* OpenGL-Framework * +* Copyright (c) 2013 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Libraries +#include "Light.h" + +// Namespaces +using namespace openglframework; + +// Constructor +Light::Light(GLuint id) + : mLightID(id), mDiffuseColor(Color::white()), + mSpecularColor(Color::white()), mIsActive(false) { + +} + +// Constructor +Light::Light(GLuint id, Color diffuseColor, Color specularColor) + : mLightID(id), mDiffuseColor(diffuseColor), + mSpecularColor(specularColor), mIsActive(false) { + +} + +// Destructor +Light::~Light() { + +} + +// Initialize the light +void Light::init() { + + // Enable the light + enable(); + + // Set the diffuse and specular color + GLfloat diffuseColor[] = {mDiffuseColor.r, mDiffuseColor.g, mDiffuseColor.b, mDiffuseColor.a}; + GLfloat specularColor[] = {mSpecularColor.r,mSpecularColor.g,mSpecularColor.b,mSpecularColor.a}; + glLightfv(mLightID, GL_DIFFUSE, diffuseColor); + glLightfv(mLightID, GL_SPECULAR, specularColor); +} + +// Create a shadow map associated with this light +bool Light::createShadowMap(uint width, uint height) { + + // Destroy the current shadow map + destroyShadowMap(); + + // Create the Framebuffer object to render the shadow map + bool isFBOCreated = mFBOShadowMap.create(width, height, false); + if (!isFBOCreated) { + std::cerr << "Error : Cannot create the Shadow Map !" << std::endl; + destroyShadowMap(); + return false; + } + + // Bind the Framebuffer object + mFBOShadowMap.bind(GL_NONE); + + // Create the shadow map depth texture + mShadowMap.create(width, height, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE); + + // Attache the shadow map texture to the Framebuffer object + mFBOShadowMap.attachTexture(GL_DEPTH_ATTACHMENT_EXT, mShadowMap.getID()); + + // Unbind the Framebuffer object + mFBOShadowMap.unbind(); + + // TODO : Change the path of the shader here so that it does not depend on the build folder + bool isShaderCreated = mDepthShader.create("../../opengl-framework/src/shaders/depth.vert", + "../../opengl-framework/src/shaders/depth.vert"); + if (!isShaderCreated) { + std::cerr << "Error : Cannot create the Shadow Map !" << std::endl; + destroyShadowMap(); + return false; + } + + return true; +} diff --git a/testbed/opengl-framework/src/Light.h b/testbed/opengl-framework/src/Light.h new file mode 100644 index 00000000..8f8323d9 --- /dev/null +++ b/testbed/opengl-framework/src/Light.h @@ -0,0 +1,181 @@ +/******************************************************************************** +* OpenGL-Framework * +* Copyright (c) 2013 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +#ifndef LIGHT_H +#define LIGHT_H + +// Libraries +#include "maths/Color.h" +#include "maths/Vector3.h" +#include "Object3D.h" +#include "Texture2D.h" +#include "FrameBufferObject.h" +#include "Shader.h" +#include + +namespace openglframework { + +// Class Light +class Light : public Object3D { + + private: + + // -------------------- Attributes -------------------- // + + // OpenGL light ID + GLuint mLightID; + + // Diffuse color of the light + Color mDiffuseColor; + + // Specular color of the light + Color mSpecularColor; + + // True if the light is active + bool mIsActive; + + // Shadow map associated with this light + Texture2D mShadowMap; + + // Framebuffer object to render the shadow map + FrameBufferObject mFBOShadowMap; + + // Shader to render the depth of the scene into a texture + Shader mDepthShader; + + public: + + // -------------------- Methods -------------------- // + + // Constructor + Light(GLuint id); + + // Constructor + Light(GLuint id, Color diffuseColor, Color specularColor); + + // Destructor + virtual ~Light(); + + // Return the diffuse color + Color getDiffuseColor() const; + + // Set the diffuse color + void setDiffuseColor(const Color& color); + + // Return the specular color + Color getSpecularColor() const; + + // Set the specular color + void setSpecularColor(const Color& color); + + // Return true if the light is active + bool getIsActive() const; + + // Initialize the light + void init(); + + // Enable the light + void enable(); + + // Disable the light + void disable(); + + // Create a shadow map associated with this light + bool createShadowMap(uint width, uint height); + + // Call this method before rendering the scene for the shadow map computation + void startRenderingShadowMap(); + + // Call this method after having rendered the scene for the shadow map computation + void stopRenderingShadowMap(); + + // Destroy the shadow map associated with this light + void destroyShadowMap(); +}; + +// Return the diffuse color +inline Color Light::getDiffuseColor() const { + return mDiffuseColor; +} + +// Set the diffuse color +inline void Light::setDiffuseColor(const Color& color) { + mDiffuseColor = color; +} + +// Return the specular color +inline Color Light::getSpecularColor() const { + return mSpecularColor; +} + +// Set the specular color +inline void Light::setSpecularColor(const Color& color) { + mSpecularColor = color; +} + +// Return true if the light is active +inline bool Light::getIsActive() const { + return mIsActive; +} + +// Enable the light +inline void Light::enable() { + + mIsActive = true; + + // Enable the light + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0 + mLightID); +} + +// Disable the light +inline void Light::disable() { + + mIsActive = false; + + // Disable the light + glDisable(GL_LIGHT0 + mLightID); +} + +// Destroy the shadow map associated with this light +inline void Light::destroyShadowMap() { + mShadowMap.destroy(); + mFBOShadowMap.destroy(); + mDepthShader.destroy(); +} + +// Call this method before rendering the scene for the shadow map computation +inline void Light::startRenderingShadowMap() { + assert(mShadowMap.getID()); +} + +// Call this method after having rendered the scene for the shadow map computation +inline void Light::stopRenderingShadowMap() { + assert(mShadowMap.getID()); +} + +} + +#endif diff --git a/testbed/opengl-framework/src/Mesh.cpp b/testbed/opengl-framework/src/Mesh.cpp new file mode 100644 index 00000000..070c1d07 --- /dev/null +++ b/testbed/opengl-framework/src/Mesh.cpp @@ -0,0 +1,176 @@ +/******************************************************************************** +* OpenGL-Framework * +* Copyright (c) 2013 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Libraries +#include "Mesh.h" + +// Namespaces +using namespace openglframework; +using namespace std; + +// Constructor +Mesh::Mesh() { + +} + +// Destructor +Mesh::~Mesh() { + +} + +// Destroy the mesh +void Mesh::destroy() { + + mVertices.clear(); + mNormals.clear(); + mTangents.clear(); + mIndices.clear(); + mColors.clear(); + mUVs.clear(); + mTextures.clear(); +} + +// Compute the normals of the mesh +void Mesh::calculateNormals() { + + mNormals = vector(getNbVertices(), Vector3(0, 0, 0)); + + // For each triangular face + for (uint i=0; i(getNbVertices(), Vector3(0, 0, 0)); + + // For each face + for (uint i=0; i::const_iterator it(mVertices.begin()); + + // For each vertex of the mesh + for (; it != mVertices.end(); ++it) { + + if( (*it).x < min.x ) min.x = (*it).x; + else if ( (*it).x > max.x ) max.x = (*it).x; + + if( (*it).y < min.y ) min.y = (*it).y; + else if ( (*it).y > max.y ) max.y = (*it).y; + + if( (*it).z < min.z ) min.z = (*it).z; + else if ( (*it).z > max.z ) max.z = (*it).z; + } + } + else { + std::cerr << "Error : Impossible to calculate the bounding box of the mesh because there" << + "are no vertices !" << std::endl; + assert(false); + } +} + +// Scale of vertices of the mesh using a given factor +void Mesh::scaleVertices(float factor) { + + // For each vertex + for (uint i=0; i +#include +#include +#include "definitions.h" +#include "maths/Vector2.h" +#include "maths/Vector3.h" +#include "maths/Color.h" +#include "Texture2D.h" +#include "Object3D.h" + +namespace openglframework { + +// Class Mesh +// This class represents a 3D triangular mesh +// object that can be loaded from an OBJ file for instance. +class Mesh : public Object3D { + + protected: + + // -------------------- Attributes -------------------- // + + // A triplet of vertex indices for each triangle + std::vector > mIndices; + + // Vertices coordinates (local space) + std::vector mVertices; + + // Normals coordinates + std::vector mNormals; + + // Tangents coordinates + std::vector mTangents; + + // Color for each vertex + std::vector mColors; + + // UV texture coordinates + std::vector mUVs; + + // Textures of the mesh (one for each part of the mesh) + std::map mTextures; + + public: + + // -------------------- Methods -------------------- // + + // Constructor + Mesh(); + + // Destructor + virtual ~Mesh(); + + // Destroy the mesh + void destroy(); + + // Compute the normals of the mesh + void calculateNormals(); + + // Compute the tangents of the mesh + void calculateTangents(); + + // Calculate the bounding box of the mesh + void calculateBoundingBox(Vector3& min, Vector3& max) const; + + // Scale of vertices of the mesh using a given factor + void scaleVertices(float factor); + + // Return the number of triangles + uint getNbFaces(uint part = 0) const; + + // Return the number of vertices + uint getNbVertices() const; + + // Return the number of parts in the mesh + uint getNbParts() const; + + // Return a reference to the vertices + const std::vector& getVertices() const; + + // Set the vertices of the mesh + void setVertices(std::vector& vertices); + + // Return a reference to the normals + const std::vector& getNormals() const; + + // set the normals of the mesh + void setNormals(std::vector& normals); + + // Return a reference to the UVs + const std::vector& getUVs() const; + + // Set the UV texture coordinates of the mesh + void setUVs(std::vector& uvs); + + // Return a reference to the vertex indices + const std::vector& getIndices(uint part = 0) const; + + // Set the vertices indices of the mesh + void setIndices(std::vector >& indices); + + // Return the coordinates of a given vertex + const Vector3& getVertex(uint i) const; + + // Set the coordinates of a given vertex + void setVertex(uint i, const Vector3& vertex); + + // Return the coordinates of a given normal + const Vector3& getNormal(uint i) const; + + // Set the coordinates of a given normal + void setNormal(uint i, const Vector3& normal); + + // Return the color of a given vertex + const Color& getColor(uint i) const; + + // Set the color of a given vertex + void setColor(uint i, const Color& color); + + // Set a color to all the vertices + void setColorToAllVertices(const Color& color); + + // Return the UV of a given vertex + const Vector2& getUV(uint i) const; + + // Set the UV of a given vertex + void setUV(uint i, const Vector2& uv); + + // Return the vertex index of the ith (i=0,1,2) vertex of a given face + uint getVertexIndexInFace(uint faceIndex, uint i, uint part = 0) const; + + // Return true if the mesh has normals + bool hasNormals() const; + + // Return true if the mesh has tangents + bool hasTangents() const; + + // Return true if the mesh has vertex colors + bool hasColors() const; + + // Return true if the mesh has UV texture coordinates + bool hasUVTextureCoordinates() const; + + // Return true if the mesh has a texture for a given part of the mesh and if it + // also have texture coordinates + bool hasTextureForPart(uint part = 0) const; + + // Return true if the mesh has a texture (and texture coordinates) for at least one + // part of the mesh + bool hasTexture() const; + + // Return a pointer to the vertices data + void* getVerticesPointer(); + + // Return a pointer to the normals data + void* getNormalsPointer(); + + // Return a pointer to the colors data + void* getColorsPointer(); + + // Return a pointer to the tangents data + void* getTangentsPointer(); + + // Return a pointer to the UV texture coordinates data + void* getUVTextureCoordinatesPointer(); + + // Return a pointer to the vertex indicies data + void* getIndicesPointer(uint part = 0); + + // Return a reference to a texture of the mesh + Texture2D &getTexture(uint part = 0); + + // Set a texture to a part of the mesh + void setTexture(Texture2D &texture, uint part = 0); +}; + +// Return the number of triangles +inline uint Mesh::getNbFaces(uint part) const { + return mIndices[part].size() / 3; +} + +// Return the number of vertices +inline uint Mesh::getNbVertices() const { + return mVertices.size(); +} + +// Return the number of parts in the mesh +inline uint Mesh::getNbParts() const { + return mIndices.size(); +} + +// Return a reference to the vertices +inline const std::vector& Mesh::getVertices() const { + return mVertices; +} + +// Set the vertices of the mesh +inline void Mesh::setVertices(std::vector& vertices) { + mVertices = vertices; +} + +// Return a reference to the normals +inline const std::vector& Mesh::getNormals() const { + return mNormals; +} + +// set the normals of the mesh +inline void Mesh::setNormals(std::vector& normals) { + mNormals = normals; +} + +// Return a reference to the UVs +inline const std::vector& Mesh::getUVs() const { + return mUVs; +} + +// Set the UV texture coordinates of the mesh +inline void Mesh::setUVs(std::vector& uvs) { + mUVs = uvs; +} + +// Return a reference to the vertex indices +inline const std::vector& Mesh::getIndices(uint part) const { + return mIndices[part]; +} + +// Set the vertices indices of the mesh +inline void Mesh::setIndices(std::vector >& indices) { + mIndices = indices; +} + +// Return the coordinates of a given vertex +inline const Vector3& Mesh::getVertex(uint i) const { + assert(i < getNbVertices()); + return mVertices[i]; +} + +// Set the coordinates of a given vertex +inline void Mesh::setVertex(uint i, const Vector3& vertex) { + assert(i < getNbVertices()); + mVertices[i] = vertex; +} + +// Return the coordinates of a given normal +inline const Vector3& Mesh::getNormal(uint i) const { + assert(i < getNbVertices()); + return mNormals[i]; +} + +// Set the coordinates of a given normal +inline void Mesh::setNormal(uint i, const Vector3& normal) { + assert(i < getNbVertices()); + mNormals[i] = normal; +} + +// Return the color of a given vertex +inline const Color& Mesh::getColor(uint i) const { + assert(i < getNbVertices()); + return mColors[i]; +} + +// Set the color of a given vertex +inline void Mesh::setColor(uint i, const Color& color) { + + // If the color array does not have the same size as + // the vertices array + if (mColors.size() != mVertices.size()) { + + // Create the color array with the same size + mColors = std::vector(mVertices.size()); + } + + mColors[i] = color; +} + +// Set a color to all the vertices +inline void Mesh::setColorToAllVertices(const Color& color) { + + // If the color array does not have the same size as + // the vertices array + if (mColors.size() != mVertices.size()) { + + // Create the color array with the same size + mColors = std::vector(mVertices.size()); + } + + for (size_t v=0; v 0); +} + +// Return a pointer to the vertices data +inline void* Mesh::getVerticesPointer() { + return &(mVertices[0]); +} + +// Return a pointer to the normals data +inline void* Mesh::getNormalsPointer() { + return &(mNormals[0]); +} + +// Return a pointer to the colors data +inline void* Mesh::getColorsPointer() { + return &(mColors[0]); +} + +// Return a pointer to the tangents data +inline void* Mesh::getTangentsPointer() { + return &(mTangents[0]); +} + +// Return a pointer to the UV texture coordinates data +inline void* Mesh::getUVTextureCoordinatesPointer() { + return &(mUVs[0]); +} + +// Return a pointer to the vertex indicies data +inline void* Mesh::getIndicesPointer(uint part) { + return &(mIndices[part])[0]; +} + +// Return a reference to a texture of the mesh +inline Texture2D& Mesh::getTexture(uint part) { + return mTextures[part]; +} + +// Set a texture to a part of the mesh +inline void Mesh::setTexture(Texture2D& texture, uint part) { + mTextures[part] = texture; +} + +} + +#endif diff --git a/testbed/opengl-framework/src/MeshReaderWriter.cpp b/testbed/opengl-framework/src/MeshReaderWriter.cpp new file mode 100644 index 00000000..275226ae --- /dev/null +++ b/testbed/opengl-framework/src/MeshReaderWriter.cpp @@ -0,0 +1,393 @@ +/******************************************************************************** +* OpenGL-Framework * +* Copyright (c) 2013 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Libraries +#include "MeshReaderWriter.h" +#include +#include +#include +#include +#include +#include + +using namespace openglframework; +using namespace std; + +// Constructor +MeshReaderWriter::MeshReaderWriter() { + +} + +// Load a mesh from a file and returns true if the mesh has been sucessfully loaded +void MeshReaderWriter::loadMeshFromFile(const std::string& filename, Mesh& meshToCreate) { + + // Get the extension of the file + uint startPosExtension = filename.find_last_of("."); + string extension = filename.substr(startPosExtension+1); + + // Load the file using the correct method + if (extension == "obj") { + loadOBJFile(filename, meshToCreate); + } + else { + + // Display an error message and throw an exception + string errorMessage("Error : the MeshReaderWriter class cannot load a file with the extension ."); + errorMessage += extension; + std::cerr << errorMessage << std::endl; + throw std::invalid_argument(errorMessage.c_str()); + } +} + +// Write a mesh to a file +void MeshReaderWriter::writeMeshToFile(const std::string& filename, const Mesh& meshToWrite) { + + // Get the extension of the file + uint startPosExtension = filename.find_last_of("."); + string extension = filename.substr(startPosExtension+1); + + // Load the file using the correct method + if (extension == "obj") { + writeOBJFile(filename, meshToWrite); + } + else { + + // Display an error message and throw an exception + string errorMessage("Error : the MeshReaderWriter class cannot store a mesh file with the extension ."); + errorMessage += extension; + std::cerr << errorMessage << std::endl; + throw std::invalid_argument(errorMessage.c_str()); + } +} + +// Load an OBJ file with a triangular or quad mesh +void MeshReaderWriter::loadOBJFile(const string &filename, Mesh& meshToCreate) { + + // Open the file + std::ifstream meshFile(filename.c_str()); + + // If we cannot open the file + if(!meshFile.is_open()) { + + // Throw an exception and display an error message + string errorMessage("Error : Cannot open the file " + filename); + std::cerr << errorMessage << std::endl; + throw runtime_error(errorMessage); + } + + std::string buffer; + string line, tmp; + int id1, id2, id3, id4; + int nId1, nId2, nId3, nId4; + int tId1, tId2, tId3, tId4; + float v1, v2, v3; + size_t found1, found2; + std::vector isQuad; + std::vector vertices; + std::vector normals; + std::vector uvs; + std::vector verticesIndices; + std::vector normalsIndices; + std::vector uvsIndices; + + // ---------- Collect the data from the file ---------- // + + // For each line of the file + while(std::getline(meshFile, buffer)) { + + std::istringstream lineStream(buffer); + std::string word; + lineStream >> word; + std::transform(word.begin(), word.end(), word.begin(), ::tolower); + if(word == "usemtl") { // Material definition + + // Loading of MTL file is not implemented + + } + else if(word == "v") { // Vertex position + sscanf(buffer.c_str(), "%*s %f %f %f", &v1, &v2, &v3); + vertices.push_back(Vector3(v1, v2, v3)); + } + else if(word == "vt") { // Vertex texture coordinate + sscanf(buffer.c_str(), "%*s %f %f", &v1, &v2); + uvs.push_back(Vector2(v1,v2)); + } + else if(word == "vn") { // Vertex normal + sscanf(buffer.c_str(), "%*s %f %f %f", &v1, &v2, &v3); + normals.push_back(Vector3(v1 ,v2, v3)); + } + else if (word == "f") { // Face + line = buffer; + found1 = (int)line.find("/"); + bool isFaceQuad = false; + int foundNext = (int)line.substr(found1+1).find("/"); + + // If the face definition is of the form "f v1 v2 v3 v4" + if(found1 == string::npos) { + int nbVertices = sscanf(buffer.c_str(), "%*s %d %d %d %d", &id1, &id2, &id3, &id4); + if (nbVertices == 4) isFaceQuad = true; + } + // If the face definition is of the form "f v1// v2// v3// v4//" + else if (foundNext == 0) { + int nbVertices = sscanf(buffer.c_str(), "%*s %d// %d// %d// %d//", &id1, &id2, &id3, &id4); + if (nbVertices == 4) isFaceQuad = true; + } + else { // If the face definition contains vertices and texture coordinates + + //get the part of the string until the second index + tmp = line.substr(found1+1); + found2 = (int)tmp.find(" "); + tmp = tmp.substr(0,found2); + found2 = (int)tmp.find("/"); + + // If the face definition is of the form "f vert1/textcoord1 vert2/textcoord2 ..." + if(found2 == string::npos) { + int n = sscanf(buffer.c_str(), "%*s %d/%d %d/%d %d/%d %d/%d", &id1, &tId1, &id2, &tId2, &id3, &tId3, &id4, &tId4); + if (n == 8) isFaceQuad = true; + uvsIndices.push_back(tId1-1); + uvsIndices.push_back(tId2-1); + uvsIndices.push_back(tId3-1); + if (isFaceQuad) uvsIndices.push_back(tId4-1); + } + else { + tmp = line.substr(found1+1); + found2 = (int)tmp.find("/"); + + // If the face definition is of the form "f vert1/normal1 vert2/normal2 ..." + if(found2 == 0) { + int n = sscanf(buffer.c_str(), "%*s %d//%d %d//%d %d//%d %d//%d", &id1, &nId1, &id2, &nId2, &id3, &nId3, &id4, &nId4); + if (n == 8) isFaceQuad = true; + } + // If the face definition is of the form "f vert1/textcoord1/normal1 ..." + else { + int n = sscanf(buffer.c_str(), "%*s %d/%d/%d %d/%d/%d %d/%d/%d %d/%d/%d", &id1, &tId1, &nId1, &id2, &tId2, &nId2, &id3, &tId3, &nId3, &id4, &tId4, &nId4); + if (n == 12) isFaceQuad = true; + uvsIndices.push_back(tId1-1); + uvsIndices.push_back(tId2-1); + uvsIndices.push_back(tId3-1); + if (isFaceQuad) uvsIndices.push_back(tId4-1); + } + normalsIndices.push_back(nId1-1); + normalsIndices.push_back(nId2-1); + normalsIndices.push_back(nId3-1); + if (isFaceQuad) normalsIndices.push_back(nId4-1); + } + } + verticesIndices.push_back(id1-1); + verticesIndices.push_back(id2-1); + verticesIndices.push_back(id3-1); + if (isFaceQuad) verticesIndices.push_back((id4-1)); + isQuad.push_back(isFaceQuad); + } + } + + assert(!verticesIndices.empty()); + assert(normalsIndices.empty() || normalsIndices.size() == verticesIndices.size()); + assert(uvsIndices.empty() || uvsIndices.size() == verticesIndices.size()); + meshFile.close(); + + // ---------- Merge the data that we have collected from the file ---------- // + + // Destroy the current mesh + meshToCreate.destroy(); + + // Mesh data + vector > meshIndices; + vector meshNormals; + if (!normals.empty()) meshNormals = vector(vertices.size(), Vector3(0, 0, 0)); + vector meshUVs; + if (!uvs.empty()) meshUVs = vector(vertices.size(), Vector2(0, 0)); + + // We cannot load mesh with several parts for the moment + uint meshPart = 0; + + // Fill in the vertex indices + // We also triangulate each quad face + meshIndices.push_back(std::vector()); + for(size_t i = 0, j = 0; i < verticesIndices.size(); j++) { + + // Get the current vertex IDs + uint i1 = verticesIndices[i]; + uint i2 = verticesIndices[i+1]; + uint i3 = verticesIndices[i+2]; + + // Add the vertex normal + if (!normalsIndices.empty() && !normals.empty()) { + meshNormals[i1] = normals[normalsIndices[i]]; + meshNormals[i2] = normals[normalsIndices[i+1]]; + meshNormals[i3] = normals[normalsIndices[i+2]]; + } + + // Add the vertex UV texture coordinates + if (!uvsIndices.empty() && !uvs.empty()) { + meshUVs[i1] = uvs[uvsIndices[i]]; + meshUVs[i2] = uvs[uvsIndices[i+1]]; + meshUVs[i3] = uvs[uvsIndices[i+2]]; + } + + // If the current vertex not in a quad (it is part of a triangle) + if (!isQuad[j]) { + + // Add the vertex indices + meshIndices[meshPart].push_back(i1); + meshIndices[meshPart].push_back(i2); + meshIndices[meshPart].push_back(i3); + + i+=3; + } + else { // If the current vertex is in a quad + + Vector3 v1 = vertices[i1]; + Vector3 v2 = vertices[i2]; + Vector3 v3 = vertices[i3]; + uint i4 = verticesIndices[i+3]; + Vector3 v4 = vertices[i4]; + + Vector3 v13 = v3-v1; + Vector3 v12 = v2-v1; + Vector3 v14 = v4-v1; + + float a1 = v13.dot(v12); + float a2 = v13.dot(v14); + if((a1 >= 0 && a2 <= 0) || (a1 <= 0 && a2 >= 0)) { + meshIndices[meshPart].push_back(i1); + meshIndices[meshPart].push_back(i2); + meshIndices[meshPart].push_back(i3); + meshIndices[meshPart].push_back(i1); + meshIndices[meshPart].push_back(i3); + meshIndices[meshPart].push_back(i4); + } + else { + meshIndices[meshPart].push_back(i1); + meshIndices[meshPart].push_back(i2); + meshIndices[meshPart].push_back(i4); + meshIndices[meshPart].push_back(i2); + meshIndices[meshPart].push_back(i3); + meshIndices[meshPart].push_back(i4); + } + + // Add the vertex normal + if (!normalsIndices.empty() && !normals.empty()) { + meshNormals[i4] = normals[normalsIndices[i]]; + } + + // Add the vertex UV texture coordinates + if (!uvsIndices.empty() && !uvs.empty()) { + meshUVs[i4] = uvs[uvsIndices[i]]; + } + + i+=4; + } + } + + assert(meshNormals.empty() || meshNormals.size() == vertices.size()); + assert(meshUVs.empty() || meshUVs.size() == vertices.size()); + + // Set the data to the mesh + meshToCreate.setIndices(meshIndices); + meshToCreate.setVertices(vertices); + meshToCreate.setNormals(meshNormals); + meshToCreate.setUVs(meshUVs); +} + +// Store a mesh into a OBJ file +void MeshReaderWriter::writeOBJFile(const std::string& filename, const Mesh& meshToWrite) { + std::ofstream file(filename.c_str()); + + // Geth the mesh data + const std::vector& vertices = meshToWrite.getVertices(); + const std::vector& normals = meshToWrite.getNormals(); + const std::vector& uvs = meshToWrite.getUVs(); + + // If we can open the file + if (file.is_open()) { + + assert(meshToWrite.getNbVertices() == vertices.size()); + + // Write the vertices + for (uint v=0; v& indices = meshToWrite.getIndices(p); + + // For each index of the part + for (uint i=0; i +#include +#include "Mesh.h" + +namespace openglframework { + +// Class MeshReaderWriter +// This class is used to read or write any mesh file in order to +// create the corresponding Mesh object. Currently, this class +// is able to read meshes of the current formats : .obj +class MeshReaderWriter { + + private : + + // -------------------- Methods -------------------- // + + // Constructor (private because we do not want instances of this class) + MeshReaderWriter(); + + // Load an OBJ file with a triangular or quad mesh + static void loadOBJFile(const std::string& filename, Mesh& meshToCreate); + + // Store a mesh into a OBJ file + static void writeOBJFile(const std::string& filename, const Mesh &meshToWrite); + + public : + + // -------------------- Methods -------------------- // + + // Read a mesh from a file + static void loadMeshFromFile(const std::string& filename, Mesh& meshToCreate); + + // Write a mesh to a file + static void writeMeshToFile(const std::string& filename, const Mesh& meshToWrite); +}; + +// Class VertexMergingData +// This class is used in the method to read a mesh +class VertexMergingData { + + public: + VertexMergingData() : indexPosition(0), indexNormal(0), indexUV(0) {} + unsigned int indexPosition; + unsigned int indexNormal; + unsigned int indexUV; +}; + +// Class VertexMergingDataComparison +// This class is used in the method to read a mesh +class VertexMergingDataComparison { + + public: + bool operator()(const VertexMergingData& x, const VertexMergingData& y) const { + if(x.indexPosition < y.indexPosition) + return true; + if(x.indexPosition == y.indexPosition && x.indexNormal < y.indexNormal) + return true; + if(x.indexPosition == y.indexPosition && x.indexNormal == + y.indexNormal && x.indexUV < y.indexUV) + return true; + return false; + } +}; + +} + +#endif diff --git a/testbed/opengl-framework/src/Object3D.cpp b/testbed/opengl-framework/src/Object3D.cpp new file mode 100644 index 00000000..6beb8d28 --- /dev/null +++ b/testbed/opengl-framework/src/Object3D.cpp @@ -0,0 +1,41 @@ +/******************************************************************************** +* OpenGL-Framework * +* Copyright (c) 2013 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Libraries +#include "Object3D.h" + +// Namespaces +using namespace openglframework; + +// Constructor +Object3D::Object3D() { + // Set the transformation matrix to the identity + setToIdentity(); +} + +// Destructor +Object3D::~Object3D() { + +} diff --git a/testbed/opengl-framework/src/Object3D.h b/testbed/opengl-framework/src/Object3D.h new file mode 100644 index 00000000..24c28fa1 --- /dev/null +++ b/testbed/opengl-framework/src/Object3D.h @@ -0,0 +1,149 @@ +/******************************************************************************** +* OpenGL-Framework * +* Copyright (c) 2013 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +#ifndef OBJECT3D_H +#define OBJECT3D_H + +// Libraries +#include "maths/Vector3.h" +#include "maths/Matrix4.h" + +namespace openglframework { + +// Class Object3D +// This class represent a generic 3D object on the scene. +class Object3D { + + protected: + + // -------------------- Attributes -------------------- // + + // Transformation matrix that convert local-space + // coordinates to world-space coordinates + Matrix4 mTransformMatrix; + + public: + + // -------------------- Methods -------------------- // + + // Constructor + Object3D(); + + // Destructor + virtual ~Object3D(); + + // Return the transform matrix + const Matrix4& getTransformMatrix() const; + + // Set the transform matrix + void setTransformMatrix(const Matrix4& matrix); + + // Set to the identity transform + void setToIdentity(); + + // Return the origin of object in world-space + Vector3 getOrigin() const; + + // Translate the object in world-space + void translateWorld(const Vector3& v); + + // Translate the object in local-space + void translateLocal(const Vector3& v); + + // Rotate the object in world-space + void rotateWorld(const Vector3& axis, float angle); + + // Rotate the object in local-space + void rotateLocal(const Vector3& axis, float angle); + + // Rotate around a world-space point + void rotateAroundWorldPoint(const Vector3& axis, float angle, const Vector3& point); + + // Rotate around a local-space point + void rotateAroundLocalPoint(const Vector3& axis, float angle, const Vector3& worldPoint); +}; + +// Return the transform matrix +inline const Matrix4& Object3D::getTransformMatrix() const { + return mTransformMatrix; +} + +// Set the transform matrix +inline void Object3D::setTransformMatrix(const Matrix4& matrix) { + mTransformMatrix = matrix; +} + +// Set to the identity transform +inline void Object3D::setToIdentity() { + mTransformMatrix.setToIdentity(); +} + + // Return the origin of object in world-space +inline Vector3 Object3D::getOrigin() const { + return mTransformMatrix * Vector3(0.0, 0.0, 0.0); +} + +// Translate the object in world-space +inline void Object3D::translateWorld(const Vector3& v) { + mTransformMatrix = Matrix4::translationMatrix(v) * mTransformMatrix; +} + +// Translate the object in local-space +inline void Object3D::translateLocal(const Vector3& v) { + mTransformMatrix = mTransformMatrix * Matrix4::translationMatrix(v); +} + +// Rotate the object in world-space +inline void Object3D::rotateWorld(const Vector3& axis, float angle) { + mTransformMatrix = Matrix4::rotationMatrix(axis, angle) * mTransformMatrix; +} + +// Rotate the object in local-space +inline void Object3D::rotateLocal(const Vector3& axis, float angle) { + mTransformMatrix = mTransformMatrix * Matrix4::rotationMatrix(axis, angle); +} + +// Rotate the object around a world-space point +inline void Object3D::rotateAroundWorldPoint(const Vector3& axis, float angle, + const Vector3& worldPoint) { + mTransformMatrix = Matrix4::translationMatrix(worldPoint) * Matrix4::rotationMatrix(axis, angle) + * Matrix4::translationMatrix(-worldPoint) * mTransformMatrix; +} + +// Rotate the object around a local-space point +inline void Object3D::rotateAroundLocalPoint(const Vector3& axis, float angle, + const Vector3& worldPoint) { + + // Convert the world point into the local coordinate system + Vector3 localPoint = mTransformMatrix.getInverse() * worldPoint; + + mTransformMatrix = mTransformMatrix * Matrix4::translationMatrix(localPoint) + * Matrix4::rotationMatrix(axis, angle) + * Matrix4::translationMatrix(-localPoint); +} + +} + +#endif diff --git a/testbed/opengl-framework/src/Shader.cpp b/testbed/opengl-framework/src/Shader.cpp new file mode 100644 index 00000000..137669f7 --- /dev/null +++ b/testbed/opengl-framework/src/Shader.cpp @@ -0,0 +1,206 @@ +/******************************************************************************** +* OpenGL-Framework * +* Copyright (c) 2013 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Libraries +#include "Shader.h" +#include +#include +#include + +// Namespaces +using namespace openglframework; +using namespace std; + +// Constructor +Shader::Shader() : mProgramObjectID(0) { + +} + +// Constructor with arguments +Shader::Shader(const std::string vertexShaderFilename, const std::string fragmentShaderFilename) + : mProgramObjectID(0) { + + // Create the shader + create(vertexShaderFilename, fragmentShaderFilename); +} + +// Destructor +Shader::~Shader() { + +} + +// Create the shader +bool Shader::create(const std::string vertexShaderFilename, + const std::string fragmentShaderFilename) { + + // Set the shader filenames + mFilenameVertexShader = vertexShaderFilename; + mFilenameFragmentShader = fragmentShaderFilename; + + // Check that the needed OpenGL extensions are available + bool isExtensionOK = checkOpenGLExtensions(); + if (!isExtensionOK) { + cerr << "Error : Impossible to use GLSL vertex or fragment shaders on this platform" << endl; + assert(false); + return false; + } + + // Delete the current shader + destroy(); + + assert(!vertexShaderFilename.empty() && !fragmentShaderFilename.empty()); + + // ------------------- Load the vertex shader ------------------- // + GLuint vertexShaderID; + std::ifstream fileVertexShader; + fileVertexShader.open(vertexShaderFilename.c_str(), std::ios::binary); + + if (fileVertexShader.is_open()) { + + // Get the size of the file + fileVertexShader.seekg(0, std::ios::end); + uint fileSize = (uint) (fileVertexShader.tellg()); + assert(fileSize != 0); + + // Read the file + fileVertexShader.seekg(std::ios::beg); + char* bufferVertexShader = new char[fileSize + 1]; + fileVertexShader.read(bufferVertexShader, fileSize); + fileVertexShader.close(); + bufferVertexShader[fileSize] = '\0'; + + // Create the OpenGL vertex shader and compile it + vertexShaderID = glCreateShader(GL_VERTEX_SHADER); + assert(vertexShaderID != 0); + glShaderSource(vertexShaderID, 1, (const char **) (&bufferVertexShader), NULL); + glCompileShader(vertexShaderID); + delete[] bufferVertexShader; + + // Get the compilation information + int compiled; + glGetShaderiv(vertexShaderID, GL_COMPILE_STATUS, &compiled); + + // If the compilation failed + if (compiled == 0) { + + // Get the log of the compilation + int lengthLog; + glGetShaderiv(vertexShaderID, GL_INFO_LOG_LENGTH, &lengthLog); + char* str = new char[lengthLog]; + glGetShaderInfoLog(vertexShaderID, lengthLog, NULL, str); + + // Display the log of the compilation + std::cerr << "Vertex Shader Error : " << str << std::endl; + delete[] str; + assert(false); + return false; + } + } + else { + std::cerr << "Error : Impossible to open the vertex shader file " << + vertexShaderFilename << std::endl; + assert(false); + return false; + } + + // ------------------- Load the fragment shader ------------------- // + GLuint fragmentShaderID; + std::ifstream fileFragmentShader; + fileFragmentShader.open(fragmentShaderFilename.c_str(), std::ios::binary); + + if (fileFragmentShader.is_open()) { + + // Get the size of the file + fileFragmentShader.seekg(0, std::ios::end); + uint fileSize = (uint) (fileFragmentShader.tellg()); + assert(fileSize != 0); + + // Read the file + fileFragmentShader.seekg(std::ios::beg); + char* bufferFragmentShader = new char[fileSize + 1]; + fileFragmentShader.read(bufferFragmentShader, fileSize); + fileFragmentShader.close(); + bufferFragmentShader[fileSize] = '\0'; + + // Create the OpenGL fragment shader and compile it + fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); + assert(fragmentShaderID != 0); + glShaderSource(fragmentShaderID, 1, (const char **) (&bufferFragmentShader), NULL); + glCompileShader(fragmentShaderID); + delete[] bufferFragmentShader; + + // Get the compilation information + int compiled; + glGetShaderiv(fragmentShaderID, GL_COMPILE_STATUS, &compiled); + + // If the compilation failed + if (compiled == 0) { + + // Get the log of the compilation + int lengthLog; + glGetShaderiv(fragmentShaderID, GL_INFO_LOG_LENGTH, &lengthLog); + char* str = new char[lengthLog]; + glGetShaderInfoLog(fragmentShaderID, lengthLog, NULL, str); + + // Display the log of the compilation + std::cerr << "Fragment Shader Error : " << str << std::endl; + delete[] str; + assert(false); + return false; + } + } + else { + std::cerr << "Error : Impossible to open the fragment shader file " << + fragmentShaderFilename << std::endl; + assert(false); + return false; + } + + // Create the shader program and attach the shaders + mProgramObjectID = glCreateProgram(); + assert(mProgramObjectID); + glAttachShader(mProgramObjectID, vertexShaderID); + glAttachShader(mProgramObjectID, fragmentShaderID); + glDeleteShader(vertexShaderID); + glDeleteShader(fragmentShaderID); + + // Try to link the program + glLinkProgram(mProgramObjectID); + int linked; + glGetProgramiv(mProgramObjectID, GL_LINK_STATUS, &linked); + if (!linked) { + int logLength; + glGetProgramiv(mProgramObjectID, GL_INFO_LOG_LENGTH, &logLength); + char* strLog = new char[logLength]; + glGetProgramInfoLog(mProgramObjectID, logLength, NULL, strLog); + cerr << "Linker Error in vertex shader " << vertexShaderFilename << + " or in fragment shader " << fragmentShaderFilename << " : " << strLog << endl; + delete[] strLog; + destroy(); + assert(false); + } + + return true; +} diff --git a/testbed/opengl-framework/src/Shader.h b/testbed/opengl-framework/src/Shader.h new file mode 100644 index 00000000..52a206bc --- /dev/null +++ b/testbed/opengl-framework/src/Shader.h @@ -0,0 +1,260 @@ +/******************************************************************************** +* OpenGL-Framework * +* Copyright (c) 2013 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +#ifndef SHADER_H +#define SHADER_H + +// Libraries +#include "definitions.h" +#include "maths/Matrix4.h" +#include "maths/Vector2.h" +#include "maths/Vector3.h" +#include "maths/Vector4.h" +#include +#include +#include + +namespace openglframework { + +// Class Shader +class Shader { + + private : + + // -------------------- Attributes -------------------- // + + // Shader object program ID + GLuint mProgramObjectID; + + // Filenames of the vertex and fragment shaders + std::string mFilenameVertexShader, mFilenameFragmentShader; + + public : + + // -------------------- Methods -------------------- // + + // Constructor + Shader(); + + // Constructor with arguments + Shader(const std::string vertexShaderFilename, const std::string fragmentShaderFilename); + + // Destructor + ~Shader(); + + // Create the shader + bool create(const std::string vertexShaderFilename, + const std::string fragmentShaderFilename); + + // Clear the shader + void destroy(); + + // Bind the shader + void bind() const; + + // Unbind the shader + void unbind() const; + + // Return the location of a uniform variable inside a shader program + int getUniformLocation(const std::string& variableName) const; + + // Set a float uniform value to this shader (be careful if the uniform is not + // used in the shader, the compiler will remove it, then when you will try + // to set it, an assert will occur) + void setFloatUniform(const std::string& variableName, float value) const; + + // Set an int uniform value to this shader (be careful if the uniform is not + // used in the shader, the compiler will remove it, then when you will try + // to set it, an assert will occur) + void setIntUniform(const std::string& variableName, int value) const; + + // Set a vector 2 uniform value to this shader (be careful if the uniform is not + // used in the shader, the compiler will remove it, then when you will try + // to set it, an assert will occur) + void setVector2Uniform(const std::string& variableName, const Vector2& v) const; + + // Set a vector 3 uniform value to this shader (be careful if the uniform is not + // used in the shader, the compiler will remove it, then when you will try + // to set it, an assert will occur) + void setVector3Uniform(const std::string& variableName, const Vector3& v) const; + + // Set a vector 4 uniform value to this shader (be careful if the uniform is not + // used in the shader, the compiler will remove it, then when you will try + // to set it, an assert will occur) + void setVector4Uniform(const std::string& variableName, const Vector4 &v) const; + + // Set a 3x3 matrix uniform value to this shader (be careful if the uniform is not + // used in the shader, the compiler will remove it, then when you will try + // to set it, an assert will occur) + void setMatrix3x3Uniform(const std::string& variableName, const float* matrix, + bool transpose = false) const; + + // Set a 3x3 matrix uniform value to this shader (be careful if the uniform is not + // used in the shader, the compiler will remove it, then when you will try + // to set it, an assert will occur) + void setMatrix3x3Uniform(const std::string& variableName, const Matrix3& matrix) const; + + // Set a 4x4 matrix uniform value to this shader (be careful if the uniform is not + // used in the shader, the compiler will remove it, then when you will try + // to set it, an assert will occur) + void setMatrix4x4Uniform(const std::string& variableName, const float* matrix, + bool transpose = false) const; + + // Set a 4x4 matrix uniform value to this shader (be careful if the uniform is not + // used in the shader, the compiler will remove it, then when you will try + // to set it, an assert will occur) + void setMatrix4x4Uniform(const std::string& variableName, const Matrix4& matrix) const; + + // Return true if the needed OpenGL extensions are available + static bool checkOpenGLExtensions(); +}; + +// Bind the shader +inline void Shader::bind() const { + assert(mProgramObjectID != 0); + glUseProgram(mProgramObjectID); +} + +// Unbind the shader +inline void Shader::unbind() const { + assert(mProgramObjectID != 0); + glUseProgram(0); +} + +// Return the location of a uniform variable inside a shader program +inline int Shader::getUniformLocation(const std::string& variableName) const { + assert(mProgramObjectID != 0); + int location = glGetUniformLocation(mProgramObjectID, variableName.c_str()); + if (location == -1) { + std::cerr << "Error in vertex shader " << mFilenameVertexShader << " or in fragment shader" + << mFilenameFragmentShader << " : No Uniform variable : " << variableName + << std::endl; + } + assert(location != -1); + return location; +} + +// Clear the shader +inline void Shader::destroy() { + glDeleteProgram(mProgramObjectID); + mProgramObjectID = 0; +} + +// Set a float uniform value to this shader (be careful if the uniform is not +// used in the shader, the compiler will remove it, then when you will try +// to set it, an assert will occur) +inline void Shader::setFloatUniform(const std::string& variableName, float value) const { + assert(mProgramObjectID != 0); + glUniform1f(getUniformLocation(variableName), value); +} + +// Set an int uniform value to this shader (be careful if the uniform is not +// used in the shader, the compiler will remove it, then when you will try +// to set it, an assert will occur) +inline void Shader::setIntUniform(const std::string& variableName, int value) const { + assert(mProgramObjectID != 0); + glUniform1i(getUniformLocation(variableName), value); +} + +// Set a vector 2 uniform value to this shader (be careful if the uniform is not +// used in the shader, the compiler will remove it, then when you will try +// to set it, an assert will occur) +inline void Shader::setVector2Uniform(const std::string& variableName, const Vector2& v) const { + assert(mProgramObjectID != 0); + glUniform2f(getUniformLocation(variableName), v.x, v.y); +} + +// Set a vector 3 uniform value to this shader (be careful if the uniform is not +// used in the shader, the compiler will remove it, then when you will try +// to set it, an assert will occur) +inline void Shader::setVector3Uniform(const std::string& variableName, const Vector3 &v) const { + assert(mProgramObjectID != 0); + glUniform3f(getUniformLocation(variableName), v.x, v.y, v.z); +} + +// Set a vector 4 uniform value to this shader (be careful if the uniform is not +// used in the shader, the compiler will remove it, then when you will try +// to set it, an assert will occur) +inline void Shader::setVector4Uniform(const std::string& variableName, const Vector4& v) const { + assert(mProgramObjectID != 0); + glUniform4f(getUniformLocation(variableName), v.x, v.y, v.z, v.w); +} + +// Set a 4x4 matrix uniform value to this shader (be careful if the uniform is not +// used in the shader, the compiler will remove it, then when you will try +// to set it, an assert will occur) +inline void Shader::setMatrix3x3Uniform(const std::string& variableName, const float* matrix, + bool transpose) const { + assert(mProgramObjectID != 0); + glUniformMatrix3fv(getUniformLocation(variableName), 1, transpose, matrix); +} + +// Set a 3x3 matrix uniform value to this shader (be careful if the uniform is not +// used in the shader, the compiler will remove it, then when you will try +// to set it, an assert will occur) +inline void Shader::setMatrix3x3Uniform(const std::string& variableName, const Matrix3& matrix) const { + assert(mProgramObjectID != 0); + GLfloat mat[9]; + for (int i=0; i<3; i++) { + for (int j=0; j<3; j++) { + mat[i*3 + j] = matrix.getValue(i, j); + } + } + glUniformMatrix3fv(getUniformLocation(variableName), 1, true, mat); +} + +// Set a 4x4 matrix uniform value to this shader (be careful if the uniform is not +// used in the shader, the compiler will remove it, then when you will try +// to set it, an assert will occur) +inline void Shader::setMatrix4x4Uniform(const std::string& variableName, const float* matrix, + bool transpose) const { + assert(mProgramObjectID != 0); + glUniformMatrix4fv(getUniformLocation(variableName), 1, transpose, matrix); +} + +// Set a 4x4 matrix uniform value to this shader (be careful if the uniform is not +// used in the shader, the compiler will remove it, then when you will try +// to set it, an assert will occur) +inline void Shader::setMatrix4x4Uniform(const std::string& variableName, const Matrix4& matrix) const { + assert(mProgramObjectID != 0); + GLfloat mat[16]; + for (int i=0; i<4; i++) { + for (int j=0; j<4; j++) { + mat[i*4 + j] = matrix.m[i][j]; + } + } + glUniformMatrix4fv(getUniformLocation(variableName), 1, true, mat); +} + +// Return true if the needed OpenGL extensions are available for shaders +inline bool Shader::checkOpenGLExtensions() { + + // Check that GLSL vertex and fragment shaders are available on the platform + return (GLEW_VERSION_2_0 || (GLEW_ARB_vertex_shader && GLEW_ARB_fragment_shader)); +} + +} + +#endif diff --git a/testbed/opengl-framework/src/Texture2D.cpp b/testbed/opengl-framework/src/Texture2D.cpp new file mode 100644 index 00000000..1b316b73 --- /dev/null +++ b/testbed/opengl-framework/src/Texture2D.cpp @@ -0,0 +1,84 @@ +/******************************************************************************** +* OpenGL-Framework * +* Copyright (c) 2013 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Libraries +#include "Texture2D.h" +#include +#include +#include + +// Namespaces +using namespace openglframework; + +// Constructor +Texture2D::Texture2D() : mID(0), mLayer(0), mWidth(0), mHeight(0) { + +} + +// Constructor +Texture2D::Texture2D(uint width, uint height, uint internalFormat, uint format, uint type) + : mID(0), mLayer(0), mWidth(0), mHeight(0){ + + // Create the texture + create(width, height, internalFormat, format, type); +} + +// Destructor +Texture2D::~Texture2D() { + +} + +// Create the texture +void Texture2D::create(uint width, uint height, uint internalFormat, uint format, uint type, + void* data) { + + // Destroy the current texture + destroy(); + + mWidth = width; + mHeight = height; + + // Create the OpenGL texture + glGenTextures(1, &mID); + assert(mID != 0); + glBindTexture(GL_TEXTURE_2D, mID); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, mWidth, mHeight, 0, format, type, data); + glBindTexture(GL_TEXTURE_2D, 0); +} + +// Destroy the texture +void Texture2D::destroy() { + if (mID != 0) { + glDeleteTextures(1, &mID); + mID = 0; + mLayer = 0; + mWidth = 0; + mHeight = 0; + } +} diff --git a/testbed/opengl-framework/src/Texture2D.h b/testbed/opengl-framework/src/Texture2D.h new file mode 100644 index 00000000..9c6fa1c0 --- /dev/null +++ b/testbed/opengl-framework/src/Texture2D.h @@ -0,0 +1,142 @@ +/******************************************************************************** +* OpenGL-Framework * +* Copyright (c) 2013 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +#ifndef TEXTURE2D_H +#define TEXTURE2D_H + +// Libraries +#include +#include +#include "definitions.h" +#include + +namespace openglframework { + +// Class Texture2D +// This class represents a 2D texture +class Texture2D { + + private: + + // -------------------- Attributes -------------------- // + + // OpenGL texture ID + GLuint mID; + + // Layer of the texture + GLuint mLayer; + + // Width + uint mWidth; + + // Height + uint mHeight; + + public: + + // -------------------- Methods -------------------- // + + // Constructor + Texture2D(); + + // Constructor + Texture2D(uint width, uint height, uint internalFormat, uint format, uint type); + + // Destructor + ~Texture2D(); + + // Create the texture + void create(uint width, uint height, uint internalFormat, uint format, uint type, + void* data = NULL); + + // Destroy the texture + void destroy(); + + // Bind the texture + void bind() const; + + // Unbind the texture + void unbind() const; + + // Get the OpenGL texture ID + uint getID() const; + + // Get the layer of the texture + uint getLayer() const; + + // Set the layer of the texture + void setLayer(uint layer); + + // Get the width + uint getWidth() const; + + // Get the height + uint getHeight() const; +}; + +// Bind the texture +inline void Texture2D::bind() const { + assert(mID != 0); + glEnable(GL_TEXTURE_2D); + glActiveTexture(GL_TEXTURE0 + mLayer); + glBindTexture(GL_TEXTURE_2D, mID); +} + +// Unbind the texture +inline void Texture2D::unbind() const { + assert(mID != 0); + glActiveTexture(GL_TEXTURE0 + mLayer); + glBindTexture(GL_TEXTURE_2D, 0); + glDisable(GL_TEXTURE_2D); +} + +// Get the OpenGL texture ID +inline uint Texture2D::getID() const { + return mID; +} + +// Get the layer of the texture +inline uint Texture2D::getLayer() const { + return mLayer; +} + +// Set the layer of the texture +inline void Texture2D::setLayer(uint layer) { + mLayer = layer; +} + +// Get the width +inline uint Texture2D::getWidth() const { + return mWidth; +} + +// Get the height +inline uint Texture2D::getHeight() const { + return mHeight; +} + +} + +#endif diff --git a/testbed/opengl-framework/src/TextureReaderWriter.cpp b/testbed/opengl-framework/src/TextureReaderWriter.cpp new file mode 100644 index 00000000..2e09ad0c --- /dev/null +++ b/testbed/opengl-framework/src/TextureReaderWriter.cpp @@ -0,0 +1,332 @@ +/******************************************************************************** +* OpenGL-Framework * +* Copyright (c) 2013 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Librairies +#include "TextureReaderWriter.h" +#include +#ifdef USE_JPEG_TEXTURE + #include + #include +#endif + +using namespace openglframework; +using namespace std; + +// Constants +const uint TextureReaderWriter::JPEG_COMPRESSION_QUALITY = 98; + +// TGA file Header +#pragma pack(push, 1) +typedef struct { + unsigned char identsize; // size of ID field that follows 18 byte header (0 usually) + unsigned char colourmaptype; // type of colour map 0=none, 1=has palette + unsigned char imagetype; // type of image 0=none,1=indexed,2=rgb,3=grey,+8=rle packed + + short colourmapstart; // first colour map entry in palette + short colourmaplength; // number of colours in palette + unsigned char colourmapbits; // number of bits per palette entry 15,16,24,32 + + short xstart; // image x origin + short ystart; // image y origin + short width; // image width in pixels + short height; // image height in pixels + unsigned char bits; // image bits per pixel 8,16,24,32 + unsigned char descriptor; // image descriptor bits (vh flip bits) + + // pixel data follows header +} TGA_HEADER; +#pragma pack(pop) + +// Load a texture from a file +void TextureReaderWriter::loadTextureFromFile(const std::string& filename, + Texture2D& textureToCreate) { + + // Get the extension of the file + uint startPosExtension = filename.find_last_of("."); + string extension = filename.substr(startPosExtension+1); + + // Load the file using the correct method + if (extension == "tga") { + readTGAPicture(filename, textureToCreate); + } +#ifdef USE_JPEG_TEXTURE + else if (extension == "jpg" || extension == "jpeg"){ + readJPEGPicture(filename, textureToCreate); + } +#endif + else { + + // Display an error message and throw an exception + string errorMessage("Error : the TextureLoader class cannot load a file with the extension ."); + errorMessage += extension; + std::cerr << errorMessage << std::endl; + throw std::invalid_argument(errorMessage.c_str()); + } +} + +// Write a texture to a file +void TextureReaderWriter::writeTextureToFile(const std::string& filename,const Texture2D& texture) { + + // Get the extension of the file + uint startPosExtension = filename.find_last_of("."); + string extension = filename.substr(startPosExtension+1); + + // Write the file using the correct method + if (extension == "tga") { + writeTGAPicture(filename, texture); + } +#ifdef USE_JPEG_TEXTURE + else if (extension == "jpg" || extension == "jpeg"){ + writeJPEGPicture(filename, texture); + } +#endif + else { + + // Display an error message and throw an exception + string errorMessage("Error : the TextureReaderWriter class cannot write a file with the extension ."); + errorMessage += extension; + std::cerr << errorMessage << std::endl; + throw std::invalid_argument(errorMessage.c_str()); + } +} + +// Load a TGA picture +void TextureReaderWriter::readTGAPicture(const std::string &filename, Texture2D& textureToCreate) { + + // Open the file + std::ifstream stream(filename.c_str(), std::ios::binary); + + // If we cannot open the file + if(!stream.is_open()) { + + // Throw an exception and display an error message + string errorMessage("Error : Cannot open the file " + filename); + std::cerr << errorMessage << std::endl; + throw std::runtime_error(errorMessage); + } + + TGA_HEADER header; + stream.read((char *)(&header), sizeof(TGA_HEADER)); + assert(header.width <= 4096 && header.width <= 4096 && + header.imagetype == 2 && header.bits == 24); + + // Read the file + uint width = header.width; + uint height = header.width; + uint sizeImg = width*height; + char* data = new char[sizeImg*3]; + assert(data); + stream.read(data, sizeImg*3); + for(uint i = 0; i < sizeImg; i++) { + unsigned pos = i*3; + unsigned char red = data[pos]; + data[pos] = data[pos + 2]; + data[pos + 2] = red; + } + + // Close the stream + stream.close(); + + // Create the OpenGL texture using the picture data from the file + textureToCreate.create(width, height, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, data); + + // Free the data memory + delete[] data; +} + + +// Write a TGA picture +void TextureReaderWriter::writeTGAPicture(const std::string& filename, const Texture2D& texture) { + assert(texture.getID() != 0); + + // Bind the corresponding texture + glBindTexture(GL_TEXTURE_2D, texture.getID()); + + uint sizeImg = texture.getWidth() * texture.getHeight(); + + // Get the bytes form the OpenGL texture + char* data = new char[sizeImg * 3]; + glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, data); + + // Open the file + std::ofstream stream(filename.c_str(), std::ios::binary); + + // If the file cannot be opened + if(!stream.is_open()) { + + // Throw an exception and display an error message + string errorMessage("Error : Cannot create/access the file " + filename); + std::cerr << errorMessage << std::endl; + delete[] data; + throw std::runtime_error(errorMessage); + } + + // Fill in the TGA header + TGA_HEADER header; + header.identsize = 0; // size of ID field that follows 18 byte header (0 usually) + header.colourmaptype = 0; // type of colour map 0=none, 1=has palette + header.imagetype = 2; // type of image 0=none,1=indexed,2=rgb,3=grey,+8=rle packed + header.colourmapstart = 0; // first colour map entry in palette + header.colourmaplength = 0; // number of colours in palette + header.colourmapbits=0; // number of bits per palette entry 15,16,24,32 + header.xstart = 0; // image x origin + header.ystart = 0; // image y origin + header.width = (short)texture.getWidth(); // image width in pixels + header.height = (short)texture.getHeight(); // image height in pixels + header.bits = 24; // image bits per pixel 8,16,24,32 + header.descriptor = 0; // image descriptor bits (vh flip bits) + + // Write the header to the file + stream.write((char*)(&header), sizeof(TGA_HEADER)); + + // Write the bytes to the file + for(uint i = 0; i < sizeImg; i++) { + unsigned pos = i*3; + unsigned char red = data[pos]; + data[pos] = data[pos + 2]; + data[pos + 2] = red; + } + stream.write(data, sizeImg*3); + + // Close the file + stream.close(); + + // Delete the data + delete[] data; + + // Unbind the corresponding texture + glBindTexture(GL_TEXTURE_2D, 0); +} + +#ifdef USE_JPEG_TEXTURE + +// Read a JPEG picture +void TextureReaderWriter::readJPEGPicture(const std::string& filename, Texture2D& textureToCreate) { + + struct jpeg_decompress_struct info; + struct jpeg_error_mgr error; + + info.err = jpeg_std_error(&error); + jpeg_create_decompress(&info); + + // Open the file + FILE* file = fopen(filename.c_str(), "rb"); + + // If we cannot open the file + if (!file) { + + // Throw an exception and display an error message + string errorMessage("Error : Cannot open the file " + filename); + std::cerr << errorMessage << std::endl; + throw std::runtime_error(errorMessage); + } + + jpeg_stdio_src(&info, file); + jpeg_read_header(&info, true); + jpeg_start_decompress(&info); + + unsigned long x = info.output_width; + unsigned long y = info.output_height; + int channels = info.num_components; + assert(channels == 3); + + unsigned long size = x * y * 3; + + BYTE* data = new BYTE[size]; + + BYTE* p1 = data; + BYTE** p2 = &p1; + int numlines = 0; + + while(info.output_scanline < info.output_height) { + numlines = jpeg_read_scanlines(&info, p2, 1); + *p2 += numlines * 3 * info.output_width; + } + + jpeg_finish_decompress(&info); //finish decompressing this file + + // Close the file + fclose(file); + + // Create the OpenGL texture + textureToCreate.create(x, y, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, data); + + // Free allocated memory + delete[] data; +} + +// Write a JPEG picture +void TextureReaderWriter::writeJPEGPicture(const std::string& filename, const Texture2D& texture) { + + struct jpeg_compress_struct info; + struct jpeg_error_mgr error; + + info.err = jpeg_std_error(&error); + jpeg_create_compress(&info); + + // Open the file + FILE* file = fopen(filename.c_str(), "wb"); + + if (!file) { + // Throw an exception and display an error message + string errorMessage("Error : Cannot write JPEG picture into the file " + filename); + std::cerr << errorMessage << std::endl; + throw std::runtime_error(errorMessage); + } + + // Get the bytes form the OpenGL texture + char* data = new char[texture.getWidth() * texture.getHeight() * 3]; + glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, data); + + jpeg_stdio_dest(&info, file); + + info.image_width = texture.getWidth(); + info.image_height = texture.getHeight(); + info.input_components = 3; + info.in_color_space = JCS_RGB; + jpeg_set_defaults(&info); + jpeg_set_quality(&info, JPEG_COMPRESSION_QUALITY, true); + + jpeg_start_compress(&info, true); + + // Write the data into the file + JSAMPROW rowPointer; + int rowStride = texture.getWidth() * 3; + while (info.next_scanline < info.image_height) { + rowPointer = (JSAMPROW) &data[info.next_scanline * rowStride]; + jpeg_write_scanlines(&info, &rowPointer, 1); + } + + jpeg_finish_compress(&info); + jpeg_destroy_compress(&info); + + // Close the file + fclose(file); + + // Free allocated memory + delete[] data; +} + +#endif diff --git a/testbed/opengl-framework/src/TextureReaderWriter.h b/testbed/opengl-framework/src/TextureReaderWriter.h new file mode 100644 index 00000000..a83b9671 --- /dev/null +++ b/testbed/opengl-framework/src/TextureReaderWriter.h @@ -0,0 +1,79 @@ +/******************************************************************************** +* OpenGL-Framework * +* Copyright (c) 2013 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +#ifndef TEXTURE_READER_WRITER_H +#define TEXTURE_READER_WRITER_H + +// Libraries +#include "Texture2D.h" +#include +#include +#include + +namespace openglframework { + +// Class TextureReaderWriter +// This class is used to load or write a texture image in different picture format. +// It currently allows to read and write the following formats : .tga +class TextureReaderWriter { + + private : + + // ------------------- Constants ------------------- // + + // JPEG quality for compression (in percent) + static const uint JPEG_COMPRESSION_QUALITY; + + // -------------------- Methods -------------------- // + + // Constructor (private because we do not want instances of this class) + TextureReaderWriter(); + + // Read a TGA picture + static void readTGAPicture(const std::string& filename, Texture2D& textureToCreate); + + // Write a TGA picture + static void writeTGAPicture(const std::string& filename, const Texture2D& texture); + + // Read a JPEG picture + static void readJPEGPicture(const std::string& filename, Texture2D& textureToCreate); + + // Write a JPEG picture + static void writeJPEGPicture(const std::string& filename, const Texture2D& texture); + + public : + + // -------------------- Methods -------------------- // + + // Load a texture from a file + static void loadTextureFromFile(const std::string& filename, Texture2D& textureToCreate); + + // Write a texture to a file + static void writeTextureToFile(const std::string& filename, const Texture2D& texture); +}; + +} + +#endif diff --git a/testbed/opengl-framework/src/VertexBufferObject.cpp b/testbed/opengl-framework/src/VertexBufferObject.cpp new file mode 100644 index 00000000..8afd1daf --- /dev/null +++ b/testbed/opengl-framework/src/VertexBufferObject.cpp @@ -0,0 +1,84 @@ +/******************************************************************************** +* OpenGL-Framework * +* Copyright (c) 2013 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Libraries +#include "VertexBufferObject.h" + +using namespace openglframework; + +// Constructor +VertexBufferObject::VertexBufferObject(GLenum targetData) + : mVertexBufferID(0), mTargetData(targetData) { + +} + +// Destructor +VertexBufferObject::~VertexBufferObject() { + +} + +// Create the vertex buffer object +bool VertexBufferObject::create() { + + // Destroy the current VBO + destroy(); + + // Check that the needed OpenGL extensions are available + bool isExtensionOK = checkOpenGLExtensions(); + if (!isExtensionOK) { + std::cerr << "Error : Impossible to use Vertex Buffer Object on this platform" << std::endl; + assert(false); + return false; + } + + // Generate a new VBO + glGenBuffers(1, &mVertexBufferID); + assert(mVertexBufferID != 0); + + return true; +} + +// Copy data into the VBO +void VertexBufferObject::copyDataIntoVBO(GLsizei size, const void* data, GLenum usage) { + + // Bind the VBO + bind(); + + // Copy the data into the VBO + glBufferData(mTargetData, size, data, usage); + + // Unbind the VBO + unbind(); +} + +// Destroy the VBO +void VertexBufferObject::destroy() { + + // Delete the vertex buffer object + if (mVertexBufferID) { + glDeleteFramebuffers(1, &mVertexBufferID); + mVertexBufferID = 0; + } +} diff --git a/testbed/opengl-framework/src/VertexBufferObject.h b/testbed/opengl-framework/src/VertexBufferObject.h new file mode 100644 index 00000000..d697c659 --- /dev/null +++ b/testbed/opengl-framework/src/VertexBufferObject.h @@ -0,0 +1,106 @@ +/******************************************************************************** +* OpenGL-Framework * +* Copyright (c) 2013 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +#ifndef VERTEX_BUFFER_OBJECT_H +#define VERTEX_BUFFER_OBJECT_H + +// Libraries +#include +#include +#include + +namespace openglframework { + + +// Class VertexBufferObject +class VertexBufferObject { + + private : + + // -------------------- Attributes -------------------- // + + /// ID of the Vertex Buffer Object + GLuint mVertexBufferID; + + /// Target data. This variable must be GL_ARRAY_BUFFER if the VBO contains vertex + /// data (vertex coordinates, texture coordinates, normals, colors) or must be + /// GL_ELEMENT_ARRAY_BUFFER if the VBO contains index data (index array). + GLenum mTargetData; + + public : + + // -------------------- Methods -------------------- // + + /// Constructor + VertexBufferObject(GLenum targetData); + + /// Destructor + ~VertexBufferObject(); + + /// Create the vertex buffer object + bool create(); + + /// Copy data into the VBO + void copyDataIntoVBO(GLsizei size, const void* data, GLenum usage); + + /// Bind the VBO + void bind() const; + + /// Unbind the VBO + void unbind() const; + + /// Return true if the needed OpenGL extensions are available for VBO + static bool checkOpenGLExtensions(); + + /// Destroy the VBO + void destroy(); +}; + +// Bind the VBO +inline void VertexBufferObject::bind() const { + assert(mVertexBufferID != 0); + + // Bind the VBO + glBindBuffer(mTargetData, mVertexBufferID); +} + +// Unbind the VBO +inline void VertexBufferObject::unbind() const { + assert(mVertexBufferID != 0); + + // Unbind the VBO + glBindBuffer(mTargetData, 0); +} + +// Return true if the needed OpenGL extensions are available for VBO +inline bool VertexBufferObject::checkOpenGLExtensions() { + + // Check that OpenGL version is at least 1.5 or there the vertex buffer object extension exists + return (GLEW_VERSION_1_5 || GL_ARB_vertex_buffer_object); +} + +} + +#endif diff --git a/testbed/opengl-framework/src/definitions.h b/testbed/opengl-framework/src/definitions.h new file mode 100644 index 00000000..5cacbdf4 --- /dev/null +++ b/testbed/opengl-framework/src/definitions.h @@ -0,0 +1,39 @@ +/******************************************************************************** +* OpenGL-Framework * +* Copyright (c) 2013 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +#ifndef DEFINITIONS_H +#define DEFINITIONS_H + +namespace openglframework { + +// ------------------- Type definitions ------------------- // +typedef unsigned int uint; + +// ------------------- Constants ------------------- // +const float PI = 3.141592654f; + +} + +#endif diff --git a/testbed/opengl-framework/src/maths/Color.h b/testbed/opengl-framework/src/maths/Color.h new file mode 100644 index 00000000..3216a0a7 --- /dev/null +++ b/testbed/opengl-framework/src/maths/Color.h @@ -0,0 +1,85 @@ +/******************************************************************************** +* OpenGL-Framework * +* Copyright (c) 2013 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +#ifndef COLOR_H +#define COLOR_H + +namespace openglframework { + +// Structure Color +// This structure represents a RGBA color. +struct Color { + + public: + + // -------------------- Attributes -------------------- // + + // RGBA color components + float r, g, b, a; + + // -------------------- Methods -------------------- // + + // Constructor + Color() : r(1), g(1), b(1), a(1) {} + + // Constructor + Color(float r, float g, float b, float a) : r(r), g(g), b(b), a(a) {} + + // Copy-constructor + Color(const Color& color) : r(color.r), g(color.g), b(color.b), a(color.a) {} + + // Destructor + ~Color() {} + + // Return the black color + static Color black() { return Color(0.0f, 0.0f, 0.0f, 1.0f);} + + // Return the white color + static Color white() { return Color(1.0f, 1.0f, 1.0f, 1.0f);} + + // Return the red color + static Color red() { return Color(1.0f, 0.0f, 0.0f, 1.0f);} + + // Return the green color + static Color green() { return Color(0.0f, 1.0f, 0.0f, 1.0f);} + + // Return the blue color + static Color blue() { return Color(0.0f, 0.0f, 1.0f, 1.0f);} + + // = operator + Color& operator=(const Color& color) { + if (&color != this) { + r = color.r; + g = color.g; + b = color.b; + a = color.a; + } + return *this; + } +}; + +} + +#endif diff --git a/testbed/opengl-framework/src/maths/Matrix3.h b/testbed/opengl-framework/src/maths/Matrix3.h new file mode 100644 index 00000000..5460f616 --- /dev/null +++ b/testbed/opengl-framework/src/maths/Matrix3.h @@ -0,0 +1,279 @@ +/******************************************************************************** +* OpenGL-Framework * +* Copyright (c) 2013 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +#ifndef MATRIX3_H +#define MATRIX3_H + +// Libraries +#include +#include +#include "Vector3.h" + +namespace openglframework { + +// Class Matrix4 +// This class represents a 4x4 matrix +class Matrix3 { + + private : + + // -------------------- Attributes -------------------- // + + // Elements of the matrix + float m[3][3]; + + public : + + // Constructor + Matrix3() { + setToNull(); + } + + // Constructor + Matrix3(float a1, float a2, + float a3, float b1, float b2, float b3, + float c1, float c2, float c3) { + setAllValues(a1, a2, a3, b1, b2, b3, c1, c2, c3); + } + + // Constructor + Matrix3(float n[3][3]) { + m[0][0]=n[0][0]; m[0][1]=n[0][1]; m[0][2]=n[0][2]; + m[1][0]=n[1][0]; m[1][1]=n[1][1]; m[1][2]=n[1][2]; + m[2][0]=n[2][0]; m[2][1]=n[2][1]; m[2][2]=n[2][2]; + } + + // Constructor + Matrix3(const Vector3& a1, const Vector3& a2, const Vector3& a3) { + m[0][0] = a1.x; m[0][1] = a2.x; m[0][2] = a3.x; + m[1][0] = a1.y; m[1][1] = a2.y; m[1][2] = a3.y; + m[2][0] = a1.z; m[2][1] = a2.z; m[2][2] = a3.z; + } + + // Constructor + Matrix3(const Matrix3& matrix) { + setAllValues(matrix.m[0][0], matrix.m[0][1], matrix.m[0][2], + matrix.m[1][0], matrix.m[1][1], matrix.m[1][2], + matrix.m[2][0], matrix.m[2][1], matrix.m[2][2]); + } + + // Method to get a value in the matrix + float getValue(int i, int j) const { + assert(i>=0 && i<3 && j>=0 && j<3); + return m[i][j]; + } + + // Method to set a value in the matrix + void setValue(int i, int j, float value) { + assert(i>=0 && i<3 && j>=0 && j<3); + m[i][j] = value; + } + + // Method to set all the values in the matrix + void setAllValues(float a1, float a2, float a3, float b1, float b2, float b3, + float c1, float c2, float c3) { + m[0][0] = a1; m[0][1] = a2; m[0][2] = a3; + m[1][0] = b1; m[1][1] = b2; m[1][2] = b3; + m[2][0] = c1; m[2][1] = c2; m[2][2] = c3; + } + + // Return a column + Vector3 getColumn(int i) const { + assert(i>= 0 && i<3); + return Vector3(m[0][i], m[1][i], m[2][i]); + } + + // Return the transpose matrix + Matrix3 getTranspose() const { + // Return the transpose matrix + return Matrix3(m[0][0], m[1][0], m[2][0], + m[0][1], m[1][1], m[2][1], + m[0][2], m[1][2], m[2][2]); + } + + // Return the determinant of the matrix + float getDeterminant() const { + // Compute and return the determinant of the matrix + return (m[0][0]*(m[1][1]*m[2][2]-m[2][1]*m[1][2]) - m[0][1]*(m[1][0]*m[2][2]-m[2][0]*m[1][2]) + + m[0][2]*(m[1][0]*m[2][1]-m[2][0]*m[1][1])); + } + + // Return the trace of the matrix + float getTrace() const { + // Compute and return the trace + return (m[0][0] + m[1][1] + m[2][2]); + } + + void setToNull() { + m[0][0] = 0.0; m[0][1] = 0.0; m[0][2] = 0.0; + m[1][0] = 0.0; m[1][1] = 0.0; m[1][2] = 0.0; + m[2][0] = 0.0; m[2][1] = 0.0; m[2][2] = 0.0; + } + + bool isNull() const { + Matrix3 zero; + return *this == zero; + } + + // Set the matrix to the identity matrix + void setToIdentity() { + m[0][0] = 1.0; m[0][1] = 0.0; m[0][2] = 0.0; + m[1][0] = 0.0; m[1][1] = 1.0; m[1][2] = 0.0; + m[2][0] = 0.0; m[2][1] = 0.0; m[2][2] = 1.0; + } + + bool isIdentity() const { + Matrix3 I; + I.setToIdentity(); + return ( *this == I ); + } + + // Return the inverse matrix + Matrix3 getInverse() const { + + // Compute the determinant of the matrix + float determinant = getDeterminant(); + + // Check if the determinant is equal to zero + assert(determinant > std::numeric_limits::epsilon()); + + float invDeterminant = 1.0f / determinant; + Matrix3 tempMatrix((m[1][1]*m[2][2]-m[2][1]*m[1][2]), -(m[0][1]*m[2][2]-m[2][1]*m[0][2]), (m[0][1]*m[1][2]-m[0][2]*m[1][1]), + -(m[1][0]*m[2][2]-m[2][0]*m[1][2]), (m[0][0]*m[2][2]-m[2][0]*m[0][2]), -(m[0][0]*m[1][2]-m[1][0]*m[0][2]), + (m[1][0]*m[2][1]-m[2][0]*m[1][1]), -(m[0][0]*m[2][1]-m[2][0]*m[0][1]), (m[0][0]*m[1][1]-m[0][1]*m[1][0])); + + // Return the inverse matrix + return (tempMatrix * invDeterminant); + } + + // Display the matrix + void print() const { + for (int i=0; i<3; i++) { + for (int j=0; j<3; j++) { + std::cout << m[i][j] << " "; + } + std::cout << std::endl; + } + } + + // Overloaded operator = + Matrix3& operator=(const Matrix3& matrix) { + if (&matrix != this) { + setAllValues(matrix.m[0][0], matrix.m[0][1], matrix.m[0][2], + matrix.m[1][0], matrix.m[1][1], matrix.m[1][2], + matrix.m[2][0], matrix.m[2][1], matrix.m[2][2]); + } + return *this; + } + + + // Overloaded operator for addition + Matrix3 operator+(const Matrix3& matrix2) { + return Matrix3(m[0][0] + matrix2.m[0][0], m[0][1] + matrix2.m[0][1], m[0][2] + matrix2.m[0][2], + m[1][0] + matrix2.m[1][0], m[1][1] + matrix2.m[1][1], m[1][2] + matrix2.m[1][2], + m[2][0] + matrix2.m[2][0], m[2][1] + matrix2.m[2][1], m[2][2] + matrix2.m[2][2]); + } + + // Overloaded operator for substraction + Matrix3 operator-(const Matrix3& matrix2) { + return Matrix3(m[0][0] - matrix2.m[0][0], m[0][1] - matrix2.m[0][1], m[0][2] - matrix2.m[0][2], + m[1][0] - matrix2.m[1][0], m[1][1] - matrix2.m[1][1], m[1][2] - matrix2.m[1][2], + m[2][0] - matrix2.m[2][0], m[2][1] - matrix2.m[2][1], m[2][2] - matrix2.m[2][2]); + } + + // Overloaded operator for the negative of the matrix + Matrix3 operator-() { + return Matrix3(-m[0][0], -m[0][1], -m[0][2], + -m[1][0], -m[1][1], -m[1][2], + -m[2][0], -m[2][1], -m[2][2]); + } + + // Overloaded operator for multiplication with a number + Matrix3 operator*(float nb) { + return Matrix3(m[0][0] * nb, m[0][1] * nb, m[0][2] * nb, + m[1][0] * nb, m[1][1] * nb, m[1][2] * nb, + m[2][0] * nb, m[2][1] * nb, m[2][2] * nb); + } + + // Overloaded operator for matrix multiplication + Matrix3 operator*(const Matrix3& matrix2) { + return Matrix3(m[0][0]*matrix2.m[0][0] + m[0][1]*matrix2.m[1][0] + m[0][2]*matrix2.m[2][0], + m[0][0]*matrix2.m[0][1] + m[0][1]*matrix2.m[1][1] + m[0][2]*matrix2.m[2][1], + m[0][0]*matrix2.m[0][2] + m[0][1]*matrix2.m[1][2] + m[0][2]*matrix2.m[2][2], + m[1][0]*matrix2.m[0][0] + m[1][1]*matrix2.m[1][0] + m[1][2]*matrix2.m[2][0], + m[1][0]*matrix2.m[0][1] + m[1][1]*matrix2.m[1][1] + m[1][2]*matrix2.m[2][1], + m[1][0]*matrix2.m[0][2] + m[1][1]*matrix2.m[1][2] + m[1][2]*matrix2.m[2][2], + m[2][0]*matrix2.m[0][0] + m[2][1]*matrix2.m[1][0] + m[2][2]*matrix2.m[2][0], + m[2][0]*matrix2.m[0][1] + m[2][1]*matrix2.m[1][1] + m[2][2]*matrix2.m[2][1], + m[2][0]*matrix2.m[0][2] + m[2][1]*matrix2.m[1][2] + m[2][2]*matrix2.m[2][2]); + } + + // Overloaded operator for multiplication with a vector + Vector3 operator*(const Vector3& vector) { + return Vector3(m[0][0]*vector.x + m[0][1]*vector.y + m[0][2]*vector.z, + m[1][0]*vector.x + m[1][1]*vector.y + m[1][2]*vector.z, + m[2][0]*vector.x + m[2][1]*vector.y + m[2][2]*vector.z); + } + + // Overloaded operator for equality condition + bool operator==(const Matrix3& matrix) const { + return (m[0][0] == matrix.m[0][0] && m[0][1] == matrix.m[0][1] && m[0][2] == matrix.m[0][2] && + m[1][0] == matrix.m[1][0] && m[1][1] == matrix.m[1][1] && m[1][2] == matrix.m[1][2] && + m[2][0] == matrix.m[2][0] && m[2][1] == matrix.m[2][1] && m[2][2] == matrix.m[2][2]); + } + + // Overloaded operator for the is different condition + bool operator!= (const Matrix3& matrix) const { + return !(*this == matrix); + } + + // Overloaded operator for addition with assignment + Matrix3& operator+=(const Matrix3& matrix) { + m[0][0] += matrix.m[0][0]; m[0][1] += matrix.m[0][1]; m[0][2] += matrix.m[0][2]; + m[1][0] += matrix.m[1][0]; m[1][1] += matrix.m[1][1]; m[1][2] += matrix.m[1][2]; + m[2][0] += matrix.m[2][0]; m[2][1] += matrix.m[2][1]; m[2][2] += matrix.m[2][2]; + return *this; + } + + // Overloaded operator for substraction with assignment + Matrix3& operator-=(const Matrix3& matrix) { + m[0][0] -= matrix.m[0][0]; m[0][1] -= matrix.m[0][1]; m[0][2] -= matrix.m[0][2]; + m[1][0] -= matrix.m[1][0]; m[1][1] -= matrix.m[1][1]; m[1][2] -= matrix.m[1][2]; + m[2][0] -= matrix.m[2][0]; m[2][1] -= matrix.m[2][1]; m[2][2] -= matrix.m[2][2]; + return *this; + } + + // Overloaded operator for multiplication with a number with assignment + Matrix3& operator*=(float nb) { + m[0][0] *= nb; m[0][1] *= nb; m[0][2] *= nb; + m[1][0] *= nb; m[1][1] *= nb; m[1][2] *= nb; + m[2][0] *= nb; m[2][1] *= nb; m[2][2] *= nb; + return *this; + } +}; + +} + +#endif diff --git a/testbed/opengl-framework/src/maths/Matrix4.h b/testbed/opengl-framework/src/maths/Matrix4.h new file mode 100644 index 00000000..bcfbcebd --- /dev/null +++ b/testbed/opengl-framework/src/maths/Matrix4.h @@ -0,0 +1,427 @@ +/******************************************************************************** +* OpenGL-Framework * +* Copyright (c) 2013 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +#ifndef MATRIX4_H +#define MATRIX4_H + +// Libraries +#include +#include +#include +#include "Vector3.h" +#include "Vector4.h" +#include "Matrix3.h" + +namespace openglframework { + +// Class Matrix4 +// This class represents a 4x4 matrix +class Matrix4 { + + public: + + // -------------------- Attributes -------------------- // + + // Elements of the matrix + float m[4][4]; + + // -------------------- Methods -------------------- // + + // Constructor + Matrix4(float m_00=0, float m_01=0, float m_02=0, float m_03=0, + float m_10=0, float m_11=0, float m_12=0, float m_13=0, + float m_20=0, float m_21=0, float m_22=0, float m_23=0, + float m_30=0, float m_31=0, float m_32=0, float m_33=0) { + m[0][0] = m_00; m[0][1] = m_01; m[0][2] = m_02; m[0][3] = m_03; + m[1][0] = m_10; m[1][1] = m_11; m[1][2] = m_12; m[1][3] = m_13; + m[2][0] = m_20; m[2][1] = m_21; m[2][2] = m_22; m[2][3] = m_23; + m[3][0] = m_30; m[3][1] = m_31; m[3][2] = m_32; m[3][3] = m_33; + } + + // Constructor + Matrix4(float n[4][4]) { + m[0][0]=n[0][0]; m[0][1]=n[0][1]; m[0][2]=n[0][2]; m[0][3]=n[0][3]; + m[1][0]=n[1][0]; m[1][1]=n[1][1]; m[1][2]=n[1][2]; m[1][3]=n[1][3]; + m[2][0]=n[2][0]; m[2][1]=n[2][1]; m[2][2]=n[2][2]; m[2][3]=n[2][3]; + m[3][0]=n[3][0]; m[3][1]=n[3][1]; m[3][2]=n[3][2]; m[3][3]=n[3][3]; + } + + // Constructor + Matrix4(const Vector3& a1, const Vector3& a2, const Vector3& a3) { + m[0][0] = a1.x; m[0][1] = a2.x; m[0][2] = a3.x; m[0][3] = 0.f; + m[1][0] = a1.y; m[1][1] = a2.y; m[1][2] = a3.y; m[1][3] = 0.f; + m[2][0] = a1.z; m[2][1] = a2.z; m[2][2] = a3.z; m[2][3] = 0.f; + m[3][0] = 0.f; m[3][1] = 0.f; m[3][2] = 0.f; m[3][3] = 1.f; + } + + // Constructor + Matrix4(const Vector4& a1, const Vector4& a2, const Vector4& a3) { + m[0][0] = a1.x; m[0][1] = a2.x; m[0][2] = a3.x; m[0][3] = 0.f; + m[1][0] = a1.y; m[1][1] = a2.y; m[1][2] = a3.y; m[1][3] = 0.f; + m[2][0] = a1.z; m[2][1] = a2.z; m[2][2] = a3.z; m[2][3] = 0.f; + m[3][0] = a1.w; m[3][1] = a2.w; m[3][2] = a3.w; m[3][3] = 1.f; + } + + // Constructor + Matrix4(const Matrix4& matrix) { + + setAllValues(matrix.m[0][0], matrix.m[0][1], matrix.m[0][2], matrix.m[0][3], + matrix.m[1][0], matrix.m[1][1], matrix.m[1][2], matrix.m[1][3], + matrix.m[2][0], matrix.m[2][1], matrix.m[2][2], matrix.m[2][3], + matrix.m[3][0], matrix.m[3][1], matrix.m[3][2], matrix.m[3][3]); + } + + // + operator + Matrix4 operator+(const Matrix4 &n) const { + return Matrix4(m[0][0]+n.m[0][0], m[0][1]+n.m[0][1], m[0][2]+n.m[0][2], m[0][3]+n.m[0][3], + m[1][0]+n.m[1][0], m[1][1]+n.m[1][1], m[1][2]+n.m[1][2], m[1][3]+n.m[1][3], + m[2][0]+n.m[2][0], m[2][1]+n.m[2][1], m[2][2]+n.m[2][2], m[2][3]+n.m[2][3], + m[3][0]+n.m[3][0], m[3][1]+n.m[3][1], m[3][2]+n.m[3][2], m[3][3]+n.m[3][3]); + } + + // += operator + Matrix4& operator+=(const Matrix4 &n) { + m[0][0]+=n.m[0][0]; m[0][1]+=n.m[0][1]; m[0][2]+=n.m[0][2]; m[0][3]+=n.m[0][3]; + m[1][0]+=n.m[1][0]; m[1][1]+=n.m[1][1]; m[1][2]+=n.m[1][2]; m[1][3]+=n.m[1][3]; + m[2][0]+=n.m[2][0]; m[2][1]+=n.m[2][1]; m[2][2]+=n.m[2][2]; m[2][3]+=n.m[2][3]; + m[3][0]+=n.m[3][0]; m[3][1]+=n.m[3][1]; m[3][2]+=n.m[3][2]; m[3][3]+=n.m[3][3]; + return *this; + } + + // - operator + Matrix4 operator-(const Matrix4 &n) const { + return Matrix4(m[0][0]-n.m[0][0], m[0][1]-n.m[0][1], m[0][2]-n.m[0][2], m[0][3]-n.m[0][3], + m[1][0]-n.m[1][0], m[1][1]-n.m[1][1], m[1][2]-n.m[1][2], m[1][3]-n.m[1][3], + m[2][0]-n.m[2][0], m[2][1]-n.m[2][1], m[2][2]-n.m[2][2], m[2][3]-n.m[2][3], + m[3][0]-n.m[3][0], m[3][1]-n.m[3][1], m[3][2]-n.m[3][2], m[3][3]-n.m[3][3]); + } + + // -= operator + Matrix4& operator-=(const Matrix4 &n) { + m[0][0]-=n.m[0][0]; m[0][1]-=n.m[0][1]; m[0][2]-=n.m[0][2]; m[0][3]-=n.m[0][3]; + m[1][0]-=n.m[1][0]; m[1][1]-=n.m[1][1]; m[1][2]-=n.m[1][2]; m[1][3]-=n.m[1][3]; + m[2][0]-=n.m[2][0]; m[2][1]-=n.m[2][1]; m[2][2]-=n.m[2][2]; m[2][3]-=n.m[2][3]; + m[3][0]-=n.m[3][0]; m[3][1]-=n.m[3][1]; m[3][2]-=n.m[3][2]; m[3][3]-=n.m[3][3]; + return *this; + } + + // = operator + Matrix4& operator=(const Matrix4& matrix) { + if (&matrix != this) { + setAllValues(matrix.m[0][0], matrix.m[0][1], matrix.m[0][2], matrix.m[0][3], + matrix.m[1][0], matrix.m[1][1], matrix.m[1][2], matrix.m[1][3], + matrix.m[2][0], matrix.m[2][1], matrix.m[2][2], matrix.m[2][3], + matrix.m[3][0], matrix.m[3][1], matrix.m[3][2], matrix.m[3][3]); + } + return *this; + } + + // == operator + bool operator==(const Matrix4 &n) const { + return m[0][0]==n.m[0][0] && m[0][1]==n.m[0][1] && m[0][2]==n.m[0][2] && m[0][3]==n.m[0][3] && + m[1][0]==n.m[1][0] && m[1][1]==n.m[1][1] && m[1][2]==n.m[1][2] && m[1][3]==n.m[1][3] && + m[2][0]==n.m[2][0] && m[2][1]==n.m[2][1] && m[2][2]==n.m[2][2] && m[2][3]==n.m[2][3] && + m[3][0]==n.m[3][0] && m[3][1]==n.m[3][1] && m[3][2]==n.m[3][2] && m[3][3]==n.m[3][3]; + } + + // * operator + Matrix4 operator*(const Matrix4 &n) const { + Matrix4 o; + for(int i = 0; i < 4; i++) { + for(int j = 0; j < 4; j++) { + float v = 0; + for(int k = 0; k < 4; k++) { + v += m[i][k] * n.m[k][j]; + } + o.m[i][j] = v; + } + } + return o; + } + + // * operator + Vector3 operator*(const Vector3 &v) const { + Vector3 u =Vector3(m[0][0]*v.x + m[0][1]*v.y + m[0][2]*v.z + m[0][3], + m[1][0]*v.x + m[1][1]*v.y + m[1][2]*v.z + m[1][3], + m[2][0]*v.x + m[2][1]*v.y + m[2][2]*v.z + m[2][3]); + float w = m[3][0]*v.x + m[3][1]*v.y + m[3][2]*v.z + m[3][3]; + return u/w; + } + + // * operator + Vector4 operator*(const Vector4 &v) const { + Vector4 u = Vector4(m[0][0]*v.x + m[0][1]*v.y + m[0][2]*v.z + v.w*m[0][3], + m[1][0]*v.x + m[1][1]*v.y + m[1][2]*v.z + v.w*m[1][3], + m[2][0]*v.x + m[2][1]*v.y + m[2][2]*v.z + v.w*m[2][3], + m[3][0]*v.x + m[3][1]*v.y + m[3][2]*v.z + v.w*m[3][3]); + if(u.w != 0) + return u/u.w; + else + return u; + } + + // * operator + Matrix4 operator*(float f) const { + return Matrix4(m[0][0]*f, m[0][1]*f, m[0][2]*f, m[0][3]*f, + m[1][0]*f, m[1][1]*f, m[1][2]*f, m[1][3]*f, + m[2][0]*f, m[2][1]*f, m[2][2]*f, m[2][3]*f, + m[3][0]*f, m[3][1]*f, m[3][2]*f, m[3][3]*f); + } + + // * operator + Matrix4 &operator*=(float f) { + m[0][0]*=f; m[0][1]*=f; m[0][2]*=f; m[0][3]*=f; + m[1][0]*=f; m[1][1]*=f; m[1][2]*=f; m[1][3]*=f; + m[2][0]*=f; m[2][1]*=f; m[2][2]*=f; m[2][3]*=f; + m[3][0]*=f; m[3][1]*=f; m[3][2]*=f; m[3][3]*=f; + return *this; + } + + // / operator + Matrix4 operator/(float f) const { + assert(f!=0); + return Matrix4(m[0][0]/f, m[0][1]/f, m[0][2]/f, m[0][3]/f, + m[1][0]/f, m[1][1]/f, m[1][2]/f, m[1][3]/f, + m[2][0]/f, m[2][1]/f, m[2][2]/f, m[2][3]/f, + m[3][0]/f, m[3][1]/f, m[3][2]/f, m[3][3]/f); + } + + // /= operator + Matrix4 &operator/=(float f) { + assert(f!=0); + m[0][0]/=f; m[0][1]/=f; m[0][2]/=f; m[0][3]/=f; + m[1][0]/=f; m[1][1]/=f; m[1][2]/=f; m[1][3]/=f; + m[2][0]/=f; m[2][1]/=f; m[2][2]/=f; m[2][3]/=f; + m[3][0]/=f; m[3][1]/=f; m[3][2]/=f; m[3][3]/=f; + return *this; + } + + // - operator + Matrix4 operator-() const { + return Matrix4(-m[0][0], -m[0][1], -m[0][2], -m[0][3], + -m[1][0], -m[1][1], -m[1][2], -m[1][3], + -m[2][0], -m[2][1], -m[2][2], -m[2][3], + -m[3][0], -m[3][1], -m[3][2], -m[3][3]); + } + + // Return the transpose matrix + Matrix4 getTranspose() const { + return Matrix4(m[0][0], m[1][0], m[2][0], m[3][0], + m[0][1], m[1][1], m[2][1], m[3][1], + m[0][2], m[1][2], m[2][2], m[3][2], + m[0][3], m[1][3], m[2][3], m[3][3]); + } + + // Return the 3x3 upper-left matrix + Matrix3 getUpperLeft3x3Matrix() const { + return Matrix3(m[0][0], m[0][1], m[0][2], + m[1][0], m[1][1], m[1][2], + m[2][0], m[2][1], m[2][2]); + } + + // Return the inversed matrix + Matrix4 getInverse() const { + int indxc[4], indxr[4]; + int ipiv[4] = { 0, 0, 0, 0 }; + float minv[4][4]; + float temp; + + for (int s=0; s<4; s++) { + for (int t=0; t<4; t++) { + minv[s][t] = m[s][t]; + } + } + + for (int i = 0; i < 4; i++) { + int irow = -1, icol = -1; + float big = 0.; + // Choose pivot + for (int j = 0; j < 4; j++) { + if (ipiv[j] != 1) { + for (int k = 0; k < 4; k++) { + if (ipiv[k] == 0) { + if (fabs(minv[j][k]) >= big) { + big = float(fabs(minv[j][k])); + irow = j; + icol = k; + } + } + else if (ipiv[k] > 1) { + std::cout << "ERROR: Singular matrix in MatrixInvert\n"; + } + } + } + } + ++ipiv[icol]; + // Swap rows _irow_ and _icol_ for pivot + if (irow != icol) { + for (int k = 0; k < 4; ++k){ + temp = minv[irow][k]; + minv[irow][k] = minv[icol][k]; + minv[icol][k] = temp; + } + } + indxr[i] = irow; + indxc[i] = icol; + if (minv[icol][icol] == 0.){ + std::cout << "Singular matrix in MatrixInvert\n"; + } + // Set $m[icol][icol]$ to one by scaling row _icol_ appropriately + float pivinv = 1.f / minv[icol][icol]; + minv[icol][icol] = 1.f; + for (int j = 0; j < 4; j++) { + minv[icol][j] *= pivinv; + } + + // Subtract this row from others to zero out their columns + for (int j = 0; j < 4; j++) { + if (j != icol) { + float save = minv[j][icol]; + minv[j][icol] = 0; + for (int k = 0; k < 4; k++) { + minv[j][k] -= minv[icol][k]*save; + } + } + } + } + // Swap columns to reflect permutation + for (int j = 3; j >= 0; j--) { + if (indxr[j] != indxc[j]) { + for (int k = 0; k < 4; k++){ + temp = minv[k][indxr[j]]; + minv[k][indxr[j]] = minv[k][indxc[j]]; + minv[k][indxc[j]] = temp; + } + } + } + return Matrix4(minv); + } + + // Method to set all the values in the matrix + void setAllValues(float a1, float a2, float a3, float a4, + float b1, float b2, float b3, float b4, + float c1, float c2, float c3, float c4, + float d1, float d2, float d3, float d4) { + m[0][0] = a1; m[0][1] = a2; m[0][2] = a3, m[0][3] = a4; + m[1][0] = b1; m[1][1] = b2; m[1][2] = b3; m[1][3] = b4; + m[2][0] = c1; m[2][1] = c2; m[2][2] = c3; m[2][3] = c4; + m[3][0] = d1; m[3][1] = d2; m[3][2] = d3; m[3][3] = d4; + } + + // Set the matrix to the identity matrix + Matrix4 setToIdentity() { + m[0][0] = 1.f; m[0][1] = 0.f; m[0][2] = 0.f; m[0][3] = 0.f; + m[1][0] = 0.f; m[1][1] = 1.f; m[1][2] = 0.f; m[1][3] = 0.f; + m[2][0] = 0.f; m[2][1] = 0.f; m[2][2] = 1.f; m[2][3] = 0.f; + m[3][0] = 0.f; m[3][1] = 0.f; m[3][2] = 0.f; m[3][3] = 1.f; + return *this; + } + + // Display the matrix + void print() const { + for (int i=0; i<4; i++) { + for (int j=0; j<4; j++) { + std::cout << m[i][j]; + } + std::cout << std::endl; + } + } + + // Return the pointer to the data array of the matrix + float* dataBlock() { + return m[0]; + } + + // Return the constant pointer to the data array of the matrix + const float* dataBlock() const { + return m[0]; + } + + // Return a given value from the matrix + float getValue(int i, int j) const { + assert(i >= 0 && i<4 && j >= 0 && j<4); + return m[i][j]; + } + + // Return the trace of the matrix + float getTrace() const { + // Compute and return the trace + return (m[0][0] + m[1][1] + m[2][2] + m[3][3]); + } + + // Return a 4x4 translation matrix + static Matrix4 translationMatrix(const Vector3& v); + + // Return a 4x4 rotation matrix + static Matrix4 rotationMatrix(const Vector3& axis, float angle); +}; + +// * operator +inline Matrix4 operator*(float f, const Matrix4 & m) { + return (m * f); +} + +// Return a 4x4 translation matrix +inline Matrix4 Matrix4::translationMatrix(const Vector3& v) { + return Matrix4(1, 0, 0, v.x, + 0, 1, 0, v.y, + 0, 0, 1, v.z, + 0, 0, 0, 1); +} + +// Return a 4x4 rotation matrix +inline Matrix4 Matrix4::rotationMatrix(const Vector3& axis, float angle) { + + float cosA = cos(angle); + float sinA = sin(angle); + Matrix4 rotationMatrix; + rotationMatrix.setToIdentity(); + + rotationMatrix.m[0][0] = cosA + (1-cosA) * axis.x * axis.x; + rotationMatrix.m[0][1] = (1-cosA) * axis.x * axis.y - axis.z * sinA; + rotationMatrix.m[0][2] = (1-cosA) * axis.x * axis.z + axis.y * sinA; + rotationMatrix.m[0][3] = 0.f; + + rotationMatrix.m[1][0] = (1-cosA) * axis.x * axis.y + axis.z * sinA; + rotationMatrix.m[1][1] = cosA + (1-cosA) * axis.y * axis.y; + rotationMatrix.m[1][2] = (1-cosA) * axis.y * axis.z - axis.x * sinA; + rotationMatrix.m[1][3] = 0.f; + + rotationMatrix.m[2][0] = (1-cosA) * axis.x * axis.z - axis.y * sinA; + rotationMatrix.m[2][1] = (1-cosA) * axis.y * axis.z + axis.x * sinA; + rotationMatrix.m[2][2] = cosA + (1-cosA) * axis.z * axis.z; + rotationMatrix.m[2][3] = 0.f; + + rotationMatrix.m[3][0] = 0.f; + rotationMatrix.m[3][1] = 0.f; + rotationMatrix.m[3][2] = 0.f; + rotationMatrix.m[3][3] = 1.f; + + return rotationMatrix; +} + +} + +#endif //_MATRIX4_H diff --git a/testbed/opengl-framework/src/maths/Vector2.h b/testbed/opengl-framework/src/maths/Vector2.h new file mode 100644 index 00000000..0bc0eb9c --- /dev/null +++ b/testbed/opengl-framework/src/maths/Vector2.h @@ -0,0 +1,159 @@ +/******************************************************************************** +* OpenGL-Framework * +* Copyright (c) 2013 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +#ifndef VECTOR2_H +#define VECTOR2_H + +// Libraries +#include +#include + +namespace openglframework { + +// Class Vector2 +// This class represents a 2D vector. +class Vector2 { + + public: + + // -------------------- Attributes -------------------- // + + // Components of the vector + float x, y; + + + // -------------------- Methods -------------------- // + + // Constructor + Vector2(float x=0, float y=0) : x(x), y(y) {} + + // Constructor + Vector2(const Vector2& vector) : x(vector.x), y(vector.y) {} + + // + operator + Vector2 operator+(const Vector2 &v) const { + return Vector2(x + v.x, y + v.y); + } + + // += operator + Vector2& operator+=(const Vector2 &v) { + x += v.x; y += v.y; + return *this; + } + + // - operator + Vector2 operator-(const Vector2 &v) const { + return Vector2(x - v.x, y - v.y); + } + + // -= operator + Vector2& operator-=(const Vector2 &v) { + x -= v.x; y -= v.y; + return *this; + } + + // = operator + Vector2& operator=(const Vector2& vector) { + if (&vector != this) { + x = vector.x; + y = vector.y; + } + return *this; + } + + // == operator + bool operator==(const Vector2 &v) const { + return x == v.x && y == v.y; + } + + // * operator + Vector2 operator*(float f) const { + return Vector2(f*x, f*y); + } + + // *= operator + Vector2 &operator*=(float f) { + x *= f; y *= f; + return *this; + } + + // / operator + Vector2 operator/(float f) const { + assert(f!=0); + float inv = 1.f / f; + return Vector2(x * inv, y * inv); + } + + // /= operator + Vector2 &operator/=(float f) { + assert(f!=0); + float inv = 1.f / f; + x *= inv; y *= inv; + return *this; + } + + // - operator + Vector2 operator-() const { + return Vector2(-x, -y); + } + + // [] operator + float &operator[](int i) { + assert(i >= 0 && i <= 1); + switch (i) { + case 0: return x; + case 1: return y; + } + return y; + } + + // Normalize the vector and return it + Vector2 normalize() { + float l = length(); + assert(l > 0); + x /= l; + y /= l; + return *this; + } + + // Clamp the vector values between 0 and 1 + Vector2 clamp01() { + if (x>1.f) x=1.f; + else if (x<0.f) x=0.f; + if (y>1.f) y=1.f; + else if (y<0.f) y=0.f; + return *this; + } + + // Return the squared length of the vector + float lengthSquared() const { return x*x + y*y; } + + // Return the length of the vector + float length() const { return sqrt(lengthSquared()); } +}; + +} + +#endif diff --git a/testbed/opengl-framework/src/maths/Vector3.h b/testbed/opengl-framework/src/maths/Vector3.h new file mode 100644 index 00000000..adeecb7c --- /dev/null +++ b/testbed/opengl-framework/src/maths/Vector3.h @@ -0,0 +1,203 @@ +/******************************************************************************** +* OpenGL-Framework * +* Copyright (c) 2013 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +#ifndef OPENGLFRAMEWORK_VECTOR3_H +#define OPENGLFRAMEWORK_VECTOR3_H + +// Libraries +#include +#include +#include + +namespace openglframework { + +// Class Vector3 +// This class represents a 3D vector. +class Vector3 { + + public: + + // -------------------- Attributes -------------------- // + + // Components of the vector + float x, y, z; + + // -------------------- Methods -------------------- // + + // Constructor + Vector3(float x=0, float y=0, float z=0) : x(x), y(y), z(z) {} + + // Constructor + Vector3(const Vector3& vector) : x(vector.x), y(vector.y), z(vector.z) {} + + // Constructor + ~Vector3() {} + + // = operator + Vector3& operator=(const Vector3& vector) { + if (&vector != this) { + x = vector.x; + y = vector.y; + z = vector.z; + } + return *this; + } + + // + operator + Vector3 operator+(const Vector3 &v) const { + return Vector3(x + v.x, y + v.y, z + v.z); + } + + // += operator + Vector3& operator+=(const Vector3 &v) { + x += v.x; y += v.y; z += v.z; + return *this; + } + + // - operator + Vector3 operator-(const Vector3 &v) const { + return Vector3(x - v.x, y - v.y, z - v.z); + } + + // -= operator + Vector3& operator-=(const Vector3 &v) { + x -= v.x; y -= v.y; z -= v.z; + return *this; + } + + // == operator + bool operator==(const Vector3 &v) const { + return x == v.x && y == v.y && z == v.z; + } + + // != operator + bool operator!=(const Vector3 &v) const { + return !( *this == v ); + } + + // * operator + Vector3 operator*(float f) const { + return Vector3(f*x, f*y, f*z); + } + + // *= operator + Vector3 &operator*=(float f) { + x *= f; y *= f; z *= f; + return *this; + } + + // / operator + Vector3 operator/(float f) const { + assert(f > std::numeric_limits::epsilon() ); + float inv = 1.f / f; + return Vector3(x * inv, y * inv, z * inv); + } + + // /= operator + Vector3 &operator/=(float f) { + assert(f > std::numeric_limits::epsilon()); + float inv = 1.f / f; + x *= inv; y *= inv; z *= inv; + return *this; + } + + // - operator + Vector3 operator-() const { + return Vector3(-x, -y, -z); + } + + // [] operator + float &operator[](int i) { + assert(i >= 0 && i <= 2); + switch (i) { + case 0: return x; + case 1: return y; + case 2: return z; + } + return z; + } + + // [] operator + const float &operator[](int i) const { + assert(i >= 0 && i <= 2); + switch (i) { + case 0: return x; + case 1: return y; + case 2: return z; + } + return z; + } + + // Cross product operator + Vector3 cross(const Vector3 &v) const{ + return Vector3(y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x); + } + + // Dot product operator + float dot(const Vector3 &v) const{ + return x * v.x + y * v.y + z * v.z; + } + + // Normalize the vector and return it + Vector3 normalize() { + float l = length(); + if(l < std::numeric_limits::epsilon() ) { + assert(false); + } + x /= l; + y /= l; + z /= l; + return *this; + } + + bool isNull() const { + return( x == 0. && y == 0. && z == 0. ); + } + + // Clamp the values between 0 and 1 + Vector3 clamp01() { + if (x>1.f) x=1.f; + else if (x<0.f) x=0.f; + if (y>1.f) y=1.f; + else if (y<0.f) y=0.f; + if (z>1.f) z=1.f; + else if (z<0.f) z=0.f; + return *this; + } + + // Return the squared length of the vector + float lengthSquared() const { return x*x + y*y + z*z; } + + // Return the length of the vector + float length() const { return sqrt(lengthSquared()); } +}; + +inline Vector3 operator*(float f, const Vector3 & o) { + return o*f; +} + +} + +#endif diff --git a/testbed/opengl-framework/src/maths/Vector4.h b/testbed/opengl-framework/src/maths/Vector4.h new file mode 100644 index 00000000..3c4002d8 --- /dev/null +++ b/testbed/opengl-framework/src/maths/Vector4.h @@ -0,0 +1,167 @@ +/******************************************************************************** +* OpenGL-Framework * +* Copyright (c) 2013 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +#ifndef VECTOR4_H +#define VECTOR4_H + +// Libraries +#include +#include + +namespace openglframework { + +// Class Vector4 +// This class represents a 4D vector. +class Vector4 { + + public: + + // -------------------- Attributes -------------------- // + + // Components of the vector + float x, y, z, w; + + // -------------------- Methods -------------------- // + + // Constructor + Vector4(float x=0, float y=0, float z=0, float w=0) : x(x), y(y), z(z), w(w) {} + + // Constructor + Vector4(const Vector4& vector) : x(vector.x), y(vector.y), z(vector.z), w(vector.w) {} + + // + operator + Vector4 operator+(const Vector4 &v) const { + return Vector4(x + v.x, y + v.y, z + v.z, w + v.w); + } + + // += operator + Vector4& operator+=(const Vector4 &v) { + x += v.x; y += v.y; z += v.z; w += v.w; + return *this; + } + + // - operator + Vector4 operator-(const Vector4 &v) const { + return Vector4(x - v.x, y - v.y, z - v.z, w - v.w); + } + + // -= operator + Vector4& operator-=(const Vector4 &v) { + x -= v.x; y -= v.y; z -= v.z, w -=v.w; + return *this; + } + + // = operator + Vector4& operator=(const Vector4& vector) { + if (&vector != this) { + x = vector.x; + y = vector.y; + z = vector.z; + w = vector.w; + } + return *this; + } + + // == operator + bool operator==(const Vector4 &v) const { + return x == v.x && y == v.y && z == v.z && w == v.w; + } + + // * operator + Vector4 operator*(float f) const { + return Vector4(f*x, f*y, f*z, f*w); + } + + // *= operator + Vector4 &operator*=(float f) { + x *= f; y *= f; z *= f; w *= f; + return *this; + } + + // / operator + Vector4 operator/(float f) const { + assert(f!=0); + float inv = 1.f / f; + return Vector4(x * inv, y * inv, z * inv, w * inv); + } + + // /= operator + Vector4 &operator/=(float f) { + assert(f!=0); + float inv = 1.f / f; + x *= inv; y *= inv; z *= inv; w *= inv; + return *this; + } + + // - operator + Vector4 operator-() const { + return Vector4(-x, -y, -z, -w); + } + + // [] operator + float &operator[](int i) { + assert(i >= 0 && i <= 3); + switch (i) { + case 0: return x; + case 1: return y; + case 2: return z; + case 3: return w; + } + return w; + } + + // Dot product operator + float dot(const Vector4 &v) const { + return x * v.x + y * v.y + z * v.z + w * v.w; + } + + // Multiply two vectors by their components + Vector4 componentMul(const Vector4 &v) const { + return Vector4(x * v.x, y * v.y, z * v.z, w * v.w); + } + + // Clamp the values between 0 and 1 + Vector4 clamp01() { + if (x>1.f) x=1.f; + else if (x<0.f) x=0.f; + if (y>1.f) y=1.f; + else if (y<0.f) y=0.f; + if (z>1.f) z=1.f; + else if (z<0.f) z=0.f; + if (w>1.f) w=1.f; + else if (w<0.f) w=0.f; + return *this; + } + + // Return the squared length of the vector + float lengthSquared() const { return x * x + y * y + z * z + w * w; } + + // Return the length of the vector + float length() const { return sqrt(lengthSquared()); } +}; + +} + +#endif //_VECTOR4_H diff --git a/testbed/opengl-framework/src/openglframework.h b/testbed/opengl-framework/src/openglframework.h new file mode 100644 index 00000000..4ac735d8 --- /dev/null +++ b/testbed/opengl-framework/src/openglframework.h @@ -0,0 +1,48 @@ +/******************************************************************************** +* OpenGL-Framework * +* Copyright (c) 2013 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +#ifndef OPENGL_FRAMEWORK_H +#define OPENGL_FRAMEWORK_H + +// Libraries +#include "MeshReaderWriter.h" +#include "TextureReaderWriter.h" +#include "Camera.h" +#include "Light.h" +#include "Mesh.h" +#include "Shader.h" +#include "Texture2D.h" +#include "FrameBufferObject.h" +#include "VertexBufferObject.h" +#include "Shader.h" +#include "maths/Color.h" +#include "maths/Vector2.h" +#include "maths/Vector3.h" +#include "maths/Vector4.h" +#include "maths/Matrix4.h" +#include "maths/Matrix3.h" +#include "definitions.h" + +#endif diff --git a/testbed/shaders/depth.frag b/testbed/shaders/depth.frag new file mode 100644 index 00000000..4ef97b32 --- /dev/null +++ b/testbed/shaders/depth.frag @@ -0,0 +1,32 @@ +/******************************************************************************** +* OpenGL-Framework * +* Copyright (c) 2013 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +void main(void) { + + // Compute the depth of the pixel + float depth = + + gl_FragColor = vec4(depth, depth, depth, 1); +} diff --git a/testbed/shaders/depth.vert b/testbed/shaders/depth.vert new file mode 100644 index 00000000..f320cc72 --- /dev/null +++ b/testbed/shaders/depth.vert @@ -0,0 +1,36 @@ +/******************************************************************************** +* OpenGL-Framework * +* Copyright (c) 2013 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Uniform variables +uniform mat4 modelToWorldMatrix; // Model too world coordinates matrix +uniform mat4 worldToCameraMatrix; // World to camera coordinates matrix +uniform mat4 projectionMatrix; // Projection matrix + +void main(void) { + + // Compute the clip-space vertex coordinates + gl_Position = projectionMatrix * worldToCameraMatrix * + modelToWorldMatrix * gl_Vertex; +} diff --git a/testbed/shaders/phong.frag b/testbed/shaders/phong.frag new file mode 100644 index 00000000..f09777da --- /dev/null +++ b/testbed/shaders/phong.frag @@ -0,0 +1,67 @@ +/******************************************************************************** +* OpenGL-Framework * +* Copyright (c) 2013 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Uniform variables +uniform vec3 lightAmbientColor; // Lights ambient color +uniform vec3 light0PosCameraSpace; // Camera-space position of the light +uniform vec3 light0DiffuseColor; // Light 0 diffuse color +uniform vec3 light0SpecularColor; // Light 0 specular color +uniform float shininess; // Shininess +uniform sampler2D texture; // Texture +uniform bool isTexture; // True if we need to use the texture +uniform vec4 vertexColor; // Vertex color + +// Varying variables +varying vec3 vertexPosCameraSpace; // Camera-space position of the vertex +varying vec3 vertexNormalCameraSpace; // Vertex normal in camera-space +varying vec2 texCoords; // Texture coordinates + +void main() { + + // Compute the ambient term + vec3 ambient = lightAmbientColor; + + // Get the texture color + vec3 textureColor = vertexColor.rgb; + if (isTexture) textureColor = texture2D(texture, texCoords).rgb; + + // Compute the surface normal vector + vec3 N = normalize(vertexNormalCameraSpace); + + // Compute the diffuse term of light 0 + vec3 L0 = normalize(light0PosCameraSpace - vertexPosCameraSpace); + float diffuseFactor = max(dot(N, L0), 0.0); + vec3 diffuse = light0DiffuseColor * diffuseFactor * textureColor; + + // Compute the specular term of light 0 + vec3 V = normalize(-vertexPosCameraSpace); + vec3 H0 = normalize(V + L0); + float specularFactor = pow(max(dot(N, H0), 0.0), shininess); + if (diffuseFactor < 0.0) specularFactor = 0.0; + vec3 specular = light0SpecularColor * specularFactor; + + // Compute the final color + gl_FragColor = vec4(ambient + diffuse + specular, 1.0); +} diff --git a/testbed/shaders/phong.vert b/testbed/shaders/phong.vert new file mode 100644 index 00000000..620344a9 --- /dev/null +++ b/testbed/shaders/phong.vert @@ -0,0 +1,50 @@ +/******************************************************************************** +* OpenGL-Framework * +* Copyright (c) 2013 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Uniform variables +uniform mat4 localToCameraMatrix; // Local-space to camera-space matrix +uniform mat4 projectionMatrix; // Projection matrix +uniform mat3 normalMatrix; // Normal matrix + +// Varying variables +varying vec3 vertexPosCameraSpace; // Camera-space position of the vertex +varying vec3 vertexNormalCameraSpace; // Vertex normal in camera-space +varying vec2 texCoords; // Texture coordinates + +void main() { + + // Compute the vertex position + vec4 positionCameraSpace = localToCameraMatrix * gl_Vertex; + vertexPosCameraSpace = positionCameraSpace.xyz; + + // Compute the world surface normal + vertexNormalCameraSpace = normalMatrix * gl_Normal; + + // Get the texture coordinates + texCoords = gl_MultiTexCoord0.xy; + + // Compute the clip-space vertex coordinates + gl_Position = projectionMatrix * positionCameraSpace; +} From c264356cc6299b794d7340de6e0092c15b645e5b Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Wed, 8 Apr 2015 20:50:31 +0200 Subject: [PATCH 02/36] Add files for the testbed application --- CMakeLists.txt | 10 +- examples/CMakeLists.txt | 11 - examples/collisionshapes/CMakeLists.txt | 42 - examples/collisionshapes/CollisionShapes.cpp | 152 - examples/collisionshapes/Scene.cpp | 444 - examples/collisionshapes/Scene.h | 158 - examples/common/Box.cpp | 239 - examples/common/Box.h | 131 - examples/common/CMakeLists.txt | 5 - examples/common/Capsule.cpp | 179 - examples/common/Capsule.h | 94 - examples/common/Cone.cpp | 179 - examples/common/Cone.h | 93 - examples/common/ConvexMesh.cpp | 218 - examples/common/ConvexMesh.h | 84 - examples/common/Cylinder.cpp | 179 - examples/common/Cylinder.h | 93 - examples/common/Dumbbell.cpp | 216 - examples/common/Dumbbell.h | 91 - examples/common/Line.cpp | 59 - examples/common/Line.h | 79 - examples/common/Sphere.cpp | 179 - examples/common/Sphere.h | 90 - examples/common/Viewer.cpp | 342 - examples/common/Viewer.h | 208 - examples/common/VisualContactPoint.cpp | 115 - examples/common/VisualContactPoint.h | 73 - examples/common/glfw/.gitignore | 70 - .../common/glfw/CMake/amd64-mingw32msvc.cmake | 13 - .../common/glfw/CMake/i586-mingw32msvc.cmake | 13 - .../common/glfw/CMake/i686-pc-mingw32.cmake | 13 - .../common/glfw/CMake/i686-w64-mingw32.cmake | 13 - .../common/glfw/CMake/modules/FindEGL.cmake | 16 - .../glfw/CMake/modules/FindGLESv1.cmake | 16 - .../glfw/CMake/modules/FindGLESv2.cmake | 16 - .../common/glfw/CMake/modules/FindMir.cmake | 18 - .../glfw/CMake/modules/FindWayland.cmake | 66 - .../glfw/CMake/modules/FindXKBCommon.cmake | 34 - .../glfw/CMake/x86_64-w64-mingw32.cmake | 13 - examples/common/glfw/CMakeLists.txt | 586 - examples/common/glfw/COPYING.txt | 22 - examples/common/glfw/README.md | 294 - examples/common/glfw/cmake_uninstall.cmake.in | 29 - examples/common/glfw/deps/EGL/eglext.h | 565 - examples/common/glfw/deps/GL/glext.h | 11626 ---------------- examples/common/glfw/deps/GL/glxext.h | 906 -- examples/common/glfw/deps/GL/wglext.h | 840 -- examples/common/glfw/deps/KHR/khrplatform.h | 282 - examples/common/glfw/deps/getopt.c | 230 - examples/common/glfw/deps/getopt.h | 57 - examples/common/glfw/deps/glad.c | 728 - examples/common/glfw/deps/glad/glad.h | 1925 --- examples/common/glfw/deps/tinycthread.c | 593 - examples/common/glfw/deps/tinycthread.h | 440 - examples/common/glfw/docs/CMakeLists.txt | 5 - examples/common/glfw/docs/Doxyfile.in | 1863 --- examples/common/glfw/docs/DoxygenLayout.xml | 188 - examples/common/glfw/docs/build.dox | 303 - examples/common/glfw/docs/compat.dox | 179 - examples/common/glfw/docs/compile.dox | 315 - examples/common/glfw/docs/context.dox | 329 - examples/common/glfw/docs/extra.css | 1 - examples/common/glfw/docs/extra.less | 370 - examples/common/glfw/docs/footer.html | 7 - examples/common/glfw/docs/header.html | 34 - examples/common/glfw/docs/input.dox | 588 - examples/common/glfw/docs/internal.dox | 116 - examples/common/glfw/docs/intro.dox | 347 - examples/common/glfw/docs/main.dox | 47 - examples/common/glfw/docs/monitor.dox | 204 - examples/common/glfw/docs/moving.dox | 494 - examples/common/glfw/docs/news.dox | 292 - examples/common/glfw/docs/quick.dox | 328 - examples/common/glfw/docs/rift.dox | 199 - examples/common/glfw/docs/spaces.svg | 872 -- examples/common/glfw/docs/window.dox | 803 -- examples/common/glfw/examples/CMakeLists.txt | 80 - examples/common/glfw/examples/boing.c | 669 - examples/common/glfw/examples/gears.c | 372 - examples/common/glfw/examples/heightmap.c | 509 - examples/common/glfw/examples/particles.c | 1061 -- examples/common/glfw/examples/simple.c | 102 - examples/common/glfw/examples/splitview.c | 511 - examples/common/glfw/examples/wave.c | 452 - examples/common/glfw/include/GLFW/glfw3.h | 3355 ----- .../common/glfw/include/GLFW/glfw3native.h | 356 - examples/common/glfw/src/CMakeLists.txt | 95 - examples/common/glfw/src/cocoa_init.m | 272 - examples/common/glfw/src/cocoa_monitor.m | 439 - examples/common/glfw/src/cocoa_platform.h | 124 - examples/common/glfw/src/cocoa_window.m | 1284 -- examples/common/glfw/src/context.c | 665 - examples/common/glfw/src/egl_context.c | 533 - examples/common/glfw/src/egl_context.h | 85 - examples/common/glfw/src/glfw3.pc.in | 13 - examples/common/glfw/src/glfw3Config.cmake.in | 15 - examples/common/glfw/src/glfw_config.h.in | 87 - examples/common/glfw/src/glx_context.c | 558 - examples/common/glfw/src/glx_context.h | 120 - examples/common/glfw/src/init.c | 201 - examples/common/glfw/src/input.c | 596 - examples/common/glfw/src/internal.h | 886 -- examples/common/glfw/src/iokit_joystick.h | 61 - examples/common/glfw/src/iokit_joystick.m | 506 - examples/common/glfw/src/linux_joystick.c | 322 - examples/common/glfw/src/linux_joystick.h | 63 - examples/common/glfw/src/mach_time.c | 71 - examples/common/glfw/src/mir_init.c | 101 - examples/common/glfw/src/mir_monitor.c | 138 - examples/common/glfw/src/mir_platform.h | 110 - examples/common/glfw/src/mir_window.c | 687 - examples/common/glfw/src/monitor.c | 442 - examples/common/glfw/src/nsgl_context.h | 62 - examples/common/glfw/src/nsgl_context.m | 314 - examples/common/glfw/src/posix_time.c | 97 - examples/common/glfw/src/posix_time.h | 49 - examples/common/glfw/src/posix_tls.c | 66 - examples/common/glfw/src/posix_tls.h | 49 - examples/common/glfw/src/wgl_context.c | 709 - examples/common/glfw/src/wgl_context.h | 89 - examples/common/glfw/src/win32_init.c | 394 - examples/common/glfw/src/win32_monitor.c | 348 - examples/common/glfw/src/win32_platform.h | 250 - examples/common/glfw/src/win32_time.c | 86 - examples/common/glfw/src/win32_tls.c | 69 - examples/common/glfw/src/win32_tls.h | 48 - examples/common/glfw/src/win32_window.c | 1312 -- examples/common/glfw/src/window.c | 740 - examples/common/glfw/src/winmm_joystick.c | 177 - examples/common/glfw/src/winmm_joystick.h | 47 - examples/common/glfw/src/wl_init.c | 630 - examples/common/glfw/src/wl_monitor.c | 250 - examples/common/glfw/src/wl_platform.h | 140 - examples/common/glfw/src/wl_window.c | 524 - examples/common/glfw/src/x11_init.c | 816 -- examples/common/glfw/src/x11_monitor.c | 490 - examples/common/glfw/src/x11_platform.h | 259 - examples/common/glfw/src/x11_window.c | 1935 --- examples/common/glfw/src/xkb_unicode.c | 889 -- examples/common/glfw/src/xkb_unicode.h | 33 - examples/common/glfw/tests/CMakeLists.txt | 81 - examples/common/glfw/tests/accuracy.c | 128 - examples/common/glfw/tests/clipboard.c | 149 - examples/common/glfw/tests/cursor.c | 289 - examples/common/glfw/tests/cursoranim.c | 135 - examples/common/glfw/tests/defaults.c | 131 - examples/common/glfw/tests/empty.c | 129 - examples/common/glfw/tests/events.c | 581 - examples/common/glfw/tests/fsaa.c | 162 - examples/common/glfw/tests/gamma.c | 181 - examples/common/glfw/tests/glfwinfo.c | 429 - examples/common/glfw/tests/iconify.c | 254 - examples/common/glfw/tests/joysticks.c | 234 - examples/common/glfw/tests/modes.c | 240 - examples/common/glfw/tests/peter.c | 151 - examples/common/glfw/tests/reopen.c | 177 - examples/common/glfw/tests/sharing.c | 184 - examples/common/glfw/tests/tearing.c | 130 - examples/common/glfw/tests/threads.c | 135 - examples/common/glfw/tests/title.c | 76 - examples/common/glfw/tests/windows.c | 117 - examples/common/meshes/capsule.obj | 1060 -- examples/common/meshes/cone.obj | 101 - examples/common/meshes/convexmesh.obj | 125 - examples/common/meshes/cylinder.obj | 293 - examples/common/meshes/dumbbell.obj | 1396 -- examples/common/meshes/sphere.obj | 997 -- .../common/opengl-framework/CMakeLists.txt | 84 - .../opengl-framework/cmake/FindFREEGLUT.cmake | 32 - .../opengl-framework/cmake/FindGLEW.cmake | 65 - .../common/opengl-framework/src/Camera.cpp | 97 - examples/common/opengl-framework/src/Camera.h | 181 - .../src/FrameBufferObject.cpp | 115 - .../opengl-framework/src/FrameBufferObject.h | 105 - .../common/opengl-framework/src/Light.cpp | 100 - examples/common/opengl-framework/src/Light.h | 181 - examples/common/opengl-framework/src/Mesh.cpp | 176 - examples/common/opengl-framework/src/Mesh.h | 411 - .../opengl-framework/src/MeshReaderWriter.cpp | 393 - .../opengl-framework/src/MeshReaderWriter.h | 96 - .../common/opengl-framework/src/Object3D.cpp | 41 - .../common/opengl-framework/src/Object3D.h | 149 - .../common/opengl-framework/src/Shader.cpp | 206 - examples/common/opengl-framework/src/Shader.h | 260 - .../common/opengl-framework/src/Texture2D.cpp | 84 - .../common/opengl-framework/src/Texture2D.h | 142 - .../src/TextureReaderWriter.cpp | 332 - .../src/TextureReaderWriter.h | 79 - .../src/VertexBufferObject.cpp | 84 - .../opengl-framework/src/VertexBufferObject.h | 106 - .../common/opengl-framework/src/definitions.h | 39 - .../common/opengl-framework/src/maths/Color.h | 85 - .../opengl-framework/src/maths/Matrix3.h | 279 - .../opengl-framework/src/maths/Matrix4.h | 427 - .../opengl-framework/src/maths/Vector2.h | 159 - .../opengl-framework/src/maths/Vector3.h | 203 - .../opengl-framework/src/maths/Vector4.h | 167 - .../opengl-framework/src/openglframework.h | 48 - .../opengl-framework/src/shaders/depth.frag | 32 - .../opengl-framework/src/shaders/depth.vert | 36 - .../opengl-framework/src/shaders/phong.frag | 67 - .../opengl-framework/src/shaders/phong.vert | 50 - examples/cubes/CMakeLists.txt | 34 - examples/cubes/Cubes.cpp | 148 - examples/cubes/Scene.cpp | 197 - examples/cubes/Scene.h | 120 - examples/joints/CMakeLists.txt | 34 - examples/joints/Joints.cpp | 149 - examples/joints/Scene.cpp | 394 - examples/joints/Scene.h | 172 - examples/raycast/CMakeLists.txt | 43 - examples/raycast/Raycast.cpp | 155 - examples/raycast/Scene.cpp | 307 - examples/raycast/Scene.h | 200 - 214 files changed, 5 insertions(+), 73008 deletions(-) delete mode 100644 examples/CMakeLists.txt delete mode 100644 examples/collisionshapes/CMakeLists.txt delete mode 100644 examples/collisionshapes/CollisionShapes.cpp delete mode 100644 examples/collisionshapes/Scene.cpp delete mode 100644 examples/collisionshapes/Scene.h delete mode 100644 examples/common/Box.cpp delete mode 100644 examples/common/Box.h delete mode 100644 examples/common/CMakeLists.txt delete mode 100644 examples/common/Capsule.cpp delete mode 100644 examples/common/Capsule.h delete mode 100644 examples/common/Cone.cpp delete mode 100644 examples/common/Cone.h delete mode 100644 examples/common/ConvexMesh.cpp delete mode 100644 examples/common/ConvexMesh.h delete mode 100644 examples/common/Cylinder.cpp delete mode 100644 examples/common/Cylinder.h delete mode 100644 examples/common/Dumbbell.cpp delete mode 100644 examples/common/Dumbbell.h delete mode 100644 examples/common/Line.cpp delete mode 100644 examples/common/Line.h delete mode 100644 examples/common/Sphere.cpp delete mode 100644 examples/common/Sphere.h delete mode 100644 examples/common/Viewer.cpp delete mode 100644 examples/common/Viewer.h delete mode 100644 examples/common/VisualContactPoint.cpp delete mode 100644 examples/common/VisualContactPoint.h delete mode 100644 examples/common/glfw/.gitignore delete mode 100644 examples/common/glfw/CMake/amd64-mingw32msvc.cmake delete mode 100644 examples/common/glfw/CMake/i586-mingw32msvc.cmake delete mode 100644 examples/common/glfw/CMake/i686-pc-mingw32.cmake delete mode 100644 examples/common/glfw/CMake/i686-w64-mingw32.cmake delete mode 100644 examples/common/glfw/CMake/modules/FindEGL.cmake delete mode 100644 examples/common/glfw/CMake/modules/FindGLESv1.cmake delete mode 100644 examples/common/glfw/CMake/modules/FindGLESv2.cmake delete mode 100644 examples/common/glfw/CMake/modules/FindMir.cmake delete mode 100644 examples/common/glfw/CMake/modules/FindWayland.cmake delete mode 100644 examples/common/glfw/CMake/modules/FindXKBCommon.cmake delete mode 100644 examples/common/glfw/CMake/x86_64-w64-mingw32.cmake delete mode 100644 examples/common/glfw/CMakeLists.txt delete mode 100644 examples/common/glfw/COPYING.txt delete mode 100644 examples/common/glfw/README.md delete mode 100644 examples/common/glfw/cmake_uninstall.cmake.in delete mode 100644 examples/common/glfw/deps/EGL/eglext.h delete mode 100644 examples/common/glfw/deps/GL/glext.h delete mode 100644 examples/common/glfw/deps/GL/glxext.h delete mode 100644 examples/common/glfw/deps/GL/wglext.h delete mode 100644 examples/common/glfw/deps/KHR/khrplatform.h delete mode 100644 examples/common/glfw/deps/getopt.c delete mode 100644 examples/common/glfw/deps/getopt.h delete mode 100644 examples/common/glfw/deps/glad.c delete mode 100644 examples/common/glfw/deps/glad/glad.h delete mode 100644 examples/common/glfw/deps/tinycthread.c delete mode 100644 examples/common/glfw/deps/tinycthread.h delete mode 100644 examples/common/glfw/docs/CMakeLists.txt delete mode 100644 examples/common/glfw/docs/Doxyfile.in delete mode 100644 examples/common/glfw/docs/DoxygenLayout.xml delete mode 100644 examples/common/glfw/docs/build.dox delete mode 100644 examples/common/glfw/docs/compat.dox delete mode 100644 examples/common/glfw/docs/compile.dox delete mode 100644 examples/common/glfw/docs/context.dox delete mode 100644 examples/common/glfw/docs/extra.css delete mode 100644 examples/common/glfw/docs/extra.less delete mode 100644 examples/common/glfw/docs/footer.html delete mode 100644 examples/common/glfw/docs/header.html delete mode 100644 examples/common/glfw/docs/input.dox delete mode 100644 examples/common/glfw/docs/internal.dox delete mode 100644 examples/common/glfw/docs/intro.dox delete mode 100644 examples/common/glfw/docs/main.dox delete mode 100644 examples/common/glfw/docs/monitor.dox delete mode 100644 examples/common/glfw/docs/moving.dox delete mode 100644 examples/common/glfw/docs/news.dox delete mode 100644 examples/common/glfw/docs/quick.dox delete mode 100644 examples/common/glfw/docs/rift.dox delete mode 100644 examples/common/glfw/docs/spaces.svg delete mode 100644 examples/common/glfw/docs/window.dox delete mode 100644 examples/common/glfw/examples/CMakeLists.txt delete mode 100644 examples/common/glfw/examples/boing.c delete mode 100644 examples/common/glfw/examples/gears.c delete mode 100644 examples/common/glfw/examples/heightmap.c delete mode 100644 examples/common/glfw/examples/particles.c delete mode 100644 examples/common/glfw/examples/simple.c delete mode 100644 examples/common/glfw/examples/splitview.c delete mode 100644 examples/common/glfw/examples/wave.c delete mode 100644 examples/common/glfw/include/GLFW/glfw3.h delete mode 100644 examples/common/glfw/include/GLFW/glfw3native.h delete mode 100644 examples/common/glfw/src/CMakeLists.txt delete mode 100644 examples/common/glfw/src/cocoa_init.m delete mode 100644 examples/common/glfw/src/cocoa_monitor.m delete mode 100644 examples/common/glfw/src/cocoa_platform.h delete mode 100644 examples/common/glfw/src/cocoa_window.m delete mode 100644 examples/common/glfw/src/context.c delete mode 100644 examples/common/glfw/src/egl_context.c delete mode 100644 examples/common/glfw/src/egl_context.h delete mode 100644 examples/common/glfw/src/glfw3.pc.in delete mode 100644 examples/common/glfw/src/glfw3Config.cmake.in delete mode 100644 examples/common/glfw/src/glfw_config.h.in delete mode 100644 examples/common/glfw/src/glx_context.c delete mode 100644 examples/common/glfw/src/glx_context.h delete mode 100644 examples/common/glfw/src/init.c delete mode 100644 examples/common/glfw/src/input.c delete mode 100644 examples/common/glfw/src/internal.h delete mode 100644 examples/common/glfw/src/iokit_joystick.h delete mode 100644 examples/common/glfw/src/iokit_joystick.m delete mode 100644 examples/common/glfw/src/linux_joystick.c delete mode 100644 examples/common/glfw/src/linux_joystick.h delete mode 100644 examples/common/glfw/src/mach_time.c delete mode 100644 examples/common/glfw/src/mir_init.c delete mode 100644 examples/common/glfw/src/mir_monitor.c delete mode 100644 examples/common/glfw/src/mir_platform.h delete mode 100644 examples/common/glfw/src/mir_window.c delete mode 100644 examples/common/glfw/src/monitor.c delete mode 100644 examples/common/glfw/src/nsgl_context.h delete mode 100644 examples/common/glfw/src/nsgl_context.m delete mode 100644 examples/common/glfw/src/posix_time.c delete mode 100644 examples/common/glfw/src/posix_time.h delete mode 100644 examples/common/glfw/src/posix_tls.c delete mode 100644 examples/common/glfw/src/posix_tls.h delete mode 100644 examples/common/glfw/src/wgl_context.c delete mode 100644 examples/common/glfw/src/wgl_context.h delete mode 100644 examples/common/glfw/src/win32_init.c delete mode 100644 examples/common/glfw/src/win32_monitor.c delete mode 100644 examples/common/glfw/src/win32_platform.h delete mode 100644 examples/common/glfw/src/win32_time.c delete mode 100644 examples/common/glfw/src/win32_tls.c delete mode 100644 examples/common/glfw/src/win32_tls.h delete mode 100644 examples/common/glfw/src/win32_window.c delete mode 100644 examples/common/glfw/src/window.c delete mode 100644 examples/common/glfw/src/winmm_joystick.c delete mode 100644 examples/common/glfw/src/winmm_joystick.h delete mode 100644 examples/common/glfw/src/wl_init.c delete mode 100644 examples/common/glfw/src/wl_monitor.c delete mode 100644 examples/common/glfw/src/wl_platform.h delete mode 100644 examples/common/glfw/src/wl_window.c delete mode 100644 examples/common/glfw/src/x11_init.c delete mode 100644 examples/common/glfw/src/x11_monitor.c delete mode 100644 examples/common/glfw/src/x11_platform.h delete mode 100644 examples/common/glfw/src/x11_window.c delete mode 100644 examples/common/glfw/src/xkb_unicode.c delete mode 100644 examples/common/glfw/src/xkb_unicode.h delete mode 100644 examples/common/glfw/tests/CMakeLists.txt delete mode 100644 examples/common/glfw/tests/accuracy.c delete mode 100644 examples/common/glfw/tests/clipboard.c delete mode 100644 examples/common/glfw/tests/cursor.c delete mode 100644 examples/common/glfw/tests/cursoranim.c delete mode 100644 examples/common/glfw/tests/defaults.c delete mode 100644 examples/common/glfw/tests/empty.c delete mode 100644 examples/common/glfw/tests/events.c delete mode 100644 examples/common/glfw/tests/fsaa.c delete mode 100644 examples/common/glfw/tests/gamma.c delete mode 100644 examples/common/glfw/tests/glfwinfo.c delete mode 100644 examples/common/glfw/tests/iconify.c delete mode 100644 examples/common/glfw/tests/joysticks.c delete mode 100644 examples/common/glfw/tests/modes.c delete mode 100644 examples/common/glfw/tests/peter.c delete mode 100644 examples/common/glfw/tests/reopen.c delete mode 100644 examples/common/glfw/tests/sharing.c delete mode 100644 examples/common/glfw/tests/tearing.c delete mode 100644 examples/common/glfw/tests/threads.c delete mode 100644 examples/common/glfw/tests/title.c delete mode 100644 examples/common/glfw/tests/windows.c delete mode 100644 examples/common/meshes/capsule.obj delete mode 100644 examples/common/meshes/cone.obj delete mode 100644 examples/common/meshes/convexmesh.obj delete mode 100644 examples/common/meshes/cylinder.obj delete mode 100644 examples/common/meshes/dumbbell.obj delete mode 100644 examples/common/meshes/sphere.obj delete mode 100644 examples/common/opengl-framework/CMakeLists.txt delete mode 100644 examples/common/opengl-framework/cmake/FindFREEGLUT.cmake delete mode 100644 examples/common/opengl-framework/cmake/FindGLEW.cmake delete mode 100644 examples/common/opengl-framework/src/Camera.cpp delete mode 100644 examples/common/opengl-framework/src/Camera.h delete mode 100644 examples/common/opengl-framework/src/FrameBufferObject.cpp delete mode 100644 examples/common/opengl-framework/src/FrameBufferObject.h delete mode 100644 examples/common/opengl-framework/src/Light.cpp delete mode 100644 examples/common/opengl-framework/src/Light.h delete mode 100644 examples/common/opengl-framework/src/Mesh.cpp delete mode 100644 examples/common/opengl-framework/src/Mesh.h delete mode 100644 examples/common/opengl-framework/src/MeshReaderWriter.cpp delete mode 100644 examples/common/opengl-framework/src/MeshReaderWriter.h delete mode 100644 examples/common/opengl-framework/src/Object3D.cpp delete mode 100644 examples/common/opengl-framework/src/Object3D.h delete mode 100644 examples/common/opengl-framework/src/Shader.cpp delete mode 100644 examples/common/opengl-framework/src/Shader.h delete mode 100644 examples/common/opengl-framework/src/Texture2D.cpp delete mode 100644 examples/common/opengl-framework/src/Texture2D.h delete mode 100644 examples/common/opengl-framework/src/TextureReaderWriter.cpp delete mode 100644 examples/common/opengl-framework/src/TextureReaderWriter.h delete mode 100644 examples/common/opengl-framework/src/VertexBufferObject.cpp delete mode 100644 examples/common/opengl-framework/src/VertexBufferObject.h delete mode 100644 examples/common/opengl-framework/src/definitions.h delete mode 100644 examples/common/opengl-framework/src/maths/Color.h delete mode 100644 examples/common/opengl-framework/src/maths/Matrix3.h delete mode 100644 examples/common/opengl-framework/src/maths/Matrix4.h delete mode 100644 examples/common/opengl-framework/src/maths/Vector2.h delete mode 100644 examples/common/opengl-framework/src/maths/Vector3.h delete mode 100644 examples/common/opengl-framework/src/maths/Vector4.h delete mode 100644 examples/common/opengl-framework/src/openglframework.h delete mode 100644 examples/common/opengl-framework/src/shaders/depth.frag delete mode 100644 examples/common/opengl-framework/src/shaders/depth.vert delete mode 100644 examples/common/opengl-framework/src/shaders/phong.frag delete mode 100644 examples/common/opengl-framework/src/shaders/phong.vert delete mode 100644 examples/cubes/CMakeLists.txt delete mode 100644 examples/cubes/Cubes.cpp delete mode 100644 examples/cubes/Scene.cpp delete mode 100644 examples/cubes/Scene.h delete mode 100644 examples/joints/CMakeLists.txt delete mode 100644 examples/joints/Joints.cpp delete mode 100644 examples/joints/Scene.cpp delete mode 100644 examples/joints/Scene.h delete mode 100644 examples/raycast/CMakeLists.txt delete mode 100644 examples/raycast/Raycast.cpp delete mode 100644 examples/raycast/Scene.cpp delete mode 100644 examples/raycast/Scene.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 10ddb5cb..819b99ee 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ SET(LIBRARY_OUTPUT_PATH "lib") SET(OUR_EXECUTABLE_OUTPUT_PATH "${PROJECT_BINARY_DIR}/bin") # Options -OPTION(COMPILE_EXAMPLES "Select this if you want to build the examples" OFF) +OPTION(COMPILE_TESTBED "Select this if you want to build the testbed application" OFF) OPTION(COMPILE_TESTS "Select this if you want to build the tests" OFF) OPTION(PROFILING_ENABLED "Select this if you want to compile with enabled profiling" OFF) OPTION(DOUBLE_PRECISION_ENABLED "Select this if you want to compile using double precision floating @@ -142,10 +142,10 @@ SET (REACTPHYSICS3D_SOURCES # Create the library ADD_LIBRARY (reactphysics3d STATIC ${REACTPHYSICS3D_SOURCES}) -# If we need to compile the examples -IF(COMPILE_EXAMPLES) - add_subdirectory(examples/) -ENDIF(COMPILE_EXAMPLES) +# If we need to compile the testbed application +IF(COMPILE_TESTBED) + add_subdirectory(testbed/) +ENDIF(COMPILE_TESTBED) # If we need to compile the tests IF(COMPILE_TESTS) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt deleted file mode 100644 index 3743dc56..00000000 --- a/examples/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -# Minimum cmake version required -CMAKE_MINIMUM_REQUIRED(VERSION 2.6) - -# Set a variable for the directory of the opengl-framework -SET(OPENGLFRAMEWORK_DIR "${CMAKE_CURRENT_SOURCE_DIR}/common/opengl-framework") - -ADD_SUBDIRECTORY(common/) -ADD_SUBDIRECTORY(cubes/) -ADD_SUBDIRECTORY(joints/) -ADD_SUBDIRECTORY(collisionshapes/) -ADD_SUBDIRECTORY(raycast/) diff --git a/examples/collisionshapes/CMakeLists.txt b/examples/collisionshapes/CMakeLists.txt deleted file mode 100644 index 6bdd5d3e..00000000 --- a/examples/collisionshapes/CMakeLists.txt +++ /dev/null @@ -1,42 +0,0 @@ -# Minimum cmake version required -cmake_minimum_required(VERSION 2.6) - -# Project configuration -PROJECT(CollisionShapes) - -# Where to build the executables -SET(EXECUTABLE_OUTPUT_PATH "${OUR_EXECUTABLE_OUTPUT_PATH}/collisionshapes") -SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}) -SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${EXECUTABLE_OUTPUT_PATH}) -SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${EXECUTABLE_OUTPUT_PATH}) - -# Copy the shaders used for the demo into the build directory -FILE(COPY "${OPENGLFRAMEWORK_DIR}/src/shaders/" DESTINATION "${EXECUTABLE_OUTPUT_PATH}/shaders/") - -# Copy the meshes used for the demo into the build directory -FILE(COPY "../common/meshes/" DESTINATION "${EXECUTABLE_OUTPUT_PATH}/meshes/") - -# Headers -INCLUDE_DIRECTORIES("${OPENGLFRAMEWORK_DIR}/src/" "../common/glfw/include/" "../common/") - -# Source files -SET(COLLISION_SHAPES_SOURCES - CollisionShapes.cpp - Scene.cpp - Scene.h - "../common/VisualContactPoint.cpp" - "../common/ConvexMesh.cpp" - "../common/Capsule.cpp" - "../common/Sphere.cpp" - "../common/Cylinder.cpp" - "../common/Cone.cpp" - "../common/Dumbbell.cpp" - "../common/Box.cpp" - "../common/Viewer.cpp" -) - -# Create the executable -ADD_EXECUTABLE(collisionshapes ${COLLISION_SHAPES_SOURCES}) - -# Link with libraries -TARGET_LINK_LIBRARIES(collisionshapes reactphysics3d openglframework glfw ${GLFW_LIBRARIES}) diff --git a/examples/collisionshapes/CollisionShapes.cpp b/examples/collisionshapes/CollisionShapes.cpp deleted file mode 100644 index f8affc1d..00000000 --- a/examples/collisionshapes/CollisionShapes.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/******************************************************************************** -* ReactPhysics3D physics library, http://www.reactphysics3d.com * -* Copyright (c) 2010-2015 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -// Libraries -#include "Scene.h" -#include "../common/Viewer.h" - -// Declarations -void simulate(); -void render(); -void update(); -void mouseButton(GLFWwindow* window, int button, int action, int mods); -void mouseMotion(GLFWwindow* window, double x, double y); -void keyboard(GLFWwindow* window, int key, int scancode, int action, int mods); -void scroll(GLFWwindow* window, double xAxis, double yAxis); -void init(); - -// Namespaces -using namespace openglframework; - -// Global variables -Viewer* viewer; -Scene* scene; - -// Main function -int main(int argc, char** argv) { - - // Create and initialize the Viewer - viewer = new Viewer(); - Vector2 windowsSize = Vector2(800, 600); - Vector2 windowsPosition = Vector2(100, 100); - viewer->init(argc, argv, "ReactPhysics3D Examples - Collision Shapes", - windowsSize, windowsPosition, true); - - // If the shaders and meshes folders are not specified as an argument - if (argc < 3) { - std::cerr << "Error : You need to specify the shaders folder as the first argument" - << " and the meshes folder as the second argument" << std::endl; - return 1; - } - - // Get the path of the shaders folder - std::string shaderFolderPath(argv[1]); - std::string meshFolderPath(argv[2]); - - // Register callback methods - viewer->registerUpdateFunction(update); - viewer->registerKeyboardCallback(keyboard); - viewer->registerMouseButtonCallback(mouseButton); - viewer->registerMouseCursorCallback(mouseMotion); - viewer->registerScrollingCallback(scroll); - - // Create the scene - scene = new Scene(viewer, shaderFolderPath, meshFolderPath); - - init(); - - viewer->startMainLoop(); - - delete viewer; - delete scene; - - return 0; -} - -// Update function that is called each frame -void update() { - - // Take a simulation step - simulate(); - - // Render - render(); -} - -// Simulate function -void simulate() { - - // Physics simulation - scene->simulate(); - - viewer->computeFPS(); -} - -// Initialization -void init() { - - // Define the background color (black) - glClearColor(0.0, 0.0, 0.0, 1.0); -} - -// Callback method to receive keyboard events -void keyboard(GLFWwindow* window, int key, int scancode, int action, int mods) { - if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) { - glfwSetWindowShouldClose(window, GL_TRUE); - } - else if (key == GLFW_KEY_SPACE && action == GLFW_PRESS) { - scene->pauseContinueSimulation(); - } -} - -// Callback method to receive scrolling events -void scroll(GLFWwindow* window, double xAxis, double yAxis) { - viewer->scrollingEvent(static_cast(yAxis)); -} - -// Called when a mouse button event occurs -void mouseButton(GLFWwindow* window, int button, int action, int mods) { - viewer->mouseButtonEvent(button, action); -} - -// Called when a mouse motion event occurs -void mouseMotion(GLFWwindow* window, double x, double y) { - viewer->mouseMotionEvent(x, y); -} - -// Display the scene -void render() { - - // Render the scene - scene->render(); - - // Display the FPS - viewer->displayGUI(); - - // Check the OpenGL errors - Viewer::checkOpenGLErrors(); -} - - diff --git a/examples/collisionshapes/Scene.cpp b/examples/collisionshapes/Scene.cpp deleted file mode 100644 index 740a48e6..00000000 --- a/examples/collisionshapes/Scene.cpp +++ /dev/null @@ -1,444 +0,0 @@ -/******************************************************************************** -* ReactPhysics3D physics library, http://www.reactphysics3d.com * -* Copyright (c) 2010-2015 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -// Libraries -#include "Scene.h" - -// Namespaces -using namespace openglframework; - -// Constructor -Scene::Scene(Viewer* viewer, const std::string& shaderFolderPath, const std::string& meshFolderPath) - : mViewer(viewer), mLight0(0), - mPhongShader(shaderFolderPath + "phong.vert", - shaderFolderPath +"phong.frag"), mIsRunning(false) { - - // Move the light 0 - mLight0.translateWorld(Vector3(50, 50, 50)); - - // Compute the radius and the center of the scene - float radiusScene = 30.0f; - openglframework::Vector3 center(0, 5, 0); - - // Set the center of the scene - mViewer->setScenePosition(center, radiusScene); - - // Gravity vector in the dynamics world - rp3d::Vector3 gravity(0, -9.81, 0); - - // Time step for the physics simulation - rp3d::decimal timeStep = 1.0f / 60.0f; - - // Create the dynamics world for the physics simulation - mDynamicsWorld = new rp3d::DynamicsWorld(gravity, timeStep); - - // Set the number of iterations of the constraint solver - mDynamicsWorld->setNbIterationsVelocitySolver(15); - - // Create the static data for the visual contact points - VisualContactPoint::createStaticData(meshFolderPath); - - float radius = 3.0f; - - for (int i=0; igetRigidBody()->getMaterial(); - material.setBounciness(rp3d::decimal(0.2)); - - // Add the mesh the list of dumbbells in the scene - mDumbbells.push_back(dumbbell); - } - - // Create all the boxes of the scene - for (int i=0; igetRigidBody()->getMaterial(); - material.setBounciness(rp3d::decimal(0.2)); - - // Add the sphere the list of sphere in the scene - mBoxes.push_back(box); - } - - // Create all the spheres of the scene - for (int i=0; igetRigidBody()->getMaterial(); - material.setBounciness(rp3d::decimal(0.2)); - - // Add the sphere the list of sphere in the scene - mSpheres.push_back(sphere); - } - - // Create all the cones of the scene - for (int i=0; igetRigidBody()->getMaterial(); - material.setBounciness(rp3d::decimal(0.2)); - - // Add the cone the list of sphere in the scene - mCones.push_back(cone); - } - - // Create all the cylinders of the scene - for (int i=0; igetRigidBody()->getMaterial(); - material.setBounciness(rp3d::decimal(0.2)); - - // Add the cylinder the list of sphere in the scene - mCylinders.push_back(cylinder); - } - - // Create all the capsules of the scene - for (int i=0; igetRigidBody()->getMaterial(); - material.setBounciness(rp3d::decimal(0.2)); - - // Add the cylinder the list of sphere in the scene - mCapsules.push_back(capsule); - } - - // Create all the convex meshes of the scene - for (int i=0; igetRigidBody()->getMaterial(); - material.setBounciness(rp3d::decimal(0.2)); - - // Add the mesh the list of sphere in the scene - mConvexMeshes.push_back(mesh); - } - - // Create the floor - openglframework::Vector3 floorPosition(0, 0, 0); - mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld); - - // The floor must be a static rigid body - mFloor->getRigidBody()->setType(rp3d::STATIC); - - // Change the material properties of the rigid body - rp3d::Material& material = mFloor->getRigidBody()->getMaterial(); - material.setBounciness(rp3d::decimal(0.2)); - - // Start the simulation - startSimulation(); -} - -// Destructor -Scene::~Scene() { - - // Stop the physics simulation - stopSimulation(); - - // Destroy the shader - mPhongShader.destroy(); - - // Destroy all the boxes of the scene - for (std::vector::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { - - // Destroy the corresponding rigid body from the dynamics world - mDynamicsWorld->destroyRigidBody((*it)->getRigidBody()); - - // Destroy the box - delete (*it); - } - - // Destroy all the sphere of the scene - for (std::vector::iterator it = mSpheres.begin(); it != mSpheres.end(); ++it) { - - // Destroy the corresponding rigid body from the dynamics world - mDynamicsWorld->destroyRigidBody((*it)->getRigidBody()); - - // Destroy the sphere - delete (*it); - } - - // Destroy all the cones of the scene - for (std::vector::iterator it = mCones.begin(); it != mCones.end(); ++it) { - - // Destroy the corresponding rigid body from the dynamics world - mDynamicsWorld->destroyRigidBody((*it)->getRigidBody()); - - // Destroy the sphere - delete (*it); - } - - // Destroy all the cylinders of the scene - for (std::vector::iterator it = mCylinders.begin(); it != mCylinders.end(); ++it) { - - // Destroy the corresponding rigid body from the dynamics world - mDynamicsWorld->destroyRigidBody((*it)->getRigidBody()); - - // Destroy the sphere - delete (*it); - } - - // Destroy all the capsules of the scene - for (std::vector::iterator it = mCapsules.begin(); it != mCapsules.end(); ++it) { - - // Destroy the corresponding rigid body from the dynamics world - mDynamicsWorld->destroyRigidBody((*it)->getRigidBody()); - - // Destroy the sphere - delete (*it); - } - - // Destroy all the convex meshes of the scene - for (std::vector::iterator it = mConvexMeshes.begin(); - it != mConvexMeshes.end(); ++it) { - - // Destroy the corresponding rigid body from the dynamics world - mDynamicsWorld->destroyRigidBody((*it)->getRigidBody()); - - // Destroy the convex mesh - delete (*it); - } - - // Destroy all the dumbbell of the scene - for (std::vector::iterator it = mDumbbells.begin(); - it != mDumbbells.end(); ++it) { - - // Destroy the corresponding rigid body from the dynamics world - mDynamicsWorld->destroyRigidBody((*it)->getRigidBody()); - - // Destroy the convex mesh - delete (*it); - } - - // Destroy the rigid body of the floor - mDynamicsWorld->destroyRigidBody(mFloor->getRigidBody()); - - // Destroy the floor - delete mFloor; - - // Destroy the dynamics world - delete mDynamicsWorld; -} - -// Take a step for the simulation -void Scene::simulate() { - - // If the physics simulation is running - if (mIsRunning) { - - // Take a simulation step - mDynamicsWorld->update(); - - // Update the position and orientation of the boxes - for (std::vector::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { - - // Update the transform used for the rendering - (*it)->updateTransform(); - } - - // Update the position and orientation of the sphere - for (std::vector::iterator it = mSpheres.begin(); it != mSpheres.end(); ++it) { - - // Update the transform used for the rendering - (*it)->updateTransform(); - } - - // Update the position and orientation of the cones - for (std::vector::iterator it = mCones.begin(); it != mCones.end(); ++it) { - - // Update the transform used for the rendering - (*it)->updateTransform(); - } - - // Update the position and orientation of the cylinders - for (std::vector::iterator it = mCylinders.begin(); it != mCylinders.end(); ++it) { - - // Update the transform used for the rendering - (*it)->updateTransform(); - } - - // Update the position and orientation of the capsules - for (std::vector::iterator it = mCapsules.begin(); it != mCapsules.end(); ++it) { - - // Update the transform used for the rendering - (*it)->updateTransform(); - } - - // Update the position and orientation of the convex meshes - for (std::vector::iterator it = mConvexMeshes.begin(); - it != mConvexMeshes.end(); ++it) { - - // Update the transform used for the rendering - (*it)->updateTransform(); - } - - // Update the position and orientation of the dumbbells - for (std::vector::iterator it = mDumbbells.begin(); - it != mDumbbells.end(); ++it) { - - // Update the transform used for the rendering - (*it)->updateTransform(); - } - - mFloor->updateTransform(); - } -} - -// Render the scene -void Scene::render() { - - glEnable(GL_DEPTH_TEST); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glEnable(GL_CULL_FACE); - - // Get the world-space to camera-space matrix - const Camera& camera = mViewer->getCamera(); - const openglframework::Matrix4 worldToCameraMatrix = camera.getTransformMatrix().getInverse(); - - // Bind the shader - mPhongShader.bind(); - - // Set the variables of the shader - mPhongShader.setMatrix4x4Uniform("projectionMatrix", camera.getProjectionMatrix()); - mPhongShader.setVector3Uniform("light0PosCameraSpace", worldToCameraMatrix * mLight0.getOrigin()); - mPhongShader.setVector3Uniform("lightAmbientColor", Vector3(0.3f, 0.3f, 0.3f)); - const Color& diffColLight0 = mLight0.getDiffuseColor(); - const Color& specColLight0 = mLight0.getSpecularColor(); - mPhongShader.setVector3Uniform("light0DiffuseColor", Vector3(diffColLight0.r, diffColLight0.g, diffColLight0.b)); - mPhongShader.setVector3Uniform("light0SpecularColor", Vector3(specColLight0.r, specColLight0.g, specColLight0.b)); - mPhongShader.setFloatUniform("shininess", 200.0f); - - // Render all the boxes of the scene - for (std::vector::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { - (*it)->render(mPhongShader, worldToCameraMatrix); - } - - // Render all the sphere of the scene - for (std::vector::iterator it = mSpheres.begin(); it != mSpheres.end(); ++it) { - (*it)->render(mPhongShader, worldToCameraMatrix); - } - - // Render all the cones of the scene - for (std::vector::iterator it = mCones.begin(); it != mCones.end(); ++it) { - (*it)->render(mPhongShader, worldToCameraMatrix); - } - - // Render all the cylinders of the scene - for (std::vector::iterator it = mCylinders.begin(); it != mCylinders.end(); ++it) { - (*it)->render(mPhongShader, worldToCameraMatrix); - } - - // Render all the capsules of the scene - for (std::vector::iterator it = mCapsules.begin(); it != mCapsules.end(); ++it) { - (*it)->render(mPhongShader, worldToCameraMatrix); - } - - // Render all the convex meshes of the scene - for (std::vector::iterator it = mConvexMeshes.begin(); - it != mConvexMeshes.end(); ++it) { - (*it)->render(mPhongShader, worldToCameraMatrix); - } - - // Render all the dumbbells of the scene - for (std::vector::iterator it = mDumbbells.begin(); - it != mDumbbells.end(); ++it) { - (*it)->render(mPhongShader, worldToCameraMatrix); - } - - // Render the floor - mFloor->render(mPhongShader, worldToCameraMatrix); - - // Unbind the shader - mPhongShader.unbind(); -} diff --git a/examples/collisionshapes/Scene.h b/examples/collisionshapes/Scene.h deleted file mode 100644 index 61a2e7a7..00000000 --- a/examples/collisionshapes/Scene.h +++ /dev/null @@ -1,158 +0,0 @@ -/******************************************************************************** -* ReactPhysics3D physics library, http://www.reactphysics3d.com * -* Copyright (c) 2010-2015 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -#ifndef SCENE_H -#define SCENE_H - -// Libraries -#include "openglframework.h" -#include "reactphysics3d.h" -#include "Sphere.h" -#include "Box.h" -#include "Cone.h" -#include "Cylinder.h" -#include "Capsule.h" -#include "ConvexMesh.h" -#include "Dumbbell.h" -#include "VisualContactPoint.h" -#include "../common/Viewer.h" - -// Constants -const int NB_BOXES = 2; -const int NB_CUBES = 1; -const int NB_CONES = 3; -const int NB_CYLINDERS = 2; -const int NB_CAPSULES = 1; -const int NB_MESHES = 2; -const int NB_COMPOUND_SHAPES = 2; -const openglframework::Vector3 BOX_SIZE(2, 2, 2); -const float SPHERE_RADIUS = 1.5f; -const float CONE_RADIUS = 2.0f; -const float CONE_HEIGHT = 3.0f; -const float CYLINDER_RADIUS = 1.0f; -const float CYLINDER_HEIGHT = 5.0f; -const float CAPSULE_RADIUS = 1.0f; -const float CAPSULE_HEIGHT = 1.0f; -const float DUMBBELL_HEIGHT = 1.0f; -const openglframework::Vector3 FLOOR_SIZE(20, 0.5f, 20); // Floor dimensions in meters -const float BOX_MASS = 1.0f; -const float CONE_MASS = 1.0f; -const float CYLINDER_MASS = 1.0f; -const float CAPSULE_MASS = 1.0f; -const float MESH_MASS = 1.0f; -const float FLOOR_MASS = 100.0f; // Floor mass in kilograms - -// Class Scene -class Scene { - - private : - - // -------------------- Attributes -------------------- // - - /// Pointer to the viewer - Viewer* mViewer; - - /// Light 0 - openglframework::Light mLight0; - - /// Phong shader - openglframework::Shader mPhongShader; - - /// All the spheres of the scene - std::vector mBoxes; - - std::vector mSpheres; - - std::vector mCones; - - std::vector mCylinders; - - std::vector mCapsules; - - /// All the convex meshes of the scene - std::vector mConvexMeshes; - - /// All the dumbbell of the scene - std::vector mDumbbells; - - /// Box for the floor - Box* mFloor; - - /// Dynamics world used for the physics simulation - rp3d::DynamicsWorld* mDynamicsWorld; - - /// True if the physics simulation is running - bool mIsRunning; - - public: - - // -------------------- Methods -------------------- // - - /// Constructor - Scene(Viewer* viewer, const std::string& shaderFolderPath, - const std::string& meshFolderPath); - - /// Destructor - ~Scene(); - - /// Take a step for the simulation - void simulate(); - - /// Stop the simulation - void stopSimulation(); - - /// Start the simulation - void startSimulation(); - - /// Pause or continue simulation - void pauseContinueSimulation(); - - /// Render the scene - void render(); -}; - -// Stop the simulation -inline void Scene::stopSimulation() { - mDynamicsWorld->stop(); - mIsRunning = false; -} - -// Start the simulation -inline void Scene::startSimulation() { - mDynamicsWorld->start(); - mIsRunning = true; -} - -// Pause or continue simulation -inline void Scene::pauseContinueSimulation() { - if (mIsRunning) { - stopSimulation(); - } - else { - startSimulation(); - } -} - -#endif diff --git a/examples/common/Box.cpp b/examples/common/Box.cpp deleted file mode 100644 index d0c7a1df..00000000 --- a/examples/common/Box.cpp +++ /dev/null @@ -1,239 +0,0 @@ -/******************************************************************************** -* ReactPhysics3D physics library, http://www.reactphysics3d.com * -* Copyright (c) 2010-2015 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -// Libraries -#include "Box.h" - -// Macros -#define MEMBER_OFFSET(s,m) ((char *)NULL + (offsetof(s,m))) - -// Initialize static variables -openglframework::VertexBufferObject Box::mVBOVertices(GL_ARRAY_BUFFER); -openglframework::VertexBufferObject Box::mVBOIndices(GL_ELEMENT_ARRAY_BUFFER); -bool Box::areVBOsCreated = false; -VertexData Box::mCubeVertices[8] = { - {openglframework::Vector3(1,1,1),openglframework::Vector3(1,1,1),openglframework::Color(1,0,0,1)}, - {openglframework::Vector3(-1,1,1),openglframework::Vector3(-1,1,1),openglframework::Color(1,0,0,1)}, - {openglframework::Vector3(-1,-1,1),openglframework::Vector3(-1,-1,1),openglframework::Color(1,0,0,1)}, - {openglframework::Vector3(1,-1,1),openglframework::Vector3(1,-1,1),openglframework::Color(1,0,0,1)}, - {openglframework::Vector3(1,-1,-1),openglframework::Vector3(1,-1,-1),openglframework::Color(1,0,0,1)}, - {openglframework::Vector3(-1,-1,-1),openglframework::Vector3(-1,-1,-1),openglframework::Color(1,0,0,1)}, - {openglframework::Vector3(-1,1,-1),openglframework::Vector3(-1,1,-1),openglframework::Color(1,0,0,1)}, - {openglframework::Vector3(1,1,-1),openglframework::Vector3(1,1,-1),openglframework::Color(1,0,0,1)} -}; -GLuint Box::mCubeIndices[36] = { 0, 1, 2, - 2, 3, 0, - 7, 4, 5, - 5, 6, 7, - 6, 5, 2, - 2, 1, 6, - 7, 0, 3, - 3, 4, 7, - 7, 6, 1, - 1, 0, 7, - 3, 2, 5, - 5, 4, 3}; - -// Constructor -Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &position, - reactphysics3d::CollisionWorld* world) - : openglframework::Object3D(), mColor(0.5f, 0.5f, 0.5f, 1.0f) { - - // Initialize the size of the box - mSize[0] = size.x * 0.5f; - mSize[1] = size.y * 0.5f; - mSize[2] = size.z * 0.5f; - - // Compute the scaling matrix - mScalingMatrix = openglframework::Matrix4(mSize[0], 0, 0, 0, - 0, mSize[1], 0, 0, - 0, 0, mSize[2], 0, - 0, 0, 0, 1); - - // Initialize the position where the cube will be rendered - translateWorld(position); - - // Create the collision shape for the rigid body (box shape) - // ReactPhysics3D will clone this object to create an internal one. Therefore, - // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() - const rp3d::BoxShape collisionShape(rp3d::Vector3(mSize[0], mSize[1], mSize[2])); - - // Initial position and orientation of the rigid body - rp3d::Vector3 initPosition(position.x, position.y, position.z); - rp3d::Quaternion initOrientation = rp3d::Quaternion::identity(); - rp3d::Transform transform(initPosition, initOrientation); - - // Create a rigid body in the dynamics world - mRigidBody = world->createCollisionBody(transform); - - // Add the collision shape to the body - mRigidBody->addCollisionShape(collisionShape, rp3d::Transform::identity()); - - // If the Vertex Buffer object has not been created yet - if (!areVBOsCreated) { - // Create the Vertex Buffer - createVBO(); - } - - mTransformMatrix = mTransformMatrix * mScalingMatrix; -} - -// Constructor -Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &position, - float mass, reactphysics3d::DynamicsWorld* world) - : openglframework::Object3D(), mColor(0.5f, 0.5f, 0.5f, 1.0f) { - - // Initialize the size of the box - mSize[0] = size.x * 0.5f; - mSize[1] = size.y * 0.5f; - mSize[2] = size.z * 0.5f; - - // Compute the scaling matrix - mScalingMatrix = openglframework::Matrix4(mSize[0], 0, 0, 0, - 0, mSize[1], 0, 0, - 0, 0, mSize[2], 0, - 0, 0, 0, 1); - - // Initialize the position where the cube will be rendered - translateWorld(position); - - // Create the collision shape for the rigid body (box shape) - // ReactPhysics3D will clone this object to create an internal one. Therefore, - // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() - const rp3d::BoxShape collisionShape(rp3d::Vector3(mSize[0], mSize[1], mSize[2])); - - // Initial position and orientation of the rigid body - rp3d::Vector3 initPosition(position.x, position.y, position.z); - rp3d::Quaternion initOrientation = rp3d::Quaternion::identity(); - rp3d::Transform transform(initPosition, initOrientation); - - // Create a rigid body in the dynamics world - rp3d::RigidBody* body = world->createRigidBody(transform); - - // Add the collision shape to the body - body->addCollisionShape(collisionShape, rp3d::Transform::identity(), mass); - - mRigidBody = body; - - // If the Vertex Buffer object has not been created yet - if (!areVBOsCreated) { - // Create the Vertex Buffer - createVBO(); - } - - mTransformMatrix = mTransformMatrix * mScalingMatrix; -} - -// Destructor -Box::~Box() { - -} - -// Render the cube at the correct position and with the correct orientation -void Box::render(openglframework::Shader& shader, - const openglframework::Matrix4& worldToCameraMatrix) { - - // Bind the shader - shader.bind(); - - // Set the model to camera matrix - const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix; - shader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix); - - // Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the - // model-view matrix) - const openglframework::Matrix3 normalMatrix = - localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose(); - shader.setMatrix3x3Uniform("normalMatrix", normalMatrix); - - // Set the vertex color - openglframework::Vector4 color(mColor.r, mColor.g, mColor.b, mColor.a); - shader.setVector4Uniform("vertexColor", color); - - // Bind the vertices VBO - mVBOVertices.bind(); - - // Enable the vertex, normal and color arrays - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - - // Set the arrays pointers - glVertexPointer(3, GL_FLOAT, sizeof(VertexData), MEMBER_OFFSET(VertexData, position)); - glNormalPointer(GL_FLOAT, sizeof(VertexData), MEMBER_OFFSET(VertexData, normal)); - glColorPointer(3, GL_FLOAT, sizeof(VertexData), MEMBER_OFFSET(VertexData, color)); - - // Bind the indices VBO - mVBOIndices.bind(); - - // Draw the geometry of the box - glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, (char*)NULL); - - // Unbind the VBOs - mVBOVertices.unbind(); - mVBOIndices.unbind(); - - // Disable the arrays - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - - // Unbind the shader - shader.unbind(); -} - -// Update the transform matrix of the box -void Box::updateTransform() { - - // Get the interpolated transform of the rigid body - rp3d::Transform transform = mRigidBody->getInterpolatedTransform(); - - // Compute the transform used for rendering the box - rp3d::decimal matrix[16]; - transform.getOpenGLMatrix(matrix); - openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12], - matrix[1], matrix[5], matrix[9], matrix[13], - matrix[2], matrix[6], matrix[10], matrix[14], - matrix[3], matrix[7], matrix[11], matrix[15]); - - // Apply the scaling matrix to have the correct box dimensions - mTransformMatrix = newMatrix * mScalingMatrix; -} - -// Create the Vertex Buffer Objects used to render to box with OpenGL. -/// We create two VBOs (one for vertices and one for indices) to render all the boxes -/// in the simulation. -void Box::createVBO() { - - // Create the VBOs - mVBOVertices.create(); - mVBOIndices.create(); - - // Copy the data into the VBOs - mVBOVertices.copyDataIntoVBO(sizeof(mCubeVertices), mCubeVertices, GL_STATIC_DRAW); - mVBOIndices.copyDataIntoVBO(sizeof(mCubeIndices), mCubeIndices, GL_STATIC_DRAW); - - areVBOsCreated = true; -} diff --git a/examples/common/Box.h b/examples/common/Box.h deleted file mode 100644 index 2cc333d8..00000000 --- a/examples/common/Box.h +++ /dev/null @@ -1,131 +0,0 @@ -/******************************************************************************** -* ReactPhysics3D physics library, http://www.reactphysics3d.com * -* Copyright (c) 2010-2015 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -#ifndef BOX_H -#define BOX_H - -// Libraries -#include "openglframework.h" -#include "reactphysics3d.h" - -// Structure VertexData -struct VertexData { - - /// Vertex position - openglframework::Vector3 position; - - /// Vertex normal - openglframework::Vector3 normal; - - // Vertex color - openglframework::Color color; -}; - -// Class Box -class Box : public openglframework::Object3D { - - private : - - // -------------------- Attributes -------------------- // - - /// Size of each side of the box - float mSize[3]; - - /// Rigid body used to simulate the dynamics of the box - rp3d::CollisionBody* mRigidBody; - - /// Scaling matrix (applied to a cube to obtain the correct box dimensions) - openglframework::Matrix4 mScalingMatrix; - - /// Vertex Buffer Object for the vertices data used to render the box with OpenGL - static openglframework::VertexBufferObject mVBOVertices; - - /// Vertex Buffer Object for the indices used to render the box with OpenGL - static openglframework::VertexBufferObject mVBOIndices; - - /// Vertex data for each vertex of the cube (used to render the box) - static VertexData mCubeVertices[8]; - - /// Indices of the cube (used to render the box) - static GLuint mCubeIndices[36]; - - /// True if the VBOs have already been created - static bool areVBOsCreated; - - /// Main color of the box - openglframework::Color mColor; - - // -------------------- Methods -------------------- // - - /// Create a Vertex Buffer Object to render to box with OpenGL - static void createVBO(); - - public : - - // -------------------- Methods -------------------- // - - /// Constructor - Box(const openglframework::Vector3& size, const openglframework::Vector3& position, - reactphysics3d::CollisionWorld* world); - - /// Constructor - Box(const openglframework::Vector3& size, const openglframework::Vector3& position, - float mass, reactphysics3d::DynamicsWorld *world); - - /// Destructor - ~Box(); - - /// Return a pointer to the collision body of the box - reactphysics3d::CollisionBody* getCollisionBody(); - - /// Return a pointer to the rigid body of the box - reactphysics3d::RigidBody* getRigidBody(); - - /// Update the transform matrix of the box - void updateTransform(); - - /// Render the cube at the correct position and with the correct orientation - void render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix); - - /// Set the color of the box - void setColor(const openglframework::Color& color); -}; - -// Return a pointer to the collision body of the box -inline rp3d::CollisionBody* Box::getCollisionBody() { - return mRigidBody; -} - -// Return a pointer to the rigid body of the box -inline rp3d::RigidBody* Box::getRigidBody() { - return dynamic_cast(mRigidBody); -} - -// Set the color of the box -inline void Box::setColor(const openglframework::Color& color) { - mColor = color; -} - -#endif diff --git a/examples/common/CMakeLists.txt b/examples/common/CMakeLists.txt deleted file mode 100644 index 0c4f652b..00000000 --- a/examples/common/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -# Minimum cmake version required -CMAKE_MINIMUM_REQUIRED(VERSION 2.6) - -ADD_SUBDIRECTORY(opengl-framework/) -ADD_SUBDIRECTORY(glfw/) diff --git a/examples/common/Capsule.cpp b/examples/common/Capsule.cpp deleted file mode 100644 index faf8484e..00000000 --- a/examples/common/Capsule.cpp +++ /dev/null @@ -1,179 +0,0 @@ -/******************************************************************************** -* ReactPhysics3D physics library, http://www.reactphysics3d.com * -* Copyright (c) 2010-2015 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -// Libraries -#include "Capsule.h" - -// Constructor -Capsule::Capsule(float radius, float height, const openglframework::Vector3& position, - reactphysics3d::CollisionWorld* world, - const std::string& meshFolderPath) - : openglframework::Mesh(), mRadius(radius), mHeight(height) { - - // Load the mesh from a file - openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "capsule.obj", *this); - - // Calculate the normals of the mesh - calculateNormals(); - - // Compute the scaling matrix - mScalingMatrix = openglframework::Matrix4(mRadius, 0, 0, 0, - 0, (mHeight + 2.0f * mRadius) / 3.0f, 0,0, - 0, 0, mRadius, 0, - 0, 0, 0, 1.0f); - - // Initialize the position where the sphere will be rendered - translateWorld(position); - - // Create the collision shape for the rigid body (sphere shape) - // ReactPhysics3D will clone this object to create an internal one. Therefore, - // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() - const rp3d::CapsuleShape collisionShape(mRadius, mHeight); - - // Initial position and orientation of the rigid body - rp3d::Vector3 initPosition(position.x, position.y, position.z); - rp3d::Quaternion initOrientation = rp3d::Quaternion::identity(); - rp3d::Transform transform(initPosition, initOrientation); - - // Create a rigid body corresponding in the dynamics world - mRigidBody = world->createCollisionBody(transform); - - // Add a collision shape to the body and specify the mass of the shape - mRigidBody->addCollisionShape(collisionShape, rp3d::Transform::identity()); - - mTransformMatrix = mTransformMatrix * mScalingMatrix; -} - -// Constructor -Capsule::Capsule(float radius, float height, const openglframework::Vector3& position, - float mass, reactphysics3d::DynamicsWorld* dynamicsWorld, - const std::string& meshFolderPath) - : openglframework::Mesh(), mRadius(radius), mHeight(height) { - - // Load the mesh from a file - openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "capsule.obj", *this); - - // Calculate the normals of the mesh - calculateNormals(); - - // Compute the scaling matrix - mScalingMatrix = openglframework::Matrix4(mRadius, 0, 0, 0, - 0, (mHeight + 2.0f * mRadius) / 3.0f, 0,0, - 0, 0, mRadius, 0, - 0, 0, 0, 1.0f); - - // Initialize the position where the sphere will be rendered - translateWorld(position); - - // Create the collision shape for the rigid body (sphere shape) - // ReactPhysics3D will clone this object to create an internal one. Therefore, - // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() - const rp3d::CapsuleShape collisionShape(mRadius, mHeight); - - // Initial position and orientation of the rigid body - rp3d::Vector3 initPosition(position.x, position.y, position.z); - rp3d::Quaternion initOrientation = rp3d::Quaternion::identity(); - rp3d::Transform transform(initPosition, initOrientation); - - // Create a rigid body corresponding in the dynamics world - rp3d::RigidBody* body = dynamicsWorld->createRigidBody(transform); - - // Add a collision shape to the body and specify the mass of the shape - body->addCollisionShape(collisionShape, rp3d::Transform::identity(), mass); - - mRigidBody = body; - - mTransformMatrix = mTransformMatrix * mScalingMatrix; -} - -// Destructor -Capsule::~Capsule() { - - // Destroy the mesh - destroy(); -} - -// Render the sphere at the correct position and with the correct orientation -void Capsule::render(openglframework::Shader& shader, - const openglframework::Matrix4& worldToCameraMatrix) { - - // Bind the shader - shader.bind(); - - // Set the model to camera matrix - const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix; - shader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix); - - // Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the - // model-view matrix) - const openglframework::Matrix3 normalMatrix = - localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose(); - shader.setMatrix3x3Uniform("normalMatrix", normalMatrix); - - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - if (hasTexture()) { - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - } - - glVertexPointer(3, GL_FLOAT, 0, getVerticesPointer()); - glNormalPointer(GL_FLOAT, 0, getNormalsPointer()); - if(hasTexture()) { - glTexCoordPointer(2, GL_FLOAT, 0, getUVTextureCoordinatesPointer()); - } - - // For each part of the mesh - for (unsigned int i=0; igetInterpolatedTransform(); - - // Compute the transform used for rendering the sphere - rp3d::decimal matrix[16]; - transform.getOpenGLMatrix(matrix); - openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12], - matrix[1], matrix[5], matrix[9], matrix[13], - matrix[2], matrix[6], matrix[10], matrix[14], - matrix[3], matrix[7], matrix[11], matrix[15]); - - // Apply the scaling matrix to have the correct sphere dimensions - mTransformMatrix = newMatrix * mScalingMatrix; -} diff --git a/examples/common/Capsule.h b/examples/common/Capsule.h deleted file mode 100644 index 2ce438d1..00000000 --- a/examples/common/Capsule.h +++ /dev/null @@ -1,94 +0,0 @@ -/******************************************************************************** -* ReactPhysics3D physics library, http://www.reactphysics3d.com * -* Copyright (c) 2010-2015 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -#ifndef CAPSULE_H -#define CAPSULE_H - -// Libraries -#include "openglframework.h" -#include "reactphysics3d.h" - -// Class Sphere -class Capsule : public openglframework::Mesh { - - private : - - // -------------------- Attributes -------------------- // - - /// Radius of the capsule - float mRadius; - - /// Height of the capsule - float mHeight; - - /// Rigid body used to simulate the dynamics of the sphere - rp3d::CollisionBody* mRigidBody; - - /// Scaling matrix (applied to a sphere to obtain the correct sphere dimensions) - openglframework::Matrix4 mScalingMatrix; - - // -------------------- Methods -------------------- // - - public : - - // -------------------- Methods -------------------- // - - /// Constructor - Capsule(float radius, float height, const openglframework::Vector3& position, - reactphysics3d::CollisionWorld* world, const std::string& meshFolderPath); - - /// Constructor - Capsule(float radius, float height, const openglframework::Vector3& position, - float mass, reactphysics3d::DynamicsWorld* dynamicsWorld, - const std::string& meshFolderPath); - - /// Destructor - ~Capsule(); - - /// Return a pointer to the collision body of the box - reactphysics3d::CollisionBody* getCollisionBody(); - - /// Return a pointer to the rigid body of the box - reactphysics3d::RigidBody* getRigidBody(); - - /// Update the transform matrix of the sphere - void updateTransform(); - - /// Render the sphere at the correct position and with the correct orientation - void render(openglframework::Shader& shader, - const openglframework::Matrix4& worldToCameraMatrix); -}; - -// Return a pointer to the collision body of the box -inline rp3d::CollisionBody* Capsule::getCollisionBody() { - return mRigidBody; -} - -// Return a pointer to the rigid body of the box -inline rp3d::RigidBody* Capsule::getRigidBody() { - return dynamic_cast(mRigidBody); -} - -#endif diff --git a/examples/common/Cone.cpp b/examples/common/Cone.cpp deleted file mode 100644 index 9e3f24b6..00000000 --- a/examples/common/Cone.cpp +++ /dev/null @@ -1,179 +0,0 @@ -/******************************************************************************** -* ReactPhysics3D physics library, http://www.reactphysics3d.com * -* Copyright (c) 2010-2015 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -// Libraries -#include "Cone.h" - -// Constructor -Cone::Cone(float radius, float height, const openglframework::Vector3 &position, - reactphysics3d::CollisionWorld* world, - const std::string& meshFolderPath) - : openglframework::Mesh(), mRadius(radius), mHeight(height) { - - // Load the mesh from a file - openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "cone.obj", *this); - - // Calculate the normals of the mesh - calculateNormals(); - - // Compute the scaling matrix - mScalingMatrix = openglframework::Matrix4(mRadius, 0, 0, 0, - 0, mHeight, 0, 0, - 0, 0, mRadius, 0, - 0, 0, 0, 1); - - // Initialize the position where the cone will be rendered - translateWorld(position); - - // Create the collision shape for the rigid body (cone shape) - // ReactPhysics3D will clone this object to create an internal one. Therefore, - // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() - const rp3d::ConeShape collisionShape(mRadius, mHeight); - - // Initial position and orientation of the rigid body - rp3d::Vector3 initPosition(position.x, position.y, position.z); - rp3d::Quaternion initOrientation = rp3d::Quaternion::identity(); - rp3d::Transform transform(initPosition, initOrientation); - - // Create a rigid body corresponding to the cone in the dynamics world - mRigidBody = world->createCollisionBody(transform); - - // Add a collision shape to the body and specify the mass of the shape - mRigidBody->addCollisionShape(collisionShape, rp3d::Transform::identity()); - - mTransformMatrix = mTransformMatrix * mScalingMatrix; -} - -// Constructor -Cone::Cone(float radius, float height, const openglframework::Vector3 &position, - float mass, reactphysics3d::DynamicsWorld* dynamicsWorld, - const std::string& meshFolderPath) - : openglframework::Mesh(), mRadius(radius), mHeight(height) { - - // Load the mesh from a file - openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "cone.obj", *this); - - // Calculate the normals of the mesh - calculateNormals(); - - // Compute the scaling matrix - mScalingMatrix = openglframework::Matrix4(mRadius, 0, 0, 0, - 0, mHeight, 0, 0, - 0, 0, mRadius, 0, - 0, 0, 0, 1); - - // Initialize the position where the cone will be rendered - translateWorld(position); - - // Create the collision shape for the rigid body (cone shape) - // ReactPhysics3D will clone this object to create an internal one. Therefore, - // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() - const rp3d::ConeShape collisionShape(mRadius, mHeight); - - // Initial position and orientation of the rigid body - rp3d::Vector3 initPosition(position.x, position.y, position.z); - rp3d::Quaternion initOrientation = rp3d::Quaternion::identity(); - rp3d::Transform transform(initPosition, initOrientation); - - // Create a rigid body corresponding to the cone in the dynamics world - rp3d::RigidBody* body = dynamicsWorld->createRigidBody(transform); - - // Add a collision shape to the body and specify the mass of the shape - body->addCollisionShape(collisionShape, rp3d::Transform::identity(), mass); - - mRigidBody = body; - - mTransformMatrix = mTransformMatrix * mScalingMatrix; -} - -// Destructor -Cone::~Cone() { - - // Destroy the mesh - destroy(); -} - -// Render the cone at the correct position and with the correct orientation -void Cone::render(openglframework::Shader& shader, - const openglframework::Matrix4& worldToCameraMatrix) { - - // Bind the shader - shader.bind(); - - // Set the model to camera matrix - const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix; - shader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix); - - // Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the - // model-view matrix) - const openglframework::Matrix3 normalMatrix = - localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose(); - shader.setMatrix3x3Uniform("normalMatrix", normalMatrix); - - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - if (hasTexture()) { - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - } - - glVertexPointer(3, GL_FLOAT, 0, getVerticesPointer()); - glNormalPointer(GL_FLOAT, 0, getNormalsPointer()); - if(hasTexture()) { - glTexCoordPointer(2, GL_FLOAT, 0, getUVTextureCoordinatesPointer()); - } - - // For each part of the mesh - for (unsigned int i=0; igetInterpolatedTransform(); - - // Compute the transform used for rendering the cone - rp3d::decimal matrix[16]; - transform.getOpenGLMatrix(matrix); - openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12], - matrix[1], matrix[5], matrix[9], matrix[13], - matrix[2], matrix[6], matrix[10], matrix[14], - matrix[3], matrix[7], matrix[11], matrix[15]); - - // Apply the scaling matrix to have the correct cone dimensions - mTransformMatrix = newMatrix * mScalingMatrix; -} diff --git a/examples/common/Cone.h b/examples/common/Cone.h deleted file mode 100644 index d3002eab..00000000 --- a/examples/common/Cone.h +++ /dev/null @@ -1,93 +0,0 @@ -/******************************************************************************** -* ReactPhysics3D physics library, http://www.reactphysics3d.com * -* Copyright (c) 2010-2015 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -#ifndef CONE_H -#define CONE_H - -// Libraries -#include "openglframework.h" -#include "reactphysics3d.h" - -// Class Cone -class Cone : public openglframework::Mesh { - - private : - - // -------------------- Attributes -------------------- // - - /// Radius of the cone - float mRadius; - - /// Height of the cone - float mHeight; - - /// Rigid body used to simulate the dynamics of the cone - rp3d::CollisionBody* mRigidBody; - - /// Scaling matrix (applied to a sphere to obtain the correct cone dimensions) - openglframework::Matrix4 mScalingMatrix; - - // -------------------- Methods -------------------- // - - public : - - // -------------------- Methods -------------------- // - - /// Constructor - Cone(float radius, float height, const openglframework::Vector3& position, - rp3d::CollisionWorld* world, const std::string& meshFolderPath); - - /// Constructor - Cone(float radius, float height, const openglframework::Vector3& position, - float mass, rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath); - - /// Destructor - ~Cone(); - - /// Return a pointer to the collision body of the box - reactphysics3d::CollisionBody* getCollisionBody(); - - /// Return a pointer to the rigid body of the box - reactphysics3d::RigidBody* getRigidBody(); - - /// Update the transform matrix of the cone - void updateTransform(); - - /// Render the cone at the correct position and with the correct orientation - void render(openglframework::Shader& shader, - const openglframework::Matrix4& worldToCameraMatrix); -}; - -// Return a pointer to the collision body of the box -inline rp3d::CollisionBody* Cone::getCollisionBody() { - return mRigidBody; -} - -// Return a pointer to the rigid body of the box -inline rp3d::RigidBody* Cone::getRigidBody() { - return dynamic_cast(mRigidBody); -} - -#endif diff --git a/examples/common/ConvexMesh.cpp b/examples/common/ConvexMesh.cpp deleted file mode 100644 index dbb2c28a..00000000 --- a/examples/common/ConvexMesh.cpp +++ /dev/null @@ -1,218 +0,0 @@ -/******************************************************************************** -* ReactPhysics3D physics library, http://www.reactphysics3d.com * -* Copyright (c) 2010-2015 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -// Libraries -#include "ConvexMesh.h" - -// Constructor -ConvexMesh::ConvexMesh(const openglframework::Vector3 &position, - reactphysics3d::CollisionWorld* world, - const std::string& meshFolderPath) - : openglframework::Mesh() { - - // Load the mesh from a file - openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "convexmesh.obj", *this); - - // Calculate the normals of the mesh - calculateNormals(); - - // Initialize the position where the sphere will be rendered - translateWorld(position); - - // Convert the vertices array to the rp3d::decimal type - rp3d::decimal* vertices = new rp3d::decimal[3 * mVertices.size()]; - for (int i=0; i < mVertices.size(); i++) { - vertices[3 * i] = static_cast(mVertices[i].x); - vertices[3 * i + 1] = static_cast(mVertices[i].y); - vertices[3 * i + 2] = static_cast(mVertices[i].z); - } - - // Create the collision shape for the rigid body (convex mesh shape) - // ReactPhysics3D will clone this object to create an internal one. Therefore, - // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() - - rp3d::ConvexMeshShape collisionShape(vertices, mVertices.size(), 3 * sizeof(rp3d::decimal)); - - delete[] vertices; - - // Add the edges information of the mesh into the convex mesh collision shape. - // This is optional but it really speed up the convex mesh collision detection at the - // cost of some additional memory to store the edges inside the collision shape. - for (unsigned int i=0; icreateCollisionBody(transform); - - // Add a collision shape to the body and specify the mass of the collision shape - mRigidBody->addCollisionShape(collisionShape, rp3d::Transform::identity()); -} - -// Constructor -ConvexMesh::ConvexMesh(const openglframework::Vector3 &position, float mass, - reactphysics3d::DynamicsWorld* dynamicsWorld, - const std::string& meshFolderPath) - : openglframework::Mesh() { - - // Load the mesh from a file - openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "convexmesh.obj", *this); - - // Calculate the normals of the mesh - calculateNormals(); - - // Initialize the position where the sphere will be rendered - translateWorld(position); - - // Convert the vertices array to the rp3d::decimal type - rp3d::decimal* vertices = new rp3d::decimal[3 * mVertices.size()]; - for (int i=0; i < mVertices.size(); i++) { - vertices[3 * i] = static_cast(mVertices[i].x); - vertices[3 * i + 1] = static_cast(mVertices[i].y); - vertices[3 * i + 2] = static_cast(mVertices[i].z); - } - - // Create the collision shape for the rigid body (convex mesh shape) - // ReactPhysics3D will clone this object to create an internal one. Therefore, - // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() - rp3d::ConvexMeshShape collisionShape(vertices, mVertices.size(), 3 * sizeof(rp3d::decimal)); - - delete[] vertices; - - // Add the edges information of the mesh into the convex mesh collision shape. - // This is optional but it really speed up the convex mesh collision detection at the - // cost of some additional memory to store the edges inside the collision shape. - for (unsigned int i=0; icreateRigidBody(transform); - - // Add a collision shape to the body and specify the mass of the collision shape - body->addCollisionShape(collisionShape, rp3d::Transform::identity(), mass); - - mRigidBody = body; -} - -// Destructor -ConvexMesh::~ConvexMesh() { - - // Destroy the mesh - destroy(); -} - -// Render the sphere at the correct position and with the correct orientation -void ConvexMesh::render(openglframework::Shader& shader, - const openglframework::Matrix4& worldToCameraMatrix) { - - // Bind the shader - shader.bind(); - - // Set the model to camera matrix - const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix; - shader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix); - - // Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the - // model-view matrix) - const openglframework::Matrix3 normalMatrix = - localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose(); - shader.setMatrix3x3Uniform("normalMatrix", normalMatrix); - - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - if (hasTexture()) { - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - } - - glVertexPointer(3, GL_FLOAT, 0, getVerticesPointer()); - glNormalPointer(GL_FLOAT, 0, getNormalsPointer()); - if(hasTexture()) { - glTexCoordPointer(2, GL_FLOAT, 0, getUVTextureCoordinatesPointer()); - } - - // For each part of the mesh - for (unsigned int i=0; igetInterpolatedTransform(); - - // Compute the transform used for rendering the sphere - rp3d::decimal matrix[16]; - transform.getOpenGLMatrix(matrix); - openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12], - matrix[1], matrix[5], matrix[9], matrix[13], - matrix[2], matrix[6], matrix[10], matrix[14], - matrix[3], matrix[7], matrix[11], matrix[15]); - - // Apply the scaling matrix to have the correct sphere dimensions - mTransformMatrix = newMatrix; -} diff --git a/examples/common/ConvexMesh.h b/examples/common/ConvexMesh.h deleted file mode 100644 index f97ec5ec..00000000 --- a/examples/common/ConvexMesh.h +++ /dev/null @@ -1,84 +0,0 @@ -/******************************************************************************** -* ReactPhysics3D physics library, http://www.reactphysics3d.com * -* Copyright (c) 2010-2015 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -#ifndef CONVEX_MESH_H -#define CONVEX_MESH_H - -// Libraries -#include "openglframework.h" -#include "reactphysics3d.h" - -// Class ConvexMesh -class ConvexMesh : public openglframework::Mesh { - - private : - - // -------------------- Attributes -------------------- // - - /// Rigid body used to simulate the dynamics of the mesh - rp3d::CollisionBody* mRigidBody; - - // -------------------- Methods -------------------- // - - public : - - // -------------------- Methods -------------------- // - - /// Constructor - ConvexMesh(const openglframework::Vector3& position, - rp3d::CollisionWorld* world, const std::string& meshFolderPath); - - /// Constructor - ConvexMesh(const openglframework::Vector3& position, float mass, - rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath); - - /// Destructor - ~ConvexMesh(); - - /// Return a pointer to the collision body of the box - reactphysics3d::CollisionBody* getCollisionBody(); - - /// Return a pointer to the rigid body of the box - reactphysics3d::RigidBody* getRigidBody(); - - /// Update the transform matrix of the mesh - void updateTransform(); - - /// Render the mesh at the correct position and with the correct orientation - void render(openglframework::Shader& shader, - const openglframework::Matrix4& worldToCameraMatrix); -}; - -// Return a pointer to the collision body of the box -inline rp3d::CollisionBody* ConvexMesh::getCollisionBody() { - return mRigidBody; -} - -// Return a pointer to the rigid body of the box -inline rp3d::RigidBody* ConvexMesh::getRigidBody() { - return dynamic_cast(mRigidBody); -} - -#endif diff --git a/examples/common/Cylinder.cpp b/examples/common/Cylinder.cpp deleted file mode 100644 index 7c2b7690..00000000 --- a/examples/common/Cylinder.cpp +++ /dev/null @@ -1,179 +0,0 @@ -/******************************************************************************** -* ReactPhysics3D physics library, http://www.reactphysics3d.com * -* Copyright (c) 2010-2015 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -// Libraries -#include "Cylinder.h" - -// Constructor -Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& position, - reactphysics3d::CollisionWorld* world, - const std::string& meshFolderPath) - : openglframework::Mesh(), mRadius(radius), mHeight(height) { - - // Load the mesh from a file - openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "cylinder.obj", *this); - - // Calculate the normals of the mesh - calculateNormals(); - - // Compute the scaling matrix - mScalingMatrix = openglframework::Matrix4(mRadius, 0, 0, 0, - 0, mHeight, 0, 0, - 0, 0, mRadius, 0, - 0, 0, 0, 1); - - // Initialize the position where the cylinder will be rendered - translateWorld(position); - - // Create the collision shape for the rigid body (cylinder shape) - // ReactPhysics3D will clone this object to create an internal one. Therefore, - // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() - const rp3d::CylinderShape collisionShape(mRadius, mHeight); - - // Initial position and orientation of the rigid body - rp3d::Vector3 initPosition(position.x, position.y, position.z); - rp3d::Quaternion initOrientation = rp3d::Quaternion::identity(); - rp3d::Transform transform(initPosition, initOrientation); - - // Create a rigid body corresponding to the cylinder in the dynamics world - mRigidBody = world->createCollisionBody(transform); - - // Add a collision shape to the body and specify the mass of the shape - mRigidBody->addCollisionShape(collisionShape, rp3d::Transform::identity()); - - mTransformMatrix = mTransformMatrix * mScalingMatrix; -} - -// Constructor -Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& position, - float mass, reactphysics3d::DynamicsWorld* dynamicsWorld, - const std::string& meshFolderPath) - : openglframework::Mesh(), mRadius(radius), mHeight(height) { - - // Load the mesh from a file - openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "cylinder.obj", *this); - - // Calculate the normals of the mesh - calculateNormals(); - - // Compute the scaling matrix - mScalingMatrix = openglframework::Matrix4(mRadius, 0, 0, 0, - 0, mHeight, 0, 0, - 0, 0, mRadius, 0, - 0, 0, 0, 1); - - // Initialize the position where the cylinder will be rendered - translateWorld(position); - - // Create the collision shape for the rigid body (cylinder shape) - // ReactPhysics3D will clone this object to create an internal one. Therefore, - // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() - const rp3d::CylinderShape collisionShape(mRadius, mHeight); - - // Initial position and orientation of the rigid body - rp3d::Vector3 initPosition(position.x, position.y, position.z); - rp3d::Quaternion initOrientation = rp3d::Quaternion::identity(); - rp3d::Transform transform(initPosition, initOrientation); - - // Create a rigid body corresponding to the cylinder in the dynamics world - rp3d::RigidBody* body = dynamicsWorld->createRigidBody(transform); - - // Add a collision shape to the body and specify the mass of the shape - body->addCollisionShape(collisionShape, rp3d::Transform::identity(), mass); - - mTransformMatrix = mTransformMatrix * mScalingMatrix; - - mRigidBody = body; -} - -// Destructor -Cylinder::~Cylinder() { - - // Destroy the mesh - destroy(); -} - -// Render the cylinder at the correct position and with the correct orientation -void Cylinder::render(openglframework::Shader& shader, - const openglframework::Matrix4& worldToCameraMatrix) { - - // Bind the shader - shader.bind(); - - // Set the model to camera matrix - const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix; - shader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix); - - // Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the - // model-view matrix) - const openglframework::Matrix3 normalMatrix = - localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose(); - shader.setMatrix3x3Uniform("normalMatrix", normalMatrix); - - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - if (hasTexture()) { - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - } - - glVertexPointer(3, GL_FLOAT, 0, getVerticesPointer()); - glNormalPointer(GL_FLOAT, 0, getNormalsPointer()); - if(hasTexture()) { - glTexCoordPointer(2, GL_FLOAT, 0, getUVTextureCoordinatesPointer()); - } - - // For each part of the mesh - for (unsigned int i=0; igetInterpolatedTransform(); - - // Compute the transform used for rendering the cylinder - rp3d::decimal matrix[16]; - transform.getOpenGLMatrix(matrix); - openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12], - matrix[1], matrix[5], matrix[9], matrix[13], - matrix[2], matrix[6], matrix[10], matrix[14], - matrix[3], matrix[7], matrix[11], matrix[15]); - - // Apply the scaling matrix to have the correct cylinder dimensions - mTransformMatrix = newMatrix * mScalingMatrix; -} diff --git a/examples/common/Cylinder.h b/examples/common/Cylinder.h deleted file mode 100644 index 9236fe20..00000000 --- a/examples/common/Cylinder.h +++ /dev/null @@ -1,93 +0,0 @@ -/******************************************************************************** -* ReactPhysics3D physics library, http://www.reactphysics3d.com * -* Copyright (c) 2010-2015 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -#ifndef CYLINDER_H -#define CYLINDER_H - -// Libraries -#include "openglframework.h" -#include "reactphysics3d.h" - -// Class Cylinder -class Cylinder : public openglframework::Mesh { - - private : - - // -------------------- Attributes -------------------- // - - /// Radius of the cylinder - float mRadius; - - /// Height of the cylinder - float mHeight; - - /// Rigid body used to simulate the dynamics of the cylinder - rp3d::CollisionBody* mRigidBody; - - /// Scaling matrix (applied to a sphere to obtain the correct cylinder dimensions) - openglframework::Matrix4 mScalingMatrix; - - // -------------------- Methods -------------------- // - - public : - - // -------------------- Methods -------------------- // - - /// Constructor - Cylinder(float radius, float height, const openglframework::Vector3& position, - rp3d::CollisionWorld* world, const std::string &meshFolderPath); - - /// Constructor - Cylinder(float radius, float height, const openglframework::Vector3& position, - float mass, rp3d::DynamicsWorld* dynamicsWorld, const std::string &meshFolderPath); - - /// Destructor - ~Cylinder(); - - /// Return a pointer to the collision body of the box - reactphysics3d::CollisionBody* getCollisionBody(); - - /// Return a pointer to the rigid body of the box - reactphysics3d::RigidBody* getRigidBody(); - - /// Update the transform matrix of the cylinder - void updateTransform(); - - /// Render the cylinder at the correct position and with the correct orientation - void render(openglframework::Shader& shader, - const openglframework::Matrix4& worldToCameraMatrix); -}; - -// Return a pointer to the collision body of the box -inline rp3d::CollisionBody* Cylinder::getCollisionBody() { - return mRigidBody; -} - -// Return a pointer to the rigid body of the box -inline rp3d::RigidBody* Cylinder::getRigidBody() { - return dynamic_cast(mRigidBody); -} - -#endif diff --git a/examples/common/Dumbbell.cpp b/examples/common/Dumbbell.cpp deleted file mode 100644 index a358db61..00000000 --- a/examples/common/Dumbbell.cpp +++ /dev/null @@ -1,216 +0,0 @@ -/******************************************************************************** -* ReactPhysics3D physics library, http://www.reactphysics3d.com * -* Copyright (c) 2010-2015 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -// Libraries -#include "Dumbbell.h" - -// Constructor -Dumbbell::Dumbbell(const openglframework::Vector3 &position, - reactphysics3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath) - : openglframework::Mesh() { - - // Load the mesh from a file - openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "dumbbell.obj", *this); - - // Calculate the normals of the mesh - calculateNormals(); - - // Identity scaling matrix - mScalingMatrix.setToIdentity(); - - // Initialize the position where the sphere will be rendered - translateWorld(position); - - // Create a sphere collision shape for the two ends of the dumbbell - // ReactPhysics3D will clone this object to create an internal one. Therefore, - // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() - const rp3d::decimal radiusSphere = rp3d::decimal(1.5); - const rp3d::decimal massSphere = rp3d::decimal(2.0); - const rp3d::SphereShape sphereCollisionShape(radiusSphere); - - // Create a cylinder collision shape for the middle of the dumbbell - // ReactPhysics3D will clone this object to create an internal one. Therefore, - // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() - const rp3d::decimal radiusCylinder = rp3d::decimal(0.5); - const rp3d::decimal heightCylinder = rp3d::decimal(8.0); - const rp3d::decimal massCylinder = rp3d::decimal(1.0); - const rp3d::CylinderShape cylinderCollisionShape(radiusCylinder, heightCylinder); - - // Initial position and orientation of the rigid body - rp3d::Vector3 initPosition(position.x, position.y, position.z); - rp3d::decimal angleAroundX = 0;//rp3d::PI / 2; - rp3d::Quaternion initOrientation(angleAroundX, 0, 0); - rp3d::Transform transformBody(initPosition, initOrientation); - - // Initial transform of the first sphere collision shape of the dumbbell (in local-space) - rp3d::Transform transformSphereShape1(rp3d::Vector3(0, 4.0, 0), rp3d::Quaternion::identity()); - - // Initial transform of the second sphere collision shape of the dumbell (in local-space) - rp3d::Transform transformSphereShape2(rp3d::Vector3(0, -4.0, 0), rp3d::Quaternion::identity()); - - // Initial transform of the cylinder collision shape of the dumbell (in local-space) - rp3d::Transform transformCylinderShape(rp3d::Vector3(0, 0, 0), rp3d::Quaternion::identity()); - - // Create a rigid body corresponding to the dumbbell in the dynamics world - rp3d::RigidBody* body = dynamicsWorld->createRigidBody(transformBody); - - // Add the three collision shapes to the body and specify the mass and transform of the shapes - body->addCollisionShape(sphereCollisionShape, transformSphereShape1, massSphere); - body->addCollisionShape(sphereCollisionShape, transformSphereShape2, massSphere); - body->addCollisionShape(cylinderCollisionShape, transformCylinderShape, massCylinder); - - mBody = body; - - mTransformMatrix = mTransformMatrix * mScalingMatrix; -} - -// Constructor -Dumbbell::Dumbbell(const openglframework::Vector3 &position, - reactphysics3d::CollisionWorld* world, const std::string& meshFolderPath) - : openglframework::Mesh() { - - // Load the mesh from a file - openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "dumbbell.obj", *this); - - // Calculate the normals of the mesh - calculateNormals(); - - // Identity scaling matrix - mScalingMatrix.setToIdentity(); - - // Initialize the position where the sphere will be rendered - translateWorld(position); - - // Create a sphere collision shape for the two ends of the dumbbell - // ReactPhysics3D will clone this object to create an internal one. Therefore, - // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() - const rp3d::decimal radiusSphere = rp3d::decimal(1.5); - const rp3d::decimal massSphere = rp3d::decimal(2.0); - const rp3d::SphereShape sphereCollisionShape(radiusSphere); - - // Create a cylinder collision shape for the middle of the dumbbell - // ReactPhysics3D will clone this object to create an internal one. Therefore, - // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() - const rp3d::decimal radiusCylinder = rp3d::decimal(0.5); - const rp3d::decimal heightCylinder = rp3d::decimal(8.0); - const rp3d::decimal massCylinder = rp3d::decimal(1.0); - const rp3d::CylinderShape cylinderCollisionShape(radiusCylinder, heightCylinder); - - // Initial position and orientation of the rigid body - rp3d::Vector3 initPosition(position.x, position.y, position.z); - rp3d::decimal angleAroundX = 0;//rp3d::PI / 2; - rp3d::Quaternion initOrientation(angleAroundX, 0, 0); - rp3d::Transform transformBody(initPosition, initOrientation); - - // Initial transform of the first sphere collision shape of the dumbbell (in local-space) - rp3d::Transform transformSphereShape1(rp3d::Vector3(0, 4.0, 0), rp3d::Quaternion::identity()); - - // Initial transform of the second sphere collision shape of the dumbell (in local-space) - rp3d::Transform transformSphereShape2(rp3d::Vector3(0, -4.0, 0), rp3d::Quaternion::identity()); - - // Initial transform of the cylinder collision shape of the dumbell (in local-space) - rp3d::Transform transformCylinderShape(rp3d::Vector3(0, 0, 0), rp3d::Quaternion::identity()); - - // Create a rigid body corresponding to the dumbbell in the dynamics world - mBody = world->createCollisionBody(transformBody); - - // Add the three collision shapes to the body and specify the mass and transform of the shapes - mBody->addCollisionShape(sphereCollisionShape, transformSphereShape1); - mBody->addCollisionShape(sphereCollisionShape, transformSphereShape2); - mBody->addCollisionShape(cylinderCollisionShape, transformCylinderShape); - - mTransformMatrix = mTransformMatrix * mScalingMatrix; -} - -// Destructor -Dumbbell::~Dumbbell() { - - // Destroy the mesh - destroy(); -} - -// Render the sphere at the correct position and with the correct orientation -void Dumbbell::render(openglframework::Shader& shader, - const openglframework::Matrix4& worldToCameraMatrix) { - - // Bind the shader - shader.bind(); - - // Set the model to camera matrix - const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix; - shader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix); - - // Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the - // model-view matrix) - const openglframework::Matrix3 normalMatrix = - localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose(); - shader.setMatrix3x3Uniform("normalMatrix", normalMatrix); - - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - if (hasTexture()) { - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - } - - glVertexPointer(3, GL_FLOAT, 0, getVerticesPointer()); - glNormalPointer(GL_FLOAT, 0, getNormalsPointer()); - if(hasTexture()) { - glTexCoordPointer(2, GL_FLOAT, 0, getUVTextureCoordinatesPointer()); - } - - // For each part of the mesh - for (unsigned int i=0; igetInterpolatedTransform(); - - // Compute the transform used for rendering the sphere - rp3d::decimal matrix[16]; - transform.getOpenGLMatrix(matrix); - openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12], - matrix[1], matrix[5], matrix[9], matrix[13], - matrix[2], matrix[6], matrix[10], matrix[14], - matrix[3], matrix[7], matrix[11], matrix[15]); - - // Apply the scaling matrix to have the correct sphere dimensions - mTransformMatrix = newMatrix * mScalingMatrix; -} - diff --git a/examples/common/Dumbbell.h b/examples/common/Dumbbell.h deleted file mode 100644 index ff673951..00000000 --- a/examples/common/Dumbbell.h +++ /dev/null @@ -1,91 +0,0 @@ -/******************************************************************************** -* ReactPhysics3D physics library, http://www.reactphysics3d.com * -* Copyright (c) 2010-2015 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -#ifndef DUMBBELL_H -#define DUMBBELL_H - -// Libraries -#include "openglframework.h" -#include "reactphysics3d.h" - -// Class Sphere -class Dumbbell : public openglframework::Mesh { - - private : - - // -------------------- Attributes -------------------- // - - /// Radius of the spheres - float mRadius; - - /// Rigid body used to simulate the dynamics of the sphere - rp3d::CollisionBody* mBody; - - /// Scaling matrix (applied to a sphere to obtain the correct sphere dimensions) - openglframework::Matrix4 mScalingMatrix; - - // -------------------- Methods -------------------- // - - public : - - // -------------------- Methods -------------------- // - - /// Constructor - Dumbbell(const openglframework::Vector3& position, rp3d::DynamicsWorld* dynamicsWorld, - const std::string& meshFolderPath); - - /// Constructor - Dumbbell(const openglframework::Vector3& position, rp3d::CollisionWorld* world, - const std::string& meshFolderPath); - - - /// Destructor - ~Dumbbell(); - - /// Return a pointer to the rigid body - rp3d::RigidBody* getRigidBody(); - - /// Return a pointer to the body - rp3d::CollisionBody* getCollisionBody(); - - /// Update the transform matrix of the sphere - void updateTransform(); - - /// Render the sphere at the correct position and with the correct orientation - void render(openglframework::Shader& shader, - const openglframework::Matrix4& worldToCameraMatrix); -}; - -// Return a pointer to the rigid body of the sphere -inline rp3d::RigidBody* Dumbbell::getRigidBody() { - return dynamic_cast(mBody); -} - -// Return a pointer to the body -inline rp3d::CollisionBody* Dumbbell::getCollisionBody() { - return mBody; -} - -#endif diff --git a/examples/common/Line.cpp b/examples/common/Line.cpp deleted file mode 100644 index 9263c1d6..00000000 --- a/examples/common/Line.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/******************************************************************************** -* ReactPhysics3D physics library, http://www.reactphysics3d.com * -* Copyright (c) 2010-2015 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -// Libraries -#include "Line.h" - -// Constructor -Line::Line(const openglframework::Vector3& worldPoint1, - const openglframework::Vector3& worldPoint2) - : mWorldPoint1(worldPoint1), mWorldPoint2(worldPoint2) { - -} - -// Destructor -Line::~Line() { - - -} - -// Render the sphere at the correct position and with the correct orientation -void Line::render(openglframework::Shader& shader, - const openglframework::Matrix4& worldToCameraMatrix) { - - // Bind the shader - shader.bind(); - - // Set the model to camera matrix - shader.setMatrix4x4Uniform("localToCameraMatrix", worldToCameraMatrix); - - glBegin(GL_LINES); - glVertex3f(mWorldPoint1.x, mWorldPoint1.y, mWorldPoint1.z); - glVertex3f(mWorldPoint2.x, mWorldPoint2.y, mWorldPoint2.z); - glEnd(); - - // Unbind the shader - shader.unbind(); -} diff --git a/examples/common/Line.h b/examples/common/Line.h deleted file mode 100644 index 41de3266..00000000 --- a/examples/common/Line.h +++ /dev/null @@ -1,79 +0,0 @@ -/******************************************************************************** -* ReactPhysics3D physics library, http://www.reactphysics3d.com * -* Copyright (c) 2010-2015 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -#ifndef LINE_H -#define LINE_H - -// Libraries -#include "openglframework.h" -#include "reactphysics3d.h" - -// Class Line -class Line : public openglframework::Object3D { - - private : - - // -------------------- Attributes -------------------- // - - openglframework::Vector3 mWorldPoint1, mWorldPoint2; - - // -------------------- Methods -------------------- // - - public : - - // -------------------- Methods -------------------- // - - /// Constructor - Line(const openglframework::Vector3& worldPoint1, - const openglframework::Vector3& worldPoint2); - - /// Destructor - ~Line(); - - /// Return the first point of the line - openglframework::Vector3 getPoint1() const; - - /// Return the second point of the line - openglframework::Vector3 getPoint2() const; - - /// Update the transform matrix of the sphere - void updateTransform(); - - /// Render the line at the correct position and with the correct orientation - void render(openglframework::Shader& shader, - const openglframework::Matrix4& worldToCameraMatrix); -}; - -// Return the first point of the line -inline openglframework::Vector3 Line::getPoint1() const { - return mWorldPoint1; -} - -// Return the second point of the line -inline openglframework::Vector3 Line::getPoint2() const { - return mWorldPoint2; -} - -#endif diff --git a/examples/common/Sphere.cpp b/examples/common/Sphere.cpp deleted file mode 100644 index 56882569..00000000 --- a/examples/common/Sphere.cpp +++ /dev/null @@ -1,179 +0,0 @@ -/******************************************************************************** -* ReactPhysics3D physics library, http://www.reactphysics3d.com * -* Copyright (c) 2010-2015 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -// Libraries -#include "Sphere.h" - -// Constructor -Sphere::Sphere(float radius, const openglframework::Vector3 &position, - reactphysics3d::CollisionWorld* world, - const std::string& meshFolderPath) - : openglframework::Mesh(), mRadius(radius) { - - // Load the mesh from a file - openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "sphere.obj", *this); - - // Calculate the normals of the mesh - calculateNormals(); - - // Compute the scaling matrix - mScalingMatrix = openglframework::Matrix4(mRadius, 0, 0, 0, - 0, mRadius, 0, 0, - 0, 0, mRadius, 0, - 0, 0, 0, 1); - - // Initialize the position where the sphere will be rendered - translateWorld(position); - - // Create the collision shape for the rigid body (sphere shape) - // ReactPhysics3D will clone this object to create an internal one. Therefore, - // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() - const rp3d::SphereShape collisionShape(mRadius); - - // Initial position and orientation of the rigid body - rp3d::Vector3 initPosition(position.x, position.y, position.z); - rp3d::Quaternion initOrientation = rp3d::Quaternion::identity(); - rp3d::Transform transform(initPosition, initOrientation); - - // Create a rigid body corresponding to the sphere in the dynamics world - mRigidBody = world->createCollisionBody(transform); - - // Add a collision shape to the body and specify the mass of the shape - mRigidBody->addCollisionShape(collisionShape, rp3d::Transform::identity()); - - mTransformMatrix = mTransformMatrix * mScalingMatrix; -} - -// Constructor -Sphere::Sphere(float radius, const openglframework::Vector3 &position, - float mass, reactphysics3d::DynamicsWorld* world, - const std::string& meshFolderPath) - : openglframework::Mesh(), mRadius(radius) { - - // Load the mesh from a file - openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "sphere.obj", *this); - - // Calculate the normals of the mesh - calculateNormals(); - - // Compute the scaling matrix - mScalingMatrix = openglframework::Matrix4(mRadius, 0, 0, 0, - 0, mRadius, 0, 0, - 0, 0, mRadius, 0, - 0, 0, 0, 1); - - // Initialize the position where the sphere will be rendered - translateWorld(position); - - // Create the collision shape for the rigid body (sphere shape) - // ReactPhysics3D will clone this object to create an internal one. Therefore, - // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() - const rp3d::SphereShape collisionShape(mRadius); - - // Initial position and orientation of the rigid body - rp3d::Vector3 initPosition(position.x, position.y, position.z); - rp3d::Quaternion initOrientation = rp3d::Quaternion::identity(); - rp3d::Transform transform(initPosition, initOrientation); - - // Create a rigid body corresponding to the sphere in the dynamics world - rp3d::RigidBody* body = world->createRigidBody(transform); - - // Add a collision shape to the body and specify the mass of the shape - body->addCollisionShape(collisionShape, rp3d::Transform::identity(), mass); - - mRigidBody = body; - - mTransformMatrix = mTransformMatrix * mScalingMatrix; -} - -// Destructor -Sphere::~Sphere() { - - // Destroy the mesh - destroy(); -} - -// Render the sphere at the correct position and with the correct orientation -void Sphere::render(openglframework::Shader& shader, - const openglframework::Matrix4& worldToCameraMatrix) { - - // Bind the shader - shader.bind(); - - // Set the model to camera matrix - const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix; - shader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix); - - // Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the - // model-view matrix) - const openglframework::Matrix3 normalMatrix = - localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose(); - shader.setMatrix3x3Uniform("normalMatrix", normalMatrix); - - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - if (hasTexture()) { - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - } - - glVertexPointer(3, GL_FLOAT, 0, getVerticesPointer()); - glNormalPointer(GL_FLOAT, 0, getNormalsPointer()); - if(hasTexture()) { - glTexCoordPointer(2, GL_FLOAT, 0, getUVTextureCoordinatesPointer()); - } - - // For each part of the mesh - for (unsigned int i=0; igetInterpolatedTransform(); - - // Compute the transform used for rendering the sphere - rp3d::decimal matrix[16]; - transform.getOpenGLMatrix(matrix); - openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12], - matrix[1], matrix[5], matrix[9], matrix[13], - matrix[2], matrix[6], matrix[10], matrix[14], - matrix[3], matrix[7], matrix[11], matrix[15]); - - // Apply the scaling matrix to have the correct sphere dimensions - mTransformMatrix = newMatrix * mScalingMatrix; -} diff --git a/examples/common/Sphere.h b/examples/common/Sphere.h deleted file mode 100644 index 08a335f7..00000000 --- a/examples/common/Sphere.h +++ /dev/null @@ -1,90 +0,0 @@ -/******************************************************************************** -* ReactPhysics3D physics library, http://www.reactphysics3d.com * -* Copyright (c) 2010-2015 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -#ifndef SPHERE_H -#define SPHERE_H - -// Libraries -#include "openglframework.h" -#include "reactphysics3d.h" - -// Class Sphere -class Sphere : public openglframework::Mesh { - - private : - - // -------------------- Attributes -------------------- // - - /// Radius of the sphere - float mRadius; - - /// Rigid body used to simulate the dynamics of the sphere - rp3d::CollisionBody* mRigidBody; - - /// Scaling matrix (applied to a sphere to obtain the correct sphere dimensions) - openglframework::Matrix4 mScalingMatrix; - - // -------------------- Methods -------------------- // - - public : - - // -------------------- Methods -------------------- // - - /// Constructor - Sphere(float radius, const openglframework::Vector3& position, - rp3d::CollisionWorld* world, const std::string& meshFolderPath); - - /// Constructor - Sphere(float radius, const openglframework::Vector3& position, - float mass, rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath); - - /// Destructor - ~Sphere(); - - /// Return a pointer to the collision body of the box - reactphysics3d::CollisionBody* getCollisionBody(); - - /// Return a pointer to the rigid body of the box - reactphysics3d::RigidBody* getRigidBody(); - - /// Update the transform matrix of the sphere - void updateTransform(); - - /// Render the sphere at the correct position and with the correct orientation - void render(openglframework::Shader& shader, - const openglframework::Matrix4& worldToCameraMatrix); -}; - -// Return a pointer to the collision body of the box -inline rp3d::CollisionBody* Sphere::getCollisionBody() { - return mRigidBody; -} - -// Return a pointer to the rigid body of the box -inline rp3d::RigidBody* Sphere::getRigidBody() { - return dynamic_cast(mRigidBody); -} - -#endif diff --git a/examples/common/Viewer.cpp b/examples/common/Viewer.cpp deleted file mode 100644 index 7383fc6c..00000000 --- a/examples/common/Viewer.cpp +++ /dev/null @@ -1,342 +0,0 @@ -/******************************************************************************** -* ReactPhysics3D physics library, http://www.reactphysics3d.com * -* Copyright (c) 2010-2015 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -// Libraries -#include "Viewer.h" -#include "openglframework.h" -#include -#include -#include - -using namespace openglframework; - -// Initialization of static variables -const float Viewer::SCROLL_SENSITIVITY = 0.02f; - -// Constructor -Viewer::Viewer() : mFPS(0), mNbFrames(0), mPreviousTime(0) { - -} - -// Destructor -Viewer::~Viewer() { - - // Destroy the window - glfwDestroyWindow(mWindow); - - // Terminate GLFW - glfwTerminate(); -} - -// Initialize the viewer -void Viewer::init(int argc, char** argv, const std::string& windowsTitle, - const Vector2& windowsSize, const Vector2& windowsPosition, - bool isMultisamplingActive) { - - mWindowTitle = windowsTitle; - - // Set the GLFW error callback method - glfwSetErrorCallback(error_callback); - - // Initialize the GLFW library - if (!glfwInit()) { - std::exit(EXIT_FAILURE); - } - - // Active the multi-sampling by default - if (isMultisamplingActive) { - glfwWindowHint(GLFW_SAMPLES, 4); - } - - // Create the GLFW window - mWindow = glfwCreateWindow(static_cast(windowsSize.x), - static_cast(windowsSize.y), mWindowTitle.c_str(), NULL, NULL); - if (!mWindow) { - glfwTerminate(); - std::exit(EXIT_FAILURE); - } - glfwMakeContextCurrent(mWindow); - - // Disable Vertical Synchronization - glfwSwapInterval(0); - - // Initialize the GLEW library - GLenum errorGLEW = glewInit(); - if (errorGLEW != GLEW_OK) { - - // Problem: glewInit failed, something is wrong - std::cerr << "GLEW Error : " << glewGetErrorString(errorGLEW) << std::endl; - assert(false); - std::exit(EXIT_FAILURE); - } - - if (isMultisamplingActive) { - glEnable(GL_MULTISAMPLE); - } -} - -// Set the dimension of the camera viewport -void Viewer::reshape() { - - // Get the framebuffer dimension - int width, height; - glfwGetFramebufferSize(mWindow, &width, &height); - - // Resize the viewport - mCamera.setDimensions(width, height); - glViewport(0, 0, width, height); -} - -// Start the main loop where rendering occur -void Viewer::startMainLoop() { - - // Loop until the user closes the window - while (!glfwWindowShouldClose(mWindow)) { - - // Reshape the viewport - reshape(); - - // Call the update function - (*mUpdateFunctionPointer)(); - - // Swap front and back buffers - glfwSwapBuffers(mWindow); - - // Poll for and process events - glfwPollEvents(); - } -} - -// Set the camera so that we can view the whole scene -void Viewer::resetCameraToViewAll() { - - // Move the camera to the origin of the scene - mCamera.translateWorld(-mCamera.getOrigin()); - - // Move the camera to the center of the scene - mCamera.translateWorld(mCenterScene); - - // Set the zoom of the camera so that the scene center is - // in negative view direction of the camera - mCamera.setZoom(1.0); -} - -// Called when a mouse button event occurs -void Viewer::mouseButtonEvent(int button, int action) { - - // Get the mouse cursor position - double x, y; - glfwGetCursorPos(mWindow, &x, &y); - - // If the mouse button is pressed - if (action == GLFW_PRESS) { - mLastMouseX = x; - mLastMouseY = y; - mIsLastPointOnSphereValid = mapMouseCoordinatesToSphere(x, y, mLastPointOnSphere); - } - else { // If the mouse button is released - mIsLastPointOnSphereValid = false; - } -} - -// Called when a mouse motion event occurs -void Viewer::mouseMotionEvent(double xMouse, double yMouse) { - - int leftButtonState = glfwGetMouseButton(mWindow, GLFW_MOUSE_BUTTON_LEFT); - int rightButtonState = glfwGetMouseButton(mWindow, GLFW_MOUSE_BUTTON_RIGHT); - int middleButtonState = glfwGetMouseButton(mWindow, GLFW_MOUSE_BUTTON_MIDDLE); - int altKeyState = glfwGetKey(mWindow, GLFW_KEY_LEFT_ALT); - - // Zoom - if (leftButtonState == GLFW_PRESS && altKeyState == GLFW_PRESS) { - - // Get the window dimension - int width, height; - glfwGetWindowSize(mWindow, &width, &height); - - float dy = static_cast(yMouse - mLastMouseY); - float h = static_cast(height); - - // Zoom the camera - zoom(-dy / h); - } - // Translation - else if (middleButtonState == GLFW_PRESS || rightButtonState == GLFW_PRESS || - (leftButtonState == GLFW_PRESS && altKeyState == GLFW_PRESS)) { - translate(xMouse, yMouse); - } - // Rotation - else if (leftButtonState == GLFW_PRESS) { - rotate(xMouse, yMouse); - } - - // Remember the mouse position - mLastMouseX = xMouse; - mLastMouseY = yMouse; - mIsLastPointOnSphereValid = mapMouseCoordinatesToSphere(xMouse, yMouse, mLastPointOnSphere); -} - -// Called when a scrolling event occurs -void Viewer::scrollingEvent(float scrollAxis) { - zoom(scrollAxis * SCROLL_SENSITIVITY); -} - -// Map the mouse x,y coordinates to a point on a sphere -bool Viewer::mapMouseCoordinatesToSphere(double xMouse, double yMouse, Vector3& spherePoint) const { - - // Get the window dimension - int width, height; - glfwGetWindowSize(mWindow, &width, &height); - - if ((xMouse >= 0) && (xMouse <= width) && (yMouse >= 0) && (yMouse <= height)) { - float x = float(xMouse - 0.5f * width) / float(width); - float y = float(0.5f * height - yMouse) / float(height); - float sinx = sin(PI * x * 0.5f); - float siny = sin(PI * y * 0.5f); - float sinx2siny2 = sinx * sinx + siny * siny; - - // Compute the point on the sphere - spherePoint.x = sinx; - spherePoint.y = siny; - spherePoint.z = (sinx2siny2 < 1.0) ? sqrt(1.0f - sinx2siny2) : 0.0f; - - return true; - } - - return false; -} - -// Zoom the camera -void Viewer::zoom(float zoomDiff) { - - // Zoom the camera - mCamera.setZoom(zoomDiff); -} - -// Translate the camera -void Viewer::translate(int xMouse, int yMouse) { - float dx = static_cast(xMouse - mLastMouseX); - float dy = static_cast(yMouse - mLastMouseY); - - // Translate the camera - mCamera.translateCamera(-dx / float(mCamera.getWidth()), - -dy / float(mCamera.getHeight()), mCenterScene); -} - -// Rotate the camera -void Viewer::rotate(int xMouse, int yMouse) { - - if (mIsLastPointOnSphereValid) { - - Vector3 newPoint3D; - bool isNewPointOK = mapMouseCoordinatesToSphere(xMouse, yMouse, newPoint3D); - - if (isNewPointOK) { - Vector3 axis = mLastPointOnSphere.cross(newPoint3D); - float cosAngle = mLastPointOnSphere.dot(newPoint3D); - - float epsilon = std::numeric_limits::epsilon(); - if (fabs(cosAngle) < 1.0f && axis.length() > epsilon) { - axis.normalize(); - float angle = 2.0f * acos(cosAngle); - - // Rotate the camera around the center of the scene - mCamera.rotateAroundLocalPoint(axis, -angle, mCenterScene); - } - } - } -} - -// Check the OpenGL errors -void Viewer::checkOpenGLErrors() { - GLenum glError; - - // Get the OpenGL errors - glError = glGetError(); - - // While there are errors - while (glError != GL_NO_ERROR) { - - // Get the error string - const GLubyte* stringError = gluErrorString(glError); - - // Display the error - if (stringError) - std::cerr << "OpenGL Error #" << glError << "(" << gluErrorString(glError) << std::endl; - else - std::cerr << "OpenGL Error #" << glError << " (no message available)" << std::endl; - - // Get the next error - glError = glGetError(); - } -} - - -// Compute the FPS -void Viewer::computeFPS() { - - mNbFrames++; - - // Get the number of milliseconds since glutInit called - mCurrentTime = glfwGetTime(); - - // Calculate time passed - double timeInterval = mCurrentTime - mPreviousTime; - - // Update the FPS counter each second - if(timeInterval > 1.0) { - - // calculate the number of frames per second - mFPS = static_cast(mNbFrames) / timeInterval; - - // Set time - mPreviousTime = mCurrentTime; - - // Reset frame count - mNbFrames = 0; - } -} - -// GLFW error callback method -void Viewer::error_callback(int error, const char* description) { - fputs(description, stderr); -} - -// Display the GUI -void Viewer::displayGUI() { - - // Display the FPS - displayFPS(); -} - -// Display the FPS -void Viewer::displayFPS() { - - std::stringstream ss; - ss << mFPS; - std::string fpsString = ss.str(); - std::string windowTitle = mWindowTitle + " | FPS : " + fpsString; - glfwSetWindowTitle(mWindow, windowTitle.c_str()); -} diff --git a/examples/common/Viewer.h b/examples/common/Viewer.h deleted file mode 100644 index b3742509..00000000 --- a/examples/common/Viewer.h +++ /dev/null @@ -1,208 +0,0 @@ -/******************************************************************************** -* ReactPhysics3D physics library, http://www.reactphysics3d.com * -* Copyright (c) 2010-2015 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -#ifndef VIEWER_H -#define VIEWER_H - -// Libraries -#include "openglframework.h" -#include - -// Class Viewer -class Viewer { - - private : - - // -------------------- Constants -------------------- // - - static const float SCROLL_SENSITIVITY; - - // -------------------- Attributes -------------------- // - - /// GLFW window - GLFWwindow* mWindow; - - /// Window title - std::string mWindowTitle; - - /// Camera - openglframework::Camera mCamera; - - /// Center of the scene - openglframework::Vector3 mCenterScene; - - /// Last mouse coordinates on the windows - double mLastMouseX, mLastMouseY; - - /// Last point computed on a sphere (for camera rotation) - openglframework::Vector3 mLastPointOnSphere; - - /// True if the last point computed on a sphere (for camera rotation) is valid - bool mIsLastPointOnSphereValid; - - /// Current number of frames per seconds - double mFPS; - - /// Number of frames during the last second - int mNbFrames; - - /// Current time for fps computation - double mCurrentTime; - - /// Previous time for fps computation - double mPreviousTime; - - /// Pointer to the update function - void (*mUpdateFunctionPointer)(); - - // -------------------- Methods -------------------- // - - bool mapMouseCoordinatesToSphere(double xMouse, double yMouse, openglframework::Vector3& spherePoint) const; - - public : - - // -------------------- Methods -------------------- // - - /// Constructor - Viewer(); - - /// Destructor - ~Viewer(); - - // -------------------- Methods -------------------- // - - /// Initialize the viewer - void init(int argc, char** argv, const std::string& windowsTitle, - const openglframework::Vector2& windowsSize, - const openglframework::Vector2& windowsPosition, - bool isMultisamplingActive = false); - - /// Start the main loop where rendering occur - void startMainLoop(); - - /// Called when the windows is reshaped - void reshape(); - - /// Set the scene position (where the camera needs to look at) - void setScenePosition(const openglframework::Vector3& position, float sceneRadius); - - /// Set the camera so that we can view the whole scene - void resetCameraToViewAll(); - - /// Zoom the camera - void zoom(float zoomDiff); - - /// Translate the camera - void translate(int xMouse, int yMouse); - - /// Rotate the camera - void rotate(int xMouse, int yMouse); - - /// Get the camera - openglframework::Camera& getCamera(); - - /// Called when a GLUT mouse button event occurs - void mouseButtonEvent(int button, int action); - - /// Called when a GLUT mouse motion event occurs - void mouseMotionEvent(double xMouse, double yMouse); - - /// Called when a scrolling event occurs - void scrollingEvent(float scrollAxis); - - /// Check the OpenGL errors - static void checkOpenGLErrors(); - - /// Display the FPS - void displayFPS(); - - /// Compute the FPS - void computeFPS(); - - /// Display the GUI - void displayGUI(); - - /// GLFW error callback method - static void error_callback(int error, const char* description); - - /// Register the update function that has to be called each frame - void registerUpdateFunction(void (*updateFunctionPointer)()); - - /// Register a keyboard callback method - void registerKeyboardCallback(GLFWkeyfun method); - - /// Register a mouse button callback method - void registerMouseButtonCallback(GLFWmousebuttonfun method); - - /// Register a mouse cursor motion callback method - void registerMouseCursorCallback(GLFWcursorposfun method); - - /// Register a scrolling cursor callback method - void registerScrollingCallback(GLFWscrollfun method); - -}; - -// Set the scene position (where the camera needs to look at) -inline void Viewer::setScenePosition(const openglframework::Vector3& position, float sceneRadius) { - - // Set the position and radius of the scene - mCenterScene = position; - mCamera.setSceneRadius(sceneRadius); - - // Reset the camera position and zoom in order to view all the scene - resetCameraToViewAll(); -} - -// Get the camera -inline openglframework::Camera& Viewer::getCamera() { - return mCamera; -} - -// Register the update function that has to be called each frame -inline void Viewer::registerUpdateFunction(void (*updateFunctionPointer)()) { - mUpdateFunctionPointer = updateFunctionPointer; -} - -// Register a keyboard callback method -inline void Viewer::registerKeyboardCallback(GLFWkeyfun method) { - glfwSetKeyCallback(mWindow, method); -} - -// Register a mouse button callback method -inline void Viewer::registerMouseButtonCallback(GLFWmousebuttonfun method) { - glfwSetMouseButtonCallback(mWindow, method); -} - -// Register a mouse cursor motion callback method -inline void Viewer::registerMouseCursorCallback(GLFWcursorposfun method) { - glfwSetCursorPosCallback(mWindow, method); -} - -// Register a scrolling cursor callback method -inline void Viewer::registerScrollingCallback(GLFWscrollfun method) { - glfwSetScrollCallback(mWindow, method); -} - -#endif diff --git a/examples/common/VisualContactPoint.cpp b/examples/common/VisualContactPoint.cpp deleted file mode 100644 index 77337192..00000000 --- a/examples/common/VisualContactPoint.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/******************************************************************************** -* ReactPhysics3D physics library, http://www.reactphysics3d.com * -* Copyright (c) 2010-2015 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -// Libraries -#include "VisualContactPoint.h" - -// Initialization of static variables -int VisualContactPoint::mNbTotalPoints = 0; -bool VisualContactPoint::mIsMeshInitialized = false; -openglframework::Mesh VisualContactPoint::mMesh; - -// Constructor -VisualContactPoint::VisualContactPoint(const openglframework::Vector3& position) { - - assert(mIsMeshInitialized); - - // Initialize the position where the sphere will be rendered - translateWorld(position); -} - -// Destructor -VisualContactPoint::~VisualContactPoint() { - -} - -// Load and initialize the mesh for all the contact points -void VisualContactPoint::createStaticData(const std::string& meshFolderPath) { - - if (!mIsMeshInitialized) { - - // Load the mesh from a file - openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "sphere.obj", mMesh); - - // Calculate the normals of the mesh - mMesh.calculateNormals(); - - mMesh.scaleVertices(VISUAL_CONTACT_POINT_RADIUS); - - mIsMeshInitialized = true; - } -} - -// Destroy the mesh for the contact points -void VisualContactPoint::destroyStaticData() { - - mMesh.destroy(); - mIsMeshInitialized = false; -} - -// Render the sphere at the correct position and with the correct orientation -void VisualContactPoint::render(openglframework::Shader& shader, - const openglframework::Matrix4& worldToCameraMatrix) { - - // Bind the shader - shader.bind(); - - // Set the model to camera matrix - const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix; - shader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix); - - // Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the - // model-view matrix) - const openglframework::Matrix3 normalMatrix = - localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose(); - shader.setMatrix3x3Uniform("normalMatrix", normalMatrix); - - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - if (mMesh.hasTexture()) { - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - } - - glVertexPointer(3, GL_FLOAT, 0, mMesh.getVerticesPointer()); - glNormalPointer(GL_FLOAT, 0, mMesh.getNormalsPointer()); - if(mMesh.hasTexture()) { - glTexCoordPointer(2, GL_FLOAT, 0, mMesh.getUVTextureCoordinatesPointer()); - } - - // For each part of the mesh - for (unsigned int i=0; i - -if (NOT WIN32) - - find_package (PkgConfig) - pkg_check_modules (PKG_MIR QUIET mirclient) - - set (MIR_INCLUDE_DIR ${PKG_MIR_INCLUDE_DIRS}) - set (MIR_LIBRARIES ${PKG_MIR_LIBRARIES}) - -endif () diff --git a/examples/common/glfw/CMake/modules/FindWayland.cmake b/examples/common/glfw/CMake/modules/FindWayland.cmake deleted file mode 100644 index f93218b8..00000000 --- a/examples/common/glfw/CMake/modules/FindWayland.cmake +++ /dev/null @@ -1,66 +0,0 @@ -# Try to find Wayland on a Unix system -# -# This will define: -# -# WAYLAND_FOUND - True if Wayland is found -# WAYLAND_LIBRARIES - Link these to use Wayland -# WAYLAND_INCLUDE_DIR - Include directory for Wayland -# WAYLAND_DEFINITIONS - Compiler flags for using Wayland -# -# In addition the following more fine grained variables will be defined: -# -# WAYLAND_CLIENT_FOUND WAYLAND_CLIENT_INCLUDE_DIR WAYLAND_CLIENT_LIBRARIES -# WAYLAND_SERVER_FOUND WAYLAND_SERVER_INCLUDE_DIR WAYLAND_SERVER_LIBRARIES -# WAYLAND_EGL_FOUND WAYLAND_EGL_INCLUDE_DIR WAYLAND_EGL_LIBRARIES -# -# Copyright (c) 2013 Martin Gräßlin -# -# Redistribution and use is allowed according to the terms of the BSD license. -# For details see the accompanying COPYING-CMAKE-SCRIPTS file. - -IF (NOT WIN32) - IF (WAYLAND_INCLUDE_DIR AND WAYLAND_LIBRARIES) - # In the cache already - SET(WAYLAND_FIND_QUIETLY TRUE) - ENDIF () - - # Use pkg-config to get the directories and then use these values - # in the FIND_PATH() and FIND_LIBRARY() calls - FIND_PACKAGE(PkgConfig) - PKG_CHECK_MODULES(PKG_WAYLAND QUIET wayland-client wayland-server wayland-egl wayland-cursor) - - SET(WAYLAND_DEFINITIONS ${PKG_WAYLAND_CFLAGS}) - - FIND_PATH(WAYLAND_CLIENT_INCLUDE_DIR NAMES wayland-client.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS}) - FIND_PATH(WAYLAND_SERVER_INCLUDE_DIR NAMES wayland-server.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS}) - FIND_PATH(WAYLAND_EGL_INCLUDE_DIR NAMES wayland-egl.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS}) - FIND_PATH(WAYLAND_CURSOR_INCLUDE_DIR NAMES wayland-cursor.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS}) - - FIND_LIBRARY(WAYLAND_CLIENT_LIBRARIES NAMES wayland-client HINTS ${PKG_WAYLAND_LIBRARY_DIRS}) - FIND_LIBRARY(WAYLAND_SERVER_LIBRARIES NAMES wayland-server HINTS ${PKG_WAYLAND_LIBRARY_DIRS}) - FIND_LIBRARY(WAYLAND_EGL_LIBRARIES NAMES wayland-egl HINTS ${PKG_WAYLAND_LIBRARY_DIRS}) - FIND_LIBRARY(WAYLAND_CURSOR_LIBRARIES NAMES wayland-cursor HINTS ${PKG_WAYLAND_LIBRARY_DIRS}) - - set(WAYLAND_INCLUDE_DIR ${WAYLAND_CLIENT_INCLUDE_DIR} ${WAYLAND_SERVER_INCLUDE_DIR} ${WAYLAND_EGL_INCLUDE_DIR} ${WAYLAND_CURSOR_INCLUDE_DIR}) - - set(WAYLAND_LIBRARIES ${WAYLAND_CLIENT_LIBRARIES} ${WAYLAND_SERVER_LIBRARIES} ${WAYLAND_EGL_LIBRARIES} ${WAYLAND_CURSOR_LIBRARIES}) - - list(REMOVE_DUPLICATES WAYLAND_INCLUDE_DIR) - - include(FindPackageHandleStandardArgs) - - FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_CLIENT DEFAULT_MSG WAYLAND_CLIENT_LIBRARIES WAYLAND_CLIENT_INCLUDE_DIR) - FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_SERVER DEFAULT_MSG WAYLAND_SERVER_LIBRARIES WAYLAND_SERVER_INCLUDE_DIR) - FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_EGL DEFAULT_MSG WAYLAND_EGL_LIBRARIES WAYLAND_EGL_INCLUDE_DIR) - FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_CURSOR DEFAULT_MSG WAYLAND_CURSOR_LIBRARIES WAYLAND_CURSOR_INCLUDE_DIR) - FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND DEFAULT_MSG WAYLAND_LIBRARIES WAYLAND_INCLUDE_DIR) - - MARK_AS_ADVANCED( - WAYLAND_INCLUDE_DIR WAYLAND_LIBRARIES - WAYLAND_CLIENT_INCLUDE_DIR WAYLAND_CLIENT_LIBRARIES - WAYLAND_SERVER_INCLUDE_DIR WAYLAND_SERVER_LIBRARIES - WAYLAND_EGL_INCLUDE_DIR WAYLAND_EGL_LIBRARIES - WAYLAND_CURSOR_INCLUDE_DIR WAYLAND_CURSOR_LIBRARIES - ) - -ENDIF () diff --git a/examples/common/glfw/CMake/modules/FindXKBCommon.cmake b/examples/common/glfw/CMake/modules/FindXKBCommon.cmake deleted file mode 100644 index 0f571eea..00000000 --- a/examples/common/glfw/CMake/modules/FindXKBCommon.cmake +++ /dev/null @@ -1,34 +0,0 @@ -# - Try to find XKBCommon -# Once done, this will define -# -# XKBCOMMON_FOUND - System has XKBCommon -# XKBCOMMON_INCLUDE_DIRS - The XKBCommon include directories -# XKBCOMMON_LIBRARIES - The libraries needed to use XKBCommon -# XKBCOMMON_DEFINITIONS - Compiler switches required for using XKBCommon - -find_package(PkgConfig) -pkg_check_modules(PC_XKBCOMMON QUIET xkbcommon) -set(XKBCOMMON_DEFINITIONS ${PC_XKBCOMMON_CFLAGS_OTHER}) - -find_path(XKBCOMMON_INCLUDE_DIR - NAMES xkbcommon/xkbcommon.h - HINTS ${PC_XKBCOMMON_INCLUDE_DIR} ${PC_XKBCOMMON_INCLUDE_DIRS} -) - -find_library(XKBCOMMON_LIBRARY - NAMES xkbcommon - HINTS ${PC_XKBCOMMON_LIBRARY} ${PC_XKBCOMMON_LIBRARY_DIRS} -) - -set(XKBCOMMON_LIBRARIES ${XKBCOMMON_LIBRARY}) -set(XKBCOMMON_LIBRARY_DIRS ${XKBCOMMON_LIBRARY_DIRS}) -set(XKBCOMMON_INCLUDE_DIRS ${XKBCOMMON_INCLUDE_DIR}) - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(XKBCommon DEFAULT_MSG - XKBCOMMON_LIBRARY - XKBCOMMON_INCLUDE_DIR -) - -mark_as_advanced(XKBCOMMON_LIBRARY XKBCOMMON_INCLUDE_DIR) - diff --git a/examples/common/glfw/CMake/x86_64-w64-mingw32.cmake b/examples/common/glfw/CMake/x86_64-w64-mingw32.cmake deleted file mode 100644 index 84b2c701..00000000 --- a/examples/common/glfw/CMake/x86_64-w64-mingw32.cmake +++ /dev/null @@ -1,13 +0,0 @@ -# Define the environment for cross compiling from Linux to Win32 -SET(CMAKE_SYSTEM_NAME Windows) # Target system name -SET(CMAKE_SYSTEM_VERSION 1) -SET(CMAKE_C_COMPILER "x86_64-w64-mingw32-gcc") -SET(CMAKE_CXX_COMPILER "x86_64-w64-mingw32-g++") -SET(CMAKE_RC_COMPILER "x86_64-w64-mingw32-windres") -SET(CMAKE_RANLIB "x86_64-w64-mingw32-ranlib") - -# Configure the behaviour of the find commands -SET(CMAKE_FIND_ROOT_PATH "/usr/x86_64-w64-mingw32") -SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) -SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) -SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/examples/common/glfw/CMakeLists.txt b/examples/common/glfw/CMakeLists.txt deleted file mode 100644 index 731f09f7..00000000 --- a/examples/common/glfw/CMakeLists.txt +++ /dev/null @@ -1,586 +0,0 @@ -project(GLFW C) - -cmake_minimum_required(VERSION 2.8.9) - -if (CMAKE_VERSION VERSION_EQUAL "3.0" OR CMAKE_VERSION VERSION_GREATER "3.0") - # Until all major package systems have moved to CMake 3, - # we stick with the older INSTALL_NAME_DIR mechanism - cmake_policy(SET CMP0042 OLD) -endif() - -set(GLFW_VERSION_MAJOR "3") -set(GLFW_VERSION_MINOR "1") -set(GLFW_VERSION_PATCH "0") -set(GLFW_VERSION_EXTRA "") -set(GLFW_VERSION "${GLFW_VERSION_MAJOR}.${GLFW_VERSION_MINOR}") -set(GLFW_VERSION_FULL "${GLFW_VERSION}.${GLFW_VERSION_PATCH}${GLFW_VERSION_EXTRA}") -set(LIB_SUFFIX "" CACHE STRING "Takes an empty string or 64. Directory where lib will be installed: lib or lib64") - -set_property(GLOBAL PROPERTY USE_FOLDERS ON) - -option(BUILD_SHARED_LIBS "Build shared libraries" OFF) -option(GLFW_BUILD_EXAMPLES "Build the GLFW example programs" ON) -option(GLFW_BUILD_TESTS "Build the GLFW test programs" ON) -option(GLFW_BUILD_DOCS "Build the GLFW documentation" ON) -option(GLFW_INSTALL "Generate installation target" ON) -option(GLFW_DOCUMENT_INTERNALS "Include internals in documentation" OFF) - -if (WIN32) - option(GLFW_USE_DWM_SWAP_INTERVAL "Set swap interval even when DWM compositing is enabled" OFF) - option(GLFW_USE_OPTIMUS_HPG "Force use of high-performance GPU on Optimus systems" OFF) -endif() - -if (APPLE) - option(GLFW_BUILD_UNIVERSAL "Build GLFW as a Universal Binary" OFF) - option(GLFW_USE_CHDIR "Make glfwInit chdir to Contents/Resources" ON) - option(GLFW_USE_MENUBAR "Populate the menu bar on first window creation" ON) - option(GLFW_USE_RETINA "Use the full resolution of Retina displays" ON) -else() - option(GLFW_USE_EGL "Use EGL for context creation" OFF) -endif() - -if (UNIX AND NOT APPLE) - option(GLFW_USE_WAYLAND "Use Wayland for context creation (implies EGL as well)" OFF) - option(GLFW_USE_MIR "Use Mir for context creation (implies EGL as well)" OFF) -endif() - -if (MSVC) - option(USE_MSVC_RUNTIME_LIBRARY_DLL "Use MSVC runtime library DLL" ON) -endif() - -if (BUILD_SHARED_LIBS) - set(_GLFW_BUILD_DLL 1) -endif() - -if (GLFW_USE_WAYLAND) - set(GLFW_USE_EGL ON) -elseif (GLFW_USE_MIR) - set(GLFW_USE_EGL ON) -endif() - -if (GLFW_USE_EGL) - set(GLFW_CLIENT_LIBRARY "opengl" CACHE STRING - "The client library to use; one of opengl, glesv1 or glesv2") - - if (${GLFW_CLIENT_LIBRARY} STREQUAL "opengl") - set(_GLFW_USE_OPENGL 1) - elseif (${GLFW_CLIENT_LIBRARY} STREQUAL "glesv1") - set(_GLFW_USE_GLESV1 1) - elseif (${GLFW_CLIENT_LIBRARY} STREQUAL "glesv2") - set(_GLFW_USE_GLESV2 1) - else() - message(FATAL_ERROR "Unsupported client library") - endif() - - set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/CMake/modules") - find_package(EGL REQUIRED) - - if (NOT _GLFW_USE_OPENGL) - set(GLFW_BUILD_EXAMPLES OFF) - set(GLFW_BUILD_TESTS OFF) - message(STATUS "NOTE: Examples and tests require OpenGL") - endif() -else() - set(_GLFW_USE_OPENGL 1) -endif() - -if (_GLFW_USE_OPENGL) - find_package(OpenGL REQUIRED) -elseif (_GLFW_USE_GLESV1) - find_package(GLESv1 REQUIRED) -elseif (_GLFW_USE_GLESV2) - find_package(GLESv2 REQUIRED) -endif() - -find_package(Threads REQUIRED) - -if (GLFW_BUILD_DOCS) - set(DOXYGEN_SKIP_DOT TRUE) - find_package(Doxygen) - - if (GLFW_DOCUMENT_INTERNALS) - set(GLFW_INTERNAL_DOCS "${GLFW_SOURCE_DIR}/src/internal.h ${GLFW_SOURCE_DIR}/docs/internal.dox") - endif() -endif() - -#-------------------------------------------------------------------- -# Set compiler specific flags -#-------------------------------------------------------------------- -if (UNIX) - add_definitions(-Wall) - - if (BUILD_SHARED_LIBS) - add_definitions(-fvisibility=hidden) - endif() -endif() - -if (MSVC) - add_definitions(-D_CRT_SECURE_NO_WARNINGS) - - if (NOT USE_MSVC_RUNTIME_LIBRARY_DLL) - foreach (flag CMAKE_C_FLAGS - CMAKE_C_FLAGS_DEBUG - CMAKE_C_FLAGS_RELEASE - CMAKE_C_FLAGS_MINSIZEREL - CMAKE_C_FLAGS_RELWITHDEBINFO) - - if (${flag} MATCHES "/MD") - string(REGEX REPLACE "/MD" "/MT" ${flag} "${${flag}}") - endif() - if (${flag} MATCHES "/MDd") - string(REGEX REPLACE "/MDd" "/MTd" ${flag} "${${flag}}") - endif() - - endforeach() - endif() -endif() - -if (MINGW) - # Enable link-time exploit mitigation features enabled by default on MSVC - - include(CheckCCompilerFlag) - - # Compatibility with data execution prevention (DEP) - set(CMAKE_REQUIRED_FLAGS "-Wl,--nxcompat") - check_c_compiler_flag("" _GLFW_HAS_DEP) - if (_GLFW_HAS_DEP) - set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--nxcompat ${CMAKE_SHARED_LINKER_FLAGS}") - endif() - - # Compatibility with address space layout randomization (ASLR) - set(CMAKE_REQUIRED_FLAGS "-Wl,--dynamicbase") - check_c_compiler_flag("" _GLFW_HAS_ASLR) - if (_GLFW_HAS_ASLR) - set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--dynamicbase ${CMAKE_SHARED_LINKER_FLAGS}") - endif() - - # Compatibility with 64-bit address space layout randomization (ASLR) - set(CMAKE_REQUIRED_FLAGS "-Wl,--high-entropy-va") - check_c_compiler_flag("" _GLFW_HAS_64ASLR) - if (_GLFW_HAS_64ASLR) - set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--high-entropy-va ${CMAKE_SHARED_LINKER_FLAGS}") - endif() -endif() - -#-------------------------------------------------------------------- -# Detect and select backend APIs -#-------------------------------------------------------------------- -if (WIN32) - set(_GLFW_WIN32 1) - message(STATUS "Using Win32 for window creation") - - if (GLFW_USE_EGL) - set(_GLFW_EGL 1) - message(STATUS "Using EGL for context creation") - else() - set(_GLFW_WGL 1) - message(STATUS "Using WGL for context creation") - endif() -elseif (APPLE) - set(_GLFW_COCOA 1) - message(STATUS "Using Cocoa for window creation") - set(_GLFW_NSGL 1) - message(STATUS "Using NSGL for context creation") -elseif (UNIX) - if (GLFW_USE_WAYLAND) - set(_GLFW_WAYLAND 1) - message(STATUS "Using Wayland for window creation") - elseif (GLFW_USE_MIR) - set(_GLFW_MIR 1) - message(STATUS "Using Mir for window creation") - else() - set(_GLFW_X11 1) - message(STATUS "Using X11 for window creation") - endif() - - if (GLFW_USE_EGL) - set(_GLFW_EGL 1) - message(STATUS "Using EGL for context creation") - else() - set(_GLFW_GLX 1) - message(STATUS "Using GLX for context creation") - endif() -else() - message(FATAL_ERROR "No supported platform was detected") -endif() - -#-------------------------------------------------------------------- -# Use Win32 for window creation -#-------------------------------------------------------------------- -if (_GLFW_WIN32) - - list(APPEND glfw_PKG_LIBS "-lgdi32") - - if (GLFW_USE_DWM_SWAP_INTERVAL) - set(_GLFW_USE_DWM_SWAP_INTERVAL 1) - endif() - if (GLFW_USE_OPTIMUS_HPG) - set(_GLFW_USE_OPTIMUS_HPG 1) - endif() - - # HACK: When building on MinGW, WINVER and UNICODE need to be defined before - # the inclusion of stddef.h (by glfw3.h), which is itself included before - # win32_platform.h. We define them here until a saner solution can be found - # NOTE: MinGW-w64 and Visual C++ do /not/ need this hack. - if (${CMAKE_C_COMPILER_ID} STREQUAL "GNU") - add_definitions(-DUNICODE -DWINVER=0x0501) - endif() -endif() - -#-------------------------------------------------------------------- -# Use WGL for context creation -#-------------------------------------------------------------------- -if (_GLFW_WGL) - - list(APPEND glfw_PKG_LIBS "-lopengl32") - - list(APPEND glfw_INCLUDE_DIRS "${OPENGL_INCLUDE_DIR}") - list(APPEND glfw_LIBRARIES "${OPENGL_gl_LIBRARY}") -endif() - -#-------------------------------------------------------------------- -# Use X11 for window creation -#-------------------------------------------------------------------- -if (_GLFW_X11) - - find_package(X11 REQUIRED) - - list(APPEND glfw_PKG_DEPS "x11") - - # Set up library and include paths - list(APPEND glfw_INCLUDE_DIRS "${X11_X11_INCLUDE_PATH}") - list(APPEND glfw_LIBRARIES "${X11_X11_LIB}" "${CMAKE_THREAD_LIBS_INIT}") - if (UNIX AND NOT APPLE) - list(APPEND glfw_LIBRARIES "${RT_LIBRARY}") - endif() - - # Check for XRandR (modern resolution switching and gamma control) - if (NOT X11_Xrandr_FOUND) - message(FATAL_ERROR "The RandR library and headers were not found") - endif() - - list(APPEND glfw_INCLUDE_DIRS "${X11_Xrandr_INCLUDE_PATH}") - list(APPEND glfw_LIBRARIES "${X11_Xrandr_LIB}") - list(APPEND glfw_PKG_DEPS "xrandr") - - # Check for Xinerama (legacy multi-monitor support) - if (NOT X11_Xinerama_FOUND) - message(FATAL_ERROR "The Xinerama library and headers were not found") - endif() - - list(APPEND glfw_INCLUDE_DIRS "${X11_Xinerama_INCLUDE_PATH}") - list(APPEND glfw_LIBRARIES "${X11_Xinerama_LIB}") - list(APPEND glfw_PKG_DEPS "xinerama") - - # Check for XInput (high-resolution cursor motion) - if (NOT X11_Xinput_FOUND) - message(FATAL_ERROR "The XInput library and headers were not found") - endif() - - list(APPEND glfw_INCLUDE_DIRS "${X11_Xinput_INCLUDE_PATH}") - - if (X11_Xinput_LIB) - list(APPEND glfw_LIBRARIES "${X11_Xinput_LIB}") - else() - # Backwards compatibility (bug in CMake 2.8.7) - list(APPEND glfw_LIBRARIES Xi) - endif() - list(APPEND glfw_PKG_DEPS "xi") - - # Check for Xf86VidMode (fallback gamma control) - if (NOT X11_xf86vmode_FOUND) - message(FATAL_ERROR "The Xf86VidMode library and headers were not found") - endif() - - list(APPEND glfw_INCLUDE_DIRS "${X11_xf86vmode_INCLUDE_PATH}") - list(APPEND glfw_PKG_DEPS "xxf86vm") - - if (X11_Xxf86vm_LIB) - list(APPEND glfw_LIBRARIES "${X11_Xxf86vm_LIB}") - else() - # Backwards compatibility (see CMake bug 0006976) - list(APPEND glfw_LIBRARIES Xxf86vm) - endif() - - # Check for Xkb (X keyboard extension) - if (NOT X11_Xkb_FOUND) - message(FATAL_ERROR "The X keyboard extension headers were not found") - endif() - - list(APPEND glfw_INCLUDE_DIR "${X11_Xkb_INCLUDE_PATH}") - - find_library(RT_LIBRARY rt) - mark_as_advanced(RT_LIBRARY) - if (RT_LIBRARY) - list(APPEND glfw_LIBRARIES "${RT_LIBRARY}") - list(APPEND glfw_PKG_LIBS "-lrt") - endif() - - find_library(MATH_LIBRARY m) - mark_as_advanced(MATH_LIBRARY) - if (MATH_LIBRARY) - list(APPEND glfw_LIBRARIES "${MATH_LIBRARY}") - list(APPEND glfw_PKG_LIBS "-lm") - endif() - - # Check for Xcursor - if (NOT X11_Xcursor_FOUND) - message(FATAL_ERROR "The Xcursor libraries and headers were not found") - endif() - - list(APPEND glfw_INCLUDE_DIR "${X11_Xcursor_INCLUDE_PATH}") - list(APPEND glfw_LIBRARIES "${X11_Xcursor_LIB}") - list(APPEND glfw_PKG_DEPS "xcursor") - -endif() - -#-------------------------------------------------------------------- -# Use Wayland for window creation -#-------------------------------------------------------------------- -if (_GLFW_WAYLAND) - find_package(Wayland REQUIRED) - list(APPEND glfw_PKG_DEPS "wayland-egl") - - list(APPEND glfw_INCLUDE_DIRS "${WAYLAND_INCLUDE_DIR}") - list(APPEND glfw_LIBRARIES "${WAYLAND_LIBRARIES}" "${CMAKE_THREAD_LIBS_INIT}") - - find_package(XKBCommon REQUIRED) - list(APPEND glfw_PKG_DEPS "xkbcommon") - list(APPEND glfw_INCLUDE_DIRS "${XKBCOMMON_INCLUDE_DIRS}") - list(APPEND glfw_LIBRARIES "${XKBCOMMON_LIBRARY}") - - find_library(MATH_LIBRARY m) - mark_as_advanced(MATH_LIBRARY) - if (MATH_LIBRARY) - list(APPEND glfw_LIBRARIES "${MATH_LIBRARY}") - list(APPEND glfw_PKG_LIBS "-lm") - endif() -endif() - -#-------------------------------------------------------------------- -# Use Mir for window creation -#-------------------------------------------------------------------- -if (_GLFW_MIR) - find_package(Mir REQUIRED) - list(APPEND glfw_PKG_DEPS "mirclient") - - list(APPEND glfw_INCLUDE_DIRS "${MIR_INCLUDE_DIR}") - list(APPEND glfw_LIBRARIES "${MIR_LIBRARIES}" "${CMAKE_THREAD_LIBS_INIT}") - - find_package(XKBCommon REQUIRED) - list(APPEND glfw_PKG_DEPS "xkbcommon") - list(APPEND glfw_INCLUDE_DIRS "${XKBCOMMON_INCLUDE_DIRS}") - list(APPEND glfw_LIBRARIES "${XKBCOMMON_LIBRARY}") - - find_library(MATH_LIBRARY m) - mark_as_advanced(MATH_LIBRARY) - if (MATH_LIBRARY) - list(APPEND glfw_LIBRARIES "${MATH_LIBRARY}") - list(APPEND glfw_PKG_LIBS "-lm") - endif() -endif() - -#-------------------------------------------------------------------- -# Use GLX for context creation -#-------------------------------------------------------------------- -if (_GLFW_GLX) - - list(APPEND glfw_INCLUDE_DIRS "${OPENGL_INCLUDE_DIR}") - list(APPEND glfw_LIBRARIES "${OPENGL_gl_LIBRARY}") - - list(APPEND glfw_PKG_DEPS "gl") - - include(CheckFunctionExists) - - set(CMAKE_REQUIRED_LIBRARIES "${OPENGL_gl_LIBRARY}") - check_function_exists(glXGetProcAddress _GLFW_HAS_GLXGETPROCADDRESS) - check_function_exists(glXGetProcAddressARB _GLFW_HAS_GLXGETPROCADDRESSARB) - check_function_exists(glXGetProcAddressEXT _GLFW_HAS_GLXGETPROCADDRESSEXT) - - if (NOT _GLFW_HAS_GLXGETPROCADDRESS AND - NOT _GLFW_HAS_GLXGETPROCADDRESSARB AND - NOT _GLFW_HAS_GLXGETPROCADDRESSEXT) - message(WARNING "No glXGetProcAddressXXX variant found") - - # Check for dlopen support as a fallback - - set(CMAKE_REQUIRED_LIBRARIES "${CMAKE_DL_LIBS}") - check_function_exists(dlopen _GLFW_HAS_DLOPEN) - if (NOT _GLFW_HAS_DLOPEN) - message(FATAL_ERROR "No entry point retrieval mechanism found") - endif() - - if (CMAKE_DL_LIBS) - list(APPEND glfw_LIBRARIES "${CMAKE_DL_LIBS}") - list(APPEND glfw_PKG_LIBS "-l${CMAKE_DL_LIBS}") - endif() - endif() - -endif() - -#-------------------------------------------------------------------- -# Use EGL for context creation -#-------------------------------------------------------------------- -if (_GLFW_EGL) - - list(APPEND glfw_INCLUDE_DIRS "${EGL_INCLUDE_DIR}") - list(APPEND glfw_LIBRARIES "${EGL_LIBRARY}") - - list(APPEND glfw_PKG_DEPS "egl") - - if (_GLFW_USE_OPENGL) - list(APPEND glfw_LIBRARIES "${OPENGL_gl_LIBRARY}") - list(APPEND glfw_INCLUDE_DIRS "${OPENGL_INCLUDE_DIR}") - list(APPEND glfw_PKG_DEPS "gl") - elseif (_GLFW_USE_GLESV1) - list(APPEND glfw_LIBRARIES "${GLESv1_LIBRARY}") - list(APPEND glfw_INCLUDE_DIRS "${GLESv1_INCLUDE_DIR}") - list(APPEND glfw_PKG_DEPS "glesv1_cm") - elseif (_GLFW_USE_GLESV2) - list(APPEND glfw_LIBRARIES "${GLESv2_LIBRARY}") - list(APPEND glfw_INCLUDE_DIRS "${GLESv2_INCLUDE_DIR}") - list(APPEND glfw_PKG_DEPS "glesv2") - endif() - -endif() - -#-------------------------------------------------------------------- -# Use Cocoa for window creation and NSOpenGL for context creation -#-------------------------------------------------------------------- -if (_GLFW_COCOA AND _GLFW_NSGL) - - if (GLFW_USE_MENUBAR) - set(_GLFW_USE_MENUBAR 1) - endif() - - if (GLFW_USE_CHDIR) - set(_GLFW_USE_CHDIR 1) - endif() - - if (GLFW_USE_RETINA) - set(_GLFW_USE_RETINA 1) - endif() - - if (GLFW_BUILD_UNIVERSAL) - message(STATUS "Building GLFW as Universal Binaries") - set(CMAKE_OSX_ARCHITECTURES i386;x86_64) - else() - message(STATUS "Building GLFW only for the native architecture") - endif() - - # Set up library and include paths - find_library(COCOA_FRAMEWORK Cocoa) - find_library(IOKIT_FRAMEWORK IOKit) - find_library(CORE_FOUNDATION_FRAMEWORK CoreFoundation) - find_library(CORE_VIDEO_FRAMEWORK CoreVideo) - mark_as_advanced(COCOA_FRAMEWORK - IOKIT_FRAMEWORK - CORE_FOUNDATION_FRAMEWORK - CORE_VIDEO_FRAMEWORK) - list(APPEND glfw_LIBRARIES "${COCOA_FRAMEWORK}" - "${OPENGL_gl_LIBRARY}" - "${IOKIT_FRAMEWORK}" - "${CORE_FOUNDATION_FRAMEWORK}" - "${CORE_VIDEO_FRAMEWORK}") - - set(glfw_PKG_DEPS "") - set(glfw_PKG_LIBS "-framework Cocoa -framework OpenGL -framework IOKit -framework CoreFoundation -framework CoreVideo") -endif() - -#-------------------------------------------------------------------- -# Export GLFW library dependencies -#-------------------------------------------------------------------- -set(GLFW_LIBRARIES ${glfw_LIBRARIES} CACHE STRING "Dependencies of GLFW") -foreach(arg ${glfw_PKG_DEPS}) - set(GLFW_PKG_DEPS "${GLFW_PKG_DEPS} ${arg}") -endforeach() -foreach(arg ${glfw_PKG_LIBS}) - set(GLFW_PKG_LIBS "${GLFW_PKG_LIBS} ${arg}") -endforeach() - -#-------------------------------------------------------------------- -# Choose library output name -#-------------------------------------------------------------------- -if (BUILD_SHARED_LIBS AND UNIX) - # On Unix-like systems, shared libraries can use the soname system. - set(GLFW_LIB_NAME glfw) -else() - set(GLFW_LIB_NAME glfw3) -endif() - -#-------------------------------------------------------------------- -# Create generated files -#-------------------------------------------------------------------- -include(CMakePackageConfigHelpers) - -if (UNIX) - set(GLFW_CONFIG_PATH "${CMAKE_INSTALL_PREFIX}/lib/cmake/glfw3/") -else() - set(GLFW_CONFIG_PATH "${CMAKE_INSTALL_PREFIX}/") -endif() - -configure_package_config_file("${GLFW_SOURCE_DIR}/src/glfw3Config.cmake.in" - "${GLFW_BINARY_DIR}/src/glfw3Config.cmake" - INSTALL_DESTINATION "${GLFW_CONFIG_PATH}" - PATH_VARS CMAKE_INSTALL_PREFIX - NO_CHECK_REQUIRED_COMPONENTS_MACRO) - -write_basic_package_version_file("${GLFW_BINARY_DIR}/src/glfw3ConfigVersion.cmake" - VERSION ${GLFW_VERSION_FULL} - COMPATIBILITY SameMajorVersion) - -if (GLFW_BUILD_DOCS) - configure_file("${GLFW_SOURCE_DIR}/docs/Doxyfile.in" - "${GLFW_BINARY_DIR}/docs/Doxyfile" @ONLY) -endif() - -configure_file("${GLFW_SOURCE_DIR}/src/glfw_config.h.in" - "${GLFW_BINARY_DIR}/src/glfw_config.h" @ONLY) - -configure_file("${GLFW_SOURCE_DIR}/src/glfw3.pc.in" - "${GLFW_BINARY_DIR}/src/glfw3.pc" @ONLY) - -#-------------------------------------------------------------------- -# Add subdirectories -#-------------------------------------------------------------------- -add_subdirectory(src) - -if (GLFW_BUILD_EXAMPLES) - add_subdirectory(examples) -endif() - -if (GLFW_BUILD_TESTS) - add_subdirectory(tests) -endif() - -if (DOXYGEN_FOUND AND GLFW_BUILD_DOCS) - add_subdirectory(docs) -endif() - -#-------------------------------------------------------------------- -# Install files other than the library -# The library is installed by src/CMakeLists.txt -#-------------------------------------------------------------------- -if (GLFW_INSTALL) - install(DIRECTORY include/GLFW DESTINATION include - FILES_MATCHING PATTERN glfw3.h PATTERN glfw3native.h) - - install(FILES "${GLFW_BINARY_DIR}/src/glfw3Config.cmake" - "${GLFW_BINARY_DIR}/src/glfw3ConfigVersion.cmake" - DESTINATION lib${LIB_SUFFIX}/cmake/glfw) - - install(EXPORT glfwTargets DESTINATION lib${LIB_SUFFIX}/cmake/glfw) - install(FILES "${GLFW_BINARY_DIR}/src/glfw3.pc" - DESTINATION lib${LIB_SUFFIX}/pkgconfig) - - # Only generate this target if no higher-level project already has - if (NOT TARGET uninstall) - configure_file("${GLFW_SOURCE_DIR}/cmake_uninstall.cmake.in" - "${GLFW_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY) - - add_custom_target(uninstall - "${CMAKE_COMMAND}" -P - "${GLFW_BINARY_DIR}/cmake_uninstall.cmake") - endif() -endif() - diff --git a/examples/common/glfw/COPYING.txt b/examples/common/glfw/COPYING.txt deleted file mode 100644 index b30c7015..00000000 --- a/examples/common/glfw/COPYING.txt +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 2002-2006 Marcus Geelnard -Copyright (c) 2006-2010 Camilla Berglund - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any damages -arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would - be appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and must not - be misrepresented as being the original software. - -3. This notice may not be removed or altered from any source - distribution. - diff --git a/examples/common/glfw/README.md b/examples/common/glfw/README.md deleted file mode 100644 index 91b3ae5e..00000000 --- a/examples/common/glfw/README.md +++ /dev/null @@ -1,294 +0,0 @@ -# GLFW - -## Introduction - -GLFW is a free, Open Source, multi-platform library for OpenGL and OpenGL ES -application development. It provides a simple, platform-independent API for -creating windows and contexts, reading input, handling events, etc. - -Version 3.1 adds improved documentation, support for custom system cursors, file -drop events, main thread wake-up, window frame size retrieval, floating windows, -character input with modifier keys, single buffered windows, build improvements -and fixes for a large number of bugs. - -If you are new to GLFW, you may find the -[introductory tutorial](http://www.glfw.org/docs/latest/quick.html) for GLFW -3 useful. If you have used GLFW 2 in the past, there is a -[transition guide](http://www.glfw.org/docs/latest/moving.html) for moving to -the GLFW 3 API. - -Note that a number of source files have been added or renamed in 3.1, which may -require you to update any custom build files you have. - - -## Compiling GLFW - -See the [Compiling GLFW](http://www.glfw.org/docs/latest/compile.html) guide in -the GLFW documentation. - - -## Using GLFW - -See the -[Building programs that use GLFW](http://www.glfw.org/docs/latest/build.html) -guide in the GLFW documentation. - - -## Reporting bugs - -Bugs are reported to our [issue tracker](https://github.com/glfw/glfw/issues). -Please always include the name and version of the OS where the bug occurs and -the version of GLFW used. If you have cloned it, include the commit ID used. - -If it's a build issue, please also include the build log and the name and -version of your development environment. - -If it's a context creation issue, please also include the make and model of your -graphics card and the version of your driver. - -This will help both us and other people experiencing the same bug. - - -## Dependencies - -GLFW bundles a number of dependencies in the `deps/` directory. - - - [Khronos extension headers](https://www.opengl.org/registry/) for API - extension symbols used by GLFW - - [getopt\_port](https://github.com/kimgr/getopt_port/) for examples - with command-line options - - [TinyCThread](https://github.com/tinycthread/tinycthread) for threaded - examples - - An OpenGL 3.2 core loader generated by - [glad](https://github.com/Dav1dde/glad) for examples using modern OpenGL - - -## Changelog - - - Added `GLFWcursor` custom system cursor handle - - Added `glfwCreateCursor`, `glfwCreateStandardCursor`, `glfwDestroyCursor` and - `glfwSetCursor` for managing system cursor images - - Added `GLFWimage` struct for passing 32-bit RGBA images - - Added monitor and adapter identifier access to native API - - Added `glfwSetDropCallback` and `GLFWdropfun` for receiving dropped files - - Added `glfwPostEmptyEvent` for allowing secondary threads to cause - `glfwWaitEvents` to return - - Added `empty` test program for verifying posting of empty events - - Added `glfwSetCharModsCallback` for receiving character events with modifiers - - Added `glfwGetWindowFrameSize` for retrieving the size of the frame around - the client area of a window - - Added `GLFW_AUTO_ICONIFY` for controlling whether full screen windows - automatically iconify (and restore the previous video mode) on focus loss - - Added `GLFW_DONT_CARE` for indicating that any value is acceptable - - Added `GLFW_DOUBLEBUFFER` for controlling whether to use double buffering - - Added `GLFW_CONTEXT_RELEASE_BEHAVIOR` and values - `GLFW_ANY_RELEASE_BEHAVIOR`, `GLFW_RELEASE_BEHAVIOR_FLUSH` and - `GLFW_RELEASE_BEHAVIOR_NONE` for `GL_KHR_context_flush_control` support - - Added `GLFW_INCLUDE_ES31` for including the OpenGL ES 3.1 header - - Added `GLFW_FLOATING` for creating always-on-top windowed mode windows - - Added `GLFW_FOCUSED` window hint for controlling initial input focus - - Added *partial and experimental* support for Wayland - - Added *partial and experimental* support for Mir - - Changed the window state attributes (focused, iconified and visible) to query - the system directly - - Changed the default of `GLFW_REFRESH_RATE` to `GLFW_DONT_CARE` to maintain - the default behavior - - Changed static library to build as position independent code for easier use - from the Rust language - - Changed `glfwGetCursorPos` to query the system directly for all cursor modes - except captured mode - - Bugfix: The debug context attribute was set from `GL_ARB_debug_output` even - when a debug context had not been requested - - Bugfix: The particles example was not linked against the threading library - - Bugfix: The cursor was not positioned over newly created full screen windows - - Bugfix: The queried cursor position was not always up-to-date - - Bugfix: `glfwExtensionSupported` always failed for OpenGL ES 3.0 and later if - the library was compiled for OpenGL ES - - [Cocoa] Added `_GLFW_USE_RETINA` to control whether windows will use the full - resolution on Retina displays - - [Cocoa] Made content view subclass of `NSOpenGLView` - - [Cocoa] Bugfix: Using a 1x1 cursor for hidden mode caused some screen - recorders to fail - - [Cocoa] Bugfix: Some Core Foundation objects were leaked during joystick - enumeration and termination - - [Cocoa] Bugfix: One copy of each display name string was leaked - - [Cocoa] Bugfix: Monitor enumeration caused a segfault if no `NSScreen` was - found for a given `CGDisplay` - - [Cocoa] Bugfix: Modifier key events were lost if the corresponding modifier - bit field was unchanged - - [Cocoa] Bugfix: Joystick enumeration took hundreds of ms on some systems - - [Cocoa] Bugfix: The cursor was hidden when the user resized a GLFW window - - [Cocoa] Bugfix: The 10.10 Yosemite OpenGL 4.1 profile token was not used - - [Cocoa] Bugfix: The generic software OpenGL renderer could be selected under - certain conditions - - [Cocoa] Bugfix: The virtual cursor jumped unpredictably when entering - disabled cursor mode - - [Win32] Enabled generation of pkg-config file for MinGW - - [Win32] Removed option to require explicitly linking against `winmm.dll` - - [Win32] Bugfix: Failure to load winmm or its functions was not reported to - the error callback - - [Win32] Bugfix: Some keys were reported based on the current layout instead - of their physical location - - [Win32] Bugfix: Maximized hidden windows were restored by `glfwShowWindow` - - [Win32] Bugfix: Context re-creation was not triggered by sRGB hint - - [Win32] Bugfix: Full screen windows were incorrectly sized and placed on some - systems - - [Win32] Bugfix: Gamma ramp functions acted on entire desktop instead of the - specified monitor - - [Win32] Bugfix: The wrong incorrect physical size was returned for - non-primary monitors - - [Win32] Bugfix: X-axis scroll offsets were inverted - - [Win32] Bugfix: The Optimus HPG forcing variable was not correctly exported - - [Win32] Bugfix: The iconified window state attribute was not always updated - - [Win32] Bugfix: Previously focused windows with disabled cursor mode and that - had been iconified by Win+D were not visible when restored - - [Win32] Bugfix: The virtual cursor jumped unpredictably when entering - disabled cursor mode - - [X11] Added run-time support for systems lacking the XKB extension - - [X11] Made GLX 1.3 the minimum supported version - - [X11] Replaced `XRRGetScreenResources` with `XRRGetScreenResourcesCurrent` - for monitor property retrieval - - [X11] Bugfix: The case of finding no usable CRTCs was not detected - - [X11] Bugfix: Detection of broken Nvidia RandR gamma support did not verify - that at least one CRTC was present - - [X11] Bugfix: A stale `_NET_SUPPORTING_WM_CHECK` root window property would - cause an uncaught `BadWindow` error - - [X11] Bugfix: No check was made for the presence of GLX 1.3 when - `GLX_SGIX_fbconfig` was unavailable - - [X11] Bugfix: The message type of ICCCM protocol events was not checked - - [X11] Bugfix: `glfwDestroyWindow` did not flush the output buffer - - [X11] Bugfix: Window frame interactions were reported as focus events - - [X11] Bugfix: Workaround for legacy Compiz caused flickering during resize - - [X11] Bugfix: The name pointer of joysticks were not cleared on disconnection - - [X11] Bugfix: Video mode resolutions and monitor physical sizes were not - corrected for rotated CRTCs - - [X11] Bugfix: Unicode character input ignored dead keys - - [X11] Bugfix: X-axis scroll offsets were inverted - - [X11] Bugfix: Full screen override redirect windows were not always - positioned over the specified monitor - - [X11] Bugfix: Character input did not work for the default `"C"` locale - - [X11] Bugfix: Joysticks connected after `glfwInit` were not detected - (temporary inotify solution until proper libudev solution) - - -## Contact - -The official website for GLFW is [glfw.org](http://www.glfw.org/). There you -can find the latest version of GLFW, as well as news, documentation and other -information about the project. - -If you have questions related to the use of GLFW, we have a -[support forum](https://sourceforge.net/p/glfw/discussion/247562/), and the IRC -channel `#glfw` on [Freenode](http://freenode.net/). - -If you have a bug to report, a patch to submit or a feature you'd like to -request, please file it in the -[issue tracker](https://github.com/glfw/glfw/issues) on GitHub. - -Finally, if you're interested in helping out with the development of GLFW or -porting it to your favorite platform, we have an occasionally active -[developer's mailing list](https://lists.stacken.kth.se/mailman/listinfo/glfw-dev), -or you could join us on `#glfw`. - - -## Acknowledgements - -GLFW exists because people around the world donated their time and lent their -skills. - - - Bobyshev Alexander - - artblanc - - arturo - - Matt Arsenault - - Keith Bauer - - John Bartholomew - - Niklas Behrens - - Niklas Bergström - - Doug Binks - - blanco - - Martin Capitanio - - Lambert Clara - - Andrew Corrigan - - Noel Cower - - Jarrod Davis - - Olivier Delannoy - - Paul R. Deppe - - Michael Dickens - - Jonathan Dummer - - Ralph Eastwood - - Michael Fogleman - - Gerald Franz - - GeO4d - - Marcus Geelnard - - Eloi Marín Gratacós - - Stefan Gustavson - - Sylvain Hellegouarch - - Matthew Henry - - heromyth - - Lucas Hinderberger - - Paul Holden - - Toni Jovanoski - - Arseny Kapoulkine - - Osman Keskin - - Cameron King - - Peter Knut - - Robin Leffmann - - Glenn Lewis - - Shane Liesegang - - Дмитри Малышев - - Martins Mozeiko - - Tristam MacDonald - - Hans Mackowiak - - Kyle McDonald - - David Medlock - - Jonathan Mercier - - Marcel Metz - - Kenneth Miller - - Bruce Mitchener - - Jack Moffitt - - Jeff Molofee - - Jon Morton - - Pierre Moulon - - Julian Møller - - Kamil Nowakowski - - Ozzy - - Andri Pálsson - - Peoro - - Braden Pellett - - Arturo J. Pérez - - Cyril Pichard - - Pieroman - - Jorge Rodriguez - - Ed Ropple - - Riku Salminen - - Brandon Schaefer - - Sebastian Schuberth - - Matt Sealey - - SephiRok - - Steve Sexton - - Systemcluster - - Dmitri Shuralyov - - Daniel Skorupski - - Bradley Smith - - Julian Squires - - Johannes Stein - - Justin Stoecker - - Nathan Sweet - - TTK-Bandit - - Sergey Tikhomirov - - Samuli Tuomola - - urraka - - Jari Vetoniemi - - Ricardo Vieira - - Simon Voordouw - - Torsten Walluhn - - Patrick Walton - - Jay Weisskopf - - Frank Wille - - yuriks - - Santi Zupancic - - Jonas Ådahl - - Lasse Öörni - - All the unmentioned and anonymous contributors in the GLFW community, for bug - reports, patches, feedback, testing and encouragement - diff --git a/examples/common/glfw/cmake_uninstall.cmake.in b/examples/common/glfw/cmake_uninstall.cmake.in deleted file mode 100644 index 4ea57b1c..00000000 --- a/examples/common/glfw/cmake_uninstall.cmake.in +++ /dev/null @@ -1,29 +0,0 @@ - -if (NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") - message(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"") -endif() - -file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) -string(REGEX REPLACE "\n" ";" files "${files}") - -foreach (file ${files}) - message(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"") - if (EXISTS "$ENV{DESTDIR}${file}") - exec_program("@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" - OUTPUT_VARIABLE rm_out - RETURN_VALUE rm_retval) - if (NOT "${rm_retval}" STREQUAL 0) - MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") - endif() - elseif (IS_SYMLINK "$ENV{DESTDIR}${file}") - EXEC_PROGRAM("@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" - OUTPUT_VARIABLE rm_out - RETURN_VALUE rm_retval) - if (NOT "${rm_retval}" STREQUAL 0) - message(FATAL_ERROR "Problem when removing symlink \"$ENV{DESTDIR}${file}\"") - endif() - else() - message(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.") - endif() -endforeach() - diff --git a/examples/common/glfw/deps/EGL/eglext.h b/examples/common/glfw/deps/EGL/eglext.h deleted file mode 100644 index bd51114b..00000000 --- a/examples/common/glfw/deps/EGL/eglext.h +++ /dev/null @@ -1,565 +0,0 @@ -#ifndef __eglext_h_ -#define __eglext_h_ - -#ifdef __cplusplus -extern "C" { -#endif - -/* -** Copyright (c) 2007-2013 The Khronos Group Inc. -** -** Permission is hereby granted, free of charge, to any person obtaining a -** copy of this software and/or associated documentation files (the -** "Materials"), to deal in the Materials without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Materials, and to -** permit persons to whom the Materials are furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be included -** in all copies or substantial portions of the Materials. -** -** THE MATERIALS ARE 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 -** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. -*/ - -#include - -/*************************************************************/ - -/* Header file version number */ -/* Current version at http://www.khronos.org/registry/egl/ */ -/* $Revision: 20690 $ on $Date: 2013-02-22 17:15:05 -0800 (Fri, 22 Feb 2013) $ */ -#define EGL_EGLEXT_VERSION 15 - -#ifndef EGL_KHR_config_attribs -#define EGL_KHR_config_attribs 1 -#define EGL_CONFORMANT_KHR 0x3042 /* EGLConfig attribute */ -#define EGL_VG_COLORSPACE_LINEAR_BIT_KHR 0x0020 /* EGL_SURFACE_TYPE bitfield */ -#define EGL_VG_ALPHA_FORMAT_PRE_BIT_KHR 0x0040 /* EGL_SURFACE_TYPE bitfield */ -#endif - -#ifndef EGL_KHR_lock_surface -#define EGL_KHR_lock_surface 1 -#define EGL_READ_SURFACE_BIT_KHR 0x0001 /* EGL_LOCK_USAGE_HINT_KHR bitfield */ -#define EGL_WRITE_SURFACE_BIT_KHR 0x0002 /* EGL_LOCK_USAGE_HINT_KHR bitfield */ -#define EGL_LOCK_SURFACE_BIT_KHR 0x0080 /* EGL_SURFACE_TYPE bitfield */ -#define EGL_OPTIMAL_FORMAT_BIT_KHR 0x0100 /* EGL_SURFACE_TYPE bitfield */ -#define EGL_MATCH_FORMAT_KHR 0x3043 /* EGLConfig attribute */ -#define EGL_FORMAT_RGB_565_EXACT_KHR 0x30C0 /* EGL_MATCH_FORMAT_KHR value */ -#define EGL_FORMAT_RGB_565_KHR 0x30C1 /* EGL_MATCH_FORMAT_KHR value */ -#define EGL_FORMAT_RGBA_8888_EXACT_KHR 0x30C2 /* EGL_MATCH_FORMAT_KHR value */ -#define EGL_FORMAT_RGBA_8888_KHR 0x30C3 /* EGL_MATCH_FORMAT_KHR value */ -#define EGL_MAP_PRESERVE_PIXELS_KHR 0x30C4 /* eglLockSurfaceKHR attribute */ -#define EGL_LOCK_USAGE_HINT_KHR 0x30C5 /* eglLockSurfaceKHR attribute */ -#define EGL_BITMAP_POINTER_KHR 0x30C6 /* eglQuerySurface attribute */ -#define EGL_BITMAP_PITCH_KHR 0x30C7 /* eglQuerySurface attribute */ -#define EGL_BITMAP_ORIGIN_KHR 0x30C8 /* eglQuerySurface attribute */ -#define EGL_BITMAP_PIXEL_RED_OFFSET_KHR 0x30C9 /* eglQuerySurface attribute */ -#define EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR 0x30CA /* eglQuerySurface attribute */ -#define EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR 0x30CB /* eglQuerySurface attribute */ -#define EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR 0x30CC /* eglQuerySurface attribute */ -#define EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR 0x30CD /* eglQuerySurface attribute */ -#define EGL_LOWER_LEFT_KHR 0x30CE /* EGL_BITMAP_ORIGIN_KHR value */ -#define EGL_UPPER_LEFT_KHR 0x30CF /* EGL_BITMAP_ORIGIN_KHR value */ -#ifdef EGL_EGLEXT_PROTOTYPES -EGLAPI EGLBoolean EGLAPIENTRY eglLockSurfaceKHR (EGLDisplay display, EGLSurface surface, const EGLint *attrib_list); -EGLAPI EGLBoolean EGLAPIENTRY eglUnlockSurfaceKHR (EGLDisplay display, EGLSurface surface); -#endif /* EGL_EGLEXT_PROTOTYPES */ -typedef EGLBoolean (EGLAPIENTRYP PFNEGLLOCKSURFACEKHRPROC) (EGLDisplay display, EGLSurface surface, const EGLint *attrib_list); -typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNLOCKSURFACEKHRPROC) (EGLDisplay display, EGLSurface surface); -#endif - -#ifndef EGL_KHR_image -#define EGL_KHR_image 1 -#define EGL_NATIVE_PIXMAP_KHR 0x30B0 /* eglCreateImageKHR target */ -typedef void *EGLImageKHR; -#define EGL_NO_IMAGE_KHR ((EGLImageKHR)0) -#ifdef EGL_EGLEXT_PROTOTYPES -EGLAPI EGLImageKHR EGLAPIENTRY eglCreateImageKHR (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list); -EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImageKHR (EGLDisplay dpy, EGLImageKHR image); -#endif /* EGL_EGLEXT_PROTOTYPES */ -typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEIMAGEKHRPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list); -typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEKHRPROC) (EGLDisplay dpy, EGLImageKHR image); -#endif - -#ifndef EGL_KHR_vg_parent_image -#define EGL_KHR_vg_parent_image 1 -#define EGL_VG_PARENT_IMAGE_KHR 0x30BA /* eglCreateImageKHR target */ -#endif - -#ifndef EGL_KHR_gl_texture_2D_image -#define EGL_KHR_gl_texture_2D_image 1 -#define EGL_GL_TEXTURE_2D_KHR 0x30B1 /* eglCreateImageKHR target */ -#define EGL_GL_TEXTURE_LEVEL_KHR 0x30BC /* eglCreateImageKHR attribute */ -#endif - -#ifndef EGL_KHR_gl_texture_cubemap_image -#define EGL_KHR_gl_texture_cubemap_image 1 -#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR 0x30B3 /* eglCreateImageKHR target */ -#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR 0x30B4 /* eglCreateImageKHR target */ -#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR 0x30B5 /* eglCreateImageKHR target */ -#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR 0x30B6 /* eglCreateImageKHR target */ -#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR 0x30B7 /* eglCreateImageKHR target */ -#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR 0x30B8 /* eglCreateImageKHR target */ -#endif - -#ifndef EGL_KHR_gl_texture_3D_image -#define EGL_KHR_gl_texture_3D_image 1 -#define EGL_GL_TEXTURE_3D_KHR 0x30B2 /* eglCreateImageKHR target */ -#define EGL_GL_TEXTURE_ZOFFSET_KHR 0x30BD /* eglCreateImageKHR attribute */ -#endif - -#ifndef EGL_KHR_gl_renderbuffer_image -#define EGL_KHR_gl_renderbuffer_image 1 -#define EGL_GL_RENDERBUFFER_KHR 0x30B9 /* eglCreateImageKHR target */ -#endif - -#if KHRONOS_SUPPORT_INT64 /* EGLTimeKHR requires 64-bit uint support */ -#ifndef EGL_KHR_reusable_sync -#define EGL_KHR_reusable_sync 1 - -typedef void* EGLSyncKHR; -typedef khronos_utime_nanoseconds_t EGLTimeKHR; - -#define EGL_SYNC_STATUS_KHR 0x30F1 -#define EGL_SIGNALED_KHR 0x30F2 -#define EGL_UNSIGNALED_KHR 0x30F3 -#define EGL_TIMEOUT_EXPIRED_KHR 0x30F5 -#define EGL_CONDITION_SATISFIED_KHR 0x30F6 -#define EGL_SYNC_TYPE_KHR 0x30F7 -#define EGL_SYNC_REUSABLE_KHR 0x30FA -#define EGL_SYNC_FLUSH_COMMANDS_BIT_KHR 0x0001 /* eglClientWaitSyncKHR bitfield */ -#define EGL_FOREVER_KHR 0xFFFFFFFFFFFFFFFFull -#define EGL_NO_SYNC_KHR ((EGLSyncKHR)0) -#ifdef EGL_EGLEXT_PROTOTYPES -EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list); -EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync); -EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout); -EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode); -EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value); -#endif /* EGL_EGLEXT_PROTOTYPES */ -typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESYNCKHRPROC) (EGLDisplay dpy, EGLenum type, const EGLint *attrib_list); -typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync); -typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout); -typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode); -typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value); -#endif -#endif - -#ifndef EGL_KHR_image_base -#define EGL_KHR_image_base 1 -/* Most interfaces defined by EGL_KHR_image_pixmap above */ -#define EGL_IMAGE_PRESERVED_KHR 0x30D2 /* eglCreateImageKHR attribute */ -#endif - -#ifndef EGL_KHR_image_pixmap -#define EGL_KHR_image_pixmap 1 -/* Interfaces defined by EGL_KHR_image above */ -#endif - -#ifndef EGL_IMG_context_priority -#define EGL_IMG_context_priority 1 -#define EGL_CONTEXT_PRIORITY_LEVEL_IMG 0x3100 -#define EGL_CONTEXT_PRIORITY_HIGH_IMG 0x3101 -#define EGL_CONTEXT_PRIORITY_MEDIUM_IMG 0x3102 -#define EGL_CONTEXT_PRIORITY_LOW_IMG 0x3103 -#endif - -#ifndef EGL_KHR_lock_surface2 -#define EGL_KHR_lock_surface2 1 -#define EGL_BITMAP_PIXEL_SIZE_KHR 0x3110 -#endif - -#ifndef EGL_NV_coverage_sample -#define EGL_NV_coverage_sample 1 -#define EGL_COVERAGE_BUFFERS_NV 0x30E0 -#define EGL_COVERAGE_SAMPLES_NV 0x30E1 -#endif - -#ifndef EGL_NV_depth_nonlinear -#define EGL_NV_depth_nonlinear 1 -#define EGL_DEPTH_ENCODING_NV 0x30E2 -#define EGL_DEPTH_ENCODING_NONE_NV 0 -#define EGL_DEPTH_ENCODING_NONLINEAR_NV 0x30E3 -#endif - -#if KHRONOS_SUPPORT_INT64 /* EGLTimeNV requires 64-bit uint support */ -#ifndef EGL_NV_sync -#define EGL_NV_sync 1 -#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_NV 0x30E6 -#define EGL_SYNC_STATUS_NV 0x30E7 -#define EGL_SIGNALED_NV 0x30E8 -#define EGL_UNSIGNALED_NV 0x30E9 -#define EGL_SYNC_FLUSH_COMMANDS_BIT_NV 0x0001 -#define EGL_FOREVER_NV 0xFFFFFFFFFFFFFFFFull -#define EGL_ALREADY_SIGNALED_NV 0x30EA -#define EGL_TIMEOUT_EXPIRED_NV 0x30EB -#define EGL_CONDITION_SATISFIED_NV 0x30EC -#define EGL_SYNC_TYPE_NV 0x30ED -#define EGL_SYNC_CONDITION_NV 0x30EE -#define EGL_SYNC_FENCE_NV 0x30EF -#define EGL_NO_SYNC_NV ((EGLSyncNV)0) -typedef void* EGLSyncNV; -typedef khronos_utime_nanoseconds_t EGLTimeNV; -#ifdef EGL_EGLEXT_PROTOTYPES -EGLAPI EGLSyncNV EGLAPIENTRY eglCreateFenceSyncNV (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list); -EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncNV (EGLSyncNV sync); -EGLAPI EGLBoolean EGLAPIENTRY eglFenceNV (EGLSyncNV sync); -EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncNV (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout); -EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncNV (EGLSyncNV sync, EGLenum mode); -EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribNV (EGLSyncNV sync, EGLint attribute, EGLint *value); -#endif /* EGL_EGLEXT_PROTOTYPES */ -typedef EGLSyncNV (EGLAPIENTRYP PFNEGLCREATEFENCESYNCNVPROC) (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list); -typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCNVPROC) (EGLSyncNV sync); -typedef EGLBoolean (EGLAPIENTRYP PFNEGLFENCENVPROC) (EGLSyncNV sync); -typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCNVPROC) (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout); -typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCNVPROC) (EGLSyncNV sync, EGLenum mode); -typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBNVPROC) (EGLSyncNV sync, EGLint attribute, EGLint *value); -#endif -#endif - -#if KHRONOS_SUPPORT_INT64 /* Dependent on EGL_KHR_reusable_sync which requires 64-bit uint support */ -#ifndef EGL_KHR_fence_sync -#define EGL_KHR_fence_sync 1 -/* Reuses most tokens and entry points from EGL_KHR_reusable_sync */ -#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR 0x30F0 -#define EGL_SYNC_CONDITION_KHR 0x30F8 -#define EGL_SYNC_FENCE_KHR 0x30F9 -#endif -#endif - -#ifndef EGL_HI_clientpixmap -#define EGL_HI_clientpixmap 1 - -/* Surface Attribute */ -#define EGL_CLIENT_PIXMAP_POINTER_HI 0x8F74 -/* - * Structure representing a client pixmap - * (pixmap's data is in client-space memory). - */ -struct EGLClientPixmapHI -{ - void* pData; - EGLint iWidth; - EGLint iHeight; - EGLint iStride; -}; -#ifdef EGL_EGLEXT_PROTOTYPES -EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurfaceHI(EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI* pixmap); -#endif /* EGL_EGLEXT_PROTOTYPES */ -typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPIXMAPSURFACEHIPROC) (EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI* pixmap); -#endif /* EGL_HI_clientpixmap */ - -#ifndef EGL_HI_colorformats -#define EGL_HI_colorformats 1 -/* Config Attribute */ -#define EGL_COLOR_FORMAT_HI 0x8F70 -/* Color Formats */ -#define EGL_COLOR_RGB_HI 0x8F71 -#define EGL_COLOR_RGBA_HI 0x8F72 -#define EGL_COLOR_ARGB_HI 0x8F73 -#endif /* EGL_HI_colorformats */ - -#ifndef EGL_MESA_drm_image -#define EGL_MESA_drm_image 1 -#define EGL_DRM_BUFFER_FORMAT_MESA 0x31D0 /* CreateDRMImageMESA attribute */ -#define EGL_DRM_BUFFER_USE_MESA 0x31D1 /* CreateDRMImageMESA attribute */ -#define EGL_DRM_BUFFER_FORMAT_ARGB32_MESA 0x31D2 /* EGL_IMAGE_FORMAT_MESA attribute value */ -#define EGL_DRM_BUFFER_MESA 0x31D3 /* eglCreateImageKHR target */ -#define EGL_DRM_BUFFER_STRIDE_MESA 0x31D4 -#define EGL_DRM_BUFFER_USE_SCANOUT_MESA 0x00000001 /* EGL_DRM_BUFFER_USE_MESA bits */ -#define EGL_DRM_BUFFER_USE_SHARE_MESA 0x00000002 /* EGL_DRM_BUFFER_USE_MESA bits */ -#ifdef EGL_EGLEXT_PROTOTYPES -EGLAPI EGLImageKHR EGLAPIENTRY eglCreateDRMImageMESA (EGLDisplay dpy, const EGLint *attrib_list); -EGLAPI EGLBoolean EGLAPIENTRY eglExportDRMImageMESA (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride); -#endif /* EGL_EGLEXT_PROTOTYPES */ -typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEDRMIMAGEMESAPROC) (EGLDisplay dpy, const EGLint *attrib_list); -typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDRMIMAGEMESAPROC) (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride); -#endif - -#ifndef EGL_NV_post_sub_buffer -#define EGL_NV_post_sub_buffer 1 -#define EGL_POST_SUB_BUFFER_SUPPORTED_NV 0x30BE -#ifdef EGL_EGLEXT_PROTOTYPES -EGLAPI EGLBoolean EGLAPIENTRY eglPostSubBufferNV (EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height); -#endif /* EGL_EGLEXT_PROTOTYPES */ -typedef EGLBoolean (EGLAPIENTRYP PFNEGLPOSTSUBBUFFERNVPROC) (EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height); -#endif - -#ifndef EGL_ANGLE_query_surface_pointer -#define EGL_ANGLE_query_surface_pointer 1 -#ifdef EGL_EGLEXT_PROTOTYPES -EGLAPI EGLBoolean eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value); -#endif -typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACEPOINTERANGLEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value); -#endif - -#ifndef EGL_ANGLE_surface_d3d_texture_2d_share_handle -#define EGL_ANGLE_surface_d3d_texture_2d_share_handle 1 -#define EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE 0x3200 -#endif - -#ifndef EGL_NV_coverage_sample_resolve -#define EGL_NV_coverage_sample_resolve 1 -#define EGL_COVERAGE_SAMPLE_RESOLVE_NV 0x3131 -#define EGL_COVERAGE_SAMPLE_RESOLVE_DEFAULT_NV 0x3132 -#define EGL_COVERAGE_SAMPLE_RESOLVE_NONE_NV 0x3133 -#endif - -#if KHRONOS_SUPPORT_INT64 /* EGLuint64NV requires 64-bit uint support */ -#ifndef EGL_NV_system_time -#define EGL_NV_system_time 1 -typedef khronos_utime_nanoseconds_t EGLuint64NV; -#ifdef EGL_EGLEXT_PROTOTYPES -EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeFrequencyNV(void); -EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeNV(void); -#endif /* EGL_EGLEXT_PROTOTYPES */ -typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC) (void); -typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMENVPROC) (void); -#endif -#endif - -#if KHRONOS_SUPPORT_INT64 /* EGLuint64KHR requires 64-bit uint support */ -#ifndef EGL_KHR_stream -#define EGL_KHR_stream 1 -typedef void* EGLStreamKHR; -typedef khronos_uint64_t EGLuint64KHR; -#define EGL_NO_STREAM_KHR ((EGLStreamKHR)0) -#define EGL_CONSUMER_LATENCY_USEC_KHR 0x3210 -#define EGL_PRODUCER_FRAME_KHR 0x3212 -#define EGL_CONSUMER_FRAME_KHR 0x3213 -#define EGL_STREAM_STATE_KHR 0x3214 -#define EGL_STREAM_STATE_CREATED_KHR 0x3215 -#define EGL_STREAM_STATE_CONNECTING_KHR 0x3216 -#define EGL_STREAM_STATE_EMPTY_KHR 0x3217 -#define EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR 0x3218 -#define EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR 0x3219 -#define EGL_STREAM_STATE_DISCONNECTED_KHR 0x321A -#define EGL_BAD_STREAM_KHR 0x321B -#define EGL_BAD_STATE_KHR 0x321C -#ifdef EGL_EGLEXT_PROTOTYPES -EGLAPI EGLStreamKHR EGLAPIENTRY eglCreateStreamKHR(EGLDisplay dpy, const EGLint *attrib_list); -EGLAPI EGLBoolean EGLAPIENTRY eglDestroyStreamKHR(EGLDisplay dpy, EGLStreamKHR stream); -EGLAPI EGLBoolean EGLAPIENTRY eglStreamAttribKHR(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint value); -EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamKHR(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint *value); -EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamu64KHR(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLuint64KHR *value); -#endif /* EGL_EGLEXT_PROTOTYPES */ -typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMKHRPROC)(EGLDisplay dpy, const EGLint *attrib_list); -typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSTREAMKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream); -typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMATTRIBKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint value); -typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint *value); -typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMU64KHRPROC)(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLuint64KHR *value); -#endif -#endif - -#ifdef EGL_KHR_stream /* Requires KHR_stream extension */ -#ifndef EGL_KHR_stream_consumer_gltexture -#define EGL_KHR_stream_consumer_gltexture 1 -#define EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR 0x321E -#ifdef EGL_EGLEXT_PROTOTYPES -EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalKHR(EGLDisplay dpy, EGLStreamKHR stream); -EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerAcquireKHR(EGLDisplay dpy, EGLStreamKHR stream); -EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerReleaseKHR(EGLDisplay dpy, EGLStreamKHR stream); -#endif /* EGL_EGLEXT_PROTOTYPES */ -typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream); -typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERACQUIREKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream); -typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERRELEASEKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream); -#endif -#endif - -#ifdef EGL_KHR_stream /* Requires KHR_stream extension */ -#ifndef EGL_KHR_stream_producer_eglsurface -#define EGL_KHR_stream_producer_eglsurface 1 -#define EGL_STREAM_BIT_KHR 0x0800 -#ifdef EGL_EGLEXT_PROTOTYPES -EGLAPI EGLSurface EGLAPIENTRY eglCreateStreamProducerSurfaceKHR(EGLDisplay dpy, EGLConfig config, EGLStreamKHR stream, const EGLint *attrib_list); -#endif /* EGL_EGLEXT_PROTOTYPES */ -typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC)(EGLDisplay dpy, EGLConfig config, EGLStreamKHR stream, const EGLint *attrib_list); -#endif -#endif - -#ifdef EGL_KHR_stream /* Requires KHR_stream extension */ -#ifndef EGL_KHR_stream_producer_aldatalocator -#define EGL_KHR_stream_producer_aldatalocator 1 -#endif -#endif - -#ifdef EGL_KHR_stream /* Requires KHR_stream extension */ -#ifndef EGL_KHR_stream_fifo -#define EGL_KHR_stream_fifo 1 -/* reuse EGLTimeKHR */ -#define EGL_STREAM_FIFO_LENGTH_KHR 0x31FC -#define EGL_STREAM_TIME_NOW_KHR 0x31FD -#define EGL_STREAM_TIME_CONSUMER_KHR 0x31FE -#define EGL_STREAM_TIME_PRODUCER_KHR 0x31FF -#ifdef EGL_EGLEXT_PROTOTYPES -EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamTimeKHR(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLTimeKHR *value); -#endif /* EGL_EGLEXT_PROTOTYPES */ -typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMTIMEKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLTimeKHR *value); -#endif -#endif - -#ifndef EGL_EXT_create_context_robustness -#define EGL_EXT_create_context_robustness 1 -#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT 0x30BF -#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT 0x3138 -#define EGL_NO_RESET_NOTIFICATION_EXT 0x31BE -#define EGL_LOSE_CONTEXT_ON_RESET_EXT 0x31BF -#endif - -#ifndef EGL_ANGLE_d3d_share_handle_client_buffer -#define EGL_ANGLE_d3d_share_handle_client_buffer 1 -/* reuse EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE */ -#endif - -#ifndef EGL_KHR_create_context -#define EGL_KHR_create_context 1 -#define EGL_CONTEXT_MAJOR_VERSION_KHR EGL_CONTEXT_CLIENT_VERSION -#define EGL_CONTEXT_MINOR_VERSION_KHR 0x30FB -#define EGL_CONTEXT_FLAGS_KHR 0x30FC -#define EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR 0x30FD -#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR 0x31BD -#define EGL_NO_RESET_NOTIFICATION_KHR 0x31BE -#define EGL_LOSE_CONTEXT_ON_RESET_KHR 0x31BF -#define EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR 0x00000001 -#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002 -#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR 0x00000004 -#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001 -#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002 -#define EGL_OPENGL_ES3_BIT_KHR 0x00000040 -#endif - -#ifndef EGL_KHR_surfaceless_context -#define EGL_KHR_surfaceless_context 1 -/* No tokens/entry points, just relaxes an error condition */ -#endif - -#ifdef EGL_KHR_stream /* Requires KHR_stream extension */ -#ifndef EGL_KHR_stream_cross_process_fd -#define EGL_KHR_stream_cross_process_fd 1 -typedef int EGLNativeFileDescriptorKHR; -#define EGL_NO_FILE_DESCRIPTOR_KHR ((EGLNativeFileDescriptorKHR)(-1)) -#ifdef EGL_EGLEXT_PROTOTYPES -EGLAPI EGLNativeFileDescriptorKHR EGLAPIENTRY eglGetStreamFileDescriptorKHR(EGLDisplay dpy, EGLStreamKHR stream); -EGLAPI EGLStreamKHR EGLAPIENTRY eglCreateStreamFromFileDescriptorKHR(EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor); -#endif /* EGL_EGLEXT_PROTOTYPES */ -typedef EGLNativeFileDescriptorKHR (EGLAPIENTRYP PFNEGLGETSTREAMFILEDESCRIPTORKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream); -typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMFROMFILEDESCRIPTORKHRPROC)(EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor); -#endif -#endif - -#ifndef EGL_EXT_multiview_window -#define EGL_EXT_multiview_window 1 -#define EGL_MULTIVIEW_VIEW_COUNT_EXT 0x3134 -#endif - -#ifndef EGL_KHR_wait_sync -#define EGL_KHR_wait_sync 1 -#ifdef EGL_EGLEXT_PROTOTYPES -EGLAPI EGLint EGLAPIENTRY eglWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags); -#endif /* EGL_EGLEXT_PROTOTYPES */ -typedef EGLint (EGLAPIENTRYP PFNEGLWAITSYNCKHRPROC)(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags); -#endif - -#ifndef EGL_NV_post_convert_rounding -#define EGL_NV_post_convert_rounding 1 -/* No tokens or entry points, just relaxes behavior of SwapBuffers */ -#endif - -#ifndef EGL_NV_native_query -#define EGL_NV_native_query 1 -#ifdef EGL_EGLEXT_PROTOTYPES -EGLAPI EGLBoolean EGLAPIENTRY eglQueryNativeDisplayNV( EGLDisplay dpy, EGLNativeDisplayType* display_id); -EGLAPI EGLBoolean EGLAPIENTRY eglQueryNativeWindowNV( EGLDisplay dpy, EGLSurface surf, EGLNativeWindowType* window); -EGLAPI EGLBoolean EGLAPIENTRY eglQueryNativePixmapNV( EGLDisplay dpy, EGLSurface surf, EGLNativePixmapType* pixmap); -#endif /* EGL_EGLEXT_PROTOTYPES */ -typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEDISPLAYNVPROC)(EGLDisplay dpy, EGLNativeDisplayType *display_id); -typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEWINDOWNVPROC)(EGLDisplay dpy, EGLSurface surf, EGLNativeWindowType *window); -typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEPIXMAPNVPROC)(EGLDisplay dpy, EGLSurface surf, EGLNativePixmapType *pixmap); -#endif - -#ifndef EGL_NV_3dvision_surface -#define EGL_NV_3dvision_surface 1 -#define EGL_AUTO_STEREO_NV 0x3136 -#endif - -#ifndef EGL_ANDROID_framebuffer_target -#define EGL_ANDROID_framebuffer_target 1 -#define EGL_FRAMEBUFFER_TARGET_ANDROID 0x3147 -#endif - -#ifndef EGL_ANDROID_blob_cache -#define EGL_ANDROID_blob_cache 1 -typedef khronos_ssize_t EGLsizeiANDROID; -typedef void (*EGLSetBlobFuncANDROID) (const void *key, EGLsizeiANDROID keySize, const void *value, EGLsizeiANDROID valueSize); -typedef EGLsizeiANDROID (*EGLGetBlobFuncANDROID) (const void *key, EGLsizeiANDROID keySize, void *value, EGLsizeiANDROID valueSize); -#ifdef EGL_EGLEXT_PROTOTYPES -EGLAPI void EGLAPIENTRY eglSetBlobCacheFuncsANDROID(EGLDisplay dpy, EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get); -#endif /* EGL_EGLEXT_PROTOTYPES */ -typedef void (EGLAPIENTRYP PFNEGLSETBLOBCACHEFUNCSANDROIDPROC)(EGLDisplay dpy, EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get); -#endif - -#ifndef EGL_ANDROID_image_native_buffer -#define EGL_ANDROID_image_native_buffer 1 -#define EGL_NATIVE_BUFFER_ANDROID 0x3140 -#endif - -#ifndef EGL_ANDROID_native_fence_sync -#define EGL_ANDROID_native_fence_sync 1 -#define EGL_SYNC_NATIVE_FENCE_ANDROID 0x3144 -#define EGL_SYNC_NATIVE_FENCE_FD_ANDROID 0x3145 -#define EGL_SYNC_NATIVE_FENCE_SIGNALED_ANDROID 0x3146 -#define EGL_NO_NATIVE_FENCE_FD_ANDROID -1 -#ifdef EGL_EGLEXT_PROTOTYPES -EGLAPI EGLint EGLAPIENTRY eglDupNativeFenceFDANDROID( EGLDisplay dpy, EGLSyncKHR); -#endif /* EGL_EGLEXT_PROTOTYPES */ -typedef EGLint (EGLAPIENTRYP PFNEGLDUPNATIVEFENCEFDANDROIDPROC)(EGLDisplay dpy, EGLSyncKHR); -#endif - -#ifndef EGL_ANDROID_recordable -#define EGL_ANDROID_recordable 1 -#define EGL_RECORDABLE_ANDROID 0x3142 -#endif - -#ifndef EGL_EXT_buffer_age -#define EGL_EXT_buffer_age 1 -#define EGL_BUFFER_AGE_EXT 0x313D -#endif - -#ifndef EGL_EXT_image_dma_buf_import -#define EGL_EXT_image_dma_buf_import 1 -#define EGL_LINUX_DMA_BUF_EXT 0x3270 -#define EGL_LINUX_DRM_FOURCC_EXT 0x3271 -#define EGL_DMA_BUF_PLANE0_FD_EXT 0x3272 -#define EGL_DMA_BUF_PLANE0_OFFSET_EXT 0x3273 -#define EGL_DMA_BUF_PLANE0_PITCH_EXT 0x3274 -#define EGL_DMA_BUF_PLANE1_FD_EXT 0x3275 -#define EGL_DMA_BUF_PLANE1_OFFSET_EXT 0x3276 -#define EGL_DMA_BUF_PLANE1_PITCH_EXT 0x3277 -#define EGL_DMA_BUF_PLANE2_FD_EXT 0x3278 -#define EGL_DMA_BUF_PLANE2_OFFSET_EXT 0x3279 -#define EGL_DMA_BUF_PLANE2_PITCH_EXT 0x327A -#define EGL_YUV_COLOR_SPACE_HINT_EXT 0x327B -#define EGL_SAMPLE_RANGE_HINT_EXT 0x327C -#define EGL_YUV_CHROMA_HORIZONTAL_SITING_HINT_EXT 0x327D -#define EGL_YUV_CHROMA_VERTICAL_SITING_HINT_EXT 0x327E -#define EGL_ITU_REC601_EXT 0x327F -#define EGL_ITU_REC709_EXT 0x3280 -#define EGL_ITU_REC2020_EXT 0x3281 -#define EGL_YUV_FULL_RANGE_EXT 0x3282 -#define EGL_YUV_NARROW_RANGE_EXT 0x3283 -#define EGL_YUV_CHROMA_SITING_0_EXT 0x3284 -#define EGL_YUV_CHROMA_SITING_0_5_EXT 0x3285 -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* __eglext_h_ */ diff --git a/examples/common/glfw/deps/GL/glext.h b/examples/common/glfw/deps/GL/glext.h deleted file mode 100644 index e619fa3c..00000000 --- a/examples/common/glfw/deps/GL/glext.h +++ /dev/null @@ -1,11626 +0,0 @@ -#ifndef __glext_h_ -#define __glext_h_ 1 - -#ifdef __cplusplus -extern "C" { -#endif - -/* -** Copyright (c) 2013-2014 The Khronos Group Inc. -** -** Permission is hereby granted, free of charge, to any person obtaining a -** copy of this software and/or associated documentation files (the -** "Materials"), to deal in the Materials without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Materials, and to -** permit persons to whom the Materials are furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be included -** in all copies or substantial portions of the Materials. -** -** THE MATERIALS ARE 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 -** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. -*/ -/* -** This header is generated from the Khronos OpenGL / OpenGL ES XML -** API Registry. The current version of the Registry, generator scripts -** used to make the header, and the header can be found at -** http://www.opengl.org/registry/ -** -** Khronos $Revision: 27684 $ on $Date: 2014-08-11 01:21:35 -0700 (Mon, 11 Aug 2014) $ -*/ - -#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN 1 -#endif -#include -#endif - -#ifndef APIENTRY -#define APIENTRY -#endif -#ifndef APIENTRYP -#define APIENTRYP APIENTRY * -#endif -#ifndef GLAPI -#define GLAPI extern -#endif - -#define GL_GLEXT_VERSION 20140810 - -/* Generated C header for: - * API: gl - * Profile: compatibility - * Versions considered: .* - * Versions emitted: 1\.[2-9]|[234]\.[0-9] - * Default extensions included: gl - * Additional extensions included: _nomatch_^ - * Extensions removed: _nomatch_^ - */ - -#ifndef GL_VERSION_1_2 -#define GL_VERSION_1_2 1 -#define GL_UNSIGNED_BYTE_3_3_2 0x8032 -#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 -#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 -#define GL_UNSIGNED_INT_8_8_8_8 0x8035 -#define GL_UNSIGNED_INT_10_10_10_2 0x8036 -#define GL_TEXTURE_BINDING_3D 0x806A -#define GL_PACK_SKIP_IMAGES 0x806B -#define GL_PACK_IMAGE_HEIGHT 0x806C -#define GL_UNPACK_SKIP_IMAGES 0x806D -#define GL_UNPACK_IMAGE_HEIGHT 0x806E -#define GL_TEXTURE_3D 0x806F -#define GL_PROXY_TEXTURE_3D 0x8070 -#define GL_TEXTURE_DEPTH 0x8071 -#define GL_TEXTURE_WRAP_R 0x8072 -#define GL_MAX_3D_TEXTURE_SIZE 0x8073 -#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 -#define GL_UNSIGNED_SHORT_5_6_5 0x8363 -#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 -#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 -#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 -#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 -#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 -#define GL_BGR 0x80E0 -#define GL_BGRA 0x80E1 -#define GL_MAX_ELEMENTS_VERTICES 0x80E8 -#define GL_MAX_ELEMENTS_INDICES 0x80E9 -#define GL_CLAMP_TO_EDGE 0x812F -#define GL_TEXTURE_MIN_LOD 0x813A -#define GL_TEXTURE_MAX_LOD 0x813B -#define GL_TEXTURE_BASE_LEVEL 0x813C -#define GL_TEXTURE_MAX_LEVEL 0x813D -#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 -#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 -#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 -#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 -#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E -#define GL_RESCALE_NORMAL 0x803A -#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 -#define GL_SINGLE_COLOR 0x81F9 -#define GL_SEPARATE_SPECULAR_COLOR 0x81FA -#define GL_ALIASED_POINT_SIZE_RANGE 0x846D -typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); -typedef void (APIENTRYP PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); -typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); -typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDrawRangeElements (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); -GLAPI void APIENTRY glTexImage3D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); -GLAPI void APIENTRY glTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); -GLAPI void APIENTRY glCopyTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -#endif -#endif /* GL_VERSION_1_2 */ - -#ifndef GL_VERSION_1_3 -#define GL_VERSION_1_3 1 -#define GL_TEXTURE0 0x84C0 -#define GL_TEXTURE1 0x84C1 -#define GL_TEXTURE2 0x84C2 -#define GL_TEXTURE3 0x84C3 -#define GL_TEXTURE4 0x84C4 -#define GL_TEXTURE5 0x84C5 -#define GL_TEXTURE6 0x84C6 -#define GL_TEXTURE7 0x84C7 -#define GL_TEXTURE8 0x84C8 -#define GL_TEXTURE9 0x84C9 -#define GL_TEXTURE10 0x84CA -#define GL_TEXTURE11 0x84CB -#define GL_TEXTURE12 0x84CC -#define GL_TEXTURE13 0x84CD -#define GL_TEXTURE14 0x84CE -#define GL_TEXTURE15 0x84CF -#define GL_TEXTURE16 0x84D0 -#define GL_TEXTURE17 0x84D1 -#define GL_TEXTURE18 0x84D2 -#define GL_TEXTURE19 0x84D3 -#define GL_TEXTURE20 0x84D4 -#define GL_TEXTURE21 0x84D5 -#define GL_TEXTURE22 0x84D6 -#define GL_TEXTURE23 0x84D7 -#define GL_TEXTURE24 0x84D8 -#define GL_TEXTURE25 0x84D9 -#define GL_TEXTURE26 0x84DA -#define GL_TEXTURE27 0x84DB -#define GL_TEXTURE28 0x84DC -#define GL_TEXTURE29 0x84DD -#define GL_TEXTURE30 0x84DE -#define GL_TEXTURE31 0x84DF -#define GL_ACTIVE_TEXTURE 0x84E0 -#define GL_MULTISAMPLE 0x809D -#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E -#define GL_SAMPLE_ALPHA_TO_ONE 0x809F -#define GL_SAMPLE_COVERAGE 0x80A0 -#define GL_SAMPLE_BUFFERS 0x80A8 -#define GL_SAMPLES 0x80A9 -#define GL_SAMPLE_COVERAGE_VALUE 0x80AA -#define GL_SAMPLE_COVERAGE_INVERT 0x80AB -#define GL_TEXTURE_CUBE_MAP 0x8513 -#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A -#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B -#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C -#define GL_COMPRESSED_RGB 0x84ED -#define GL_COMPRESSED_RGBA 0x84EE -#define GL_TEXTURE_COMPRESSION_HINT 0x84EF -#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 -#define GL_TEXTURE_COMPRESSED 0x86A1 -#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 -#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 -#define GL_CLAMP_TO_BORDER 0x812D -#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 -#define GL_MAX_TEXTURE_UNITS 0x84E2 -#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 -#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 -#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 -#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 -#define GL_MULTISAMPLE_BIT 0x20000000 -#define GL_NORMAL_MAP 0x8511 -#define GL_REFLECTION_MAP 0x8512 -#define GL_COMPRESSED_ALPHA 0x84E9 -#define GL_COMPRESSED_LUMINANCE 0x84EA -#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB -#define GL_COMPRESSED_INTENSITY 0x84EC -#define GL_COMBINE 0x8570 -#define GL_COMBINE_RGB 0x8571 -#define GL_COMBINE_ALPHA 0x8572 -#define GL_SOURCE0_RGB 0x8580 -#define GL_SOURCE1_RGB 0x8581 -#define GL_SOURCE2_RGB 0x8582 -#define GL_SOURCE0_ALPHA 0x8588 -#define GL_SOURCE1_ALPHA 0x8589 -#define GL_SOURCE2_ALPHA 0x858A -#define GL_OPERAND0_RGB 0x8590 -#define GL_OPERAND1_RGB 0x8591 -#define GL_OPERAND2_RGB 0x8592 -#define GL_OPERAND0_ALPHA 0x8598 -#define GL_OPERAND1_ALPHA 0x8599 -#define GL_OPERAND2_ALPHA 0x859A -#define GL_RGB_SCALE 0x8573 -#define GL_ADD_SIGNED 0x8574 -#define GL_INTERPOLATE 0x8575 -#define GL_SUBTRACT 0x84E7 -#define GL_CONSTANT 0x8576 -#define GL_PRIMARY_COLOR 0x8577 -#define GL_PREVIOUS 0x8578 -#define GL_DOT3_RGB 0x86AE -#define GL_DOT3_RGBA 0x86AF -typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture); -typedef void (APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLfloat value, GLboolean invert); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); -typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, void *img); -typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREPROC) (GLenum texture); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1DPROC) (GLenum target, GLdouble s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1FPROC) (GLenum target, GLfloat s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1IPROC) (GLenum target, GLint s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1SPROC) (GLenum target, GLshort s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVPROC) (GLenum target, const GLshort *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2DPROC) (GLenum target, GLdouble s, GLdouble t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2FPROC) (GLenum target, GLfloat s, GLfloat t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2IPROC) (GLenum target, GLint s, GLint t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2SPROC) (GLenum target, GLshort s, GLshort t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVPROC) (GLenum target, const GLshort *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3IPROC) (GLenum target, GLint s, GLint t, GLint r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3SPROC) (GLenum target, GLshort s, GLshort t, GLshort r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVPROC) (GLenum target, const GLshort *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4IPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4SPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVPROC) (GLenum target, const GLshort *v); -typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXFPROC) (const GLfloat *m); -typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXDPROC) (const GLdouble *m); -typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXFPROC) (const GLfloat *m); -typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXDPROC) (const GLdouble *m); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glActiveTexture (GLenum texture); -GLAPI void APIENTRY glSampleCoverage (GLfloat value, GLboolean invert); -GLAPI void APIENTRY glCompressedTexImage3D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); -GLAPI void APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); -GLAPI void APIENTRY glCompressedTexImage1D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data); -GLAPI void APIENTRY glCompressedTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); -GLAPI void APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); -GLAPI void APIENTRY glCompressedTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); -GLAPI void APIENTRY glGetCompressedTexImage (GLenum target, GLint level, void *img); -GLAPI void APIENTRY glClientActiveTexture (GLenum texture); -GLAPI void APIENTRY glMultiTexCoord1d (GLenum target, GLdouble s); -GLAPI void APIENTRY glMultiTexCoord1dv (GLenum target, const GLdouble *v); -GLAPI void APIENTRY glMultiTexCoord1f (GLenum target, GLfloat s); -GLAPI void APIENTRY glMultiTexCoord1fv (GLenum target, const GLfloat *v); -GLAPI void APIENTRY glMultiTexCoord1i (GLenum target, GLint s); -GLAPI void APIENTRY glMultiTexCoord1iv (GLenum target, const GLint *v); -GLAPI void APIENTRY glMultiTexCoord1s (GLenum target, GLshort s); -GLAPI void APIENTRY glMultiTexCoord1sv (GLenum target, const GLshort *v); -GLAPI void APIENTRY glMultiTexCoord2d (GLenum target, GLdouble s, GLdouble t); -GLAPI void APIENTRY glMultiTexCoord2dv (GLenum target, const GLdouble *v); -GLAPI void APIENTRY glMultiTexCoord2f (GLenum target, GLfloat s, GLfloat t); -GLAPI void APIENTRY glMultiTexCoord2fv (GLenum target, const GLfloat *v); -GLAPI void APIENTRY glMultiTexCoord2i (GLenum target, GLint s, GLint t); -GLAPI void APIENTRY glMultiTexCoord2iv (GLenum target, const GLint *v); -GLAPI void APIENTRY glMultiTexCoord2s (GLenum target, GLshort s, GLshort t); -GLAPI void APIENTRY glMultiTexCoord2sv (GLenum target, const GLshort *v); -GLAPI void APIENTRY glMultiTexCoord3d (GLenum target, GLdouble s, GLdouble t, GLdouble r); -GLAPI void APIENTRY glMultiTexCoord3dv (GLenum target, const GLdouble *v); -GLAPI void APIENTRY glMultiTexCoord3f (GLenum target, GLfloat s, GLfloat t, GLfloat r); -GLAPI void APIENTRY glMultiTexCoord3fv (GLenum target, const GLfloat *v); -GLAPI void APIENTRY glMultiTexCoord3i (GLenum target, GLint s, GLint t, GLint r); -GLAPI void APIENTRY glMultiTexCoord3iv (GLenum target, const GLint *v); -GLAPI void APIENTRY glMultiTexCoord3s (GLenum target, GLshort s, GLshort t, GLshort r); -GLAPI void APIENTRY glMultiTexCoord3sv (GLenum target, const GLshort *v); -GLAPI void APIENTRY glMultiTexCoord4d (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); -GLAPI void APIENTRY glMultiTexCoord4dv (GLenum target, const GLdouble *v); -GLAPI void APIENTRY glMultiTexCoord4f (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); -GLAPI void APIENTRY glMultiTexCoord4fv (GLenum target, const GLfloat *v); -GLAPI void APIENTRY glMultiTexCoord4i (GLenum target, GLint s, GLint t, GLint r, GLint q); -GLAPI void APIENTRY glMultiTexCoord4iv (GLenum target, const GLint *v); -GLAPI void APIENTRY glMultiTexCoord4s (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); -GLAPI void APIENTRY glMultiTexCoord4sv (GLenum target, const GLshort *v); -GLAPI void APIENTRY glLoadTransposeMatrixf (const GLfloat *m); -GLAPI void APIENTRY glLoadTransposeMatrixd (const GLdouble *m); -GLAPI void APIENTRY glMultTransposeMatrixf (const GLfloat *m); -GLAPI void APIENTRY glMultTransposeMatrixd (const GLdouble *m); -#endif -#endif /* GL_VERSION_1_3 */ - -#ifndef GL_VERSION_1_4 -#define GL_VERSION_1_4 1 -#define GL_BLEND_DST_RGB 0x80C8 -#define GL_BLEND_SRC_RGB 0x80C9 -#define GL_BLEND_DST_ALPHA 0x80CA -#define GL_BLEND_SRC_ALPHA 0x80CB -#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 -#define GL_DEPTH_COMPONENT16 0x81A5 -#define GL_DEPTH_COMPONENT24 0x81A6 -#define GL_DEPTH_COMPONENT32 0x81A7 -#define GL_MIRRORED_REPEAT 0x8370 -#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD -#define GL_TEXTURE_LOD_BIAS 0x8501 -#define GL_INCR_WRAP 0x8507 -#define GL_DECR_WRAP 0x8508 -#define GL_TEXTURE_DEPTH_SIZE 0x884A -#define GL_TEXTURE_COMPARE_MODE 0x884C -#define GL_TEXTURE_COMPARE_FUNC 0x884D -#define GL_POINT_SIZE_MIN 0x8126 -#define GL_POINT_SIZE_MAX 0x8127 -#define GL_POINT_DISTANCE_ATTENUATION 0x8129 -#define GL_GENERATE_MIPMAP 0x8191 -#define GL_GENERATE_MIPMAP_HINT 0x8192 -#define GL_FOG_COORDINATE_SOURCE 0x8450 -#define GL_FOG_COORDINATE 0x8451 -#define GL_FRAGMENT_DEPTH 0x8452 -#define GL_CURRENT_FOG_COORDINATE 0x8453 -#define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454 -#define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455 -#define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456 -#define GL_FOG_COORDINATE_ARRAY 0x8457 -#define GL_COLOR_SUM 0x8458 -#define GL_CURRENT_SECONDARY_COLOR 0x8459 -#define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A -#define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B -#define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C -#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D -#define GL_SECONDARY_COLOR_ARRAY 0x845E -#define GL_TEXTURE_FILTER_CONTROL 0x8500 -#define GL_DEPTH_TEXTURE_MODE 0x884B -#define GL_COMPARE_R_TO_TEXTURE 0x884E -#define GL_FUNC_ADD 0x8006 -#define GL_FUNC_SUBTRACT 0x800A -#define GL_FUNC_REVERSE_SUBTRACT 0x800B -#define GL_MIN 0x8007 -#define GL_MAX 0x8008 -#define GL_CONSTANT_COLOR 0x8001 -#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 -#define GL_CONSTANT_ALPHA 0x8003 -#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 -typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); -typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount); -typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount); -typedef void (APIENTRYP PFNGLPOINTPARAMETERFPROC) (GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLPOINTPARAMETERFVPROC) (GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLPOINTPARAMETERIPROC) (GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLPOINTPARAMETERIVPROC) (GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLFOGCOORDFPROC) (GLfloat coord); -typedef void (APIENTRYP PFNGLFOGCOORDFVPROC) (const GLfloat *coord); -typedef void (APIENTRYP PFNGLFOGCOORDDPROC) (GLdouble coord); -typedef void (APIENTRYP PFNGLFOGCOORDDVPROC) (const GLdouble *coord); -typedef void (APIENTRYP PFNGLFOGCOORDPOINTERPROC) (GLenum type, GLsizei stride, const void *pointer); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BPROC) (GLbyte red, GLbyte green, GLbyte blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BVPROC) (const GLbyte *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DPROC) (GLdouble red, GLdouble green, GLdouble blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DVPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FPROC) (GLfloat red, GLfloat green, GLfloat blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FVPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IPROC) (GLint red, GLint green, GLint blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IVPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SPROC) (GLshort red, GLshort green, GLshort blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SVPROC) (const GLshort *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBPROC) (GLubyte red, GLubyte green, GLubyte blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBVPROC) (const GLubyte *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIPROC) (GLuint red, GLuint green, GLuint blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIVPROC) (const GLuint *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USPROC) (GLushort red, GLushort green, GLushort blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USVPROC) (const GLushort *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTERPROC) (GLint size, GLenum type, GLsizei stride, const void *pointer); -typedef void (APIENTRYP PFNGLWINDOWPOS2DPROC) (GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLWINDOWPOS2DVPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLWINDOWPOS2FPROC) (GLfloat x, GLfloat y); -typedef void (APIENTRYP PFNGLWINDOWPOS2FVPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLWINDOWPOS2IPROC) (GLint x, GLint y); -typedef void (APIENTRYP PFNGLWINDOWPOS2IVPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLWINDOWPOS2SPROC) (GLshort x, GLshort y); -typedef void (APIENTRYP PFNGLWINDOWPOS2SVPROC) (const GLshort *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3DPROC) (GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLWINDOWPOS3DVPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3FPROC) (GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLWINDOWPOS3FVPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3IPROC) (GLint x, GLint y, GLint z); -typedef void (APIENTRYP PFNGLWINDOWPOS3IVPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3SPROC) (GLshort x, GLshort y, GLshort z); -typedef void (APIENTRYP PFNGLWINDOWPOS3SVPROC) (const GLshort *v); -typedef void (APIENTRYP PFNGLBLENDCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); -typedef void (APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendFuncSeparate (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); -GLAPI void APIENTRY glMultiDrawArrays (GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount); -GLAPI void APIENTRY glMultiDrawElements (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount); -GLAPI void APIENTRY glPointParameterf (GLenum pname, GLfloat param); -GLAPI void APIENTRY glPointParameterfv (GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glPointParameteri (GLenum pname, GLint param); -GLAPI void APIENTRY glPointParameteriv (GLenum pname, const GLint *params); -GLAPI void APIENTRY glFogCoordf (GLfloat coord); -GLAPI void APIENTRY glFogCoordfv (const GLfloat *coord); -GLAPI void APIENTRY glFogCoordd (GLdouble coord); -GLAPI void APIENTRY glFogCoorddv (const GLdouble *coord); -GLAPI void APIENTRY glFogCoordPointer (GLenum type, GLsizei stride, const void *pointer); -GLAPI void APIENTRY glSecondaryColor3b (GLbyte red, GLbyte green, GLbyte blue); -GLAPI void APIENTRY glSecondaryColor3bv (const GLbyte *v); -GLAPI void APIENTRY glSecondaryColor3d (GLdouble red, GLdouble green, GLdouble blue); -GLAPI void APIENTRY glSecondaryColor3dv (const GLdouble *v); -GLAPI void APIENTRY glSecondaryColor3f (GLfloat red, GLfloat green, GLfloat blue); -GLAPI void APIENTRY glSecondaryColor3fv (const GLfloat *v); -GLAPI void APIENTRY glSecondaryColor3i (GLint red, GLint green, GLint blue); -GLAPI void APIENTRY glSecondaryColor3iv (const GLint *v); -GLAPI void APIENTRY glSecondaryColor3s (GLshort red, GLshort green, GLshort blue); -GLAPI void APIENTRY glSecondaryColor3sv (const GLshort *v); -GLAPI void APIENTRY glSecondaryColor3ub (GLubyte red, GLubyte green, GLubyte blue); -GLAPI void APIENTRY glSecondaryColor3ubv (const GLubyte *v); -GLAPI void APIENTRY glSecondaryColor3ui (GLuint red, GLuint green, GLuint blue); -GLAPI void APIENTRY glSecondaryColor3uiv (const GLuint *v); -GLAPI void APIENTRY glSecondaryColor3us (GLushort red, GLushort green, GLushort blue); -GLAPI void APIENTRY glSecondaryColor3usv (const GLushort *v); -GLAPI void APIENTRY glSecondaryColorPointer (GLint size, GLenum type, GLsizei stride, const void *pointer); -GLAPI void APIENTRY glWindowPos2d (GLdouble x, GLdouble y); -GLAPI void APIENTRY glWindowPos2dv (const GLdouble *v); -GLAPI void APIENTRY glWindowPos2f (GLfloat x, GLfloat y); -GLAPI void APIENTRY glWindowPos2fv (const GLfloat *v); -GLAPI void APIENTRY glWindowPos2i (GLint x, GLint y); -GLAPI void APIENTRY glWindowPos2iv (const GLint *v); -GLAPI void APIENTRY glWindowPos2s (GLshort x, GLshort y); -GLAPI void APIENTRY glWindowPos2sv (const GLshort *v); -GLAPI void APIENTRY glWindowPos3d (GLdouble x, GLdouble y, GLdouble z); -GLAPI void APIENTRY glWindowPos3dv (const GLdouble *v); -GLAPI void APIENTRY glWindowPos3f (GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glWindowPos3fv (const GLfloat *v); -GLAPI void APIENTRY glWindowPos3i (GLint x, GLint y, GLint z); -GLAPI void APIENTRY glWindowPos3iv (const GLint *v); -GLAPI void APIENTRY glWindowPos3s (GLshort x, GLshort y, GLshort z); -GLAPI void APIENTRY glWindowPos3sv (const GLshort *v); -GLAPI void APIENTRY glBlendColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); -GLAPI void APIENTRY glBlendEquation (GLenum mode); -#endif -#endif /* GL_VERSION_1_4 */ - -#ifndef GL_VERSION_1_5 -#define GL_VERSION_1_5 1 -#include -typedef ptrdiff_t GLsizeiptr; -typedef ptrdiff_t GLintptr; -#define GL_BUFFER_SIZE 0x8764 -#define GL_BUFFER_USAGE 0x8765 -#define GL_QUERY_COUNTER_BITS 0x8864 -#define GL_CURRENT_QUERY 0x8865 -#define GL_QUERY_RESULT 0x8866 -#define GL_QUERY_RESULT_AVAILABLE 0x8867 -#define GL_ARRAY_BUFFER 0x8892 -#define GL_ELEMENT_ARRAY_BUFFER 0x8893 -#define GL_ARRAY_BUFFER_BINDING 0x8894 -#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 -#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F -#define GL_READ_ONLY 0x88B8 -#define GL_WRITE_ONLY 0x88B9 -#define GL_READ_WRITE 0x88BA -#define GL_BUFFER_ACCESS 0x88BB -#define GL_BUFFER_MAPPED 0x88BC -#define GL_BUFFER_MAP_POINTER 0x88BD -#define GL_STREAM_DRAW 0x88E0 -#define GL_STREAM_READ 0x88E1 -#define GL_STREAM_COPY 0x88E2 -#define GL_STATIC_DRAW 0x88E4 -#define GL_STATIC_READ 0x88E5 -#define GL_STATIC_COPY 0x88E6 -#define GL_DYNAMIC_DRAW 0x88E8 -#define GL_DYNAMIC_READ 0x88E9 -#define GL_DYNAMIC_COPY 0x88EA -#define GL_SAMPLES_PASSED 0x8914 -#define GL_SRC1_ALPHA 0x8589 -#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 -#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897 -#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898 -#define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899 -#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A -#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B -#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C -#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D -#define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E -#define GL_FOG_COORD_SRC 0x8450 -#define GL_FOG_COORD 0x8451 -#define GL_CURRENT_FOG_COORD 0x8453 -#define GL_FOG_COORD_ARRAY_TYPE 0x8454 -#define GL_FOG_COORD_ARRAY_STRIDE 0x8455 -#define GL_FOG_COORD_ARRAY_POINTER 0x8456 -#define GL_FOG_COORD_ARRAY 0x8457 -#define GL_FOG_COORD_ARRAY_BUFFER_BINDING 0x889D -#define GL_SRC0_RGB 0x8580 -#define GL_SRC1_RGB 0x8581 -#define GL_SRC2_RGB 0x8582 -#define GL_SRC0_ALPHA 0x8588 -#define GL_SRC2_ALPHA 0x858A -typedef void (APIENTRYP PFNGLGENQUERIESPROC) (GLsizei n, GLuint *ids); -typedef void (APIENTRYP PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint *ids); -typedef GLboolean (APIENTRYP PFNGLISQUERYPROC) (GLuint id); -typedef void (APIENTRYP PFNGLBEGINQUERYPROC) (GLenum target, GLuint id); -typedef void (APIENTRYP PFNGLENDQUERYPROC) (GLenum target); -typedef void (APIENTRYP PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVPROC) (GLuint id, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint *params); -typedef void (APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer); -typedef void (APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers); -typedef void (APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers); -typedef GLboolean (APIENTRYP PFNGLISBUFFERPROC) (GLuint buffer); -typedef void (APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const void *data, GLenum usage); -typedef void (APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const void *data); -typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, void *data); -typedef void *(APIENTRYP PFNGLMAPBUFFERPROC) (GLenum target, GLenum access); -typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERPROC) (GLenum target); -typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, void **params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGenQueries (GLsizei n, GLuint *ids); -GLAPI void APIENTRY glDeleteQueries (GLsizei n, const GLuint *ids); -GLAPI GLboolean APIENTRY glIsQuery (GLuint id); -GLAPI void APIENTRY glBeginQuery (GLenum target, GLuint id); -GLAPI void APIENTRY glEndQuery (GLenum target); -GLAPI void APIENTRY glGetQueryiv (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetQueryObjectiv (GLuint id, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetQueryObjectuiv (GLuint id, GLenum pname, GLuint *params); -GLAPI void APIENTRY glBindBuffer (GLenum target, GLuint buffer); -GLAPI void APIENTRY glDeleteBuffers (GLsizei n, const GLuint *buffers); -GLAPI void APIENTRY glGenBuffers (GLsizei n, GLuint *buffers); -GLAPI GLboolean APIENTRY glIsBuffer (GLuint buffer); -GLAPI void APIENTRY glBufferData (GLenum target, GLsizeiptr size, const void *data, GLenum usage); -GLAPI void APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const void *data); -GLAPI void APIENTRY glGetBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, void *data); -GLAPI void *APIENTRY glMapBuffer (GLenum target, GLenum access); -GLAPI GLboolean APIENTRY glUnmapBuffer (GLenum target); -GLAPI void APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetBufferPointerv (GLenum target, GLenum pname, void **params); -#endif -#endif /* GL_VERSION_1_5 */ - -#ifndef GL_VERSION_2_0 -#define GL_VERSION_2_0 1 -typedef char GLchar; -#define GL_BLEND_EQUATION_RGB 0x8009 -#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 -#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 -#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 -#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 -#define GL_CURRENT_VERTEX_ATTRIB 0x8626 -#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 -#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 -#define GL_STENCIL_BACK_FUNC 0x8800 -#define GL_STENCIL_BACK_FAIL 0x8801 -#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 -#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 -#define GL_MAX_DRAW_BUFFERS 0x8824 -#define GL_DRAW_BUFFER0 0x8825 -#define GL_DRAW_BUFFER1 0x8826 -#define GL_DRAW_BUFFER2 0x8827 -#define GL_DRAW_BUFFER3 0x8828 -#define GL_DRAW_BUFFER4 0x8829 -#define GL_DRAW_BUFFER5 0x882A -#define GL_DRAW_BUFFER6 0x882B -#define GL_DRAW_BUFFER7 0x882C -#define GL_DRAW_BUFFER8 0x882D -#define GL_DRAW_BUFFER9 0x882E -#define GL_DRAW_BUFFER10 0x882F -#define GL_DRAW_BUFFER11 0x8830 -#define GL_DRAW_BUFFER12 0x8831 -#define GL_DRAW_BUFFER13 0x8832 -#define GL_DRAW_BUFFER14 0x8833 -#define GL_DRAW_BUFFER15 0x8834 -#define GL_BLEND_EQUATION_ALPHA 0x883D -#define GL_MAX_VERTEX_ATTRIBS 0x8869 -#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A -#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 -#define GL_FRAGMENT_SHADER 0x8B30 -#define GL_VERTEX_SHADER 0x8B31 -#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 -#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A -#define GL_MAX_VARYING_FLOATS 0x8B4B -#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C -#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D -#define GL_SHADER_TYPE 0x8B4F -#define GL_FLOAT_VEC2 0x8B50 -#define GL_FLOAT_VEC3 0x8B51 -#define GL_FLOAT_VEC4 0x8B52 -#define GL_INT_VEC2 0x8B53 -#define GL_INT_VEC3 0x8B54 -#define GL_INT_VEC4 0x8B55 -#define GL_BOOL 0x8B56 -#define GL_BOOL_VEC2 0x8B57 -#define GL_BOOL_VEC3 0x8B58 -#define GL_BOOL_VEC4 0x8B59 -#define GL_FLOAT_MAT2 0x8B5A -#define GL_FLOAT_MAT3 0x8B5B -#define GL_FLOAT_MAT4 0x8B5C -#define GL_SAMPLER_1D 0x8B5D -#define GL_SAMPLER_2D 0x8B5E -#define GL_SAMPLER_3D 0x8B5F -#define GL_SAMPLER_CUBE 0x8B60 -#define GL_SAMPLER_1D_SHADOW 0x8B61 -#define GL_SAMPLER_2D_SHADOW 0x8B62 -#define GL_DELETE_STATUS 0x8B80 -#define GL_COMPILE_STATUS 0x8B81 -#define GL_LINK_STATUS 0x8B82 -#define GL_VALIDATE_STATUS 0x8B83 -#define GL_INFO_LOG_LENGTH 0x8B84 -#define GL_ATTACHED_SHADERS 0x8B85 -#define GL_ACTIVE_UNIFORMS 0x8B86 -#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 -#define GL_SHADER_SOURCE_LENGTH 0x8B88 -#define GL_ACTIVE_ATTRIBUTES 0x8B89 -#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A -#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B -#define GL_SHADING_LANGUAGE_VERSION 0x8B8C -#define GL_CURRENT_PROGRAM 0x8B8D -#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 -#define GL_LOWER_LEFT 0x8CA1 -#define GL_UPPER_LEFT 0x8CA2 -#define GL_STENCIL_BACK_REF 0x8CA3 -#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 -#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 -#define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643 -#define GL_POINT_SPRITE 0x8861 -#define GL_COORD_REPLACE 0x8862 -#define GL_MAX_TEXTURE_COORDS 0x8871 -typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha); -typedef void (APIENTRYP PFNGLDRAWBUFFERSPROC) (GLsizei n, const GLenum *bufs); -typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); -typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC) (GLenum face, GLenum func, GLint ref, GLuint mask); -typedef void (APIENTRYP PFNGLSTENCILMASKSEPARATEPROC) (GLenum face, GLuint mask); -typedef void (APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader); -typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar *name); -typedef void (APIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader); -typedef GLuint (APIENTRYP PFNGLCREATEPROGRAMPROC) (void); -typedef GLuint (APIENTRYP PFNGLCREATESHADERPROC) (GLenum type); -typedef void (APIENTRYP PFNGLDELETEPROGRAMPROC) (GLuint program); -typedef void (APIENTRYP PFNGLDELETESHADERPROC) (GLuint shader); -typedef void (APIENTRYP PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader); -typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index); -typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index); -typedef void (APIENTRYP PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); -typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); -typedef void (APIENTRYP PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders); -typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name); -typedef void (APIENTRYP PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); -typedef void (APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); -typedef void (APIENTRYP PFNGLGETSHADERSOURCEPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); -typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name); -typedef void (APIENTRYP PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat *params); -typedef void (APIENTRYP PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVPROC) (GLuint index, GLenum pname, GLdouble *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVPROC) (GLuint index, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, void **pointer); -typedef GLboolean (APIENTRYP PFNGLISPROGRAMPROC) (GLuint program); -typedef GLboolean (APIENTRYP PFNGLISSHADERPROC) (GLuint shader); -typedef void (APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program); -typedef void (APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length); -typedef void (APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program); -typedef void (APIENTRYP PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0); -typedef void (APIENTRYP PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1); -typedef void (APIENTRYP PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); -typedef void (APIENTRYP PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); -typedef void (APIENTRYP PFNGLUNIFORM1IPROC) (GLint location, GLint v0); -typedef void (APIENTRYP PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1); -typedef void (APIENTRYP PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2); -typedef void (APIENTRYP PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); -typedef void (APIENTRYP PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1DPROC) (GLuint index, GLdouble x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1SPROC) (GLuint index, GLshort x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2DPROC) (GLuint index, GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2SPROC) (GLuint index, GLshort x, GLshort y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3SPROC) (GLuint index, GLshort x, GLshort y, GLshort z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVPROC) (GLuint index, const GLbyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVPROC) (GLuint index, const GLubyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVPROC) (GLuint index, const GLushort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVPROC) (GLuint index, const GLbyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4SPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVPROC) (GLuint index, const GLubyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVPROC) (GLuint index, const GLushort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha); -GLAPI void APIENTRY glDrawBuffers (GLsizei n, const GLenum *bufs); -GLAPI void APIENTRY glStencilOpSeparate (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); -GLAPI void APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask); -GLAPI void APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask); -GLAPI void APIENTRY glAttachShader (GLuint program, GLuint shader); -GLAPI void APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar *name); -GLAPI void APIENTRY glCompileShader (GLuint shader); -GLAPI GLuint APIENTRY glCreateProgram (void); -GLAPI GLuint APIENTRY glCreateShader (GLenum type); -GLAPI void APIENTRY glDeleteProgram (GLuint program); -GLAPI void APIENTRY glDeleteShader (GLuint shader); -GLAPI void APIENTRY glDetachShader (GLuint program, GLuint shader); -GLAPI void APIENTRY glDisableVertexAttribArray (GLuint index); -GLAPI void APIENTRY glEnableVertexAttribArray (GLuint index); -GLAPI void APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); -GLAPI void APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); -GLAPI void APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders); -GLAPI GLint APIENTRY glGetAttribLocation (GLuint program, const GLchar *name); -GLAPI void APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); -GLAPI void APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); -GLAPI void APIENTRY glGetShaderSource (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); -GLAPI GLint APIENTRY glGetUniformLocation (GLuint program, const GLchar *name); -GLAPI void APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat *params); -GLAPI void APIENTRY glGetUniformiv (GLuint program, GLint location, GLint *params); -GLAPI void APIENTRY glGetVertexAttribdv (GLuint index, GLenum pname, GLdouble *params); -GLAPI void APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, void **pointer); -GLAPI GLboolean APIENTRY glIsProgram (GLuint program); -GLAPI GLboolean APIENTRY glIsShader (GLuint shader); -GLAPI void APIENTRY glLinkProgram (GLuint program); -GLAPI void APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length); -GLAPI void APIENTRY glUseProgram (GLuint program); -GLAPI void APIENTRY glUniform1f (GLint location, GLfloat v0); -GLAPI void APIENTRY glUniform2f (GLint location, GLfloat v0, GLfloat v1); -GLAPI void APIENTRY glUniform3f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); -GLAPI void APIENTRY glUniform4f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); -GLAPI void APIENTRY glUniform1i (GLint location, GLint v0); -GLAPI void APIENTRY glUniform2i (GLint location, GLint v0, GLint v1); -GLAPI void APIENTRY glUniform3i (GLint location, GLint v0, GLint v1, GLint v2); -GLAPI void APIENTRY glUniform4i (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); -GLAPI void APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glValidateProgram (GLuint program); -GLAPI void APIENTRY glVertexAttrib1d (GLuint index, GLdouble x); -GLAPI void APIENTRY glVertexAttrib1dv (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttrib1f (GLuint index, GLfloat x); -GLAPI void APIENTRY glVertexAttrib1fv (GLuint index, const GLfloat *v); -GLAPI void APIENTRY glVertexAttrib1s (GLuint index, GLshort x); -GLAPI void APIENTRY glVertexAttrib1sv (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttrib2d (GLuint index, GLdouble x, GLdouble y); -GLAPI void APIENTRY glVertexAttrib2dv (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttrib2f (GLuint index, GLfloat x, GLfloat y); -GLAPI void APIENTRY glVertexAttrib2fv (GLuint index, const GLfloat *v); -GLAPI void APIENTRY glVertexAttrib2s (GLuint index, GLshort x, GLshort y); -GLAPI void APIENTRY glVertexAttrib2sv (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttrib3d (GLuint index, GLdouble x, GLdouble y, GLdouble z); -GLAPI void APIENTRY glVertexAttrib3dv (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttrib3f (GLuint index, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glVertexAttrib3fv (GLuint index, const GLfloat *v); -GLAPI void APIENTRY glVertexAttrib3s (GLuint index, GLshort x, GLshort y, GLshort z); -GLAPI void APIENTRY glVertexAttrib3sv (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttrib4Nbv (GLuint index, const GLbyte *v); -GLAPI void APIENTRY glVertexAttrib4Niv (GLuint index, const GLint *v); -GLAPI void APIENTRY glVertexAttrib4Nsv (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttrib4Nub (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); -GLAPI void APIENTRY glVertexAttrib4Nubv (GLuint index, const GLubyte *v); -GLAPI void APIENTRY glVertexAttrib4Nuiv (GLuint index, const GLuint *v); -GLAPI void APIENTRY glVertexAttrib4Nusv (GLuint index, const GLushort *v); -GLAPI void APIENTRY glVertexAttrib4bv (GLuint index, const GLbyte *v); -GLAPI void APIENTRY glVertexAttrib4d (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void APIENTRY glVertexAttrib4dv (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttrib4f (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI void APIENTRY glVertexAttrib4fv (GLuint index, const GLfloat *v); -GLAPI void APIENTRY glVertexAttrib4iv (GLuint index, const GLint *v); -GLAPI void APIENTRY glVertexAttrib4s (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); -GLAPI void APIENTRY glVertexAttrib4sv (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttrib4ubv (GLuint index, const GLubyte *v); -GLAPI void APIENTRY glVertexAttrib4uiv (GLuint index, const GLuint *v); -GLAPI void APIENTRY glVertexAttrib4usv (GLuint index, const GLushort *v); -GLAPI void APIENTRY glVertexAttribPointer (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); -#endif -#endif /* GL_VERSION_2_0 */ - -#ifndef GL_VERSION_2_1 -#define GL_VERSION_2_1 1 -#define GL_PIXEL_PACK_BUFFER 0x88EB -#define GL_PIXEL_UNPACK_BUFFER 0x88EC -#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED -#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF -#define GL_FLOAT_MAT2x3 0x8B65 -#define GL_FLOAT_MAT2x4 0x8B66 -#define GL_FLOAT_MAT3x2 0x8B67 -#define GL_FLOAT_MAT3x4 0x8B68 -#define GL_FLOAT_MAT4x2 0x8B69 -#define GL_FLOAT_MAT4x3 0x8B6A -#define GL_SRGB 0x8C40 -#define GL_SRGB8 0x8C41 -#define GL_SRGB_ALPHA 0x8C42 -#define GL_SRGB8_ALPHA8 0x8C43 -#define GL_COMPRESSED_SRGB 0x8C48 -#define GL_COMPRESSED_SRGB_ALPHA 0x8C49 -#define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F -#define GL_SLUMINANCE_ALPHA 0x8C44 -#define GL_SLUMINANCE8_ALPHA8 0x8C45 -#define GL_SLUMINANCE 0x8C46 -#define GL_SLUMINANCE8 0x8C47 -#define GL_COMPRESSED_SLUMINANCE 0x8C4A -#define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B -typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glUniformMatrix2x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glUniformMatrix3x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glUniformMatrix2x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glUniformMatrix4x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glUniformMatrix3x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glUniformMatrix4x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -#endif -#endif /* GL_VERSION_2_1 */ - -#ifndef GL_VERSION_3_0 -#define GL_VERSION_3_0 1 -typedef unsigned short GLhalf; -#define GL_COMPARE_REF_TO_TEXTURE 0x884E -#define GL_CLIP_DISTANCE0 0x3000 -#define GL_CLIP_DISTANCE1 0x3001 -#define GL_CLIP_DISTANCE2 0x3002 -#define GL_CLIP_DISTANCE3 0x3003 -#define GL_CLIP_DISTANCE4 0x3004 -#define GL_CLIP_DISTANCE5 0x3005 -#define GL_CLIP_DISTANCE6 0x3006 -#define GL_CLIP_DISTANCE7 0x3007 -#define GL_MAX_CLIP_DISTANCES 0x0D32 -#define GL_MAJOR_VERSION 0x821B -#define GL_MINOR_VERSION 0x821C -#define GL_NUM_EXTENSIONS 0x821D -#define GL_CONTEXT_FLAGS 0x821E -#define GL_COMPRESSED_RED 0x8225 -#define GL_COMPRESSED_RG 0x8226 -#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x00000001 -#define GL_RGBA32F 0x8814 -#define GL_RGB32F 0x8815 -#define GL_RGBA16F 0x881A -#define GL_RGB16F 0x881B -#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD -#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF -#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 -#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 -#define GL_CLAMP_READ_COLOR 0x891C -#define GL_FIXED_ONLY 0x891D -#define GL_MAX_VARYING_COMPONENTS 0x8B4B -#define GL_TEXTURE_1D_ARRAY 0x8C18 -#define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19 -#define GL_TEXTURE_2D_ARRAY 0x8C1A -#define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B -#define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C -#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D -#define GL_R11F_G11F_B10F 0x8C3A -#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B -#define GL_RGB9_E5 0x8C3D -#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E -#define GL_TEXTURE_SHARED_SIZE 0x8C3F -#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 -#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 -#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 -#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 -#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 -#define GL_PRIMITIVES_GENERATED 0x8C87 -#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 -#define GL_RASTERIZER_DISCARD 0x8C89 -#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B -#define GL_INTERLEAVED_ATTRIBS 0x8C8C -#define GL_SEPARATE_ATTRIBS 0x8C8D -#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E -#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F -#define GL_RGBA32UI 0x8D70 -#define GL_RGB32UI 0x8D71 -#define GL_RGBA16UI 0x8D76 -#define GL_RGB16UI 0x8D77 -#define GL_RGBA8UI 0x8D7C -#define GL_RGB8UI 0x8D7D -#define GL_RGBA32I 0x8D82 -#define GL_RGB32I 0x8D83 -#define GL_RGBA16I 0x8D88 -#define GL_RGB16I 0x8D89 -#define GL_RGBA8I 0x8D8E -#define GL_RGB8I 0x8D8F -#define GL_RED_INTEGER 0x8D94 -#define GL_GREEN_INTEGER 0x8D95 -#define GL_BLUE_INTEGER 0x8D96 -#define GL_RGB_INTEGER 0x8D98 -#define GL_RGBA_INTEGER 0x8D99 -#define GL_BGR_INTEGER 0x8D9A -#define GL_BGRA_INTEGER 0x8D9B -#define GL_SAMPLER_1D_ARRAY 0x8DC0 -#define GL_SAMPLER_2D_ARRAY 0x8DC1 -#define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3 -#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 -#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 -#define GL_UNSIGNED_INT_VEC2 0x8DC6 -#define GL_UNSIGNED_INT_VEC3 0x8DC7 -#define GL_UNSIGNED_INT_VEC4 0x8DC8 -#define GL_INT_SAMPLER_1D 0x8DC9 -#define GL_INT_SAMPLER_2D 0x8DCA -#define GL_INT_SAMPLER_3D 0x8DCB -#define GL_INT_SAMPLER_CUBE 0x8DCC -#define GL_INT_SAMPLER_1D_ARRAY 0x8DCE -#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF -#define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1 -#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 -#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 -#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 -#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6 -#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 -#define GL_QUERY_WAIT 0x8E13 -#define GL_QUERY_NO_WAIT 0x8E14 -#define GL_QUERY_BY_REGION_WAIT 0x8E15 -#define GL_QUERY_BY_REGION_NO_WAIT 0x8E16 -#define GL_BUFFER_ACCESS_FLAGS 0x911F -#define GL_BUFFER_MAP_LENGTH 0x9120 -#define GL_BUFFER_MAP_OFFSET 0x9121 -#define GL_DEPTH_COMPONENT32F 0x8CAC -#define GL_DEPTH32F_STENCIL8 0x8CAD -#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD -#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 -#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 -#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 -#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 -#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 -#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 -#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 -#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 -#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 -#define GL_FRAMEBUFFER_DEFAULT 0x8218 -#define GL_FRAMEBUFFER_UNDEFINED 0x8219 -#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A -#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 -#define GL_DEPTH_STENCIL 0x84F9 -#define GL_UNSIGNED_INT_24_8 0x84FA -#define GL_DEPTH24_STENCIL8 0x88F0 -#define GL_TEXTURE_STENCIL_SIZE 0x88F1 -#define GL_TEXTURE_RED_TYPE 0x8C10 -#define GL_TEXTURE_GREEN_TYPE 0x8C11 -#define GL_TEXTURE_BLUE_TYPE 0x8C12 -#define GL_TEXTURE_ALPHA_TYPE 0x8C13 -#define GL_TEXTURE_DEPTH_TYPE 0x8C16 -#define GL_UNSIGNED_NORMALIZED 0x8C17 -#define GL_FRAMEBUFFER_BINDING 0x8CA6 -#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6 -#define GL_RENDERBUFFER_BINDING 0x8CA7 -#define GL_READ_FRAMEBUFFER 0x8CA8 -#define GL_DRAW_FRAMEBUFFER 0x8CA9 -#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA -#define GL_RENDERBUFFER_SAMPLES 0x8CAB -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 -#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 -#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 -#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 -#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB -#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC -#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD -#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF -#define GL_COLOR_ATTACHMENT0 0x8CE0 -#define GL_COLOR_ATTACHMENT1 0x8CE1 -#define GL_COLOR_ATTACHMENT2 0x8CE2 -#define GL_COLOR_ATTACHMENT3 0x8CE3 -#define GL_COLOR_ATTACHMENT4 0x8CE4 -#define GL_COLOR_ATTACHMENT5 0x8CE5 -#define GL_COLOR_ATTACHMENT6 0x8CE6 -#define GL_COLOR_ATTACHMENT7 0x8CE7 -#define GL_COLOR_ATTACHMENT8 0x8CE8 -#define GL_COLOR_ATTACHMENT9 0x8CE9 -#define GL_COLOR_ATTACHMENT10 0x8CEA -#define GL_COLOR_ATTACHMENT11 0x8CEB -#define GL_COLOR_ATTACHMENT12 0x8CEC -#define GL_COLOR_ATTACHMENT13 0x8CED -#define GL_COLOR_ATTACHMENT14 0x8CEE -#define GL_COLOR_ATTACHMENT15 0x8CEF -#define GL_DEPTH_ATTACHMENT 0x8D00 -#define GL_STENCIL_ATTACHMENT 0x8D20 -#define GL_FRAMEBUFFER 0x8D40 -#define GL_RENDERBUFFER 0x8D41 -#define GL_RENDERBUFFER_WIDTH 0x8D42 -#define GL_RENDERBUFFER_HEIGHT 0x8D43 -#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 -#define GL_STENCIL_INDEX1 0x8D46 -#define GL_STENCIL_INDEX4 0x8D47 -#define GL_STENCIL_INDEX8 0x8D48 -#define GL_STENCIL_INDEX16 0x8D49 -#define GL_RENDERBUFFER_RED_SIZE 0x8D50 -#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 -#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 -#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 -#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 -#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 -#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 -#define GL_MAX_SAMPLES 0x8D57 -#define GL_INDEX 0x8222 -#define GL_TEXTURE_LUMINANCE_TYPE 0x8C14 -#define GL_TEXTURE_INTENSITY_TYPE 0x8C15 -#define GL_FRAMEBUFFER_SRGB 0x8DB9 -#define GL_HALF_FLOAT 0x140B -#define GL_MAP_READ_BIT 0x0001 -#define GL_MAP_WRITE_BIT 0x0002 -#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 -#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 -#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 -#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 -#define GL_COMPRESSED_RED_RGTC1 0x8DBB -#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC -#define GL_COMPRESSED_RG_RGTC2 0x8DBD -#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE -#define GL_RG 0x8227 -#define GL_RG_INTEGER 0x8228 -#define GL_R8 0x8229 -#define GL_R16 0x822A -#define GL_RG8 0x822B -#define GL_RG16 0x822C -#define GL_R16F 0x822D -#define GL_R32F 0x822E -#define GL_RG16F 0x822F -#define GL_RG32F 0x8230 -#define GL_R8I 0x8231 -#define GL_R8UI 0x8232 -#define GL_R16I 0x8233 -#define GL_R16UI 0x8234 -#define GL_R32I 0x8235 -#define GL_R32UI 0x8236 -#define GL_RG8I 0x8237 -#define GL_RG8UI 0x8238 -#define GL_RG16I 0x8239 -#define GL_RG16UI 0x823A -#define GL_RG32I 0x823B -#define GL_RG32UI 0x823C -#define GL_VERTEX_ARRAY_BINDING 0x85B5 -#define GL_CLAMP_VERTEX_COLOR 0x891A -#define GL_CLAMP_FRAGMENT_COLOR 0x891B -#define GL_ALPHA_INTEGER 0x8D97 -typedef void (APIENTRYP PFNGLCOLORMASKIPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); -typedef void (APIENTRYP PFNGLGETBOOLEANI_VPROC) (GLenum target, GLuint index, GLboolean *data); -typedef void (APIENTRYP PFNGLGETINTEGERI_VPROC) (GLenum target, GLuint index, GLint *data); -typedef void (APIENTRYP PFNGLENABLEIPROC) (GLenum target, GLuint index); -typedef void (APIENTRYP PFNGLDISABLEIPROC) (GLenum target, GLuint index); -typedef GLboolean (APIENTRYP PFNGLISENABLEDIPROC) (GLenum target, GLuint index); -typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKPROC) (GLenum primitiveMode); -typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKPROC) (void); -typedef void (APIENTRYP PFNGLBINDBUFFERRANGEPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); -typedef void (APIENTRYP PFNGLBINDBUFFERBASEPROC) (GLenum target, GLuint index, GLuint buffer); -typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode); -typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); -typedef void (APIENTRYP PFNGLCLAMPCOLORPROC) (GLenum target, GLenum clamp); -typedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERPROC) (GLuint id, GLenum mode); -typedef void (APIENTRYP PFNGLENDCONDITIONALRENDERPROC) (void); -typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVPROC) (GLuint index, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVPROC) (GLuint index, GLenum pname, GLuint *params); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IPROC) (GLuint index, GLint x); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IPROC) (GLuint index, GLint x, GLint y); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IPROC) (GLuint index, GLint x, GLint y, GLint z); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIPROC) (GLuint index, GLuint x); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIPROC) (GLuint index, GLuint x, GLuint y); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IVPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IVPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IVPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IVPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIVPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIVPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIVPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIVPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4BVPROC) (GLuint index, const GLbyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4SVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UBVPROC) (GLuint index, const GLubyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4USVPROC) (GLuint index, const GLushort *v); -typedef void (APIENTRYP PFNGLGETUNIFORMUIVPROC) (GLuint program, GLint location, GLuint *params); -typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONPROC) (GLuint program, GLuint color, const GLchar *name); -typedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONPROC) (GLuint program, const GLchar *name); -typedef void (APIENTRYP PFNGLUNIFORM1UIPROC) (GLint location, GLuint v0); -typedef void (APIENTRYP PFNGLUNIFORM2UIPROC) (GLint location, GLuint v0, GLuint v1); -typedef void (APIENTRYP PFNGLUNIFORM3UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2); -typedef void (APIENTRYP PFNGLUNIFORM4UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); -typedef void (APIENTRYP PFNGLUNIFORM1UIVPROC) (GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLUNIFORM2UIVPROC) (GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLUNIFORM3UIVPROC) (GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLUNIFORM4UIVPROC) (GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, const GLuint *params); -typedef void (APIENTRYP PFNGLGETTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, GLuint *params); -typedef void (APIENTRYP PFNGLCLEARBUFFERIVPROC) (GLenum buffer, GLint drawbuffer, const GLint *value); -typedef void (APIENTRYP PFNGLCLEARBUFFERUIVPROC) (GLenum buffer, GLint drawbuffer, const GLuint *value); -typedef void (APIENTRYP PFNGLCLEARBUFFERFVPROC) (GLenum buffer, GLint drawbuffer, const GLfloat *value); -typedef void (APIENTRYP PFNGLCLEARBUFFERFIPROC) (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); -typedef const GLubyte *(APIENTRYP PFNGLGETSTRINGIPROC) (GLenum name, GLuint index); -typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFERPROC) (GLuint renderbuffer); -typedef void (APIENTRYP PFNGLBINDRENDERBUFFERPROC) (GLenum target, GLuint renderbuffer); -typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSPROC) (GLsizei n, const GLuint *renderbuffers); -typedef void (APIENTRYP PFNGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint *renderbuffers); -typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFERPROC) (GLuint framebuffer); -typedef void (APIENTRYP PFNGLBINDFRAMEBUFFERPROC) (GLenum target, GLuint framebuffer); -typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSPROC) (GLsizei n, const GLuint *framebuffers); -typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint *framebuffers); -typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSPROC) (GLenum target); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); -typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGENERATEMIPMAPPROC) (GLenum target); -typedef void (APIENTRYP PFNGLBLITFRAMEBUFFERPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); -typedef void *(APIENTRYP PFNGLMAPBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); -typedef void (APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length); -typedef void (APIENTRYP PFNGLBINDVERTEXARRAYPROC) (GLuint array); -typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint *arrays); -typedef void (APIENTRYP PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays); -typedef GLboolean (APIENTRYP PFNGLISVERTEXARRAYPROC) (GLuint array); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glColorMaski (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); -GLAPI void APIENTRY glGetBooleani_v (GLenum target, GLuint index, GLboolean *data); -GLAPI void APIENTRY glGetIntegeri_v (GLenum target, GLuint index, GLint *data); -GLAPI void APIENTRY glEnablei (GLenum target, GLuint index); -GLAPI void APIENTRY glDisablei (GLenum target, GLuint index); -GLAPI GLboolean APIENTRY glIsEnabledi (GLenum target, GLuint index); -GLAPI void APIENTRY glBeginTransformFeedback (GLenum primitiveMode); -GLAPI void APIENTRY glEndTransformFeedback (void); -GLAPI void APIENTRY glBindBufferRange (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); -GLAPI void APIENTRY glBindBufferBase (GLenum target, GLuint index, GLuint buffer); -GLAPI void APIENTRY glTransformFeedbackVaryings (GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode); -GLAPI void APIENTRY glGetTransformFeedbackVarying (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); -GLAPI void APIENTRY glClampColor (GLenum target, GLenum clamp); -GLAPI void APIENTRY glBeginConditionalRender (GLuint id, GLenum mode); -GLAPI void APIENTRY glEndConditionalRender (void); -GLAPI void APIENTRY glVertexAttribIPointer (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); -GLAPI void APIENTRY glGetVertexAttribIiv (GLuint index, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetVertexAttribIuiv (GLuint index, GLenum pname, GLuint *params); -GLAPI void APIENTRY glVertexAttribI1i (GLuint index, GLint x); -GLAPI void APIENTRY glVertexAttribI2i (GLuint index, GLint x, GLint y); -GLAPI void APIENTRY glVertexAttribI3i (GLuint index, GLint x, GLint y, GLint z); -GLAPI void APIENTRY glVertexAttribI4i (GLuint index, GLint x, GLint y, GLint z, GLint w); -GLAPI void APIENTRY glVertexAttribI1ui (GLuint index, GLuint x); -GLAPI void APIENTRY glVertexAttribI2ui (GLuint index, GLuint x, GLuint y); -GLAPI void APIENTRY glVertexAttribI3ui (GLuint index, GLuint x, GLuint y, GLuint z); -GLAPI void APIENTRY glVertexAttribI4ui (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -GLAPI void APIENTRY glVertexAttribI1iv (GLuint index, const GLint *v); -GLAPI void APIENTRY glVertexAttribI2iv (GLuint index, const GLint *v); -GLAPI void APIENTRY glVertexAttribI3iv (GLuint index, const GLint *v); -GLAPI void APIENTRY glVertexAttribI4iv (GLuint index, const GLint *v); -GLAPI void APIENTRY glVertexAttribI1uiv (GLuint index, const GLuint *v); -GLAPI void APIENTRY glVertexAttribI2uiv (GLuint index, const GLuint *v); -GLAPI void APIENTRY glVertexAttribI3uiv (GLuint index, const GLuint *v); -GLAPI void APIENTRY glVertexAttribI4uiv (GLuint index, const GLuint *v); -GLAPI void APIENTRY glVertexAttribI4bv (GLuint index, const GLbyte *v); -GLAPI void APIENTRY glVertexAttribI4sv (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttribI4ubv (GLuint index, const GLubyte *v); -GLAPI void APIENTRY glVertexAttribI4usv (GLuint index, const GLushort *v); -GLAPI void APIENTRY glGetUniformuiv (GLuint program, GLint location, GLuint *params); -GLAPI void APIENTRY glBindFragDataLocation (GLuint program, GLuint color, const GLchar *name); -GLAPI GLint APIENTRY glGetFragDataLocation (GLuint program, const GLchar *name); -GLAPI void APIENTRY glUniform1ui (GLint location, GLuint v0); -GLAPI void APIENTRY glUniform2ui (GLint location, GLuint v0, GLuint v1); -GLAPI void APIENTRY glUniform3ui (GLint location, GLuint v0, GLuint v1, GLuint v2); -GLAPI void APIENTRY glUniform4ui (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); -GLAPI void APIENTRY glUniform1uiv (GLint location, GLsizei count, const GLuint *value); -GLAPI void APIENTRY glUniform2uiv (GLint location, GLsizei count, const GLuint *value); -GLAPI void APIENTRY glUniform3uiv (GLint location, GLsizei count, const GLuint *value); -GLAPI void APIENTRY glUniform4uiv (GLint location, GLsizei count, const GLuint *value); -GLAPI void APIENTRY glTexParameterIiv (GLenum target, GLenum pname, const GLint *params); -GLAPI void APIENTRY glTexParameterIuiv (GLenum target, GLenum pname, const GLuint *params); -GLAPI void APIENTRY glGetTexParameterIiv (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetTexParameterIuiv (GLenum target, GLenum pname, GLuint *params); -GLAPI void APIENTRY glClearBufferiv (GLenum buffer, GLint drawbuffer, const GLint *value); -GLAPI void APIENTRY glClearBufferuiv (GLenum buffer, GLint drawbuffer, const GLuint *value); -GLAPI void APIENTRY glClearBufferfv (GLenum buffer, GLint drawbuffer, const GLfloat *value); -GLAPI void APIENTRY glClearBufferfi (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); -GLAPI const GLubyte *APIENTRY glGetStringi (GLenum name, GLuint index); -GLAPI GLboolean APIENTRY glIsRenderbuffer (GLuint renderbuffer); -GLAPI void APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer); -GLAPI void APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint *renderbuffers); -GLAPI void APIENTRY glGenRenderbuffers (GLsizei n, GLuint *renderbuffers); -GLAPI void APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); -GLAPI void APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint *params); -GLAPI GLboolean APIENTRY glIsFramebuffer (GLuint framebuffer); -GLAPI void APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer); -GLAPI void APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint *framebuffers); -GLAPI void APIENTRY glGenFramebuffers (GLsizei n, GLuint *framebuffers); -GLAPI GLenum APIENTRY glCheckFramebufferStatus (GLenum target); -GLAPI void APIENTRY glFramebufferTexture1D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -GLAPI void APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -GLAPI void APIENTRY glFramebufferTexture3D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); -GLAPI void APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -GLAPI void APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint *params); -GLAPI void APIENTRY glGenerateMipmap (GLenum target); -GLAPI void APIENTRY glBlitFramebuffer (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -GLAPI void APIENTRY glRenderbufferStorageMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -GLAPI void APIENTRY glFramebufferTextureLayer (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); -GLAPI void *APIENTRY glMapBufferRange (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); -GLAPI void APIENTRY glFlushMappedBufferRange (GLenum target, GLintptr offset, GLsizeiptr length); -GLAPI void APIENTRY glBindVertexArray (GLuint array); -GLAPI void APIENTRY glDeleteVertexArrays (GLsizei n, const GLuint *arrays); -GLAPI void APIENTRY glGenVertexArrays (GLsizei n, GLuint *arrays); -GLAPI GLboolean APIENTRY glIsVertexArray (GLuint array); -#endif -#endif /* GL_VERSION_3_0 */ - -#ifndef GL_VERSION_3_1 -#define GL_VERSION_3_1 1 -#define GL_SAMPLER_2D_RECT 0x8B63 -#define GL_SAMPLER_2D_RECT_SHADOW 0x8B64 -#define GL_SAMPLER_BUFFER 0x8DC2 -#define GL_INT_SAMPLER_2D_RECT 0x8DCD -#define GL_INT_SAMPLER_BUFFER 0x8DD0 -#define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5 -#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8 -#define GL_TEXTURE_BUFFER 0x8C2A -#define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B -#define GL_TEXTURE_BINDING_BUFFER 0x8C2C -#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D -#define GL_TEXTURE_RECTANGLE 0x84F5 -#define GL_TEXTURE_BINDING_RECTANGLE 0x84F6 -#define GL_PROXY_TEXTURE_RECTANGLE 0x84F7 -#define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8 -#define GL_R8_SNORM 0x8F94 -#define GL_RG8_SNORM 0x8F95 -#define GL_RGB8_SNORM 0x8F96 -#define GL_RGBA8_SNORM 0x8F97 -#define GL_R16_SNORM 0x8F98 -#define GL_RG16_SNORM 0x8F99 -#define GL_RGB16_SNORM 0x8F9A -#define GL_RGBA16_SNORM 0x8F9B -#define GL_SIGNED_NORMALIZED 0x8F9C -#define GL_PRIMITIVE_RESTART 0x8F9D -#define GL_PRIMITIVE_RESTART_INDEX 0x8F9E -#define GL_COPY_READ_BUFFER 0x8F36 -#define GL_COPY_WRITE_BUFFER 0x8F37 -#define GL_UNIFORM_BUFFER 0x8A11 -#define GL_UNIFORM_BUFFER_BINDING 0x8A28 -#define GL_UNIFORM_BUFFER_START 0x8A29 -#define GL_UNIFORM_BUFFER_SIZE 0x8A2A -#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B -#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C -#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D -#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E -#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F -#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 -#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 -#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32 -#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 -#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34 -#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35 -#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 -#define GL_UNIFORM_TYPE 0x8A37 -#define GL_UNIFORM_SIZE 0x8A38 -#define GL_UNIFORM_NAME_LENGTH 0x8A39 -#define GL_UNIFORM_BLOCK_INDEX 0x8A3A -#define GL_UNIFORM_OFFSET 0x8A3B -#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C -#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D -#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E -#define GL_UNIFORM_BLOCK_BINDING 0x8A3F -#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 -#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41 -#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 -#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43 -#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 -#define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45 -#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 -#define GL_INVALID_INDEX 0xFFFFFFFFu -typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instancecount); -typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount); -typedef void (APIENTRYP PFNGLTEXBUFFERPROC) (GLenum target, GLenum internalformat, GLuint buffer); -typedef void (APIENTRYP PFNGLPRIMITIVERESTARTINDEXPROC) (GLuint index); -typedef void (APIENTRYP PFNGLCOPYBUFFERSUBDATAPROC) (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); -typedef void (APIENTRYP PFNGLGETUNIFORMINDICESPROC) (GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices); -typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMSIVPROC) (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMNAMEPROC) (GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformName); -typedef GLuint (APIENTRYP PFNGLGETUNIFORMBLOCKINDEXPROC) (GLuint program, const GLchar *uniformBlockName); -typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKIVPROC) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName); -typedef void (APIENTRYP PFNGLUNIFORMBLOCKBINDINGPROC) (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDrawArraysInstanced (GLenum mode, GLint first, GLsizei count, GLsizei instancecount); -GLAPI void APIENTRY glDrawElementsInstanced (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount); -GLAPI void APIENTRY glTexBuffer (GLenum target, GLenum internalformat, GLuint buffer); -GLAPI void APIENTRY glPrimitiveRestartIndex (GLuint index); -GLAPI void APIENTRY glCopyBufferSubData (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); -GLAPI void APIENTRY glGetUniformIndices (GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices); -GLAPI void APIENTRY glGetActiveUniformsiv (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetActiveUniformName (GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformName); -GLAPI GLuint APIENTRY glGetUniformBlockIndex (GLuint program, const GLchar *uniformBlockName); -GLAPI void APIENTRY glGetActiveUniformBlockiv (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetActiveUniformBlockName (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName); -GLAPI void APIENTRY glUniformBlockBinding (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); -#endif -#endif /* GL_VERSION_3_1 */ - -#ifndef GL_VERSION_3_2 -#define GL_VERSION_3_2 1 -typedef struct __GLsync *GLsync; -#ifndef GLEXT_64_TYPES_DEFINED -/* This code block is duplicated in glxext.h, so must be protected */ -#define GLEXT_64_TYPES_DEFINED -/* Define int32_t, int64_t, and uint64_t types for UST/MSC */ -/* (as used in the GL_EXT_timer_query extension). */ -#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L -#include -#elif defined(__sun__) || defined(__digital__) -#include -#if defined(__STDC__) -#if defined(__arch64__) || defined(_LP64) -typedef long int int64_t; -typedef unsigned long int uint64_t; -#else -typedef long long int int64_t; -typedef unsigned long long int uint64_t; -#endif /* __arch64__ */ -#endif /* __STDC__ */ -#elif defined( __VMS ) || defined(__sgi) -#include -#elif defined(__SCO__) || defined(__USLC__) -#include -#elif defined(__UNIXOS2__) || defined(__SOL64__) -typedef long int int32_t; -typedef long long int int64_t; -typedef unsigned long long int uint64_t; -#elif defined(_WIN32) && defined(__GNUC__) -#include -#elif defined(_WIN32) -typedef __int32 int32_t; -typedef __int64 int64_t; -typedef unsigned __int64 uint64_t; -#else -/* Fallback if nothing above works */ -#include -#endif -#endif -typedef uint64_t GLuint64; -typedef int64_t GLint64; -#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001 -#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002 -#define GL_LINES_ADJACENCY 0x000A -#define GL_LINE_STRIP_ADJACENCY 0x000B -#define GL_TRIANGLES_ADJACENCY 0x000C -#define GL_TRIANGLE_STRIP_ADJACENCY 0x000D -#define GL_PROGRAM_POINT_SIZE 0x8642 -#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29 -#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7 -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8 -#define GL_GEOMETRY_SHADER 0x8DD9 -#define GL_GEOMETRY_VERTICES_OUT 0x8916 -#define GL_GEOMETRY_INPUT_TYPE 0x8917 -#define GL_GEOMETRY_OUTPUT_TYPE 0x8918 -#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF -#define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0 -#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1 -#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 -#define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123 -#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124 -#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 -#define GL_CONTEXT_PROFILE_MASK 0x9126 -#define GL_DEPTH_CLAMP 0x864F -#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C -#define GL_FIRST_VERTEX_CONVENTION 0x8E4D -#define GL_LAST_VERTEX_CONVENTION 0x8E4E -#define GL_PROVOKING_VERTEX 0x8E4F -#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F -#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111 -#define GL_OBJECT_TYPE 0x9112 -#define GL_SYNC_CONDITION 0x9113 -#define GL_SYNC_STATUS 0x9114 -#define GL_SYNC_FLAGS 0x9115 -#define GL_SYNC_FENCE 0x9116 -#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 -#define GL_UNSIGNALED 0x9118 -#define GL_SIGNALED 0x9119 -#define GL_ALREADY_SIGNALED 0x911A -#define GL_TIMEOUT_EXPIRED 0x911B -#define GL_CONDITION_SATISFIED 0x911C -#define GL_WAIT_FAILED 0x911D -#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull -#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 -#define GL_SAMPLE_POSITION 0x8E50 -#define GL_SAMPLE_MASK 0x8E51 -#define GL_SAMPLE_MASK_VALUE 0x8E52 -#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59 -#define GL_TEXTURE_2D_MULTISAMPLE 0x9100 -#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101 -#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102 -#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103 -#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104 -#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105 -#define GL_TEXTURE_SAMPLES 0x9106 -#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107 -#define GL_SAMPLER_2D_MULTISAMPLE 0x9108 -#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 -#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A -#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B -#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C -#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D -#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E -#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F -#define GL_MAX_INTEGER_SAMPLES 0x9110 -typedef void (APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex); -typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex); -typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex); -typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount, const GLint *basevertex); -typedef void (APIENTRYP PFNGLPROVOKINGVERTEXPROC) (GLenum mode); -typedef GLsync (APIENTRYP PFNGLFENCESYNCPROC) (GLenum condition, GLbitfield flags); -typedef GLboolean (APIENTRYP PFNGLISSYNCPROC) (GLsync sync); -typedef void (APIENTRYP PFNGLDELETESYNCPROC) (GLsync sync); -typedef GLenum (APIENTRYP PFNGLCLIENTWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); -typedef void (APIENTRYP PFNGLWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); -typedef void (APIENTRYP PFNGLGETINTEGER64VPROC) (GLenum pname, GLint64 *data); -typedef void (APIENTRYP PFNGLGETSYNCIVPROC) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); -typedef void (APIENTRYP PFNGLGETINTEGER64I_VPROC) (GLenum target, GLuint index, GLint64 *data); -typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERI64VPROC) (GLenum target, GLenum pname, GLint64 *params); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLTEXIMAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); -typedef void (APIENTRYP PFNGLTEXIMAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); -typedef void (APIENTRYP PFNGLGETMULTISAMPLEFVPROC) (GLenum pname, GLuint index, GLfloat *val); -typedef void (APIENTRYP PFNGLSAMPLEMASKIPROC) (GLuint maskNumber, GLbitfield mask); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDrawElementsBaseVertex (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex); -GLAPI void APIENTRY glDrawRangeElementsBaseVertex (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex); -GLAPI void APIENTRY glDrawElementsInstancedBaseVertex (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex); -GLAPI void APIENTRY glMultiDrawElementsBaseVertex (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount, const GLint *basevertex); -GLAPI void APIENTRY glProvokingVertex (GLenum mode); -GLAPI GLsync APIENTRY glFenceSync (GLenum condition, GLbitfield flags); -GLAPI GLboolean APIENTRY glIsSync (GLsync sync); -GLAPI void APIENTRY glDeleteSync (GLsync sync); -GLAPI GLenum APIENTRY glClientWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout); -GLAPI void APIENTRY glWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout); -GLAPI void APIENTRY glGetInteger64v (GLenum pname, GLint64 *data); -GLAPI void APIENTRY glGetSynciv (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); -GLAPI void APIENTRY glGetInteger64i_v (GLenum target, GLuint index, GLint64 *data); -GLAPI void APIENTRY glGetBufferParameteri64v (GLenum target, GLenum pname, GLint64 *params); -GLAPI void APIENTRY glFramebufferTexture (GLenum target, GLenum attachment, GLuint texture, GLint level); -GLAPI void APIENTRY glTexImage2DMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); -GLAPI void APIENTRY glTexImage3DMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); -GLAPI void APIENTRY glGetMultisamplefv (GLenum pname, GLuint index, GLfloat *val); -GLAPI void APIENTRY glSampleMaski (GLuint maskNumber, GLbitfield mask); -#endif -#endif /* GL_VERSION_3_2 */ - -#ifndef GL_VERSION_3_3 -#define GL_VERSION_3_3 1 -#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE -#define GL_SRC1_COLOR 0x88F9 -#define GL_ONE_MINUS_SRC1_COLOR 0x88FA -#define GL_ONE_MINUS_SRC1_ALPHA 0x88FB -#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS 0x88FC -#define GL_ANY_SAMPLES_PASSED 0x8C2F -#define GL_SAMPLER_BINDING 0x8919 -#define GL_RGB10_A2UI 0x906F -#define GL_TEXTURE_SWIZZLE_R 0x8E42 -#define GL_TEXTURE_SWIZZLE_G 0x8E43 -#define GL_TEXTURE_SWIZZLE_B 0x8E44 -#define GL_TEXTURE_SWIZZLE_A 0x8E45 -#define GL_TEXTURE_SWIZZLE_RGBA 0x8E46 -#define GL_TIME_ELAPSED 0x88BF -#define GL_TIMESTAMP 0x8E28 -#define GL_INT_2_10_10_10_REV 0x8D9F -typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONINDEXEDPROC) (GLuint program, GLuint colorNumber, GLuint index, const GLchar *name); -typedef GLint (APIENTRYP PFNGLGETFRAGDATAINDEXPROC) (GLuint program, const GLchar *name); -typedef void (APIENTRYP PFNGLGENSAMPLERSPROC) (GLsizei count, GLuint *samplers); -typedef void (APIENTRYP PFNGLDELETESAMPLERSPROC) (GLsizei count, const GLuint *samplers); -typedef GLboolean (APIENTRYP PFNGLISSAMPLERPROC) (GLuint sampler); -typedef void (APIENTRYP PFNGLBINDSAMPLERPROC) (GLuint unit, GLuint sampler); -typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIPROC) (GLuint sampler, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, const GLint *param); -typedef void (APIENTRYP PFNGLSAMPLERPARAMETERFPROC) (GLuint sampler, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, const GLfloat *param); -typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, const GLint *param); -typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, const GLuint *param); -typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, GLuint *params); -typedef void (APIENTRYP PFNGLQUERYCOUNTERPROC) (GLuint id, GLenum target); -typedef void (APIENTRYP PFNGLGETQUERYOBJECTI64VPROC) (GLuint id, GLenum pname, GLint64 *params); -typedef void (APIENTRYP PFNGLGETQUERYOBJECTUI64VPROC) (GLuint id, GLenum pname, GLuint64 *params); -typedef void (APIENTRYP PFNGLVERTEXATTRIBDIVISORPROC) (GLuint index, GLuint divisor); -typedef void (APIENTRYP PFNGLVERTEXATTRIBP1UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); -typedef void (APIENTRYP PFNGLVERTEXATTRIBP1UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); -typedef void (APIENTRYP PFNGLVERTEXATTRIBP2UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); -typedef void (APIENTRYP PFNGLVERTEXATTRIBP2UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); -typedef void (APIENTRYP PFNGLVERTEXATTRIBP3UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); -typedef void (APIENTRYP PFNGLVERTEXATTRIBP3UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); -typedef void (APIENTRYP PFNGLVERTEXATTRIBP4UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); -typedef void (APIENTRYP PFNGLVERTEXATTRIBP4UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); -typedef void (APIENTRYP PFNGLVERTEXP2UIPROC) (GLenum type, GLuint value); -typedef void (APIENTRYP PFNGLVERTEXP2UIVPROC) (GLenum type, const GLuint *value); -typedef void (APIENTRYP PFNGLVERTEXP3UIPROC) (GLenum type, GLuint value); -typedef void (APIENTRYP PFNGLVERTEXP3UIVPROC) (GLenum type, const GLuint *value); -typedef void (APIENTRYP PFNGLVERTEXP4UIPROC) (GLenum type, GLuint value); -typedef void (APIENTRYP PFNGLVERTEXP4UIVPROC) (GLenum type, const GLuint *value); -typedef void (APIENTRYP PFNGLTEXCOORDP1UIPROC) (GLenum type, GLuint coords); -typedef void (APIENTRYP PFNGLTEXCOORDP1UIVPROC) (GLenum type, const GLuint *coords); -typedef void (APIENTRYP PFNGLTEXCOORDP2UIPROC) (GLenum type, GLuint coords); -typedef void (APIENTRYP PFNGLTEXCOORDP2UIVPROC) (GLenum type, const GLuint *coords); -typedef void (APIENTRYP PFNGLTEXCOORDP3UIPROC) (GLenum type, GLuint coords); -typedef void (APIENTRYP PFNGLTEXCOORDP3UIVPROC) (GLenum type, const GLuint *coords); -typedef void (APIENTRYP PFNGLTEXCOORDP4UIPROC) (GLenum type, GLuint coords); -typedef void (APIENTRYP PFNGLTEXCOORDP4UIVPROC) (GLenum type, const GLuint *coords); -typedef void (APIENTRYP PFNGLMULTITEXCOORDP1UIPROC) (GLenum texture, GLenum type, GLuint coords); -typedef void (APIENTRYP PFNGLMULTITEXCOORDP1UIVPROC) (GLenum texture, GLenum type, const GLuint *coords); -typedef void (APIENTRYP PFNGLMULTITEXCOORDP2UIPROC) (GLenum texture, GLenum type, GLuint coords); -typedef void (APIENTRYP PFNGLMULTITEXCOORDP2UIVPROC) (GLenum texture, GLenum type, const GLuint *coords); -typedef void (APIENTRYP PFNGLMULTITEXCOORDP3UIPROC) (GLenum texture, GLenum type, GLuint coords); -typedef void (APIENTRYP PFNGLMULTITEXCOORDP3UIVPROC) (GLenum texture, GLenum type, const GLuint *coords); -typedef void (APIENTRYP PFNGLMULTITEXCOORDP4UIPROC) (GLenum texture, GLenum type, GLuint coords); -typedef void (APIENTRYP PFNGLMULTITEXCOORDP4UIVPROC) (GLenum texture, GLenum type, const GLuint *coords); -typedef void (APIENTRYP PFNGLNORMALP3UIPROC) (GLenum type, GLuint coords); -typedef void (APIENTRYP PFNGLNORMALP3UIVPROC) (GLenum type, const GLuint *coords); -typedef void (APIENTRYP PFNGLCOLORP3UIPROC) (GLenum type, GLuint color); -typedef void (APIENTRYP PFNGLCOLORP3UIVPROC) (GLenum type, const GLuint *color); -typedef void (APIENTRYP PFNGLCOLORP4UIPROC) (GLenum type, GLuint color); -typedef void (APIENTRYP PFNGLCOLORP4UIVPROC) (GLenum type, const GLuint *color); -typedef void (APIENTRYP PFNGLSECONDARYCOLORP3UIPROC) (GLenum type, GLuint color); -typedef void (APIENTRYP PFNGLSECONDARYCOLORP3UIVPROC) (GLenum type, const GLuint *color); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBindFragDataLocationIndexed (GLuint program, GLuint colorNumber, GLuint index, const GLchar *name); -GLAPI GLint APIENTRY glGetFragDataIndex (GLuint program, const GLchar *name); -GLAPI void APIENTRY glGenSamplers (GLsizei count, GLuint *samplers); -GLAPI void APIENTRY glDeleteSamplers (GLsizei count, const GLuint *samplers); -GLAPI GLboolean APIENTRY glIsSampler (GLuint sampler); -GLAPI void APIENTRY glBindSampler (GLuint unit, GLuint sampler); -GLAPI void APIENTRY glSamplerParameteri (GLuint sampler, GLenum pname, GLint param); -GLAPI void APIENTRY glSamplerParameteriv (GLuint sampler, GLenum pname, const GLint *param); -GLAPI void APIENTRY glSamplerParameterf (GLuint sampler, GLenum pname, GLfloat param); -GLAPI void APIENTRY glSamplerParameterfv (GLuint sampler, GLenum pname, const GLfloat *param); -GLAPI void APIENTRY glSamplerParameterIiv (GLuint sampler, GLenum pname, const GLint *param); -GLAPI void APIENTRY glSamplerParameterIuiv (GLuint sampler, GLenum pname, const GLuint *param); -GLAPI void APIENTRY glGetSamplerParameteriv (GLuint sampler, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetSamplerParameterIiv (GLuint sampler, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetSamplerParameterfv (GLuint sampler, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetSamplerParameterIuiv (GLuint sampler, GLenum pname, GLuint *params); -GLAPI void APIENTRY glQueryCounter (GLuint id, GLenum target); -GLAPI void APIENTRY glGetQueryObjecti64v (GLuint id, GLenum pname, GLint64 *params); -GLAPI void APIENTRY glGetQueryObjectui64v (GLuint id, GLenum pname, GLuint64 *params); -GLAPI void APIENTRY glVertexAttribDivisor (GLuint index, GLuint divisor); -GLAPI void APIENTRY glVertexAttribP1ui (GLuint index, GLenum type, GLboolean normalized, GLuint value); -GLAPI void APIENTRY glVertexAttribP1uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); -GLAPI void APIENTRY glVertexAttribP2ui (GLuint index, GLenum type, GLboolean normalized, GLuint value); -GLAPI void APIENTRY glVertexAttribP2uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); -GLAPI void APIENTRY glVertexAttribP3ui (GLuint index, GLenum type, GLboolean normalized, GLuint value); -GLAPI void APIENTRY glVertexAttribP3uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); -GLAPI void APIENTRY glVertexAttribP4ui (GLuint index, GLenum type, GLboolean normalized, GLuint value); -GLAPI void APIENTRY glVertexAttribP4uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); -GLAPI void APIENTRY glVertexP2ui (GLenum type, GLuint value); -GLAPI void APIENTRY glVertexP2uiv (GLenum type, const GLuint *value); -GLAPI void APIENTRY glVertexP3ui (GLenum type, GLuint value); -GLAPI void APIENTRY glVertexP3uiv (GLenum type, const GLuint *value); -GLAPI void APIENTRY glVertexP4ui (GLenum type, GLuint value); -GLAPI void APIENTRY glVertexP4uiv (GLenum type, const GLuint *value); -GLAPI void APIENTRY glTexCoordP1ui (GLenum type, GLuint coords); -GLAPI void APIENTRY glTexCoordP1uiv (GLenum type, const GLuint *coords); -GLAPI void APIENTRY glTexCoordP2ui (GLenum type, GLuint coords); -GLAPI void APIENTRY glTexCoordP2uiv (GLenum type, const GLuint *coords); -GLAPI void APIENTRY glTexCoordP3ui (GLenum type, GLuint coords); -GLAPI void APIENTRY glTexCoordP3uiv (GLenum type, const GLuint *coords); -GLAPI void APIENTRY glTexCoordP4ui (GLenum type, GLuint coords); -GLAPI void APIENTRY glTexCoordP4uiv (GLenum type, const GLuint *coords); -GLAPI void APIENTRY glMultiTexCoordP1ui (GLenum texture, GLenum type, GLuint coords); -GLAPI void APIENTRY glMultiTexCoordP1uiv (GLenum texture, GLenum type, const GLuint *coords); -GLAPI void APIENTRY glMultiTexCoordP2ui (GLenum texture, GLenum type, GLuint coords); -GLAPI void APIENTRY glMultiTexCoordP2uiv (GLenum texture, GLenum type, const GLuint *coords); -GLAPI void APIENTRY glMultiTexCoordP3ui (GLenum texture, GLenum type, GLuint coords); -GLAPI void APIENTRY glMultiTexCoordP3uiv (GLenum texture, GLenum type, const GLuint *coords); -GLAPI void APIENTRY glMultiTexCoordP4ui (GLenum texture, GLenum type, GLuint coords); -GLAPI void APIENTRY glMultiTexCoordP4uiv (GLenum texture, GLenum type, const GLuint *coords); -GLAPI void APIENTRY glNormalP3ui (GLenum type, GLuint coords); -GLAPI void APIENTRY glNormalP3uiv (GLenum type, const GLuint *coords); -GLAPI void APIENTRY glColorP3ui (GLenum type, GLuint color); -GLAPI void APIENTRY glColorP3uiv (GLenum type, const GLuint *color); -GLAPI void APIENTRY glColorP4ui (GLenum type, GLuint color); -GLAPI void APIENTRY glColorP4uiv (GLenum type, const GLuint *color); -GLAPI void APIENTRY glSecondaryColorP3ui (GLenum type, GLuint color); -GLAPI void APIENTRY glSecondaryColorP3uiv (GLenum type, const GLuint *color); -#endif -#endif /* GL_VERSION_3_3 */ - -#ifndef GL_VERSION_4_0 -#define GL_VERSION_4_0 1 -#define GL_SAMPLE_SHADING 0x8C36 -#define GL_MIN_SAMPLE_SHADING_VALUE 0x8C37 -#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E -#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F -#define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009 -#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A -#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY 0x900B -#define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C -#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D -#define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E -#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F -#define GL_DRAW_INDIRECT_BUFFER 0x8F3F -#define GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43 -#define GL_GEOMETRY_SHADER_INVOCATIONS 0x887F -#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS 0x8E5A -#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET 0x8E5B -#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET 0x8E5C -#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS 0x8E5D -#define GL_MAX_VERTEX_STREAMS 0x8E71 -#define GL_DOUBLE_VEC2 0x8FFC -#define GL_DOUBLE_VEC3 0x8FFD -#define GL_DOUBLE_VEC4 0x8FFE -#define GL_DOUBLE_MAT2 0x8F46 -#define GL_DOUBLE_MAT3 0x8F47 -#define GL_DOUBLE_MAT4 0x8F48 -#define GL_DOUBLE_MAT2x3 0x8F49 -#define GL_DOUBLE_MAT2x4 0x8F4A -#define GL_DOUBLE_MAT3x2 0x8F4B -#define GL_DOUBLE_MAT3x4 0x8F4C -#define GL_DOUBLE_MAT4x2 0x8F4D -#define GL_DOUBLE_MAT4x3 0x8F4E -#define GL_ACTIVE_SUBROUTINES 0x8DE5 -#define GL_ACTIVE_SUBROUTINE_UNIFORMS 0x8DE6 -#define GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS 0x8E47 -#define GL_ACTIVE_SUBROUTINE_MAX_LENGTH 0x8E48 -#define GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH 0x8E49 -#define GL_MAX_SUBROUTINES 0x8DE7 -#define GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS 0x8DE8 -#define GL_NUM_COMPATIBLE_SUBROUTINES 0x8E4A -#define GL_COMPATIBLE_SUBROUTINES 0x8E4B -#define GL_PATCHES 0x000E -#define GL_PATCH_VERTICES 0x8E72 -#define GL_PATCH_DEFAULT_INNER_LEVEL 0x8E73 -#define GL_PATCH_DEFAULT_OUTER_LEVEL 0x8E74 -#define GL_TESS_CONTROL_OUTPUT_VERTICES 0x8E75 -#define GL_TESS_GEN_MODE 0x8E76 -#define GL_TESS_GEN_SPACING 0x8E77 -#define GL_TESS_GEN_VERTEX_ORDER 0x8E78 -#define GL_TESS_GEN_POINT_MODE 0x8E79 -#define GL_ISOLINES 0x8E7A -#define GL_FRACTIONAL_ODD 0x8E7B -#define GL_FRACTIONAL_EVEN 0x8E7C -#define GL_MAX_PATCH_VERTICES 0x8E7D -#define GL_MAX_TESS_GEN_LEVEL 0x8E7E -#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E7F -#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E80 -#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS 0x8E81 -#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS 0x8E82 -#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS 0x8E83 -#define GL_MAX_TESS_PATCH_COMPONENTS 0x8E84 -#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS 0x8E85 -#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS 0x8E86 -#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS 0x8E89 -#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS 0x8E8A -#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS 0x886C -#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS 0x886D -#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E1E -#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E1F -#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER 0x84F0 -#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER 0x84F1 -#define GL_TESS_EVALUATION_SHADER 0x8E87 -#define GL_TESS_CONTROL_SHADER 0x8E88 -#define GL_TRANSFORM_FEEDBACK 0x8E22 -#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED 0x8E23 -#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE 0x8E24 -#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25 -#define GL_MAX_TRANSFORM_FEEDBACK_BUFFERS 0x8E70 -typedef void (APIENTRYP PFNGLMINSAMPLESHADINGPROC) (GLfloat value); -typedef void (APIENTRYP PFNGLBLENDEQUATIONIPROC) (GLuint buf, GLenum mode); -typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEIPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); -typedef void (APIENTRYP PFNGLBLENDFUNCIPROC) (GLuint buf, GLenum src, GLenum dst); -typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEIPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); -typedef void (APIENTRYP PFNGLDRAWARRAYSINDIRECTPROC) (GLenum mode, const void *indirect); -typedef void (APIENTRYP PFNGLDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const void *indirect); -typedef void (APIENTRYP PFNGLUNIFORM1DPROC) (GLint location, GLdouble x); -typedef void (APIENTRYP PFNGLUNIFORM2DPROC) (GLint location, GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLUNIFORM3DPROC) (GLint location, GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLUNIFORM4DPROC) (GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLUNIFORM1DVPROC) (GLint location, GLsizei count, const GLdouble *value); -typedef void (APIENTRYP PFNGLUNIFORM2DVPROC) (GLint location, GLsizei count, const GLdouble *value); -typedef void (APIENTRYP PFNGLUNIFORM3DVPROC) (GLint location, GLsizei count, const GLdouble *value); -typedef void (APIENTRYP PFNGLUNIFORM4DVPROC) (GLint location, GLsizei count, const GLdouble *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLGETUNIFORMDVPROC) (GLuint program, GLint location, GLdouble *params); -typedef GLint (APIENTRYP PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC) (GLuint program, GLenum shadertype, const GLchar *name); -typedef GLuint (APIENTRYP PFNGLGETSUBROUTINEINDEXPROC) (GLuint program, GLenum shadertype, const GLchar *name); -typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC) (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint *values); -typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); -typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINENAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); -typedef void (APIENTRYP PFNGLUNIFORMSUBROUTINESUIVPROC) (GLenum shadertype, GLsizei count, const GLuint *indices); -typedef void (APIENTRYP PFNGLGETUNIFORMSUBROUTINEUIVPROC) (GLenum shadertype, GLint location, GLuint *params); -typedef void (APIENTRYP PFNGLGETPROGRAMSTAGEIVPROC) (GLuint program, GLenum shadertype, GLenum pname, GLint *values); -typedef void (APIENTRYP PFNGLPATCHPARAMETERIPROC) (GLenum pname, GLint value); -typedef void (APIENTRYP PFNGLPATCHPARAMETERFVPROC) (GLenum pname, const GLfloat *values); -typedef void (APIENTRYP PFNGLBINDTRANSFORMFEEDBACKPROC) (GLenum target, GLuint id); -typedef void (APIENTRYP PFNGLDELETETRANSFORMFEEDBACKSPROC) (GLsizei n, const GLuint *ids); -typedef void (APIENTRYP PFNGLGENTRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint *ids); -typedef GLboolean (APIENTRYP PFNGLISTRANSFORMFEEDBACKPROC) (GLuint id); -typedef void (APIENTRYP PFNGLPAUSETRANSFORMFEEDBACKPROC) (void); -typedef void (APIENTRYP PFNGLRESUMETRANSFORMFEEDBACKPROC) (void); -typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKPROC) (GLenum mode, GLuint id); -typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC) (GLenum mode, GLuint id, GLuint stream); -typedef void (APIENTRYP PFNGLBEGINQUERYINDEXEDPROC) (GLenum target, GLuint index, GLuint id); -typedef void (APIENTRYP PFNGLENDQUERYINDEXEDPROC) (GLenum target, GLuint index); -typedef void (APIENTRYP PFNGLGETQUERYINDEXEDIVPROC) (GLenum target, GLuint index, GLenum pname, GLint *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glMinSampleShading (GLfloat value); -GLAPI void APIENTRY glBlendEquationi (GLuint buf, GLenum mode); -GLAPI void APIENTRY glBlendEquationSeparatei (GLuint buf, GLenum modeRGB, GLenum modeAlpha); -GLAPI void APIENTRY glBlendFunci (GLuint buf, GLenum src, GLenum dst); -GLAPI void APIENTRY glBlendFuncSeparatei (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); -GLAPI void APIENTRY glDrawArraysIndirect (GLenum mode, const void *indirect); -GLAPI void APIENTRY glDrawElementsIndirect (GLenum mode, GLenum type, const void *indirect); -GLAPI void APIENTRY glUniform1d (GLint location, GLdouble x); -GLAPI void APIENTRY glUniform2d (GLint location, GLdouble x, GLdouble y); -GLAPI void APIENTRY glUniform3d (GLint location, GLdouble x, GLdouble y, GLdouble z); -GLAPI void APIENTRY glUniform4d (GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void APIENTRY glUniform1dv (GLint location, GLsizei count, const GLdouble *value); -GLAPI void APIENTRY glUniform2dv (GLint location, GLsizei count, const GLdouble *value); -GLAPI void APIENTRY glUniform3dv (GLint location, GLsizei count, const GLdouble *value); -GLAPI void APIENTRY glUniform4dv (GLint location, GLsizei count, const GLdouble *value); -GLAPI void APIENTRY glUniformMatrix2dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glUniformMatrix3dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glUniformMatrix4dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glUniformMatrix2x3dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glUniformMatrix2x4dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glUniformMatrix3x2dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glUniformMatrix3x4dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glUniformMatrix4x2dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glUniformMatrix4x3dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glGetUniformdv (GLuint program, GLint location, GLdouble *params); -GLAPI GLint APIENTRY glGetSubroutineUniformLocation (GLuint program, GLenum shadertype, const GLchar *name); -GLAPI GLuint APIENTRY glGetSubroutineIndex (GLuint program, GLenum shadertype, const GLchar *name); -GLAPI void APIENTRY glGetActiveSubroutineUniformiv (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint *values); -GLAPI void APIENTRY glGetActiveSubroutineUniformName (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); -GLAPI void APIENTRY glGetActiveSubroutineName (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); -GLAPI void APIENTRY glUniformSubroutinesuiv (GLenum shadertype, GLsizei count, const GLuint *indices); -GLAPI void APIENTRY glGetUniformSubroutineuiv (GLenum shadertype, GLint location, GLuint *params); -GLAPI void APIENTRY glGetProgramStageiv (GLuint program, GLenum shadertype, GLenum pname, GLint *values); -GLAPI void APIENTRY glPatchParameteri (GLenum pname, GLint value); -GLAPI void APIENTRY glPatchParameterfv (GLenum pname, const GLfloat *values); -GLAPI void APIENTRY glBindTransformFeedback (GLenum target, GLuint id); -GLAPI void APIENTRY glDeleteTransformFeedbacks (GLsizei n, const GLuint *ids); -GLAPI void APIENTRY glGenTransformFeedbacks (GLsizei n, GLuint *ids); -GLAPI GLboolean APIENTRY glIsTransformFeedback (GLuint id); -GLAPI void APIENTRY glPauseTransformFeedback (void); -GLAPI void APIENTRY glResumeTransformFeedback (void); -GLAPI void APIENTRY glDrawTransformFeedback (GLenum mode, GLuint id); -GLAPI void APIENTRY glDrawTransformFeedbackStream (GLenum mode, GLuint id, GLuint stream); -GLAPI void APIENTRY glBeginQueryIndexed (GLenum target, GLuint index, GLuint id); -GLAPI void APIENTRY glEndQueryIndexed (GLenum target, GLuint index); -GLAPI void APIENTRY glGetQueryIndexediv (GLenum target, GLuint index, GLenum pname, GLint *params); -#endif -#endif /* GL_VERSION_4_0 */ - -#ifndef GL_VERSION_4_1 -#define GL_VERSION_4_1 1 -#define GL_FIXED 0x140C -#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A -#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B -#define GL_LOW_FLOAT 0x8DF0 -#define GL_MEDIUM_FLOAT 0x8DF1 -#define GL_HIGH_FLOAT 0x8DF2 -#define GL_LOW_INT 0x8DF3 -#define GL_MEDIUM_INT 0x8DF4 -#define GL_HIGH_INT 0x8DF5 -#define GL_SHADER_COMPILER 0x8DFA -#define GL_SHADER_BINARY_FORMATS 0x8DF8 -#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 -#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB -#define GL_MAX_VARYING_VECTORS 0x8DFC -#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD -#define GL_RGB565 0x8D62 -#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257 -#define GL_PROGRAM_BINARY_LENGTH 0x8741 -#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE -#define GL_PROGRAM_BINARY_FORMATS 0x87FF -#define GL_VERTEX_SHADER_BIT 0x00000001 -#define GL_FRAGMENT_SHADER_BIT 0x00000002 -#define GL_GEOMETRY_SHADER_BIT 0x00000004 -#define GL_TESS_CONTROL_SHADER_BIT 0x00000008 -#define GL_TESS_EVALUATION_SHADER_BIT 0x00000010 -#define GL_ALL_SHADER_BITS 0xFFFFFFFF -#define GL_PROGRAM_SEPARABLE 0x8258 -#define GL_ACTIVE_PROGRAM 0x8259 -#define GL_PROGRAM_PIPELINE_BINDING 0x825A -#define GL_MAX_VIEWPORTS 0x825B -#define GL_VIEWPORT_SUBPIXEL_BITS 0x825C -#define GL_VIEWPORT_BOUNDS_RANGE 0x825D -#define GL_LAYER_PROVOKING_VERTEX 0x825E -#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX 0x825F -#define GL_UNDEFINED_VERTEX 0x8260 -typedef void (APIENTRYP PFNGLRELEASESHADERCOMPILERPROC) (void); -typedef void (APIENTRYP PFNGLSHADERBINARYPROC) (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length); -typedef void (APIENTRYP PFNGLGETSHADERPRECISIONFORMATPROC) (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision); -typedef void (APIENTRYP PFNGLDEPTHRANGEFPROC) (GLfloat n, GLfloat f); -typedef void (APIENTRYP PFNGLCLEARDEPTHFPROC) (GLfloat d); -typedef void (APIENTRYP PFNGLGETPROGRAMBINARYPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary); -typedef void (APIENTRYP PFNGLPROGRAMBINARYPROC) (GLuint program, GLenum binaryFormat, const void *binary, GLsizei length); -typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIPROC) (GLuint program, GLenum pname, GLint value); -typedef void (APIENTRYP PFNGLUSEPROGRAMSTAGESPROC) (GLuint pipeline, GLbitfield stages, GLuint program); -typedef void (APIENTRYP PFNGLACTIVESHADERPROGRAMPROC) (GLuint pipeline, GLuint program); -typedef GLuint (APIENTRYP PFNGLCREATESHADERPROGRAMVPROC) (GLenum type, GLsizei count, const GLchar *const*strings); -typedef void (APIENTRYP PFNGLBINDPROGRAMPIPELINEPROC) (GLuint pipeline); -typedef void (APIENTRYP PFNGLDELETEPROGRAMPIPELINESPROC) (GLsizei n, const GLuint *pipelines); -typedef void (APIENTRYP PFNGLGENPROGRAMPIPELINESPROC) (GLsizei n, GLuint *pipelines); -typedef GLboolean (APIENTRYP PFNGLISPROGRAMPIPELINEPROC) (GLuint pipeline); -typedef void (APIENTRYP PFNGLGETPROGRAMPIPELINEIVPROC) (GLuint pipeline, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IPROC) (GLuint program, GLint location, GLint v0); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FPROC) (GLuint program, GLint location, GLfloat v0); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DPROC) (GLuint program, GLint location, GLdouble v0); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIPROC) (GLuint program, GLint location, GLuint v0); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IPROC) (GLuint program, GLint location, GLint v0, GLint v1); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPIPELINEPROC) (GLuint pipeline); -typedef void (APIENTRYP PFNGLGETPROGRAMPIPELINEINFOLOGPROC) (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DPROC) (GLuint index, GLdouble x); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DPROC) (GLuint index, GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBLPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLDVPROC) (GLuint index, GLenum pname, GLdouble *params); -typedef void (APIENTRYP PFNGLVIEWPORTARRAYVPROC) (GLuint first, GLsizei count, const GLfloat *v); -typedef void (APIENTRYP PFNGLVIEWPORTINDEXEDFPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); -typedef void (APIENTRYP PFNGLVIEWPORTINDEXEDFVPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLSCISSORARRAYVPROC) (GLuint first, GLsizei count, const GLint *v); -typedef void (APIENTRYP PFNGLSCISSORINDEXEDPROC) (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLSCISSORINDEXEDVPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLDEPTHRANGEARRAYVPROC) (GLuint first, GLsizei count, const GLdouble *v); -typedef void (APIENTRYP PFNGLDEPTHRANGEINDEXEDPROC) (GLuint index, GLdouble n, GLdouble f); -typedef void (APIENTRYP PFNGLGETFLOATI_VPROC) (GLenum target, GLuint index, GLfloat *data); -typedef void (APIENTRYP PFNGLGETDOUBLEI_VPROC) (GLenum target, GLuint index, GLdouble *data); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glReleaseShaderCompiler (void); -GLAPI void APIENTRY glShaderBinary (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length); -GLAPI void APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision); -GLAPI void APIENTRY glDepthRangef (GLfloat n, GLfloat f); -GLAPI void APIENTRY glClearDepthf (GLfloat d); -GLAPI void APIENTRY glGetProgramBinary (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary); -GLAPI void APIENTRY glProgramBinary (GLuint program, GLenum binaryFormat, const void *binary, GLsizei length); -GLAPI void APIENTRY glProgramParameteri (GLuint program, GLenum pname, GLint value); -GLAPI void APIENTRY glUseProgramStages (GLuint pipeline, GLbitfield stages, GLuint program); -GLAPI void APIENTRY glActiveShaderProgram (GLuint pipeline, GLuint program); -GLAPI GLuint APIENTRY glCreateShaderProgramv (GLenum type, GLsizei count, const GLchar *const*strings); -GLAPI void APIENTRY glBindProgramPipeline (GLuint pipeline); -GLAPI void APIENTRY glDeleteProgramPipelines (GLsizei n, const GLuint *pipelines); -GLAPI void APIENTRY glGenProgramPipelines (GLsizei n, GLuint *pipelines); -GLAPI GLboolean APIENTRY glIsProgramPipeline (GLuint pipeline); -GLAPI void APIENTRY glGetProgramPipelineiv (GLuint pipeline, GLenum pname, GLint *params); -GLAPI void APIENTRY glProgramUniform1i (GLuint program, GLint location, GLint v0); -GLAPI void APIENTRY glProgramUniform1iv (GLuint program, GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glProgramUniform1f (GLuint program, GLint location, GLfloat v0); -GLAPI void APIENTRY glProgramUniform1fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glProgramUniform1d (GLuint program, GLint location, GLdouble v0); -GLAPI void APIENTRY glProgramUniform1dv (GLuint program, GLint location, GLsizei count, const GLdouble *value); -GLAPI void APIENTRY glProgramUniform1ui (GLuint program, GLint location, GLuint v0); -GLAPI void APIENTRY glProgramUniform1uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); -GLAPI void APIENTRY glProgramUniform2i (GLuint program, GLint location, GLint v0, GLint v1); -GLAPI void APIENTRY glProgramUniform2iv (GLuint program, GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glProgramUniform2f (GLuint program, GLint location, GLfloat v0, GLfloat v1); -GLAPI void APIENTRY glProgramUniform2fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glProgramUniform2d (GLuint program, GLint location, GLdouble v0, GLdouble v1); -GLAPI void APIENTRY glProgramUniform2dv (GLuint program, GLint location, GLsizei count, const GLdouble *value); -GLAPI void APIENTRY glProgramUniform2ui (GLuint program, GLint location, GLuint v0, GLuint v1); -GLAPI void APIENTRY glProgramUniform2uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); -GLAPI void APIENTRY glProgramUniform3i (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); -GLAPI void APIENTRY glProgramUniform3iv (GLuint program, GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glProgramUniform3f (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); -GLAPI void APIENTRY glProgramUniform3fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glProgramUniform3d (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2); -GLAPI void APIENTRY glProgramUniform3dv (GLuint program, GLint location, GLsizei count, const GLdouble *value); -GLAPI void APIENTRY glProgramUniform3ui (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); -GLAPI void APIENTRY glProgramUniform3uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); -GLAPI void APIENTRY glProgramUniform4i (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); -GLAPI void APIENTRY glProgramUniform4iv (GLuint program, GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glProgramUniform4f (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); -GLAPI void APIENTRY glProgramUniform4fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glProgramUniform4d (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3); -GLAPI void APIENTRY glProgramUniform4dv (GLuint program, GLint location, GLsizei count, const GLdouble *value); -GLAPI void APIENTRY glProgramUniform4ui (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); -GLAPI void APIENTRY glProgramUniform4uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); -GLAPI void APIENTRY glProgramUniformMatrix2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix2dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix3dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix4dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix2x3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix3x2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix2x4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix4x2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix3x4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix4x3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix2x3dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix3x2dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix2x4dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix4x2dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix3x4dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix4x3dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glValidateProgramPipeline (GLuint pipeline); -GLAPI void APIENTRY glGetProgramPipelineInfoLog (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); -GLAPI void APIENTRY glVertexAttribL1d (GLuint index, GLdouble x); -GLAPI void APIENTRY glVertexAttribL2d (GLuint index, GLdouble x, GLdouble y); -GLAPI void APIENTRY glVertexAttribL3d (GLuint index, GLdouble x, GLdouble y, GLdouble z); -GLAPI void APIENTRY glVertexAttribL4d (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void APIENTRY glVertexAttribL1dv (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttribL2dv (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttribL3dv (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttribL4dv (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttribLPointer (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); -GLAPI void APIENTRY glGetVertexAttribLdv (GLuint index, GLenum pname, GLdouble *params); -GLAPI void APIENTRY glViewportArrayv (GLuint first, GLsizei count, const GLfloat *v); -GLAPI void APIENTRY glViewportIndexedf (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); -GLAPI void APIENTRY glViewportIndexedfv (GLuint index, const GLfloat *v); -GLAPI void APIENTRY glScissorArrayv (GLuint first, GLsizei count, const GLint *v); -GLAPI void APIENTRY glScissorIndexed (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); -GLAPI void APIENTRY glScissorIndexedv (GLuint index, const GLint *v); -GLAPI void APIENTRY glDepthRangeArrayv (GLuint first, GLsizei count, const GLdouble *v); -GLAPI void APIENTRY glDepthRangeIndexed (GLuint index, GLdouble n, GLdouble f); -GLAPI void APIENTRY glGetFloati_v (GLenum target, GLuint index, GLfloat *data); -GLAPI void APIENTRY glGetDoublei_v (GLenum target, GLuint index, GLdouble *data); -#endif -#endif /* GL_VERSION_4_1 */ - -#ifndef GL_VERSION_4_2 -#define GL_VERSION_4_2 1 -#define GL_UNPACK_COMPRESSED_BLOCK_WIDTH 0x9127 -#define GL_UNPACK_COMPRESSED_BLOCK_HEIGHT 0x9128 -#define GL_UNPACK_COMPRESSED_BLOCK_DEPTH 0x9129 -#define GL_UNPACK_COMPRESSED_BLOCK_SIZE 0x912A -#define GL_PACK_COMPRESSED_BLOCK_WIDTH 0x912B -#define GL_PACK_COMPRESSED_BLOCK_HEIGHT 0x912C -#define GL_PACK_COMPRESSED_BLOCK_DEPTH 0x912D -#define GL_PACK_COMPRESSED_BLOCK_SIZE 0x912E -#define GL_NUM_SAMPLE_COUNTS 0x9380 -#define GL_MIN_MAP_BUFFER_ALIGNMENT 0x90BC -#define GL_ATOMIC_COUNTER_BUFFER 0x92C0 -#define GL_ATOMIC_COUNTER_BUFFER_BINDING 0x92C1 -#define GL_ATOMIC_COUNTER_BUFFER_START 0x92C2 -#define GL_ATOMIC_COUNTER_BUFFER_SIZE 0x92C3 -#define GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE 0x92C4 -#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS 0x92C5 -#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES 0x92C6 -#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER 0x92C7 -#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER 0x92C8 -#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER 0x92C9 -#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER 0x92CA -#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER 0x92CB -#define GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS 0x92CC -#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS 0x92CD -#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS 0x92CE -#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS 0x92CF -#define GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS 0x92D0 -#define GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS 0x92D1 -#define GL_MAX_VERTEX_ATOMIC_COUNTERS 0x92D2 -#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS 0x92D3 -#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS 0x92D4 -#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS 0x92D5 -#define GL_MAX_FRAGMENT_ATOMIC_COUNTERS 0x92D6 -#define GL_MAX_COMBINED_ATOMIC_COUNTERS 0x92D7 -#define GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE 0x92D8 -#define GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS 0x92DC -#define GL_ACTIVE_ATOMIC_COUNTER_BUFFERS 0x92D9 -#define GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX 0x92DA -#define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB -#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001 -#define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002 -#define GL_UNIFORM_BARRIER_BIT 0x00000004 -#define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008 -#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020 -#define GL_COMMAND_BARRIER_BIT 0x00000040 -#define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080 -#define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100 -#define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200 -#define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400 -#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800 -#define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000 -#define GL_ALL_BARRIER_BITS 0xFFFFFFFF -#define GL_MAX_IMAGE_UNITS 0x8F38 -#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS 0x8F39 -#define GL_IMAGE_BINDING_NAME 0x8F3A -#define GL_IMAGE_BINDING_LEVEL 0x8F3B -#define GL_IMAGE_BINDING_LAYERED 0x8F3C -#define GL_IMAGE_BINDING_LAYER 0x8F3D -#define GL_IMAGE_BINDING_ACCESS 0x8F3E -#define GL_IMAGE_1D 0x904C -#define GL_IMAGE_2D 0x904D -#define GL_IMAGE_3D 0x904E -#define GL_IMAGE_2D_RECT 0x904F -#define GL_IMAGE_CUBE 0x9050 -#define GL_IMAGE_BUFFER 0x9051 -#define GL_IMAGE_1D_ARRAY 0x9052 -#define GL_IMAGE_2D_ARRAY 0x9053 -#define GL_IMAGE_CUBE_MAP_ARRAY 0x9054 -#define GL_IMAGE_2D_MULTISAMPLE 0x9055 -#define GL_IMAGE_2D_MULTISAMPLE_ARRAY 0x9056 -#define GL_INT_IMAGE_1D 0x9057 -#define GL_INT_IMAGE_2D 0x9058 -#define GL_INT_IMAGE_3D 0x9059 -#define GL_INT_IMAGE_2D_RECT 0x905A -#define GL_INT_IMAGE_CUBE 0x905B -#define GL_INT_IMAGE_BUFFER 0x905C -#define GL_INT_IMAGE_1D_ARRAY 0x905D -#define GL_INT_IMAGE_2D_ARRAY 0x905E -#define GL_INT_IMAGE_CUBE_MAP_ARRAY 0x905F -#define GL_INT_IMAGE_2D_MULTISAMPLE 0x9060 -#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x9061 -#define GL_UNSIGNED_INT_IMAGE_1D 0x9062 -#define GL_UNSIGNED_INT_IMAGE_2D 0x9063 -#define GL_UNSIGNED_INT_IMAGE_3D 0x9064 -#define GL_UNSIGNED_INT_IMAGE_2D_RECT 0x9065 -#define GL_UNSIGNED_INT_IMAGE_CUBE 0x9066 -#define GL_UNSIGNED_INT_IMAGE_BUFFER 0x9067 -#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY 0x9068 -#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY 0x9069 -#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY 0x906A -#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE 0x906B -#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x906C -#define GL_MAX_IMAGE_SAMPLES 0x906D -#define GL_IMAGE_BINDING_FORMAT 0x906E -#define GL_IMAGE_FORMAT_COMPATIBILITY_TYPE 0x90C7 -#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE 0x90C8 -#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS 0x90C9 -#define GL_MAX_VERTEX_IMAGE_UNIFORMS 0x90CA -#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS 0x90CB -#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS 0x90CC -#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS 0x90CD -#define GL_MAX_FRAGMENT_IMAGE_UNIFORMS 0x90CE -#define GL_MAX_COMBINED_IMAGE_UNIFORMS 0x90CF -#define GL_COMPRESSED_RGBA_BPTC_UNORM 0x8E8C -#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM 0x8E8D -#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E -#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F -#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F -typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance); -typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance); -typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance); -typedef void (APIENTRYP PFNGLGETINTERNALFORMATIVPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params); -typedef void (APIENTRYP PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC) (GLuint program, GLuint bufferIndex, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLBINDIMAGETEXTUREPROC) (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); -typedef void (APIENTRYP PFNGLMEMORYBARRIERPROC) (GLbitfield barriers); -typedef void (APIENTRYP PFNGLTEXSTORAGE1DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); -typedef void (APIENTRYP PFNGLTEXSTORAGE2DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLTEXSTORAGE3DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); -typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC) (GLenum mode, GLuint id, GLsizei instancecount); -typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC) (GLenum mode, GLuint id, GLuint stream, GLsizei instancecount); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDrawArraysInstancedBaseInstance (GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance); -GLAPI void APIENTRY glDrawElementsInstancedBaseInstance (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance); -GLAPI void APIENTRY glDrawElementsInstancedBaseVertexBaseInstance (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance); -GLAPI void APIENTRY glGetInternalformativ (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params); -GLAPI void APIENTRY glGetActiveAtomicCounterBufferiv (GLuint program, GLuint bufferIndex, GLenum pname, GLint *params); -GLAPI void APIENTRY glBindImageTexture (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); -GLAPI void APIENTRY glMemoryBarrier (GLbitfield barriers); -GLAPI void APIENTRY glTexStorage1D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); -GLAPI void APIENTRY glTexStorage2D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); -GLAPI void APIENTRY glTexStorage3D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); -GLAPI void APIENTRY glDrawTransformFeedbackInstanced (GLenum mode, GLuint id, GLsizei instancecount); -GLAPI void APIENTRY glDrawTransformFeedbackStreamInstanced (GLenum mode, GLuint id, GLuint stream, GLsizei instancecount); -#endif -#endif /* GL_VERSION_4_2 */ - -#ifndef GL_VERSION_4_3 -#define GL_VERSION_4_3 1 -typedef void (APIENTRY *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); -#define GL_NUM_SHADING_LANGUAGE_VERSIONS 0x82E9 -#define GL_VERTEX_ATTRIB_ARRAY_LONG 0x874E -#define GL_COMPRESSED_RGB8_ETC2 0x9274 -#define GL_COMPRESSED_SRGB8_ETC2 0x9275 -#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276 -#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277 -#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 -#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279 -#define GL_COMPRESSED_R11_EAC 0x9270 -#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271 -#define GL_COMPRESSED_RG11_EAC 0x9272 -#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273 -#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69 -#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A -#define GL_MAX_ELEMENT_INDEX 0x8D6B -#define GL_COMPUTE_SHADER 0x91B9 -#define GL_MAX_COMPUTE_UNIFORM_BLOCKS 0x91BB -#define GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS 0x91BC -#define GL_MAX_COMPUTE_IMAGE_UNIFORMS 0x91BD -#define GL_MAX_COMPUTE_SHARED_MEMORY_SIZE 0x8262 -#define GL_MAX_COMPUTE_UNIFORM_COMPONENTS 0x8263 -#define GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS 0x8264 -#define GL_MAX_COMPUTE_ATOMIC_COUNTERS 0x8265 -#define GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS 0x8266 -#define GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS 0x90EB -#define GL_MAX_COMPUTE_WORK_GROUP_COUNT 0x91BE -#define GL_MAX_COMPUTE_WORK_GROUP_SIZE 0x91BF -#define GL_COMPUTE_WORK_GROUP_SIZE 0x8267 -#define GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER 0x90EC -#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER 0x90ED -#define GL_DISPATCH_INDIRECT_BUFFER 0x90EE -#define GL_DISPATCH_INDIRECT_BUFFER_BINDING 0x90EF -#define GL_COMPUTE_SHADER_BIT 0x00000020 -#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242 -#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243 -#define GL_DEBUG_CALLBACK_FUNCTION 0x8244 -#define GL_DEBUG_CALLBACK_USER_PARAM 0x8245 -#define GL_DEBUG_SOURCE_API 0x8246 -#define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247 -#define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248 -#define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249 -#define GL_DEBUG_SOURCE_APPLICATION 0x824A -#define GL_DEBUG_SOURCE_OTHER 0x824B -#define GL_DEBUG_TYPE_ERROR 0x824C -#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D -#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E -#define GL_DEBUG_TYPE_PORTABILITY 0x824F -#define GL_DEBUG_TYPE_PERFORMANCE 0x8250 -#define GL_DEBUG_TYPE_OTHER 0x8251 -#define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143 -#define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144 -#define GL_DEBUG_LOGGED_MESSAGES 0x9145 -#define GL_DEBUG_SEVERITY_HIGH 0x9146 -#define GL_DEBUG_SEVERITY_MEDIUM 0x9147 -#define GL_DEBUG_SEVERITY_LOW 0x9148 -#define GL_DEBUG_TYPE_MARKER 0x8268 -#define GL_DEBUG_TYPE_PUSH_GROUP 0x8269 -#define GL_DEBUG_TYPE_POP_GROUP 0x826A -#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B -#define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C -#define GL_DEBUG_GROUP_STACK_DEPTH 0x826D -#define GL_BUFFER 0x82E0 -#define GL_SHADER 0x82E1 -#define GL_PROGRAM 0x82E2 -#define GL_QUERY 0x82E3 -#define GL_PROGRAM_PIPELINE 0x82E4 -#define GL_SAMPLER 0x82E6 -#define GL_MAX_LABEL_LENGTH 0x82E8 -#define GL_DEBUG_OUTPUT 0x92E0 -#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002 -#define GL_MAX_UNIFORM_LOCATIONS 0x826E -#define GL_FRAMEBUFFER_DEFAULT_WIDTH 0x9310 -#define GL_FRAMEBUFFER_DEFAULT_HEIGHT 0x9311 -#define GL_FRAMEBUFFER_DEFAULT_LAYERS 0x9312 -#define GL_FRAMEBUFFER_DEFAULT_SAMPLES 0x9313 -#define GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS 0x9314 -#define GL_MAX_FRAMEBUFFER_WIDTH 0x9315 -#define GL_MAX_FRAMEBUFFER_HEIGHT 0x9316 -#define GL_MAX_FRAMEBUFFER_LAYERS 0x9317 -#define GL_MAX_FRAMEBUFFER_SAMPLES 0x9318 -#define GL_INTERNALFORMAT_SUPPORTED 0x826F -#define GL_INTERNALFORMAT_PREFERRED 0x8270 -#define GL_INTERNALFORMAT_RED_SIZE 0x8271 -#define GL_INTERNALFORMAT_GREEN_SIZE 0x8272 -#define GL_INTERNALFORMAT_BLUE_SIZE 0x8273 -#define GL_INTERNALFORMAT_ALPHA_SIZE 0x8274 -#define GL_INTERNALFORMAT_DEPTH_SIZE 0x8275 -#define GL_INTERNALFORMAT_STENCIL_SIZE 0x8276 -#define GL_INTERNALFORMAT_SHARED_SIZE 0x8277 -#define GL_INTERNALFORMAT_RED_TYPE 0x8278 -#define GL_INTERNALFORMAT_GREEN_TYPE 0x8279 -#define GL_INTERNALFORMAT_BLUE_TYPE 0x827A -#define GL_INTERNALFORMAT_ALPHA_TYPE 0x827B -#define GL_INTERNALFORMAT_DEPTH_TYPE 0x827C -#define GL_INTERNALFORMAT_STENCIL_TYPE 0x827D -#define GL_MAX_WIDTH 0x827E -#define GL_MAX_HEIGHT 0x827F -#define GL_MAX_DEPTH 0x8280 -#define GL_MAX_LAYERS 0x8281 -#define GL_MAX_COMBINED_DIMENSIONS 0x8282 -#define GL_COLOR_COMPONENTS 0x8283 -#define GL_DEPTH_COMPONENTS 0x8284 -#define GL_STENCIL_COMPONENTS 0x8285 -#define GL_COLOR_RENDERABLE 0x8286 -#define GL_DEPTH_RENDERABLE 0x8287 -#define GL_STENCIL_RENDERABLE 0x8288 -#define GL_FRAMEBUFFER_RENDERABLE 0x8289 -#define GL_FRAMEBUFFER_RENDERABLE_LAYERED 0x828A -#define GL_FRAMEBUFFER_BLEND 0x828B -#define GL_READ_PIXELS 0x828C -#define GL_READ_PIXELS_FORMAT 0x828D -#define GL_READ_PIXELS_TYPE 0x828E -#define GL_TEXTURE_IMAGE_FORMAT 0x828F -#define GL_TEXTURE_IMAGE_TYPE 0x8290 -#define GL_GET_TEXTURE_IMAGE_FORMAT 0x8291 -#define GL_GET_TEXTURE_IMAGE_TYPE 0x8292 -#define GL_MIPMAP 0x8293 -#define GL_MANUAL_GENERATE_MIPMAP 0x8294 -#define GL_AUTO_GENERATE_MIPMAP 0x8295 -#define GL_COLOR_ENCODING 0x8296 -#define GL_SRGB_READ 0x8297 -#define GL_SRGB_WRITE 0x8298 -#define GL_FILTER 0x829A -#define GL_VERTEX_TEXTURE 0x829B -#define GL_TESS_CONTROL_TEXTURE 0x829C -#define GL_TESS_EVALUATION_TEXTURE 0x829D -#define GL_GEOMETRY_TEXTURE 0x829E -#define GL_FRAGMENT_TEXTURE 0x829F -#define GL_COMPUTE_TEXTURE 0x82A0 -#define GL_TEXTURE_SHADOW 0x82A1 -#define GL_TEXTURE_GATHER 0x82A2 -#define GL_TEXTURE_GATHER_SHADOW 0x82A3 -#define GL_SHADER_IMAGE_LOAD 0x82A4 -#define GL_SHADER_IMAGE_STORE 0x82A5 -#define GL_SHADER_IMAGE_ATOMIC 0x82A6 -#define GL_IMAGE_TEXEL_SIZE 0x82A7 -#define GL_IMAGE_COMPATIBILITY_CLASS 0x82A8 -#define GL_IMAGE_PIXEL_FORMAT 0x82A9 -#define GL_IMAGE_PIXEL_TYPE 0x82AA -#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST 0x82AC -#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST 0x82AD -#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE 0x82AE -#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE 0x82AF -#define GL_TEXTURE_COMPRESSED_BLOCK_WIDTH 0x82B1 -#define GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT 0x82B2 -#define GL_TEXTURE_COMPRESSED_BLOCK_SIZE 0x82B3 -#define GL_CLEAR_BUFFER 0x82B4 -#define GL_TEXTURE_VIEW 0x82B5 -#define GL_VIEW_COMPATIBILITY_CLASS 0x82B6 -#define GL_FULL_SUPPORT 0x82B7 -#define GL_CAVEAT_SUPPORT 0x82B8 -#define GL_IMAGE_CLASS_4_X_32 0x82B9 -#define GL_IMAGE_CLASS_2_X_32 0x82BA -#define GL_IMAGE_CLASS_1_X_32 0x82BB -#define GL_IMAGE_CLASS_4_X_16 0x82BC -#define GL_IMAGE_CLASS_2_X_16 0x82BD -#define GL_IMAGE_CLASS_1_X_16 0x82BE -#define GL_IMAGE_CLASS_4_X_8 0x82BF -#define GL_IMAGE_CLASS_2_X_8 0x82C0 -#define GL_IMAGE_CLASS_1_X_8 0x82C1 -#define GL_IMAGE_CLASS_11_11_10 0x82C2 -#define GL_IMAGE_CLASS_10_10_10_2 0x82C3 -#define GL_VIEW_CLASS_128_BITS 0x82C4 -#define GL_VIEW_CLASS_96_BITS 0x82C5 -#define GL_VIEW_CLASS_64_BITS 0x82C6 -#define GL_VIEW_CLASS_48_BITS 0x82C7 -#define GL_VIEW_CLASS_32_BITS 0x82C8 -#define GL_VIEW_CLASS_24_BITS 0x82C9 -#define GL_VIEW_CLASS_16_BITS 0x82CA -#define GL_VIEW_CLASS_8_BITS 0x82CB -#define GL_VIEW_CLASS_S3TC_DXT1_RGB 0x82CC -#define GL_VIEW_CLASS_S3TC_DXT1_RGBA 0x82CD -#define GL_VIEW_CLASS_S3TC_DXT3_RGBA 0x82CE -#define GL_VIEW_CLASS_S3TC_DXT5_RGBA 0x82CF -#define GL_VIEW_CLASS_RGTC1_RED 0x82D0 -#define GL_VIEW_CLASS_RGTC2_RG 0x82D1 -#define GL_VIEW_CLASS_BPTC_UNORM 0x82D2 -#define GL_VIEW_CLASS_BPTC_FLOAT 0x82D3 -#define GL_UNIFORM 0x92E1 -#define GL_UNIFORM_BLOCK 0x92E2 -#define GL_PROGRAM_INPUT 0x92E3 -#define GL_PROGRAM_OUTPUT 0x92E4 -#define GL_BUFFER_VARIABLE 0x92E5 -#define GL_SHADER_STORAGE_BLOCK 0x92E6 -#define GL_VERTEX_SUBROUTINE 0x92E8 -#define GL_TESS_CONTROL_SUBROUTINE 0x92E9 -#define GL_TESS_EVALUATION_SUBROUTINE 0x92EA -#define GL_GEOMETRY_SUBROUTINE 0x92EB -#define GL_FRAGMENT_SUBROUTINE 0x92EC -#define GL_COMPUTE_SUBROUTINE 0x92ED -#define GL_VERTEX_SUBROUTINE_UNIFORM 0x92EE -#define GL_TESS_CONTROL_SUBROUTINE_UNIFORM 0x92EF -#define GL_TESS_EVALUATION_SUBROUTINE_UNIFORM 0x92F0 -#define GL_GEOMETRY_SUBROUTINE_UNIFORM 0x92F1 -#define GL_FRAGMENT_SUBROUTINE_UNIFORM 0x92F2 -#define GL_COMPUTE_SUBROUTINE_UNIFORM 0x92F3 -#define GL_TRANSFORM_FEEDBACK_VARYING 0x92F4 -#define GL_ACTIVE_RESOURCES 0x92F5 -#define GL_MAX_NAME_LENGTH 0x92F6 -#define GL_MAX_NUM_ACTIVE_VARIABLES 0x92F7 -#define GL_MAX_NUM_COMPATIBLE_SUBROUTINES 0x92F8 -#define GL_NAME_LENGTH 0x92F9 -#define GL_TYPE 0x92FA -#define GL_ARRAY_SIZE 0x92FB -#define GL_OFFSET 0x92FC -#define GL_BLOCK_INDEX 0x92FD -#define GL_ARRAY_STRIDE 0x92FE -#define GL_MATRIX_STRIDE 0x92FF -#define GL_IS_ROW_MAJOR 0x9300 -#define GL_ATOMIC_COUNTER_BUFFER_INDEX 0x9301 -#define GL_BUFFER_BINDING 0x9302 -#define GL_BUFFER_DATA_SIZE 0x9303 -#define GL_NUM_ACTIVE_VARIABLES 0x9304 -#define GL_ACTIVE_VARIABLES 0x9305 -#define GL_REFERENCED_BY_VERTEX_SHADER 0x9306 -#define GL_REFERENCED_BY_TESS_CONTROL_SHADER 0x9307 -#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER 0x9308 -#define GL_REFERENCED_BY_GEOMETRY_SHADER 0x9309 -#define GL_REFERENCED_BY_FRAGMENT_SHADER 0x930A -#define GL_REFERENCED_BY_COMPUTE_SHADER 0x930B -#define GL_TOP_LEVEL_ARRAY_SIZE 0x930C -#define GL_TOP_LEVEL_ARRAY_STRIDE 0x930D -#define GL_LOCATION 0x930E -#define GL_LOCATION_INDEX 0x930F -#define GL_IS_PER_PATCH 0x92E7 -#define GL_SHADER_STORAGE_BUFFER 0x90D2 -#define GL_SHADER_STORAGE_BUFFER_BINDING 0x90D3 -#define GL_SHADER_STORAGE_BUFFER_START 0x90D4 -#define GL_SHADER_STORAGE_BUFFER_SIZE 0x90D5 -#define GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS 0x90D6 -#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS 0x90D7 -#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS 0x90D8 -#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS 0x90D9 -#define GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS 0x90DA -#define GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS 0x90DB -#define GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS 0x90DC -#define GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS 0x90DD -#define GL_MAX_SHADER_STORAGE_BLOCK_SIZE 0x90DE -#define GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT 0x90DF -#define GL_SHADER_STORAGE_BARRIER_BIT 0x00002000 -#define GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES 0x8F39 -#define GL_DEPTH_STENCIL_TEXTURE_MODE 0x90EA -#define GL_TEXTURE_BUFFER_OFFSET 0x919D -#define GL_TEXTURE_BUFFER_SIZE 0x919E -#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT 0x919F -#define GL_TEXTURE_VIEW_MIN_LEVEL 0x82DB -#define GL_TEXTURE_VIEW_NUM_LEVELS 0x82DC -#define GL_TEXTURE_VIEW_MIN_LAYER 0x82DD -#define GL_TEXTURE_VIEW_NUM_LAYERS 0x82DE -#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF -#define GL_VERTEX_ATTRIB_BINDING 0x82D4 -#define GL_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D5 -#define GL_VERTEX_BINDING_DIVISOR 0x82D6 -#define GL_VERTEX_BINDING_OFFSET 0x82D7 -#define GL_VERTEX_BINDING_STRIDE 0x82D8 -#define GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D9 -#define GL_MAX_VERTEX_ATTRIB_BINDINGS 0x82DA -#define GL_VERTEX_BINDING_BUFFER 0x8F4F -#define GL_DISPLAY_LIST 0x82E7 -typedef void (APIENTRYP PFNGLCLEARBUFFERDATAPROC) (GLenum target, GLenum internalformat, GLenum format, GLenum type, const void *data); -typedef void (APIENTRYP PFNGLCLEARBUFFERSUBDATAPROC) (GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); -typedef void (APIENTRYP PFNGLDISPATCHCOMPUTEPROC) (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); -typedef void (APIENTRYP PFNGLDISPATCHCOMPUTEINDIRECTPROC) (GLintptr indirect); -typedef void (APIENTRYP PFNGLCOPYIMAGESUBDATAPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); -typedef void (APIENTRYP PFNGLFRAMEBUFFERPARAMETERIPROC) (GLenum target, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETINTERNALFORMATI64VPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint64 *params); -typedef void (APIENTRYP PFNGLINVALIDATETEXSUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); -typedef void (APIENTRYP PFNGLINVALIDATETEXIMAGEPROC) (GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLINVALIDATEBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length); -typedef void (APIENTRYP PFNGLINVALIDATEBUFFERDATAPROC) (GLuint buffer); -typedef void (APIENTRYP PFNGLINVALIDATEFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments); -typedef void (APIENTRYP PFNGLINVALIDATESUBFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTPROC) (GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride); -typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride); -typedef void (APIENTRYP PFNGLGETPROGRAMINTERFACEIVPROC) (GLuint program, GLenum programInterface, GLenum pname, GLint *params); -typedef GLuint (APIENTRYP PFNGLGETPROGRAMRESOURCEINDEXPROC) (GLuint program, GLenum programInterface, const GLchar *name); -typedef void (APIENTRYP PFNGLGETPROGRAMRESOURCENAMEPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name); -typedef void (APIENTRYP PFNGLGETPROGRAMRESOURCEIVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params); -typedef GLint (APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONPROC) (GLuint program, GLenum programInterface, const GLchar *name); -typedef GLint (APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC) (GLuint program, GLenum programInterface, const GLchar *name); -typedef void (APIENTRYP PFNGLSHADERSTORAGEBLOCKBINDINGPROC) (GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding); -typedef void (APIENTRYP PFNGLTEXBUFFERRANGEPROC) (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); -typedef void (APIENTRYP PFNGLTEXSTORAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); -typedef void (APIENTRYP PFNGLTEXSTORAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); -typedef void (APIENTRYP PFNGLTEXTUREVIEWPROC) (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers); -typedef void (APIENTRYP PFNGLBINDVERTEXBUFFERPROC) (GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); -typedef void (APIENTRYP PFNGLVERTEXATTRIBFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); -typedef void (APIENTRYP PFNGLVERTEXATTRIBIFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); -typedef void (APIENTRYP PFNGLVERTEXATTRIBLFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); -typedef void (APIENTRYP PFNGLVERTEXATTRIBBINDINGPROC) (GLuint attribindex, GLuint bindingindex); -typedef void (APIENTRYP PFNGLVERTEXBINDINGDIVISORPROC) (GLuint bindingindex, GLuint divisor); -typedef void (APIENTRYP PFNGLDEBUGMESSAGECONTROLPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); -typedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); -typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKPROC) (GLDEBUGPROC callback, const void *userParam); -typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGPROC) (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); -typedef void (APIENTRYP PFNGLPUSHDEBUGGROUPPROC) (GLenum source, GLuint id, GLsizei length, const GLchar *message); -typedef void (APIENTRYP PFNGLPOPDEBUGGROUPPROC) (void); -typedef void (APIENTRYP PFNGLOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei length, const GLchar *label); -typedef void (APIENTRYP PFNGLGETOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label); -typedef void (APIENTRYP PFNGLOBJECTPTRLABELPROC) (const void *ptr, GLsizei length, const GLchar *label); -typedef void (APIENTRYP PFNGLGETOBJECTPTRLABELPROC) (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glClearBufferData (GLenum target, GLenum internalformat, GLenum format, GLenum type, const void *data); -GLAPI void APIENTRY glClearBufferSubData (GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); -GLAPI void APIENTRY glDispatchCompute (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); -GLAPI void APIENTRY glDispatchComputeIndirect (GLintptr indirect); -GLAPI void APIENTRY glCopyImageSubData (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); -GLAPI void APIENTRY glFramebufferParameteri (GLenum target, GLenum pname, GLint param); -GLAPI void APIENTRY glGetFramebufferParameteriv (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetInternalformati64v (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint64 *params); -GLAPI void APIENTRY glInvalidateTexSubImage (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); -GLAPI void APIENTRY glInvalidateTexImage (GLuint texture, GLint level); -GLAPI void APIENTRY glInvalidateBufferSubData (GLuint buffer, GLintptr offset, GLsizeiptr length); -GLAPI void APIENTRY glInvalidateBufferData (GLuint buffer); -GLAPI void APIENTRY glInvalidateFramebuffer (GLenum target, GLsizei numAttachments, const GLenum *attachments); -GLAPI void APIENTRY glInvalidateSubFramebuffer (GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); -GLAPI void APIENTRY glMultiDrawArraysIndirect (GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride); -GLAPI void APIENTRY glMultiDrawElementsIndirect (GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride); -GLAPI void APIENTRY glGetProgramInterfaceiv (GLuint program, GLenum programInterface, GLenum pname, GLint *params); -GLAPI GLuint APIENTRY glGetProgramResourceIndex (GLuint program, GLenum programInterface, const GLchar *name); -GLAPI void APIENTRY glGetProgramResourceName (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name); -GLAPI void APIENTRY glGetProgramResourceiv (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params); -GLAPI GLint APIENTRY glGetProgramResourceLocation (GLuint program, GLenum programInterface, const GLchar *name); -GLAPI GLint APIENTRY glGetProgramResourceLocationIndex (GLuint program, GLenum programInterface, const GLchar *name); -GLAPI void APIENTRY glShaderStorageBlockBinding (GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding); -GLAPI void APIENTRY glTexBufferRange (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); -GLAPI void APIENTRY glTexStorage2DMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); -GLAPI void APIENTRY glTexStorage3DMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); -GLAPI void APIENTRY glTextureView (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers); -GLAPI void APIENTRY glBindVertexBuffer (GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); -GLAPI void APIENTRY glVertexAttribFormat (GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); -GLAPI void APIENTRY glVertexAttribIFormat (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); -GLAPI void APIENTRY glVertexAttribLFormat (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); -GLAPI void APIENTRY glVertexAttribBinding (GLuint attribindex, GLuint bindingindex); -GLAPI void APIENTRY glVertexBindingDivisor (GLuint bindingindex, GLuint divisor); -GLAPI void APIENTRY glDebugMessageControl (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); -GLAPI void APIENTRY glDebugMessageInsert (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); -GLAPI void APIENTRY glDebugMessageCallback (GLDEBUGPROC callback, const void *userParam); -GLAPI GLuint APIENTRY glGetDebugMessageLog (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); -GLAPI void APIENTRY glPushDebugGroup (GLenum source, GLuint id, GLsizei length, const GLchar *message); -GLAPI void APIENTRY glPopDebugGroup (void); -GLAPI void APIENTRY glObjectLabel (GLenum identifier, GLuint name, GLsizei length, const GLchar *label); -GLAPI void APIENTRY glGetObjectLabel (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label); -GLAPI void APIENTRY glObjectPtrLabel (const void *ptr, GLsizei length, const GLchar *label); -GLAPI void APIENTRY glGetObjectPtrLabel (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label); -#endif -#endif /* GL_VERSION_4_3 */ - -#ifndef GL_VERSION_4_4 -#define GL_VERSION_4_4 1 -#define GL_MAX_VERTEX_ATTRIB_STRIDE 0x82E5 -#define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED 0x8221 -#define GL_TEXTURE_BUFFER_BINDING 0x8C2A -#define GL_MAP_PERSISTENT_BIT 0x0040 -#define GL_MAP_COHERENT_BIT 0x0080 -#define GL_DYNAMIC_STORAGE_BIT 0x0100 -#define GL_CLIENT_STORAGE_BIT 0x0200 -#define GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT 0x00004000 -#define GL_BUFFER_IMMUTABLE_STORAGE 0x821F -#define GL_BUFFER_STORAGE_FLAGS 0x8220 -#define GL_CLEAR_TEXTURE 0x9365 -#define GL_LOCATION_COMPONENT 0x934A -#define GL_TRANSFORM_FEEDBACK_BUFFER_INDEX 0x934B -#define GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE 0x934C -#define GL_QUERY_BUFFER 0x9192 -#define GL_QUERY_BUFFER_BARRIER_BIT 0x00008000 -#define GL_QUERY_BUFFER_BINDING 0x9193 -#define GL_QUERY_RESULT_NO_WAIT 0x9194 -#define GL_MIRROR_CLAMP_TO_EDGE 0x8743 -typedef void (APIENTRYP PFNGLBUFFERSTORAGEPROC) (GLenum target, GLsizeiptr size, const void *data, GLbitfield flags); -typedef void (APIENTRYP PFNGLCLEARTEXIMAGEPROC) (GLuint texture, GLint level, GLenum format, GLenum type, const void *data); -typedef void (APIENTRYP PFNGLCLEARTEXSUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data); -typedef void (APIENTRYP PFNGLBINDBUFFERSBASEPROC) (GLenum target, GLuint first, GLsizei count, const GLuint *buffers); -typedef void (APIENTRYP PFNGLBINDBUFFERSRANGEPROC) (GLenum target, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizeiptr *sizes); -typedef void (APIENTRYP PFNGLBINDTEXTURESPROC) (GLuint first, GLsizei count, const GLuint *textures); -typedef void (APIENTRYP PFNGLBINDSAMPLERSPROC) (GLuint first, GLsizei count, const GLuint *samplers); -typedef void (APIENTRYP PFNGLBINDIMAGETEXTURESPROC) (GLuint first, GLsizei count, const GLuint *textures); -typedef void (APIENTRYP PFNGLBINDVERTEXBUFFERSPROC) (GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizei *strides); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBufferStorage (GLenum target, GLsizeiptr size, const void *data, GLbitfield flags); -GLAPI void APIENTRY glClearTexImage (GLuint texture, GLint level, GLenum format, GLenum type, const void *data); -GLAPI void APIENTRY glClearTexSubImage (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data); -GLAPI void APIENTRY glBindBuffersBase (GLenum target, GLuint first, GLsizei count, const GLuint *buffers); -GLAPI void APIENTRY glBindBuffersRange (GLenum target, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizeiptr *sizes); -GLAPI void APIENTRY glBindTextures (GLuint first, GLsizei count, const GLuint *textures); -GLAPI void APIENTRY glBindSamplers (GLuint first, GLsizei count, const GLuint *samplers); -GLAPI void APIENTRY glBindImageTextures (GLuint first, GLsizei count, const GLuint *textures); -GLAPI void APIENTRY glBindVertexBuffers (GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizei *strides); -#endif -#endif /* GL_VERSION_4_4 */ - -#ifndef GL_VERSION_4_5 -#define GL_VERSION_4_5 1 -#define GL_CONTEXT_LOST 0x0507 -#define GL_NEGATIVE_ONE_TO_ONE 0x935E -#define GL_ZERO_TO_ONE 0x935F -#define GL_CLIP_ORIGIN 0x935C -#define GL_CLIP_DEPTH_MODE 0x935D -#define GL_QUERY_WAIT_INVERTED 0x8E17 -#define GL_QUERY_NO_WAIT_INVERTED 0x8E18 -#define GL_QUERY_BY_REGION_WAIT_INVERTED 0x8E19 -#define GL_QUERY_BY_REGION_NO_WAIT_INVERTED 0x8E1A -#define GL_MAX_CULL_DISTANCES 0x82F9 -#define GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES 0x82FA -#define GL_TEXTURE_TARGET 0x1006 -#define GL_QUERY_TARGET 0x82EA -#define GL_TEXTURE_BINDING 0x82EB -#define GL_GUILTY_CONTEXT_RESET 0x8253 -#define GL_INNOCENT_CONTEXT_RESET 0x8254 -#define GL_UNKNOWN_CONTEXT_RESET 0x8255 -#define GL_RESET_NOTIFICATION_STRATEGY 0x8256 -#define GL_LOSE_CONTEXT_ON_RESET 0x8252 -#define GL_NO_RESET_NOTIFICATION 0x8261 -#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT 0x00000004 -#define GL_CONTEXT_RELEASE_BEHAVIOR 0x82FB -#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH 0x82FC -typedef void (APIENTRYP PFNGLCLIPCONTROLPROC) (GLenum origin, GLenum depth); -typedef void (APIENTRYP PFNGLCREATETRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint *ids); -typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC) (GLuint xfb, GLuint index, GLuint buffer); -typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC) (GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizei size); -typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKIVPROC) (GLuint xfb, GLenum pname, GLint *param); -typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKI_VPROC) (GLuint xfb, GLenum pname, GLuint index, GLint *param); -typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKI64_VPROC) (GLuint xfb, GLenum pname, GLuint index, GLint64 *param); -typedef void (APIENTRYP PFNGLCREATEBUFFERSPROC) (GLsizei n, GLuint *buffers); -typedef void (APIENTRYP PFNGLNAMEDBUFFERSTORAGEPROC) (GLuint buffer, GLsizei size, const void *data, GLbitfield flags); -typedef void (APIENTRYP PFNGLNAMEDBUFFERDATAPROC) (GLuint buffer, GLsizei size, const void *data, GLenum usage); -typedef void (APIENTRYP PFNGLNAMEDBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizei size, const void *data); -typedef void (APIENTRYP PFNGLCOPYNAMEDBUFFERSUBDATAPROC) (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizei size); -typedef void (APIENTRYP PFNGLCLEARNAMEDBUFFERDATAPROC) (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data); -typedef void (APIENTRYP PFNGLCLEARNAMEDBUFFERSUBDATAPROC) (GLuint buffer, GLenum internalformat, GLintptr offset, GLsizei size, GLenum format, GLenum type, const void *data); -typedef void *(APIENTRYP PFNGLMAPNAMEDBUFFERPROC) (GLuint buffer, GLenum access); -typedef void *(APIENTRYP PFNGLMAPNAMEDBUFFERRANGEPROC) (GLuint buffer, GLintptr offset, GLsizei length, GLbitfield access); -typedef GLboolean (APIENTRYP PFNGLUNMAPNAMEDBUFFERPROC) (GLuint buffer); -typedef void (APIENTRYP PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC) (GLuint buffer, GLintptr offset, GLsizei length); -typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPARAMETERIVPROC) (GLuint buffer, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPARAMETERI64VPROC) (GLuint buffer, GLenum pname, GLint64 *params); -typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPOINTERVPROC) (GLuint buffer, GLenum pname, void **params); -typedef void (APIENTRYP PFNGLGETNAMEDBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizei size, void *data); -typedef void (APIENTRYP PFNGLCREATEFRAMEBUFFERSPROC) (GLsizei n, GLuint *framebuffers); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC) (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC) (GLuint framebuffer, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTUREPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC) (GLuint framebuffer, GLenum buf); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC) (GLuint framebuffer, GLsizei n, const GLenum *bufs); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC) (GLuint framebuffer, GLenum src); -typedef void (APIENTRYP PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC) (GLuint framebuffer, GLsizei numAttachments, const GLenum *attachments); -typedef void (APIENTRYP PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC) (GLuint framebuffer, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLCLEARNAMEDFRAMEBUFFERIVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint *value); -typedef void (APIENTRYP PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint *value); -typedef void (APIENTRYP PFNGLCLEARNAMEDFRAMEBUFFERFVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat *value); -typedef void (APIENTRYP PFNGLCLEARNAMEDFRAMEBUFFERFIPROC) (GLuint framebuffer, GLenum buffer, const GLfloat depth, GLint stencil); -typedef void (APIENTRYP PFNGLBLITNAMEDFRAMEBUFFERPROC) (GLuint readFramebuffer, GLuint drawFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -typedef GLenum (APIENTRYP PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC) (GLuint framebuffer, GLenum target); -typedef void (APIENTRYP PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC) (GLuint framebuffer, GLenum pname, GLint *param); -typedef void (APIENTRYP PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLCREATERENDERBUFFERSPROC) (GLsizei n, GLuint *renderbuffers); -typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEPROC) (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC) (GLuint renderbuffer, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLCREATETEXTURESPROC) (GLenum target, GLsizei n, GLuint *textures); -typedef void (APIENTRYP PFNGLTEXTUREBUFFERPROC) (GLuint texture, GLenum internalformat, GLuint buffer); -typedef void (APIENTRYP PFNGLTEXTUREBUFFERRANGEPROC) (GLuint texture, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizei size); -typedef void (APIENTRYP PFNGLTEXTURESTORAGE1DPROC) (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width); -typedef void (APIENTRYP PFNGLTEXTURESTORAGE2DPROC) (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLTEXTURESTORAGE3DPROC) (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); -typedef void (APIENTRYP PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC) (GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); -typedef void (APIENTRYP PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC) (GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); -typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE1DPROC) (GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); -typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE2DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); -typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE3DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC) (GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); -typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE1DPROC) (GLuint texture, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); -typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE2DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE3DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLTEXTUREPARAMETERFPROC) (GLuint texture, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLTEXTUREPARAMETERFVPROC) (GLuint texture, GLenum pname, const GLfloat *param); -typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIPROC) (GLuint texture, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIIVPROC) (GLuint texture, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIUIVPROC) (GLuint texture, GLenum pname, const GLuint *params); -typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIVPROC) (GLuint texture, GLenum pname, const GLint *param); -typedef void (APIENTRYP PFNGLGENERATETEXTUREMIPMAPPROC) (GLuint texture); -typedef void (APIENTRYP PFNGLBINDTEXTUREUNITPROC) (GLuint unit, GLuint texture); -typedef void (APIENTRYP PFNGLGETTEXTUREIMAGEPROC) (GLuint texture, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels); -typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC) (GLuint texture, GLint level, GLsizei bufSize, void *pixels); -typedef void (APIENTRYP PFNGLGETTEXTURELEVELPARAMETERFVPROC) (GLuint texture, GLint level, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETTEXTURELEVELPARAMETERIVPROC) (GLuint texture, GLint level, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERFVPROC) (GLuint texture, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIIVPROC) (GLuint texture, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIUIVPROC) (GLuint texture, GLenum pname, GLuint *params); -typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIVPROC) (GLuint texture, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLCREATEVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays); -typedef void (APIENTRYP PFNGLDISABLEVERTEXARRAYATTRIBPROC) (GLuint vaobj, GLuint index); -typedef void (APIENTRYP PFNGLENABLEVERTEXARRAYATTRIBPROC) (GLuint vaobj, GLuint index); -typedef void (APIENTRYP PFNGLVERTEXARRAYELEMENTBUFFERPROC) (GLuint vaobj, GLuint buffer); -typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXBUFFERPROC) (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); -typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXBUFFERSPROC) (GLuint vaobj, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizei *strides); -typedef void (APIENTRYP PFNGLVERTEXARRAYATTRIBBINDINGPROC) (GLuint vaobj, GLuint attribindex, GLuint bindingindex); -typedef void (APIENTRYP PFNGLVERTEXARRAYATTRIBFORMATPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); -typedef void (APIENTRYP PFNGLVERTEXARRAYATTRIBIFORMATPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); -typedef void (APIENTRYP PFNGLVERTEXARRAYATTRIBLFORMATPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); -typedef void (APIENTRYP PFNGLVERTEXARRAYBINDINGDIVISORPROC) (GLuint vaobj, GLuint bindingindex, GLuint divisor); -typedef void (APIENTRYP PFNGLGETVERTEXARRAYIVPROC) (GLuint vaobj, GLenum pname, GLint *param); -typedef void (APIENTRYP PFNGLGETVERTEXARRAYINDEXEDIVPROC) (GLuint vaobj, GLuint index, GLenum pname, GLint *param); -typedef void (APIENTRYP PFNGLGETVERTEXARRAYINDEXED64IVPROC) (GLuint vaobj, GLuint index, GLenum pname, GLint64 *param); -typedef void (APIENTRYP PFNGLCREATESAMPLERSPROC) (GLsizei n, GLuint *samplers); -typedef void (APIENTRYP PFNGLCREATEPROGRAMPIPELINESPROC) (GLsizei n, GLuint *pipelines); -typedef void (APIENTRYP PFNGLCREATEQUERIESPROC) (GLenum target, GLsizei n, GLuint *ids); -typedef void (APIENTRYP PFNGLMEMORYBARRIERBYREGIONPROC) (GLbitfield barriers); -typedef void (APIENTRYP PFNGLGETTEXTURESUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLsizei bufSize, void *pixels); -typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei bufSize, void *pixels); -typedef GLenum (APIENTRYP PFNGLGETGRAPHICSRESETSTATUSPROC) (void); -typedef void (APIENTRYP PFNGLGETNCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint lod, GLsizei bufSize, void *pixels); -typedef void (APIENTRYP PFNGLGETNTEXIMAGEPROC) (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels); -typedef void (APIENTRYP PFNGLGETNUNIFORMDVPROC) (GLuint program, GLint location, GLsizei bufSize, GLdouble *params); -typedef void (APIENTRYP PFNGLGETNUNIFORMFVPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); -typedef void (APIENTRYP PFNGLGETNUNIFORMIVPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params); -typedef void (APIENTRYP PFNGLGETNUNIFORMUIVPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint *params); -typedef void (APIENTRYP PFNGLREADNPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); -typedef void (APIENTRYP PFNGLGETNMAPDVPROC) (GLenum target, GLenum query, GLsizei bufSize, GLdouble *v); -typedef void (APIENTRYP PFNGLGETNMAPFVPROC) (GLenum target, GLenum query, GLsizei bufSize, GLfloat *v); -typedef void (APIENTRYP PFNGLGETNMAPIVPROC) (GLenum target, GLenum query, GLsizei bufSize, GLint *v); -typedef void (APIENTRYP PFNGLGETNPIXELMAPFVPROC) (GLenum map, GLsizei bufSize, GLfloat *values); -typedef void (APIENTRYP PFNGLGETNPIXELMAPUIVPROC) (GLenum map, GLsizei bufSize, GLuint *values); -typedef void (APIENTRYP PFNGLGETNPIXELMAPUSVPROC) (GLenum map, GLsizei bufSize, GLushort *values); -typedef void (APIENTRYP PFNGLGETNPOLYGONSTIPPLEPROC) (GLsizei bufSize, GLubyte *pattern); -typedef void (APIENTRYP PFNGLGETNCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *table); -typedef void (APIENTRYP PFNGLGETNCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *image); -typedef void (APIENTRYP PFNGLGETNSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, void *row, GLsizei columnBufSize, void *column, void *span); -typedef void (APIENTRYP PFNGLGETNHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void *values); -typedef void (APIENTRYP PFNGLGETNMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void *values); -typedef void (APIENTRYP PFNGLTEXTUREBARRIERPROC) (void); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glClipControl (GLenum origin, GLenum depth); -GLAPI void APIENTRY glCreateTransformFeedbacks (GLsizei n, GLuint *ids); -GLAPI void APIENTRY glTransformFeedbackBufferBase (GLuint xfb, GLuint index, GLuint buffer); -GLAPI void APIENTRY glTransformFeedbackBufferRange (GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizei size); -GLAPI void APIENTRY glGetTransformFeedbackiv (GLuint xfb, GLenum pname, GLint *param); -GLAPI void APIENTRY glGetTransformFeedbacki_v (GLuint xfb, GLenum pname, GLuint index, GLint *param); -GLAPI void APIENTRY glGetTransformFeedbacki64_v (GLuint xfb, GLenum pname, GLuint index, GLint64 *param); -GLAPI void APIENTRY glCreateBuffers (GLsizei n, GLuint *buffers); -GLAPI void APIENTRY glNamedBufferStorage (GLuint buffer, GLsizei size, const void *data, GLbitfield flags); -GLAPI void APIENTRY glNamedBufferData (GLuint buffer, GLsizei size, const void *data, GLenum usage); -GLAPI void APIENTRY glNamedBufferSubData (GLuint buffer, GLintptr offset, GLsizei size, const void *data); -GLAPI void APIENTRY glCopyNamedBufferSubData (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizei size); -GLAPI void APIENTRY glClearNamedBufferData (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data); -GLAPI void APIENTRY glClearNamedBufferSubData (GLuint buffer, GLenum internalformat, GLintptr offset, GLsizei size, GLenum format, GLenum type, const void *data); -GLAPI void *APIENTRY glMapNamedBuffer (GLuint buffer, GLenum access); -GLAPI void *APIENTRY glMapNamedBufferRange (GLuint buffer, GLintptr offset, GLsizei length, GLbitfield access); -GLAPI GLboolean APIENTRY glUnmapNamedBuffer (GLuint buffer); -GLAPI void APIENTRY glFlushMappedNamedBufferRange (GLuint buffer, GLintptr offset, GLsizei length); -GLAPI void APIENTRY glGetNamedBufferParameteriv (GLuint buffer, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetNamedBufferParameteri64v (GLuint buffer, GLenum pname, GLint64 *params); -GLAPI void APIENTRY glGetNamedBufferPointerv (GLuint buffer, GLenum pname, void **params); -GLAPI void APIENTRY glGetNamedBufferSubData (GLuint buffer, GLintptr offset, GLsizei size, void *data); -GLAPI void APIENTRY glCreateFramebuffers (GLsizei n, GLuint *framebuffers); -GLAPI void APIENTRY glNamedFramebufferRenderbuffer (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -GLAPI void APIENTRY glNamedFramebufferParameteri (GLuint framebuffer, GLenum pname, GLint param); -GLAPI void APIENTRY glNamedFramebufferTexture (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); -GLAPI void APIENTRY glNamedFramebufferTextureLayer (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); -GLAPI void APIENTRY glNamedFramebufferDrawBuffer (GLuint framebuffer, GLenum buf); -GLAPI void APIENTRY glNamedFramebufferDrawBuffers (GLuint framebuffer, GLsizei n, const GLenum *bufs); -GLAPI void APIENTRY glNamedFramebufferReadBuffer (GLuint framebuffer, GLenum src); -GLAPI void APIENTRY glInvalidateNamedFramebufferData (GLuint framebuffer, GLsizei numAttachments, const GLenum *attachments); -GLAPI void APIENTRY glInvalidateNamedFramebufferSubData (GLuint framebuffer, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); -GLAPI void APIENTRY glClearNamedFramebufferiv (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint *value); -GLAPI void APIENTRY glClearNamedFramebufferuiv (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint *value); -GLAPI void APIENTRY glClearNamedFramebufferfv (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat *value); -GLAPI void APIENTRY glClearNamedFramebufferfi (GLuint framebuffer, GLenum buffer, const GLfloat depth, GLint stencil); -GLAPI void APIENTRY glBlitNamedFramebuffer (GLuint readFramebuffer, GLuint drawFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -GLAPI GLenum APIENTRY glCheckNamedFramebufferStatus (GLuint framebuffer, GLenum target); -GLAPI void APIENTRY glGetNamedFramebufferParameteriv (GLuint framebuffer, GLenum pname, GLint *param); -GLAPI void APIENTRY glGetNamedFramebufferAttachmentParameteriv (GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params); -GLAPI void APIENTRY glCreateRenderbuffers (GLsizei n, GLuint *renderbuffers); -GLAPI void APIENTRY glNamedRenderbufferStorage (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); -GLAPI void APIENTRY glNamedRenderbufferStorageMultisample (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -GLAPI void APIENTRY glGetNamedRenderbufferParameteriv (GLuint renderbuffer, GLenum pname, GLint *params); -GLAPI void APIENTRY glCreateTextures (GLenum target, GLsizei n, GLuint *textures); -GLAPI void APIENTRY glTextureBuffer (GLuint texture, GLenum internalformat, GLuint buffer); -GLAPI void APIENTRY glTextureBufferRange (GLuint texture, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizei size); -GLAPI void APIENTRY glTextureStorage1D (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width); -GLAPI void APIENTRY glTextureStorage2D (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); -GLAPI void APIENTRY glTextureStorage3D (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); -GLAPI void APIENTRY glTextureStorage2DMultisample (GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); -GLAPI void APIENTRY glTextureStorage3DMultisample (GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); -GLAPI void APIENTRY glTextureSubImage1D (GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); -GLAPI void APIENTRY glTextureSubImage2D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); -GLAPI void APIENTRY glTextureSubImage3D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); -GLAPI void APIENTRY glCompressedTextureSubImage1D (GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); -GLAPI void APIENTRY glCompressedTextureSubImage2D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); -GLAPI void APIENTRY glCompressedTextureSubImage3D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); -GLAPI void APIENTRY glCopyTextureSubImage1D (GLuint texture, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); -GLAPI void APIENTRY glCopyTextureSubImage2D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -GLAPI void APIENTRY glCopyTextureSubImage3D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -GLAPI void APIENTRY glTextureParameterf (GLuint texture, GLenum pname, GLfloat param); -GLAPI void APIENTRY glTextureParameterfv (GLuint texture, GLenum pname, const GLfloat *param); -GLAPI void APIENTRY glTextureParameteri (GLuint texture, GLenum pname, GLint param); -GLAPI void APIENTRY glTextureParameterIiv (GLuint texture, GLenum pname, const GLint *params); -GLAPI void APIENTRY glTextureParameterIuiv (GLuint texture, GLenum pname, const GLuint *params); -GLAPI void APIENTRY glTextureParameteriv (GLuint texture, GLenum pname, const GLint *param); -GLAPI void APIENTRY glGenerateTextureMipmap (GLuint texture); -GLAPI void APIENTRY glBindTextureUnit (GLuint unit, GLuint texture); -GLAPI void APIENTRY glGetTextureImage (GLuint texture, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels); -GLAPI void APIENTRY glGetCompressedTextureImage (GLuint texture, GLint level, GLsizei bufSize, void *pixels); -GLAPI void APIENTRY glGetTextureLevelParameterfv (GLuint texture, GLint level, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetTextureLevelParameteriv (GLuint texture, GLint level, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetTextureParameterfv (GLuint texture, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetTextureParameterIiv (GLuint texture, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetTextureParameterIuiv (GLuint texture, GLenum pname, GLuint *params); -GLAPI void APIENTRY glGetTextureParameteriv (GLuint texture, GLenum pname, GLint *params); -GLAPI void APIENTRY glCreateVertexArrays (GLsizei n, GLuint *arrays); -GLAPI void APIENTRY glDisableVertexArrayAttrib (GLuint vaobj, GLuint index); -GLAPI void APIENTRY glEnableVertexArrayAttrib (GLuint vaobj, GLuint index); -GLAPI void APIENTRY glVertexArrayElementBuffer (GLuint vaobj, GLuint buffer); -GLAPI void APIENTRY glVertexArrayVertexBuffer (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); -GLAPI void APIENTRY glVertexArrayVertexBuffers (GLuint vaobj, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizei *strides); -GLAPI void APIENTRY glVertexArrayAttribBinding (GLuint vaobj, GLuint attribindex, GLuint bindingindex); -GLAPI void APIENTRY glVertexArrayAttribFormat (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); -GLAPI void APIENTRY glVertexArrayAttribIFormat (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); -GLAPI void APIENTRY glVertexArrayAttribLFormat (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); -GLAPI void APIENTRY glVertexArrayBindingDivisor (GLuint vaobj, GLuint bindingindex, GLuint divisor); -GLAPI void APIENTRY glGetVertexArrayiv (GLuint vaobj, GLenum pname, GLint *param); -GLAPI void APIENTRY glGetVertexArrayIndexediv (GLuint vaobj, GLuint index, GLenum pname, GLint *param); -GLAPI void APIENTRY glGetVertexArrayIndexed64iv (GLuint vaobj, GLuint index, GLenum pname, GLint64 *param); -GLAPI void APIENTRY glCreateSamplers (GLsizei n, GLuint *samplers); -GLAPI void APIENTRY glCreateProgramPipelines (GLsizei n, GLuint *pipelines); -GLAPI void APIENTRY glCreateQueries (GLenum target, GLsizei n, GLuint *ids); -GLAPI void APIENTRY glMemoryBarrierByRegion (GLbitfield barriers); -GLAPI void APIENTRY glGetTextureSubImage (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLsizei bufSize, void *pixels); -GLAPI void APIENTRY glGetCompressedTextureSubImage (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei bufSize, void *pixels); -GLAPI GLenum APIENTRY glGetGraphicsResetStatus (void); -GLAPI void APIENTRY glGetnCompressedTexImage (GLenum target, GLint lod, GLsizei bufSize, void *pixels); -GLAPI void APIENTRY glGetnTexImage (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels); -GLAPI void APIENTRY glGetnUniformdv (GLuint program, GLint location, GLsizei bufSize, GLdouble *params); -GLAPI void APIENTRY glGetnUniformfv (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); -GLAPI void APIENTRY glGetnUniformiv (GLuint program, GLint location, GLsizei bufSize, GLint *params); -GLAPI void APIENTRY glGetnUniformuiv (GLuint program, GLint location, GLsizei bufSize, GLuint *params); -GLAPI void APIENTRY glReadnPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); -GLAPI void APIENTRY glGetnMapdv (GLenum target, GLenum query, GLsizei bufSize, GLdouble *v); -GLAPI void APIENTRY glGetnMapfv (GLenum target, GLenum query, GLsizei bufSize, GLfloat *v); -GLAPI void APIENTRY glGetnMapiv (GLenum target, GLenum query, GLsizei bufSize, GLint *v); -GLAPI void APIENTRY glGetnPixelMapfv (GLenum map, GLsizei bufSize, GLfloat *values); -GLAPI void APIENTRY glGetnPixelMapuiv (GLenum map, GLsizei bufSize, GLuint *values); -GLAPI void APIENTRY glGetnPixelMapusv (GLenum map, GLsizei bufSize, GLushort *values); -GLAPI void APIENTRY glGetnPolygonStipple (GLsizei bufSize, GLubyte *pattern); -GLAPI void APIENTRY glGetnColorTable (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *table); -GLAPI void APIENTRY glGetnConvolutionFilter (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *image); -GLAPI void APIENTRY glGetnSeparableFilter (GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, void *row, GLsizei columnBufSize, void *column, void *span); -GLAPI void APIENTRY glGetnHistogram (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void *values); -GLAPI void APIENTRY glGetnMinmax (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void *values); -GLAPI void APIENTRY glTextureBarrier (void); -#endif -#endif /* GL_VERSION_4_5 */ - -#ifndef GL_ARB_ES2_compatibility -#define GL_ARB_ES2_compatibility 1 -#endif /* GL_ARB_ES2_compatibility */ - -#ifndef GL_ARB_ES3_1_compatibility -#define GL_ARB_ES3_1_compatibility 1 -#endif /* GL_ARB_ES3_1_compatibility */ - -#ifndef GL_ARB_ES3_compatibility -#define GL_ARB_ES3_compatibility 1 -#endif /* GL_ARB_ES3_compatibility */ - -#ifndef GL_ARB_arrays_of_arrays -#define GL_ARB_arrays_of_arrays 1 -#endif /* GL_ARB_arrays_of_arrays */ - -#ifndef GL_ARB_base_instance -#define GL_ARB_base_instance 1 -#endif /* GL_ARB_base_instance */ - -#ifndef GL_ARB_bindless_texture -#define GL_ARB_bindless_texture 1 -typedef uint64_t GLuint64EXT; -#define GL_UNSIGNED_INT64_ARB 0x140F -typedef GLuint64 (APIENTRYP PFNGLGETTEXTUREHANDLEARBPROC) (GLuint texture); -typedef GLuint64 (APIENTRYP PFNGLGETTEXTURESAMPLERHANDLEARBPROC) (GLuint texture, GLuint sampler); -typedef void (APIENTRYP PFNGLMAKETEXTUREHANDLERESIDENTARBPROC) (GLuint64 handle); -typedef void (APIENTRYP PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC) (GLuint64 handle); -typedef GLuint64 (APIENTRYP PFNGLGETIMAGEHANDLEARBPROC) (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format); -typedef void (APIENTRYP PFNGLMAKEIMAGEHANDLERESIDENTARBPROC) (GLuint64 handle, GLenum access); -typedef void (APIENTRYP PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC) (GLuint64 handle); -typedef void (APIENTRYP PFNGLUNIFORMHANDLEUI64ARBPROC) (GLint location, GLuint64 value); -typedef void (APIENTRYP PFNGLUNIFORMHANDLEUI64VARBPROC) (GLint location, GLsizei count, const GLuint64 *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC) (GLuint program, GLint location, GLuint64 value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLuint64 *values); -typedef GLboolean (APIENTRYP PFNGLISTEXTUREHANDLERESIDENTARBPROC) (GLuint64 handle); -typedef GLboolean (APIENTRYP PFNGLISIMAGEHANDLERESIDENTARBPROC) (GLuint64 handle); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL1UI64ARBPROC) (GLuint index, GLuint64EXT x); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL1UI64VARBPROC) (GLuint index, const GLuint64EXT *v); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLUI64VARBPROC) (GLuint index, GLenum pname, GLuint64EXT *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLuint64 APIENTRY glGetTextureHandleARB (GLuint texture); -GLAPI GLuint64 APIENTRY glGetTextureSamplerHandleARB (GLuint texture, GLuint sampler); -GLAPI void APIENTRY glMakeTextureHandleResidentARB (GLuint64 handle); -GLAPI void APIENTRY glMakeTextureHandleNonResidentARB (GLuint64 handle); -GLAPI GLuint64 APIENTRY glGetImageHandleARB (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format); -GLAPI void APIENTRY glMakeImageHandleResidentARB (GLuint64 handle, GLenum access); -GLAPI void APIENTRY glMakeImageHandleNonResidentARB (GLuint64 handle); -GLAPI void APIENTRY glUniformHandleui64ARB (GLint location, GLuint64 value); -GLAPI void APIENTRY glUniformHandleui64vARB (GLint location, GLsizei count, const GLuint64 *value); -GLAPI void APIENTRY glProgramUniformHandleui64ARB (GLuint program, GLint location, GLuint64 value); -GLAPI void APIENTRY glProgramUniformHandleui64vARB (GLuint program, GLint location, GLsizei count, const GLuint64 *values); -GLAPI GLboolean APIENTRY glIsTextureHandleResidentARB (GLuint64 handle); -GLAPI GLboolean APIENTRY glIsImageHandleResidentARB (GLuint64 handle); -GLAPI void APIENTRY glVertexAttribL1ui64ARB (GLuint index, GLuint64EXT x); -GLAPI void APIENTRY glVertexAttribL1ui64vARB (GLuint index, const GLuint64EXT *v); -GLAPI void APIENTRY glGetVertexAttribLui64vARB (GLuint index, GLenum pname, GLuint64EXT *params); -#endif -#endif /* GL_ARB_bindless_texture */ - -#ifndef GL_ARB_blend_func_extended -#define GL_ARB_blend_func_extended 1 -#endif /* GL_ARB_blend_func_extended */ - -#ifndef GL_ARB_buffer_storage -#define GL_ARB_buffer_storage 1 -#endif /* GL_ARB_buffer_storage */ - -#ifndef GL_ARB_cl_event -#define GL_ARB_cl_event 1 -struct _cl_context; -struct _cl_event; -#define GL_SYNC_CL_EVENT_ARB 0x8240 -#define GL_SYNC_CL_EVENT_COMPLETE_ARB 0x8241 -typedef GLsync (APIENTRYP PFNGLCREATESYNCFROMCLEVENTARBPROC) (struct _cl_context *context, struct _cl_event *event, GLbitfield flags); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLsync APIENTRY glCreateSyncFromCLeventARB (struct _cl_context *context, struct _cl_event *event, GLbitfield flags); -#endif -#endif /* GL_ARB_cl_event */ - -#ifndef GL_ARB_clear_buffer_object -#define GL_ARB_clear_buffer_object 1 -#endif /* GL_ARB_clear_buffer_object */ - -#ifndef GL_ARB_clear_texture -#define GL_ARB_clear_texture 1 -#endif /* GL_ARB_clear_texture */ - -#ifndef GL_ARB_clip_control -#define GL_ARB_clip_control 1 -#endif /* GL_ARB_clip_control */ - -#ifndef GL_ARB_color_buffer_float -#define GL_ARB_color_buffer_float 1 -#define GL_RGBA_FLOAT_MODE_ARB 0x8820 -#define GL_CLAMP_VERTEX_COLOR_ARB 0x891A -#define GL_CLAMP_FRAGMENT_COLOR_ARB 0x891B -#define GL_CLAMP_READ_COLOR_ARB 0x891C -#define GL_FIXED_ONLY_ARB 0x891D -typedef void (APIENTRYP PFNGLCLAMPCOLORARBPROC) (GLenum target, GLenum clamp); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glClampColorARB (GLenum target, GLenum clamp); -#endif -#endif /* GL_ARB_color_buffer_float */ - -#ifndef GL_ARB_compatibility -#define GL_ARB_compatibility 1 -#endif /* GL_ARB_compatibility */ - -#ifndef GL_ARB_compressed_texture_pixel_storage -#define GL_ARB_compressed_texture_pixel_storage 1 -#endif /* GL_ARB_compressed_texture_pixel_storage */ - -#ifndef GL_ARB_compute_shader -#define GL_ARB_compute_shader 1 -#endif /* GL_ARB_compute_shader */ - -#ifndef GL_ARB_compute_variable_group_size -#define GL_ARB_compute_variable_group_size 1 -#define GL_MAX_COMPUTE_VARIABLE_GROUP_INVOCATIONS_ARB 0x9344 -#define GL_MAX_COMPUTE_FIXED_GROUP_INVOCATIONS_ARB 0x90EB -#define GL_MAX_COMPUTE_VARIABLE_GROUP_SIZE_ARB 0x9345 -#define GL_MAX_COMPUTE_FIXED_GROUP_SIZE_ARB 0x91BF -typedef void (APIENTRYP PFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC) (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z, GLuint group_size_x, GLuint group_size_y, GLuint group_size_z); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDispatchComputeGroupSizeARB (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z, GLuint group_size_x, GLuint group_size_y, GLuint group_size_z); -#endif -#endif /* GL_ARB_compute_variable_group_size */ - -#ifndef GL_ARB_conditional_render_inverted -#define GL_ARB_conditional_render_inverted 1 -#endif /* GL_ARB_conditional_render_inverted */ - -#ifndef GL_ARB_conservative_depth -#define GL_ARB_conservative_depth 1 -#endif /* GL_ARB_conservative_depth */ - -#ifndef GL_ARB_copy_buffer -#define GL_ARB_copy_buffer 1 -#define GL_COPY_READ_BUFFER_BINDING 0x8F36 -#define GL_COPY_WRITE_BUFFER_BINDING 0x8F37 -#endif /* GL_ARB_copy_buffer */ - -#ifndef GL_ARB_copy_image -#define GL_ARB_copy_image 1 -#endif /* GL_ARB_copy_image */ - -#ifndef GL_ARB_cull_distance -#define GL_ARB_cull_distance 1 -#endif /* GL_ARB_cull_distance */ - -#ifndef GL_ARB_debug_output -#define GL_ARB_debug_output 1 -typedef void (APIENTRY *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); -#define GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB 0x8242 -#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB 0x8243 -#define GL_DEBUG_CALLBACK_FUNCTION_ARB 0x8244 -#define GL_DEBUG_CALLBACK_USER_PARAM_ARB 0x8245 -#define GL_DEBUG_SOURCE_API_ARB 0x8246 -#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB 0x8247 -#define GL_DEBUG_SOURCE_SHADER_COMPILER_ARB 0x8248 -#define GL_DEBUG_SOURCE_THIRD_PARTY_ARB 0x8249 -#define GL_DEBUG_SOURCE_APPLICATION_ARB 0x824A -#define GL_DEBUG_SOURCE_OTHER_ARB 0x824B -#define GL_DEBUG_TYPE_ERROR_ARB 0x824C -#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB 0x824D -#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB 0x824E -#define GL_DEBUG_TYPE_PORTABILITY_ARB 0x824F -#define GL_DEBUG_TYPE_PERFORMANCE_ARB 0x8250 -#define GL_DEBUG_TYPE_OTHER_ARB 0x8251 -#define GL_MAX_DEBUG_MESSAGE_LENGTH_ARB 0x9143 -#define GL_MAX_DEBUG_LOGGED_MESSAGES_ARB 0x9144 -#define GL_DEBUG_LOGGED_MESSAGES_ARB 0x9145 -#define GL_DEBUG_SEVERITY_HIGH_ARB 0x9146 -#define GL_DEBUG_SEVERITY_MEDIUM_ARB 0x9147 -#define GL_DEBUG_SEVERITY_LOW_ARB 0x9148 -typedef void (APIENTRYP PFNGLDEBUGMESSAGECONTROLARBPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); -typedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTARBPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); -typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKARBPROC) (GLDEBUGPROCARB callback, const void *userParam); -typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGARBPROC) (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDebugMessageControlARB (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); -GLAPI void APIENTRY glDebugMessageInsertARB (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); -GLAPI void APIENTRY glDebugMessageCallbackARB (GLDEBUGPROCARB callback, const void *userParam); -GLAPI GLuint APIENTRY glGetDebugMessageLogARB (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); -#endif -#endif /* GL_ARB_debug_output */ - -#ifndef GL_ARB_depth_buffer_float -#define GL_ARB_depth_buffer_float 1 -#endif /* GL_ARB_depth_buffer_float */ - -#ifndef GL_ARB_depth_clamp -#define GL_ARB_depth_clamp 1 -#endif /* GL_ARB_depth_clamp */ - -#ifndef GL_ARB_depth_texture -#define GL_ARB_depth_texture 1 -#define GL_DEPTH_COMPONENT16_ARB 0x81A5 -#define GL_DEPTH_COMPONENT24_ARB 0x81A6 -#define GL_DEPTH_COMPONENT32_ARB 0x81A7 -#define GL_TEXTURE_DEPTH_SIZE_ARB 0x884A -#define GL_DEPTH_TEXTURE_MODE_ARB 0x884B -#endif /* GL_ARB_depth_texture */ - -#ifndef GL_ARB_derivative_control -#define GL_ARB_derivative_control 1 -#endif /* GL_ARB_derivative_control */ - -#ifndef GL_ARB_direct_state_access -#define GL_ARB_direct_state_access 1 -#endif /* GL_ARB_direct_state_access */ - -#ifndef GL_ARB_draw_buffers -#define GL_ARB_draw_buffers 1 -#define GL_MAX_DRAW_BUFFERS_ARB 0x8824 -#define GL_DRAW_BUFFER0_ARB 0x8825 -#define GL_DRAW_BUFFER1_ARB 0x8826 -#define GL_DRAW_BUFFER2_ARB 0x8827 -#define GL_DRAW_BUFFER3_ARB 0x8828 -#define GL_DRAW_BUFFER4_ARB 0x8829 -#define GL_DRAW_BUFFER5_ARB 0x882A -#define GL_DRAW_BUFFER6_ARB 0x882B -#define GL_DRAW_BUFFER7_ARB 0x882C -#define GL_DRAW_BUFFER8_ARB 0x882D -#define GL_DRAW_BUFFER9_ARB 0x882E -#define GL_DRAW_BUFFER10_ARB 0x882F -#define GL_DRAW_BUFFER11_ARB 0x8830 -#define GL_DRAW_BUFFER12_ARB 0x8831 -#define GL_DRAW_BUFFER13_ARB 0x8832 -#define GL_DRAW_BUFFER14_ARB 0x8833 -#define GL_DRAW_BUFFER15_ARB 0x8834 -typedef void (APIENTRYP PFNGLDRAWBUFFERSARBPROC) (GLsizei n, const GLenum *bufs); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDrawBuffersARB (GLsizei n, const GLenum *bufs); -#endif -#endif /* GL_ARB_draw_buffers */ - -#ifndef GL_ARB_draw_buffers_blend -#define GL_ARB_draw_buffers_blend 1 -typedef void (APIENTRYP PFNGLBLENDEQUATIONIARBPROC) (GLuint buf, GLenum mode); -typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEIARBPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); -typedef void (APIENTRYP PFNGLBLENDFUNCIARBPROC) (GLuint buf, GLenum src, GLenum dst); -typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEIARBPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendEquationiARB (GLuint buf, GLenum mode); -GLAPI void APIENTRY glBlendEquationSeparateiARB (GLuint buf, GLenum modeRGB, GLenum modeAlpha); -GLAPI void APIENTRY glBlendFunciARB (GLuint buf, GLenum src, GLenum dst); -GLAPI void APIENTRY glBlendFuncSeparateiARB (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); -#endif -#endif /* GL_ARB_draw_buffers_blend */ - -#ifndef GL_ARB_draw_elements_base_vertex -#define GL_ARB_draw_elements_base_vertex 1 -#endif /* GL_ARB_draw_elements_base_vertex */ - -#ifndef GL_ARB_draw_indirect -#define GL_ARB_draw_indirect 1 -#endif /* GL_ARB_draw_indirect */ - -#ifndef GL_ARB_draw_instanced -#define GL_ARB_draw_instanced 1 -typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDARBPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); -typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDARBPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDrawArraysInstancedARB (GLenum mode, GLint first, GLsizei count, GLsizei primcount); -GLAPI void APIENTRY glDrawElementsInstancedARB (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); -#endif -#endif /* GL_ARB_draw_instanced */ - -#ifndef GL_ARB_enhanced_layouts -#define GL_ARB_enhanced_layouts 1 -#endif /* GL_ARB_enhanced_layouts */ - -#ifndef GL_ARB_explicit_attrib_location -#define GL_ARB_explicit_attrib_location 1 -#endif /* GL_ARB_explicit_attrib_location */ - -#ifndef GL_ARB_explicit_uniform_location -#define GL_ARB_explicit_uniform_location 1 -#endif /* GL_ARB_explicit_uniform_location */ - -#ifndef GL_ARB_fragment_coord_conventions -#define GL_ARB_fragment_coord_conventions 1 -#endif /* GL_ARB_fragment_coord_conventions */ - -#ifndef GL_ARB_fragment_layer_viewport -#define GL_ARB_fragment_layer_viewport 1 -#endif /* GL_ARB_fragment_layer_viewport */ - -#ifndef GL_ARB_fragment_program -#define GL_ARB_fragment_program 1 -#define GL_FRAGMENT_PROGRAM_ARB 0x8804 -#define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875 -#define GL_PROGRAM_LENGTH_ARB 0x8627 -#define GL_PROGRAM_FORMAT_ARB 0x8876 -#define GL_PROGRAM_BINDING_ARB 0x8677 -#define GL_PROGRAM_INSTRUCTIONS_ARB 0x88A0 -#define GL_MAX_PROGRAM_INSTRUCTIONS_ARB 0x88A1 -#define GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2 -#define GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3 -#define GL_PROGRAM_TEMPORARIES_ARB 0x88A4 -#define GL_MAX_PROGRAM_TEMPORARIES_ARB 0x88A5 -#define GL_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6 -#define GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7 -#define GL_PROGRAM_PARAMETERS_ARB 0x88A8 -#define GL_MAX_PROGRAM_PARAMETERS_ARB 0x88A9 -#define GL_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AA -#define GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB -#define GL_PROGRAM_ATTRIBS_ARB 0x88AC -#define GL_MAX_PROGRAM_ATTRIBS_ARB 0x88AD -#define GL_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AE -#define GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF -#define GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4 -#define GL_MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5 -#define GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6 -#define GL_PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805 -#define GL_PROGRAM_TEX_INSTRUCTIONS_ARB 0x8806 -#define GL_PROGRAM_TEX_INDIRECTIONS_ARB 0x8807 -#define GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808 -#define GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809 -#define GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A -#define GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B -#define GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C -#define GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D -#define GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E -#define GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F -#define GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810 -#define GL_PROGRAM_STRING_ARB 0x8628 -#define GL_PROGRAM_ERROR_POSITION_ARB 0x864B -#define GL_CURRENT_MATRIX_ARB 0x8641 -#define GL_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7 -#define GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640 -#define GL_MAX_PROGRAM_MATRICES_ARB 0x862F -#define GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E -#define GL_MAX_TEXTURE_COORDS_ARB 0x8871 -#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872 -#define GL_PROGRAM_ERROR_STRING_ARB 0x8874 -#define GL_MATRIX0_ARB 0x88C0 -#define GL_MATRIX1_ARB 0x88C1 -#define GL_MATRIX2_ARB 0x88C2 -#define GL_MATRIX3_ARB 0x88C3 -#define GL_MATRIX4_ARB 0x88C4 -#define GL_MATRIX5_ARB 0x88C5 -#define GL_MATRIX6_ARB 0x88C6 -#define GL_MATRIX7_ARB 0x88C7 -#define GL_MATRIX8_ARB 0x88C8 -#define GL_MATRIX9_ARB 0x88C9 -#define GL_MATRIX10_ARB 0x88CA -#define GL_MATRIX11_ARB 0x88CB -#define GL_MATRIX12_ARB 0x88CC -#define GL_MATRIX13_ARB 0x88CD -#define GL_MATRIX14_ARB 0x88CE -#define GL_MATRIX15_ARB 0x88CF -#define GL_MATRIX16_ARB 0x88D0 -#define GL_MATRIX17_ARB 0x88D1 -#define GL_MATRIX18_ARB 0x88D2 -#define GL_MATRIX19_ARB 0x88D3 -#define GL_MATRIX20_ARB 0x88D4 -#define GL_MATRIX21_ARB 0x88D5 -#define GL_MATRIX22_ARB 0x88D6 -#define GL_MATRIX23_ARB 0x88D7 -#define GL_MATRIX24_ARB 0x88D8 -#define GL_MATRIX25_ARB 0x88D9 -#define GL_MATRIX26_ARB 0x88DA -#define GL_MATRIX27_ARB 0x88DB -#define GL_MATRIX28_ARB 0x88DC -#define GL_MATRIX29_ARB 0x88DD -#define GL_MATRIX30_ARB 0x88DE -#define GL_MATRIX31_ARB 0x88DF -typedef void (APIENTRYP PFNGLPROGRAMSTRINGARBPROC) (GLenum target, GLenum format, GLsizei len, const void *string); -typedef void (APIENTRYP PFNGLBINDPROGRAMARBPROC) (GLenum target, GLuint program); -typedef void (APIENTRYP PFNGLDELETEPROGRAMSARBPROC) (GLsizei n, const GLuint *programs); -typedef void (APIENTRYP PFNGLGENPROGRAMSARBPROC) (GLsizei n, GLuint *programs); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params); -typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params); -typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params); -typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params); -typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params); -typedef void (APIENTRYP PFNGLGETPROGRAMIVARBPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETPROGRAMSTRINGARBPROC) (GLenum target, GLenum pname, void *string); -typedef GLboolean (APIENTRYP PFNGLISPROGRAMARBPROC) (GLuint program); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glProgramStringARB (GLenum target, GLenum format, GLsizei len, const void *string); -GLAPI void APIENTRY glBindProgramARB (GLenum target, GLuint program); -GLAPI void APIENTRY glDeleteProgramsARB (GLsizei n, const GLuint *programs); -GLAPI void APIENTRY glGenProgramsARB (GLsizei n, GLuint *programs); -GLAPI void APIENTRY glProgramEnvParameter4dARB (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void APIENTRY glProgramEnvParameter4dvARB (GLenum target, GLuint index, const GLdouble *params); -GLAPI void APIENTRY glProgramEnvParameter4fARB (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI void APIENTRY glProgramEnvParameter4fvARB (GLenum target, GLuint index, const GLfloat *params); -GLAPI void APIENTRY glProgramLocalParameter4dARB (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void APIENTRY glProgramLocalParameter4dvARB (GLenum target, GLuint index, const GLdouble *params); -GLAPI void APIENTRY glProgramLocalParameter4fARB (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI void APIENTRY glProgramLocalParameter4fvARB (GLenum target, GLuint index, const GLfloat *params); -GLAPI void APIENTRY glGetProgramEnvParameterdvARB (GLenum target, GLuint index, GLdouble *params); -GLAPI void APIENTRY glGetProgramEnvParameterfvARB (GLenum target, GLuint index, GLfloat *params); -GLAPI void APIENTRY glGetProgramLocalParameterdvARB (GLenum target, GLuint index, GLdouble *params); -GLAPI void APIENTRY glGetProgramLocalParameterfvARB (GLenum target, GLuint index, GLfloat *params); -GLAPI void APIENTRY glGetProgramivARB (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetProgramStringARB (GLenum target, GLenum pname, void *string); -GLAPI GLboolean APIENTRY glIsProgramARB (GLuint program); -#endif -#endif /* GL_ARB_fragment_program */ - -#ifndef GL_ARB_fragment_program_shadow -#define GL_ARB_fragment_program_shadow 1 -#endif /* GL_ARB_fragment_program_shadow */ - -#ifndef GL_ARB_fragment_shader -#define GL_ARB_fragment_shader 1 -#define GL_FRAGMENT_SHADER_ARB 0x8B30 -#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49 -#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB 0x8B8B -#endif /* GL_ARB_fragment_shader */ - -#ifndef GL_ARB_framebuffer_no_attachments -#define GL_ARB_framebuffer_no_attachments 1 -#endif /* GL_ARB_framebuffer_no_attachments */ - -#ifndef GL_ARB_framebuffer_object -#define GL_ARB_framebuffer_object 1 -#endif /* GL_ARB_framebuffer_object */ - -#ifndef GL_ARB_framebuffer_sRGB -#define GL_ARB_framebuffer_sRGB 1 -#endif /* GL_ARB_framebuffer_sRGB */ - -#ifndef GL_ARB_geometry_shader4 -#define GL_ARB_geometry_shader4 1 -#define GL_LINES_ADJACENCY_ARB 0x000A -#define GL_LINE_STRIP_ADJACENCY_ARB 0x000B -#define GL_TRIANGLES_ADJACENCY_ARB 0x000C -#define GL_TRIANGLE_STRIP_ADJACENCY_ARB 0x000D -#define GL_PROGRAM_POINT_SIZE_ARB 0x8642 -#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB 0x8C29 -#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_ARB 0x8DA7 -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB 0x8DA8 -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB 0x8DA9 -#define GL_GEOMETRY_SHADER_ARB 0x8DD9 -#define GL_GEOMETRY_VERTICES_OUT_ARB 0x8DDA -#define GL_GEOMETRY_INPUT_TYPE_ARB 0x8DDB -#define GL_GEOMETRY_OUTPUT_TYPE_ARB 0x8DDC -#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB 0x8DDD -#define GL_MAX_VERTEX_VARYING_COMPONENTS_ARB 0x8DDE -#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB 0x8DDF -#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB 0x8DE0 -#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB 0x8DE1 -typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIARBPROC) (GLuint program, GLenum pname, GLint value); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREFACEARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glProgramParameteriARB (GLuint program, GLenum pname, GLint value); -GLAPI void APIENTRY glFramebufferTextureARB (GLenum target, GLenum attachment, GLuint texture, GLint level); -GLAPI void APIENTRY glFramebufferTextureLayerARB (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); -GLAPI void APIENTRY glFramebufferTextureFaceARB (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); -#endif -#endif /* GL_ARB_geometry_shader4 */ - -#ifndef GL_ARB_get_program_binary -#define GL_ARB_get_program_binary 1 -#endif /* GL_ARB_get_program_binary */ - -#ifndef GL_ARB_get_texture_sub_image -#define GL_ARB_get_texture_sub_image 1 -#endif /* GL_ARB_get_texture_sub_image */ - -#ifndef GL_ARB_gpu_shader5 -#define GL_ARB_gpu_shader5 1 -#endif /* GL_ARB_gpu_shader5 */ - -#ifndef GL_ARB_gpu_shader_fp64 -#define GL_ARB_gpu_shader_fp64 1 -#endif /* GL_ARB_gpu_shader_fp64 */ - -#ifndef GL_ARB_half_float_pixel -#define GL_ARB_half_float_pixel 1 -typedef unsigned short GLhalfARB; -#define GL_HALF_FLOAT_ARB 0x140B -#endif /* GL_ARB_half_float_pixel */ - -#ifndef GL_ARB_half_float_vertex -#define GL_ARB_half_float_vertex 1 -#endif /* GL_ARB_half_float_vertex */ - -#ifndef GL_ARB_imaging -#define GL_ARB_imaging 1 -#define GL_BLEND_COLOR 0x8005 -#define GL_BLEND_EQUATION 0x8009 -#define GL_CONVOLUTION_1D 0x8010 -#define GL_CONVOLUTION_2D 0x8011 -#define GL_SEPARABLE_2D 0x8012 -#define GL_CONVOLUTION_BORDER_MODE 0x8013 -#define GL_CONVOLUTION_FILTER_SCALE 0x8014 -#define GL_CONVOLUTION_FILTER_BIAS 0x8015 -#define GL_REDUCE 0x8016 -#define GL_CONVOLUTION_FORMAT 0x8017 -#define GL_CONVOLUTION_WIDTH 0x8018 -#define GL_CONVOLUTION_HEIGHT 0x8019 -#define GL_MAX_CONVOLUTION_WIDTH 0x801A -#define GL_MAX_CONVOLUTION_HEIGHT 0x801B -#define GL_POST_CONVOLUTION_RED_SCALE 0x801C -#define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D -#define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E -#define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F -#define GL_POST_CONVOLUTION_RED_BIAS 0x8020 -#define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021 -#define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022 -#define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023 -#define GL_HISTOGRAM 0x8024 -#define GL_PROXY_HISTOGRAM 0x8025 -#define GL_HISTOGRAM_WIDTH 0x8026 -#define GL_HISTOGRAM_FORMAT 0x8027 -#define GL_HISTOGRAM_RED_SIZE 0x8028 -#define GL_HISTOGRAM_GREEN_SIZE 0x8029 -#define GL_HISTOGRAM_BLUE_SIZE 0x802A -#define GL_HISTOGRAM_ALPHA_SIZE 0x802B -#define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C -#define GL_HISTOGRAM_SINK 0x802D -#define GL_MINMAX 0x802E -#define GL_MINMAX_FORMAT 0x802F -#define GL_MINMAX_SINK 0x8030 -#define GL_TABLE_TOO_LARGE 0x8031 -#define GL_COLOR_MATRIX 0x80B1 -#define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2 -#define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3 -#define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4 -#define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5 -#define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6 -#define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7 -#define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8 -#define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9 -#define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA -#define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB -#define GL_COLOR_TABLE 0x80D0 -#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1 -#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2 -#define GL_PROXY_COLOR_TABLE 0x80D3 -#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4 -#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5 -#define GL_COLOR_TABLE_SCALE 0x80D6 -#define GL_COLOR_TABLE_BIAS 0x80D7 -#define GL_COLOR_TABLE_FORMAT 0x80D8 -#define GL_COLOR_TABLE_WIDTH 0x80D9 -#define GL_COLOR_TABLE_RED_SIZE 0x80DA -#define GL_COLOR_TABLE_GREEN_SIZE 0x80DB -#define GL_COLOR_TABLE_BLUE_SIZE 0x80DC -#define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD -#define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE -#define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF -#define GL_CONSTANT_BORDER 0x8151 -#define GL_REPLICATE_BORDER 0x8153 -#define GL_CONVOLUTION_BORDER_COLOR 0x8154 -typedef void (APIENTRYP PFNGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *table); -typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLCOPYCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); -typedef void (APIENTRYP PFNGLGETCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, void *table); -typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const void *data); -typedef void (APIENTRYP PFNGLCOPYCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); -typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *image); -typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *image); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat params); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIPROC) (GLenum target, GLenum pname, GLint params); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); -typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLGETCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, void *image); -typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, void *row, void *column, void *span); -typedef void (APIENTRYP PFNGLSEPARABLEFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *row, const void *column); -typedef void (APIENTRYP PFNGLGETHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); -typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); -typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLHISTOGRAMPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); -typedef void (APIENTRYP PFNGLMINMAXPROC) (GLenum target, GLenum internalformat, GLboolean sink); -typedef void (APIENTRYP PFNGLRESETHISTOGRAMPROC) (GLenum target); -typedef void (APIENTRYP PFNGLRESETMINMAXPROC) (GLenum target); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glColorTable (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *table); -GLAPI void APIENTRY glColorTableParameterfv (GLenum target, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glColorTableParameteriv (GLenum target, GLenum pname, const GLint *params); -GLAPI void APIENTRY glCopyColorTable (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); -GLAPI void APIENTRY glGetColorTable (GLenum target, GLenum format, GLenum type, void *table); -GLAPI void APIENTRY glGetColorTableParameterfv (GLenum target, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetColorTableParameteriv (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glColorSubTable (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const void *data); -GLAPI void APIENTRY glCopyColorSubTable (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); -GLAPI void APIENTRY glConvolutionFilter1D (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *image); -GLAPI void APIENTRY glConvolutionFilter2D (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *image); -GLAPI void APIENTRY glConvolutionParameterf (GLenum target, GLenum pname, GLfloat params); -GLAPI void APIENTRY glConvolutionParameterfv (GLenum target, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glConvolutionParameteri (GLenum target, GLenum pname, GLint params); -GLAPI void APIENTRY glConvolutionParameteriv (GLenum target, GLenum pname, const GLint *params); -GLAPI void APIENTRY glCopyConvolutionFilter1D (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); -GLAPI void APIENTRY glCopyConvolutionFilter2D (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); -GLAPI void APIENTRY glGetConvolutionFilter (GLenum target, GLenum format, GLenum type, void *image); -GLAPI void APIENTRY glGetConvolutionParameterfv (GLenum target, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetConvolutionParameteriv (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetSeparableFilter (GLenum target, GLenum format, GLenum type, void *row, void *column, void *span); -GLAPI void APIENTRY glSeparableFilter2D (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *row, const void *column); -GLAPI void APIENTRY glGetHistogram (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); -GLAPI void APIENTRY glGetHistogramParameterfv (GLenum target, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetHistogramParameteriv (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetMinmax (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); -GLAPI void APIENTRY glGetMinmaxParameterfv (GLenum target, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetMinmaxParameteriv (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glHistogram (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); -GLAPI void APIENTRY glMinmax (GLenum target, GLenum internalformat, GLboolean sink); -GLAPI void APIENTRY glResetHistogram (GLenum target); -GLAPI void APIENTRY glResetMinmax (GLenum target); -#endif -#endif /* GL_ARB_imaging */ - -#ifndef GL_ARB_indirect_parameters -#define GL_ARB_indirect_parameters 1 -#define GL_PARAMETER_BUFFER_ARB 0x80EE -#define GL_PARAMETER_BUFFER_BINDING_ARB 0x80EF -typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC) (GLenum mode, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); -typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC) (GLenum mode, GLenum type, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glMultiDrawArraysIndirectCountARB (GLenum mode, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); -GLAPI void APIENTRY glMultiDrawElementsIndirectCountARB (GLenum mode, GLenum type, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); -#endif -#endif /* GL_ARB_indirect_parameters */ - -#ifndef GL_ARB_instanced_arrays -#define GL_ARB_instanced_arrays 1 -#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB 0x88FE -typedef void (APIENTRYP PFNGLVERTEXATTRIBDIVISORARBPROC) (GLuint index, GLuint divisor); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexAttribDivisorARB (GLuint index, GLuint divisor); -#endif -#endif /* GL_ARB_instanced_arrays */ - -#ifndef GL_ARB_internalformat_query -#define GL_ARB_internalformat_query 1 -#endif /* GL_ARB_internalformat_query */ - -#ifndef GL_ARB_internalformat_query2 -#define GL_ARB_internalformat_query2 1 -#define GL_SRGB_DECODE_ARB 0x8299 -#endif /* GL_ARB_internalformat_query2 */ - -#ifndef GL_ARB_invalidate_subdata -#define GL_ARB_invalidate_subdata 1 -#endif /* GL_ARB_invalidate_subdata */ - -#ifndef GL_ARB_map_buffer_alignment -#define GL_ARB_map_buffer_alignment 1 -#endif /* GL_ARB_map_buffer_alignment */ - -#ifndef GL_ARB_map_buffer_range -#define GL_ARB_map_buffer_range 1 -#endif /* GL_ARB_map_buffer_range */ - -#ifndef GL_ARB_matrix_palette -#define GL_ARB_matrix_palette 1 -#define GL_MATRIX_PALETTE_ARB 0x8840 -#define GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB 0x8841 -#define GL_MAX_PALETTE_MATRICES_ARB 0x8842 -#define GL_CURRENT_PALETTE_MATRIX_ARB 0x8843 -#define GL_MATRIX_INDEX_ARRAY_ARB 0x8844 -#define GL_CURRENT_MATRIX_INDEX_ARB 0x8845 -#define GL_MATRIX_INDEX_ARRAY_SIZE_ARB 0x8846 -#define GL_MATRIX_INDEX_ARRAY_TYPE_ARB 0x8847 -#define GL_MATRIX_INDEX_ARRAY_STRIDE_ARB 0x8848 -#define GL_MATRIX_INDEX_ARRAY_POINTER_ARB 0x8849 -typedef void (APIENTRYP PFNGLCURRENTPALETTEMATRIXARBPROC) (GLint index); -typedef void (APIENTRYP PFNGLMATRIXINDEXUBVARBPROC) (GLint size, const GLubyte *indices); -typedef void (APIENTRYP PFNGLMATRIXINDEXUSVARBPROC) (GLint size, const GLushort *indices); -typedef void (APIENTRYP PFNGLMATRIXINDEXUIVARBPROC) (GLint size, const GLuint *indices); -typedef void (APIENTRYP PFNGLMATRIXINDEXPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const void *pointer); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glCurrentPaletteMatrixARB (GLint index); -GLAPI void APIENTRY glMatrixIndexubvARB (GLint size, const GLubyte *indices); -GLAPI void APIENTRY glMatrixIndexusvARB (GLint size, const GLushort *indices); -GLAPI void APIENTRY glMatrixIndexuivARB (GLint size, const GLuint *indices); -GLAPI void APIENTRY glMatrixIndexPointerARB (GLint size, GLenum type, GLsizei stride, const void *pointer); -#endif -#endif /* GL_ARB_matrix_palette */ - -#ifndef GL_ARB_multi_bind -#define GL_ARB_multi_bind 1 -#endif /* GL_ARB_multi_bind */ - -#ifndef GL_ARB_multi_draw_indirect -#define GL_ARB_multi_draw_indirect 1 -#endif /* GL_ARB_multi_draw_indirect */ - -#ifndef GL_ARB_multisample -#define GL_ARB_multisample 1 -#define GL_MULTISAMPLE_ARB 0x809D -#define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E -#define GL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F -#define GL_SAMPLE_COVERAGE_ARB 0x80A0 -#define GL_SAMPLE_BUFFERS_ARB 0x80A8 -#define GL_SAMPLES_ARB 0x80A9 -#define GL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA -#define GL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB -#define GL_MULTISAMPLE_BIT_ARB 0x20000000 -typedef void (APIENTRYP PFNGLSAMPLECOVERAGEARBPROC) (GLfloat value, GLboolean invert); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glSampleCoverageARB (GLfloat value, GLboolean invert); -#endif -#endif /* GL_ARB_multisample */ - -#ifndef GL_ARB_multitexture -#define GL_ARB_multitexture 1 -#define GL_TEXTURE0_ARB 0x84C0 -#define GL_TEXTURE1_ARB 0x84C1 -#define GL_TEXTURE2_ARB 0x84C2 -#define GL_TEXTURE3_ARB 0x84C3 -#define GL_TEXTURE4_ARB 0x84C4 -#define GL_TEXTURE5_ARB 0x84C5 -#define GL_TEXTURE6_ARB 0x84C6 -#define GL_TEXTURE7_ARB 0x84C7 -#define GL_TEXTURE8_ARB 0x84C8 -#define GL_TEXTURE9_ARB 0x84C9 -#define GL_TEXTURE10_ARB 0x84CA -#define GL_TEXTURE11_ARB 0x84CB -#define GL_TEXTURE12_ARB 0x84CC -#define GL_TEXTURE13_ARB 0x84CD -#define GL_TEXTURE14_ARB 0x84CE -#define GL_TEXTURE15_ARB 0x84CF -#define GL_TEXTURE16_ARB 0x84D0 -#define GL_TEXTURE17_ARB 0x84D1 -#define GL_TEXTURE18_ARB 0x84D2 -#define GL_TEXTURE19_ARB 0x84D3 -#define GL_TEXTURE20_ARB 0x84D4 -#define GL_TEXTURE21_ARB 0x84D5 -#define GL_TEXTURE22_ARB 0x84D6 -#define GL_TEXTURE23_ARB 0x84D7 -#define GL_TEXTURE24_ARB 0x84D8 -#define GL_TEXTURE25_ARB 0x84D9 -#define GL_TEXTURE26_ARB 0x84DA -#define GL_TEXTURE27_ARB 0x84DB -#define GL_TEXTURE28_ARB 0x84DC -#define GL_TEXTURE29_ARB 0x84DD -#define GL_TEXTURE30_ARB 0x84DE -#define GL_TEXTURE31_ARB 0x84DF -#define GL_ACTIVE_TEXTURE_ARB 0x84E0 -#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 -#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 -typedef void (APIENTRYP PFNGLACTIVETEXTUREARBPROC) (GLenum texture); -typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort *v); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glActiveTextureARB (GLenum texture); -GLAPI void APIENTRY glClientActiveTextureARB (GLenum texture); -GLAPI void APIENTRY glMultiTexCoord1dARB (GLenum target, GLdouble s); -GLAPI void APIENTRY glMultiTexCoord1dvARB (GLenum target, const GLdouble *v); -GLAPI void APIENTRY glMultiTexCoord1fARB (GLenum target, GLfloat s); -GLAPI void APIENTRY glMultiTexCoord1fvARB (GLenum target, const GLfloat *v); -GLAPI void APIENTRY glMultiTexCoord1iARB (GLenum target, GLint s); -GLAPI void APIENTRY glMultiTexCoord1ivARB (GLenum target, const GLint *v); -GLAPI void APIENTRY glMultiTexCoord1sARB (GLenum target, GLshort s); -GLAPI void APIENTRY glMultiTexCoord1svARB (GLenum target, const GLshort *v); -GLAPI void APIENTRY glMultiTexCoord2dARB (GLenum target, GLdouble s, GLdouble t); -GLAPI void APIENTRY glMultiTexCoord2dvARB (GLenum target, const GLdouble *v); -GLAPI void APIENTRY glMultiTexCoord2fARB (GLenum target, GLfloat s, GLfloat t); -GLAPI void APIENTRY glMultiTexCoord2fvARB (GLenum target, const GLfloat *v); -GLAPI void APIENTRY glMultiTexCoord2iARB (GLenum target, GLint s, GLint t); -GLAPI void APIENTRY glMultiTexCoord2ivARB (GLenum target, const GLint *v); -GLAPI void APIENTRY glMultiTexCoord2sARB (GLenum target, GLshort s, GLshort t); -GLAPI void APIENTRY glMultiTexCoord2svARB (GLenum target, const GLshort *v); -GLAPI void APIENTRY glMultiTexCoord3dARB (GLenum target, GLdouble s, GLdouble t, GLdouble r); -GLAPI void APIENTRY glMultiTexCoord3dvARB (GLenum target, const GLdouble *v); -GLAPI void APIENTRY glMultiTexCoord3fARB (GLenum target, GLfloat s, GLfloat t, GLfloat r); -GLAPI void APIENTRY glMultiTexCoord3fvARB (GLenum target, const GLfloat *v); -GLAPI void APIENTRY glMultiTexCoord3iARB (GLenum target, GLint s, GLint t, GLint r); -GLAPI void APIENTRY glMultiTexCoord3ivARB (GLenum target, const GLint *v); -GLAPI void APIENTRY glMultiTexCoord3sARB (GLenum target, GLshort s, GLshort t, GLshort r); -GLAPI void APIENTRY glMultiTexCoord3svARB (GLenum target, const GLshort *v); -GLAPI void APIENTRY glMultiTexCoord4dARB (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); -GLAPI void APIENTRY glMultiTexCoord4dvARB (GLenum target, const GLdouble *v); -GLAPI void APIENTRY glMultiTexCoord4fARB (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); -GLAPI void APIENTRY glMultiTexCoord4fvARB (GLenum target, const GLfloat *v); -GLAPI void APIENTRY glMultiTexCoord4iARB (GLenum target, GLint s, GLint t, GLint r, GLint q); -GLAPI void APIENTRY glMultiTexCoord4ivARB (GLenum target, const GLint *v); -GLAPI void APIENTRY glMultiTexCoord4sARB (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); -GLAPI void APIENTRY glMultiTexCoord4svARB (GLenum target, const GLshort *v); -#endif -#endif /* GL_ARB_multitexture */ - -#ifndef GL_ARB_occlusion_query -#define GL_ARB_occlusion_query 1 -#define GL_QUERY_COUNTER_BITS_ARB 0x8864 -#define GL_CURRENT_QUERY_ARB 0x8865 -#define GL_QUERY_RESULT_ARB 0x8866 -#define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867 -#define GL_SAMPLES_PASSED_ARB 0x8914 -typedef void (APIENTRYP PFNGLGENQUERIESARBPROC) (GLsizei n, GLuint *ids); -typedef void (APIENTRYP PFNGLDELETEQUERIESARBPROC) (GLsizei n, const GLuint *ids); -typedef GLboolean (APIENTRYP PFNGLISQUERYARBPROC) (GLuint id); -typedef void (APIENTRYP PFNGLBEGINQUERYARBPROC) (GLenum target, GLuint id); -typedef void (APIENTRYP PFNGLENDQUERYARBPROC) (GLenum target); -typedef void (APIENTRYP PFNGLGETQUERYIVARBPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVARBPROC) (GLuint id, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVARBPROC) (GLuint id, GLenum pname, GLuint *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGenQueriesARB (GLsizei n, GLuint *ids); -GLAPI void APIENTRY glDeleteQueriesARB (GLsizei n, const GLuint *ids); -GLAPI GLboolean APIENTRY glIsQueryARB (GLuint id); -GLAPI void APIENTRY glBeginQueryARB (GLenum target, GLuint id); -GLAPI void APIENTRY glEndQueryARB (GLenum target); -GLAPI void APIENTRY glGetQueryivARB (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetQueryObjectivARB (GLuint id, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetQueryObjectuivARB (GLuint id, GLenum pname, GLuint *params); -#endif -#endif /* GL_ARB_occlusion_query */ - -#ifndef GL_ARB_occlusion_query2 -#define GL_ARB_occlusion_query2 1 -#endif /* GL_ARB_occlusion_query2 */ - -#ifndef GL_ARB_pipeline_statistics_query -#define GL_ARB_pipeline_statistics_query 1 -#define GL_VERTICES_SUBMITTED_ARB 0x82EE -#define GL_PRIMITIVES_SUBMITTED_ARB 0x82EF -#define GL_VERTEX_SHADER_INVOCATIONS_ARB 0x82F0 -#define GL_TESS_CONTROL_SHADER_PATCHES_ARB 0x82F1 -#define GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB 0x82F2 -#define GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB 0x82F3 -#define GL_FRAGMENT_SHADER_INVOCATIONS_ARB 0x82F4 -#define GL_COMPUTE_SHADER_INVOCATIONS_ARB 0x82F5 -#define GL_CLIPPING_INPUT_PRIMITIVES_ARB 0x82F6 -#define GL_CLIPPING_OUTPUT_PRIMITIVES_ARB 0x82F7 -#endif /* GL_ARB_pipeline_statistics_query */ - -#ifndef GL_ARB_pixel_buffer_object -#define GL_ARB_pixel_buffer_object 1 -#define GL_PIXEL_PACK_BUFFER_ARB 0x88EB -#define GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC -#define GL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED -#define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF -#endif /* GL_ARB_pixel_buffer_object */ - -#ifndef GL_ARB_point_parameters -#define GL_ARB_point_parameters 1 -#define GL_POINT_SIZE_MIN_ARB 0x8126 -#define GL_POINT_SIZE_MAX_ARB 0x8127 -#define GL_POINT_FADE_THRESHOLD_SIZE_ARB 0x8128 -#define GL_POINT_DISTANCE_ATTENUATION_ARB 0x8129 -typedef void (APIENTRYP PFNGLPOINTPARAMETERFARBPROC) (GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLPOINTPARAMETERFVARBPROC) (GLenum pname, const GLfloat *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPointParameterfARB (GLenum pname, GLfloat param); -GLAPI void APIENTRY glPointParameterfvARB (GLenum pname, const GLfloat *params); -#endif -#endif /* GL_ARB_point_parameters */ - -#ifndef GL_ARB_point_sprite -#define GL_ARB_point_sprite 1 -#define GL_POINT_SPRITE_ARB 0x8861 -#define GL_COORD_REPLACE_ARB 0x8862 -#endif /* GL_ARB_point_sprite */ - -#ifndef GL_ARB_program_interface_query -#define GL_ARB_program_interface_query 1 -#endif /* GL_ARB_program_interface_query */ - -#ifndef GL_ARB_provoking_vertex -#define GL_ARB_provoking_vertex 1 -#endif /* GL_ARB_provoking_vertex */ - -#ifndef GL_ARB_query_buffer_object -#define GL_ARB_query_buffer_object 1 -#endif /* GL_ARB_query_buffer_object */ - -#ifndef GL_ARB_robust_buffer_access_behavior -#define GL_ARB_robust_buffer_access_behavior 1 -#endif /* GL_ARB_robust_buffer_access_behavior */ - -#ifndef GL_ARB_robustness -#define GL_ARB_robustness 1 -#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB 0x00000004 -#define GL_LOSE_CONTEXT_ON_RESET_ARB 0x8252 -#define GL_GUILTY_CONTEXT_RESET_ARB 0x8253 -#define GL_INNOCENT_CONTEXT_RESET_ARB 0x8254 -#define GL_UNKNOWN_CONTEXT_RESET_ARB 0x8255 -#define GL_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 -#define GL_NO_RESET_NOTIFICATION_ARB 0x8261 -typedef GLenum (APIENTRYP PFNGLGETGRAPHICSRESETSTATUSARBPROC) (void); -typedef void (APIENTRYP PFNGLGETNTEXIMAGEARBPROC) (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *img); -typedef void (APIENTRYP PFNGLREADNPIXELSARBPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); -typedef void (APIENTRYP PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint lod, GLsizei bufSize, void *img); -typedef void (APIENTRYP PFNGLGETNUNIFORMFVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); -typedef void (APIENTRYP PFNGLGETNUNIFORMIVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params); -typedef void (APIENTRYP PFNGLGETNUNIFORMUIVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint *params); -typedef void (APIENTRYP PFNGLGETNUNIFORMDVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLdouble *params); -typedef void (APIENTRYP PFNGLGETNMAPDVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLdouble *v); -typedef void (APIENTRYP PFNGLGETNMAPFVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLfloat *v); -typedef void (APIENTRYP PFNGLGETNMAPIVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLint *v); -typedef void (APIENTRYP PFNGLGETNPIXELMAPFVARBPROC) (GLenum map, GLsizei bufSize, GLfloat *values); -typedef void (APIENTRYP PFNGLGETNPIXELMAPUIVARBPROC) (GLenum map, GLsizei bufSize, GLuint *values); -typedef void (APIENTRYP PFNGLGETNPIXELMAPUSVARBPROC) (GLenum map, GLsizei bufSize, GLushort *values); -typedef void (APIENTRYP PFNGLGETNPOLYGONSTIPPLEARBPROC) (GLsizei bufSize, GLubyte *pattern); -typedef void (APIENTRYP PFNGLGETNCOLORTABLEARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *table); -typedef void (APIENTRYP PFNGLGETNCONVOLUTIONFILTERARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *image); -typedef void (APIENTRYP PFNGLGETNSEPARABLEFILTERARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, void *row, GLsizei columnBufSize, void *column, void *span); -typedef void (APIENTRYP PFNGLGETNHISTOGRAMARBPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void *values); -typedef void (APIENTRYP PFNGLGETNMINMAXARBPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void *values); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLenum APIENTRY glGetGraphicsResetStatusARB (void); -GLAPI void APIENTRY glGetnTexImageARB (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *img); -GLAPI void APIENTRY glReadnPixelsARB (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); -GLAPI void APIENTRY glGetnCompressedTexImageARB (GLenum target, GLint lod, GLsizei bufSize, void *img); -GLAPI void APIENTRY glGetnUniformfvARB (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); -GLAPI void APIENTRY glGetnUniformivARB (GLuint program, GLint location, GLsizei bufSize, GLint *params); -GLAPI void APIENTRY glGetnUniformuivARB (GLuint program, GLint location, GLsizei bufSize, GLuint *params); -GLAPI void APIENTRY glGetnUniformdvARB (GLuint program, GLint location, GLsizei bufSize, GLdouble *params); -GLAPI void APIENTRY glGetnMapdvARB (GLenum target, GLenum query, GLsizei bufSize, GLdouble *v); -GLAPI void APIENTRY glGetnMapfvARB (GLenum target, GLenum query, GLsizei bufSize, GLfloat *v); -GLAPI void APIENTRY glGetnMapivARB (GLenum target, GLenum query, GLsizei bufSize, GLint *v); -GLAPI void APIENTRY glGetnPixelMapfvARB (GLenum map, GLsizei bufSize, GLfloat *values); -GLAPI void APIENTRY glGetnPixelMapuivARB (GLenum map, GLsizei bufSize, GLuint *values); -GLAPI void APIENTRY glGetnPixelMapusvARB (GLenum map, GLsizei bufSize, GLushort *values); -GLAPI void APIENTRY glGetnPolygonStippleARB (GLsizei bufSize, GLubyte *pattern); -GLAPI void APIENTRY glGetnColorTableARB (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *table); -GLAPI void APIENTRY glGetnConvolutionFilterARB (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *image); -GLAPI void APIENTRY glGetnSeparableFilterARB (GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, void *row, GLsizei columnBufSize, void *column, void *span); -GLAPI void APIENTRY glGetnHistogramARB (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void *values); -GLAPI void APIENTRY glGetnMinmaxARB (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void *values); -#endif -#endif /* GL_ARB_robustness */ - -#ifndef GL_ARB_robustness_isolation -#define GL_ARB_robustness_isolation 1 -#endif /* GL_ARB_robustness_isolation */ - -#ifndef GL_ARB_sample_shading -#define GL_ARB_sample_shading 1 -#define GL_SAMPLE_SHADING_ARB 0x8C36 -#define GL_MIN_SAMPLE_SHADING_VALUE_ARB 0x8C37 -typedef void (APIENTRYP PFNGLMINSAMPLESHADINGARBPROC) (GLfloat value); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glMinSampleShadingARB (GLfloat value); -#endif -#endif /* GL_ARB_sample_shading */ - -#ifndef GL_ARB_sampler_objects -#define GL_ARB_sampler_objects 1 -#endif /* GL_ARB_sampler_objects */ - -#ifndef GL_ARB_seamless_cube_map -#define GL_ARB_seamless_cube_map 1 -#endif /* GL_ARB_seamless_cube_map */ - -#ifndef GL_ARB_seamless_cubemap_per_texture -#define GL_ARB_seamless_cubemap_per_texture 1 -#endif /* GL_ARB_seamless_cubemap_per_texture */ - -#ifndef GL_ARB_separate_shader_objects -#define GL_ARB_separate_shader_objects 1 -#endif /* GL_ARB_separate_shader_objects */ - -#ifndef GL_ARB_shader_atomic_counters -#define GL_ARB_shader_atomic_counters 1 -#endif /* GL_ARB_shader_atomic_counters */ - -#ifndef GL_ARB_shader_bit_encoding -#define GL_ARB_shader_bit_encoding 1 -#endif /* GL_ARB_shader_bit_encoding */ - -#ifndef GL_ARB_shader_draw_parameters -#define GL_ARB_shader_draw_parameters 1 -#endif /* GL_ARB_shader_draw_parameters */ - -#ifndef GL_ARB_shader_group_vote -#define GL_ARB_shader_group_vote 1 -#endif /* GL_ARB_shader_group_vote */ - -#ifndef GL_ARB_shader_image_load_store -#define GL_ARB_shader_image_load_store 1 -#endif /* GL_ARB_shader_image_load_store */ - -#ifndef GL_ARB_shader_image_size -#define GL_ARB_shader_image_size 1 -#endif /* GL_ARB_shader_image_size */ - -#ifndef GL_ARB_shader_objects -#define GL_ARB_shader_objects 1 -#ifdef __APPLE__ -typedef void *GLhandleARB; -#else -typedef unsigned int GLhandleARB; -#endif -typedef char GLcharARB; -#define GL_PROGRAM_OBJECT_ARB 0x8B40 -#define GL_SHADER_OBJECT_ARB 0x8B48 -#define GL_OBJECT_TYPE_ARB 0x8B4E -#define GL_OBJECT_SUBTYPE_ARB 0x8B4F -#define GL_FLOAT_VEC2_ARB 0x8B50 -#define GL_FLOAT_VEC3_ARB 0x8B51 -#define GL_FLOAT_VEC4_ARB 0x8B52 -#define GL_INT_VEC2_ARB 0x8B53 -#define GL_INT_VEC3_ARB 0x8B54 -#define GL_INT_VEC4_ARB 0x8B55 -#define GL_BOOL_ARB 0x8B56 -#define GL_BOOL_VEC2_ARB 0x8B57 -#define GL_BOOL_VEC3_ARB 0x8B58 -#define GL_BOOL_VEC4_ARB 0x8B59 -#define GL_FLOAT_MAT2_ARB 0x8B5A -#define GL_FLOAT_MAT3_ARB 0x8B5B -#define GL_FLOAT_MAT4_ARB 0x8B5C -#define GL_SAMPLER_1D_ARB 0x8B5D -#define GL_SAMPLER_2D_ARB 0x8B5E -#define GL_SAMPLER_3D_ARB 0x8B5F -#define GL_SAMPLER_CUBE_ARB 0x8B60 -#define GL_SAMPLER_1D_SHADOW_ARB 0x8B61 -#define GL_SAMPLER_2D_SHADOW_ARB 0x8B62 -#define GL_SAMPLER_2D_RECT_ARB 0x8B63 -#define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64 -#define GL_OBJECT_DELETE_STATUS_ARB 0x8B80 -#define GL_OBJECT_COMPILE_STATUS_ARB 0x8B81 -#define GL_OBJECT_LINK_STATUS_ARB 0x8B82 -#define GL_OBJECT_VALIDATE_STATUS_ARB 0x8B83 -#define GL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84 -#define GL_OBJECT_ATTACHED_OBJECTS_ARB 0x8B85 -#define GL_OBJECT_ACTIVE_UNIFORMS_ARB 0x8B86 -#define GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB 0x8B87 -#define GL_OBJECT_SHADER_SOURCE_LENGTH_ARB 0x8B88 -typedef void (APIENTRYP PFNGLDELETEOBJECTARBPROC) (GLhandleARB obj); -typedef GLhandleARB (APIENTRYP PFNGLGETHANDLEARBPROC) (GLenum pname); -typedef void (APIENTRYP PFNGLDETACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB attachedObj); -typedef GLhandleARB (APIENTRYP PFNGLCREATESHADEROBJECTARBPROC) (GLenum shaderType); -typedef void (APIENTRYP PFNGLSHADERSOURCEARBPROC) (GLhandleARB shaderObj, GLsizei count, const GLcharARB **string, const GLint *length); -typedef void (APIENTRYP PFNGLCOMPILESHADERARBPROC) (GLhandleARB shaderObj); -typedef GLhandleARB (APIENTRYP PFNGLCREATEPROGRAMOBJECTARBPROC) (void); -typedef void (APIENTRYP PFNGLATTACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB obj); -typedef void (APIENTRYP PFNGLLINKPROGRAMARBPROC) (GLhandleARB programObj); -typedef void (APIENTRYP PFNGLUSEPROGRAMOBJECTARBPROC) (GLhandleARB programObj); -typedef void (APIENTRYP PFNGLVALIDATEPROGRAMARBPROC) (GLhandleARB programObj); -typedef void (APIENTRYP PFNGLUNIFORM1FARBPROC) (GLint location, GLfloat v0); -typedef void (APIENTRYP PFNGLUNIFORM2FARBPROC) (GLint location, GLfloat v0, GLfloat v1); -typedef void (APIENTRYP PFNGLUNIFORM3FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); -typedef void (APIENTRYP PFNGLUNIFORM4FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); -typedef void (APIENTRYP PFNGLUNIFORM1IARBPROC) (GLint location, GLint v0); -typedef void (APIENTRYP PFNGLUNIFORM2IARBPROC) (GLint location, GLint v0, GLint v1); -typedef void (APIENTRYP PFNGLUNIFORM3IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2); -typedef void (APIENTRYP PFNGLUNIFORM4IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); -typedef void (APIENTRYP PFNGLUNIFORM1FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORM2FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORM3FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORM4FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORM1IVARBPROC) (GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLUNIFORM2IVARBPROC) (GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLUNIFORM3IVARBPROC) (GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLUNIFORM4IVARBPROC) (GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERFVARBPROC) (GLhandleARB obj, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERIVARBPROC) (GLhandleARB obj, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETINFOLOGARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog); -typedef void (APIENTRYP PFNGLGETATTACHEDOBJECTSARBPROC) (GLhandleARB containerObj, GLsizei maxCount, GLsizei *count, GLhandleARB *obj); -typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name); -typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); -typedef void (APIENTRYP PFNGLGETUNIFORMFVARBPROC) (GLhandleARB programObj, GLint location, GLfloat *params); -typedef void (APIENTRYP PFNGLGETUNIFORMIVARBPROC) (GLhandleARB programObj, GLint location, GLint *params); -typedef void (APIENTRYP PFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDeleteObjectARB (GLhandleARB obj); -GLAPI GLhandleARB APIENTRY glGetHandleARB (GLenum pname); -GLAPI void APIENTRY glDetachObjectARB (GLhandleARB containerObj, GLhandleARB attachedObj); -GLAPI GLhandleARB APIENTRY glCreateShaderObjectARB (GLenum shaderType); -GLAPI void APIENTRY glShaderSourceARB (GLhandleARB shaderObj, GLsizei count, const GLcharARB **string, const GLint *length); -GLAPI void APIENTRY glCompileShaderARB (GLhandleARB shaderObj); -GLAPI GLhandleARB APIENTRY glCreateProgramObjectARB (void); -GLAPI void APIENTRY glAttachObjectARB (GLhandleARB containerObj, GLhandleARB obj); -GLAPI void APIENTRY glLinkProgramARB (GLhandleARB programObj); -GLAPI void APIENTRY glUseProgramObjectARB (GLhandleARB programObj); -GLAPI void APIENTRY glValidateProgramARB (GLhandleARB programObj); -GLAPI void APIENTRY glUniform1fARB (GLint location, GLfloat v0); -GLAPI void APIENTRY glUniform2fARB (GLint location, GLfloat v0, GLfloat v1); -GLAPI void APIENTRY glUniform3fARB (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); -GLAPI void APIENTRY glUniform4fARB (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); -GLAPI void APIENTRY glUniform1iARB (GLint location, GLint v0); -GLAPI void APIENTRY glUniform2iARB (GLint location, GLint v0, GLint v1); -GLAPI void APIENTRY glUniform3iARB (GLint location, GLint v0, GLint v1, GLint v2); -GLAPI void APIENTRY glUniform4iARB (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); -GLAPI void APIENTRY glUniform1fvARB (GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glUniform2fvARB (GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glUniform3fvARB (GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glUniform4fvARB (GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glUniform1ivARB (GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glUniform2ivARB (GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glUniform3ivARB (GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glUniform4ivARB (GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glUniformMatrix2fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glUniformMatrix3fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glUniformMatrix4fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glGetObjectParameterfvARB (GLhandleARB obj, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetObjectParameterivARB (GLhandleARB obj, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetInfoLogARB (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog); -GLAPI void APIENTRY glGetAttachedObjectsARB (GLhandleARB containerObj, GLsizei maxCount, GLsizei *count, GLhandleARB *obj); -GLAPI GLint APIENTRY glGetUniformLocationARB (GLhandleARB programObj, const GLcharARB *name); -GLAPI void APIENTRY glGetActiveUniformARB (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); -GLAPI void APIENTRY glGetUniformfvARB (GLhandleARB programObj, GLint location, GLfloat *params); -GLAPI void APIENTRY glGetUniformivARB (GLhandleARB programObj, GLint location, GLint *params); -GLAPI void APIENTRY glGetShaderSourceARB (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source); -#endif -#endif /* GL_ARB_shader_objects */ - -#ifndef GL_ARB_shader_precision -#define GL_ARB_shader_precision 1 -#endif /* GL_ARB_shader_precision */ - -#ifndef GL_ARB_shader_stencil_export -#define GL_ARB_shader_stencil_export 1 -#endif /* GL_ARB_shader_stencil_export */ - -#ifndef GL_ARB_shader_storage_buffer_object -#define GL_ARB_shader_storage_buffer_object 1 -#endif /* GL_ARB_shader_storage_buffer_object */ - -#ifndef GL_ARB_shader_subroutine -#define GL_ARB_shader_subroutine 1 -#endif /* GL_ARB_shader_subroutine */ - -#ifndef GL_ARB_shader_texture_image_samples -#define GL_ARB_shader_texture_image_samples 1 -#endif /* GL_ARB_shader_texture_image_samples */ - -#ifndef GL_ARB_shader_texture_lod -#define GL_ARB_shader_texture_lod 1 -#endif /* GL_ARB_shader_texture_lod */ - -#ifndef GL_ARB_shading_language_100 -#define GL_ARB_shading_language_100 1 -#define GL_SHADING_LANGUAGE_VERSION_ARB 0x8B8C -#endif /* GL_ARB_shading_language_100 */ - -#ifndef GL_ARB_shading_language_420pack -#define GL_ARB_shading_language_420pack 1 -#endif /* GL_ARB_shading_language_420pack */ - -#ifndef GL_ARB_shading_language_include -#define GL_ARB_shading_language_include 1 -#define GL_SHADER_INCLUDE_ARB 0x8DAE -#define GL_NAMED_STRING_LENGTH_ARB 0x8DE9 -#define GL_NAMED_STRING_TYPE_ARB 0x8DEA -typedef void (APIENTRYP PFNGLNAMEDSTRINGARBPROC) (GLenum type, GLint namelen, const GLchar *name, GLint stringlen, const GLchar *string); -typedef void (APIENTRYP PFNGLDELETENAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name); -typedef void (APIENTRYP PFNGLCOMPILESHADERINCLUDEARBPROC) (GLuint shader, GLsizei count, const GLchar *const*path, const GLint *length); -typedef GLboolean (APIENTRYP PFNGLISNAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name); -typedef void (APIENTRYP PFNGLGETNAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name, GLsizei bufSize, GLint *stringlen, GLchar *string); -typedef void (APIENTRYP PFNGLGETNAMEDSTRINGIVARBPROC) (GLint namelen, const GLchar *name, GLenum pname, GLint *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glNamedStringARB (GLenum type, GLint namelen, const GLchar *name, GLint stringlen, const GLchar *string); -GLAPI void APIENTRY glDeleteNamedStringARB (GLint namelen, const GLchar *name); -GLAPI void APIENTRY glCompileShaderIncludeARB (GLuint shader, GLsizei count, const GLchar *const*path, const GLint *length); -GLAPI GLboolean APIENTRY glIsNamedStringARB (GLint namelen, const GLchar *name); -GLAPI void APIENTRY glGetNamedStringARB (GLint namelen, const GLchar *name, GLsizei bufSize, GLint *stringlen, GLchar *string); -GLAPI void APIENTRY glGetNamedStringivARB (GLint namelen, const GLchar *name, GLenum pname, GLint *params); -#endif -#endif /* GL_ARB_shading_language_include */ - -#ifndef GL_ARB_shading_language_packing -#define GL_ARB_shading_language_packing 1 -#endif /* GL_ARB_shading_language_packing */ - -#ifndef GL_ARB_shadow -#define GL_ARB_shadow 1 -#define GL_TEXTURE_COMPARE_MODE_ARB 0x884C -#define GL_TEXTURE_COMPARE_FUNC_ARB 0x884D -#define GL_COMPARE_R_TO_TEXTURE_ARB 0x884E -#endif /* GL_ARB_shadow */ - -#ifndef GL_ARB_shadow_ambient -#define GL_ARB_shadow_ambient 1 -#define GL_TEXTURE_COMPARE_FAIL_VALUE_ARB 0x80BF -#endif /* GL_ARB_shadow_ambient */ - -#ifndef GL_ARB_sparse_buffer -#define GL_ARB_sparse_buffer 1 -#define GL_SPARSE_STORAGE_BIT_ARB 0x0400 -#define GL_SPARSE_BUFFER_PAGE_SIZE_ARB 0x82F8 -typedef void (APIENTRYP PFNGLBUFFERPAGECOMMITMENTARBPROC) (GLenum target, GLintptr offset, GLsizei size, GLboolean commit); -typedef void (APIENTRYP PFNGLNAMEDBUFFERPAGECOMMITMENTEXTPROC) (GLuint buffer, GLintptr offset, GLsizei size, GLboolean commit); -typedef void (APIENTRYP PFNGLNAMEDBUFFERPAGECOMMITMENTARBPROC) (GLuint buffer, GLintptr offset, GLsizei size, GLboolean commit); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBufferPageCommitmentARB (GLenum target, GLintptr offset, GLsizei size, GLboolean commit); -GLAPI void APIENTRY glNamedBufferPageCommitmentEXT (GLuint buffer, GLintptr offset, GLsizei size, GLboolean commit); -GLAPI void APIENTRY glNamedBufferPageCommitmentARB (GLuint buffer, GLintptr offset, GLsizei size, GLboolean commit); -#endif -#endif /* GL_ARB_sparse_buffer */ - -#ifndef GL_ARB_sparse_texture -#define GL_ARB_sparse_texture 1 -#define GL_TEXTURE_SPARSE_ARB 0x91A6 -#define GL_VIRTUAL_PAGE_SIZE_INDEX_ARB 0x91A7 -#define GL_MIN_SPARSE_LEVEL_ARB 0x919B -#define GL_NUM_VIRTUAL_PAGE_SIZES_ARB 0x91A8 -#define GL_VIRTUAL_PAGE_SIZE_X_ARB 0x9195 -#define GL_VIRTUAL_PAGE_SIZE_Y_ARB 0x9196 -#define GL_VIRTUAL_PAGE_SIZE_Z_ARB 0x9197 -#define GL_MAX_SPARSE_TEXTURE_SIZE_ARB 0x9198 -#define GL_MAX_SPARSE_3D_TEXTURE_SIZE_ARB 0x9199 -#define GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_ARB 0x919A -#define GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_ARB 0x91A9 -typedef void (APIENTRYP PFNGLTEXPAGECOMMITMENTARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean resident); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTexPageCommitmentARB (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean resident); -#endif -#endif /* GL_ARB_sparse_texture */ - -#ifndef GL_ARB_stencil_texturing -#define GL_ARB_stencil_texturing 1 -#endif /* GL_ARB_stencil_texturing */ - -#ifndef GL_ARB_sync -#define GL_ARB_sync 1 -#endif /* GL_ARB_sync */ - -#ifndef GL_ARB_tessellation_shader -#define GL_ARB_tessellation_shader 1 -#endif /* GL_ARB_tessellation_shader */ - -#ifndef GL_ARB_texture_barrier -#define GL_ARB_texture_barrier 1 -#endif /* GL_ARB_texture_barrier */ - -#ifndef GL_ARB_texture_border_clamp -#define GL_ARB_texture_border_clamp 1 -#define GL_CLAMP_TO_BORDER_ARB 0x812D -#endif /* GL_ARB_texture_border_clamp */ - -#ifndef GL_ARB_texture_buffer_object -#define GL_ARB_texture_buffer_object 1 -#define GL_TEXTURE_BUFFER_ARB 0x8C2A -#define GL_MAX_TEXTURE_BUFFER_SIZE_ARB 0x8C2B -#define GL_TEXTURE_BINDING_BUFFER_ARB 0x8C2C -#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_ARB 0x8C2D -#define GL_TEXTURE_BUFFER_FORMAT_ARB 0x8C2E -typedef void (APIENTRYP PFNGLTEXBUFFERARBPROC) (GLenum target, GLenum internalformat, GLuint buffer); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTexBufferARB (GLenum target, GLenum internalformat, GLuint buffer); -#endif -#endif /* GL_ARB_texture_buffer_object */ - -#ifndef GL_ARB_texture_buffer_object_rgb32 -#define GL_ARB_texture_buffer_object_rgb32 1 -#endif /* GL_ARB_texture_buffer_object_rgb32 */ - -#ifndef GL_ARB_texture_buffer_range -#define GL_ARB_texture_buffer_range 1 -#endif /* GL_ARB_texture_buffer_range */ - -#ifndef GL_ARB_texture_compression -#define GL_ARB_texture_compression 1 -#define GL_COMPRESSED_ALPHA_ARB 0x84E9 -#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA -#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB -#define GL_COMPRESSED_INTENSITY_ARB 0x84EC -#define GL_COMPRESSED_RGB_ARB 0x84ED -#define GL_COMPRESSED_RGBA_ARB 0x84EE -#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF -#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0 -#define GL_TEXTURE_COMPRESSED_ARB 0x86A1 -#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2 -#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3 -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); -typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint level, void *img); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glCompressedTexImage3DARB (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); -GLAPI void APIENTRY glCompressedTexImage2DARB (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); -GLAPI void APIENTRY glCompressedTexImage1DARB (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data); -GLAPI void APIENTRY glCompressedTexSubImage3DARB (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); -GLAPI void APIENTRY glCompressedTexSubImage2DARB (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); -GLAPI void APIENTRY glCompressedTexSubImage1DARB (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); -GLAPI void APIENTRY glGetCompressedTexImageARB (GLenum target, GLint level, void *img); -#endif -#endif /* GL_ARB_texture_compression */ - -#ifndef GL_ARB_texture_compression_bptc -#define GL_ARB_texture_compression_bptc 1 -#define GL_COMPRESSED_RGBA_BPTC_UNORM_ARB 0x8E8C -#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D -#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E -#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F -#endif /* GL_ARB_texture_compression_bptc */ - -#ifndef GL_ARB_texture_compression_rgtc -#define GL_ARB_texture_compression_rgtc 1 -#endif /* GL_ARB_texture_compression_rgtc */ - -#ifndef GL_ARB_texture_cube_map -#define GL_ARB_texture_cube_map 1 -#define GL_NORMAL_MAP_ARB 0x8511 -#define GL_REFLECTION_MAP_ARB 0x8512 -#define GL_TEXTURE_CUBE_MAP_ARB 0x8513 -#define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A -#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B -#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C -#endif /* GL_ARB_texture_cube_map */ - -#ifndef GL_ARB_texture_cube_map_array -#define GL_ARB_texture_cube_map_array 1 -#define GL_TEXTURE_CUBE_MAP_ARRAY_ARB 0x9009 -#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_ARB 0x900A -#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB 0x900B -#define GL_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900C -#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB 0x900D -#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900E -#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900F -#endif /* GL_ARB_texture_cube_map_array */ - -#ifndef GL_ARB_texture_env_add -#define GL_ARB_texture_env_add 1 -#endif /* GL_ARB_texture_env_add */ - -#ifndef GL_ARB_texture_env_combine -#define GL_ARB_texture_env_combine 1 -#define GL_COMBINE_ARB 0x8570 -#define GL_COMBINE_RGB_ARB 0x8571 -#define GL_COMBINE_ALPHA_ARB 0x8572 -#define GL_SOURCE0_RGB_ARB 0x8580 -#define GL_SOURCE1_RGB_ARB 0x8581 -#define GL_SOURCE2_RGB_ARB 0x8582 -#define GL_SOURCE0_ALPHA_ARB 0x8588 -#define GL_SOURCE1_ALPHA_ARB 0x8589 -#define GL_SOURCE2_ALPHA_ARB 0x858A -#define GL_OPERAND0_RGB_ARB 0x8590 -#define GL_OPERAND1_RGB_ARB 0x8591 -#define GL_OPERAND2_RGB_ARB 0x8592 -#define GL_OPERAND0_ALPHA_ARB 0x8598 -#define GL_OPERAND1_ALPHA_ARB 0x8599 -#define GL_OPERAND2_ALPHA_ARB 0x859A -#define GL_RGB_SCALE_ARB 0x8573 -#define GL_ADD_SIGNED_ARB 0x8574 -#define GL_INTERPOLATE_ARB 0x8575 -#define GL_SUBTRACT_ARB 0x84E7 -#define GL_CONSTANT_ARB 0x8576 -#define GL_PRIMARY_COLOR_ARB 0x8577 -#define GL_PREVIOUS_ARB 0x8578 -#endif /* GL_ARB_texture_env_combine */ - -#ifndef GL_ARB_texture_env_crossbar -#define GL_ARB_texture_env_crossbar 1 -#endif /* GL_ARB_texture_env_crossbar */ - -#ifndef GL_ARB_texture_env_dot3 -#define GL_ARB_texture_env_dot3 1 -#define GL_DOT3_RGB_ARB 0x86AE -#define GL_DOT3_RGBA_ARB 0x86AF -#endif /* GL_ARB_texture_env_dot3 */ - -#ifndef GL_ARB_texture_float -#define GL_ARB_texture_float 1 -#define GL_TEXTURE_RED_TYPE_ARB 0x8C10 -#define GL_TEXTURE_GREEN_TYPE_ARB 0x8C11 -#define GL_TEXTURE_BLUE_TYPE_ARB 0x8C12 -#define GL_TEXTURE_ALPHA_TYPE_ARB 0x8C13 -#define GL_TEXTURE_LUMINANCE_TYPE_ARB 0x8C14 -#define GL_TEXTURE_INTENSITY_TYPE_ARB 0x8C15 -#define GL_TEXTURE_DEPTH_TYPE_ARB 0x8C16 -#define GL_UNSIGNED_NORMALIZED_ARB 0x8C17 -#define GL_RGBA32F_ARB 0x8814 -#define GL_RGB32F_ARB 0x8815 -#define GL_ALPHA32F_ARB 0x8816 -#define GL_INTENSITY32F_ARB 0x8817 -#define GL_LUMINANCE32F_ARB 0x8818 -#define GL_LUMINANCE_ALPHA32F_ARB 0x8819 -#define GL_RGBA16F_ARB 0x881A -#define GL_RGB16F_ARB 0x881B -#define GL_ALPHA16F_ARB 0x881C -#define GL_INTENSITY16F_ARB 0x881D -#define GL_LUMINANCE16F_ARB 0x881E -#define GL_LUMINANCE_ALPHA16F_ARB 0x881F -#endif /* GL_ARB_texture_float */ - -#ifndef GL_ARB_texture_gather -#define GL_ARB_texture_gather 1 -#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5E -#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5F -#define GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS_ARB 0x8F9F -#endif /* GL_ARB_texture_gather */ - -#ifndef GL_ARB_texture_mirror_clamp_to_edge -#define GL_ARB_texture_mirror_clamp_to_edge 1 -#endif /* GL_ARB_texture_mirror_clamp_to_edge */ - -#ifndef GL_ARB_texture_mirrored_repeat -#define GL_ARB_texture_mirrored_repeat 1 -#define GL_MIRRORED_REPEAT_ARB 0x8370 -#endif /* GL_ARB_texture_mirrored_repeat */ - -#ifndef GL_ARB_texture_multisample -#define GL_ARB_texture_multisample 1 -#endif /* GL_ARB_texture_multisample */ - -#ifndef GL_ARB_texture_non_power_of_two -#define GL_ARB_texture_non_power_of_two 1 -#endif /* GL_ARB_texture_non_power_of_two */ - -#ifndef GL_ARB_texture_query_levels -#define GL_ARB_texture_query_levels 1 -#endif /* GL_ARB_texture_query_levels */ - -#ifndef GL_ARB_texture_query_lod -#define GL_ARB_texture_query_lod 1 -#endif /* GL_ARB_texture_query_lod */ - -#ifndef GL_ARB_texture_rectangle -#define GL_ARB_texture_rectangle 1 -#define GL_TEXTURE_RECTANGLE_ARB 0x84F5 -#define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6 -#define GL_PROXY_TEXTURE_RECTANGLE_ARB 0x84F7 -#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8 -#endif /* GL_ARB_texture_rectangle */ - -#ifndef GL_ARB_texture_rg -#define GL_ARB_texture_rg 1 -#endif /* GL_ARB_texture_rg */ - -#ifndef GL_ARB_texture_rgb10_a2ui -#define GL_ARB_texture_rgb10_a2ui 1 -#endif /* GL_ARB_texture_rgb10_a2ui */ - -#ifndef GL_ARB_texture_stencil8 -#define GL_ARB_texture_stencil8 1 -#endif /* GL_ARB_texture_stencil8 */ - -#ifndef GL_ARB_texture_storage -#define GL_ARB_texture_storage 1 -#endif /* GL_ARB_texture_storage */ - -#ifndef GL_ARB_texture_storage_multisample -#define GL_ARB_texture_storage_multisample 1 -#endif /* GL_ARB_texture_storage_multisample */ - -#ifndef GL_ARB_texture_swizzle -#define GL_ARB_texture_swizzle 1 -#endif /* GL_ARB_texture_swizzle */ - -#ifndef GL_ARB_texture_view -#define GL_ARB_texture_view 1 -#endif /* GL_ARB_texture_view */ - -#ifndef GL_ARB_timer_query -#define GL_ARB_timer_query 1 -#endif /* GL_ARB_timer_query */ - -#ifndef GL_ARB_transform_feedback2 -#define GL_ARB_transform_feedback2 1 -#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23 -#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24 -#endif /* GL_ARB_transform_feedback2 */ - -#ifndef GL_ARB_transform_feedback3 -#define GL_ARB_transform_feedback3 1 -#endif /* GL_ARB_transform_feedback3 */ - -#ifndef GL_ARB_transform_feedback_instanced -#define GL_ARB_transform_feedback_instanced 1 -#endif /* GL_ARB_transform_feedback_instanced */ - -#ifndef GL_ARB_transform_feedback_overflow_query -#define GL_ARB_transform_feedback_overflow_query 1 -#define GL_TRANSFORM_FEEDBACK_OVERFLOW_ARB 0x82EC -#define GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW_ARB 0x82ED -#endif /* GL_ARB_transform_feedback_overflow_query */ - -#ifndef GL_ARB_transpose_matrix -#define GL_ARB_transpose_matrix 1 -#define GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3 -#define GL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4 -#define GL_TRANSPOSE_TEXTURE_MATRIX_ARB 0x84E5 -#define GL_TRANSPOSE_COLOR_MATRIX_ARB 0x84E6 -typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXFARBPROC) (const GLfloat *m); -typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXDARBPROC) (const GLdouble *m); -typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXFARBPROC) (const GLfloat *m); -typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXDARBPROC) (const GLdouble *m); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glLoadTransposeMatrixfARB (const GLfloat *m); -GLAPI void APIENTRY glLoadTransposeMatrixdARB (const GLdouble *m); -GLAPI void APIENTRY glMultTransposeMatrixfARB (const GLfloat *m); -GLAPI void APIENTRY glMultTransposeMatrixdARB (const GLdouble *m); -#endif -#endif /* GL_ARB_transpose_matrix */ - -#ifndef GL_ARB_uniform_buffer_object -#define GL_ARB_uniform_buffer_object 1 -#endif /* GL_ARB_uniform_buffer_object */ - -#ifndef GL_ARB_vertex_array_bgra -#define GL_ARB_vertex_array_bgra 1 -#endif /* GL_ARB_vertex_array_bgra */ - -#ifndef GL_ARB_vertex_array_object -#define GL_ARB_vertex_array_object 1 -#endif /* GL_ARB_vertex_array_object */ - -#ifndef GL_ARB_vertex_attrib_64bit -#define GL_ARB_vertex_attrib_64bit 1 -#endif /* GL_ARB_vertex_attrib_64bit */ - -#ifndef GL_ARB_vertex_attrib_binding -#define GL_ARB_vertex_attrib_binding 1 -#endif /* GL_ARB_vertex_attrib_binding */ - -#ifndef GL_ARB_vertex_blend -#define GL_ARB_vertex_blend 1 -#define GL_MAX_VERTEX_UNITS_ARB 0x86A4 -#define GL_ACTIVE_VERTEX_UNITS_ARB 0x86A5 -#define GL_WEIGHT_SUM_UNITY_ARB 0x86A6 -#define GL_VERTEX_BLEND_ARB 0x86A7 -#define GL_CURRENT_WEIGHT_ARB 0x86A8 -#define GL_WEIGHT_ARRAY_TYPE_ARB 0x86A9 -#define GL_WEIGHT_ARRAY_STRIDE_ARB 0x86AA -#define GL_WEIGHT_ARRAY_SIZE_ARB 0x86AB -#define GL_WEIGHT_ARRAY_POINTER_ARB 0x86AC -#define GL_WEIGHT_ARRAY_ARB 0x86AD -#define GL_MODELVIEW0_ARB 0x1700 -#define GL_MODELVIEW1_ARB 0x850A -#define GL_MODELVIEW2_ARB 0x8722 -#define GL_MODELVIEW3_ARB 0x8723 -#define GL_MODELVIEW4_ARB 0x8724 -#define GL_MODELVIEW5_ARB 0x8725 -#define GL_MODELVIEW6_ARB 0x8726 -#define GL_MODELVIEW7_ARB 0x8727 -#define GL_MODELVIEW8_ARB 0x8728 -#define GL_MODELVIEW9_ARB 0x8729 -#define GL_MODELVIEW10_ARB 0x872A -#define GL_MODELVIEW11_ARB 0x872B -#define GL_MODELVIEW12_ARB 0x872C -#define GL_MODELVIEW13_ARB 0x872D -#define GL_MODELVIEW14_ARB 0x872E -#define GL_MODELVIEW15_ARB 0x872F -#define GL_MODELVIEW16_ARB 0x8730 -#define GL_MODELVIEW17_ARB 0x8731 -#define GL_MODELVIEW18_ARB 0x8732 -#define GL_MODELVIEW19_ARB 0x8733 -#define GL_MODELVIEW20_ARB 0x8734 -#define GL_MODELVIEW21_ARB 0x8735 -#define GL_MODELVIEW22_ARB 0x8736 -#define GL_MODELVIEW23_ARB 0x8737 -#define GL_MODELVIEW24_ARB 0x8738 -#define GL_MODELVIEW25_ARB 0x8739 -#define GL_MODELVIEW26_ARB 0x873A -#define GL_MODELVIEW27_ARB 0x873B -#define GL_MODELVIEW28_ARB 0x873C -#define GL_MODELVIEW29_ARB 0x873D -#define GL_MODELVIEW30_ARB 0x873E -#define GL_MODELVIEW31_ARB 0x873F -typedef void (APIENTRYP PFNGLWEIGHTBVARBPROC) (GLint size, const GLbyte *weights); -typedef void (APIENTRYP PFNGLWEIGHTSVARBPROC) (GLint size, const GLshort *weights); -typedef void (APIENTRYP PFNGLWEIGHTIVARBPROC) (GLint size, const GLint *weights); -typedef void (APIENTRYP PFNGLWEIGHTFVARBPROC) (GLint size, const GLfloat *weights); -typedef void (APIENTRYP PFNGLWEIGHTDVARBPROC) (GLint size, const GLdouble *weights); -typedef void (APIENTRYP PFNGLWEIGHTUBVARBPROC) (GLint size, const GLubyte *weights); -typedef void (APIENTRYP PFNGLWEIGHTUSVARBPROC) (GLint size, const GLushort *weights); -typedef void (APIENTRYP PFNGLWEIGHTUIVARBPROC) (GLint size, const GLuint *weights); -typedef void (APIENTRYP PFNGLWEIGHTPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const void *pointer); -typedef void (APIENTRYP PFNGLVERTEXBLENDARBPROC) (GLint count); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glWeightbvARB (GLint size, const GLbyte *weights); -GLAPI void APIENTRY glWeightsvARB (GLint size, const GLshort *weights); -GLAPI void APIENTRY glWeightivARB (GLint size, const GLint *weights); -GLAPI void APIENTRY glWeightfvARB (GLint size, const GLfloat *weights); -GLAPI void APIENTRY glWeightdvARB (GLint size, const GLdouble *weights); -GLAPI void APIENTRY glWeightubvARB (GLint size, const GLubyte *weights); -GLAPI void APIENTRY glWeightusvARB (GLint size, const GLushort *weights); -GLAPI void APIENTRY glWeightuivARB (GLint size, const GLuint *weights); -GLAPI void APIENTRY glWeightPointerARB (GLint size, GLenum type, GLsizei stride, const void *pointer); -GLAPI void APIENTRY glVertexBlendARB (GLint count); -#endif -#endif /* GL_ARB_vertex_blend */ - -#ifndef GL_ARB_vertex_buffer_object -#define GL_ARB_vertex_buffer_object 1 -/* HACK: This is a workaround for gltypes.h on OS X 10.9 defining these types as - * long instead of ptrdiff_t - */ -#if defined(__APPLE__) -typedef long GLsizeiptrARB; -typedef long GLintptrARB; -#else -typedef ptrdiff_t GLsizeiptrARB; -typedef ptrdiff_t GLintptrARB; -#endif -#define GL_BUFFER_SIZE_ARB 0x8764 -#define GL_BUFFER_USAGE_ARB 0x8765 -#define GL_ARRAY_BUFFER_ARB 0x8892 -#define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893 -#define GL_ARRAY_BUFFER_BINDING_ARB 0x8894 -#define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895 -#define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896 -#define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897 -#define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898 -#define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899 -#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A -#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B -#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C -#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D -#define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E -#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F -#define GL_READ_ONLY_ARB 0x88B8 -#define GL_WRITE_ONLY_ARB 0x88B9 -#define GL_READ_WRITE_ARB 0x88BA -#define GL_BUFFER_ACCESS_ARB 0x88BB -#define GL_BUFFER_MAPPED_ARB 0x88BC -#define GL_BUFFER_MAP_POINTER_ARB 0x88BD -#define GL_STREAM_DRAW_ARB 0x88E0 -#define GL_STREAM_READ_ARB 0x88E1 -#define GL_STREAM_COPY_ARB 0x88E2 -#define GL_STATIC_DRAW_ARB 0x88E4 -#define GL_STATIC_READ_ARB 0x88E5 -#define GL_STATIC_COPY_ARB 0x88E6 -#define GL_DYNAMIC_DRAW_ARB 0x88E8 -#define GL_DYNAMIC_READ_ARB 0x88E9 -#define GL_DYNAMIC_COPY_ARB 0x88EA -typedef void (APIENTRYP PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer); -typedef void (APIENTRYP PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers); -typedef void (APIENTRYP PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers); -typedef GLboolean (APIENTRYP PFNGLISBUFFERARBPROC) (GLuint buffer); -typedef void (APIENTRYP PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const void *data, GLenum usage); -typedef void (APIENTRYP PFNGLBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const void *data); -typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, void *data); -typedef void *(APIENTRYP PFNGLMAPBUFFERARBPROC) (GLenum target, GLenum access); -typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERARBPROC) (GLenum target); -typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVARBPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVARBPROC) (GLenum target, GLenum pname, void **params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBindBufferARB (GLenum target, GLuint buffer); -GLAPI void APIENTRY glDeleteBuffersARB (GLsizei n, const GLuint *buffers); -GLAPI void APIENTRY glGenBuffersARB (GLsizei n, GLuint *buffers); -GLAPI GLboolean APIENTRY glIsBufferARB (GLuint buffer); -GLAPI void APIENTRY glBufferDataARB (GLenum target, GLsizeiptrARB size, const void *data, GLenum usage); -GLAPI void APIENTRY glBufferSubDataARB (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const void *data); -GLAPI void APIENTRY glGetBufferSubDataARB (GLenum target, GLintptrARB offset, GLsizeiptrARB size, void *data); -GLAPI void *APIENTRY glMapBufferARB (GLenum target, GLenum access); -GLAPI GLboolean APIENTRY glUnmapBufferARB (GLenum target); -GLAPI void APIENTRY glGetBufferParameterivARB (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetBufferPointervARB (GLenum target, GLenum pname, void **params); -#endif -#endif /* GL_ARB_vertex_buffer_object */ - -#ifndef GL_ARB_vertex_program -#define GL_ARB_vertex_program 1 -#define GL_COLOR_SUM_ARB 0x8458 -#define GL_VERTEX_PROGRAM_ARB 0x8620 -#define GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622 -#define GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623 -#define GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624 -#define GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625 -#define GL_CURRENT_VERTEX_ATTRIB_ARB 0x8626 -#define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642 -#define GL_VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643 -#define GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645 -#define GL_MAX_VERTEX_ATTRIBS_ARB 0x8869 -#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A -#define GL_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B0 -#define GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B1 -#define GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B2 -#define GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B3 -typedef void (APIENTRYP PFNGLVERTEXATTRIB1DARBPROC) (GLuint index, GLdouble x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVARBPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1FARBPROC) (GLuint index, GLfloat x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVARBPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1SARBPROC) (GLuint index, GLshort x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVARBPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2DARBPROC) (GLuint index, GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVARBPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2FARBPROC) (GLuint index, GLfloat x, GLfloat y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVARBPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2SARBPROC) (GLuint index, GLshort x, GLshort y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVARBPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVARBPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVARBPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVARBPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVARBPROC) (GLuint index, const GLbyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVARBPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVARBPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBARBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVARBPROC) (GLuint index, const GLubyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVARBPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVARBPROC) (GLuint index, const GLushort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVARBPROC) (GLuint index, const GLbyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVARBPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVARBPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVARBPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVARBPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVARBPROC) (GLuint index, const GLubyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVARBPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVARBPROC) (GLuint index, const GLushort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERARBPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); -typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); -typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVARBPROC) (GLuint index, GLenum pname, GLdouble *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVARBPROC) (GLuint index, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVARBPROC) (GLuint index, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVARBPROC) (GLuint index, GLenum pname, void **pointer); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexAttrib1dARB (GLuint index, GLdouble x); -GLAPI void APIENTRY glVertexAttrib1dvARB (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttrib1fARB (GLuint index, GLfloat x); -GLAPI void APIENTRY glVertexAttrib1fvARB (GLuint index, const GLfloat *v); -GLAPI void APIENTRY glVertexAttrib1sARB (GLuint index, GLshort x); -GLAPI void APIENTRY glVertexAttrib1svARB (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttrib2dARB (GLuint index, GLdouble x, GLdouble y); -GLAPI void APIENTRY glVertexAttrib2dvARB (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttrib2fARB (GLuint index, GLfloat x, GLfloat y); -GLAPI void APIENTRY glVertexAttrib2fvARB (GLuint index, const GLfloat *v); -GLAPI void APIENTRY glVertexAttrib2sARB (GLuint index, GLshort x, GLshort y); -GLAPI void APIENTRY glVertexAttrib2svARB (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttrib3dARB (GLuint index, GLdouble x, GLdouble y, GLdouble z); -GLAPI void APIENTRY glVertexAttrib3dvARB (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttrib3fARB (GLuint index, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glVertexAttrib3fvARB (GLuint index, const GLfloat *v); -GLAPI void APIENTRY glVertexAttrib3sARB (GLuint index, GLshort x, GLshort y, GLshort z); -GLAPI void APIENTRY glVertexAttrib3svARB (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttrib4NbvARB (GLuint index, const GLbyte *v); -GLAPI void APIENTRY glVertexAttrib4NivARB (GLuint index, const GLint *v); -GLAPI void APIENTRY glVertexAttrib4NsvARB (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttrib4NubARB (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); -GLAPI void APIENTRY glVertexAttrib4NubvARB (GLuint index, const GLubyte *v); -GLAPI void APIENTRY glVertexAttrib4NuivARB (GLuint index, const GLuint *v); -GLAPI void APIENTRY glVertexAttrib4NusvARB (GLuint index, const GLushort *v); -GLAPI void APIENTRY glVertexAttrib4bvARB (GLuint index, const GLbyte *v); -GLAPI void APIENTRY glVertexAttrib4dARB (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void APIENTRY glVertexAttrib4dvARB (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttrib4fARB (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI void APIENTRY glVertexAttrib4fvARB (GLuint index, const GLfloat *v); -GLAPI void APIENTRY glVertexAttrib4ivARB (GLuint index, const GLint *v); -GLAPI void APIENTRY glVertexAttrib4sARB (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); -GLAPI void APIENTRY glVertexAttrib4svARB (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttrib4ubvARB (GLuint index, const GLubyte *v); -GLAPI void APIENTRY glVertexAttrib4uivARB (GLuint index, const GLuint *v); -GLAPI void APIENTRY glVertexAttrib4usvARB (GLuint index, const GLushort *v); -GLAPI void APIENTRY glVertexAttribPointerARB (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); -GLAPI void APIENTRY glEnableVertexAttribArrayARB (GLuint index); -GLAPI void APIENTRY glDisableVertexAttribArrayARB (GLuint index); -GLAPI void APIENTRY glGetVertexAttribdvARB (GLuint index, GLenum pname, GLdouble *params); -GLAPI void APIENTRY glGetVertexAttribfvARB (GLuint index, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetVertexAttribivARB (GLuint index, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetVertexAttribPointervARB (GLuint index, GLenum pname, void **pointer); -#endif -#endif /* GL_ARB_vertex_program */ - -#ifndef GL_ARB_vertex_shader -#define GL_ARB_vertex_shader 1 -#define GL_VERTEX_SHADER_ARB 0x8B31 -#define GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB 0x8B4A -#define GL_MAX_VARYING_FLOATS_ARB 0x8B4B -#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C -#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB 0x8B4D -#define GL_OBJECT_ACTIVE_ATTRIBUTES_ARB 0x8B89 -#define GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A -typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONARBPROC) (GLhandleARB programObj, GLuint index, const GLcharARB *name); -typedef void (APIENTRYP PFNGLGETACTIVEATTRIBARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); -typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBindAttribLocationARB (GLhandleARB programObj, GLuint index, const GLcharARB *name); -GLAPI void APIENTRY glGetActiveAttribARB (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); -GLAPI GLint APIENTRY glGetAttribLocationARB (GLhandleARB programObj, const GLcharARB *name); -#endif -#endif /* GL_ARB_vertex_shader */ - -#ifndef GL_ARB_vertex_type_10f_11f_11f_rev -#define GL_ARB_vertex_type_10f_11f_11f_rev 1 -#endif /* GL_ARB_vertex_type_10f_11f_11f_rev */ - -#ifndef GL_ARB_vertex_type_2_10_10_10_rev -#define GL_ARB_vertex_type_2_10_10_10_rev 1 -#endif /* GL_ARB_vertex_type_2_10_10_10_rev */ - -#ifndef GL_ARB_viewport_array -#define GL_ARB_viewport_array 1 -#endif /* GL_ARB_viewport_array */ - -#ifndef GL_ARB_window_pos -#define GL_ARB_window_pos 1 -typedef void (APIENTRYP PFNGLWINDOWPOS2DARBPROC) (GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLWINDOWPOS2DVARBPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLWINDOWPOS2FARBPROC) (GLfloat x, GLfloat y); -typedef void (APIENTRYP PFNGLWINDOWPOS2FVARBPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLWINDOWPOS2IARBPROC) (GLint x, GLint y); -typedef void (APIENTRYP PFNGLWINDOWPOS2IVARBPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLWINDOWPOS2SARBPROC) (GLshort x, GLshort y); -typedef void (APIENTRYP PFNGLWINDOWPOS2SVARBPROC) (const GLshort *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3DARBPROC) (GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLWINDOWPOS3DVARBPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3FARBPROC) (GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLWINDOWPOS3FVARBPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3IARBPROC) (GLint x, GLint y, GLint z); -typedef void (APIENTRYP PFNGLWINDOWPOS3IVARBPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3SARBPROC) (GLshort x, GLshort y, GLshort z); -typedef void (APIENTRYP PFNGLWINDOWPOS3SVARBPROC) (const GLshort *v); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glWindowPos2dARB (GLdouble x, GLdouble y); -GLAPI void APIENTRY glWindowPos2dvARB (const GLdouble *v); -GLAPI void APIENTRY glWindowPos2fARB (GLfloat x, GLfloat y); -GLAPI void APIENTRY glWindowPos2fvARB (const GLfloat *v); -GLAPI void APIENTRY glWindowPos2iARB (GLint x, GLint y); -GLAPI void APIENTRY glWindowPos2ivARB (const GLint *v); -GLAPI void APIENTRY glWindowPos2sARB (GLshort x, GLshort y); -GLAPI void APIENTRY glWindowPos2svARB (const GLshort *v); -GLAPI void APIENTRY glWindowPos3dARB (GLdouble x, GLdouble y, GLdouble z); -GLAPI void APIENTRY glWindowPos3dvARB (const GLdouble *v); -GLAPI void APIENTRY glWindowPos3fARB (GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glWindowPos3fvARB (const GLfloat *v); -GLAPI void APIENTRY glWindowPos3iARB (GLint x, GLint y, GLint z); -GLAPI void APIENTRY glWindowPos3ivARB (const GLint *v); -GLAPI void APIENTRY glWindowPos3sARB (GLshort x, GLshort y, GLshort z); -GLAPI void APIENTRY glWindowPos3svARB (const GLshort *v); -#endif -#endif /* GL_ARB_window_pos */ - -#ifndef GL_KHR_blend_equation_advanced -#define GL_KHR_blend_equation_advanced 1 -#define GL_MULTIPLY_KHR 0x9294 -#define GL_SCREEN_KHR 0x9295 -#define GL_OVERLAY_KHR 0x9296 -#define GL_DARKEN_KHR 0x9297 -#define GL_LIGHTEN_KHR 0x9298 -#define GL_COLORDODGE_KHR 0x9299 -#define GL_COLORBURN_KHR 0x929A -#define GL_HARDLIGHT_KHR 0x929B -#define GL_SOFTLIGHT_KHR 0x929C -#define GL_DIFFERENCE_KHR 0x929E -#define GL_EXCLUSION_KHR 0x92A0 -#define GL_HSL_HUE_KHR 0x92AD -#define GL_HSL_SATURATION_KHR 0x92AE -#define GL_HSL_COLOR_KHR 0x92AF -#define GL_HSL_LUMINOSITY_KHR 0x92B0 -typedef void (APIENTRYP PFNGLBLENDBARRIERKHRPROC) (void); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendBarrierKHR (void); -#endif -#endif /* GL_KHR_blend_equation_advanced */ - -#ifndef GL_KHR_blend_equation_advanced_coherent -#define GL_KHR_blend_equation_advanced_coherent 1 -#define GL_BLEND_ADVANCED_COHERENT_KHR 0x9285 -#endif /* GL_KHR_blend_equation_advanced_coherent */ - -#ifndef GL_KHR_context_flush_control -#define GL_KHR_context_flush_control 1 -#endif /* GL_KHR_context_flush_control */ - -#ifndef GL_KHR_debug -#define GL_KHR_debug 1 -#endif /* GL_KHR_debug */ - -#ifndef GL_KHR_robust_buffer_access_behavior -#define GL_KHR_robust_buffer_access_behavior 1 -#endif /* GL_KHR_robust_buffer_access_behavior */ - -#ifndef GL_KHR_robustness -#define GL_KHR_robustness 1 -#define GL_CONTEXT_ROBUST_ACCESS 0x90F3 -#endif /* GL_KHR_robustness */ - -#ifndef GL_KHR_texture_compression_astc_hdr -#define GL_KHR_texture_compression_astc_hdr 1 -#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0 -#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1 -#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2 -#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3 -#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4 -#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5 -#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6 -#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7 -#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8 -#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9 -#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA -#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB -#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC -#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD -#endif /* GL_KHR_texture_compression_astc_hdr */ - -#ifndef GL_KHR_texture_compression_astc_ldr -#define GL_KHR_texture_compression_astc_ldr 1 -#endif /* GL_KHR_texture_compression_astc_ldr */ - -#ifndef GL_OES_byte_coordinates -#define GL_OES_byte_coordinates 1 -typedef void (APIENTRYP PFNGLMULTITEXCOORD1BOESPROC) (GLenum texture, GLbyte s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1BVOESPROC) (GLenum texture, const GLbyte *coords); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2BOESPROC) (GLenum texture, GLbyte s, GLbyte t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2BVOESPROC) (GLenum texture, const GLbyte *coords); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3BOESPROC) (GLenum texture, GLbyte s, GLbyte t, GLbyte r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3BVOESPROC) (GLenum texture, const GLbyte *coords); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4BOESPROC) (GLenum texture, GLbyte s, GLbyte t, GLbyte r, GLbyte q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4BVOESPROC) (GLenum texture, const GLbyte *coords); -typedef void (APIENTRYP PFNGLTEXCOORD1BOESPROC) (GLbyte s); -typedef void (APIENTRYP PFNGLTEXCOORD1BVOESPROC) (const GLbyte *coords); -typedef void (APIENTRYP PFNGLTEXCOORD2BOESPROC) (GLbyte s, GLbyte t); -typedef void (APIENTRYP PFNGLTEXCOORD2BVOESPROC) (const GLbyte *coords); -typedef void (APIENTRYP PFNGLTEXCOORD3BOESPROC) (GLbyte s, GLbyte t, GLbyte r); -typedef void (APIENTRYP PFNGLTEXCOORD3BVOESPROC) (const GLbyte *coords); -typedef void (APIENTRYP PFNGLTEXCOORD4BOESPROC) (GLbyte s, GLbyte t, GLbyte r, GLbyte q); -typedef void (APIENTRYP PFNGLTEXCOORD4BVOESPROC) (const GLbyte *coords); -typedef void (APIENTRYP PFNGLVERTEX2BOESPROC) (GLbyte x, GLbyte y); -typedef void (APIENTRYP PFNGLVERTEX2BVOESPROC) (const GLbyte *coords); -typedef void (APIENTRYP PFNGLVERTEX3BOESPROC) (GLbyte x, GLbyte y, GLbyte z); -typedef void (APIENTRYP PFNGLVERTEX3BVOESPROC) (const GLbyte *coords); -typedef void (APIENTRYP PFNGLVERTEX4BOESPROC) (GLbyte x, GLbyte y, GLbyte z, GLbyte w); -typedef void (APIENTRYP PFNGLVERTEX4BVOESPROC) (const GLbyte *coords); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glMultiTexCoord1bOES (GLenum texture, GLbyte s); -GLAPI void APIENTRY glMultiTexCoord1bvOES (GLenum texture, const GLbyte *coords); -GLAPI void APIENTRY glMultiTexCoord2bOES (GLenum texture, GLbyte s, GLbyte t); -GLAPI void APIENTRY glMultiTexCoord2bvOES (GLenum texture, const GLbyte *coords); -GLAPI void APIENTRY glMultiTexCoord3bOES (GLenum texture, GLbyte s, GLbyte t, GLbyte r); -GLAPI void APIENTRY glMultiTexCoord3bvOES (GLenum texture, const GLbyte *coords); -GLAPI void APIENTRY glMultiTexCoord4bOES (GLenum texture, GLbyte s, GLbyte t, GLbyte r, GLbyte q); -GLAPI void APIENTRY glMultiTexCoord4bvOES (GLenum texture, const GLbyte *coords); -GLAPI void APIENTRY glTexCoord1bOES (GLbyte s); -GLAPI void APIENTRY glTexCoord1bvOES (const GLbyte *coords); -GLAPI void APIENTRY glTexCoord2bOES (GLbyte s, GLbyte t); -GLAPI void APIENTRY glTexCoord2bvOES (const GLbyte *coords); -GLAPI void APIENTRY glTexCoord3bOES (GLbyte s, GLbyte t, GLbyte r); -GLAPI void APIENTRY glTexCoord3bvOES (const GLbyte *coords); -GLAPI void APIENTRY glTexCoord4bOES (GLbyte s, GLbyte t, GLbyte r, GLbyte q); -GLAPI void APIENTRY glTexCoord4bvOES (const GLbyte *coords); -GLAPI void APIENTRY glVertex2bOES (GLbyte x, GLbyte y); -GLAPI void APIENTRY glVertex2bvOES (const GLbyte *coords); -GLAPI void APIENTRY glVertex3bOES (GLbyte x, GLbyte y, GLbyte z); -GLAPI void APIENTRY glVertex3bvOES (const GLbyte *coords); -GLAPI void APIENTRY glVertex4bOES (GLbyte x, GLbyte y, GLbyte z, GLbyte w); -GLAPI void APIENTRY glVertex4bvOES (const GLbyte *coords); -#endif -#endif /* GL_OES_byte_coordinates */ - -#ifndef GL_OES_compressed_paletted_texture -#define GL_OES_compressed_paletted_texture 1 -#define GL_PALETTE4_RGB8_OES 0x8B90 -#define GL_PALETTE4_RGBA8_OES 0x8B91 -#define GL_PALETTE4_R5_G6_B5_OES 0x8B92 -#define GL_PALETTE4_RGBA4_OES 0x8B93 -#define GL_PALETTE4_RGB5_A1_OES 0x8B94 -#define GL_PALETTE8_RGB8_OES 0x8B95 -#define GL_PALETTE8_RGBA8_OES 0x8B96 -#define GL_PALETTE8_R5_G6_B5_OES 0x8B97 -#define GL_PALETTE8_RGBA4_OES 0x8B98 -#define GL_PALETTE8_RGB5_A1_OES 0x8B99 -#endif /* GL_OES_compressed_paletted_texture */ - -#ifndef GL_OES_fixed_point -#define GL_OES_fixed_point 1 -typedef GLint GLfixed; -#define GL_FIXED_OES 0x140C -typedef void (APIENTRYP PFNGLALPHAFUNCXOESPROC) (GLenum func, GLfixed ref); -typedef void (APIENTRYP PFNGLCLEARCOLORXOESPROC) (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); -typedef void (APIENTRYP PFNGLCLEARDEPTHXOESPROC) (GLfixed depth); -typedef void (APIENTRYP PFNGLCLIPPLANEXOESPROC) (GLenum plane, const GLfixed *equation); -typedef void (APIENTRYP PFNGLCOLOR4XOESPROC) (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); -typedef void (APIENTRYP PFNGLDEPTHRANGEXOESPROC) (GLfixed n, GLfixed f); -typedef void (APIENTRYP PFNGLFOGXOESPROC) (GLenum pname, GLfixed param); -typedef void (APIENTRYP PFNGLFOGXVOESPROC) (GLenum pname, const GLfixed *param); -typedef void (APIENTRYP PFNGLFRUSTUMXOESPROC) (GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f); -typedef void (APIENTRYP PFNGLGETCLIPPLANEXOESPROC) (GLenum plane, GLfixed *equation); -typedef void (APIENTRYP PFNGLGETFIXEDVOESPROC) (GLenum pname, GLfixed *params); -typedef void (APIENTRYP PFNGLGETTEXENVXVOESPROC) (GLenum target, GLenum pname, GLfixed *params); -typedef void (APIENTRYP PFNGLGETTEXPARAMETERXVOESPROC) (GLenum target, GLenum pname, GLfixed *params); -typedef void (APIENTRYP PFNGLLIGHTMODELXOESPROC) (GLenum pname, GLfixed param); -typedef void (APIENTRYP PFNGLLIGHTMODELXVOESPROC) (GLenum pname, const GLfixed *param); -typedef void (APIENTRYP PFNGLLIGHTXOESPROC) (GLenum light, GLenum pname, GLfixed param); -typedef void (APIENTRYP PFNGLLIGHTXVOESPROC) (GLenum light, GLenum pname, const GLfixed *params); -typedef void (APIENTRYP PFNGLLINEWIDTHXOESPROC) (GLfixed width); -typedef void (APIENTRYP PFNGLLOADMATRIXXOESPROC) (const GLfixed *m); -typedef void (APIENTRYP PFNGLMATERIALXOESPROC) (GLenum face, GLenum pname, GLfixed param); -typedef void (APIENTRYP PFNGLMATERIALXVOESPROC) (GLenum face, GLenum pname, const GLfixed *param); -typedef void (APIENTRYP PFNGLMULTMATRIXXOESPROC) (const GLfixed *m); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4XOESPROC) (GLenum texture, GLfixed s, GLfixed t, GLfixed r, GLfixed q); -typedef void (APIENTRYP PFNGLNORMAL3XOESPROC) (GLfixed nx, GLfixed ny, GLfixed nz); -typedef void (APIENTRYP PFNGLORTHOXOESPROC) (GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f); -typedef void (APIENTRYP PFNGLPOINTPARAMETERXVOESPROC) (GLenum pname, const GLfixed *params); -typedef void (APIENTRYP PFNGLPOINTSIZEXOESPROC) (GLfixed size); -typedef void (APIENTRYP PFNGLPOLYGONOFFSETXOESPROC) (GLfixed factor, GLfixed units); -typedef void (APIENTRYP PFNGLROTATEXOESPROC) (GLfixed angle, GLfixed x, GLfixed y, GLfixed z); -typedef void (APIENTRYP PFNGLSAMPLECOVERAGEOESPROC) (GLfixed value, GLboolean invert); -typedef void (APIENTRYP PFNGLSCALEXOESPROC) (GLfixed x, GLfixed y, GLfixed z); -typedef void (APIENTRYP PFNGLTEXENVXOESPROC) (GLenum target, GLenum pname, GLfixed param); -typedef void (APIENTRYP PFNGLTEXENVXVOESPROC) (GLenum target, GLenum pname, const GLfixed *params); -typedef void (APIENTRYP PFNGLTEXPARAMETERXOESPROC) (GLenum target, GLenum pname, GLfixed param); -typedef void (APIENTRYP PFNGLTEXPARAMETERXVOESPROC) (GLenum target, GLenum pname, const GLfixed *params); -typedef void (APIENTRYP PFNGLTRANSLATEXOESPROC) (GLfixed x, GLfixed y, GLfixed z); -typedef void (APIENTRYP PFNGLACCUMXOESPROC) (GLenum op, GLfixed value); -typedef void (APIENTRYP PFNGLBITMAPXOESPROC) (GLsizei width, GLsizei height, GLfixed xorig, GLfixed yorig, GLfixed xmove, GLfixed ymove, const GLubyte *bitmap); -typedef void (APIENTRYP PFNGLBLENDCOLORXOESPROC) (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); -typedef void (APIENTRYP PFNGLCLEARACCUMXOESPROC) (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); -typedef void (APIENTRYP PFNGLCOLOR3XOESPROC) (GLfixed red, GLfixed green, GLfixed blue); -typedef void (APIENTRYP PFNGLCOLOR3XVOESPROC) (const GLfixed *components); -typedef void (APIENTRYP PFNGLCOLOR4XVOESPROC) (const GLfixed *components); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERXOESPROC) (GLenum target, GLenum pname, GLfixed param); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERXVOESPROC) (GLenum target, GLenum pname, const GLfixed *params); -typedef void (APIENTRYP PFNGLEVALCOORD1XOESPROC) (GLfixed u); -typedef void (APIENTRYP PFNGLEVALCOORD1XVOESPROC) (const GLfixed *coords); -typedef void (APIENTRYP PFNGLEVALCOORD2XOESPROC) (GLfixed u, GLfixed v); -typedef void (APIENTRYP PFNGLEVALCOORD2XVOESPROC) (const GLfixed *coords); -typedef void (APIENTRYP PFNGLFEEDBACKBUFFERXOESPROC) (GLsizei n, GLenum type, const GLfixed *buffer); -typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERXVOESPROC) (GLenum target, GLenum pname, GLfixed *params); -typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERXVOESPROC) (GLenum target, GLenum pname, GLfixed *params); -typedef void (APIENTRYP PFNGLGETLIGHTXOESPROC) (GLenum light, GLenum pname, GLfixed *params); -typedef void (APIENTRYP PFNGLGETMAPXVOESPROC) (GLenum target, GLenum query, GLfixed *v); -typedef void (APIENTRYP PFNGLGETMATERIALXOESPROC) (GLenum face, GLenum pname, GLfixed param); -typedef void (APIENTRYP PFNGLGETPIXELMAPXVPROC) (GLenum map, GLint size, GLfixed *values); -typedef void (APIENTRYP PFNGLGETTEXGENXVOESPROC) (GLenum coord, GLenum pname, GLfixed *params); -typedef void (APIENTRYP PFNGLGETTEXLEVELPARAMETERXVOESPROC) (GLenum target, GLint level, GLenum pname, GLfixed *params); -typedef void (APIENTRYP PFNGLINDEXXOESPROC) (GLfixed component); -typedef void (APIENTRYP PFNGLINDEXXVOESPROC) (const GLfixed *component); -typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXXOESPROC) (const GLfixed *m); -typedef void (APIENTRYP PFNGLMAP1XOESPROC) (GLenum target, GLfixed u1, GLfixed u2, GLint stride, GLint order, GLfixed points); -typedef void (APIENTRYP PFNGLMAP2XOESPROC) (GLenum target, GLfixed u1, GLfixed u2, GLint ustride, GLint uorder, GLfixed v1, GLfixed v2, GLint vstride, GLint vorder, GLfixed points); -typedef void (APIENTRYP PFNGLMAPGRID1XOESPROC) (GLint n, GLfixed u1, GLfixed u2); -typedef void (APIENTRYP PFNGLMAPGRID2XOESPROC) (GLint n, GLfixed u1, GLfixed u2, GLfixed v1, GLfixed v2); -typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXXOESPROC) (const GLfixed *m); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1XOESPROC) (GLenum texture, GLfixed s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1XVOESPROC) (GLenum texture, const GLfixed *coords); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2XOESPROC) (GLenum texture, GLfixed s, GLfixed t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2XVOESPROC) (GLenum texture, const GLfixed *coords); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3XOESPROC) (GLenum texture, GLfixed s, GLfixed t, GLfixed r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3XVOESPROC) (GLenum texture, const GLfixed *coords); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4XVOESPROC) (GLenum texture, const GLfixed *coords); -typedef void (APIENTRYP PFNGLNORMAL3XVOESPROC) (const GLfixed *coords); -typedef void (APIENTRYP PFNGLPASSTHROUGHXOESPROC) (GLfixed token); -typedef void (APIENTRYP PFNGLPIXELMAPXPROC) (GLenum map, GLint size, const GLfixed *values); -typedef void (APIENTRYP PFNGLPIXELSTOREXPROC) (GLenum pname, GLfixed param); -typedef void (APIENTRYP PFNGLPIXELTRANSFERXOESPROC) (GLenum pname, GLfixed param); -typedef void (APIENTRYP PFNGLPIXELZOOMXOESPROC) (GLfixed xfactor, GLfixed yfactor); -typedef void (APIENTRYP PFNGLPRIORITIZETEXTURESXOESPROC) (GLsizei n, const GLuint *textures, const GLfixed *priorities); -typedef void (APIENTRYP PFNGLRASTERPOS2XOESPROC) (GLfixed x, GLfixed y); -typedef void (APIENTRYP PFNGLRASTERPOS2XVOESPROC) (const GLfixed *coords); -typedef void (APIENTRYP PFNGLRASTERPOS3XOESPROC) (GLfixed x, GLfixed y, GLfixed z); -typedef void (APIENTRYP PFNGLRASTERPOS3XVOESPROC) (const GLfixed *coords); -typedef void (APIENTRYP PFNGLRASTERPOS4XOESPROC) (GLfixed x, GLfixed y, GLfixed z, GLfixed w); -typedef void (APIENTRYP PFNGLRASTERPOS4XVOESPROC) (const GLfixed *coords); -typedef void (APIENTRYP PFNGLRECTXOESPROC) (GLfixed x1, GLfixed y1, GLfixed x2, GLfixed y2); -typedef void (APIENTRYP PFNGLRECTXVOESPROC) (const GLfixed *v1, const GLfixed *v2); -typedef void (APIENTRYP PFNGLTEXCOORD1XOESPROC) (GLfixed s); -typedef void (APIENTRYP PFNGLTEXCOORD1XVOESPROC) (const GLfixed *coords); -typedef void (APIENTRYP PFNGLTEXCOORD2XOESPROC) (GLfixed s, GLfixed t); -typedef void (APIENTRYP PFNGLTEXCOORD2XVOESPROC) (const GLfixed *coords); -typedef void (APIENTRYP PFNGLTEXCOORD3XOESPROC) (GLfixed s, GLfixed t, GLfixed r); -typedef void (APIENTRYP PFNGLTEXCOORD3XVOESPROC) (const GLfixed *coords); -typedef void (APIENTRYP PFNGLTEXCOORD4XOESPROC) (GLfixed s, GLfixed t, GLfixed r, GLfixed q); -typedef void (APIENTRYP PFNGLTEXCOORD4XVOESPROC) (const GLfixed *coords); -typedef void (APIENTRYP PFNGLTEXGENXOESPROC) (GLenum coord, GLenum pname, GLfixed param); -typedef void (APIENTRYP PFNGLTEXGENXVOESPROC) (GLenum coord, GLenum pname, const GLfixed *params); -typedef void (APIENTRYP PFNGLVERTEX2XOESPROC) (GLfixed x); -typedef void (APIENTRYP PFNGLVERTEX2XVOESPROC) (const GLfixed *coords); -typedef void (APIENTRYP PFNGLVERTEX3XOESPROC) (GLfixed x, GLfixed y); -typedef void (APIENTRYP PFNGLVERTEX3XVOESPROC) (const GLfixed *coords); -typedef void (APIENTRYP PFNGLVERTEX4XOESPROC) (GLfixed x, GLfixed y, GLfixed z); -typedef void (APIENTRYP PFNGLVERTEX4XVOESPROC) (const GLfixed *coords); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glAlphaFuncxOES (GLenum func, GLfixed ref); -GLAPI void APIENTRY glClearColorxOES (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); -GLAPI void APIENTRY glClearDepthxOES (GLfixed depth); -GLAPI void APIENTRY glClipPlanexOES (GLenum plane, const GLfixed *equation); -GLAPI void APIENTRY glColor4xOES (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); -GLAPI void APIENTRY glDepthRangexOES (GLfixed n, GLfixed f); -GLAPI void APIENTRY glFogxOES (GLenum pname, GLfixed param); -GLAPI void APIENTRY glFogxvOES (GLenum pname, const GLfixed *param); -GLAPI void APIENTRY glFrustumxOES (GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f); -GLAPI void APIENTRY glGetClipPlanexOES (GLenum plane, GLfixed *equation); -GLAPI void APIENTRY glGetFixedvOES (GLenum pname, GLfixed *params); -GLAPI void APIENTRY glGetTexEnvxvOES (GLenum target, GLenum pname, GLfixed *params); -GLAPI void APIENTRY glGetTexParameterxvOES (GLenum target, GLenum pname, GLfixed *params); -GLAPI void APIENTRY glLightModelxOES (GLenum pname, GLfixed param); -GLAPI void APIENTRY glLightModelxvOES (GLenum pname, const GLfixed *param); -GLAPI void APIENTRY glLightxOES (GLenum light, GLenum pname, GLfixed param); -GLAPI void APIENTRY glLightxvOES (GLenum light, GLenum pname, const GLfixed *params); -GLAPI void APIENTRY glLineWidthxOES (GLfixed width); -GLAPI void APIENTRY glLoadMatrixxOES (const GLfixed *m); -GLAPI void APIENTRY glMaterialxOES (GLenum face, GLenum pname, GLfixed param); -GLAPI void APIENTRY glMaterialxvOES (GLenum face, GLenum pname, const GLfixed *param); -GLAPI void APIENTRY glMultMatrixxOES (const GLfixed *m); -GLAPI void APIENTRY glMultiTexCoord4xOES (GLenum texture, GLfixed s, GLfixed t, GLfixed r, GLfixed q); -GLAPI void APIENTRY glNormal3xOES (GLfixed nx, GLfixed ny, GLfixed nz); -GLAPI void APIENTRY glOrthoxOES (GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f); -GLAPI void APIENTRY glPointParameterxvOES (GLenum pname, const GLfixed *params); -GLAPI void APIENTRY glPointSizexOES (GLfixed size); -GLAPI void APIENTRY glPolygonOffsetxOES (GLfixed factor, GLfixed units); -GLAPI void APIENTRY glRotatexOES (GLfixed angle, GLfixed x, GLfixed y, GLfixed z); -GLAPI void APIENTRY glSampleCoverageOES (GLfixed value, GLboolean invert); -GLAPI void APIENTRY glScalexOES (GLfixed x, GLfixed y, GLfixed z); -GLAPI void APIENTRY glTexEnvxOES (GLenum target, GLenum pname, GLfixed param); -GLAPI void APIENTRY glTexEnvxvOES (GLenum target, GLenum pname, const GLfixed *params); -GLAPI void APIENTRY glTexParameterxOES (GLenum target, GLenum pname, GLfixed param); -GLAPI void APIENTRY glTexParameterxvOES (GLenum target, GLenum pname, const GLfixed *params); -GLAPI void APIENTRY glTranslatexOES (GLfixed x, GLfixed y, GLfixed z); -GLAPI void APIENTRY glAccumxOES (GLenum op, GLfixed value); -GLAPI void APIENTRY glBitmapxOES (GLsizei width, GLsizei height, GLfixed xorig, GLfixed yorig, GLfixed xmove, GLfixed ymove, const GLubyte *bitmap); -GLAPI void APIENTRY glBlendColorxOES (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); -GLAPI void APIENTRY glClearAccumxOES (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); -GLAPI void APIENTRY glColor3xOES (GLfixed red, GLfixed green, GLfixed blue); -GLAPI void APIENTRY glColor3xvOES (const GLfixed *components); -GLAPI void APIENTRY glColor4xvOES (const GLfixed *components); -GLAPI void APIENTRY glConvolutionParameterxOES (GLenum target, GLenum pname, GLfixed param); -GLAPI void APIENTRY glConvolutionParameterxvOES (GLenum target, GLenum pname, const GLfixed *params); -GLAPI void APIENTRY glEvalCoord1xOES (GLfixed u); -GLAPI void APIENTRY glEvalCoord1xvOES (const GLfixed *coords); -GLAPI void APIENTRY glEvalCoord2xOES (GLfixed u, GLfixed v); -GLAPI void APIENTRY glEvalCoord2xvOES (const GLfixed *coords); -GLAPI void APIENTRY glFeedbackBufferxOES (GLsizei n, GLenum type, const GLfixed *buffer); -GLAPI void APIENTRY glGetConvolutionParameterxvOES (GLenum target, GLenum pname, GLfixed *params); -GLAPI void APIENTRY glGetHistogramParameterxvOES (GLenum target, GLenum pname, GLfixed *params); -GLAPI void APIENTRY glGetLightxOES (GLenum light, GLenum pname, GLfixed *params); -GLAPI void APIENTRY glGetMapxvOES (GLenum target, GLenum query, GLfixed *v); -GLAPI void APIENTRY glGetMaterialxOES (GLenum face, GLenum pname, GLfixed param); -GLAPI void APIENTRY glGetPixelMapxv (GLenum map, GLint size, GLfixed *values); -GLAPI void APIENTRY glGetTexGenxvOES (GLenum coord, GLenum pname, GLfixed *params); -GLAPI void APIENTRY glGetTexLevelParameterxvOES (GLenum target, GLint level, GLenum pname, GLfixed *params); -GLAPI void APIENTRY glIndexxOES (GLfixed component); -GLAPI void APIENTRY glIndexxvOES (const GLfixed *component); -GLAPI void APIENTRY glLoadTransposeMatrixxOES (const GLfixed *m); -GLAPI void APIENTRY glMap1xOES (GLenum target, GLfixed u1, GLfixed u2, GLint stride, GLint order, GLfixed points); -GLAPI void APIENTRY glMap2xOES (GLenum target, GLfixed u1, GLfixed u2, GLint ustride, GLint uorder, GLfixed v1, GLfixed v2, GLint vstride, GLint vorder, GLfixed points); -GLAPI void APIENTRY glMapGrid1xOES (GLint n, GLfixed u1, GLfixed u2); -GLAPI void APIENTRY glMapGrid2xOES (GLint n, GLfixed u1, GLfixed u2, GLfixed v1, GLfixed v2); -GLAPI void APIENTRY glMultTransposeMatrixxOES (const GLfixed *m); -GLAPI void APIENTRY glMultiTexCoord1xOES (GLenum texture, GLfixed s); -GLAPI void APIENTRY glMultiTexCoord1xvOES (GLenum texture, const GLfixed *coords); -GLAPI void APIENTRY glMultiTexCoord2xOES (GLenum texture, GLfixed s, GLfixed t); -GLAPI void APIENTRY glMultiTexCoord2xvOES (GLenum texture, const GLfixed *coords); -GLAPI void APIENTRY glMultiTexCoord3xOES (GLenum texture, GLfixed s, GLfixed t, GLfixed r); -GLAPI void APIENTRY glMultiTexCoord3xvOES (GLenum texture, const GLfixed *coords); -GLAPI void APIENTRY glMultiTexCoord4xvOES (GLenum texture, const GLfixed *coords); -GLAPI void APIENTRY glNormal3xvOES (const GLfixed *coords); -GLAPI void APIENTRY glPassThroughxOES (GLfixed token); -GLAPI void APIENTRY glPixelMapx (GLenum map, GLint size, const GLfixed *values); -GLAPI void APIENTRY glPixelStorex (GLenum pname, GLfixed param); -GLAPI void APIENTRY glPixelTransferxOES (GLenum pname, GLfixed param); -GLAPI void APIENTRY glPixelZoomxOES (GLfixed xfactor, GLfixed yfactor); -GLAPI void APIENTRY glPrioritizeTexturesxOES (GLsizei n, const GLuint *textures, const GLfixed *priorities); -GLAPI void APIENTRY glRasterPos2xOES (GLfixed x, GLfixed y); -GLAPI void APIENTRY glRasterPos2xvOES (const GLfixed *coords); -GLAPI void APIENTRY glRasterPos3xOES (GLfixed x, GLfixed y, GLfixed z); -GLAPI void APIENTRY glRasterPos3xvOES (const GLfixed *coords); -GLAPI void APIENTRY glRasterPos4xOES (GLfixed x, GLfixed y, GLfixed z, GLfixed w); -GLAPI void APIENTRY glRasterPos4xvOES (const GLfixed *coords); -GLAPI void APIENTRY glRectxOES (GLfixed x1, GLfixed y1, GLfixed x2, GLfixed y2); -GLAPI void APIENTRY glRectxvOES (const GLfixed *v1, const GLfixed *v2); -GLAPI void APIENTRY glTexCoord1xOES (GLfixed s); -GLAPI void APIENTRY glTexCoord1xvOES (const GLfixed *coords); -GLAPI void APIENTRY glTexCoord2xOES (GLfixed s, GLfixed t); -GLAPI void APIENTRY glTexCoord2xvOES (const GLfixed *coords); -GLAPI void APIENTRY glTexCoord3xOES (GLfixed s, GLfixed t, GLfixed r); -GLAPI void APIENTRY glTexCoord3xvOES (const GLfixed *coords); -GLAPI void APIENTRY glTexCoord4xOES (GLfixed s, GLfixed t, GLfixed r, GLfixed q); -GLAPI void APIENTRY glTexCoord4xvOES (const GLfixed *coords); -GLAPI void APIENTRY glTexGenxOES (GLenum coord, GLenum pname, GLfixed param); -GLAPI void APIENTRY glTexGenxvOES (GLenum coord, GLenum pname, const GLfixed *params); -GLAPI void APIENTRY glVertex2xOES (GLfixed x); -GLAPI void APIENTRY glVertex2xvOES (const GLfixed *coords); -GLAPI void APIENTRY glVertex3xOES (GLfixed x, GLfixed y); -GLAPI void APIENTRY glVertex3xvOES (const GLfixed *coords); -GLAPI void APIENTRY glVertex4xOES (GLfixed x, GLfixed y, GLfixed z); -GLAPI void APIENTRY glVertex4xvOES (const GLfixed *coords); -#endif -#endif /* GL_OES_fixed_point */ - -#ifndef GL_OES_query_matrix -#define GL_OES_query_matrix 1 -typedef GLbitfield (APIENTRYP PFNGLQUERYMATRIXXOESPROC) (GLfixed *mantissa, GLint *exponent); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLbitfield APIENTRY glQueryMatrixxOES (GLfixed *mantissa, GLint *exponent); -#endif -#endif /* GL_OES_query_matrix */ - -#ifndef GL_OES_read_format -#define GL_OES_read_format 1 -#define GL_IMPLEMENTATION_COLOR_READ_TYPE_OES 0x8B9A -#define GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES 0x8B9B -#endif /* GL_OES_read_format */ - -#ifndef GL_OES_single_precision -#define GL_OES_single_precision 1 -typedef void (APIENTRYP PFNGLCLEARDEPTHFOESPROC) (GLclampf depth); -typedef void (APIENTRYP PFNGLCLIPPLANEFOESPROC) (GLenum plane, const GLfloat *equation); -typedef void (APIENTRYP PFNGLDEPTHRANGEFOESPROC) (GLclampf n, GLclampf f); -typedef void (APIENTRYP PFNGLFRUSTUMFOESPROC) (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); -typedef void (APIENTRYP PFNGLGETCLIPPLANEFOESPROC) (GLenum plane, GLfloat *equation); -typedef void (APIENTRYP PFNGLORTHOFOESPROC) (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glClearDepthfOES (GLclampf depth); -GLAPI void APIENTRY glClipPlanefOES (GLenum plane, const GLfloat *equation); -GLAPI void APIENTRY glDepthRangefOES (GLclampf n, GLclampf f); -GLAPI void APIENTRY glFrustumfOES (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); -GLAPI void APIENTRY glGetClipPlanefOES (GLenum plane, GLfloat *equation); -GLAPI void APIENTRY glOrthofOES (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); -#endif -#endif /* GL_OES_single_precision */ - -#ifndef GL_3DFX_multisample -#define GL_3DFX_multisample 1 -#define GL_MULTISAMPLE_3DFX 0x86B2 -#define GL_SAMPLE_BUFFERS_3DFX 0x86B3 -#define GL_SAMPLES_3DFX 0x86B4 -#define GL_MULTISAMPLE_BIT_3DFX 0x20000000 -#endif /* GL_3DFX_multisample */ - -#ifndef GL_3DFX_tbuffer -#define GL_3DFX_tbuffer 1 -typedef void (APIENTRYP PFNGLTBUFFERMASK3DFXPROC) (GLuint mask); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTbufferMask3DFX (GLuint mask); -#endif -#endif /* GL_3DFX_tbuffer */ - -#ifndef GL_3DFX_texture_compression_FXT1 -#define GL_3DFX_texture_compression_FXT1 1 -#define GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0 -#define GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1 -#endif /* GL_3DFX_texture_compression_FXT1 */ - -#ifndef GL_AMD_blend_minmax_factor -#define GL_AMD_blend_minmax_factor 1 -#define GL_FACTOR_MIN_AMD 0x901C -#define GL_FACTOR_MAX_AMD 0x901D -#endif /* GL_AMD_blend_minmax_factor */ - -#ifndef GL_AMD_conservative_depth -#define GL_AMD_conservative_depth 1 -#endif /* GL_AMD_conservative_depth */ - -#ifndef GL_AMD_debug_output -#define GL_AMD_debug_output 1 -typedef void (APIENTRY *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,void *userParam); -#define GL_MAX_DEBUG_MESSAGE_LENGTH_AMD 0x9143 -#define GL_MAX_DEBUG_LOGGED_MESSAGES_AMD 0x9144 -#define GL_DEBUG_LOGGED_MESSAGES_AMD 0x9145 -#define GL_DEBUG_SEVERITY_HIGH_AMD 0x9146 -#define GL_DEBUG_SEVERITY_MEDIUM_AMD 0x9147 -#define GL_DEBUG_SEVERITY_LOW_AMD 0x9148 -#define GL_DEBUG_CATEGORY_API_ERROR_AMD 0x9149 -#define GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD 0x914A -#define GL_DEBUG_CATEGORY_DEPRECATION_AMD 0x914B -#define GL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD 0x914C -#define GL_DEBUG_CATEGORY_PERFORMANCE_AMD 0x914D -#define GL_DEBUG_CATEGORY_SHADER_COMPILER_AMD 0x914E -#define GL_DEBUG_CATEGORY_APPLICATION_AMD 0x914F -#define GL_DEBUG_CATEGORY_OTHER_AMD 0x9150 -typedef void (APIENTRYP PFNGLDEBUGMESSAGEENABLEAMDPROC) (GLenum category, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); -typedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTAMDPROC) (GLenum category, GLenum severity, GLuint id, GLsizei length, const GLchar *buf); -typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKAMDPROC) (GLDEBUGPROCAMD callback, void *userParam); -typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGAMDPROC) (GLuint count, GLsizei bufsize, GLenum *categories, GLuint *severities, GLuint *ids, GLsizei *lengths, GLchar *message); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDebugMessageEnableAMD (GLenum category, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); -GLAPI void APIENTRY glDebugMessageInsertAMD (GLenum category, GLenum severity, GLuint id, GLsizei length, const GLchar *buf); -GLAPI void APIENTRY glDebugMessageCallbackAMD (GLDEBUGPROCAMD callback, void *userParam); -GLAPI GLuint APIENTRY glGetDebugMessageLogAMD (GLuint count, GLsizei bufsize, GLenum *categories, GLuint *severities, GLuint *ids, GLsizei *lengths, GLchar *message); -#endif -#endif /* GL_AMD_debug_output */ - -#ifndef GL_AMD_depth_clamp_separate -#define GL_AMD_depth_clamp_separate 1 -#define GL_DEPTH_CLAMP_NEAR_AMD 0x901E -#define GL_DEPTH_CLAMP_FAR_AMD 0x901F -#endif /* GL_AMD_depth_clamp_separate */ - -#ifndef GL_AMD_draw_buffers_blend -#define GL_AMD_draw_buffers_blend 1 -typedef void (APIENTRYP PFNGLBLENDFUNCINDEXEDAMDPROC) (GLuint buf, GLenum src, GLenum dst); -typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); -typedef void (APIENTRYP PFNGLBLENDEQUATIONINDEXEDAMDPROC) (GLuint buf, GLenum mode); -typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendFuncIndexedAMD (GLuint buf, GLenum src, GLenum dst); -GLAPI void APIENTRY glBlendFuncSeparateIndexedAMD (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); -GLAPI void APIENTRY glBlendEquationIndexedAMD (GLuint buf, GLenum mode); -GLAPI void APIENTRY glBlendEquationSeparateIndexedAMD (GLuint buf, GLenum modeRGB, GLenum modeAlpha); -#endif -#endif /* GL_AMD_draw_buffers_blend */ - -#ifndef GL_AMD_gcn_shader -#define GL_AMD_gcn_shader 1 -#endif /* GL_AMD_gcn_shader */ - -#ifndef GL_AMD_gpu_shader_int64 -#define GL_AMD_gpu_shader_int64 1 -typedef int64_t GLint64EXT; -#define GL_INT64_NV 0x140E -#define GL_UNSIGNED_INT64_NV 0x140F -#define GL_INT8_NV 0x8FE0 -#define GL_INT8_VEC2_NV 0x8FE1 -#define GL_INT8_VEC3_NV 0x8FE2 -#define GL_INT8_VEC4_NV 0x8FE3 -#define GL_INT16_NV 0x8FE4 -#define GL_INT16_VEC2_NV 0x8FE5 -#define GL_INT16_VEC3_NV 0x8FE6 -#define GL_INT16_VEC4_NV 0x8FE7 -#define GL_INT64_VEC2_NV 0x8FE9 -#define GL_INT64_VEC3_NV 0x8FEA -#define GL_INT64_VEC4_NV 0x8FEB -#define GL_UNSIGNED_INT8_NV 0x8FEC -#define GL_UNSIGNED_INT8_VEC2_NV 0x8FED -#define GL_UNSIGNED_INT8_VEC3_NV 0x8FEE -#define GL_UNSIGNED_INT8_VEC4_NV 0x8FEF -#define GL_UNSIGNED_INT16_NV 0x8FF0 -#define GL_UNSIGNED_INT16_VEC2_NV 0x8FF1 -#define GL_UNSIGNED_INT16_VEC3_NV 0x8FF2 -#define GL_UNSIGNED_INT16_VEC4_NV 0x8FF3 -#define GL_UNSIGNED_INT64_VEC2_NV 0x8FF5 -#define GL_UNSIGNED_INT64_VEC3_NV 0x8FF6 -#define GL_UNSIGNED_INT64_VEC4_NV 0x8FF7 -#define GL_FLOAT16_NV 0x8FF8 -#define GL_FLOAT16_VEC2_NV 0x8FF9 -#define GL_FLOAT16_VEC3_NV 0x8FFA -#define GL_FLOAT16_VEC4_NV 0x8FFB -typedef void (APIENTRYP PFNGLUNIFORM1I64NVPROC) (GLint location, GLint64EXT x); -typedef void (APIENTRYP PFNGLUNIFORM2I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y); -typedef void (APIENTRYP PFNGLUNIFORM3I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); -typedef void (APIENTRYP PFNGLUNIFORM4I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); -typedef void (APIENTRYP PFNGLUNIFORM1I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value); -typedef void (APIENTRYP PFNGLUNIFORM2I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value); -typedef void (APIENTRYP PFNGLUNIFORM3I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value); -typedef void (APIENTRYP PFNGLUNIFORM4I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value); -typedef void (APIENTRYP PFNGLUNIFORM1UI64NVPROC) (GLint location, GLuint64EXT x); -typedef void (APIENTRYP PFNGLUNIFORM2UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y); -typedef void (APIENTRYP PFNGLUNIFORM3UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); -typedef void (APIENTRYP PFNGLUNIFORM4UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); -typedef void (APIENTRYP PFNGLUNIFORM1UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value); -typedef void (APIENTRYP PFNGLUNIFORM2UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value); -typedef void (APIENTRYP PFNGLUNIFORM3UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value); -typedef void (APIENTRYP PFNGLUNIFORM4UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value); -typedef void (APIENTRYP PFNGLGETUNIFORMI64VNVPROC) (GLuint program, GLint location, GLint64EXT *params); -typedef void (APIENTRYP PFNGLGETUNIFORMUI64VNVPROC) (GLuint program, GLint location, GLuint64EXT *params); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1I64NVPROC) (GLuint program, GLint location, GLint64EXT x); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glUniform1i64NV (GLint location, GLint64EXT x); -GLAPI void APIENTRY glUniform2i64NV (GLint location, GLint64EXT x, GLint64EXT y); -GLAPI void APIENTRY glUniform3i64NV (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); -GLAPI void APIENTRY glUniform4i64NV (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); -GLAPI void APIENTRY glUniform1i64vNV (GLint location, GLsizei count, const GLint64EXT *value); -GLAPI void APIENTRY glUniform2i64vNV (GLint location, GLsizei count, const GLint64EXT *value); -GLAPI void APIENTRY glUniform3i64vNV (GLint location, GLsizei count, const GLint64EXT *value); -GLAPI void APIENTRY glUniform4i64vNV (GLint location, GLsizei count, const GLint64EXT *value); -GLAPI void APIENTRY glUniform1ui64NV (GLint location, GLuint64EXT x); -GLAPI void APIENTRY glUniform2ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y); -GLAPI void APIENTRY glUniform3ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); -GLAPI void APIENTRY glUniform4ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); -GLAPI void APIENTRY glUniform1ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value); -GLAPI void APIENTRY glUniform2ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value); -GLAPI void APIENTRY glUniform3ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value); -GLAPI void APIENTRY glUniform4ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value); -GLAPI void APIENTRY glGetUniformi64vNV (GLuint program, GLint location, GLint64EXT *params); -GLAPI void APIENTRY glGetUniformui64vNV (GLuint program, GLint location, GLuint64EXT *params); -GLAPI void APIENTRY glProgramUniform1i64NV (GLuint program, GLint location, GLint64EXT x); -GLAPI void APIENTRY glProgramUniform2i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y); -GLAPI void APIENTRY glProgramUniform3i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); -GLAPI void APIENTRY glProgramUniform4i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); -GLAPI void APIENTRY glProgramUniform1i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); -GLAPI void APIENTRY glProgramUniform2i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); -GLAPI void APIENTRY glProgramUniform3i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); -GLAPI void APIENTRY glProgramUniform4i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); -GLAPI void APIENTRY glProgramUniform1ui64NV (GLuint program, GLint location, GLuint64EXT x); -GLAPI void APIENTRY glProgramUniform2ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y); -GLAPI void APIENTRY glProgramUniform3ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); -GLAPI void APIENTRY glProgramUniform4ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); -GLAPI void APIENTRY glProgramUniform1ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); -GLAPI void APIENTRY glProgramUniform2ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); -GLAPI void APIENTRY glProgramUniform3ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); -GLAPI void APIENTRY glProgramUniform4ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); -#endif -#endif /* GL_AMD_gpu_shader_int64 */ - -#ifndef GL_AMD_interleaved_elements -#define GL_AMD_interleaved_elements 1 -#define GL_VERTEX_ELEMENT_SWIZZLE_AMD 0x91A4 -#define GL_VERTEX_ID_SWIZZLE_AMD 0x91A5 -typedef void (APIENTRYP PFNGLVERTEXATTRIBPARAMETERIAMDPROC) (GLuint index, GLenum pname, GLint param); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexAttribParameteriAMD (GLuint index, GLenum pname, GLint param); -#endif -#endif /* GL_AMD_interleaved_elements */ - -#ifndef GL_AMD_multi_draw_indirect -#define GL_AMD_multi_draw_indirect 1 -typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTAMDPROC) (GLenum mode, const void *indirect, GLsizei primcount, GLsizei stride); -typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTAMDPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei primcount, GLsizei stride); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glMultiDrawArraysIndirectAMD (GLenum mode, const void *indirect, GLsizei primcount, GLsizei stride); -GLAPI void APIENTRY glMultiDrawElementsIndirectAMD (GLenum mode, GLenum type, const void *indirect, GLsizei primcount, GLsizei stride); -#endif -#endif /* GL_AMD_multi_draw_indirect */ - -#ifndef GL_AMD_name_gen_delete -#define GL_AMD_name_gen_delete 1 -#define GL_DATA_BUFFER_AMD 0x9151 -#define GL_PERFORMANCE_MONITOR_AMD 0x9152 -#define GL_QUERY_OBJECT_AMD 0x9153 -#define GL_VERTEX_ARRAY_OBJECT_AMD 0x9154 -#define GL_SAMPLER_OBJECT_AMD 0x9155 -typedef void (APIENTRYP PFNGLGENNAMESAMDPROC) (GLenum identifier, GLuint num, GLuint *names); -typedef void (APIENTRYP PFNGLDELETENAMESAMDPROC) (GLenum identifier, GLuint num, const GLuint *names); -typedef GLboolean (APIENTRYP PFNGLISNAMEAMDPROC) (GLenum identifier, GLuint name); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGenNamesAMD (GLenum identifier, GLuint num, GLuint *names); -GLAPI void APIENTRY glDeleteNamesAMD (GLenum identifier, GLuint num, const GLuint *names); -GLAPI GLboolean APIENTRY glIsNameAMD (GLenum identifier, GLuint name); -#endif -#endif /* GL_AMD_name_gen_delete */ - -#ifndef GL_AMD_occlusion_query_event -#define GL_AMD_occlusion_query_event 1 -#define GL_OCCLUSION_QUERY_EVENT_MASK_AMD 0x874F -#define GL_QUERY_DEPTH_PASS_EVENT_BIT_AMD 0x00000001 -#define GL_QUERY_DEPTH_FAIL_EVENT_BIT_AMD 0x00000002 -#define GL_QUERY_STENCIL_FAIL_EVENT_BIT_AMD 0x00000004 -#define GL_QUERY_DEPTH_BOUNDS_FAIL_EVENT_BIT_AMD 0x00000008 -#define GL_QUERY_ALL_EVENT_BITS_AMD 0xFFFFFFFF -typedef void (APIENTRYP PFNGLQUERYOBJECTPARAMETERUIAMDPROC) (GLenum target, GLuint id, GLenum pname, GLuint param); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glQueryObjectParameteruiAMD (GLenum target, GLuint id, GLenum pname, GLuint param); -#endif -#endif /* GL_AMD_occlusion_query_event */ - -#ifndef GL_AMD_performance_monitor -#define GL_AMD_performance_monitor 1 -#define GL_COUNTER_TYPE_AMD 0x8BC0 -#define GL_COUNTER_RANGE_AMD 0x8BC1 -#define GL_UNSIGNED_INT64_AMD 0x8BC2 -#define GL_PERCENTAGE_AMD 0x8BC3 -#define GL_PERFMON_RESULT_AVAILABLE_AMD 0x8BC4 -#define GL_PERFMON_RESULT_SIZE_AMD 0x8BC5 -#define GL_PERFMON_RESULT_AMD 0x8BC6 -typedef void (APIENTRYP PFNGLGETPERFMONITORGROUPSAMDPROC) (GLint *numGroups, GLsizei groupsSize, GLuint *groups); -typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERSAMDPROC) (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters); -typedef void (APIENTRYP PFNGLGETPERFMONITORGROUPSTRINGAMDPROC) (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString); -typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC) (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString); -typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERINFOAMDPROC) (GLuint group, GLuint counter, GLenum pname, void *data); -typedef void (APIENTRYP PFNGLGENPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors); -typedef void (APIENTRYP PFNGLDELETEPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors); -typedef void (APIENTRYP PFNGLSELECTPERFMONITORCOUNTERSAMDPROC) (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *counterList); -typedef void (APIENTRYP PFNGLBEGINPERFMONITORAMDPROC) (GLuint monitor); -typedef void (APIENTRYP PFNGLENDPERFMONITORAMDPROC) (GLuint monitor); -typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGetPerfMonitorGroupsAMD (GLint *numGroups, GLsizei groupsSize, GLuint *groups); -GLAPI void APIENTRY glGetPerfMonitorCountersAMD (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters); -GLAPI void APIENTRY glGetPerfMonitorGroupStringAMD (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString); -GLAPI void APIENTRY glGetPerfMonitorCounterStringAMD (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString); -GLAPI void APIENTRY glGetPerfMonitorCounterInfoAMD (GLuint group, GLuint counter, GLenum pname, void *data); -GLAPI void APIENTRY glGenPerfMonitorsAMD (GLsizei n, GLuint *monitors); -GLAPI void APIENTRY glDeletePerfMonitorsAMD (GLsizei n, GLuint *monitors); -GLAPI void APIENTRY glSelectPerfMonitorCountersAMD (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *counterList); -GLAPI void APIENTRY glBeginPerfMonitorAMD (GLuint monitor); -GLAPI void APIENTRY glEndPerfMonitorAMD (GLuint monitor); -GLAPI void APIENTRY glGetPerfMonitorCounterDataAMD (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten); -#endif -#endif /* GL_AMD_performance_monitor */ - -#ifndef GL_AMD_pinned_memory -#define GL_AMD_pinned_memory 1 -#define GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD 0x9160 -#endif /* GL_AMD_pinned_memory */ - -#ifndef GL_AMD_query_buffer_object -#define GL_AMD_query_buffer_object 1 -#define GL_QUERY_BUFFER_AMD 0x9192 -#define GL_QUERY_BUFFER_BINDING_AMD 0x9193 -#define GL_QUERY_RESULT_NO_WAIT_AMD 0x9194 -#endif /* GL_AMD_query_buffer_object */ - -#ifndef GL_AMD_sample_positions -#define GL_AMD_sample_positions 1 -#define GL_SUBSAMPLE_DISTANCE_AMD 0x883F -typedef void (APIENTRYP PFNGLSETMULTISAMPLEFVAMDPROC) (GLenum pname, GLuint index, const GLfloat *val); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glSetMultisamplefvAMD (GLenum pname, GLuint index, const GLfloat *val); -#endif -#endif /* GL_AMD_sample_positions */ - -#ifndef GL_AMD_seamless_cubemap_per_texture -#define GL_AMD_seamless_cubemap_per_texture 1 -#endif /* GL_AMD_seamless_cubemap_per_texture */ - -#ifndef GL_AMD_shader_atomic_counter_ops -#define GL_AMD_shader_atomic_counter_ops 1 -#endif /* GL_AMD_shader_atomic_counter_ops */ - -#ifndef GL_AMD_shader_stencil_export -#define GL_AMD_shader_stencil_export 1 -#endif /* GL_AMD_shader_stencil_export */ - -#ifndef GL_AMD_shader_trinary_minmax -#define GL_AMD_shader_trinary_minmax 1 -#endif /* GL_AMD_shader_trinary_minmax */ - -#ifndef GL_AMD_sparse_texture -#define GL_AMD_sparse_texture 1 -#define GL_VIRTUAL_PAGE_SIZE_X_AMD 0x9195 -#define GL_VIRTUAL_PAGE_SIZE_Y_AMD 0x9196 -#define GL_VIRTUAL_PAGE_SIZE_Z_AMD 0x9197 -#define GL_MAX_SPARSE_TEXTURE_SIZE_AMD 0x9198 -#define GL_MAX_SPARSE_3D_TEXTURE_SIZE_AMD 0x9199 -#define GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS 0x919A -#define GL_MIN_SPARSE_LEVEL_AMD 0x919B -#define GL_MIN_LOD_WARNING_AMD 0x919C -#define GL_TEXTURE_STORAGE_SPARSE_BIT_AMD 0x00000001 -typedef void (APIENTRYP PFNGLTEXSTORAGESPARSEAMDPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei layers, GLbitfield flags); -typedef void (APIENTRYP PFNGLTEXTURESTORAGESPARSEAMDPROC) (GLuint texture, GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei layers, GLbitfield flags); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTexStorageSparseAMD (GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei layers, GLbitfield flags); -GLAPI void APIENTRY glTextureStorageSparseAMD (GLuint texture, GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei layers, GLbitfield flags); -#endif -#endif /* GL_AMD_sparse_texture */ - -#ifndef GL_AMD_stencil_operation_extended -#define GL_AMD_stencil_operation_extended 1 -#define GL_SET_AMD 0x874A -#define GL_REPLACE_VALUE_AMD 0x874B -#define GL_STENCIL_OP_VALUE_AMD 0x874C -#define GL_STENCIL_BACK_OP_VALUE_AMD 0x874D -typedef void (APIENTRYP PFNGLSTENCILOPVALUEAMDPROC) (GLenum face, GLuint value); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glStencilOpValueAMD (GLenum face, GLuint value); -#endif -#endif /* GL_AMD_stencil_operation_extended */ - -#ifndef GL_AMD_texture_texture4 -#define GL_AMD_texture_texture4 1 -#endif /* GL_AMD_texture_texture4 */ - -#ifndef GL_AMD_transform_feedback3_lines_triangles -#define GL_AMD_transform_feedback3_lines_triangles 1 -#endif /* GL_AMD_transform_feedback3_lines_triangles */ - -#ifndef GL_AMD_transform_feedback4 -#define GL_AMD_transform_feedback4 1 -#define GL_STREAM_RASTERIZATION_AMD 0x91A0 -#endif /* GL_AMD_transform_feedback4 */ - -#ifndef GL_AMD_vertex_shader_layer -#define GL_AMD_vertex_shader_layer 1 -#endif /* GL_AMD_vertex_shader_layer */ - -#ifndef GL_AMD_vertex_shader_tessellator -#define GL_AMD_vertex_shader_tessellator 1 -#define GL_SAMPLER_BUFFER_AMD 0x9001 -#define GL_INT_SAMPLER_BUFFER_AMD 0x9002 -#define GL_UNSIGNED_INT_SAMPLER_BUFFER_AMD 0x9003 -#define GL_TESSELLATION_MODE_AMD 0x9004 -#define GL_TESSELLATION_FACTOR_AMD 0x9005 -#define GL_DISCRETE_AMD 0x9006 -#define GL_CONTINUOUS_AMD 0x9007 -typedef void (APIENTRYP PFNGLTESSELLATIONFACTORAMDPROC) (GLfloat factor); -typedef void (APIENTRYP PFNGLTESSELLATIONMODEAMDPROC) (GLenum mode); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTessellationFactorAMD (GLfloat factor); -GLAPI void APIENTRY glTessellationModeAMD (GLenum mode); -#endif -#endif /* GL_AMD_vertex_shader_tessellator */ - -#ifndef GL_AMD_vertex_shader_viewport_index -#define GL_AMD_vertex_shader_viewport_index 1 -#endif /* GL_AMD_vertex_shader_viewport_index */ - -#ifndef GL_APPLE_aux_depth_stencil -#define GL_APPLE_aux_depth_stencil 1 -#define GL_AUX_DEPTH_STENCIL_APPLE 0x8A14 -#endif /* GL_APPLE_aux_depth_stencil */ - -#ifndef GL_APPLE_client_storage -#define GL_APPLE_client_storage 1 -#define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2 -#endif /* GL_APPLE_client_storage */ - -#ifndef GL_APPLE_element_array -#define GL_APPLE_element_array 1 -#define GL_ELEMENT_ARRAY_APPLE 0x8A0C -#define GL_ELEMENT_ARRAY_TYPE_APPLE 0x8A0D -#define GL_ELEMENT_ARRAY_POINTER_APPLE 0x8A0E -typedef void (APIENTRYP PFNGLELEMENTPOINTERAPPLEPROC) (GLenum type, const void *pointer); -typedef void (APIENTRYP PFNGLDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, GLint first, GLsizei count); -typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count); -typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); -typedef void (APIENTRYP PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, const GLint *first, const GLsizei *count, GLsizei primcount); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glElementPointerAPPLE (GLenum type, const void *pointer); -GLAPI void APIENTRY glDrawElementArrayAPPLE (GLenum mode, GLint first, GLsizei count); -GLAPI void APIENTRY glDrawRangeElementArrayAPPLE (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count); -GLAPI void APIENTRY glMultiDrawElementArrayAPPLE (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); -GLAPI void APIENTRY glMultiDrawRangeElementArrayAPPLE (GLenum mode, GLuint start, GLuint end, const GLint *first, const GLsizei *count, GLsizei primcount); -#endif -#endif /* GL_APPLE_element_array */ - -#ifndef GL_APPLE_fence -#define GL_APPLE_fence 1 -#define GL_DRAW_PIXELS_APPLE 0x8A0A -#define GL_FENCE_APPLE 0x8A0B -typedef void (APIENTRYP PFNGLGENFENCESAPPLEPROC) (GLsizei n, GLuint *fences); -typedef void (APIENTRYP PFNGLDELETEFENCESAPPLEPROC) (GLsizei n, const GLuint *fences); -typedef void (APIENTRYP PFNGLSETFENCEAPPLEPROC) (GLuint fence); -typedef GLboolean (APIENTRYP PFNGLISFENCEAPPLEPROC) (GLuint fence); -typedef GLboolean (APIENTRYP PFNGLTESTFENCEAPPLEPROC) (GLuint fence); -typedef void (APIENTRYP PFNGLFINISHFENCEAPPLEPROC) (GLuint fence); -typedef GLboolean (APIENTRYP PFNGLTESTOBJECTAPPLEPROC) (GLenum object, GLuint name); -typedef void (APIENTRYP PFNGLFINISHOBJECTAPPLEPROC) (GLenum object, GLint name); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGenFencesAPPLE (GLsizei n, GLuint *fences); -GLAPI void APIENTRY glDeleteFencesAPPLE (GLsizei n, const GLuint *fences); -GLAPI void APIENTRY glSetFenceAPPLE (GLuint fence); -GLAPI GLboolean APIENTRY glIsFenceAPPLE (GLuint fence); -GLAPI GLboolean APIENTRY glTestFenceAPPLE (GLuint fence); -GLAPI void APIENTRY glFinishFenceAPPLE (GLuint fence); -GLAPI GLboolean APIENTRY glTestObjectAPPLE (GLenum object, GLuint name); -GLAPI void APIENTRY glFinishObjectAPPLE (GLenum object, GLint name); -#endif -#endif /* GL_APPLE_fence */ - -#ifndef GL_APPLE_float_pixels -#define GL_APPLE_float_pixels 1 -#define GL_HALF_APPLE 0x140B -#define GL_RGBA_FLOAT32_APPLE 0x8814 -#define GL_RGB_FLOAT32_APPLE 0x8815 -#define GL_ALPHA_FLOAT32_APPLE 0x8816 -#define GL_INTENSITY_FLOAT32_APPLE 0x8817 -#define GL_LUMINANCE_FLOAT32_APPLE 0x8818 -#define GL_LUMINANCE_ALPHA_FLOAT32_APPLE 0x8819 -#define GL_RGBA_FLOAT16_APPLE 0x881A -#define GL_RGB_FLOAT16_APPLE 0x881B -#define GL_ALPHA_FLOAT16_APPLE 0x881C -#define GL_INTENSITY_FLOAT16_APPLE 0x881D -#define GL_LUMINANCE_FLOAT16_APPLE 0x881E -#define GL_LUMINANCE_ALPHA_FLOAT16_APPLE 0x881F -#define GL_COLOR_FLOAT_APPLE 0x8A0F -#endif /* GL_APPLE_float_pixels */ - -#ifndef GL_APPLE_flush_buffer_range -#define GL_APPLE_flush_buffer_range 1 -#define GL_BUFFER_SERIALIZED_MODIFY_APPLE 0x8A12 -#define GL_BUFFER_FLUSHING_UNMAP_APPLE 0x8A13 -typedef void (APIENTRYP PFNGLBUFFERPARAMETERIAPPLEPROC) (GLenum target, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC) (GLenum target, GLintptr offset, GLsizeiptr size); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBufferParameteriAPPLE (GLenum target, GLenum pname, GLint param); -GLAPI void APIENTRY glFlushMappedBufferRangeAPPLE (GLenum target, GLintptr offset, GLsizeiptr size); -#endif -#endif /* GL_APPLE_flush_buffer_range */ - -#ifndef GL_APPLE_object_purgeable -#define GL_APPLE_object_purgeable 1 -#define GL_BUFFER_OBJECT_APPLE 0x85B3 -#define GL_RELEASED_APPLE 0x8A19 -#define GL_VOLATILE_APPLE 0x8A1A -#define GL_RETAINED_APPLE 0x8A1B -#define GL_UNDEFINED_APPLE 0x8A1C -#define GL_PURGEABLE_APPLE 0x8A1D -typedef GLenum (APIENTRYP PFNGLOBJECTPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option); -typedef GLenum (APIENTRYP PFNGLOBJECTUNPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option); -typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERIVAPPLEPROC) (GLenum objectType, GLuint name, GLenum pname, GLint *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLenum APIENTRY glObjectPurgeableAPPLE (GLenum objectType, GLuint name, GLenum option); -GLAPI GLenum APIENTRY glObjectUnpurgeableAPPLE (GLenum objectType, GLuint name, GLenum option); -GLAPI void APIENTRY glGetObjectParameterivAPPLE (GLenum objectType, GLuint name, GLenum pname, GLint *params); -#endif -#endif /* GL_APPLE_object_purgeable */ - -#ifndef GL_APPLE_rgb_422 -#define GL_APPLE_rgb_422 1 -#define GL_RGB_422_APPLE 0x8A1F -#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA -#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB -#define GL_RGB_RAW_422_APPLE 0x8A51 -#endif /* GL_APPLE_rgb_422 */ - -#ifndef GL_APPLE_row_bytes -#define GL_APPLE_row_bytes 1 -#define GL_PACK_ROW_BYTES_APPLE 0x8A15 -#define GL_UNPACK_ROW_BYTES_APPLE 0x8A16 -#endif /* GL_APPLE_row_bytes */ - -#ifndef GL_APPLE_specular_vector -#define GL_APPLE_specular_vector 1 -#define GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0 -#endif /* GL_APPLE_specular_vector */ - -#ifndef GL_APPLE_texture_range -#define GL_APPLE_texture_range 1 -#define GL_TEXTURE_RANGE_LENGTH_APPLE 0x85B7 -#define GL_TEXTURE_RANGE_POINTER_APPLE 0x85B8 -#define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC -#define GL_STORAGE_PRIVATE_APPLE 0x85BD -#define GL_STORAGE_CACHED_APPLE 0x85BE -#define GL_STORAGE_SHARED_APPLE 0x85BF -typedef void (APIENTRYP PFNGLTEXTURERANGEAPPLEPROC) (GLenum target, GLsizei length, const void *pointer); -typedef void (APIENTRYP PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC) (GLenum target, GLenum pname, void **params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTextureRangeAPPLE (GLenum target, GLsizei length, const void *pointer); -GLAPI void APIENTRY glGetTexParameterPointervAPPLE (GLenum target, GLenum pname, void **params); -#endif -#endif /* GL_APPLE_texture_range */ - -#ifndef GL_APPLE_transform_hint -#define GL_APPLE_transform_hint 1 -#define GL_TRANSFORM_HINT_APPLE 0x85B1 -#endif /* GL_APPLE_transform_hint */ - -#ifndef GL_APPLE_vertex_array_object -#define GL_APPLE_vertex_array_object 1 -#define GL_VERTEX_ARRAY_BINDING_APPLE 0x85B5 -typedef void (APIENTRYP PFNGLBINDVERTEXARRAYAPPLEPROC) (GLuint array); -typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint *arrays); -typedef void (APIENTRYP PFNGLGENVERTEXARRAYSAPPLEPROC) (GLsizei n, GLuint *arrays); -typedef GLboolean (APIENTRYP PFNGLISVERTEXARRAYAPPLEPROC) (GLuint array); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBindVertexArrayAPPLE (GLuint array); -GLAPI void APIENTRY glDeleteVertexArraysAPPLE (GLsizei n, const GLuint *arrays); -GLAPI void APIENTRY glGenVertexArraysAPPLE (GLsizei n, GLuint *arrays); -GLAPI GLboolean APIENTRY glIsVertexArrayAPPLE (GLuint array); -#endif -#endif /* GL_APPLE_vertex_array_object */ - -#ifndef GL_APPLE_vertex_array_range -#define GL_APPLE_vertex_array_range 1 -#define GL_VERTEX_ARRAY_RANGE_APPLE 0x851D -#define GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE 0x851E -#define GL_VERTEX_ARRAY_STORAGE_HINT_APPLE 0x851F -#define GL_VERTEX_ARRAY_RANGE_POINTER_APPLE 0x8521 -#define GL_STORAGE_CLIENT_APPLE 0x85B4 -typedef void (APIENTRYP PFNGLVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, void *pointer); -typedef void (APIENTRYP PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, void *pointer); -typedef void (APIENTRYP PFNGLVERTEXARRAYPARAMETERIAPPLEPROC) (GLenum pname, GLint param); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexArrayRangeAPPLE (GLsizei length, void *pointer); -GLAPI void APIENTRY glFlushVertexArrayRangeAPPLE (GLsizei length, void *pointer); -GLAPI void APIENTRY glVertexArrayParameteriAPPLE (GLenum pname, GLint param); -#endif -#endif /* GL_APPLE_vertex_array_range */ - -#ifndef GL_APPLE_vertex_program_evaluators -#define GL_APPLE_vertex_program_evaluators 1 -#define GL_VERTEX_ATTRIB_MAP1_APPLE 0x8A00 -#define GL_VERTEX_ATTRIB_MAP2_APPLE 0x8A01 -#define GL_VERTEX_ATTRIB_MAP1_SIZE_APPLE 0x8A02 -#define GL_VERTEX_ATTRIB_MAP1_COEFF_APPLE 0x8A03 -#define GL_VERTEX_ATTRIB_MAP1_ORDER_APPLE 0x8A04 -#define GL_VERTEX_ATTRIB_MAP1_DOMAIN_APPLE 0x8A05 -#define GL_VERTEX_ATTRIB_MAP2_SIZE_APPLE 0x8A06 -#define GL_VERTEX_ATTRIB_MAP2_COEFF_APPLE 0x8A07 -#define GL_VERTEX_ATTRIB_MAP2_ORDER_APPLE 0x8A08 -#define GL_VERTEX_ATTRIB_MAP2_DOMAIN_APPLE 0x8A09 -typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname); -typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname); -typedef GLboolean (APIENTRYP PFNGLISVERTEXATTRIBENABLEDAPPLEPROC) (GLuint index, GLenum pname); -typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB1DAPPLEPROC) (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); -typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB1FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); -typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB2DAPPLEPROC) (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); -typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB2FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glEnableVertexAttribAPPLE (GLuint index, GLenum pname); -GLAPI void APIENTRY glDisableVertexAttribAPPLE (GLuint index, GLenum pname); -GLAPI GLboolean APIENTRY glIsVertexAttribEnabledAPPLE (GLuint index, GLenum pname); -GLAPI void APIENTRY glMapVertexAttrib1dAPPLE (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); -GLAPI void APIENTRY glMapVertexAttrib1fAPPLE (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); -GLAPI void APIENTRY glMapVertexAttrib2dAPPLE (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); -GLAPI void APIENTRY glMapVertexAttrib2fAPPLE (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); -#endif -#endif /* GL_APPLE_vertex_program_evaluators */ - -#ifndef GL_APPLE_ycbcr_422 -#define GL_APPLE_ycbcr_422 1 -#define GL_YCBCR_422_APPLE 0x85B9 -#endif /* GL_APPLE_ycbcr_422 */ - -#ifndef GL_ATI_draw_buffers -#define GL_ATI_draw_buffers 1 -#define GL_MAX_DRAW_BUFFERS_ATI 0x8824 -#define GL_DRAW_BUFFER0_ATI 0x8825 -#define GL_DRAW_BUFFER1_ATI 0x8826 -#define GL_DRAW_BUFFER2_ATI 0x8827 -#define GL_DRAW_BUFFER3_ATI 0x8828 -#define GL_DRAW_BUFFER4_ATI 0x8829 -#define GL_DRAW_BUFFER5_ATI 0x882A -#define GL_DRAW_BUFFER6_ATI 0x882B -#define GL_DRAW_BUFFER7_ATI 0x882C -#define GL_DRAW_BUFFER8_ATI 0x882D -#define GL_DRAW_BUFFER9_ATI 0x882E -#define GL_DRAW_BUFFER10_ATI 0x882F -#define GL_DRAW_BUFFER11_ATI 0x8830 -#define GL_DRAW_BUFFER12_ATI 0x8831 -#define GL_DRAW_BUFFER13_ATI 0x8832 -#define GL_DRAW_BUFFER14_ATI 0x8833 -#define GL_DRAW_BUFFER15_ATI 0x8834 -typedef void (APIENTRYP PFNGLDRAWBUFFERSATIPROC) (GLsizei n, const GLenum *bufs); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDrawBuffersATI (GLsizei n, const GLenum *bufs); -#endif -#endif /* GL_ATI_draw_buffers */ - -#ifndef GL_ATI_element_array -#define GL_ATI_element_array 1 -#define GL_ELEMENT_ARRAY_ATI 0x8768 -#define GL_ELEMENT_ARRAY_TYPE_ATI 0x8769 -#define GL_ELEMENT_ARRAY_POINTER_ATI 0x876A -typedef void (APIENTRYP PFNGLELEMENTPOINTERATIPROC) (GLenum type, const void *pointer); -typedef void (APIENTRYP PFNGLDRAWELEMENTARRAYATIPROC) (GLenum mode, GLsizei count); -typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTARRAYATIPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glElementPointerATI (GLenum type, const void *pointer); -GLAPI void APIENTRY glDrawElementArrayATI (GLenum mode, GLsizei count); -GLAPI void APIENTRY glDrawRangeElementArrayATI (GLenum mode, GLuint start, GLuint end, GLsizei count); -#endif -#endif /* GL_ATI_element_array */ - -#ifndef GL_ATI_envmap_bumpmap -#define GL_ATI_envmap_bumpmap 1 -#define GL_BUMP_ROT_MATRIX_ATI 0x8775 -#define GL_BUMP_ROT_MATRIX_SIZE_ATI 0x8776 -#define GL_BUMP_NUM_TEX_UNITS_ATI 0x8777 -#define GL_BUMP_TEX_UNITS_ATI 0x8778 -#define GL_DUDV_ATI 0x8779 -#define GL_DU8DV8_ATI 0x877A -#define GL_BUMP_ENVMAP_ATI 0x877B -#define GL_BUMP_TARGET_ATI 0x877C -typedef void (APIENTRYP PFNGLTEXBUMPPARAMETERIVATIPROC) (GLenum pname, const GLint *param); -typedef void (APIENTRYP PFNGLTEXBUMPPARAMETERFVATIPROC) (GLenum pname, const GLfloat *param); -typedef void (APIENTRYP PFNGLGETTEXBUMPPARAMETERIVATIPROC) (GLenum pname, GLint *param); -typedef void (APIENTRYP PFNGLGETTEXBUMPPARAMETERFVATIPROC) (GLenum pname, GLfloat *param); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTexBumpParameterivATI (GLenum pname, const GLint *param); -GLAPI void APIENTRY glTexBumpParameterfvATI (GLenum pname, const GLfloat *param); -GLAPI void APIENTRY glGetTexBumpParameterivATI (GLenum pname, GLint *param); -GLAPI void APIENTRY glGetTexBumpParameterfvATI (GLenum pname, GLfloat *param); -#endif -#endif /* GL_ATI_envmap_bumpmap */ - -#ifndef GL_ATI_fragment_shader -#define GL_ATI_fragment_shader 1 -#define GL_FRAGMENT_SHADER_ATI 0x8920 -#define GL_REG_0_ATI 0x8921 -#define GL_REG_1_ATI 0x8922 -#define GL_REG_2_ATI 0x8923 -#define GL_REG_3_ATI 0x8924 -#define GL_REG_4_ATI 0x8925 -#define GL_REG_5_ATI 0x8926 -#define GL_REG_6_ATI 0x8927 -#define GL_REG_7_ATI 0x8928 -#define GL_REG_8_ATI 0x8929 -#define GL_REG_9_ATI 0x892A -#define GL_REG_10_ATI 0x892B -#define GL_REG_11_ATI 0x892C -#define GL_REG_12_ATI 0x892D -#define GL_REG_13_ATI 0x892E -#define GL_REG_14_ATI 0x892F -#define GL_REG_15_ATI 0x8930 -#define GL_REG_16_ATI 0x8931 -#define GL_REG_17_ATI 0x8932 -#define GL_REG_18_ATI 0x8933 -#define GL_REG_19_ATI 0x8934 -#define GL_REG_20_ATI 0x8935 -#define GL_REG_21_ATI 0x8936 -#define GL_REG_22_ATI 0x8937 -#define GL_REG_23_ATI 0x8938 -#define GL_REG_24_ATI 0x8939 -#define GL_REG_25_ATI 0x893A -#define GL_REG_26_ATI 0x893B -#define GL_REG_27_ATI 0x893C -#define GL_REG_28_ATI 0x893D -#define GL_REG_29_ATI 0x893E -#define GL_REG_30_ATI 0x893F -#define GL_REG_31_ATI 0x8940 -#define GL_CON_0_ATI 0x8941 -#define GL_CON_1_ATI 0x8942 -#define GL_CON_2_ATI 0x8943 -#define GL_CON_3_ATI 0x8944 -#define GL_CON_4_ATI 0x8945 -#define GL_CON_5_ATI 0x8946 -#define GL_CON_6_ATI 0x8947 -#define GL_CON_7_ATI 0x8948 -#define GL_CON_8_ATI 0x8949 -#define GL_CON_9_ATI 0x894A -#define GL_CON_10_ATI 0x894B -#define GL_CON_11_ATI 0x894C -#define GL_CON_12_ATI 0x894D -#define GL_CON_13_ATI 0x894E -#define GL_CON_14_ATI 0x894F -#define GL_CON_15_ATI 0x8950 -#define GL_CON_16_ATI 0x8951 -#define GL_CON_17_ATI 0x8952 -#define GL_CON_18_ATI 0x8953 -#define GL_CON_19_ATI 0x8954 -#define GL_CON_20_ATI 0x8955 -#define GL_CON_21_ATI 0x8956 -#define GL_CON_22_ATI 0x8957 -#define GL_CON_23_ATI 0x8958 -#define GL_CON_24_ATI 0x8959 -#define GL_CON_25_ATI 0x895A -#define GL_CON_26_ATI 0x895B -#define GL_CON_27_ATI 0x895C -#define GL_CON_28_ATI 0x895D -#define GL_CON_29_ATI 0x895E -#define GL_CON_30_ATI 0x895F -#define GL_CON_31_ATI 0x8960 -#define GL_MOV_ATI 0x8961 -#define GL_ADD_ATI 0x8963 -#define GL_MUL_ATI 0x8964 -#define GL_SUB_ATI 0x8965 -#define GL_DOT3_ATI 0x8966 -#define GL_DOT4_ATI 0x8967 -#define GL_MAD_ATI 0x8968 -#define GL_LERP_ATI 0x8969 -#define GL_CND_ATI 0x896A -#define GL_CND0_ATI 0x896B -#define GL_DOT2_ADD_ATI 0x896C -#define GL_SECONDARY_INTERPOLATOR_ATI 0x896D -#define GL_NUM_FRAGMENT_REGISTERS_ATI 0x896E -#define GL_NUM_FRAGMENT_CONSTANTS_ATI 0x896F -#define GL_NUM_PASSES_ATI 0x8970 -#define GL_NUM_INSTRUCTIONS_PER_PASS_ATI 0x8971 -#define GL_NUM_INSTRUCTIONS_TOTAL_ATI 0x8972 -#define GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI 0x8973 -#define GL_NUM_LOOPBACK_COMPONENTS_ATI 0x8974 -#define GL_COLOR_ALPHA_PAIRING_ATI 0x8975 -#define GL_SWIZZLE_STR_ATI 0x8976 -#define GL_SWIZZLE_STQ_ATI 0x8977 -#define GL_SWIZZLE_STR_DR_ATI 0x8978 -#define GL_SWIZZLE_STQ_DQ_ATI 0x8979 -#define GL_SWIZZLE_STRQ_ATI 0x897A -#define GL_SWIZZLE_STRQ_DQ_ATI 0x897B -#define GL_RED_BIT_ATI 0x00000001 -#define GL_GREEN_BIT_ATI 0x00000002 -#define GL_BLUE_BIT_ATI 0x00000004 -#define GL_2X_BIT_ATI 0x00000001 -#define GL_4X_BIT_ATI 0x00000002 -#define GL_8X_BIT_ATI 0x00000004 -#define GL_HALF_BIT_ATI 0x00000008 -#define GL_QUARTER_BIT_ATI 0x00000010 -#define GL_EIGHTH_BIT_ATI 0x00000020 -#define GL_SATURATE_BIT_ATI 0x00000040 -#define GL_COMP_BIT_ATI 0x00000002 -#define GL_NEGATE_BIT_ATI 0x00000004 -#define GL_BIAS_BIT_ATI 0x00000008 -typedef GLuint (APIENTRYP PFNGLGENFRAGMENTSHADERSATIPROC) (GLuint range); -typedef void (APIENTRYP PFNGLBINDFRAGMENTSHADERATIPROC) (GLuint id); -typedef void (APIENTRYP PFNGLDELETEFRAGMENTSHADERATIPROC) (GLuint id); -typedef void (APIENTRYP PFNGLBEGINFRAGMENTSHADERATIPROC) (void); -typedef void (APIENTRYP PFNGLENDFRAGMENTSHADERATIPROC) (void); -typedef void (APIENTRYP PFNGLPASSTEXCOORDATIPROC) (GLuint dst, GLuint coord, GLenum swizzle); -typedef void (APIENTRYP PFNGLSAMPLEMAPATIPROC) (GLuint dst, GLuint interp, GLenum swizzle); -typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); -typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); -typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); -typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); -typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); -typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); -typedef void (APIENTRYP PFNGLSETFRAGMENTSHADERCONSTANTATIPROC) (GLuint dst, const GLfloat *value); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLuint APIENTRY glGenFragmentShadersATI (GLuint range); -GLAPI void APIENTRY glBindFragmentShaderATI (GLuint id); -GLAPI void APIENTRY glDeleteFragmentShaderATI (GLuint id); -GLAPI void APIENTRY glBeginFragmentShaderATI (void); -GLAPI void APIENTRY glEndFragmentShaderATI (void); -GLAPI void APIENTRY glPassTexCoordATI (GLuint dst, GLuint coord, GLenum swizzle); -GLAPI void APIENTRY glSampleMapATI (GLuint dst, GLuint interp, GLenum swizzle); -GLAPI void APIENTRY glColorFragmentOp1ATI (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); -GLAPI void APIENTRY glColorFragmentOp2ATI (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); -GLAPI void APIENTRY glColorFragmentOp3ATI (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); -GLAPI void APIENTRY glAlphaFragmentOp1ATI (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); -GLAPI void APIENTRY glAlphaFragmentOp2ATI (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); -GLAPI void APIENTRY glAlphaFragmentOp3ATI (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); -GLAPI void APIENTRY glSetFragmentShaderConstantATI (GLuint dst, const GLfloat *value); -#endif -#endif /* GL_ATI_fragment_shader */ - -#ifndef GL_ATI_map_object_buffer -#define GL_ATI_map_object_buffer 1 -typedef void *(APIENTRYP PFNGLMAPOBJECTBUFFERATIPROC) (GLuint buffer); -typedef void (APIENTRYP PFNGLUNMAPOBJECTBUFFERATIPROC) (GLuint buffer); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void *APIENTRY glMapObjectBufferATI (GLuint buffer); -GLAPI void APIENTRY glUnmapObjectBufferATI (GLuint buffer); -#endif -#endif /* GL_ATI_map_object_buffer */ - -#ifndef GL_ATI_meminfo -#define GL_ATI_meminfo 1 -#define GL_VBO_FREE_MEMORY_ATI 0x87FB -#define GL_TEXTURE_FREE_MEMORY_ATI 0x87FC -#define GL_RENDERBUFFER_FREE_MEMORY_ATI 0x87FD -#endif /* GL_ATI_meminfo */ - -#ifndef GL_ATI_pixel_format_float -#define GL_ATI_pixel_format_float 1 -#define GL_RGBA_FLOAT_MODE_ATI 0x8820 -#define GL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI 0x8835 -#endif /* GL_ATI_pixel_format_float */ - -#ifndef GL_ATI_pn_triangles -#define GL_ATI_pn_triangles 1 -#define GL_PN_TRIANGLES_ATI 0x87F0 -#define GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F1 -#define GL_PN_TRIANGLES_POINT_MODE_ATI 0x87F2 -#define GL_PN_TRIANGLES_NORMAL_MODE_ATI 0x87F3 -#define GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F4 -#define GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI 0x87F5 -#define GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI 0x87F6 -#define GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7 -#define GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8 -typedef void (APIENTRYP PFNGLPNTRIANGLESIATIPROC) (GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLPNTRIANGLESFATIPROC) (GLenum pname, GLfloat param); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPNTrianglesiATI (GLenum pname, GLint param); -GLAPI void APIENTRY glPNTrianglesfATI (GLenum pname, GLfloat param); -#endif -#endif /* GL_ATI_pn_triangles */ - -#ifndef GL_ATI_separate_stencil -#define GL_ATI_separate_stencil 1 -#define GL_STENCIL_BACK_FUNC_ATI 0x8800 -#define GL_STENCIL_BACK_FAIL_ATI 0x8801 -#define GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI 0x8802 -#define GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI 0x8803 -typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEATIPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); -typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEATIPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glStencilOpSeparateATI (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); -GLAPI void APIENTRY glStencilFuncSeparateATI (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); -#endif -#endif /* GL_ATI_separate_stencil */ - -#ifndef GL_ATI_text_fragment_shader -#define GL_ATI_text_fragment_shader 1 -#define GL_TEXT_FRAGMENT_SHADER_ATI 0x8200 -#endif /* GL_ATI_text_fragment_shader */ - -#ifndef GL_ATI_texture_env_combine3 -#define GL_ATI_texture_env_combine3 1 -#define GL_MODULATE_ADD_ATI 0x8744 -#define GL_MODULATE_SIGNED_ADD_ATI 0x8745 -#define GL_MODULATE_SUBTRACT_ATI 0x8746 -#endif /* GL_ATI_texture_env_combine3 */ - -#ifndef GL_ATI_texture_float -#define GL_ATI_texture_float 1 -#define GL_RGBA_FLOAT32_ATI 0x8814 -#define GL_RGB_FLOAT32_ATI 0x8815 -#define GL_ALPHA_FLOAT32_ATI 0x8816 -#define GL_INTENSITY_FLOAT32_ATI 0x8817 -#define GL_LUMINANCE_FLOAT32_ATI 0x8818 -#define GL_LUMINANCE_ALPHA_FLOAT32_ATI 0x8819 -#define GL_RGBA_FLOAT16_ATI 0x881A -#define GL_RGB_FLOAT16_ATI 0x881B -#define GL_ALPHA_FLOAT16_ATI 0x881C -#define GL_INTENSITY_FLOAT16_ATI 0x881D -#define GL_LUMINANCE_FLOAT16_ATI 0x881E -#define GL_LUMINANCE_ALPHA_FLOAT16_ATI 0x881F -#endif /* GL_ATI_texture_float */ - -#ifndef GL_ATI_texture_mirror_once -#define GL_ATI_texture_mirror_once 1 -#define GL_MIRROR_CLAMP_ATI 0x8742 -#define GL_MIRROR_CLAMP_TO_EDGE_ATI 0x8743 -#endif /* GL_ATI_texture_mirror_once */ - -#ifndef GL_ATI_vertex_array_object -#define GL_ATI_vertex_array_object 1 -#define GL_STATIC_ATI 0x8760 -#define GL_DYNAMIC_ATI 0x8761 -#define GL_PRESERVE_ATI 0x8762 -#define GL_DISCARD_ATI 0x8763 -#define GL_OBJECT_BUFFER_SIZE_ATI 0x8764 -#define GL_OBJECT_BUFFER_USAGE_ATI 0x8765 -#define GL_ARRAY_OBJECT_BUFFER_ATI 0x8766 -#define GL_ARRAY_OBJECT_OFFSET_ATI 0x8767 -typedef GLuint (APIENTRYP PFNGLNEWOBJECTBUFFERATIPROC) (GLsizei size, const void *pointer, GLenum usage); -typedef GLboolean (APIENTRYP PFNGLISOBJECTBUFFERATIPROC) (GLuint buffer); -typedef void (APIENTRYP PFNGLUPDATEOBJECTBUFFERATIPROC) (GLuint buffer, GLuint offset, GLsizei size, const void *pointer, GLenum preserve); -typedef void (APIENTRYP PFNGLGETOBJECTBUFFERFVATIPROC) (GLuint buffer, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETOBJECTBUFFERIVATIPROC) (GLuint buffer, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLFREEOBJECTBUFFERATIPROC) (GLuint buffer); -typedef void (APIENTRYP PFNGLARRAYOBJECTATIPROC) (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); -typedef void (APIENTRYP PFNGLGETARRAYOBJECTFVATIPROC) (GLenum array, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETARRAYOBJECTIVATIPROC) (GLenum array, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLVARIANTARRAYOBJECTATIPROC) (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); -typedef void (APIENTRYP PFNGLGETVARIANTARRAYOBJECTFVATIPROC) (GLuint id, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETVARIANTARRAYOBJECTIVATIPROC) (GLuint id, GLenum pname, GLint *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLuint APIENTRY glNewObjectBufferATI (GLsizei size, const void *pointer, GLenum usage); -GLAPI GLboolean APIENTRY glIsObjectBufferATI (GLuint buffer); -GLAPI void APIENTRY glUpdateObjectBufferATI (GLuint buffer, GLuint offset, GLsizei size, const void *pointer, GLenum preserve); -GLAPI void APIENTRY glGetObjectBufferfvATI (GLuint buffer, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetObjectBufferivATI (GLuint buffer, GLenum pname, GLint *params); -GLAPI void APIENTRY glFreeObjectBufferATI (GLuint buffer); -GLAPI void APIENTRY glArrayObjectATI (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); -GLAPI void APIENTRY glGetArrayObjectfvATI (GLenum array, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetArrayObjectivATI (GLenum array, GLenum pname, GLint *params); -GLAPI void APIENTRY glVariantArrayObjectATI (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); -GLAPI void APIENTRY glGetVariantArrayObjectfvATI (GLuint id, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetVariantArrayObjectivATI (GLuint id, GLenum pname, GLint *params); -#endif -#endif /* GL_ATI_vertex_array_object */ - -#ifndef GL_ATI_vertex_attrib_array_object -#define GL_ATI_vertex_attrib_array_object 1 -typedef void (APIENTRYP PFNGLVERTEXATTRIBARRAYOBJECTATIPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC) (GLuint index, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC) (GLuint index, GLenum pname, GLint *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexAttribArrayObjectATI (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset); -GLAPI void APIENTRY glGetVertexAttribArrayObjectfvATI (GLuint index, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetVertexAttribArrayObjectivATI (GLuint index, GLenum pname, GLint *params); -#endif -#endif /* GL_ATI_vertex_attrib_array_object */ - -#ifndef GL_ATI_vertex_streams -#define GL_ATI_vertex_streams 1 -#define GL_MAX_VERTEX_STREAMS_ATI 0x876B -#define GL_VERTEX_STREAM0_ATI 0x876C -#define GL_VERTEX_STREAM1_ATI 0x876D -#define GL_VERTEX_STREAM2_ATI 0x876E -#define GL_VERTEX_STREAM3_ATI 0x876F -#define GL_VERTEX_STREAM4_ATI 0x8770 -#define GL_VERTEX_STREAM5_ATI 0x8771 -#define GL_VERTEX_STREAM6_ATI 0x8772 -#define GL_VERTEX_STREAM7_ATI 0x8773 -#define GL_VERTEX_SOURCE_ATI 0x8774 -typedef void (APIENTRYP PFNGLVERTEXSTREAM1SATIPROC) (GLenum stream, GLshort x); -typedef void (APIENTRYP PFNGLVERTEXSTREAM1SVATIPROC) (GLenum stream, const GLshort *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM1IATIPROC) (GLenum stream, GLint x); -typedef void (APIENTRYP PFNGLVERTEXSTREAM1IVATIPROC) (GLenum stream, const GLint *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM1FATIPROC) (GLenum stream, GLfloat x); -typedef void (APIENTRYP PFNGLVERTEXSTREAM1FVATIPROC) (GLenum stream, const GLfloat *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM1DATIPROC) (GLenum stream, GLdouble x); -typedef void (APIENTRYP PFNGLVERTEXSTREAM1DVATIPROC) (GLenum stream, const GLdouble *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM2SATIPROC) (GLenum stream, GLshort x, GLshort y); -typedef void (APIENTRYP PFNGLVERTEXSTREAM2SVATIPROC) (GLenum stream, const GLshort *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM2IATIPROC) (GLenum stream, GLint x, GLint y); -typedef void (APIENTRYP PFNGLVERTEXSTREAM2IVATIPROC) (GLenum stream, const GLint *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM2FATIPROC) (GLenum stream, GLfloat x, GLfloat y); -typedef void (APIENTRYP PFNGLVERTEXSTREAM2FVATIPROC) (GLenum stream, const GLfloat *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM2DATIPROC) (GLenum stream, GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLVERTEXSTREAM2DVATIPROC) (GLenum stream, const GLdouble *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM3SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z); -typedef void (APIENTRYP PFNGLVERTEXSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM3IATIPROC) (GLenum stream, GLint x, GLint y, GLint z); -typedef void (APIENTRYP PFNGLVERTEXSTREAM3IVATIPROC) (GLenum stream, const GLint *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM3FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLVERTEXSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM3DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLVERTEXSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM4SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w); -typedef void (APIENTRYP PFNGLVERTEXSTREAM4SVATIPROC) (GLenum stream, const GLshort *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM4IATIPROC) (GLenum stream, GLint x, GLint y, GLint z, GLint w); -typedef void (APIENTRYP PFNGLVERTEXSTREAM4IVATIPROC) (GLenum stream, const GLint *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM4FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLVERTEXSTREAM4FVATIPROC) (GLenum stream, const GLfloat *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM4DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLVERTEXSTREAM4DVATIPROC) (GLenum stream, const GLdouble *coords); -typedef void (APIENTRYP PFNGLNORMALSTREAM3BATIPROC) (GLenum stream, GLbyte nx, GLbyte ny, GLbyte nz); -typedef void (APIENTRYP PFNGLNORMALSTREAM3BVATIPROC) (GLenum stream, const GLbyte *coords); -typedef void (APIENTRYP PFNGLNORMALSTREAM3SATIPROC) (GLenum stream, GLshort nx, GLshort ny, GLshort nz); -typedef void (APIENTRYP PFNGLNORMALSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords); -typedef void (APIENTRYP PFNGLNORMALSTREAM3IATIPROC) (GLenum stream, GLint nx, GLint ny, GLint nz); -typedef void (APIENTRYP PFNGLNORMALSTREAM3IVATIPROC) (GLenum stream, const GLint *coords); -typedef void (APIENTRYP PFNGLNORMALSTREAM3FATIPROC) (GLenum stream, GLfloat nx, GLfloat ny, GLfloat nz); -typedef void (APIENTRYP PFNGLNORMALSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords); -typedef void (APIENTRYP PFNGLNORMALSTREAM3DATIPROC) (GLenum stream, GLdouble nx, GLdouble ny, GLdouble nz); -typedef void (APIENTRYP PFNGLNORMALSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords); -typedef void (APIENTRYP PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC) (GLenum stream); -typedef void (APIENTRYP PFNGLVERTEXBLENDENVIATIPROC) (GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLVERTEXBLENDENVFATIPROC) (GLenum pname, GLfloat param); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexStream1sATI (GLenum stream, GLshort x); -GLAPI void APIENTRY glVertexStream1svATI (GLenum stream, const GLshort *coords); -GLAPI void APIENTRY glVertexStream1iATI (GLenum stream, GLint x); -GLAPI void APIENTRY glVertexStream1ivATI (GLenum stream, const GLint *coords); -GLAPI void APIENTRY glVertexStream1fATI (GLenum stream, GLfloat x); -GLAPI void APIENTRY glVertexStream1fvATI (GLenum stream, const GLfloat *coords); -GLAPI void APIENTRY glVertexStream1dATI (GLenum stream, GLdouble x); -GLAPI void APIENTRY glVertexStream1dvATI (GLenum stream, const GLdouble *coords); -GLAPI void APIENTRY glVertexStream2sATI (GLenum stream, GLshort x, GLshort y); -GLAPI void APIENTRY glVertexStream2svATI (GLenum stream, const GLshort *coords); -GLAPI void APIENTRY glVertexStream2iATI (GLenum stream, GLint x, GLint y); -GLAPI void APIENTRY glVertexStream2ivATI (GLenum stream, const GLint *coords); -GLAPI void APIENTRY glVertexStream2fATI (GLenum stream, GLfloat x, GLfloat y); -GLAPI void APIENTRY glVertexStream2fvATI (GLenum stream, const GLfloat *coords); -GLAPI void APIENTRY glVertexStream2dATI (GLenum stream, GLdouble x, GLdouble y); -GLAPI void APIENTRY glVertexStream2dvATI (GLenum stream, const GLdouble *coords); -GLAPI void APIENTRY glVertexStream3sATI (GLenum stream, GLshort x, GLshort y, GLshort z); -GLAPI void APIENTRY glVertexStream3svATI (GLenum stream, const GLshort *coords); -GLAPI void APIENTRY glVertexStream3iATI (GLenum stream, GLint x, GLint y, GLint z); -GLAPI void APIENTRY glVertexStream3ivATI (GLenum stream, const GLint *coords); -GLAPI void APIENTRY glVertexStream3fATI (GLenum stream, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glVertexStream3fvATI (GLenum stream, const GLfloat *coords); -GLAPI void APIENTRY glVertexStream3dATI (GLenum stream, GLdouble x, GLdouble y, GLdouble z); -GLAPI void APIENTRY glVertexStream3dvATI (GLenum stream, const GLdouble *coords); -GLAPI void APIENTRY glVertexStream4sATI (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w); -GLAPI void APIENTRY glVertexStream4svATI (GLenum stream, const GLshort *coords); -GLAPI void APIENTRY glVertexStream4iATI (GLenum stream, GLint x, GLint y, GLint z, GLint w); -GLAPI void APIENTRY glVertexStream4ivATI (GLenum stream, const GLint *coords); -GLAPI void APIENTRY glVertexStream4fATI (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI void APIENTRY glVertexStream4fvATI (GLenum stream, const GLfloat *coords); -GLAPI void APIENTRY glVertexStream4dATI (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void APIENTRY glVertexStream4dvATI (GLenum stream, const GLdouble *coords); -GLAPI void APIENTRY glNormalStream3bATI (GLenum stream, GLbyte nx, GLbyte ny, GLbyte nz); -GLAPI void APIENTRY glNormalStream3bvATI (GLenum stream, const GLbyte *coords); -GLAPI void APIENTRY glNormalStream3sATI (GLenum stream, GLshort nx, GLshort ny, GLshort nz); -GLAPI void APIENTRY glNormalStream3svATI (GLenum stream, const GLshort *coords); -GLAPI void APIENTRY glNormalStream3iATI (GLenum stream, GLint nx, GLint ny, GLint nz); -GLAPI void APIENTRY glNormalStream3ivATI (GLenum stream, const GLint *coords); -GLAPI void APIENTRY glNormalStream3fATI (GLenum stream, GLfloat nx, GLfloat ny, GLfloat nz); -GLAPI void APIENTRY glNormalStream3fvATI (GLenum stream, const GLfloat *coords); -GLAPI void APIENTRY glNormalStream3dATI (GLenum stream, GLdouble nx, GLdouble ny, GLdouble nz); -GLAPI void APIENTRY glNormalStream3dvATI (GLenum stream, const GLdouble *coords); -GLAPI void APIENTRY glClientActiveVertexStreamATI (GLenum stream); -GLAPI void APIENTRY glVertexBlendEnviATI (GLenum pname, GLint param); -GLAPI void APIENTRY glVertexBlendEnvfATI (GLenum pname, GLfloat param); -#endif -#endif /* GL_ATI_vertex_streams */ - -#ifndef GL_EXT_422_pixels -#define GL_EXT_422_pixels 1 -#define GL_422_EXT 0x80CC -#define GL_422_REV_EXT 0x80CD -#define GL_422_AVERAGE_EXT 0x80CE -#define GL_422_REV_AVERAGE_EXT 0x80CF -#endif /* GL_EXT_422_pixels */ - -#ifndef GL_EXT_abgr -#define GL_EXT_abgr 1 -#define GL_ABGR_EXT 0x8000 -#endif /* GL_EXT_abgr */ - -#ifndef GL_EXT_bgra -#define GL_EXT_bgra 1 -#define GL_BGR_EXT 0x80E0 -#define GL_BGRA_EXT 0x80E1 -#endif /* GL_EXT_bgra */ - -#ifndef GL_EXT_bindable_uniform -#define GL_EXT_bindable_uniform 1 -#define GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT 0x8DE2 -#define GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT 0x8DE3 -#define GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT 0x8DE4 -#define GL_MAX_BINDABLE_UNIFORM_SIZE_EXT 0x8DED -#define GL_UNIFORM_BUFFER_EXT 0x8DEE -#define GL_UNIFORM_BUFFER_BINDING_EXT 0x8DEF -typedef void (APIENTRYP PFNGLUNIFORMBUFFEREXTPROC) (GLuint program, GLint location, GLuint buffer); -typedef GLint (APIENTRYP PFNGLGETUNIFORMBUFFERSIZEEXTPROC) (GLuint program, GLint location); -typedef GLintptr (APIENTRYP PFNGLGETUNIFORMOFFSETEXTPROC) (GLuint program, GLint location); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glUniformBufferEXT (GLuint program, GLint location, GLuint buffer); -GLAPI GLint APIENTRY glGetUniformBufferSizeEXT (GLuint program, GLint location); -GLAPI GLintptr APIENTRY glGetUniformOffsetEXT (GLuint program, GLint location); -#endif -#endif /* GL_EXT_bindable_uniform */ - -#ifndef GL_EXT_blend_color -#define GL_EXT_blend_color 1 -#define GL_CONSTANT_COLOR_EXT 0x8001 -#define GL_ONE_MINUS_CONSTANT_COLOR_EXT 0x8002 -#define GL_CONSTANT_ALPHA_EXT 0x8003 -#define GL_ONE_MINUS_CONSTANT_ALPHA_EXT 0x8004 -#define GL_BLEND_COLOR_EXT 0x8005 -typedef void (APIENTRYP PFNGLBLENDCOLOREXTPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendColorEXT (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); -#endif -#endif /* GL_EXT_blend_color */ - -#ifndef GL_EXT_blend_equation_separate -#define GL_EXT_blend_equation_separate 1 -#define GL_BLEND_EQUATION_RGB_EXT 0x8009 -#define GL_BLEND_EQUATION_ALPHA_EXT 0x883D -typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEEXTPROC) (GLenum modeRGB, GLenum modeAlpha); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendEquationSeparateEXT (GLenum modeRGB, GLenum modeAlpha); -#endif -#endif /* GL_EXT_blend_equation_separate */ - -#ifndef GL_EXT_blend_func_separate -#define GL_EXT_blend_func_separate 1 -#define GL_BLEND_DST_RGB_EXT 0x80C8 -#define GL_BLEND_SRC_RGB_EXT 0x80C9 -#define GL_BLEND_DST_ALPHA_EXT 0x80CA -#define GL_BLEND_SRC_ALPHA_EXT 0x80CB -typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEEXTPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendFuncSeparateEXT (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); -#endif -#endif /* GL_EXT_blend_func_separate */ - -#ifndef GL_EXT_blend_logic_op -#define GL_EXT_blend_logic_op 1 -#endif /* GL_EXT_blend_logic_op */ - -#ifndef GL_EXT_blend_minmax -#define GL_EXT_blend_minmax 1 -#define GL_MIN_EXT 0x8007 -#define GL_MAX_EXT 0x8008 -#define GL_FUNC_ADD_EXT 0x8006 -#define GL_BLEND_EQUATION_EXT 0x8009 -typedef void (APIENTRYP PFNGLBLENDEQUATIONEXTPROC) (GLenum mode); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendEquationEXT (GLenum mode); -#endif -#endif /* GL_EXT_blend_minmax */ - -#ifndef GL_EXT_blend_subtract -#define GL_EXT_blend_subtract 1 -#define GL_FUNC_SUBTRACT_EXT 0x800A -#define GL_FUNC_REVERSE_SUBTRACT_EXT 0x800B -#endif /* GL_EXT_blend_subtract */ - -#ifndef GL_EXT_clip_volume_hint -#define GL_EXT_clip_volume_hint 1 -#define GL_CLIP_VOLUME_CLIPPING_HINT_EXT 0x80F0 -#endif /* GL_EXT_clip_volume_hint */ - -#ifndef GL_EXT_cmyka -#define GL_EXT_cmyka 1 -#define GL_CMYK_EXT 0x800C -#define GL_CMYKA_EXT 0x800D -#define GL_PACK_CMYK_HINT_EXT 0x800E -#define GL_UNPACK_CMYK_HINT_EXT 0x800F -#endif /* GL_EXT_cmyka */ - -#ifndef GL_EXT_color_subtable -#define GL_EXT_color_subtable 1 -typedef void (APIENTRYP PFNGLCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const void *data); -typedef void (APIENTRYP PFNGLCOPYCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glColorSubTableEXT (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const void *data); -GLAPI void APIENTRY glCopyColorSubTableEXT (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); -#endif -#endif /* GL_EXT_color_subtable */ - -#ifndef GL_EXT_compiled_vertex_array -#define GL_EXT_compiled_vertex_array 1 -#define GL_ARRAY_ELEMENT_LOCK_FIRST_EXT 0x81A8 -#define GL_ARRAY_ELEMENT_LOCK_COUNT_EXT 0x81A9 -typedef void (APIENTRYP PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count); -typedef void (APIENTRYP PFNGLUNLOCKARRAYSEXTPROC) (void); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glLockArraysEXT (GLint first, GLsizei count); -GLAPI void APIENTRY glUnlockArraysEXT (void); -#endif -#endif /* GL_EXT_compiled_vertex_array */ - -#ifndef GL_EXT_convolution -#define GL_EXT_convolution 1 -#define GL_CONVOLUTION_1D_EXT 0x8010 -#define GL_CONVOLUTION_2D_EXT 0x8011 -#define GL_SEPARABLE_2D_EXT 0x8012 -#define GL_CONVOLUTION_BORDER_MODE_EXT 0x8013 -#define GL_CONVOLUTION_FILTER_SCALE_EXT 0x8014 -#define GL_CONVOLUTION_FILTER_BIAS_EXT 0x8015 -#define GL_REDUCE_EXT 0x8016 -#define GL_CONVOLUTION_FORMAT_EXT 0x8017 -#define GL_CONVOLUTION_WIDTH_EXT 0x8018 -#define GL_CONVOLUTION_HEIGHT_EXT 0x8019 -#define GL_MAX_CONVOLUTION_WIDTH_EXT 0x801A -#define GL_MAX_CONVOLUTION_HEIGHT_EXT 0x801B -#define GL_POST_CONVOLUTION_RED_SCALE_EXT 0x801C -#define GL_POST_CONVOLUTION_GREEN_SCALE_EXT 0x801D -#define GL_POST_CONVOLUTION_BLUE_SCALE_EXT 0x801E -#define GL_POST_CONVOLUTION_ALPHA_SCALE_EXT 0x801F -#define GL_POST_CONVOLUTION_RED_BIAS_EXT 0x8020 -#define GL_POST_CONVOLUTION_GREEN_BIAS_EXT 0x8021 -#define GL_POST_CONVOLUTION_BLUE_BIAS_EXT 0x8022 -#define GL_POST_CONVOLUTION_ALPHA_BIAS_EXT 0x8023 -typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *image); -typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *image); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat params); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint params); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); -typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLGETCONVOLUTIONFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, void *image); -typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETSEPARABLEFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, void *row, void *column, void *span); -typedef void (APIENTRYP PFNGLSEPARABLEFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *row, const void *column); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glConvolutionFilter1DEXT (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *image); -GLAPI void APIENTRY glConvolutionFilter2DEXT (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *image); -GLAPI void APIENTRY glConvolutionParameterfEXT (GLenum target, GLenum pname, GLfloat params); -GLAPI void APIENTRY glConvolutionParameterfvEXT (GLenum target, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glConvolutionParameteriEXT (GLenum target, GLenum pname, GLint params); -GLAPI void APIENTRY glConvolutionParameterivEXT (GLenum target, GLenum pname, const GLint *params); -GLAPI void APIENTRY glCopyConvolutionFilter1DEXT (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); -GLAPI void APIENTRY glCopyConvolutionFilter2DEXT (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); -GLAPI void APIENTRY glGetConvolutionFilterEXT (GLenum target, GLenum format, GLenum type, void *image); -GLAPI void APIENTRY glGetConvolutionParameterfvEXT (GLenum target, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetConvolutionParameterivEXT (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetSeparableFilterEXT (GLenum target, GLenum format, GLenum type, void *row, void *column, void *span); -GLAPI void APIENTRY glSeparableFilter2DEXT (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *row, const void *column); -#endif -#endif /* GL_EXT_convolution */ - -#ifndef GL_EXT_coordinate_frame -#define GL_EXT_coordinate_frame 1 -#define GL_TANGENT_ARRAY_EXT 0x8439 -#define GL_BINORMAL_ARRAY_EXT 0x843A -#define GL_CURRENT_TANGENT_EXT 0x843B -#define GL_CURRENT_BINORMAL_EXT 0x843C -#define GL_TANGENT_ARRAY_TYPE_EXT 0x843E -#define GL_TANGENT_ARRAY_STRIDE_EXT 0x843F -#define GL_BINORMAL_ARRAY_TYPE_EXT 0x8440 -#define GL_BINORMAL_ARRAY_STRIDE_EXT 0x8441 -#define GL_TANGENT_ARRAY_POINTER_EXT 0x8442 -#define GL_BINORMAL_ARRAY_POINTER_EXT 0x8443 -#define GL_MAP1_TANGENT_EXT 0x8444 -#define GL_MAP2_TANGENT_EXT 0x8445 -#define GL_MAP1_BINORMAL_EXT 0x8446 -#define GL_MAP2_BINORMAL_EXT 0x8447 -typedef void (APIENTRYP PFNGLTANGENT3BEXTPROC) (GLbyte tx, GLbyte ty, GLbyte tz); -typedef void (APIENTRYP PFNGLTANGENT3BVEXTPROC) (const GLbyte *v); -typedef void (APIENTRYP PFNGLTANGENT3DEXTPROC) (GLdouble tx, GLdouble ty, GLdouble tz); -typedef void (APIENTRYP PFNGLTANGENT3DVEXTPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLTANGENT3FEXTPROC) (GLfloat tx, GLfloat ty, GLfloat tz); -typedef void (APIENTRYP PFNGLTANGENT3FVEXTPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLTANGENT3IEXTPROC) (GLint tx, GLint ty, GLint tz); -typedef void (APIENTRYP PFNGLTANGENT3IVEXTPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLTANGENT3SEXTPROC) (GLshort tx, GLshort ty, GLshort tz); -typedef void (APIENTRYP PFNGLTANGENT3SVEXTPROC) (const GLshort *v); -typedef void (APIENTRYP PFNGLBINORMAL3BEXTPROC) (GLbyte bx, GLbyte by, GLbyte bz); -typedef void (APIENTRYP PFNGLBINORMAL3BVEXTPROC) (const GLbyte *v); -typedef void (APIENTRYP PFNGLBINORMAL3DEXTPROC) (GLdouble bx, GLdouble by, GLdouble bz); -typedef void (APIENTRYP PFNGLBINORMAL3DVEXTPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLBINORMAL3FEXTPROC) (GLfloat bx, GLfloat by, GLfloat bz); -typedef void (APIENTRYP PFNGLBINORMAL3FVEXTPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLBINORMAL3IEXTPROC) (GLint bx, GLint by, GLint bz); -typedef void (APIENTRYP PFNGLBINORMAL3IVEXTPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLBINORMAL3SEXTPROC) (GLshort bx, GLshort by, GLshort bz); -typedef void (APIENTRYP PFNGLBINORMAL3SVEXTPROC) (const GLshort *v); -typedef void (APIENTRYP PFNGLTANGENTPOINTEREXTPROC) (GLenum type, GLsizei stride, const void *pointer); -typedef void (APIENTRYP PFNGLBINORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, const void *pointer); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTangent3bEXT (GLbyte tx, GLbyte ty, GLbyte tz); -GLAPI void APIENTRY glTangent3bvEXT (const GLbyte *v); -GLAPI void APIENTRY glTangent3dEXT (GLdouble tx, GLdouble ty, GLdouble tz); -GLAPI void APIENTRY glTangent3dvEXT (const GLdouble *v); -GLAPI void APIENTRY glTangent3fEXT (GLfloat tx, GLfloat ty, GLfloat tz); -GLAPI void APIENTRY glTangent3fvEXT (const GLfloat *v); -GLAPI void APIENTRY glTangent3iEXT (GLint tx, GLint ty, GLint tz); -GLAPI void APIENTRY glTangent3ivEXT (const GLint *v); -GLAPI void APIENTRY glTangent3sEXT (GLshort tx, GLshort ty, GLshort tz); -GLAPI void APIENTRY glTangent3svEXT (const GLshort *v); -GLAPI void APIENTRY glBinormal3bEXT (GLbyte bx, GLbyte by, GLbyte bz); -GLAPI void APIENTRY glBinormal3bvEXT (const GLbyte *v); -GLAPI void APIENTRY glBinormal3dEXT (GLdouble bx, GLdouble by, GLdouble bz); -GLAPI void APIENTRY glBinormal3dvEXT (const GLdouble *v); -GLAPI void APIENTRY glBinormal3fEXT (GLfloat bx, GLfloat by, GLfloat bz); -GLAPI void APIENTRY glBinormal3fvEXT (const GLfloat *v); -GLAPI void APIENTRY glBinormal3iEXT (GLint bx, GLint by, GLint bz); -GLAPI void APIENTRY glBinormal3ivEXT (const GLint *v); -GLAPI void APIENTRY glBinormal3sEXT (GLshort bx, GLshort by, GLshort bz); -GLAPI void APIENTRY glBinormal3svEXT (const GLshort *v); -GLAPI void APIENTRY glTangentPointerEXT (GLenum type, GLsizei stride, const void *pointer); -GLAPI void APIENTRY glBinormalPointerEXT (GLenum type, GLsizei stride, const void *pointer); -#endif -#endif /* GL_EXT_coordinate_frame */ - -#ifndef GL_EXT_copy_texture -#define GL_EXT_copy_texture 1 -typedef void (APIENTRYP PFNGLCOPYTEXIMAGE1DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); -typedef void (APIENTRYP PFNGLCOPYTEXIMAGE2DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); -typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); -typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glCopyTexImage1DEXT (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); -GLAPI void APIENTRY glCopyTexImage2DEXT (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); -GLAPI void APIENTRY glCopyTexSubImage1DEXT (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); -GLAPI void APIENTRY glCopyTexSubImage2DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -GLAPI void APIENTRY glCopyTexSubImage3DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -#endif -#endif /* GL_EXT_copy_texture */ - -#ifndef GL_EXT_cull_vertex -#define GL_EXT_cull_vertex 1 -#define GL_CULL_VERTEX_EXT 0x81AA -#define GL_CULL_VERTEX_EYE_POSITION_EXT 0x81AB -#define GL_CULL_VERTEX_OBJECT_POSITION_EXT 0x81AC -typedef void (APIENTRYP PFNGLCULLPARAMETERDVEXTPROC) (GLenum pname, GLdouble *params); -typedef void (APIENTRYP PFNGLCULLPARAMETERFVEXTPROC) (GLenum pname, GLfloat *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glCullParameterdvEXT (GLenum pname, GLdouble *params); -GLAPI void APIENTRY glCullParameterfvEXT (GLenum pname, GLfloat *params); -#endif -#endif /* GL_EXT_cull_vertex */ - -#ifndef GL_EXT_debug_label -#define GL_EXT_debug_label 1 -#define GL_PROGRAM_PIPELINE_OBJECT_EXT 0x8A4F -#define GL_PROGRAM_OBJECT_EXT 0x8B40 -#define GL_SHADER_OBJECT_EXT 0x8B48 -#define GL_BUFFER_OBJECT_EXT 0x9151 -#define GL_QUERY_OBJECT_EXT 0x9153 -#define GL_VERTEX_ARRAY_OBJECT_EXT 0x9154 -typedef void (APIENTRYP PFNGLLABELOBJECTEXTPROC) (GLenum type, GLuint object, GLsizei length, const GLchar *label); -typedef void (APIENTRYP PFNGLGETOBJECTLABELEXTPROC) (GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glLabelObjectEXT (GLenum type, GLuint object, GLsizei length, const GLchar *label); -GLAPI void APIENTRY glGetObjectLabelEXT (GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label); -#endif -#endif /* GL_EXT_debug_label */ - -#ifndef GL_EXT_debug_marker -#define GL_EXT_debug_marker 1 -typedef void (APIENTRYP PFNGLINSERTEVENTMARKEREXTPROC) (GLsizei length, const GLchar *marker); -typedef void (APIENTRYP PFNGLPUSHGROUPMARKEREXTPROC) (GLsizei length, const GLchar *marker); -typedef void (APIENTRYP PFNGLPOPGROUPMARKEREXTPROC) (void); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glInsertEventMarkerEXT (GLsizei length, const GLchar *marker); -GLAPI void APIENTRY glPushGroupMarkerEXT (GLsizei length, const GLchar *marker); -GLAPI void APIENTRY glPopGroupMarkerEXT (void); -#endif -#endif /* GL_EXT_debug_marker */ - -#ifndef GL_EXT_depth_bounds_test -#define GL_EXT_depth_bounds_test 1 -#define GL_DEPTH_BOUNDS_TEST_EXT 0x8890 -#define GL_DEPTH_BOUNDS_EXT 0x8891 -typedef void (APIENTRYP PFNGLDEPTHBOUNDSEXTPROC) (GLclampd zmin, GLclampd zmax); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDepthBoundsEXT (GLclampd zmin, GLclampd zmax); -#endif -#endif /* GL_EXT_depth_bounds_test */ - -#ifndef GL_EXT_direct_state_access -#define GL_EXT_direct_state_access 1 -#define GL_PROGRAM_MATRIX_EXT 0x8E2D -#define GL_TRANSPOSE_PROGRAM_MATRIX_EXT 0x8E2E -#define GL_PROGRAM_MATRIX_STACK_DEPTH_EXT 0x8E2F -typedef void (APIENTRYP PFNGLMATRIXLOADFEXTPROC) (GLenum mode, const GLfloat *m); -typedef void (APIENTRYP PFNGLMATRIXLOADDEXTPROC) (GLenum mode, const GLdouble *m); -typedef void (APIENTRYP PFNGLMATRIXMULTFEXTPROC) (GLenum mode, const GLfloat *m); -typedef void (APIENTRYP PFNGLMATRIXMULTDEXTPROC) (GLenum mode, const GLdouble *m); -typedef void (APIENTRYP PFNGLMATRIXLOADIDENTITYEXTPROC) (GLenum mode); -typedef void (APIENTRYP PFNGLMATRIXROTATEFEXTPROC) (GLenum mode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLMATRIXROTATEDEXTPROC) (GLenum mode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLMATRIXSCALEFEXTPROC) (GLenum mode, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLMATRIXSCALEDEXTPROC) (GLenum mode, GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLMATRIXTRANSLATEFEXTPROC) (GLenum mode, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLMATRIXTRANSLATEDEXTPROC) (GLenum mode, GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLMATRIXFRUSTUMEXTPROC) (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); -typedef void (APIENTRYP PFNGLMATRIXORTHOEXTPROC) (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); -typedef void (APIENTRYP PFNGLMATRIXPOPEXTPROC) (GLenum mode); -typedef void (APIENTRYP PFNGLMATRIXPUSHEXTPROC) (GLenum mode); -typedef void (APIENTRYP PFNGLCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask); -typedef void (APIENTRYP PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask); -typedef void (APIENTRYP PFNGLTEXTUREPARAMETERFEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels); -typedef void (APIENTRYP PFNGLTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); -typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); -typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); -typedef void (APIENTRYP PFNGLCOPYTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); -typedef void (APIENTRYP PFNGLCOPYTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); -typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); -typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLGETTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, void *pixels); -typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); -typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); -typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLBINDMULTITEXTUREEXTPROC) (GLenum texunit, GLenum target, GLuint texture); -typedef void (APIENTRYP PFNGLMULTITEXCOORDPOINTEREXTPROC) (GLenum texunit, GLint size, GLenum type, GLsizei stride, const void *pointer); -typedef void (APIENTRYP PFNGLMULTITEXENVFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLMULTITEXENVIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLMULTITEXGENDEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble param); -typedef void (APIENTRYP PFNGLMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLdouble *params); -typedef void (APIENTRYP PFNGLMULTITEXGENFEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLMULTITEXGENIEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLGETMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble *params); -typedef void (APIENTRYP PFNGLGETMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLMULTITEXPARAMETERFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels); -typedef void (APIENTRYP PFNGLMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); -typedef void (APIENTRYP PFNGLMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); -typedef void (APIENTRYP PFNGLMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); -typedef void (APIENTRYP PFNGLCOPYMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); -typedef void (APIENTRYP PFNGLCOPYMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); -typedef void (APIENTRYP PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); -typedef void (APIENTRYP PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLGETMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, void *pixels); -typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); -typedef void (APIENTRYP PFNGLMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); -typedef void (APIENTRYP PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLENABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index); -typedef void (APIENTRYP PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index); -typedef void (APIENTRYP PFNGLGETFLOATINDEXEDVEXTPROC) (GLenum target, GLuint index, GLfloat *data); -typedef void (APIENTRYP PFNGLGETDOUBLEINDEXEDVEXTPROC) (GLenum target, GLuint index, GLdouble *data); -typedef void (APIENTRYP PFNGLGETPOINTERINDEXEDVEXTPROC) (GLenum target, GLuint index, void **data); -typedef void (APIENTRYP PFNGLENABLEINDEXEDEXTPROC) (GLenum target, GLuint index); -typedef void (APIENTRYP PFNGLDISABLEINDEXEDEXTPROC) (GLenum target, GLuint index); -typedef GLboolean (APIENTRYP PFNGLISENABLEDINDEXEDEXTPROC) (GLenum target, GLuint index); -typedef void (APIENTRYP PFNGLGETINTEGERINDEXEDVEXTPROC) (GLenum target, GLuint index, GLint *data); -typedef void (APIENTRYP PFNGLGETBOOLEANINDEXEDVEXTPROC) (GLenum target, GLuint index, GLboolean *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *bits); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *bits); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *bits); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *bits); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *bits); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *bits); -typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint lod, void *img); -typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *bits); -typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *bits); -typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *bits); -typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *bits); -typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *bits); -typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *bits); -typedef void (APIENTRYP PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint lod, void *img); -typedef void (APIENTRYP PFNGLMATRIXLOADTRANSPOSEFEXTPROC) (GLenum mode, const GLfloat *m); -typedef void (APIENTRYP PFNGLMATRIXLOADTRANSPOSEDEXTPROC) (GLenum mode, const GLdouble *m); -typedef void (APIENTRYP PFNGLMATRIXMULTTRANSPOSEFEXTPROC) (GLenum mode, const GLfloat *m); -typedef void (APIENTRYP PFNGLMATRIXMULTTRANSPOSEDEXTPROC) (GLenum mode, const GLdouble *m); -typedef void (APIENTRYP PFNGLNAMEDBUFFERDATAEXTPROC) (GLuint buffer, GLsizeiptr size, const void *data, GLenum usage); -typedef void (APIENTRYP PFNGLNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data); -typedef void *(APIENTRYP PFNGLMAPNAMEDBUFFEREXTPROC) (GLuint buffer, GLenum access); -typedef GLboolean (APIENTRYP PFNGLUNMAPNAMEDBUFFEREXTPROC) (GLuint buffer); -typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC) (GLuint buffer, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPOINTERVEXTPROC) (GLuint buffer, GLenum pname, void **params); -typedef void (APIENTRYP PFNGLGETNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, void *data); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FEXTPROC) (GLuint program, GLint location, GLfloat v0); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IEXTPROC) (GLuint program, GLint location, GLint v0); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLTEXTUREBUFFEREXTPROC) (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer); -typedef void (APIENTRYP PFNGLMULTITEXBUFFEREXTPROC) (GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer); -typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLuint *params); -typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLuint *params); -typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLuint *params); -typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLuint *params); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIEXTPROC) (GLuint program, GLint location, GLuint v0); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLfloat *params); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC) (GLuint program, GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLint *params); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLint *params); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLuint *params); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLuint *params); -typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLint *params); -typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint *params); -typedef void (APIENTRYP PFNGLENABLECLIENTSTATEIEXTPROC) (GLenum array, GLuint index); -typedef void (APIENTRYP PFNGLDISABLECLIENTSTATEIEXTPROC) (GLenum array, GLuint index); -typedef void (APIENTRYP PFNGLGETFLOATI_VEXTPROC) (GLenum pname, GLuint index, GLfloat *params); -typedef void (APIENTRYP PFNGLGETDOUBLEI_VEXTPROC) (GLenum pname, GLuint index, GLdouble *params); -typedef void (APIENTRYP PFNGLGETPOINTERI_VEXTPROC) (GLenum pname, GLuint index, void **params); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum format, GLsizei len, const void *string); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLdouble *params); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLfloat *params); -typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble *params); -typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat *params); -typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMIVEXTPROC) (GLuint program, GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum pname, void *string); -typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC) (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC) (GLuint renderbuffer, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC) (GLuint renderbuffer, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); -typedef GLenum (APIENTRYP PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC) (GLuint framebuffer, GLenum target); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC) (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -typedef void (APIENTRYP PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGENERATETEXTUREMIPMAPEXTPROC) (GLuint texture, GLenum target); -typedef void (APIENTRYP PFNGLGENERATEMULTITEXMIPMAPEXTPROC) (GLenum texunit, GLenum target); -typedef void (APIENTRYP PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC) (GLuint framebuffer, GLenum mode); -typedef void (APIENTRYP PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC) (GLuint framebuffer, GLsizei n, const GLenum *bufs); -typedef void (APIENTRYP PFNGLFRAMEBUFFERREADBUFFEREXTPROC) (GLuint framebuffer, GLenum mode); -typedef void (APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC) (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLenum face); -typedef void (APIENTRYP PFNGLTEXTURERENDERBUFFEREXTPROC) (GLuint texture, GLenum target, GLuint renderbuffer); -typedef void (APIENTRYP PFNGLMULTITEXRENDERBUFFEREXTPROC) (GLenum texunit, GLenum target, GLuint renderbuffer); -typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); -typedef void (APIENTRYP PFNGLVERTEXARRAYCOLOROFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); -typedef void (APIENTRYP PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLsizei stride, GLintptr offset); -typedef void (APIENTRYP PFNGLVERTEXARRAYINDEXOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); -typedef void (APIENTRYP PFNGLVERTEXARRAYNORMALOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); -typedef void (APIENTRYP PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); -typedef void (APIENTRYP PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum texunit, GLint size, GLenum type, GLsizei stride, GLintptr offset); -typedef void (APIENTRYP PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); -typedef void (APIENTRYP PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); -typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLintptr offset); -typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset); -typedef void (APIENTRYP PFNGLENABLEVERTEXARRAYEXTPROC) (GLuint vaobj, GLenum array); -typedef void (APIENTRYP PFNGLDISABLEVERTEXARRAYEXTPROC) (GLuint vaobj, GLenum array); -typedef void (APIENTRYP PFNGLENABLEVERTEXARRAYATTRIBEXTPROC) (GLuint vaobj, GLuint index); -typedef void (APIENTRYP PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC) (GLuint vaobj, GLuint index); -typedef void (APIENTRYP PFNGLGETVERTEXARRAYINTEGERVEXTPROC) (GLuint vaobj, GLenum pname, GLint *param); -typedef void (APIENTRYP PFNGLGETVERTEXARRAYPOINTERVEXTPROC) (GLuint vaobj, GLenum pname, void **param); -typedef void (APIENTRYP PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC) (GLuint vaobj, GLuint index, GLenum pname, GLint *param); -typedef void (APIENTRYP PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC) (GLuint vaobj, GLuint index, GLenum pname, void **param); -typedef void *(APIENTRYP PFNGLMAPNAMEDBUFFERRANGEEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access); -typedef void (APIENTRYP PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length); -typedef void (APIENTRYP PFNGLNAMEDBUFFERSTORAGEEXTPROC) (GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags); -typedef void (APIENTRYP PFNGLCLEARNAMEDBUFFERDATAEXTPROC) (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data); -typedef void (APIENTRYP PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLenum internalformat, GLsizeiptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC) (GLuint framebuffer, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DEXTPROC) (GLuint program, GLint location, GLdouble x); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DEXTPROC) (GLuint program, GLint location, GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DEXTPROC) (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DEXTPROC) (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLTEXTUREBUFFERRANGEEXTPROC) (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); -typedef void (APIENTRYP PFNGLTEXTURESTORAGE1DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); -typedef void (APIENTRYP PFNGLTEXTURESTORAGE2DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLTEXTURESTORAGE3DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); -typedef void (APIENTRYP PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC) (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); -typedef void (APIENTRYP PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC) (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); -typedef void (APIENTRYP PFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC) (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); -typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); -typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); -typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); -typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC) (GLuint vaobj, GLuint attribindex, GLuint bindingindex); -typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC) (GLuint vaobj, GLuint bindingindex, GLuint divisor); -typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset); -typedef void (APIENTRYP PFNGLTEXTUREPAGECOMMITMENTEXTPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean resident); -typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBDIVISOREXTPROC) (GLuint vaobj, GLuint index, GLuint divisor); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glMatrixLoadfEXT (GLenum mode, const GLfloat *m); -GLAPI void APIENTRY glMatrixLoaddEXT (GLenum mode, const GLdouble *m); -GLAPI void APIENTRY glMatrixMultfEXT (GLenum mode, const GLfloat *m); -GLAPI void APIENTRY glMatrixMultdEXT (GLenum mode, const GLdouble *m); -GLAPI void APIENTRY glMatrixLoadIdentityEXT (GLenum mode); -GLAPI void APIENTRY glMatrixRotatefEXT (GLenum mode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glMatrixRotatedEXT (GLenum mode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z); -GLAPI void APIENTRY glMatrixScalefEXT (GLenum mode, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glMatrixScaledEXT (GLenum mode, GLdouble x, GLdouble y, GLdouble z); -GLAPI void APIENTRY glMatrixTranslatefEXT (GLenum mode, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glMatrixTranslatedEXT (GLenum mode, GLdouble x, GLdouble y, GLdouble z); -GLAPI void APIENTRY glMatrixFrustumEXT (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); -GLAPI void APIENTRY glMatrixOrthoEXT (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); -GLAPI void APIENTRY glMatrixPopEXT (GLenum mode); -GLAPI void APIENTRY glMatrixPushEXT (GLenum mode); -GLAPI void APIENTRY glClientAttribDefaultEXT (GLbitfield mask); -GLAPI void APIENTRY glPushClientAttribDefaultEXT (GLbitfield mask); -GLAPI void APIENTRY glTextureParameterfEXT (GLuint texture, GLenum target, GLenum pname, GLfloat param); -GLAPI void APIENTRY glTextureParameterfvEXT (GLuint texture, GLenum target, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glTextureParameteriEXT (GLuint texture, GLenum target, GLenum pname, GLint param); -GLAPI void APIENTRY glTextureParameterivEXT (GLuint texture, GLenum target, GLenum pname, const GLint *params); -GLAPI void APIENTRY glTextureImage1DEXT (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels); -GLAPI void APIENTRY glTextureImage2DEXT (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); -GLAPI void APIENTRY glTextureSubImage1DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); -GLAPI void APIENTRY glTextureSubImage2DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); -GLAPI void APIENTRY glCopyTextureImage1DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); -GLAPI void APIENTRY glCopyTextureImage2DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); -GLAPI void APIENTRY glCopyTextureSubImage1DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); -GLAPI void APIENTRY glCopyTextureSubImage2DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -GLAPI void APIENTRY glGetTextureImageEXT (GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, void *pixels); -GLAPI void APIENTRY glGetTextureParameterfvEXT (GLuint texture, GLenum target, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetTextureParameterivEXT (GLuint texture, GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetTextureLevelParameterfvEXT (GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetTextureLevelParameterivEXT (GLuint texture, GLenum target, GLint level, GLenum pname, GLint *params); -GLAPI void APIENTRY glTextureImage3DEXT (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); -GLAPI void APIENTRY glTextureSubImage3DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); -GLAPI void APIENTRY glCopyTextureSubImage3DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -GLAPI void APIENTRY glBindMultiTextureEXT (GLenum texunit, GLenum target, GLuint texture); -GLAPI void APIENTRY glMultiTexCoordPointerEXT (GLenum texunit, GLint size, GLenum type, GLsizei stride, const void *pointer); -GLAPI void APIENTRY glMultiTexEnvfEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat param); -GLAPI void APIENTRY glMultiTexEnvfvEXT (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glMultiTexEnviEXT (GLenum texunit, GLenum target, GLenum pname, GLint param); -GLAPI void APIENTRY glMultiTexEnvivEXT (GLenum texunit, GLenum target, GLenum pname, const GLint *params); -GLAPI void APIENTRY glMultiTexGendEXT (GLenum texunit, GLenum coord, GLenum pname, GLdouble param); -GLAPI void APIENTRY glMultiTexGendvEXT (GLenum texunit, GLenum coord, GLenum pname, const GLdouble *params); -GLAPI void APIENTRY glMultiTexGenfEXT (GLenum texunit, GLenum coord, GLenum pname, GLfloat param); -GLAPI void APIENTRY glMultiTexGenfvEXT (GLenum texunit, GLenum coord, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glMultiTexGeniEXT (GLenum texunit, GLenum coord, GLenum pname, GLint param); -GLAPI void APIENTRY glMultiTexGenivEXT (GLenum texunit, GLenum coord, GLenum pname, const GLint *params); -GLAPI void APIENTRY glGetMultiTexEnvfvEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetMultiTexEnvivEXT (GLenum texunit, GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetMultiTexGendvEXT (GLenum texunit, GLenum coord, GLenum pname, GLdouble *params); -GLAPI void APIENTRY glGetMultiTexGenfvEXT (GLenum texunit, GLenum coord, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetMultiTexGenivEXT (GLenum texunit, GLenum coord, GLenum pname, GLint *params); -GLAPI void APIENTRY glMultiTexParameteriEXT (GLenum texunit, GLenum target, GLenum pname, GLint param); -GLAPI void APIENTRY glMultiTexParameterivEXT (GLenum texunit, GLenum target, GLenum pname, const GLint *params); -GLAPI void APIENTRY glMultiTexParameterfEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat param); -GLAPI void APIENTRY glMultiTexParameterfvEXT (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glMultiTexImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels); -GLAPI void APIENTRY glMultiTexImage2DEXT (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); -GLAPI void APIENTRY glMultiTexSubImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); -GLAPI void APIENTRY glMultiTexSubImage2DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); -GLAPI void APIENTRY glCopyMultiTexImage1DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); -GLAPI void APIENTRY glCopyMultiTexImage2DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); -GLAPI void APIENTRY glCopyMultiTexSubImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); -GLAPI void APIENTRY glCopyMultiTexSubImage2DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -GLAPI void APIENTRY glGetMultiTexImageEXT (GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, void *pixels); -GLAPI void APIENTRY glGetMultiTexParameterfvEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetMultiTexParameterivEXT (GLenum texunit, GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetMultiTexLevelParameterfvEXT (GLenum texunit, GLenum target, GLint level, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetMultiTexLevelParameterivEXT (GLenum texunit, GLenum target, GLint level, GLenum pname, GLint *params); -GLAPI void APIENTRY glMultiTexImage3DEXT (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); -GLAPI void APIENTRY glMultiTexSubImage3DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); -GLAPI void APIENTRY glCopyMultiTexSubImage3DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -GLAPI void APIENTRY glEnableClientStateIndexedEXT (GLenum array, GLuint index); -GLAPI void APIENTRY glDisableClientStateIndexedEXT (GLenum array, GLuint index); -GLAPI void APIENTRY glGetFloatIndexedvEXT (GLenum target, GLuint index, GLfloat *data); -GLAPI void APIENTRY glGetDoubleIndexedvEXT (GLenum target, GLuint index, GLdouble *data); -GLAPI void APIENTRY glGetPointerIndexedvEXT (GLenum target, GLuint index, void **data); -GLAPI void APIENTRY glEnableIndexedEXT (GLenum target, GLuint index); -GLAPI void APIENTRY glDisableIndexedEXT (GLenum target, GLuint index); -GLAPI GLboolean APIENTRY glIsEnabledIndexedEXT (GLenum target, GLuint index); -GLAPI void APIENTRY glGetIntegerIndexedvEXT (GLenum target, GLuint index, GLint *data); -GLAPI void APIENTRY glGetBooleanIndexedvEXT (GLenum target, GLuint index, GLboolean *data); -GLAPI void APIENTRY glCompressedTextureImage3DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *bits); -GLAPI void APIENTRY glCompressedTextureImage2DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *bits); -GLAPI void APIENTRY glCompressedTextureImage1DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *bits); -GLAPI void APIENTRY glCompressedTextureSubImage3DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *bits); -GLAPI void APIENTRY glCompressedTextureSubImage2DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *bits); -GLAPI void APIENTRY glCompressedTextureSubImage1DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *bits); -GLAPI void APIENTRY glGetCompressedTextureImageEXT (GLuint texture, GLenum target, GLint lod, void *img); -GLAPI void APIENTRY glCompressedMultiTexImage3DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *bits); -GLAPI void APIENTRY glCompressedMultiTexImage2DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *bits); -GLAPI void APIENTRY glCompressedMultiTexImage1DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *bits); -GLAPI void APIENTRY glCompressedMultiTexSubImage3DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *bits); -GLAPI void APIENTRY glCompressedMultiTexSubImage2DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *bits); -GLAPI void APIENTRY glCompressedMultiTexSubImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *bits); -GLAPI void APIENTRY glGetCompressedMultiTexImageEXT (GLenum texunit, GLenum target, GLint lod, void *img); -GLAPI void APIENTRY glMatrixLoadTransposefEXT (GLenum mode, const GLfloat *m); -GLAPI void APIENTRY glMatrixLoadTransposedEXT (GLenum mode, const GLdouble *m); -GLAPI void APIENTRY glMatrixMultTransposefEXT (GLenum mode, const GLfloat *m); -GLAPI void APIENTRY glMatrixMultTransposedEXT (GLenum mode, const GLdouble *m); -GLAPI void APIENTRY glNamedBufferDataEXT (GLuint buffer, GLsizeiptr size, const void *data, GLenum usage); -GLAPI void APIENTRY glNamedBufferSubDataEXT (GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data); -GLAPI void *APIENTRY glMapNamedBufferEXT (GLuint buffer, GLenum access); -GLAPI GLboolean APIENTRY glUnmapNamedBufferEXT (GLuint buffer); -GLAPI void APIENTRY glGetNamedBufferParameterivEXT (GLuint buffer, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetNamedBufferPointervEXT (GLuint buffer, GLenum pname, void **params); -GLAPI void APIENTRY glGetNamedBufferSubDataEXT (GLuint buffer, GLintptr offset, GLsizeiptr size, void *data); -GLAPI void APIENTRY glProgramUniform1fEXT (GLuint program, GLint location, GLfloat v0); -GLAPI void APIENTRY glProgramUniform2fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1); -GLAPI void APIENTRY glProgramUniform3fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); -GLAPI void APIENTRY glProgramUniform4fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); -GLAPI void APIENTRY glProgramUniform1iEXT (GLuint program, GLint location, GLint v0); -GLAPI void APIENTRY glProgramUniform2iEXT (GLuint program, GLint location, GLint v0, GLint v1); -GLAPI void APIENTRY glProgramUniform3iEXT (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); -GLAPI void APIENTRY glProgramUniform4iEXT (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); -GLAPI void APIENTRY glProgramUniform1fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glProgramUniform2fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glProgramUniform3fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glProgramUniform4fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glProgramUniform1ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glProgramUniform2ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glProgramUniform3ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glProgramUniform4ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glProgramUniformMatrix2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix2x3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix3x2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix2x4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix4x2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix3x4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix4x3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glTextureBufferEXT (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer); -GLAPI void APIENTRY glMultiTexBufferEXT (GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer); -GLAPI void APIENTRY glTextureParameterIivEXT (GLuint texture, GLenum target, GLenum pname, const GLint *params); -GLAPI void APIENTRY glTextureParameterIuivEXT (GLuint texture, GLenum target, GLenum pname, const GLuint *params); -GLAPI void APIENTRY glGetTextureParameterIivEXT (GLuint texture, GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetTextureParameterIuivEXT (GLuint texture, GLenum target, GLenum pname, GLuint *params); -GLAPI void APIENTRY glMultiTexParameterIivEXT (GLenum texunit, GLenum target, GLenum pname, const GLint *params); -GLAPI void APIENTRY glMultiTexParameterIuivEXT (GLenum texunit, GLenum target, GLenum pname, const GLuint *params); -GLAPI void APIENTRY glGetMultiTexParameterIivEXT (GLenum texunit, GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetMultiTexParameterIuivEXT (GLenum texunit, GLenum target, GLenum pname, GLuint *params); -GLAPI void APIENTRY glProgramUniform1uiEXT (GLuint program, GLint location, GLuint v0); -GLAPI void APIENTRY glProgramUniform2uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1); -GLAPI void APIENTRY glProgramUniform3uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); -GLAPI void APIENTRY glProgramUniform4uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); -GLAPI void APIENTRY glProgramUniform1uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value); -GLAPI void APIENTRY glProgramUniform2uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value); -GLAPI void APIENTRY glProgramUniform3uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value); -GLAPI void APIENTRY glProgramUniform4uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value); -GLAPI void APIENTRY glNamedProgramLocalParameters4fvEXT (GLuint program, GLenum target, GLuint index, GLsizei count, const GLfloat *params); -GLAPI void APIENTRY glNamedProgramLocalParameterI4iEXT (GLuint program, GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); -GLAPI void APIENTRY glNamedProgramLocalParameterI4ivEXT (GLuint program, GLenum target, GLuint index, const GLint *params); -GLAPI void APIENTRY glNamedProgramLocalParametersI4ivEXT (GLuint program, GLenum target, GLuint index, GLsizei count, const GLint *params); -GLAPI void APIENTRY glNamedProgramLocalParameterI4uiEXT (GLuint program, GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -GLAPI void APIENTRY glNamedProgramLocalParameterI4uivEXT (GLuint program, GLenum target, GLuint index, const GLuint *params); -GLAPI void APIENTRY glNamedProgramLocalParametersI4uivEXT (GLuint program, GLenum target, GLuint index, GLsizei count, const GLuint *params); -GLAPI void APIENTRY glGetNamedProgramLocalParameterIivEXT (GLuint program, GLenum target, GLuint index, GLint *params); -GLAPI void APIENTRY glGetNamedProgramLocalParameterIuivEXT (GLuint program, GLenum target, GLuint index, GLuint *params); -GLAPI void APIENTRY glEnableClientStateiEXT (GLenum array, GLuint index); -GLAPI void APIENTRY glDisableClientStateiEXT (GLenum array, GLuint index); -GLAPI void APIENTRY glGetFloati_vEXT (GLenum pname, GLuint index, GLfloat *params); -GLAPI void APIENTRY glGetDoublei_vEXT (GLenum pname, GLuint index, GLdouble *params); -GLAPI void APIENTRY glGetPointeri_vEXT (GLenum pname, GLuint index, void **params); -GLAPI void APIENTRY glNamedProgramStringEXT (GLuint program, GLenum target, GLenum format, GLsizei len, const void *string); -GLAPI void APIENTRY glNamedProgramLocalParameter4dEXT (GLuint program, GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void APIENTRY glNamedProgramLocalParameter4dvEXT (GLuint program, GLenum target, GLuint index, const GLdouble *params); -GLAPI void APIENTRY glNamedProgramLocalParameter4fEXT (GLuint program, GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI void APIENTRY glNamedProgramLocalParameter4fvEXT (GLuint program, GLenum target, GLuint index, const GLfloat *params); -GLAPI void APIENTRY glGetNamedProgramLocalParameterdvEXT (GLuint program, GLenum target, GLuint index, GLdouble *params); -GLAPI void APIENTRY glGetNamedProgramLocalParameterfvEXT (GLuint program, GLenum target, GLuint index, GLfloat *params); -GLAPI void APIENTRY glGetNamedProgramivEXT (GLuint program, GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetNamedProgramStringEXT (GLuint program, GLenum target, GLenum pname, void *string); -GLAPI void APIENTRY glNamedRenderbufferStorageEXT (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); -GLAPI void APIENTRY glGetNamedRenderbufferParameterivEXT (GLuint renderbuffer, GLenum pname, GLint *params); -GLAPI void APIENTRY glNamedRenderbufferStorageMultisampleEXT (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -GLAPI void APIENTRY glNamedRenderbufferStorageMultisampleCoverageEXT (GLuint renderbuffer, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); -GLAPI GLenum APIENTRY glCheckNamedFramebufferStatusEXT (GLuint framebuffer, GLenum target); -GLAPI void APIENTRY glNamedFramebufferTexture1DEXT (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -GLAPI void APIENTRY glNamedFramebufferTexture2DEXT (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -GLAPI void APIENTRY glNamedFramebufferTexture3DEXT (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); -GLAPI void APIENTRY glNamedFramebufferRenderbufferEXT (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -GLAPI void APIENTRY glGetNamedFramebufferAttachmentParameterivEXT (GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params); -GLAPI void APIENTRY glGenerateTextureMipmapEXT (GLuint texture, GLenum target); -GLAPI void APIENTRY glGenerateMultiTexMipmapEXT (GLenum texunit, GLenum target); -GLAPI void APIENTRY glFramebufferDrawBufferEXT (GLuint framebuffer, GLenum mode); -GLAPI void APIENTRY glFramebufferDrawBuffersEXT (GLuint framebuffer, GLsizei n, const GLenum *bufs); -GLAPI void APIENTRY glFramebufferReadBufferEXT (GLuint framebuffer, GLenum mode); -GLAPI void APIENTRY glGetFramebufferParameterivEXT (GLuint framebuffer, GLenum pname, GLint *params); -GLAPI void APIENTRY glNamedCopyBufferSubDataEXT (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); -GLAPI void APIENTRY glNamedFramebufferTextureEXT (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); -GLAPI void APIENTRY glNamedFramebufferTextureLayerEXT (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); -GLAPI void APIENTRY glNamedFramebufferTextureFaceEXT (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLenum face); -GLAPI void APIENTRY glTextureRenderbufferEXT (GLuint texture, GLenum target, GLuint renderbuffer); -GLAPI void APIENTRY glMultiTexRenderbufferEXT (GLenum texunit, GLenum target, GLuint renderbuffer); -GLAPI void APIENTRY glVertexArrayVertexOffsetEXT (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); -GLAPI void APIENTRY glVertexArrayColorOffsetEXT (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); -GLAPI void APIENTRY glVertexArrayEdgeFlagOffsetEXT (GLuint vaobj, GLuint buffer, GLsizei stride, GLintptr offset); -GLAPI void APIENTRY glVertexArrayIndexOffsetEXT (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); -GLAPI void APIENTRY glVertexArrayNormalOffsetEXT (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); -GLAPI void APIENTRY glVertexArrayTexCoordOffsetEXT (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); -GLAPI void APIENTRY glVertexArrayMultiTexCoordOffsetEXT (GLuint vaobj, GLuint buffer, GLenum texunit, GLint size, GLenum type, GLsizei stride, GLintptr offset); -GLAPI void APIENTRY glVertexArrayFogCoordOffsetEXT (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); -GLAPI void APIENTRY glVertexArraySecondaryColorOffsetEXT (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); -GLAPI void APIENTRY glVertexArrayVertexAttribOffsetEXT (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLintptr offset); -GLAPI void APIENTRY glVertexArrayVertexAttribIOffsetEXT (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset); -GLAPI void APIENTRY glEnableVertexArrayEXT (GLuint vaobj, GLenum array); -GLAPI void APIENTRY glDisableVertexArrayEXT (GLuint vaobj, GLenum array); -GLAPI void APIENTRY glEnableVertexArrayAttribEXT (GLuint vaobj, GLuint index); -GLAPI void APIENTRY glDisableVertexArrayAttribEXT (GLuint vaobj, GLuint index); -GLAPI void APIENTRY glGetVertexArrayIntegervEXT (GLuint vaobj, GLenum pname, GLint *param); -GLAPI void APIENTRY glGetVertexArrayPointervEXT (GLuint vaobj, GLenum pname, void **param); -GLAPI void APIENTRY glGetVertexArrayIntegeri_vEXT (GLuint vaobj, GLuint index, GLenum pname, GLint *param); -GLAPI void APIENTRY glGetVertexArrayPointeri_vEXT (GLuint vaobj, GLuint index, GLenum pname, void **param); -GLAPI void *APIENTRY glMapNamedBufferRangeEXT (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access); -GLAPI void APIENTRY glFlushMappedNamedBufferRangeEXT (GLuint buffer, GLintptr offset, GLsizeiptr length); -GLAPI void APIENTRY glNamedBufferStorageEXT (GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags); -GLAPI void APIENTRY glClearNamedBufferDataEXT (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data); -GLAPI void APIENTRY glClearNamedBufferSubDataEXT (GLuint buffer, GLenum internalformat, GLsizeiptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); -GLAPI void APIENTRY glNamedFramebufferParameteriEXT (GLuint framebuffer, GLenum pname, GLint param); -GLAPI void APIENTRY glGetNamedFramebufferParameterivEXT (GLuint framebuffer, GLenum pname, GLint *params); -GLAPI void APIENTRY glProgramUniform1dEXT (GLuint program, GLint location, GLdouble x); -GLAPI void APIENTRY glProgramUniform2dEXT (GLuint program, GLint location, GLdouble x, GLdouble y); -GLAPI void APIENTRY glProgramUniform3dEXT (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z); -GLAPI void APIENTRY glProgramUniform4dEXT (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void APIENTRY glProgramUniform1dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value); -GLAPI void APIENTRY glProgramUniform2dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value); -GLAPI void APIENTRY glProgramUniform3dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value); -GLAPI void APIENTRY glProgramUniform4dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix2dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix3dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix4dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix2x3dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix2x4dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix3x2dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix3x4dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix4x2dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix4x3dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glTextureBufferRangeEXT (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); -GLAPI void APIENTRY glTextureStorage1DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); -GLAPI void APIENTRY glTextureStorage2DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); -GLAPI void APIENTRY glTextureStorage3DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); -GLAPI void APIENTRY glTextureStorage2DMultisampleEXT (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); -GLAPI void APIENTRY glTextureStorage3DMultisampleEXT (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); -GLAPI void APIENTRY glVertexArrayBindVertexBufferEXT (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); -GLAPI void APIENTRY glVertexArrayVertexAttribFormatEXT (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); -GLAPI void APIENTRY glVertexArrayVertexAttribIFormatEXT (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); -GLAPI void APIENTRY glVertexArrayVertexAttribLFormatEXT (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); -GLAPI void APIENTRY glVertexArrayVertexAttribBindingEXT (GLuint vaobj, GLuint attribindex, GLuint bindingindex); -GLAPI void APIENTRY glVertexArrayVertexBindingDivisorEXT (GLuint vaobj, GLuint bindingindex, GLuint divisor); -GLAPI void APIENTRY glVertexArrayVertexAttribLOffsetEXT (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset); -GLAPI void APIENTRY glTexturePageCommitmentEXT (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean resident); -GLAPI void APIENTRY glVertexArrayVertexAttribDivisorEXT (GLuint vaobj, GLuint index, GLuint divisor); -#endif -#endif /* GL_EXT_direct_state_access */ - -#ifndef GL_EXT_draw_buffers2 -#define GL_EXT_draw_buffers2 1 -typedef void (APIENTRYP PFNGLCOLORMASKINDEXEDEXTPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glColorMaskIndexedEXT (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); -#endif -#endif /* GL_EXT_draw_buffers2 */ - -#ifndef GL_EXT_draw_instanced -#define GL_EXT_draw_instanced 1 -typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount); -typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDrawArraysInstancedEXT (GLenum mode, GLint start, GLsizei count, GLsizei primcount); -GLAPI void APIENTRY glDrawElementsInstancedEXT (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); -#endif -#endif /* GL_EXT_draw_instanced */ - -#ifndef GL_EXT_draw_range_elements -#define GL_EXT_draw_range_elements 1 -#define GL_MAX_ELEMENTS_VERTICES_EXT 0x80E8 -#define GL_MAX_ELEMENTS_INDICES_EXT 0x80E9 -typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDrawRangeElementsEXT (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); -#endif -#endif /* GL_EXT_draw_range_elements */ - -#ifndef GL_EXT_fog_coord -#define GL_EXT_fog_coord 1 -#define GL_FOG_COORDINATE_SOURCE_EXT 0x8450 -#define GL_FOG_COORDINATE_EXT 0x8451 -#define GL_FRAGMENT_DEPTH_EXT 0x8452 -#define GL_CURRENT_FOG_COORDINATE_EXT 0x8453 -#define GL_FOG_COORDINATE_ARRAY_TYPE_EXT 0x8454 -#define GL_FOG_COORDINATE_ARRAY_STRIDE_EXT 0x8455 -#define GL_FOG_COORDINATE_ARRAY_POINTER_EXT 0x8456 -#define GL_FOG_COORDINATE_ARRAY_EXT 0x8457 -typedef void (APIENTRYP PFNGLFOGCOORDFEXTPROC) (GLfloat coord); -typedef void (APIENTRYP PFNGLFOGCOORDFVEXTPROC) (const GLfloat *coord); -typedef void (APIENTRYP PFNGLFOGCOORDDEXTPROC) (GLdouble coord); -typedef void (APIENTRYP PFNGLFOGCOORDDVEXTPROC) (const GLdouble *coord); -typedef void (APIENTRYP PFNGLFOGCOORDPOINTEREXTPROC) (GLenum type, GLsizei stride, const void *pointer); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFogCoordfEXT (GLfloat coord); -GLAPI void APIENTRY glFogCoordfvEXT (const GLfloat *coord); -GLAPI void APIENTRY glFogCoorddEXT (GLdouble coord); -GLAPI void APIENTRY glFogCoorddvEXT (const GLdouble *coord); -GLAPI void APIENTRY glFogCoordPointerEXT (GLenum type, GLsizei stride, const void *pointer); -#endif -#endif /* GL_EXT_fog_coord */ - -#ifndef GL_EXT_framebuffer_blit -#define GL_EXT_framebuffer_blit 1 -#define GL_READ_FRAMEBUFFER_EXT 0x8CA8 -#define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9 -#define GL_DRAW_FRAMEBUFFER_BINDING_EXT 0x8CA6 -#define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA -typedef void (APIENTRYP PFNGLBLITFRAMEBUFFEREXTPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlitFramebufferEXT (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -#endif -#endif /* GL_EXT_framebuffer_blit */ - -#ifndef GL_EXT_framebuffer_multisample -#define GL_EXT_framebuffer_multisample 1 -#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB -#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 -#define GL_MAX_SAMPLES_EXT 0x8D57 -typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glRenderbufferStorageMultisampleEXT (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -#endif -#endif /* GL_EXT_framebuffer_multisample */ - -#ifndef GL_EXT_framebuffer_multisample_blit_scaled -#define GL_EXT_framebuffer_multisample_blit_scaled 1 -#define GL_SCALED_RESOLVE_FASTEST_EXT 0x90BA -#define GL_SCALED_RESOLVE_NICEST_EXT 0x90BB -#endif /* GL_EXT_framebuffer_multisample_blit_scaled */ - -#ifndef GL_EXT_framebuffer_object -#define GL_EXT_framebuffer_object 1 -#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506 -#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8 -#define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6 -#define GL_RENDERBUFFER_BINDING_EXT 0x8CA7 -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0 -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4 -#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5 -#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6 -#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7 -#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9 -#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA -#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB -#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC -#define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD -#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF -#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 -#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1 -#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2 -#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3 -#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4 -#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5 -#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6 -#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7 -#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8 -#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9 -#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA -#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB -#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC -#define GL_COLOR_ATTACHMENT13_EXT 0x8CED -#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE -#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF -#define GL_DEPTH_ATTACHMENT_EXT 0x8D00 -#define GL_STENCIL_ATTACHMENT_EXT 0x8D20 -#define GL_FRAMEBUFFER_EXT 0x8D40 -#define GL_RENDERBUFFER_EXT 0x8D41 -#define GL_RENDERBUFFER_WIDTH_EXT 0x8D42 -#define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43 -#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44 -#define GL_STENCIL_INDEX1_EXT 0x8D46 -#define GL_STENCIL_INDEX4_EXT 0x8D47 -#define GL_STENCIL_INDEX8_EXT 0x8D48 -#define GL_STENCIL_INDEX16_EXT 0x8D49 -#define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50 -#define GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51 -#define GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52 -#define GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53 -#define GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54 -#define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55 -typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFEREXTPROC) (GLuint renderbuffer); -typedef void (APIENTRYP PFNGLBINDRENDERBUFFEREXTPROC) (GLenum target, GLuint renderbuffer); -typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint *renderbuffers); -typedef void (APIENTRYP PFNGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint *renderbuffers); -typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); -typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFEREXTPROC) (GLuint framebuffer); -typedef void (APIENTRYP PFNGLBINDFRAMEBUFFEREXTPROC) (GLenum target, GLuint framebuffer); -typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint *framebuffers); -typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint *framebuffers); -typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); -typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGENERATEMIPMAPEXTPROC) (GLenum target); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLboolean APIENTRY glIsRenderbufferEXT (GLuint renderbuffer); -GLAPI void APIENTRY glBindRenderbufferEXT (GLenum target, GLuint renderbuffer); -GLAPI void APIENTRY glDeleteRenderbuffersEXT (GLsizei n, const GLuint *renderbuffers); -GLAPI void APIENTRY glGenRenderbuffersEXT (GLsizei n, GLuint *renderbuffers); -GLAPI void APIENTRY glRenderbufferStorageEXT (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); -GLAPI void APIENTRY glGetRenderbufferParameterivEXT (GLenum target, GLenum pname, GLint *params); -GLAPI GLboolean APIENTRY glIsFramebufferEXT (GLuint framebuffer); -GLAPI void APIENTRY glBindFramebufferEXT (GLenum target, GLuint framebuffer); -GLAPI void APIENTRY glDeleteFramebuffersEXT (GLsizei n, const GLuint *framebuffers); -GLAPI void APIENTRY glGenFramebuffersEXT (GLsizei n, GLuint *framebuffers); -GLAPI GLenum APIENTRY glCheckFramebufferStatusEXT (GLenum target); -GLAPI void APIENTRY glFramebufferTexture1DEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -GLAPI void APIENTRY glFramebufferTexture2DEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -GLAPI void APIENTRY glFramebufferTexture3DEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); -GLAPI void APIENTRY glFramebufferRenderbufferEXT (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -GLAPI void APIENTRY glGetFramebufferAttachmentParameterivEXT (GLenum target, GLenum attachment, GLenum pname, GLint *params); -GLAPI void APIENTRY glGenerateMipmapEXT (GLenum target); -#endif -#endif /* GL_EXT_framebuffer_object */ - -#ifndef GL_EXT_framebuffer_sRGB -#define GL_EXT_framebuffer_sRGB 1 -#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9 -#define GL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x8DBA -#endif /* GL_EXT_framebuffer_sRGB */ - -#ifndef GL_EXT_geometry_shader4 -#define GL_EXT_geometry_shader4 1 -#define GL_GEOMETRY_SHADER_EXT 0x8DD9 -#define GL_GEOMETRY_VERTICES_OUT_EXT 0x8DDA -#define GL_GEOMETRY_INPUT_TYPE_EXT 0x8DDB -#define GL_GEOMETRY_OUTPUT_TYPE_EXT 0x8DDC -#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29 -#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT 0x8DDD -#define GL_MAX_VERTEX_VARYING_COMPONENTS_EXT 0x8DDE -#define GL_MAX_VARYING_COMPONENTS_EXT 0x8B4B -#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF -#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0 -#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1 -#define GL_LINES_ADJACENCY_EXT 0x000A -#define GL_LINE_STRIP_ADJACENCY_EXT 0x000B -#define GL_TRIANGLES_ADJACENCY_EXT 0x000C -#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0x000D -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8 -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9 -#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4 -#define GL_PROGRAM_POINT_SIZE_EXT 0x8642 -typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glProgramParameteriEXT (GLuint program, GLenum pname, GLint value); -#endif -#endif /* GL_EXT_geometry_shader4 */ - -#ifndef GL_EXT_gpu_program_parameters -#define GL_EXT_gpu_program_parameters 1 -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat *params); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glProgramEnvParameters4fvEXT (GLenum target, GLuint index, GLsizei count, const GLfloat *params); -GLAPI void APIENTRY glProgramLocalParameters4fvEXT (GLenum target, GLuint index, GLsizei count, const GLfloat *params); -#endif -#endif /* GL_EXT_gpu_program_parameters */ - -#ifndef GL_EXT_gpu_shader4 -#define GL_EXT_gpu_shader4 1 -#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_EXT 0x88FD -#define GL_SAMPLER_1D_ARRAY_EXT 0x8DC0 -#define GL_SAMPLER_2D_ARRAY_EXT 0x8DC1 -#define GL_SAMPLER_BUFFER_EXT 0x8DC2 -#define GL_SAMPLER_1D_ARRAY_SHADOW_EXT 0x8DC3 -#define GL_SAMPLER_2D_ARRAY_SHADOW_EXT 0x8DC4 -#define GL_SAMPLER_CUBE_SHADOW_EXT 0x8DC5 -#define GL_UNSIGNED_INT_VEC2_EXT 0x8DC6 -#define GL_UNSIGNED_INT_VEC3_EXT 0x8DC7 -#define GL_UNSIGNED_INT_VEC4_EXT 0x8DC8 -#define GL_INT_SAMPLER_1D_EXT 0x8DC9 -#define GL_INT_SAMPLER_2D_EXT 0x8DCA -#define GL_INT_SAMPLER_3D_EXT 0x8DCB -#define GL_INT_SAMPLER_CUBE_EXT 0x8DCC -#define GL_INT_SAMPLER_2D_RECT_EXT 0x8DCD -#define GL_INT_SAMPLER_1D_ARRAY_EXT 0x8DCE -#define GL_INT_SAMPLER_2D_ARRAY_EXT 0x8DCF -#define GL_INT_SAMPLER_BUFFER_EXT 0x8DD0 -#define GL_UNSIGNED_INT_SAMPLER_1D_EXT 0x8DD1 -#define GL_UNSIGNED_INT_SAMPLER_2D_EXT 0x8DD2 -#define GL_UNSIGNED_INT_SAMPLER_3D_EXT 0x8DD3 -#define GL_UNSIGNED_INT_SAMPLER_CUBE_EXT 0x8DD4 -#define GL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT 0x8DD5 -#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT 0x8DD6 -#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT 0x8DD7 -#define GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT 0x8DD8 -#define GL_MIN_PROGRAM_TEXEL_OFFSET_EXT 0x8904 -#define GL_MAX_PROGRAM_TEXEL_OFFSET_EXT 0x8905 -typedef void (APIENTRYP PFNGLGETUNIFORMUIVEXTPROC) (GLuint program, GLint location, GLuint *params); -typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONEXTPROC) (GLuint program, GLuint color, const GLchar *name); -typedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONEXTPROC) (GLuint program, const GLchar *name); -typedef void (APIENTRYP PFNGLUNIFORM1UIEXTPROC) (GLint location, GLuint v0); -typedef void (APIENTRYP PFNGLUNIFORM2UIEXTPROC) (GLint location, GLuint v0, GLuint v1); -typedef void (APIENTRYP PFNGLUNIFORM3UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2); -typedef void (APIENTRYP PFNGLUNIFORM4UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); -typedef void (APIENTRYP PFNGLUNIFORM1UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLUNIFORM2UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLUNIFORM3UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLUNIFORM4UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGetUniformuivEXT (GLuint program, GLint location, GLuint *params); -GLAPI void APIENTRY glBindFragDataLocationEXT (GLuint program, GLuint color, const GLchar *name); -GLAPI GLint APIENTRY glGetFragDataLocationEXT (GLuint program, const GLchar *name); -GLAPI void APIENTRY glUniform1uiEXT (GLint location, GLuint v0); -GLAPI void APIENTRY glUniform2uiEXT (GLint location, GLuint v0, GLuint v1); -GLAPI void APIENTRY glUniform3uiEXT (GLint location, GLuint v0, GLuint v1, GLuint v2); -GLAPI void APIENTRY glUniform4uiEXT (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); -GLAPI void APIENTRY glUniform1uivEXT (GLint location, GLsizei count, const GLuint *value); -GLAPI void APIENTRY glUniform2uivEXT (GLint location, GLsizei count, const GLuint *value); -GLAPI void APIENTRY glUniform3uivEXT (GLint location, GLsizei count, const GLuint *value); -GLAPI void APIENTRY glUniform4uivEXT (GLint location, GLsizei count, const GLuint *value); -#endif -#endif /* GL_EXT_gpu_shader4 */ - -#ifndef GL_EXT_histogram -#define GL_EXT_histogram 1 -#define GL_HISTOGRAM_EXT 0x8024 -#define GL_PROXY_HISTOGRAM_EXT 0x8025 -#define GL_HISTOGRAM_WIDTH_EXT 0x8026 -#define GL_HISTOGRAM_FORMAT_EXT 0x8027 -#define GL_HISTOGRAM_RED_SIZE_EXT 0x8028 -#define GL_HISTOGRAM_GREEN_SIZE_EXT 0x8029 -#define GL_HISTOGRAM_BLUE_SIZE_EXT 0x802A -#define GL_HISTOGRAM_ALPHA_SIZE_EXT 0x802B -#define GL_HISTOGRAM_LUMINANCE_SIZE_EXT 0x802C -#define GL_HISTOGRAM_SINK_EXT 0x802D -#define GL_MINMAX_EXT 0x802E -#define GL_MINMAX_FORMAT_EXT 0x802F -#define GL_MINMAX_SINK_EXT 0x8030 -#define GL_TABLE_TOO_LARGE_EXT 0x8031 -typedef void (APIENTRYP PFNGLGETHISTOGRAMEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); -typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETMINMAXEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); -typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLHISTOGRAMEXTPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); -typedef void (APIENTRYP PFNGLMINMAXEXTPROC) (GLenum target, GLenum internalformat, GLboolean sink); -typedef void (APIENTRYP PFNGLRESETHISTOGRAMEXTPROC) (GLenum target); -typedef void (APIENTRYP PFNGLRESETMINMAXEXTPROC) (GLenum target); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGetHistogramEXT (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); -GLAPI void APIENTRY glGetHistogramParameterfvEXT (GLenum target, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetHistogramParameterivEXT (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetMinmaxEXT (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); -GLAPI void APIENTRY glGetMinmaxParameterfvEXT (GLenum target, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetMinmaxParameterivEXT (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glHistogramEXT (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); -GLAPI void APIENTRY glMinmaxEXT (GLenum target, GLenum internalformat, GLboolean sink); -GLAPI void APIENTRY glResetHistogramEXT (GLenum target); -GLAPI void APIENTRY glResetMinmaxEXT (GLenum target); -#endif -#endif /* GL_EXT_histogram */ - -#ifndef GL_EXT_index_array_formats -#define GL_EXT_index_array_formats 1 -#define GL_IUI_V2F_EXT 0x81AD -#define GL_IUI_V3F_EXT 0x81AE -#define GL_IUI_N3F_V2F_EXT 0x81AF -#define GL_IUI_N3F_V3F_EXT 0x81B0 -#define GL_T2F_IUI_V2F_EXT 0x81B1 -#define GL_T2F_IUI_V3F_EXT 0x81B2 -#define GL_T2F_IUI_N3F_V2F_EXT 0x81B3 -#define GL_T2F_IUI_N3F_V3F_EXT 0x81B4 -#endif /* GL_EXT_index_array_formats */ - -#ifndef GL_EXT_index_func -#define GL_EXT_index_func 1 -#define GL_INDEX_TEST_EXT 0x81B5 -#define GL_INDEX_TEST_FUNC_EXT 0x81B6 -#define GL_INDEX_TEST_REF_EXT 0x81B7 -typedef void (APIENTRYP PFNGLINDEXFUNCEXTPROC) (GLenum func, GLclampf ref); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glIndexFuncEXT (GLenum func, GLclampf ref); -#endif -#endif /* GL_EXT_index_func */ - -#ifndef GL_EXT_index_material -#define GL_EXT_index_material 1 -#define GL_INDEX_MATERIAL_EXT 0x81B8 -#define GL_INDEX_MATERIAL_PARAMETER_EXT 0x81B9 -#define GL_INDEX_MATERIAL_FACE_EXT 0x81BA -typedef void (APIENTRYP PFNGLINDEXMATERIALEXTPROC) (GLenum face, GLenum mode); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glIndexMaterialEXT (GLenum face, GLenum mode); -#endif -#endif /* GL_EXT_index_material */ - -#ifndef GL_EXT_index_texture -#define GL_EXT_index_texture 1 -#endif /* GL_EXT_index_texture */ - -#ifndef GL_EXT_light_texture -#define GL_EXT_light_texture 1 -#define GL_FRAGMENT_MATERIAL_EXT 0x8349 -#define GL_FRAGMENT_NORMAL_EXT 0x834A -#define GL_FRAGMENT_COLOR_EXT 0x834C -#define GL_ATTENUATION_EXT 0x834D -#define GL_SHADOW_ATTENUATION_EXT 0x834E -#define GL_TEXTURE_APPLICATION_MODE_EXT 0x834F -#define GL_TEXTURE_LIGHT_EXT 0x8350 -#define GL_TEXTURE_MATERIAL_FACE_EXT 0x8351 -#define GL_TEXTURE_MATERIAL_PARAMETER_EXT 0x8352 -typedef void (APIENTRYP PFNGLAPPLYTEXTUREEXTPROC) (GLenum mode); -typedef void (APIENTRYP PFNGLTEXTURELIGHTEXTPROC) (GLenum pname); -typedef void (APIENTRYP PFNGLTEXTUREMATERIALEXTPROC) (GLenum face, GLenum mode); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glApplyTextureEXT (GLenum mode); -GLAPI void APIENTRY glTextureLightEXT (GLenum pname); -GLAPI void APIENTRY glTextureMaterialEXT (GLenum face, GLenum mode); -#endif -#endif /* GL_EXT_light_texture */ - -#ifndef GL_EXT_misc_attribute -#define GL_EXT_misc_attribute 1 -#endif /* GL_EXT_misc_attribute */ - -#ifndef GL_EXT_multi_draw_arrays -#define GL_EXT_multi_draw_arrays 1 -typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); -typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glMultiDrawArraysEXT (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); -GLAPI void APIENTRY glMultiDrawElementsEXT (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount); -#endif -#endif /* GL_EXT_multi_draw_arrays */ - -#ifndef GL_EXT_multisample -#define GL_EXT_multisample 1 -#define GL_MULTISAMPLE_EXT 0x809D -#define GL_SAMPLE_ALPHA_TO_MASK_EXT 0x809E -#define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F -#define GL_SAMPLE_MASK_EXT 0x80A0 -#define GL_1PASS_EXT 0x80A1 -#define GL_2PASS_0_EXT 0x80A2 -#define GL_2PASS_1_EXT 0x80A3 -#define GL_4PASS_0_EXT 0x80A4 -#define GL_4PASS_1_EXT 0x80A5 -#define GL_4PASS_2_EXT 0x80A6 -#define GL_4PASS_3_EXT 0x80A7 -#define GL_SAMPLE_BUFFERS_EXT 0x80A8 -#define GL_SAMPLES_EXT 0x80A9 -#define GL_SAMPLE_MASK_VALUE_EXT 0x80AA -#define GL_SAMPLE_MASK_INVERT_EXT 0x80AB -#define GL_SAMPLE_PATTERN_EXT 0x80AC -#define GL_MULTISAMPLE_BIT_EXT 0x20000000 -typedef void (APIENTRYP PFNGLSAMPLEMASKEXTPROC) (GLclampf value, GLboolean invert); -typedef void (APIENTRYP PFNGLSAMPLEPATTERNEXTPROC) (GLenum pattern); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glSampleMaskEXT (GLclampf value, GLboolean invert); -GLAPI void APIENTRY glSamplePatternEXT (GLenum pattern); -#endif -#endif /* GL_EXT_multisample */ - -#ifndef GL_EXT_packed_depth_stencil -#define GL_EXT_packed_depth_stencil 1 -#define GL_DEPTH_STENCIL_EXT 0x84F9 -#define GL_UNSIGNED_INT_24_8_EXT 0x84FA -#define GL_DEPTH24_STENCIL8_EXT 0x88F0 -#define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1 -#endif /* GL_EXT_packed_depth_stencil */ - -#ifndef GL_EXT_packed_float -#define GL_EXT_packed_float 1 -#define GL_R11F_G11F_B10F_EXT 0x8C3A -#define GL_UNSIGNED_INT_10F_11F_11F_REV_EXT 0x8C3B -#define GL_RGBA_SIGNED_COMPONENTS_EXT 0x8C3C -#endif /* GL_EXT_packed_float */ - -#ifndef GL_EXT_packed_pixels -#define GL_EXT_packed_pixels 1 -#define GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032 -#define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033 -#define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034 -#define GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035 -#define GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036 -#endif /* GL_EXT_packed_pixels */ - -#ifndef GL_EXT_paletted_texture -#define GL_EXT_paletted_texture 1 -#define GL_COLOR_INDEX1_EXT 0x80E2 -#define GL_COLOR_INDEX2_EXT 0x80E3 -#define GL_COLOR_INDEX4_EXT 0x80E4 -#define GL_COLOR_INDEX8_EXT 0x80E5 -#define GL_COLOR_INDEX12_EXT 0x80E6 -#define GL_COLOR_INDEX16_EXT 0x80E7 -#define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED -typedef void (APIENTRYP PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const void *table); -typedef void (APIENTRYP PFNGLGETCOLORTABLEEXTPROC) (GLenum target, GLenum format, GLenum type, void *data); -typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glColorTableEXT (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const void *table); -GLAPI void APIENTRY glGetColorTableEXT (GLenum target, GLenum format, GLenum type, void *data); -GLAPI void APIENTRY glGetColorTableParameterivEXT (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetColorTableParameterfvEXT (GLenum target, GLenum pname, GLfloat *params); -#endif -#endif /* GL_EXT_paletted_texture */ - -#ifndef GL_EXT_pixel_buffer_object -#define GL_EXT_pixel_buffer_object 1 -#define GL_PIXEL_PACK_BUFFER_EXT 0x88EB -#define GL_PIXEL_UNPACK_BUFFER_EXT 0x88EC -#define GL_PIXEL_PACK_BUFFER_BINDING_EXT 0x88ED -#define GL_PIXEL_UNPACK_BUFFER_BINDING_EXT 0x88EF -#endif /* GL_EXT_pixel_buffer_object */ - -#ifndef GL_EXT_pixel_transform -#define GL_EXT_pixel_transform 1 -#define GL_PIXEL_TRANSFORM_2D_EXT 0x8330 -#define GL_PIXEL_MAG_FILTER_EXT 0x8331 -#define GL_PIXEL_MIN_FILTER_EXT 0x8332 -#define GL_PIXEL_CUBIC_WEIGHT_EXT 0x8333 -#define GL_CUBIC_EXT 0x8334 -#define GL_AVERAGE_EXT 0x8335 -#define GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8336 -#define GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8337 -#define GL_PIXEL_TRANSFORM_2D_MATRIX_EXT 0x8338 -typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPixelTransformParameteriEXT (GLenum target, GLenum pname, GLint param); -GLAPI void APIENTRY glPixelTransformParameterfEXT (GLenum target, GLenum pname, GLfloat param); -GLAPI void APIENTRY glPixelTransformParameterivEXT (GLenum target, GLenum pname, const GLint *params); -GLAPI void APIENTRY glPixelTransformParameterfvEXT (GLenum target, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glGetPixelTransformParameterivEXT (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetPixelTransformParameterfvEXT (GLenum target, GLenum pname, GLfloat *params); -#endif -#endif /* GL_EXT_pixel_transform */ - -#ifndef GL_EXT_pixel_transform_color_table -#define GL_EXT_pixel_transform_color_table 1 -#endif /* GL_EXT_pixel_transform_color_table */ - -#ifndef GL_EXT_point_parameters -#define GL_EXT_point_parameters 1 -#define GL_POINT_SIZE_MIN_EXT 0x8126 -#define GL_POINT_SIZE_MAX_EXT 0x8127 -#define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128 -#define GL_DISTANCE_ATTENUATION_EXT 0x8129 -typedef void (APIENTRYP PFNGLPOINTPARAMETERFEXTPROC) (GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLPOINTPARAMETERFVEXTPROC) (GLenum pname, const GLfloat *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPointParameterfEXT (GLenum pname, GLfloat param); -GLAPI void APIENTRY glPointParameterfvEXT (GLenum pname, const GLfloat *params); -#endif -#endif /* GL_EXT_point_parameters */ - -#ifndef GL_EXT_polygon_offset -#define GL_EXT_polygon_offset 1 -#define GL_POLYGON_OFFSET_EXT 0x8037 -#define GL_POLYGON_OFFSET_FACTOR_EXT 0x8038 -#define GL_POLYGON_OFFSET_BIAS_EXT 0x8039 -typedef void (APIENTRYP PFNGLPOLYGONOFFSETEXTPROC) (GLfloat factor, GLfloat bias); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPolygonOffsetEXT (GLfloat factor, GLfloat bias); -#endif -#endif /* GL_EXT_polygon_offset */ - -#ifndef GL_EXT_provoking_vertex -#define GL_EXT_provoking_vertex 1 -#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT 0x8E4C -#define GL_FIRST_VERTEX_CONVENTION_EXT 0x8E4D -#define GL_LAST_VERTEX_CONVENTION_EXT 0x8E4E -#define GL_PROVOKING_VERTEX_EXT 0x8E4F -typedef void (APIENTRYP PFNGLPROVOKINGVERTEXEXTPROC) (GLenum mode); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glProvokingVertexEXT (GLenum mode); -#endif -#endif /* GL_EXT_provoking_vertex */ - -#ifndef GL_EXT_rescale_normal -#define GL_EXT_rescale_normal 1 -#define GL_RESCALE_NORMAL_EXT 0x803A -#endif /* GL_EXT_rescale_normal */ - -#ifndef GL_EXT_secondary_color -#define GL_EXT_secondary_color 1 -#define GL_COLOR_SUM_EXT 0x8458 -#define GL_CURRENT_SECONDARY_COLOR_EXT 0x8459 -#define GL_SECONDARY_COLOR_ARRAY_SIZE_EXT 0x845A -#define GL_SECONDARY_COLOR_ARRAY_TYPE_EXT 0x845B -#define GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT 0x845C -#define GL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D -#define GL_SECONDARY_COLOR_ARRAY_EXT 0x845E -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BEXTPROC) (GLbyte red, GLbyte green, GLbyte blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BVEXTPROC) (const GLbyte *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DEXTPROC) (GLdouble red, GLdouble green, GLdouble blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DVEXTPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FEXTPROC) (GLfloat red, GLfloat green, GLfloat blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FVEXTPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IEXTPROC) (GLint red, GLint green, GLint blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IVEXTPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SEXTPROC) (GLshort red, GLshort green, GLshort blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SVEXTPROC) (const GLshort *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBEXTPROC) (GLubyte red, GLubyte green, GLubyte blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBVEXTPROC) (const GLubyte *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIEXTPROC) (GLuint red, GLuint green, GLuint blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIVEXTPROC) (const GLuint *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USEXTPROC) (GLushort red, GLushort green, GLushort blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USVEXTPROC) (const GLushort *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, const void *pointer); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glSecondaryColor3bEXT (GLbyte red, GLbyte green, GLbyte blue); -GLAPI void APIENTRY glSecondaryColor3bvEXT (const GLbyte *v); -GLAPI void APIENTRY glSecondaryColor3dEXT (GLdouble red, GLdouble green, GLdouble blue); -GLAPI void APIENTRY glSecondaryColor3dvEXT (const GLdouble *v); -GLAPI void APIENTRY glSecondaryColor3fEXT (GLfloat red, GLfloat green, GLfloat blue); -GLAPI void APIENTRY glSecondaryColor3fvEXT (const GLfloat *v); -GLAPI void APIENTRY glSecondaryColor3iEXT (GLint red, GLint green, GLint blue); -GLAPI void APIENTRY glSecondaryColor3ivEXT (const GLint *v); -GLAPI void APIENTRY glSecondaryColor3sEXT (GLshort red, GLshort green, GLshort blue); -GLAPI void APIENTRY glSecondaryColor3svEXT (const GLshort *v); -GLAPI void APIENTRY glSecondaryColor3ubEXT (GLubyte red, GLubyte green, GLubyte blue); -GLAPI void APIENTRY glSecondaryColor3ubvEXT (const GLubyte *v); -GLAPI void APIENTRY glSecondaryColor3uiEXT (GLuint red, GLuint green, GLuint blue); -GLAPI void APIENTRY glSecondaryColor3uivEXT (const GLuint *v); -GLAPI void APIENTRY glSecondaryColor3usEXT (GLushort red, GLushort green, GLushort blue); -GLAPI void APIENTRY glSecondaryColor3usvEXT (const GLushort *v); -GLAPI void APIENTRY glSecondaryColorPointerEXT (GLint size, GLenum type, GLsizei stride, const void *pointer); -#endif -#endif /* GL_EXT_secondary_color */ - -#ifndef GL_EXT_separate_shader_objects -#define GL_EXT_separate_shader_objects 1 -#define GL_ACTIVE_PROGRAM_EXT 0x8B8D -typedef void (APIENTRYP PFNGLUSESHADERPROGRAMEXTPROC) (GLenum type, GLuint program); -typedef void (APIENTRYP PFNGLACTIVEPROGRAMEXTPROC) (GLuint program); -typedef GLuint (APIENTRYP PFNGLCREATESHADERPROGRAMEXTPROC) (GLenum type, const GLchar *string); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glUseShaderProgramEXT (GLenum type, GLuint program); -GLAPI void APIENTRY glActiveProgramEXT (GLuint program); -GLAPI GLuint APIENTRY glCreateShaderProgramEXT (GLenum type, const GLchar *string); -#endif -#endif /* GL_EXT_separate_shader_objects */ - -#ifndef GL_EXT_separate_specular_color -#define GL_EXT_separate_specular_color 1 -#define GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8 -#define GL_SINGLE_COLOR_EXT 0x81F9 -#define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA -#endif /* GL_EXT_separate_specular_color */ - -#ifndef GL_EXT_shader_image_load_formatted -#define GL_EXT_shader_image_load_formatted 1 -#endif /* GL_EXT_shader_image_load_formatted */ - -#ifndef GL_EXT_shader_image_load_store -#define GL_EXT_shader_image_load_store 1 -#define GL_MAX_IMAGE_UNITS_EXT 0x8F38 -#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS_EXT 0x8F39 -#define GL_IMAGE_BINDING_NAME_EXT 0x8F3A -#define GL_IMAGE_BINDING_LEVEL_EXT 0x8F3B -#define GL_IMAGE_BINDING_LAYERED_EXT 0x8F3C -#define GL_IMAGE_BINDING_LAYER_EXT 0x8F3D -#define GL_IMAGE_BINDING_ACCESS_EXT 0x8F3E -#define GL_IMAGE_1D_EXT 0x904C -#define GL_IMAGE_2D_EXT 0x904D -#define GL_IMAGE_3D_EXT 0x904E -#define GL_IMAGE_2D_RECT_EXT 0x904F -#define GL_IMAGE_CUBE_EXT 0x9050 -#define GL_IMAGE_BUFFER_EXT 0x9051 -#define GL_IMAGE_1D_ARRAY_EXT 0x9052 -#define GL_IMAGE_2D_ARRAY_EXT 0x9053 -#define GL_IMAGE_CUBE_MAP_ARRAY_EXT 0x9054 -#define GL_IMAGE_2D_MULTISAMPLE_EXT 0x9055 -#define GL_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9056 -#define GL_INT_IMAGE_1D_EXT 0x9057 -#define GL_INT_IMAGE_2D_EXT 0x9058 -#define GL_INT_IMAGE_3D_EXT 0x9059 -#define GL_INT_IMAGE_2D_RECT_EXT 0x905A -#define GL_INT_IMAGE_CUBE_EXT 0x905B -#define GL_INT_IMAGE_BUFFER_EXT 0x905C -#define GL_INT_IMAGE_1D_ARRAY_EXT 0x905D -#define GL_INT_IMAGE_2D_ARRAY_EXT 0x905E -#define GL_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x905F -#define GL_INT_IMAGE_2D_MULTISAMPLE_EXT 0x9060 -#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9061 -#define GL_UNSIGNED_INT_IMAGE_1D_EXT 0x9062 -#define GL_UNSIGNED_INT_IMAGE_2D_EXT 0x9063 -#define GL_UNSIGNED_INT_IMAGE_3D_EXT 0x9064 -#define GL_UNSIGNED_INT_IMAGE_2D_RECT_EXT 0x9065 -#define GL_UNSIGNED_INT_IMAGE_CUBE_EXT 0x9066 -#define GL_UNSIGNED_INT_IMAGE_BUFFER_EXT 0x9067 -#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY_EXT 0x9068 -#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY_EXT 0x9069 -#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x906A -#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_EXT 0x906B -#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x906C -#define GL_MAX_IMAGE_SAMPLES_EXT 0x906D -#define GL_IMAGE_BINDING_FORMAT_EXT 0x906E -#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT_EXT 0x00000001 -#define GL_ELEMENT_ARRAY_BARRIER_BIT_EXT 0x00000002 -#define GL_UNIFORM_BARRIER_BIT_EXT 0x00000004 -#define GL_TEXTURE_FETCH_BARRIER_BIT_EXT 0x00000008 -#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT_EXT 0x00000020 -#define GL_COMMAND_BARRIER_BIT_EXT 0x00000040 -#define GL_PIXEL_BUFFER_BARRIER_BIT_EXT 0x00000080 -#define GL_TEXTURE_UPDATE_BARRIER_BIT_EXT 0x00000100 -#define GL_BUFFER_UPDATE_BARRIER_BIT_EXT 0x00000200 -#define GL_FRAMEBUFFER_BARRIER_BIT_EXT 0x00000400 -#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT_EXT 0x00000800 -#define GL_ATOMIC_COUNTER_BARRIER_BIT_EXT 0x00001000 -#define GL_ALL_BARRIER_BITS_EXT 0xFFFFFFFF -typedef void (APIENTRYP PFNGLBINDIMAGETEXTUREEXTPROC) (GLuint index, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLint format); -typedef void (APIENTRYP PFNGLMEMORYBARRIEREXTPROC) (GLbitfield barriers); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBindImageTextureEXT (GLuint index, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLint format); -GLAPI void APIENTRY glMemoryBarrierEXT (GLbitfield barriers); -#endif -#endif /* GL_EXT_shader_image_load_store */ - -#ifndef GL_EXT_shader_integer_mix -#define GL_EXT_shader_integer_mix 1 -#endif /* GL_EXT_shader_integer_mix */ - -#ifndef GL_EXT_shadow_funcs -#define GL_EXT_shadow_funcs 1 -#endif /* GL_EXT_shadow_funcs */ - -#ifndef GL_EXT_shared_texture_palette -#define GL_EXT_shared_texture_palette 1 -#define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB -#endif /* GL_EXT_shared_texture_palette */ - -#ifndef GL_EXT_stencil_clear_tag -#define GL_EXT_stencil_clear_tag 1 -#define GL_STENCIL_TAG_BITS_EXT 0x88F2 -#define GL_STENCIL_CLEAR_TAG_VALUE_EXT 0x88F3 -typedef void (APIENTRYP PFNGLSTENCILCLEARTAGEXTPROC) (GLsizei stencilTagBits, GLuint stencilClearTag); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glStencilClearTagEXT (GLsizei stencilTagBits, GLuint stencilClearTag); -#endif -#endif /* GL_EXT_stencil_clear_tag */ - -#ifndef GL_EXT_stencil_two_side -#define GL_EXT_stencil_two_side 1 -#define GL_STENCIL_TEST_TWO_SIDE_EXT 0x8910 -#define GL_ACTIVE_STENCIL_FACE_EXT 0x8911 -typedef void (APIENTRYP PFNGLACTIVESTENCILFACEEXTPROC) (GLenum face); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glActiveStencilFaceEXT (GLenum face); -#endif -#endif /* GL_EXT_stencil_two_side */ - -#ifndef GL_EXT_stencil_wrap -#define GL_EXT_stencil_wrap 1 -#define GL_INCR_WRAP_EXT 0x8507 -#define GL_DECR_WRAP_EXT 0x8508 -#endif /* GL_EXT_stencil_wrap */ - -#ifndef GL_EXT_subtexture -#define GL_EXT_subtexture 1 -typedef void (APIENTRYP PFNGLTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); -typedef void (APIENTRYP PFNGLTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTexSubImage1DEXT (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); -GLAPI void APIENTRY glTexSubImage2DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); -#endif -#endif /* GL_EXT_subtexture */ - -#ifndef GL_EXT_texture -#define GL_EXT_texture 1 -#define GL_ALPHA4_EXT 0x803B -#define GL_ALPHA8_EXT 0x803C -#define GL_ALPHA12_EXT 0x803D -#define GL_ALPHA16_EXT 0x803E -#define GL_LUMINANCE4_EXT 0x803F -#define GL_LUMINANCE8_EXT 0x8040 -#define GL_LUMINANCE12_EXT 0x8041 -#define GL_LUMINANCE16_EXT 0x8042 -#define GL_LUMINANCE4_ALPHA4_EXT 0x8043 -#define GL_LUMINANCE6_ALPHA2_EXT 0x8044 -#define GL_LUMINANCE8_ALPHA8_EXT 0x8045 -#define GL_LUMINANCE12_ALPHA4_EXT 0x8046 -#define GL_LUMINANCE12_ALPHA12_EXT 0x8047 -#define GL_LUMINANCE16_ALPHA16_EXT 0x8048 -#define GL_INTENSITY_EXT 0x8049 -#define GL_INTENSITY4_EXT 0x804A -#define GL_INTENSITY8_EXT 0x804B -#define GL_INTENSITY12_EXT 0x804C -#define GL_INTENSITY16_EXT 0x804D -#define GL_RGB2_EXT 0x804E -#define GL_RGB4_EXT 0x804F -#define GL_RGB5_EXT 0x8050 -#define GL_RGB8_EXT 0x8051 -#define GL_RGB10_EXT 0x8052 -#define GL_RGB12_EXT 0x8053 -#define GL_RGB16_EXT 0x8054 -#define GL_RGBA2_EXT 0x8055 -#define GL_RGBA4_EXT 0x8056 -#define GL_RGB5_A1_EXT 0x8057 -#define GL_RGBA8_EXT 0x8058 -#define GL_RGB10_A2_EXT 0x8059 -#define GL_RGBA12_EXT 0x805A -#define GL_RGBA16_EXT 0x805B -#define GL_TEXTURE_RED_SIZE_EXT 0x805C -#define GL_TEXTURE_GREEN_SIZE_EXT 0x805D -#define GL_TEXTURE_BLUE_SIZE_EXT 0x805E -#define GL_TEXTURE_ALPHA_SIZE_EXT 0x805F -#define GL_TEXTURE_LUMINANCE_SIZE_EXT 0x8060 -#define GL_TEXTURE_INTENSITY_SIZE_EXT 0x8061 -#define GL_REPLACE_EXT 0x8062 -#define GL_PROXY_TEXTURE_1D_EXT 0x8063 -#define GL_PROXY_TEXTURE_2D_EXT 0x8064 -#define GL_TEXTURE_TOO_LARGE_EXT 0x8065 -#endif /* GL_EXT_texture */ - -#ifndef GL_EXT_texture3D -#define GL_EXT_texture3D 1 -#define GL_PACK_SKIP_IMAGES_EXT 0x806B -#define GL_PACK_IMAGE_HEIGHT_EXT 0x806C -#define GL_UNPACK_SKIP_IMAGES_EXT 0x806D -#define GL_UNPACK_IMAGE_HEIGHT_EXT 0x806E -#define GL_TEXTURE_3D_EXT 0x806F -#define GL_PROXY_TEXTURE_3D_EXT 0x8070 -#define GL_TEXTURE_DEPTH_EXT 0x8071 -#define GL_TEXTURE_WRAP_R_EXT 0x8072 -#define GL_MAX_3D_TEXTURE_SIZE_EXT 0x8073 -typedef void (APIENTRYP PFNGLTEXIMAGE3DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); -typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTexImage3DEXT (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); -GLAPI void APIENTRY glTexSubImage3DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); -#endif -#endif /* GL_EXT_texture3D */ - -#ifndef GL_EXT_texture_array -#define GL_EXT_texture_array 1 -#define GL_TEXTURE_1D_ARRAY_EXT 0x8C18 -#define GL_PROXY_TEXTURE_1D_ARRAY_EXT 0x8C19 -#define GL_TEXTURE_2D_ARRAY_EXT 0x8C1A -#define GL_PROXY_TEXTURE_2D_ARRAY_EXT 0x8C1B -#define GL_TEXTURE_BINDING_1D_ARRAY_EXT 0x8C1C -#define GL_TEXTURE_BINDING_2D_ARRAY_EXT 0x8C1D -#define GL_MAX_ARRAY_TEXTURE_LAYERS_EXT 0x88FF -#define GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT 0x884E -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFramebufferTextureLayerEXT (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); -#endif -#endif /* GL_EXT_texture_array */ - -#ifndef GL_EXT_texture_buffer_object -#define GL_EXT_texture_buffer_object 1 -#define GL_TEXTURE_BUFFER_EXT 0x8C2A -#define GL_MAX_TEXTURE_BUFFER_SIZE_EXT 0x8C2B -#define GL_TEXTURE_BINDING_BUFFER_EXT 0x8C2C -#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT 0x8C2D -#define GL_TEXTURE_BUFFER_FORMAT_EXT 0x8C2E -typedef void (APIENTRYP PFNGLTEXBUFFEREXTPROC) (GLenum target, GLenum internalformat, GLuint buffer); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTexBufferEXT (GLenum target, GLenum internalformat, GLuint buffer); -#endif -#endif /* GL_EXT_texture_buffer_object */ - -#ifndef GL_EXT_texture_compression_latc -#define GL_EXT_texture_compression_latc 1 -#define GL_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70 -#define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT 0x8C71 -#define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72 -#define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73 -#endif /* GL_EXT_texture_compression_latc */ - -#ifndef GL_EXT_texture_compression_rgtc -#define GL_EXT_texture_compression_rgtc 1 -#define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB -#define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC -#define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD -#define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE -#endif /* GL_EXT_texture_compression_rgtc */ - -#ifndef GL_EXT_texture_compression_s3tc -#define GL_EXT_texture_compression_s3tc 1 -#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 -#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 -#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 -#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 -#endif /* GL_EXT_texture_compression_s3tc */ - -#ifndef GL_EXT_texture_cube_map -#define GL_EXT_texture_cube_map 1 -#define GL_NORMAL_MAP_EXT 0x8511 -#define GL_REFLECTION_MAP_EXT 0x8512 -#define GL_TEXTURE_CUBE_MAP_EXT 0x8513 -#define GL_TEXTURE_BINDING_CUBE_MAP_EXT 0x8514 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT 0x8515 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT 0x8516 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT 0x8517 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT 0x8518 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT 0x8519 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT 0x851A -#define GL_PROXY_TEXTURE_CUBE_MAP_EXT 0x851B -#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT 0x851C -#endif /* GL_EXT_texture_cube_map */ - -#ifndef GL_EXT_texture_env_add -#define GL_EXT_texture_env_add 1 -#endif /* GL_EXT_texture_env_add */ - -#ifndef GL_EXT_texture_env_combine -#define GL_EXT_texture_env_combine 1 -#define GL_COMBINE_EXT 0x8570 -#define GL_COMBINE_RGB_EXT 0x8571 -#define GL_COMBINE_ALPHA_EXT 0x8572 -#define GL_RGB_SCALE_EXT 0x8573 -#define GL_ADD_SIGNED_EXT 0x8574 -#define GL_INTERPOLATE_EXT 0x8575 -#define GL_CONSTANT_EXT 0x8576 -#define GL_PRIMARY_COLOR_EXT 0x8577 -#define GL_PREVIOUS_EXT 0x8578 -#define GL_SOURCE0_RGB_EXT 0x8580 -#define GL_SOURCE1_RGB_EXT 0x8581 -#define GL_SOURCE2_RGB_EXT 0x8582 -#define GL_SOURCE0_ALPHA_EXT 0x8588 -#define GL_SOURCE1_ALPHA_EXT 0x8589 -#define GL_SOURCE2_ALPHA_EXT 0x858A -#define GL_OPERAND0_RGB_EXT 0x8590 -#define GL_OPERAND1_RGB_EXT 0x8591 -#define GL_OPERAND2_RGB_EXT 0x8592 -#define GL_OPERAND0_ALPHA_EXT 0x8598 -#define GL_OPERAND1_ALPHA_EXT 0x8599 -#define GL_OPERAND2_ALPHA_EXT 0x859A -#endif /* GL_EXT_texture_env_combine */ - -#ifndef GL_EXT_texture_env_dot3 -#define GL_EXT_texture_env_dot3 1 -#define GL_DOT3_RGB_EXT 0x8740 -#define GL_DOT3_RGBA_EXT 0x8741 -#endif /* GL_EXT_texture_env_dot3 */ - -#ifndef GL_EXT_texture_filter_anisotropic -#define GL_EXT_texture_filter_anisotropic 1 -#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE -#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF -#endif /* GL_EXT_texture_filter_anisotropic */ - -#ifndef GL_EXT_texture_integer -#define GL_EXT_texture_integer 1 -#define GL_RGBA32UI_EXT 0x8D70 -#define GL_RGB32UI_EXT 0x8D71 -#define GL_ALPHA32UI_EXT 0x8D72 -#define GL_INTENSITY32UI_EXT 0x8D73 -#define GL_LUMINANCE32UI_EXT 0x8D74 -#define GL_LUMINANCE_ALPHA32UI_EXT 0x8D75 -#define GL_RGBA16UI_EXT 0x8D76 -#define GL_RGB16UI_EXT 0x8D77 -#define GL_ALPHA16UI_EXT 0x8D78 -#define GL_INTENSITY16UI_EXT 0x8D79 -#define GL_LUMINANCE16UI_EXT 0x8D7A -#define GL_LUMINANCE_ALPHA16UI_EXT 0x8D7B -#define GL_RGBA8UI_EXT 0x8D7C -#define GL_RGB8UI_EXT 0x8D7D -#define GL_ALPHA8UI_EXT 0x8D7E -#define GL_INTENSITY8UI_EXT 0x8D7F -#define GL_LUMINANCE8UI_EXT 0x8D80 -#define GL_LUMINANCE_ALPHA8UI_EXT 0x8D81 -#define GL_RGBA32I_EXT 0x8D82 -#define GL_RGB32I_EXT 0x8D83 -#define GL_ALPHA32I_EXT 0x8D84 -#define GL_INTENSITY32I_EXT 0x8D85 -#define GL_LUMINANCE32I_EXT 0x8D86 -#define GL_LUMINANCE_ALPHA32I_EXT 0x8D87 -#define GL_RGBA16I_EXT 0x8D88 -#define GL_RGB16I_EXT 0x8D89 -#define GL_ALPHA16I_EXT 0x8D8A -#define GL_INTENSITY16I_EXT 0x8D8B -#define GL_LUMINANCE16I_EXT 0x8D8C -#define GL_LUMINANCE_ALPHA16I_EXT 0x8D8D -#define GL_RGBA8I_EXT 0x8D8E -#define GL_RGB8I_EXT 0x8D8F -#define GL_ALPHA8I_EXT 0x8D90 -#define GL_INTENSITY8I_EXT 0x8D91 -#define GL_LUMINANCE8I_EXT 0x8D92 -#define GL_LUMINANCE_ALPHA8I_EXT 0x8D93 -#define GL_RED_INTEGER_EXT 0x8D94 -#define GL_GREEN_INTEGER_EXT 0x8D95 -#define GL_BLUE_INTEGER_EXT 0x8D96 -#define GL_ALPHA_INTEGER_EXT 0x8D97 -#define GL_RGB_INTEGER_EXT 0x8D98 -#define GL_RGBA_INTEGER_EXT 0x8D99 -#define GL_BGR_INTEGER_EXT 0x8D9A -#define GL_BGRA_INTEGER_EXT 0x8D9B -#define GL_LUMINANCE_INTEGER_EXT 0x8D9C -#define GL_LUMINANCE_ALPHA_INTEGER_EXT 0x8D9D -#define GL_RGBA_INTEGER_MODE_EXT 0x8D9E -typedef void (APIENTRYP PFNGLTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, const GLuint *params); -typedef void (APIENTRYP PFNGLGETTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, GLuint *params); -typedef void (APIENTRYP PFNGLCLEARCOLORIIEXTPROC) (GLint red, GLint green, GLint blue, GLint alpha); -typedef void (APIENTRYP PFNGLCLEARCOLORIUIEXTPROC) (GLuint red, GLuint green, GLuint blue, GLuint alpha); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTexParameterIivEXT (GLenum target, GLenum pname, const GLint *params); -GLAPI void APIENTRY glTexParameterIuivEXT (GLenum target, GLenum pname, const GLuint *params); -GLAPI void APIENTRY glGetTexParameterIivEXT (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetTexParameterIuivEXT (GLenum target, GLenum pname, GLuint *params); -GLAPI void APIENTRY glClearColorIiEXT (GLint red, GLint green, GLint blue, GLint alpha); -GLAPI void APIENTRY glClearColorIuiEXT (GLuint red, GLuint green, GLuint blue, GLuint alpha); -#endif -#endif /* GL_EXT_texture_integer */ - -#ifndef GL_EXT_texture_lod_bias -#define GL_EXT_texture_lod_bias 1 -#define GL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD -#define GL_TEXTURE_FILTER_CONTROL_EXT 0x8500 -#define GL_TEXTURE_LOD_BIAS_EXT 0x8501 -#endif /* GL_EXT_texture_lod_bias */ - -#ifndef GL_EXT_texture_mirror_clamp -#define GL_EXT_texture_mirror_clamp 1 -#define GL_MIRROR_CLAMP_EXT 0x8742 -#define GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743 -#define GL_MIRROR_CLAMP_TO_BORDER_EXT 0x8912 -#endif /* GL_EXT_texture_mirror_clamp */ - -#ifndef GL_EXT_texture_object -#define GL_EXT_texture_object 1 -#define GL_TEXTURE_PRIORITY_EXT 0x8066 -#define GL_TEXTURE_RESIDENT_EXT 0x8067 -#define GL_TEXTURE_1D_BINDING_EXT 0x8068 -#define GL_TEXTURE_2D_BINDING_EXT 0x8069 -#define GL_TEXTURE_3D_BINDING_EXT 0x806A -typedef GLboolean (APIENTRYP PFNGLARETEXTURESRESIDENTEXTPROC) (GLsizei n, const GLuint *textures, GLboolean *residences); -typedef void (APIENTRYP PFNGLBINDTEXTUREEXTPROC) (GLenum target, GLuint texture); -typedef void (APIENTRYP PFNGLDELETETEXTURESEXTPROC) (GLsizei n, const GLuint *textures); -typedef void (APIENTRYP PFNGLGENTEXTURESEXTPROC) (GLsizei n, GLuint *textures); -typedef GLboolean (APIENTRYP PFNGLISTEXTUREEXTPROC) (GLuint texture); -typedef void (APIENTRYP PFNGLPRIORITIZETEXTURESEXTPROC) (GLsizei n, const GLuint *textures, const GLclampf *priorities); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLboolean APIENTRY glAreTexturesResidentEXT (GLsizei n, const GLuint *textures, GLboolean *residences); -GLAPI void APIENTRY glBindTextureEXT (GLenum target, GLuint texture); -GLAPI void APIENTRY glDeleteTexturesEXT (GLsizei n, const GLuint *textures); -GLAPI void APIENTRY glGenTexturesEXT (GLsizei n, GLuint *textures); -GLAPI GLboolean APIENTRY glIsTextureEXT (GLuint texture); -GLAPI void APIENTRY glPrioritizeTexturesEXT (GLsizei n, const GLuint *textures, const GLclampf *priorities); -#endif -#endif /* GL_EXT_texture_object */ - -#ifndef GL_EXT_texture_perturb_normal -#define GL_EXT_texture_perturb_normal 1 -#define GL_PERTURB_EXT 0x85AE -#define GL_TEXTURE_NORMAL_EXT 0x85AF -typedef void (APIENTRYP PFNGLTEXTURENORMALEXTPROC) (GLenum mode); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTextureNormalEXT (GLenum mode); -#endif -#endif /* GL_EXT_texture_perturb_normal */ - -#ifndef GL_EXT_texture_sRGB -#define GL_EXT_texture_sRGB 1 -#define GL_SRGB_EXT 0x8C40 -#define GL_SRGB8_EXT 0x8C41 -#define GL_SRGB_ALPHA_EXT 0x8C42 -#define GL_SRGB8_ALPHA8_EXT 0x8C43 -#define GL_SLUMINANCE_ALPHA_EXT 0x8C44 -#define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45 -#define GL_SLUMINANCE_EXT 0x8C46 -#define GL_SLUMINANCE8_EXT 0x8C47 -#define GL_COMPRESSED_SRGB_EXT 0x8C48 -#define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49 -#define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A -#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B -#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C -#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D -#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E -#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F -#endif /* GL_EXT_texture_sRGB */ - -#ifndef GL_EXT_texture_sRGB_decode -#define GL_EXT_texture_sRGB_decode 1 -#define GL_TEXTURE_SRGB_DECODE_EXT 0x8A48 -#define GL_DECODE_EXT 0x8A49 -#define GL_SKIP_DECODE_EXT 0x8A4A -#endif /* GL_EXT_texture_sRGB_decode */ - -#ifndef GL_EXT_texture_shared_exponent -#define GL_EXT_texture_shared_exponent 1 -#define GL_RGB9_E5_EXT 0x8C3D -#define GL_UNSIGNED_INT_5_9_9_9_REV_EXT 0x8C3E -#define GL_TEXTURE_SHARED_SIZE_EXT 0x8C3F -#endif /* GL_EXT_texture_shared_exponent */ - -#ifndef GL_EXT_texture_snorm -#define GL_EXT_texture_snorm 1 -#define GL_ALPHA_SNORM 0x9010 -#define GL_LUMINANCE_SNORM 0x9011 -#define GL_LUMINANCE_ALPHA_SNORM 0x9012 -#define GL_INTENSITY_SNORM 0x9013 -#define GL_ALPHA8_SNORM 0x9014 -#define GL_LUMINANCE8_SNORM 0x9015 -#define GL_LUMINANCE8_ALPHA8_SNORM 0x9016 -#define GL_INTENSITY8_SNORM 0x9017 -#define GL_ALPHA16_SNORM 0x9018 -#define GL_LUMINANCE16_SNORM 0x9019 -#define GL_LUMINANCE16_ALPHA16_SNORM 0x901A -#define GL_INTENSITY16_SNORM 0x901B -#define GL_RED_SNORM 0x8F90 -#define GL_RG_SNORM 0x8F91 -#define GL_RGB_SNORM 0x8F92 -#define GL_RGBA_SNORM 0x8F93 -#endif /* GL_EXT_texture_snorm */ - -#ifndef GL_EXT_texture_swizzle -#define GL_EXT_texture_swizzle 1 -#define GL_TEXTURE_SWIZZLE_R_EXT 0x8E42 -#define GL_TEXTURE_SWIZZLE_G_EXT 0x8E43 -#define GL_TEXTURE_SWIZZLE_B_EXT 0x8E44 -#define GL_TEXTURE_SWIZZLE_A_EXT 0x8E45 -#define GL_TEXTURE_SWIZZLE_RGBA_EXT 0x8E46 -#endif /* GL_EXT_texture_swizzle */ - -#ifndef GL_EXT_timer_query -#define GL_EXT_timer_query 1 -#define GL_TIME_ELAPSED_EXT 0x88BF -typedef void (APIENTRYP PFNGLGETQUERYOBJECTI64VEXTPROC) (GLuint id, GLenum pname, GLint64 *params); -typedef void (APIENTRYP PFNGLGETQUERYOBJECTUI64VEXTPROC) (GLuint id, GLenum pname, GLuint64 *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGetQueryObjecti64vEXT (GLuint id, GLenum pname, GLint64 *params); -GLAPI void APIENTRY glGetQueryObjectui64vEXT (GLuint id, GLenum pname, GLuint64 *params); -#endif -#endif /* GL_EXT_timer_query */ - -#ifndef GL_EXT_transform_feedback -#define GL_EXT_transform_feedback 1 -#define GL_TRANSFORM_FEEDBACK_BUFFER_EXT 0x8C8E -#define GL_TRANSFORM_FEEDBACK_BUFFER_START_EXT 0x8C84 -#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_EXT 0x8C85 -#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_EXT 0x8C8F -#define GL_INTERLEAVED_ATTRIBS_EXT 0x8C8C -#define GL_SEPARATE_ATTRIBS_EXT 0x8C8D -#define GL_PRIMITIVES_GENERATED_EXT 0x8C87 -#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT 0x8C88 -#define GL_RASTERIZER_DISCARD_EXT 0x8C89 -#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT 0x8C8A -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT 0x8C8B -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT 0x8C80 -#define GL_TRANSFORM_FEEDBACK_VARYINGS_EXT 0x8C83 -#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_EXT 0x8C7F -#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH_EXT 0x8C76 -typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKEXTPROC) (GLenum primitiveMode); -typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKEXTPROC) (void); -typedef void (APIENTRYP PFNGLBINDBUFFERRANGEEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); -typedef void (APIENTRYP PFNGLBINDBUFFEROFFSETEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset); -typedef void (APIENTRYP PFNGLBINDBUFFERBASEEXTPROC) (GLenum target, GLuint index, GLuint buffer); -typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC) (GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode); -typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBeginTransformFeedbackEXT (GLenum primitiveMode); -GLAPI void APIENTRY glEndTransformFeedbackEXT (void); -GLAPI void APIENTRY glBindBufferRangeEXT (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); -GLAPI void APIENTRY glBindBufferOffsetEXT (GLenum target, GLuint index, GLuint buffer, GLintptr offset); -GLAPI void APIENTRY glBindBufferBaseEXT (GLenum target, GLuint index, GLuint buffer); -GLAPI void APIENTRY glTransformFeedbackVaryingsEXT (GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode); -GLAPI void APIENTRY glGetTransformFeedbackVaryingEXT (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); -#endif -#endif /* GL_EXT_transform_feedback */ - -#ifndef GL_EXT_vertex_array -#define GL_EXT_vertex_array 1 -#define GL_VERTEX_ARRAY_EXT 0x8074 -#define GL_NORMAL_ARRAY_EXT 0x8075 -#define GL_COLOR_ARRAY_EXT 0x8076 -#define GL_INDEX_ARRAY_EXT 0x8077 -#define GL_TEXTURE_COORD_ARRAY_EXT 0x8078 -#define GL_EDGE_FLAG_ARRAY_EXT 0x8079 -#define GL_VERTEX_ARRAY_SIZE_EXT 0x807A -#define GL_VERTEX_ARRAY_TYPE_EXT 0x807B -#define GL_VERTEX_ARRAY_STRIDE_EXT 0x807C -#define GL_VERTEX_ARRAY_COUNT_EXT 0x807D -#define GL_NORMAL_ARRAY_TYPE_EXT 0x807E -#define GL_NORMAL_ARRAY_STRIDE_EXT 0x807F -#define GL_NORMAL_ARRAY_COUNT_EXT 0x8080 -#define GL_COLOR_ARRAY_SIZE_EXT 0x8081 -#define GL_COLOR_ARRAY_TYPE_EXT 0x8082 -#define GL_COLOR_ARRAY_STRIDE_EXT 0x8083 -#define GL_COLOR_ARRAY_COUNT_EXT 0x8084 -#define GL_INDEX_ARRAY_TYPE_EXT 0x8085 -#define GL_INDEX_ARRAY_STRIDE_EXT 0x8086 -#define GL_INDEX_ARRAY_COUNT_EXT 0x8087 -#define GL_TEXTURE_COORD_ARRAY_SIZE_EXT 0x8088 -#define GL_TEXTURE_COORD_ARRAY_TYPE_EXT 0x8089 -#define GL_TEXTURE_COORD_ARRAY_STRIDE_EXT 0x808A -#define GL_TEXTURE_COORD_ARRAY_COUNT_EXT 0x808B -#define GL_EDGE_FLAG_ARRAY_STRIDE_EXT 0x808C -#define GL_EDGE_FLAG_ARRAY_COUNT_EXT 0x808D -#define GL_VERTEX_ARRAY_POINTER_EXT 0x808E -#define GL_NORMAL_ARRAY_POINTER_EXT 0x808F -#define GL_COLOR_ARRAY_POINTER_EXT 0x8090 -#define GL_INDEX_ARRAY_POINTER_EXT 0x8091 -#define GL_TEXTURE_COORD_ARRAY_POINTER_EXT 0x8092 -#define GL_EDGE_FLAG_ARRAY_POINTER_EXT 0x8093 -typedef void (APIENTRYP PFNGLARRAYELEMENTEXTPROC) (GLint i); -typedef void (APIENTRYP PFNGLCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const void *pointer); -typedef void (APIENTRYP PFNGLDRAWARRAYSEXTPROC) (GLenum mode, GLint first, GLsizei count); -typedef void (APIENTRYP PFNGLEDGEFLAGPOINTEREXTPROC) (GLsizei stride, GLsizei count, const GLboolean *pointer); -typedef void (APIENTRYP PFNGLGETPOINTERVEXTPROC) (GLenum pname, void **params); -typedef void (APIENTRYP PFNGLINDEXPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const void *pointer); -typedef void (APIENTRYP PFNGLNORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const void *pointer); -typedef void (APIENTRYP PFNGLTEXCOORDPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const void *pointer); -typedef void (APIENTRYP PFNGLVERTEXPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const void *pointer); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glArrayElementEXT (GLint i); -GLAPI void APIENTRY glColorPointerEXT (GLint size, GLenum type, GLsizei stride, GLsizei count, const void *pointer); -GLAPI void APIENTRY glDrawArraysEXT (GLenum mode, GLint first, GLsizei count); -GLAPI void APIENTRY glEdgeFlagPointerEXT (GLsizei stride, GLsizei count, const GLboolean *pointer); -GLAPI void APIENTRY glGetPointervEXT (GLenum pname, void **params); -GLAPI void APIENTRY glIndexPointerEXT (GLenum type, GLsizei stride, GLsizei count, const void *pointer); -GLAPI void APIENTRY glNormalPointerEXT (GLenum type, GLsizei stride, GLsizei count, const void *pointer); -GLAPI void APIENTRY glTexCoordPointerEXT (GLint size, GLenum type, GLsizei stride, GLsizei count, const void *pointer); -GLAPI void APIENTRY glVertexPointerEXT (GLint size, GLenum type, GLsizei stride, GLsizei count, const void *pointer); -#endif -#endif /* GL_EXT_vertex_array */ - -#ifndef GL_EXT_vertex_array_bgra -#define GL_EXT_vertex_array_bgra 1 -#endif /* GL_EXT_vertex_array_bgra */ - -#ifndef GL_EXT_vertex_attrib_64bit -#define GL_EXT_vertex_attrib_64bit 1 -#define GL_DOUBLE_VEC2_EXT 0x8FFC -#define GL_DOUBLE_VEC3_EXT 0x8FFD -#define GL_DOUBLE_VEC4_EXT 0x8FFE -#define GL_DOUBLE_MAT2_EXT 0x8F46 -#define GL_DOUBLE_MAT3_EXT 0x8F47 -#define GL_DOUBLE_MAT4_EXT 0x8F48 -#define GL_DOUBLE_MAT2x3_EXT 0x8F49 -#define GL_DOUBLE_MAT2x4_EXT 0x8F4A -#define GL_DOUBLE_MAT3x2_EXT 0x8F4B -#define GL_DOUBLE_MAT3x4_EXT 0x8F4C -#define GL_DOUBLE_MAT4x2_EXT 0x8F4D -#define GL_DOUBLE_MAT4x3_EXT 0x8F4E -typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DEXTPROC) (GLuint index, GLdouble x); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DEXTPROC) (GLuint index, GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DEXTPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DEXTPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DVEXTPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DVEXTPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DVEXTPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DVEXTPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBLPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLDVEXTPROC) (GLuint index, GLenum pname, GLdouble *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexAttribL1dEXT (GLuint index, GLdouble x); -GLAPI void APIENTRY glVertexAttribL2dEXT (GLuint index, GLdouble x, GLdouble y); -GLAPI void APIENTRY glVertexAttribL3dEXT (GLuint index, GLdouble x, GLdouble y, GLdouble z); -GLAPI void APIENTRY glVertexAttribL4dEXT (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void APIENTRY glVertexAttribL1dvEXT (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttribL2dvEXT (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttribL3dvEXT (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttribL4dvEXT (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttribLPointerEXT (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); -GLAPI void APIENTRY glGetVertexAttribLdvEXT (GLuint index, GLenum pname, GLdouble *params); -#endif -#endif /* GL_EXT_vertex_attrib_64bit */ - -#ifndef GL_EXT_vertex_shader -#define GL_EXT_vertex_shader 1 -#define GL_VERTEX_SHADER_EXT 0x8780 -#define GL_VERTEX_SHADER_BINDING_EXT 0x8781 -#define GL_OP_INDEX_EXT 0x8782 -#define GL_OP_NEGATE_EXT 0x8783 -#define GL_OP_DOT3_EXT 0x8784 -#define GL_OP_DOT4_EXT 0x8785 -#define GL_OP_MUL_EXT 0x8786 -#define GL_OP_ADD_EXT 0x8787 -#define GL_OP_MADD_EXT 0x8788 -#define GL_OP_FRAC_EXT 0x8789 -#define GL_OP_MAX_EXT 0x878A -#define GL_OP_MIN_EXT 0x878B -#define GL_OP_SET_GE_EXT 0x878C -#define GL_OP_SET_LT_EXT 0x878D -#define GL_OP_CLAMP_EXT 0x878E -#define GL_OP_FLOOR_EXT 0x878F -#define GL_OP_ROUND_EXT 0x8790 -#define GL_OP_EXP_BASE_2_EXT 0x8791 -#define GL_OP_LOG_BASE_2_EXT 0x8792 -#define GL_OP_POWER_EXT 0x8793 -#define GL_OP_RECIP_EXT 0x8794 -#define GL_OP_RECIP_SQRT_EXT 0x8795 -#define GL_OP_SUB_EXT 0x8796 -#define GL_OP_CROSS_PRODUCT_EXT 0x8797 -#define GL_OP_MULTIPLY_MATRIX_EXT 0x8798 -#define GL_OP_MOV_EXT 0x8799 -#define GL_OUTPUT_VERTEX_EXT 0x879A -#define GL_OUTPUT_COLOR0_EXT 0x879B -#define GL_OUTPUT_COLOR1_EXT 0x879C -#define GL_OUTPUT_TEXTURE_COORD0_EXT 0x879D -#define GL_OUTPUT_TEXTURE_COORD1_EXT 0x879E -#define GL_OUTPUT_TEXTURE_COORD2_EXT 0x879F -#define GL_OUTPUT_TEXTURE_COORD3_EXT 0x87A0 -#define GL_OUTPUT_TEXTURE_COORD4_EXT 0x87A1 -#define GL_OUTPUT_TEXTURE_COORD5_EXT 0x87A2 -#define GL_OUTPUT_TEXTURE_COORD6_EXT 0x87A3 -#define GL_OUTPUT_TEXTURE_COORD7_EXT 0x87A4 -#define GL_OUTPUT_TEXTURE_COORD8_EXT 0x87A5 -#define GL_OUTPUT_TEXTURE_COORD9_EXT 0x87A6 -#define GL_OUTPUT_TEXTURE_COORD10_EXT 0x87A7 -#define GL_OUTPUT_TEXTURE_COORD11_EXT 0x87A8 -#define GL_OUTPUT_TEXTURE_COORD12_EXT 0x87A9 -#define GL_OUTPUT_TEXTURE_COORD13_EXT 0x87AA -#define GL_OUTPUT_TEXTURE_COORD14_EXT 0x87AB -#define GL_OUTPUT_TEXTURE_COORD15_EXT 0x87AC -#define GL_OUTPUT_TEXTURE_COORD16_EXT 0x87AD -#define GL_OUTPUT_TEXTURE_COORD17_EXT 0x87AE -#define GL_OUTPUT_TEXTURE_COORD18_EXT 0x87AF -#define GL_OUTPUT_TEXTURE_COORD19_EXT 0x87B0 -#define GL_OUTPUT_TEXTURE_COORD20_EXT 0x87B1 -#define GL_OUTPUT_TEXTURE_COORD21_EXT 0x87B2 -#define GL_OUTPUT_TEXTURE_COORD22_EXT 0x87B3 -#define GL_OUTPUT_TEXTURE_COORD23_EXT 0x87B4 -#define GL_OUTPUT_TEXTURE_COORD24_EXT 0x87B5 -#define GL_OUTPUT_TEXTURE_COORD25_EXT 0x87B6 -#define GL_OUTPUT_TEXTURE_COORD26_EXT 0x87B7 -#define GL_OUTPUT_TEXTURE_COORD27_EXT 0x87B8 -#define GL_OUTPUT_TEXTURE_COORD28_EXT 0x87B9 -#define GL_OUTPUT_TEXTURE_COORD29_EXT 0x87BA -#define GL_OUTPUT_TEXTURE_COORD30_EXT 0x87BB -#define GL_OUTPUT_TEXTURE_COORD31_EXT 0x87BC -#define GL_OUTPUT_FOG_EXT 0x87BD -#define GL_SCALAR_EXT 0x87BE -#define GL_VECTOR_EXT 0x87BF -#define GL_MATRIX_EXT 0x87C0 -#define GL_VARIANT_EXT 0x87C1 -#define GL_INVARIANT_EXT 0x87C2 -#define GL_LOCAL_CONSTANT_EXT 0x87C3 -#define GL_LOCAL_EXT 0x87C4 -#define GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87C5 -#define GL_MAX_VERTEX_SHADER_VARIANTS_EXT 0x87C6 -#define GL_MAX_VERTEX_SHADER_INVARIANTS_EXT 0x87C7 -#define GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87C8 -#define GL_MAX_VERTEX_SHADER_LOCALS_EXT 0x87C9 -#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CA -#define GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT 0x87CB -#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87CC -#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT 0x87CD -#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT 0x87CE -#define GL_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CF -#define GL_VERTEX_SHADER_VARIANTS_EXT 0x87D0 -#define GL_VERTEX_SHADER_INVARIANTS_EXT 0x87D1 -#define GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87D2 -#define GL_VERTEX_SHADER_LOCALS_EXT 0x87D3 -#define GL_VERTEX_SHADER_OPTIMIZED_EXT 0x87D4 -#define GL_X_EXT 0x87D5 -#define GL_Y_EXT 0x87D6 -#define GL_Z_EXT 0x87D7 -#define GL_W_EXT 0x87D8 -#define GL_NEGATIVE_X_EXT 0x87D9 -#define GL_NEGATIVE_Y_EXT 0x87DA -#define GL_NEGATIVE_Z_EXT 0x87DB -#define GL_NEGATIVE_W_EXT 0x87DC -#define GL_ZERO_EXT 0x87DD -#define GL_ONE_EXT 0x87DE -#define GL_NEGATIVE_ONE_EXT 0x87DF -#define GL_NORMALIZED_RANGE_EXT 0x87E0 -#define GL_FULL_RANGE_EXT 0x87E1 -#define GL_CURRENT_VERTEX_EXT 0x87E2 -#define GL_MVP_MATRIX_EXT 0x87E3 -#define GL_VARIANT_VALUE_EXT 0x87E4 -#define GL_VARIANT_DATATYPE_EXT 0x87E5 -#define GL_VARIANT_ARRAY_STRIDE_EXT 0x87E6 -#define GL_VARIANT_ARRAY_TYPE_EXT 0x87E7 -#define GL_VARIANT_ARRAY_EXT 0x87E8 -#define GL_VARIANT_ARRAY_POINTER_EXT 0x87E9 -#define GL_INVARIANT_VALUE_EXT 0x87EA -#define GL_INVARIANT_DATATYPE_EXT 0x87EB -#define GL_LOCAL_CONSTANT_VALUE_EXT 0x87EC -#define GL_LOCAL_CONSTANT_DATATYPE_EXT 0x87ED -typedef void (APIENTRYP PFNGLBEGINVERTEXSHADEREXTPROC) (void); -typedef void (APIENTRYP PFNGLENDVERTEXSHADEREXTPROC) (void); -typedef void (APIENTRYP PFNGLBINDVERTEXSHADEREXTPROC) (GLuint id); -typedef GLuint (APIENTRYP PFNGLGENVERTEXSHADERSEXTPROC) (GLuint range); -typedef void (APIENTRYP PFNGLDELETEVERTEXSHADEREXTPROC) (GLuint id); -typedef void (APIENTRYP PFNGLSHADEROP1EXTPROC) (GLenum op, GLuint res, GLuint arg1); -typedef void (APIENTRYP PFNGLSHADEROP2EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2); -typedef void (APIENTRYP PFNGLSHADEROP3EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3); -typedef void (APIENTRYP PFNGLSWIZZLEEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); -typedef void (APIENTRYP PFNGLWRITEMASKEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); -typedef void (APIENTRYP PFNGLINSERTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); -typedef void (APIENTRYP PFNGLEXTRACTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); -typedef GLuint (APIENTRYP PFNGLGENSYMBOLSEXTPROC) (GLenum datatype, GLenum storagetype, GLenum range, GLuint components); -typedef void (APIENTRYP PFNGLSETINVARIANTEXTPROC) (GLuint id, GLenum type, const void *addr); -typedef void (APIENTRYP PFNGLSETLOCALCONSTANTEXTPROC) (GLuint id, GLenum type, const void *addr); -typedef void (APIENTRYP PFNGLVARIANTBVEXTPROC) (GLuint id, const GLbyte *addr); -typedef void (APIENTRYP PFNGLVARIANTSVEXTPROC) (GLuint id, const GLshort *addr); -typedef void (APIENTRYP PFNGLVARIANTIVEXTPROC) (GLuint id, const GLint *addr); -typedef void (APIENTRYP PFNGLVARIANTFVEXTPROC) (GLuint id, const GLfloat *addr); -typedef void (APIENTRYP PFNGLVARIANTDVEXTPROC) (GLuint id, const GLdouble *addr); -typedef void (APIENTRYP PFNGLVARIANTUBVEXTPROC) (GLuint id, const GLubyte *addr); -typedef void (APIENTRYP PFNGLVARIANTUSVEXTPROC) (GLuint id, const GLushort *addr); -typedef void (APIENTRYP PFNGLVARIANTUIVEXTPROC) (GLuint id, const GLuint *addr); -typedef void (APIENTRYP PFNGLVARIANTPOINTEREXTPROC) (GLuint id, GLenum type, GLuint stride, const void *addr); -typedef void (APIENTRYP PFNGLENABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); -typedef void (APIENTRYP PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); -typedef GLuint (APIENTRYP PFNGLBINDLIGHTPARAMETEREXTPROC) (GLenum light, GLenum value); -typedef GLuint (APIENTRYP PFNGLBINDMATERIALPARAMETEREXTPROC) (GLenum face, GLenum value); -typedef GLuint (APIENTRYP PFNGLBINDTEXGENPARAMETEREXTPROC) (GLenum unit, GLenum coord, GLenum value); -typedef GLuint (APIENTRYP PFNGLBINDTEXTUREUNITPARAMETEREXTPROC) (GLenum unit, GLenum value); -typedef GLuint (APIENTRYP PFNGLBINDPARAMETEREXTPROC) (GLenum value); -typedef GLboolean (APIENTRYP PFNGLISVARIANTENABLEDEXTPROC) (GLuint id, GLenum cap); -typedef void (APIENTRYP PFNGLGETVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); -typedef void (APIENTRYP PFNGLGETVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); -typedef void (APIENTRYP PFNGLGETVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); -typedef void (APIENTRYP PFNGLGETVARIANTPOINTERVEXTPROC) (GLuint id, GLenum value, void **data); -typedef void (APIENTRYP PFNGLGETINVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); -typedef void (APIENTRYP PFNGLGETINVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); -typedef void (APIENTRYP PFNGLGETINVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); -typedef void (APIENTRYP PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); -typedef void (APIENTRYP PFNGLGETLOCALCONSTANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); -typedef void (APIENTRYP PFNGLGETLOCALCONSTANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBeginVertexShaderEXT (void); -GLAPI void APIENTRY glEndVertexShaderEXT (void); -GLAPI void APIENTRY glBindVertexShaderEXT (GLuint id); -GLAPI GLuint APIENTRY glGenVertexShadersEXT (GLuint range); -GLAPI void APIENTRY glDeleteVertexShaderEXT (GLuint id); -GLAPI void APIENTRY glShaderOp1EXT (GLenum op, GLuint res, GLuint arg1); -GLAPI void APIENTRY glShaderOp2EXT (GLenum op, GLuint res, GLuint arg1, GLuint arg2); -GLAPI void APIENTRY glShaderOp3EXT (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3); -GLAPI void APIENTRY glSwizzleEXT (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); -GLAPI void APIENTRY glWriteMaskEXT (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); -GLAPI void APIENTRY glInsertComponentEXT (GLuint res, GLuint src, GLuint num); -GLAPI void APIENTRY glExtractComponentEXT (GLuint res, GLuint src, GLuint num); -GLAPI GLuint APIENTRY glGenSymbolsEXT (GLenum datatype, GLenum storagetype, GLenum range, GLuint components); -GLAPI void APIENTRY glSetInvariantEXT (GLuint id, GLenum type, const void *addr); -GLAPI void APIENTRY glSetLocalConstantEXT (GLuint id, GLenum type, const void *addr); -GLAPI void APIENTRY glVariantbvEXT (GLuint id, const GLbyte *addr); -GLAPI void APIENTRY glVariantsvEXT (GLuint id, const GLshort *addr); -GLAPI void APIENTRY glVariantivEXT (GLuint id, const GLint *addr); -GLAPI void APIENTRY glVariantfvEXT (GLuint id, const GLfloat *addr); -GLAPI void APIENTRY glVariantdvEXT (GLuint id, const GLdouble *addr); -GLAPI void APIENTRY glVariantubvEXT (GLuint id, const GLubyte *addr); -GLAPI void APIENTRY glVariantusvEXT (GLuint id, const GLushort *addr); -GLAPI void APIENTRY glVariantuivEXT (GLuint id, const GLuint *addr); -GLAPI void APIENTRY glVariantPointerEXT (GLuint id, GLenum type, GLuint stride, const void *addr); -GLAPI void APIENTRY glEnableVariantClientStateEXT (GLuint id); -GLAPI void APIENTRY glDisableVariantClientStateEXT (GLuint id); -GLAPI GLuint APIENTRY glBindLightParameterEXT (GLenum light, GLenum value); -GLAPI GLuint APIENTRY glBindMaterialParameterEXT (GLenum face, GLenum value); -GLAPI GLuint APIENTRY glBindTexGenParameterEXT (GLenum unit, GLenum coord, GLenum value); -GLAPI GLuint APIENTRY glBindTextureUnitParameterEXT (GLenum unit, GLenum value); -GLAPI GLuint APIENTRY glBindParameterEXT (GLenum value); -GLAPI GLboolean APIENTRY glIsVariantEnabledEXT (GLuint id, GLenum cap); -GLAPI void APIENTRY glGetVariantBooleanvEXT (GLuint id, GLenum value, GLboolean *data); -GLAPI void APIENTRY glGetVariantIntegervEXT (GLuint id, GLenum value, GLint *data); -GLAPI void APIENTRY glGetVariantFloatvEXT (GLuint id, GLenum value, GLfloat *data); -GLAPI void APIENTRY glGetVariantPointervEXT (GLuint id, GLenum value, void **data); -GLAPI void APIENTRY glGetInvariantBooleanvEXT (GLuint id, GLenum value, GLboolean *data); -GLAPI void APIENTRY glGetInvariantIntegervEXT (GLuint id, GLenum value, GLint *data); -GLAPI void APIENTRY glGetInvariantFloatvEXT (GLuint id, GLenum value, GLfloat *data); -GLAPI void APIENTRY glGetLocalConstantBooleanvEXT (GLuint id, GLenum value, GLboolean *data); -GLAPI void APIENTRY glGetLocalConstantIntegervEXT (GLuint id, GLenum value, GLint *data); -GLAPI void APIENTRY glGetLocalConstantFloatvEXT (GLuint id, GLenum value, GLfloat *data); -#endif -#endif /* GL_EXT_vertex_shader */ - -#ifndef GL_EXT_vertex_weighting -#define GL_EXT_vertex_weighting 1 -#define GL_MODELVIEW0_STACK_DEPTH_EXT 0x0BA3 -#define GL_MODELVIEW1_STACK_DEPTH_EXT 0x8502 -#define GL_MODELVIEW0_MATRIX_EXT 0x0BA6 -#define GL_MODELVIEW1_MATRIX_EXT 0x8506 -#define GL_VERTEX_WEIGHTING_EXT 0x8509 -#define GL_MODELVIEW0_EXT 0x1700 -#define GL_MODELVIEW1_EXT 0x850A -#define GL_CURRENT_VERTEX_WEIGHT_EXT 0x850B -#define GL_VERTEX_WEIGHT_ARRAY_EXT 0x850C -#define GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT 0x850D -#define GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT 0x850E -#define GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT 0x850F -#define GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT 0x8510 -typedef void (APIENTRYP PFNGLVERTEXWEIGHTFEXTPROC) (GLfloat weight); -typedef void (APIENTRYP PFNGLVERTEXWEIGHTFVEXTPROC) (const GLfloat *weight); -typedef void (APIENTRYP PFNGLVERTEXWEIGHTPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, const void *pointer); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexWeightfEXT (GLfloat weight); -GLAPI void APIENTRY glVertexWeightfvEXT (const GLfloat *weight); -GLAPI void APIENTRY glVertexWeightPointerEXT (GLint size, GLenum type, GLsizei stride, const void *pointer); -#endif -#endif /* GL_EXT_vertex_weighting */ - -#ifndef GL_EXT_x11_sync_object -#define GL_EXT_x11_sync_object 1 -#define GL_SYNC_X11_FENCE_EXT 0x90E1 -typedef GLsync (APIENTRYP PFNGLIMPORTSYNCEXTPROC) (GLenum external_sync_type, GLintptr external_sync, GLbitfield flags); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLsync APIENTRY glImportSyncEXT (GLenum external_sync_type, GLintptr external_sync, GLbitfield flags); -#endif -#endif /* GL_EXT_x11_sync_object */ - -#ifndef GL_GREMEDY_frame_terminator -#define GL_GREMEDY_frame_terminator 1 -typedef void (APIENTRYP PFNGLFRAMETERMINATORGREMEDYPROC) (void); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFrameTerminatorGREMEDY (void); -#endif -#endif /* GL_GREMEDY_frame_terminator */ - -#ifndef GL_GREMEDY_string_marker -#define GL_GREMEDY_string_marker 1 -typedef void (APIENTRYP PFNGLSTRINGMARKERGREMEDYPROC) (GLsizei len, const void *string); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glStringMarkerGREMEDY (GLsizei len, const void *string); -#endif -#endif /* GL_GREMEDY_string_marker */ - -#ifndef GL_HP_convolution_border_modes -#define GL_HP_convolution_border_modes 1 -#define GL_IGNORE_BORDER_HP 0x8150 -#define GL_CONSTANT_BORDER_HP 0x8151 -#define GL_REPLICATE_BORDER_HP 0x8153 -#define GL_CONVOLUTION_BORDER_COLOR_HP 0x8154 -#endif /* GL_HP_convolution_border_modes */ - -#ifndef GL_HP_image_transform -#define GL_HP_image_transform 1 -#define GL_IMAGE_SCALE_X_HP 0x8155 -#define GL_IMAGE_SCALE_Y_HP 0x8156 -#define GL_IMAGE_TRANSLATE_X_HP 0x8157 -#define GL_IMAGE_TRANSLATE_Y_HP 0x8158 -#define GL_IMAGE_ROTATE_ANGLE_HP 0x8159 -#define GL_IMAGE_ROTATE_ORIGIN_X_HP 0x815A -#define GL_IMAGE_ROTATE_ORIGIN_Y_HP 0x815B -#define GL_IMAGE_MAG_FILTER_HP 0x815C -#define GL_IMAGE_MIN_FILTER_HP 0x815D -#define GL_IMAGE_CUBIC_WEIGHT_HP 0x815E -#define GL_CUBIC_HP 0x815F -#define GL_AVERAGE_HP 0x8160 -#define GL_IMAGE_TRANSFORM_2D_HP 0x8161 -#define GL_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8162 -#define GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8163 -typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERIHPPROC) (GLenum target, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERFHPPROC) (GLenum target, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, GLfloat *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glImageTransformParameteriHP (GLenum target, GLenum pname, GLint param); -GLAPI void APIENTRY glImageTransformParameterfHP (GLenum target, GLenum pname, GLfloat param); -GLAPI void APIENTRY glImageTransformParameterivHP (GLenum target, GLenum pname, const GLint *params); -GLAPI void APIENTRY glImageTransformParameterfvHP (GLenum target, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glGetImageTransformParameterivHP (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetImageTransformParameterfvHP (GLenum target, GLenum pname, GLfloat *params); -#endif -#endif /* GL_HP_image_transform */ - -#ifndef GL_HP_occlusion_test -#define GL_HP_occlusion_test 1 -#define GL_OCCLUSION_TEST_HP 0x8165 -#define GL_OCCLUSION_TEST_RESULT_HP 0x8166 -#endif /* GL_HP_occlusion_test */ - -#ifndef GL_HP_texture_lighting -#define GL_HP_texture_lighting 1 -#define GL_TEXTURE_LIGHTING_MODE_HP 0x8167 -#define GL_TEXTURE_POST_SPECULAR_HP 0x8168 -#define GL_TEXTURE_PRE_SPECULAR_HP 0x8169 -#endif /* GL_HP_texture_lighting */ - -#ifndef GL_IBM_cull_vertex -#define GL_IBM_cull_vertex 1 -#define GL_CULL_VERTEX_IBM 103050 -#endif /* GL_IBM_cull_vertex */ - -#ifndef GL_IBM_multimode_draw_arrays -#define GL_IBM_multimode_draw_arrays 1 -typedef void (APIENTRYP PFNGLMULTIMODEDRAWARRAYSIBMPROC) (const GLenum *mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride); -typedef void (APIENTRYP PFNGLMULTIMODEDRAWELEMENTSIBMPROC) (const GLenum *mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount, GLint modestride); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glMultiModeDrawArraysIBM (const GLenum *mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride); -GLAPI void APIENTRY glMultiModeDrawElementsIBM (const GLenum *mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount, GLint modestride); -#endif -#endif /* GL_IBM_multimode_draw_arrays */ - -#ifndef GL_IBM_rasterpos_clip -#define GL_IBM_rasterpos_clip 1 -#define GL_RASTER_POSITION_UNCLIPPED_IBM 0x19262 -#endif /* GL_IBM_rasterpos_clip */ - -#ifndef GL_IBM_static_data -#define GL_IBM_static_data 1 -#define GL_ALL_STATIC_DATA_IBM 103060 -#define GL_STATIC_VERTEX_ARRAY_IBM 103061 -typedef void (APIENTRYP PFNGLFLUSHSTATICDATAIBMPROC) (GLenum target); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFlushStaticDataIBM (GLenum target); -#endif -#endif /* GL_IBM_static_data */ - -#ifndef GL_IBM_texture_mirrored_repeat -#define GL_IBM_texture_mirrored_repeat 1 -#define GL_MIRRORED_REPEAT_IBM 0x8370 -#endif /* GL_IBM_texture_mirrored_repeat */ - -#ifndef GL_IBM_vertex_array_lists -#define GL_IBM_vertex_array_lists 1 -#define GL_VERTEX_ARRAY_LIST_IBM 103070 -#define GL_NORMAL_ARRAY_LIST_IBM 103071 -#define GL_COLOR_ARRAY_LIST_IBM 103072 -#define GL_INDEX_ARRAY_LIST_IBM 103073 -#define GL_TEXTURE_COORD_ARRAY_LIST_IBM 103074 -#define GL_EDGE_FLAG_ARRAY_LIST_IBM 103075 -#define GL_FOG_COORDINATE_ARRAY_LIST_IBM 103076 -#define GL_SECONDARY_COLOR_ARRAY_LIST_IBM 103077 -#define GL_VERTEX_ARRAY_LIST_STRIDE_IBM 103080 -#define GL_NORMAL_ARRAY_LIST_STRIDE_IBM 103081 -#define GL_COLOR_ARRAY_LIST_STRIDE_IBM 103082 -#define GL_INDEX_ARRAY_LIST_STRIDE_IBM 103083 -#define GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM 103084 -#define GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM 103085 -#define GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM 103086 -#define GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM 103087 -typedef void (APIENTRYP PFNGLCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const void **pointer, GLint ptrstride); -typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const void **pointer, GLint ptrstride); -typedef void (APIENTRYP PFNGLEDGEFLAGPOINTERLISTIBMPROC) (GLint stride, const GLboolean **pointer, GLint ptrstride); -typedef void (APIENTRYP PFNGLFOGCOORDPOINTERLISTIBMPROC) (GLenum type, GLint stride, const void **pointer, GLint ptrstride); -typedef void (APIENTRYP PFNGLINDEXPOINTERLISTIBMPROC) (GLenum type, GLint stride, const void **pointer, GLint ptrstride); -typedef void (APIENTRYP PFNGLNORMALPOINTERLISTIBMPROC) (GLenum type, GLint stride, const void **pointer, GLint ptrstride); -typedef void (APIENTRYP PFNGLTEXCOORDPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const void **pointer, GLint ptrstride); -typedef void (APIENTRYP PFNGLVERTEXPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const void **pointer, GLint ptrstride); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glColorPointerListIBM (GLint size, GLenum type, GLint stride, const void **pointer, GLint ptrstride); -GLAPI void APIENTRY glSecondaryColorPointerListIBM (GLint size, GLenum type, GLint stride, const void **pointer, GLint ptrstride); -GLAPI void APIENTRY glEdgeFlagPointerListIBM (GLint stride, const GLboolean **pointer, GLint ptrstride); -GLAPI void APIENTRY glFogCoordPointerListIBM (GLenum type, GLint stride, const void **pointer, GLint ptrstride); -GLAPI void APIENTRY glIndexPointerListIBM (GLenum type, GLint stride, const void **pointer, GLint ptrstride); -GLAPI void APIENTRY glNormalPointerListIBM (GLenum type, GLint stride, const void **pointer, GLint ptrstride); -GLAPI void APIENTRY glTexCoordPointerListIBM (GLint size, GLenum type, GLint stride, const void **pointer, GLint ptrstride); -GLAPI void APIENTRY glVertexPointerListIBM (GLint size, GLenum type, GLint stride, const void **pointer, GLint ptrstride); -#endif -#endif /* GL_IBM_vertex_array_lists */ - -#ifndef GL_INGR_blend_func_separate -#define GL_INGR_blend_func_separate 1 -typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEINGRPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendFuncSeparateINGR (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); -#endif -#endif /* GL_INGR_blend_func_separate */ - -#ifndef GL_INGR_color_clamp -#define GL_INGR_color_clamp 1 -#define GL_RED_MIN_CLAMP_INGR 0x8560 -#define GL_GREEN_MIN_CLAMP_INGR 0x8561 -#define GL_BLUE_MIN_CLAMP_INGR 0x8562 -#define GL_ALPHA_MIN_CLAMP_INGR 0x8563 -#define GL_RED_MAX_CLAMP_INGR 0x8564 -#define GL_GREEN_MAX_CLAMP_INGR 0x8565 -#define GL_BLUE_MAX_CLAMP_INGR 0x8566 -#define GL_ALPHA_MAX_CLAMP_INGR 0x8567 -#endif /* GL_INGR_color_clamp */ - -#ifndef GL_INGR_interlace_read -#define GL_INGR_interlace_read 1 -#define GL_INTERLACE_READ_INGR 0x8568 -#endif /* GL_INGR_interlace_read */ - -#ifndef GL_INTEL_fragment_shader_ordering -#define GL_INTEL_fragment_shader_ordering 1 -#endif /* GL_INTEL_fragment_shader_ordering */ - -#ifndef GL_INTEL_map_texture -#define GL_INTEL_map_texture 1 -#define GL_TEXTURE_MEMORY_LAYOUT_INTEL 0x83FF -#define GL_LAYOUT_DEFAULT_INTEL 0 -#define GL_LAYOUT_LINEAR_INTEL 1 -#define GL_LAYOUT_LINEAR_CPU_CACHED_INTEL 2 -typedef void (APIENTRYP PFNGLSYNCTEXTUREINTELPROC) (GLuint texture); -typedef void (APIENTRYP PFNGLUNMAPTEXTURE2DINTELPROC) (GLuint texture, GLint level); -typedef void *(APIENTRYP PFNGLMAPTEXTURE2DINTELPROC) (GLuint texture, GLint level, GLbitfield access, GLint *stride, GLenum *layout); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glSyncTextureINTEL (GLuint texture); -GLAPI void APIENTRY glUnmapTexture2DINTEL (GLuint texture, GLint level); -GLAPI void *APIENTRY glMapTexture2DINTEL (GLuint texture, GLint level, GLbitfield access, GLint *stride, GLenum *layout); -#endif -#endif /* GL_INTEL_map_texture */ - -#ifndef GL_INTEL_parallel_arrays -#define GL_INTEL_parallel_arrays 1 -#define GL_PARALLEL_ARRAYS_INTEL 0x83F4 -#define GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL 0x83F5 -#define GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL 0x83F6 -#define GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL 0x83F7 -#define GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL 0x83F8 -typedef void (APIENTRYP PFNGLVERTEXPOINTERVINTELPROC) (GLint size, GLenum type, const void **pointer); -typedef void (APIENTRYP PFNGLNORMALPOINTERVINTELPROC) (GLenum type, const void **pointer); -typedef void (APIENTRYP PFNGLCOLORPOINTERVINTELPROC) (GLint size, GLenum type, const void **pointer); -typedef void (APIENTRYP PFNGLTEXCOORDPOINTERVINTELPROC) (GLint size, GLenum type, const void **pointer); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexPointervINTEL (GLint size, GLenum type, const void **pointer); -GLAPI void APIENTRY glNormalPointervINTEL (GLenum type, const void **pointer); -GLAPI void APIENTRY glColorPointervINTEL (GLint size, GLenum type, const void **pointer); -GLAPI void APIENTRY glTexCoordPointervINTEL (GLint size, GLenum type, const void **pointer); -#endif -#endif /* GL_INTEL_parallel_arrays */ - -#ifndef GL_INTEL_performance_query -#define GL_INTEL_performance_query 1 -#define GL_PERFQUERY_SINGLE_CONTEXT_INTEL 0x00000000 -#define GL_PERFQUERY_GLOBAL_CONTEXT_INTEL 0x00000001 -#define GL_PERFQUERY_WAIT_INTEL 0x83FB -#define GL_PERFQUERY_FLUSH_INTEL 0x83FA -#define GL_PERFQUERY_DONOT_FLUSH_INTEL 0x83F9 -#define GL_PERFQUERY_COUNTER_EVENT_INTEL 0x94F0 -#define GL_PERFQUERY_COUNTER_DURATION_NORM_INTEL 0x94F1 -#define GL_PERFQUERY_COUNTER_DURATION_RAW_INTEL 0x94F2 -#define GL_PERFQUERY_COUNTER_THROUGHPUT_INTEL 0x94F3 -#define GL_PERFQUERY_COUNTER_RAW_INTEL 0x94F4 -#define GL_PERFQUERY_COUNTER_TIMESTAMP_INTEL 0x94F5 -#define GL_PERFQUERY_COUNTER_DATA_UINT32_INTEL 0x94F8 -#define GL_PERFQUERY_COUNTER_DATA_UINT64_INTEL 0x94F9 -#define GL_PERFQUERY_COUNTER_DATA_FLOAT_INTEL 0x94FA -#define GL_PERFQUERY_COUNTER_DATA_DOUBLE_INTEL 0x94FB -#define GL_PERFQUERY_COUNTER_DATA_BOOL32_INTEL 0x94FC -#define GL_PERFQUERY_QUERY_NAME_LENGTH_MAX_INTEL 0x94FD -#define GL_PERFQUERY_COUNTER_NAME_LENGTH_MAX_INTEL 0x94FE -#define GL_PERFQUERY_COUNTER_DESC_LENGTH_MAX_INTEL 0x94FF -#define GL_PERFQUERY_GPA_EXTENDED_COUNTERS_INTEL 0x9500 -typedef void (APIENTRYP PFNGLBEGINPERFQUERYINTELPROC) (GLuint queryHandle); -typedef void (APIENTRYP PFNGLCREATEPERFQUERYINTELPROC) (GLuint queryId, GLuint *queryHandle); -typedef void (APIENTRYP PFNGLDELETEPERFQUERYINTELPROC) (GLuint queryHandle); -typedef void (APIENTRYP PFNGLENDPERFQUERYINTELPROC) (GLuint queryHandle); -typedef void (APIENTRYP PFNGLGETFIRSTPERFQUERYIDINTELPROC) (GLuint *queryId); -typedef void (APIENTRYP PFNGLGETNEXTPERFQUERYIDINTELPROC) (GLuint queryId, GLuint *nextQueryId); -typedef void (APIENTRYP PFNGLGETPERFCOUNTERINFOINTELPROC) (GLuint queryId, GLuint counterId, GLuint counterNameLength, GLchar *counterName, GLuint counterDescLength, GLchar *counterDesc, GLuint *counterOffset, GLuint *counterDataSize, GLuint *counterTypeEnum, GLuint *counterDataTypeEnum, GLuint64 *rawCounterMaxValue); -typedef void (APIENTRYP PFNGLGETPERFQUERYDATAINTELPROC) (GLuint queryHandle, GLuint flags, GLsizei dataSize, GLvoid *data, GLuint *bytesWritten); -typedef void (APIENTRYP PFNGLGETPERFQUERYIDBYNAMEINTELPROC) (GLchar *queryName, GLuint *queryId); -typedef void (APIENTRYP PFNGLGETPERFQUERYINFOINTELPROC) (GLuint queryId, GLuint queryNameLength, GLchar *queryName, GLuint *dataSize, GLuint *noCounters, GLuint *noInstances, GLuint *capsMask); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBeginPerfQueryINTEL (GLuint queryHandle); -GLAPI void APIENTRY glCreatePerfQueryINTEL (GLuint queryId, GLuint *queryHandle); -GLAPI void APIENTRY glDeletePerfQueryINTEL (GLuint queryHandle); -GLAPI void APIENTRY glEndPerfQueryINTEL (GLuint queryHandle); -GLAPI void APIENTRY glGetFirstPerfQueryIdINTEL (GLuint *queryId); -GLAPI void APIENTRY glGetNextPerfQueryIdINTEL (GLuint queryId, GLuint *nextQueryId); -GLAPI void APIENTRY glGetPerfCounterInfoINTEL (GLuint queryId, GLuint counterId, GLuint counterNameLength, GLchar *counterName, GLuint counterDescLength, GLchar *counterDesc, GLuint *counterOffset, GLuint *counterDataSize, GLuint *counterTypeEnum, GLuint *counterDataTypeEnum, GLuint64 *rawCounterMaxValue); -GLAPI void APIENTRY glGetPerfQueryDataINTEL (GLuint queryHandle, GLuint flags, GLsizei dataSize, GLvoid *data, GLuint *bytesWritten); -GLAPI void APIENTRY glGetPerfQueryIdByNameINTEL (GLchar *queryName, GLuint *queryId); -GLAPI void APIENTRY glGetPerfQueryInfoINTEL (GLuint queryId, GLuint queryNameLength, GLchar *queryName, GLuint *dataSize, GLuint *noCounters, GLuint *noInstances, GLuint *capsMask); -#endif -#endif /* GL_INTEL_performance_query */ - -#ifndef GL_MESAX_texture_stack -#define GL_MESAX_texture_stack 1 -#define GL_TEXTURE_1D_STACK_MESAX 0x8759 -#define GL_TEXTURE_2D_STACK_MESAX 0x875A -#define GL_PROXY_TEXTURE_1D_STACK_MESAX 0x875B -#define GL_PROXY_TEXTURE_2D_STACK_MESAX 0x875C -#define GL_TEXTURE_1D_STACK_BINDING_MESAX 0x875D -#define GL_TEXTURE_2D_STACK_BINDING_MESAX 0x875E -#endif /* GL_MESAX_texture_stack */ - -#ifndef GL_MESA_pack_invert -#define GL_MESA_pack_invert 1 -#define GL_PACK_INVERT_MESA 0x8758 -#endif /* GL_MESA_pack_invert */ - -#ifndef GL_MESA_resize_buffers -#define GL_MESA_resize_buffers 1 -typedef void (APIENTRYP PFNGLRESIZEBUFFERSMESAPROC) (void); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glResizeBuffersMESA (void); -#endif -#endif /* GL_MESA_resize_buffers */ - -#ifndef GL_MESA_window_pos -#define GL_MESA_window_pos 1 -typedef void (APIENTRYP PFNGLWINDOWPOS2DMESAPROC) (GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLWINDOWPOS2DVMESAPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLWINDOWPOS2FMESAPROC) (GLfloat x, GLfloat y); -typedef void (APIENTRYP PFNGLWINDOWPOS2FVMESAPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLWINDOWPOS2IMESAPROC) (GLint x, GLint y); -typedef void (APIENTRYP PFNGLWINDOWPOS2IVMESAPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLWINDOWPOS2SMESAPROC) (GLshort x, GLshort y); -typedef void (APIENTRYP PFNGLWINDOWPOS2SVMESAPROC) (const GLshort *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3DMESAPROC) (GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLWINDOWPOS3DVMESAPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3FMESAPROC) (GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLWINDOWPOS3FVMESAPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3IMESAPROC) (GLint x, GLint y, GLint z); -typedef void (APIENTRYP PFNGLWINDOWPOS3IVMESAPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3SMESAPROC) (GLshort x, GLshort y, GLshort z); -typedef void (APIENTRYP PFNGLWINDOWPOS3SVMESAPROC) (const GLshort *v); -typedef void (APIENTRYP PFNGLWINDOWPOS4DMESAPROC) (GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLWINDOWPOS4DVMESAPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLWINDOWPOS4FMESAPROC) (GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLWINDOWPOS4FVMESAPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLWINDOWPOS4IMESAPROC) (GLint x, GLint y, GLint z, GLint w); -typedef void (APIENTRYP PFNGLWINDOWPOS4IVMESAPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLWINDOWPOS4SMESAPROC) (GLshort x, GLshort y, GLshort z, GLshort w); -typedef void (APIENTRYP PFNGLWINDOWPOS4SVMESAPROC) (const GLshort *v); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glWindowPos2dMESA (GLdouble x, GLdouble y); -GLAPI void APIENTRY glWindowPos2dvMESA (const GLdouble *v); -GLAPI void APIENTRY glWindowPos2fMESA (GLfloat x, GLfloat y); -GLAPI void APIENTRY glWindowPos2fvMESA (const GLfloat *v); -GLAPI void APIENTRY glWindowPos2iMESA (GLint x, GLint y); -GLAPI void APIENTRY glWindowPos2ivMESA (const GLint *v); -GLAPI void APIENTRY glWindowPos2sMESA (GLshort x, GLshort y); -GLAPI void APIENTRY glWindowPos2svMESA (const GLshort *v); -GLAPI void APIENTRY glWindowPos3dMESA (GLdouble x, GLdouble y, GLdouble z); -GLAPI void APIENTRY glWindowPos3dvMESA (const GLdouble *v); -GLAPI void APIENTRY glWindowPos3fMESA (GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glWindowPos3fvMESA (const GLfloat *v); -GLAPI void APIENTRY glWindowPos3iMESA (GLint x, GLint y, GLint z); -GLAPI void APIENTRY glWindowPos3ivMESA (const GLint *v); -GLAPI void APIENTRY glWindowPos3sMESA (GLshort x, GLshort y, GLshort z); -GLAPI void APIENTRY glWindowPos3svMESA (const GLshort *v); -GLAPI void APIENTRY glWindowPos4dMESA (GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void APIENTRY glWindowPos4dvMESA (const GLdouble *v); -GLAPI void APIENTRY glWindowPos4fMESA (GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI void APIENTRY glWindowPos4fvMESA (const GLfloat *v); -GLAPI void APIENTRY glWindowPos4iMESA (GLint x, GLint y, GLint z, GLint w); -GLAPI void APIENTRY glWindowPos4ivMESA (const GLint *v); -GLAPI void APIENTRY glWindowPos4sMESA (GLshort x, GLshort y, GLshort z, GLshort w); -GLAPI void APIENTRY glWindowPos4svMESA (const GLshort *v); -#endif -#endif /* GL_MESA_window_pos */ - -#ifndef GL_MESA_ycbcr_texture -#define GL_MESA_ycbcr_texture 1 -#define GL_UNSIGNED_SHORT_8_8_MESA 0x85BA -#define GL_UNSIGNED_SHORT_8_8_REV_MESA 0x85BB -#define GL_YCBCR_MESA 0x8757 -#endif /* GL_MESA_ycbcr_texture */ - -#ifndef GL_NVX_conditional_render -#define GL_NVX_conditional_render 1 -typedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERNVXPROC) (GLuint id); -typedef void (APIENTRYP PFNGLENDCONDITIONALRENDERNVXPROC) (void); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBeginConditionalRenderNVX (GLuint id); -GLAPI void APIENTRY glEndConditionalRenderNVX (void); -#endif -#endif /* GL_NVX_conditional_render */ - -#ifndef GL_NVX_gpu_memory_info -#define GL_NVX_gpu_memory_info 1 -#define GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX 0x9047 -#define GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX 0x9048 -#define GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX 0x9049 -#define GL_GPU_MEMORY_INFO_EVICTION_COUNT_NVX 0x904A -#define GL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX 0x904B -#endif /* GL_NVX_gpu_memory_info */ - -#ifndef GL_NV_bindless_multi_draw_indirect -#define GL_NV_bindless_multi_draw_indirect 1 -typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSNVPROC) (GLenum mode, const void *indirect, GLsizei drawCount, GLsizei stride, GLint vertexBufferCount); -typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSNVPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei drawCount, GLsizei stride, GLint vertexBufferCount); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glMultiDrawArraysIndirectBindlessNV (GLenum mode, const void *indirect, GLsizei drawCount, GLsizei stride, GLint vertexBufferCount); -GLAPI void APIENTRY glMultiDrawElementsIndirectBindlessNV (GLenum mode, GLenum type, const void *indirect, GLsizei drawCount, GLsizei stride, GLint vertexBufferCount); -#endif -#endif /* GL_NV_bindless_multi_draw_indirect */ - -#ifndef GL_NV_bindless_multi_draw_indirect_count -#define GL_NV_bindless_multi_draw_indirect_count 1 -typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSCOUNTNVPROC) (GLenum mode, const void *indirect, GLsizei drawCount, GLsizei maxDrawCount, GLsizei stride, GLint vertexBufferCount); -typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSCOUNTNVPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei drawCount, GLsizei maxDrawCount, GLsizei stride, GLint vertexBufferCount); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glMultiDrawArraysIndirectBindlessCountNV (GLenum mode, const void *indirect, GLsizei drawCount, GLsizei maxDrawCount, GLsizei stride, GLint vertexBufferCount); -GLAPI void APIENTRY glMultiDrawElementsIndirectBindlessCountNV (GLenum mode, GLenum type, const void *indirect, GLsizei drawCount, GLsizei maxDrawCount, GLsizei stride, GLint vertexBufferCount); -#endif -#endif /* GL_NV_bindless_multi_draw_indirect_count */ - -#ifndef GL_NV_bindless_texture -#define GL_NV_bindless_texture 1 -typedef GLuint64 (APIENTRYP PFNGLGETTEXTUREHANDLENVPROC) (GLuint texture); -typedef GLuint64 (APIENTRYP PFNGLGETTEXTURESAMPLERHANDLENVPROC) (GLuint texture, GLuint sampler); -typedef void (APIENTRYP PFNGLMAKETEXTUREHANDLERESIDENTNVPROC) (GLuint64 handle); -typedef void (APIENTRYP PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC) (GLuint64 handle); -typedef GLuint64 (APIENTRYP PFNGLGETIMAGEHANDLENVPROC) (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format); -typedef void (APIENTRYP PFNGLMAKEIMAGEHANDLERESIDENTNVPROC) (GLuint64 handle, GLenum access); -typedef void (APIENTRYP PFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC) (GLuint64 handle); -typedef void (APIENTRYP PFNGLUNIFORMHANDLEUI64NVPROC) (GLint location, GLuint64 value); -typedef void (APIENTRYP PFNGLUNIFORMHANDLEUI64VNVPROC) (GLint location, GLsizei count, const GLuint64 *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64NVPROC) (GLuint program, GLint location, GLuint64 value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64 *values); -typedef GLboolean (APIENTRYP PFNGLISTEXTUREHANDLERESIDENTNVPROC) (GLuint64 handle); -typedef GLboolean (APIENTRYP PFNGLISIMAGEHANDLERESIDENTNVPROC) (GLuint64 handle); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLuint64 APIENTRY glGetTextureHandleNV (GLuint texture); -GLAPI GLuint64 APIENTRY glGetTextureSamplerHandleNV (GLuint texture, GLuint sampler); -GLAPI void APIENTRY glMakeTextureHandleResidentNV (GLuint64 handle); -GLAPI void APIENTRY glMakeTextureHandleNonResidentNV (GLuint64 handle); -GLAPI GLuint64 APIENTRY glGetImageHandleNV (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format); -GLAPI void APIENTRY glMakeImageHandleResidentNV (GLuint64 handle, GLenum access); -GLAPI void APIENTRY glMakeImageHandleNonResidentNV (GLuint64 handle); -GLAPI void APIENTRY glUniformHandleui64NV (GLint location, GLuint64 value); -GLAPI void APIENTRY glUniformHandleui64vNV (GLint location, GLsizei count, const GLuint64 *value); -GLAPI void APIENTRY glProgramUniformHandleui64NV (GLuint program, GLint location, GLuint64 value); -GLAPI void APIENTRY glProgramUniformHandleui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64 *values); -GLAPI GLboolean APIENTRY glIsTextureHandleResidentNV (GLuint64 handle); -GLAPI GLboolean APIENTRY glIsImageHandleResidentNV (GLuint64 handle); -#endif -#endif /* GL_NV_bindless_texture */ - -#ifndef GL_NV_blend_equation_advanced -#define GL_NV_blend_equation_advanced 1 -#define GL_BLEND_OVERLAP_NV 0x9281 -#define GL_BLEND_PREMULTIPLIED_SRC_NV 0x9280 -#define GL_BLUE_NV 0x1905 -#define GL_COLORBURN_NV 0x929A -#define GL_COLORDODGE_NV 0x9299 -#define GL_CONJOINT_NV 0x9284 -#define GL_CONTRAST_NV 0x92A1 -#define GL_DARKEN_NV 0x9297 -#define GL_DIFFERENCE_NV 0x929E -#define GL_DISJOINT_NV 0x9283 -#define GL_DST_ATOP_NV 0x928F -#define GL_DST_IN_NV 0x928B -#define GL_DST_NV 0x9287 -#define GL_DST_OUT_NV 0x928D -#define GL_DST_OVER_NV 0x9289 -#define GL_EXCLUSION_NV 0x92A0 -#define GL_GREEN_NV 0x1904 -#define GL_HARDLIGHT_NV 0x929B -#define GL_HARDMIX_NV 0x92A9 -#define GL_HSL_COLOR_NV 0x92AF -#define GL_HSL_HUE_NV 0x92AD -#define GL_HSL_LUMINOSITY_NV 0x92B0 -#define GL_HSL_SATURATION_NV 0x92AE -#define GL_INVERT_OVG_NV 0x92B4 -#define GL_INVERT_RGB_NV 0x92A3 -#define GL_LIGHTEN_NV 0x9298 -#define GL_LINEARBURN_NV 0x92A5 -#define GL_LINEARDODGE_NV 0x92A4 -#define GL_LINEARLIGHT_NV 0x92A7 -#define GL_MINUS_CLAMPED_NV 0x92B3 -#define GL_MINUS_NV 0x929F -#define GL_MULTIPLY_NV 0x9294 -#define GL_OVERLAY_NV 0x9296 -#define GL_PINLIGHT_NV 0x92A8 -#define GL_PLUS_CLAMPED_ALPHA_NV 0x92B2 -#define GL_PLUS_CLAMPED_NV 0x92B1 -#define GL_PLUS_DARKER_NV 0x9292 -#define GL_PLUS_NV 0x9291 -#define GL_RED_NV 0x1903 -#define GL_SCREEN_NV 0x9295 -#define GL_SOFTLIGHT_NV 0x929C -#define GL_SRC_ATOP_NV 0x928E -#define GL_SRC_IN_NV 0x928A -#define GL_SRC_NV 0x9286 -#define GL_SRC_OUT_NV 0x928C -#define GL_SRC_OVER_NV 0x9288 -#define GL_UNCORRELATED_NV 0x9282 -#define GL_VIVIDLIGHT_NV 0x92A6 -#define GL_XOR_NV 0x1506 -typedef void (APIENTRYP PFNGLBLENDPARAMETERINVPROC) (GLenum pname, GLint value); -typedef void (APIENTRYP PFNGLBLENDBARRIERNVPROC) (void); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendParameteriNV (GLenum pname, GLint value); -GLAPI void APIENTRY glBlendBarrierNV (void); -#endif -#endif /* GL_NV_blend_equation_advanced */ - -#ifndef GL_NV_blend_equation_advanced_coherent -#define GL_NV_blend_equation_advanced_coherent 1 -#define GL_BLEND_ADVANCED_COHERENT_NV 0x9285 -#endif /* GL_NV_blend_equation_advanced_coherent */ - -#ifndef GL_NV_blend_square -#define GL_NV_blend_square 1 -#endif /* GL_NV_blend_square */ - -#ifndef GL_NV_compute_program5 -#define GL_NV_compute_program5 1 -#define GL_COMPUTE_PROGRAM_NV 0x90FB -#define GL_COMPUTE_PROGRAM_PARAMETER_BUFFER_NV 0x90FC -#endif /* GL_NV_compute_program5 */ - -#ifndef GL_NV_conditional_render -#define GL_NV_conditional_render 1 -#define GL_QUERY_WAIT_NV 0x8E13 -#define GL_QUERY_NO_WAIT_NV 0x8E14 -#define GL_QUERY_BY_REGION_WAIT_NV 0x8E15 -#define GL_QUERY_BY_REGION_NO_WAIT_NV 0x8E16 -typedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERNVPROC) (GLuint id, GLenum mode); -typedef void (APIENTRYP PFNGLENDCONDITIONALRENDERNVPROC) (void); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBeginConditionalRenderNV (GLuint id, GLenum mode); -GLAPI void APIENTRY glEndConditionalRenderNV (void); -#endif -#endif /* GL_NV_conditional_render */ - -#ifndef GL_NV_copy_depth_to_color -#define GL_NV_copy_depth_to_color 1 -#define GL_DEPTH_STENCIL_TO_RGBA_NV 0x886E -#define GL_DEPTH_STENCIL_TO_BGRA_NV 0x886F -#endif /* GL_NV_copy_depth_to_color */ - -#ifndef GL_NV_copy_image -#define GL_NV_copy_image 1 -typedef void (APIENTRYP PFNGLCOPYIMAGESUBDATANVPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glCopyImageSubDataNV (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); -#endif -#endif /* GL_NV_copy_image */ - -#ifndef GL_NV_deep_texture3D -#define GL_NV_deep_texture3D 1 -#define GL_MAX_DEEP_3D_TEXTURE_WIDTH_HEIGHT_NV 0x90D0 -#define GL_MAX_DEEP_3D_TEXTURE_DEPTH_NV 0x90D1 -#endif /* GL_NV_deep_texture3D */ - -#ifndef GL_NV_depth_buffer_float -#define GL_NV_depth_buffer_float 1 -#define GL_DEPTH_COMPONENT32F_NV 0x8DAB -#define GL_DEPTH32F_STENCIL8_NV 0x8DAC -#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV_NV 0x8DAD -#define GL_DEPTH_BUFFER_FLOAT_MODE_NV 0x8DAF -typedef void (APIENTRYP PFNGLDEPTHRANGEDNVPROC) (GLdouble zNear, GLdouble zFar); -typedef void (APIENTRYP PFNGLCLEARDEPTHDNVPROC) (GLdouble depth); -typedef void (APIENTRYP PFNGLDEPTHBOUNDSDNVPROC) (GLdouble zmin, GLdouble zmax); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDepthRangedNV (GLdouble zNear, GLdouble zFar); -GLAPI void APIENTRY glClearDepthdNV (GLdouble depth); -GLAPI void APIENTRY glDepthBoundsdNV (GLdouble zmin, GLdouble zmax); -#endif -#endif /* GL_NV_depth_buffer_float */ - -#ifndef GL_NV_depth_clamp -#define GL_NV_depth_clamp 1 -#define GL_DEPTH_CLAMP_NV 0x864F -#endif /* GL_NV_depth_clamp */ - -#ifndef GL_NV_draw_texture -#define GL_NV_draw_texture 1 -typedef void (APIENTRYP PFNGLDRAWTEXTURENVPROC) (GLuint texture, GLuint sampler, GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1, GLfloat z, GLfloat s0, GLfloat t0, GLfloat s1, GLfloat t1); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDrawTextureNV (GLuint texture, GLuint sampler, GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1, GLfloat z, GLfloat s0, GLfloat t0, GLfloat s1, GLfloat t1); -#endif -#endif /* GL_NV_draw_texture */ - -#ifndef GL_NV_evaluators -#define GL_NV_evaluators 1 -#define GL_EVAL_2D_NV 0x86C0 -#define GL_EVAL_TRIANGULAR_2D_NV 0x86C1 -#define GL_MAP_TESSELLATION_NV 0x86C2 -#define GL_MAP_ATTRIB_U_ORDER_NV 0x86C3 -#define GL_MAP_ATTRIB_V_ORDER_NV 0x86C4 -#define GL_EVAL_FRACTIONAL_TESSELLATION_NV 0x86C5 -#define GL_EVAL_VERTEX_ATTRIB0_NV 0x86C6 -#define GL_EVAL_VERTEX_ATTRIB1_NV 0x86C7 -#define GL_EVAL_VERTEX_ATTRIB2_NV 0x86C8 -#define GL_EVAL_VERTEX_ATTRIB3_NV 0x86C9 -#define GL_EVAL_VERTEX_ATTRIB4_NV 0x86CA -#define GL_EVAL_VERTEX_ATTRIB5_NV 0x86CB -#define GL_EVAL_VERTEX_ATTRIB6_NV 0x86CC -#define GL_EVAL_VERTEX_ATTRIB7_NV 0x86CD -#define GL_EVAL_VERTEX_ATTRIB8_NV 0x86CE -#define GL_EVAL_VERTEX_ATTRIB9_NV 0x86CF -#define GL_EVAL_VERTEX_ATTRIB10_NV 0x86D0 -#define GL_EVAL_VERTEX_ATTRIB11_NV 0x86D1 -#define GL_EVAL_VERTEX_ATTRIB12_NV 0x86D2 -#define GL_EVAL_VERTEX_ATTRIB13_NV 0x86D3 -#define GL_EVAL_VERTEX_ATTRIB14_NV 0x86D4 -#define GL_EVAL_VERTEX_ATTRIB15_NV 0x86D5 -#define GL_MAX_MAP_TESSELLATION_NV 0x86D6 -#define GL_MAX_RATIONAL_EVAL_ORDER_NV 0x86D7 -typedef void (APIENTRYP PFNGLMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const void *points); -typedef void (APIENTRYP PFNGLMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLGETMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, void *points); -typedef void (APIENTRYP PFNGLGETMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETMAPATTRIBPARAMETERIVNVPROC) (GLenum target, GLuint index, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETMAPATTRIBPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLEVALMAPSNVPROC) (GLenum target, GLenum mode); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glMapControlPointsNV (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const void *points); -GLAPI void APIENTRY glMapParameterivNV (GLenum target, GLenum pname, const GLint *params); -GLAPI void APIENTRY glMapParameterfvNV (GLenum target, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glGetMapControlPointsNV (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, void *points); -GLAPI void APIENTRY glGetMapParameterivNV (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetMapParameterfvNV (GLenum target, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetMapAttribParameterivNV (GLenum target, GLuint index, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetMapAttribParameterfvNV (GLenum target, GLuint index, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glEvalMapsNV (GLenum target, GLenum mode); -#endif -#endif /* GL_NV_evaluators */ - -#ifndef GL_NV_explicit_multisample -#define GL_NV_explicit_multisample 1 -#define GL_SAMPLE_POSITION_NV 0x8E50 -#define GL_SAMPLE_MASK_NV 0x8E51 -#define GL_SAMPLE_MASK_VALUE_NV 0x8E52 -#define GL_TEXTURE_BINDING_RENDERBUFFER_NV 0x8E53 -#define GL_TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV 0x8E54 -#define GL_TEXTURE_RENDERBUFFER_NV 0x8E55 -#define GL_SAMPLER_RENDERBUFFER_NV 0x8E56 -#define GL_INT_SAMPLER_RENDERBUFFER_NV 0x8E57 -#define GL_UNSIGNED_INT_SAMPLER_RENDERBUFFER_NV 0x8E58 -#define GL_MAX_SAMPLE_MASK_WORDS_NV 0x8E59 -typedef void (APIENTRYP PFNGLGETMULTISAMPLEFVNVPROC) (GLenum pname, GLuint index, GLfloat *val); -typedef void (APIENTRYP PFNGLSAMPLEMASKINDEXEDNVPROC) (GLuint index, GLbitfield mask); -typedef void (APIENTRYP PFNGLTEXRENDERBUFFERNVPROC) (GLenum target, GLuint renderbuffer); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGetMultisamplefvNV (GLenum pname, GLuint index, GLfloat *val); -GLAPI void APIENTRY glSampleMaskIndexedNV (GLuint index, GLbitfield mask); -GLAPI void APIENTRY glTexRenderbufferNV (GLenum target, GLuint renderbuffer); -#endif -#endif /* GL_NV_explicit_multisample */ - -#ifndef GL_NV_fence -#define GL_NV_fence 1 -#define GL_ALL_COMPLETED_NV 0x84F2 -#define GL_FENCE_STATUS_NV 0x84F3 -#define GL_FENCE_CONDITION_NV 0x84F4 -typedef void (APIENTRYP PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint *fences); -typedef void (APIENTRYP PFNGLGENFENCESNVPROC) (GLsizei n, GLuint *fences); -typedef GLboolean (APIENTRYP PFNGLISFENCENVPROC) (GLuint fence); -typedef GLboolean (APIENTRYP PFNGLTESTFENCENVPROC) (GLuint fence); -typedef void (APIENTRYP PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLFINISHFENCENVPROC) (GLuint fence); -typedef void (APIENTRYP PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDeleteFencesNV (GLsizei n, const GLuint *fences); -GLAPI void APIENTRY glGenFencesNV (GLsizei n, GLuint *fences); -GLAPI GLboolean APIENTRY glIsFenceNV (GLuint fence); -GLAPI GLboolean APIENTRY glTestFenceNV (GLuint fence); -GLAPI void APIENTRY glGetFenceivNV (GLuint fence, GLenum pname, GLint *params); -GLAPI void APIENTRY glFinishFenceNV (GLuint fence); -GLAPI void APIENTRY glSetFenceNV (GLuint fence, GLenum condition); -#endif -#endif /* GL_NV_fence */ - -#ifndef GL_NV_float_buffer -#define GL_NV_float_buffer 1 -#define GL_FLOAT_R_NV 0x8880 -#define GL_FLOAT_RG_NV 0x8881 -#define GL_FLOAT_RGB_NV 0x8882 -#define GL_FLOAT_RGBA_NV 0x8883 -#define GL_FLOAT_R16_NV 0x8884 -#define GL_FLOAT_R32_NV 0x8885 -#define GL_FLOAT_RG16_NV 0x8886 -#define GL_FLOAT_RG32_NV 0x8887 -#define GL_FLOAT_RGB16_NV 0x8888 -#define GL_FLOAT_RGB32_NV 0x8889 -#define GL_FLOAT_RGBA16_NV 0x888A -#define GL_FLOAT_RGBA32_NV 0x888B -#define GL_TEXTURE_FLOAT_COMPONENTS_NV 0x888C -#define GL_FLOAT_CLEAR_COLOR_VALUE_NV 0x888D -#define GL_FLOAT_RGBA_MODE_NV 0x888E -#endif /* GL_NV_float_buffer */ - -#ifndef GL_NV_fog_distance -#define GL_NV_fog_distance 1 -#define GL_FOG_DISTANCE_MODE_NV 0x855A -#define GL_EYE_RADIAL_NV 0x855B -#define GL_EYE_PLANE_ABSOLUTE_NV 0x855C -#endif /* GL_NV_fog_distance */ - -#ifndef GL_NV_fragment_program -#define GL_NV_fragment_program 1 -#define GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV 0x8868 -#define GL_FRAGMENT_PROGRAM_NV 0x8870 -#define GL_MAX_TEXTURE_COORDS_NV 0x8871 -#define GL_MAX_TEXTURE_IMAGE_UNITS_NV 0x8872 -#define GL_FRAGMENT_PROGRAM_BINDING_NV 0x8873 -#define GL_PROGRAM_ERROR_STRING_NV 0x8874 -typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4FNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, const GLfloat *v); -typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4DNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, const GLdouble *v); -typedef void (APIENTRYP PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLfloat *params); -typedef void (APIENTRYP PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLdouble *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glProgramNamedParameter4fNV (GLuint id, GLsizei len, const GLubyte *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI void APIENTRY glProgramNamedParameter4fvNV (GLuint id, GLsizei len, const GLubyte *name, const GLfloat *v); -GLAPI void APIENTRY glProgramNamedParameter4dNV (GLuint id, GLsizei len, const GLubyte *name, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void APIENTRY glProgramNamedParameter4dvNV (GLuint id, GLsizei len, const GLubyte *name, const GLdouble *v); -GLAPI void APIENTRY glGetProgramNamedParameterfvNV (GLuint id, GLsizei len, const GLubyte *name, GLfloat *params); -GLAPI void APIENTRY glGetProgramNamedParameterdvNV (GLuint id, GLsizei len, const GLubyte *name, GLdouble *params); -#endif -#endif /* GL_NV_fragment_program */ - -#ifndef GL_NV_fragment_program2 -#define GL_NV_fragment_program2 1 -#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4 -#define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5 -#define GL_MAX_PROGRAM_IF_DEPTH_NV 0x88F6 -#define GL_MAX_PROGRAM_LOOP_DEPTH_NV 0x88F7 -#define GL_MAX_PROGRAM_LOOP_COUNT_NV 0x88F8 -#endif /* GL_NV_fragment_program2 */ - -#ifndef GL_NV_fragment_program4 -#define GL_NV_fragment_program4 1 -#endif /* GL_NV_fragment_program4 */ - -#ifndef GL_NV_fragment_program_option -#define GL_NV_fragment_program_option 1 -#endif /* GL_NV_fragment_program_option */ - -#ifndef GL_NV_framebuffer_multisample_coverage -#define GL_NV_framebuffer_multisample_coverage 1 -#define GL_RENDERBUFFER_COVERAGE_SAMPLES_NV 0x8CAB -#define GL_RENDERBUFFER_COLOR_SAMPLES_NV 0x8E10 -#define GL_MAX_MULTISAMPLE_COVERAGE_MODES_NV 0x8E11 -#define GL_MULTISAMPLE_COVERAGE_MODES_NV 0x8E12 -typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glRenderbufferStorageMultisampleCoverageNV (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); -#endif -#endif /* GL_NV_framebuffer_multisample_coverage */ - -#ifndef GL_NV_geometry_program4 -#define GL_NV_geometry_program4 1 -#define GL_GEOMETRY_PROGRAM_NV 0x8C26 -#define GL_MAX_PROGRAM_OUTPUT_VERTICES_NV 0x8C27 -#define GL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV 0x8C28 -typedef void (APIENTRYP PFNGLPROGRAMVERTEXLIMITNVPROC) (GLenum target, GLint limit); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glProgramVertexLimitNV (GLenum target, GLint limit); -GLAPI void APIENTRY glFramebufferTextureEXT (GLenum target, GLenum attachment, GLuint texture, GLint level); -GLAPI void APIENTRY glFramebufferTextureFaceEXT (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); -#endif -#endif /* GL_NV_geometry_program4 */ - -#ifndef GL_NV_geometry_shader4 -#define GL_NV_geometry_shader4 1 -#endif /* GL_NV_geometry_shader4 */ - -#ifndef GL_NV_gpu_program4 -#define GL_NV_gpu_program4 1 -#define GL_MIN_PROGRAM_TEXEL_OFFSET_NV 0x8904 -#define GL_MAX_PROGRAM_TEXEL_OFFSET_NV 0x8905 -#define GL_PROGRAM_ATTRIB_COMPONENTS_NV 0x8906 -#define GL_PROGRAM_RESULT_COMPONENTS_NV 0x8907 -#define GL_MAX_PROGRAM_ATTRIB_COMPONENTS_NV 0x8908 -#define GL_MAX_PROGRAM_RESULT_COMPONENTS_NV 0x8909 -#define GL_MAX_PROGRAM_GENERIC_ATTRIBS_NV 0x8DA5 -#define GL_MAX_PROGRAM_GENERIC_RESULTS_NV 0x8DA6 -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params); -typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERIIVNVPROC) (GLenum target, GLuint index, GLint *params); -typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERIUIVNVPROC) (GLenum target, GLuint index, GLuint *params); -typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERIIVNVPROC) (GLenum target, GLuint index, GLint *params); -typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERIUIVNVPROC) (GLenum target, GLuint index, GLuint *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glProgramLocalParameterI4iNV (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); -GLAPI void APIENTRY glProgramLocalParameterI4ivNV (GLenum target, GLuint index, const GLint *params); -GLAPI void APIENTRY glProgramLocalParametersI4ivNV (GLenum target, GLuint index, GLsizei count, const GLint *params); -GLAPI void APIENTRY glProgramLocalParameterI4uiNV (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -GLAPI void APIENTRY glProgramLocalParameterI4uivNV (GLenum target, GLuint index, const GLuint *params); -GLAPI void APIENTRY glProgramLocalParametersI4uivNV (GLenum target, GLuint index, GLsizei count, const GLuint *params); -GLAPI void APIENTRY glProgramEnvParameterI4iNV (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); -GLAPI void APIENTRY glProgramEnvParameterI4ivNV (GLenum target, GLuint index, const GLint *params); -GLAPI void APIENTRY glProgramEnvParametersI4ivNV (GLenum target, GLuint index, GLsizei count, const GLint *params); -GLAPI void APIENTRY glProgramEnvParameterI4uiNV (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -GLAPI void APIENTRY glProgramEnvParameterI4uivNV (GLenum target, GLuint index, const GLuint *params); -GLAPI void APIENTRY glProgramEnvParametersI4uivNV (GLenum target, GLuint index, GLsizei count, const GLuint *params); -GLAPI void APIENTRY glGetProgramLocalParameterIivNV (GLenum target, GLuint index, GLint *params); -GLAPI void APIENTRY glGetProgramLocalParameterIuivNV (GLenum target, GLuint index, GLuint *params); -GLAPI void APIENTRY glGetProgramEnvParameterIivNV (GLenum target, GLuint index, GLint *params); -GLAPI void APIENTRY glGetProgramEnvParameterIuivNV (GLenum target, GLuint index, GLuint *params); -#endif -#endif /* GL_NV_gpu_program4 */ - -#ifndef GL_NV_gpu_program5 -#define GL_NV_gpu_program5 1 -#define GL_MAX_GEOMETRY_PROGRAM_INVOCATIONS_NV 0x8E5A -#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_NV 0x8E5B -#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_NV 0x8E5C -#define GL_FRAGMENT_PROGRAM_INTERPOLATION_OFFSET_BITS_NV 0x8E5D -#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_NV 0x8E5E -#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_NV 0x8E5F -#define GL_MAX_PROGRAM_SUBROUTINE_PARAMETERS_NV 0x8F44 -#define GL_MAX_PROGRAM_SUBROUTINE_NUM_NV 0x8F45 -typedef void (APIENTRYP PFNGLPROGRAMSUBROUTINEPARAMETERSUIVNVPROC) (GLenum target, GLsizei count, const GLuint *params); -typedef void (APIENTRYP PFNGLGETPROGRAMSUBROUTINEPARAMETERUIVNVPROC) (GLenum target, GLuint index, GLuint *param); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glProgramSubroutineParametersuivNV (GLenum target, GLsizei count, const GLuint *params); -GLAPI void APIENTRY glGetProgramSubroutineParameteruivNV (GLenum target, GLuint index, GLuint *param); -#endif -#endif /* GL_NV_gpu_program5 */ - -#ifndef GL_NV_gpu_program5_mem_extended -#define GL_NV_gpu_program5_mem_extended 1 -#endif /* GL_NV_gpu_program5_mem_extended */ - -#ifndef GL_NV_gpu_shader5 -#define GL_NV_gpu_shader5 1 -#endif /* GL_NV_gpu_shader5 */ - -#ifndef GL_NV_half_float -#define GL_NV_half_float 1 -typedef unsigned short GLhalfNV; -#define GL_HALF_FLOAT_NV 0x140B -typedef void (APIENTRYP PFNGLVERTEX2HNVPROC) (GLhalfNV x, GLhalfNV y); -typedef void (APIENTRYP PFNGLVERTEX2HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEX3HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z); -typedef void (APIENTRYP PFNGLVERTEX3HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEX4HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); -typedef void (APIENTRYP PFNGLVERTEX4HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLNORMAL3HNVPROC) (GLhalfNV nx, GLhalfNV ny, GLhalfNV nz); -typedef void (APIENTRYP PFNGLNORMAL3HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue); -typedef void (APIENTRYP PFNGLCOLOR3HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLCOLOR4HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue, GLhalfNV alpha); -typedef void (APIENTRYP PFNGLCOLOR4HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLTEXCOORD1HNVPROC) (GLhalfNV s); -typedef void (APIENTRYP PFNGLTEXCOORD1HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLTEXCOORD2HNVPROC) (GLhalfNV s, GLhalfNV t); -typedef void (APIENTRYP PFNGLTEXCOORD2HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLTEXCOORD3HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r); -typedef void (APIENTRYP PFNGLTEXCOORD3HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLTEXCOORD4HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); -typedef void (APIENTRYP PFNGLTEXCOORD4HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1HNVPROC) (GLenum target, GLhalfNV s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1HVNVPROC) (GLenum target, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2HVNVPROC) (GLenum target, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3HVNVPROC) (GLenum target, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4HVNVPROC) (GLenum target, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLFOGCOORDHNVPROC) (GLhalfNV fog); -typedef void (APIENTRYP PFNGLFOGCOORDHVNVPROC) (const GLhalfNV *fog); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEXWEIGHTHNVPROC) (GLhalfNV weight); -typedef void (APIENTRYP PFNGLVERTEXWEIGHTHVNVPROC) (const GLhalfNV *weight); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1HNVPROC) (GLuint index, GLhalfNV x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1HVNVPROC) (GLuint index, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2HVNVPROC) (GLuint index, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3HVNVPROC) (GLuint index, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4HVNVPROC) (GLuint index, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS1HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS2HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS3HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS4HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertex2hNV (GLhalfNV x, GLhalfNV y); -GLAPI void APIENTRY glVertex2hvNV (const GLhalfNV *v); -GLAPI void APIENTRY glVertex3hNV (GLhalfNV x, GLhalfNV y, GLhalfNV z); -GLAPI void APIENTRY glVertex3hvNV (const GLhalfNV *v); -GLAPI void APIENTRY glVertex4hNV (GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); -GLAPI void APIENTRY glVertex4hvNV (const GLhalfNV *v); -GLAPI void APIENTRY glNormal3hNV (GLhalfNV nx, GLhalfNV ny, GLhalfNV nz); -GLAPI void APIENTRY glNormal3hvNV (const GLhalfNV *v); -GLAPI void APIENTRY glColor3hNV (GLhalfNV red, GLhalfNV green, GLhalfNV blue); -GLAPI void APIENTRY glColor3hvNV (const GLhalfNV *v); -GLAPI void APIENTRY glColor4hNV (GLhalfNV red, GLhalfNV green, GLhalfNV blue, GLhalfNV alpha); -GLAPI void APIENTRY glColor4hvNV (const GLhalfNV *v); -GLAPI void APIENTRY glTexCoord1hNV (GLhalfNV s); -GLAPI void APIENTRY glTexCoord1hvNV (const GLhalfNV *v); -GLAPI void APIENTRY glTexCoord2hNV (GLhalfNV s, GLhalfNV t); -GLAPI void APIENTRY glTexCoord2hvNV (const GLhalfNV *v); -GLAPI void APIENTRY glTexCoord3hNV (GLhalfNV s, GLhalfNV t, GLhalfNV r); -GLAPI void APIENTRY glTexCoord3hvNV (const GLhalfNV *v); -GLAPI void APIENTRY glTexCoord4hNV (GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); -GLAPI void APIENTRY glTexCoord4hvNV (const GLhalfNV *v); -GLAPI void APIENTRY glMultiTexCoord1hNV (GLenum target, GLhalfNV s); -GLAPI void APIENTRY glMultiTexCoord1hvNV (GLenum target, const GLhalfNV *v); -GLAPI void APIENTRY glMultiTexCoord2hNV (GLenum target, GLhalfNV s, GLhalfNV t); -GLAPI void APIENTRY glMultiTexCoord2hvNV (GLenum target, const GLhalfNV *v); -GLAPI void APIENTRY glMultiTexCoord3hNV (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r); -GLAPI void APIENTRY glMultiTexCoord3hvNV (GLenum target, const GLhalfNV *v); -GLAPI void APIENTRY glMultiTexCoord4hNV (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); -GLAPI void APIENTRY glMultiTexCoord4hvNV (GLenum target, const GLhalfNV *v); -GLAPI void APIENTRY glFogCoordhNV (GLhalfNV fog); -GLAPI void APIENTRY glFogCoordhvNV (const GLhalfNV *fog); -GLAPI void APIENTRY glSecondaryColor3hNV (GLhalfNV red, GLhalfNV green, GLhalfNV blue); -GLAPI void APIENTRY glSecondaryColor3hvNV (const GLhalfNV *v); -GLAPI void APIENTRY glVertexWeighthNV (GLhalfNV weight); -GLAPI void APIENTRY glVertexWeighthvNV (const GLhalfNV *weight); -GLAPI void APIENTRY glVertexAttrib1hNV (GLuint index, GLhalfNV x); -GLAPI void APIENTRY glVertexAttrib1hvNV (GLuint index, const GLhalfNV *v); -GLAPI void APIENTRY glVertexAttrib2hNV (GLuint index, GLhalfNV x, GLhalfNV y); -GLAPI void APIENTRY glVertexAttrib2hvNV (GLuint index, const GLhalfNV *v); -GLAPI void APIENTRY glVertexAttrib3hNV (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z); -GLAPI void APIENTRY glVertexAttrib3hvNV (GLuint index, const GLhalfNV *v); -GLAPI void APIENTRY glVertexAttrib4hNV (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); -GLAPI void APIENTRY glVertexAttrib4hvNV (GLuint index, const GLhalfNV *v); -GLAPI void APIENTRY glVertexAttribs1hvNV (GLuint index, GLsizei n, const GLhalfNV *v); -GLAPI void APIENTRY glVertexAttribs2hvNV (GLuint index, GLsizei n, const GLhalfNV *v); -GLAPI void APIENTRY glVertexAttribs3hvNV (GLuint index, GLsizei n, const GLhalfNV *v); -GLAPI void APIENTRY glVertexAttribs4hvNV (GLuint index, GLsizei n, const GLhalfNV *v); -#endif -#endif /* GL_NV_half_float */ - -#ifndef GL_NV_light_max_exponent -#define GL_NV_light_max_exponent 1 -#define GL_MAX_SHININESS_NV 0x8504 -#define GL_MAX_SPOT_EXPONENT_NV 0x8505 -#endif /* GL_NV_light_max_exponent */ - -#ifndef GL_NV_multisample_coverage -#define GL_NV_multisample_coverage 1 -#define GL_COLOR_SAMPLES_NV 0x8E20 -#endif /* GL_NV_multisample_coverage */ - -#ifndef GL_NV_multisample_filter_hint -#define GL_NV_multisample_filter_hint 1 -#define GL_MULTISAMPLE_FILTER_HINT_NV 0x8534 -#endif /* GL_NV_multisample_filter_hint */ - -#ifndef GL_NV_occlusion_query -#define GL_NV_occlusion_query 1 -#define GL_PIXEL_COUNTER_BITS_NV 0x8864 -#define GL_CURRENT_OCCLUSION_QUERY_ID_NV 0x8865 -#define GL_PIXEL_COUNT_NV 0x8866 -#define GL_PIXEL_COUNT_AVAILABLE_NV 0x8867 -typedef void (APIENTRYP PFNGLGENOCCLUSIONQUERIESNVPROC) (GLsizei n, GLuint *ids); -typedef void (APIENTRYP PFNGLDELETEOCCLUSIONQUERIESNVPROC) (GLsizei n, const GLuint *ids); -typedef GLboolean (APIENTRYP PFNGLISOCCLUSIONQUERYNVPROC) (GLuint id); -typedef void (APIENTRYP PFNGLBEGINOCCLUSIONQUERYNVPROC) (GLuint id); -typedef void (APIENTRYP PFNGLENDOCCLUSIONQUERYNVPROC) (void); -typedef void (APIENTRYP PFNGLGETOCCLUSIONQUERYIVNVPROC) (GLuint id, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETOCCLUSIONQUERYUIVNVPROC) (GLuint id, GLenum pname, GLuint *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGenOcclusionQueriesNV (GLsizei n, GLuint *ids); -GLAPI void APIENTRY glDeleteOcclusionQueriesNV (GLsizei n, const GLuint *ids); -GLAPI GLboolean APIENTRY glIsOcclusionQueryNV (GLuint id); -GLAPI void APIENTRY glBeginOcclusionQueryNV (GLuint id); -GLAPI void APIENTRY glEndOcclusionQueryNV (void); -GLAPI void APIENTRY glGetOcclusionQueryivNV (GLuint id, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetOcclusionQueryuivNV (GLuint id, GLenum pname, GLuint *params); -#endif -#endif /* GL_NV_occlusion_query */ - -#ifndef GL_NV_packed_depth_stencil -#define GL_NV_packed_depth_stencil 1 -#define GL_DEPTH_STENCIL_NV 0x84F9 -#define GL_UNSIGNED_INT_24_8_NV 0x84FA -#endif /* GL_NV_packed_depth_stencil */ - -#ifndef GL_NV_parameter_buffer_object -#define GL_NV_parameter_buffer_object 1 -#define GL_MAX_PROGRAM_PARAMETER_BUFFER_BINDINGS_NV 0x8DA0 -#define GL_MAX_PROGRAM_PARAMETER_BUFFER_SIZE_NV 0x8DA1 -#define GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV 0x8DA2 -#define GL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV 0x8DA3 -#define GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV 0x8DA4 -typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC) (GLenum target, GLuint bindingIndex, GLuint wordIndex, GLsizei count, const GLfloat *params); -typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC) (GLenum target, GLuint bindingIndex, GLuint wordIndex, GLsizei count, const GLint *params); -typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC) (GLenum target, GLuint bindingIndex, GLuint wordIndex, GLsizei count, const GLuint *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glProgramBufferParametersfvNV (GLenum target, GLuint bindingIndex, GLuint wordIndex, GLsizei count, const GLfloat *params); -GLAPI void APIENTRY glProgramBufferParametersIivNV (GLenum target, GLuint bindingIndex, GLuint wordIndex, GLsizei count, const GLint *params); -GLAPI void APIENTRY glProgramBufferParametersIuivNV (GLenum target, GLuint bindingIndex, GLuint wordIndex, GLsizei count, const GLuint *params); -#endif -#endif /* GL_NV_parameter_buffer_object */ - -#ifndef GL_NV_parameter_buffer_object2 -#define GL_NV_parameter_buffer_object2 1 -#endif /* GL_NV_parameter_buffer_object2 */ - -#ifndef GL_NV_path_rendering -#define GL_NV_path_rendering 1 -#define GL_PATH_FORMAT_SVG_NV 0x9070 -#define GL_PATH_FORMAT_PS_NV 0x9071 -#define GL_STANDARD_FONT_NAME_NV 0x9072 -#define GL_SYSTEM_FONT_NAME_NV 0x9073 -#define GL_FILE_NAME_NV 0x9074 -#define GL_PATH_STROKE_WIDTH_NV 0x9075 -#define GL_PATH_END_CAPS_NV 0x9076 -#define GL_PATH_INITIAL_END_CAP_NV 0x9077 -#define GL_PATH_TERMINAL_END_CAP_NV 0x9078 -#define GL_PATH_JOIN_STYLE_NV 0x9079 -#define GL_PATH_MITER_LIMIT_NV 0x907A -#define GL_PATH_DASH_CAPS_NV 0x907B -#define GL_PATH_INITIAL_DASH_CAP_NV 0x907C -#define GL_PATH_TERMINAL_DASH_CAP_NV 0x907D -#define GL_PATH_DASH_OFFSET_NV 0x907E -#define GL_PATH_CLIENT_LENGTH_NV 0x907F -#define GL_PATH_FILL_MODE_NV 0x9080 -#define GL_PATH_FILL_MASK_NV 0x9081 -#define GL_PATH_FILL_COVER_MODE_NV 0x9082 -#define GL_PATH_STROKE_COVER_MODE_NV 0x9083 -#define GL_PATH_STROKE_MASK_NV 0x9084 -#define GL_COUNT_UP_NV 0x9088 -#define GL_COUNT_DOWN_NV 0x9089 -#define GL_PATH_OBJECT_BOUNDING_BOX_NV 0x908A -#define GL_CONVEX_HULL_NV 0x908B -#define GL_BOUNDING_BOX_NV 0x908D -#define GL_TRANSLATE_X_NV 0x908E -#define GL_TRANSLATE_Y_NV 0x908F -#define GL_TRANSLATE_2D_NV 0x9090 -#define GL_TRANSLATE_3D_NV 0x9091 -#define GL_AFFINE_2D_NV 0x9092 -#define GL_AFFINE_3D_NV 0x9094 -#define GL_TRANSPOSE_AFFINE_2D_NV 0x9096 -#define GL_TRANSPOSE_AFFINE_3D_NV 0x9098 -#define GL_UTF8_NV 0x909A -#define GL_UTF16_NV 0x909B -#define GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV 0x909C -#define GL_PATH_COMMAND_COUNT_NV 0x909D -#define GL_PATH_COORD_COUNT_NV 0x909E -#define GL_PATH_DASH_ARRAY_COUNT_NV 0x909F -#define GL_PATH_COMPUTED_LENGTH_NV 0x90A0 -#define GL_PATH_FILL_BOUNDING_BOX_NV 0x90A1 -#define GL_PATH_STROKE_BOUNDING_BOX_NV 0x90A2 -#define GL_SQUARE_NV 0x90A3 -#define GL_ROUND_NV 0x90A4 -#define GL_TRIANGULAR_NV 0x90A5 -#define GL_BEVEL_NV 0x90A6 -#define GL_MITER_REVERT_NV 0x90A7 -#define GL_MITER_TRUNCATE_NV 0x90A8 -#define GL_SKIP_MISSING_GLYPH_NV 0x90A9 -#define GL_USE_MISSING_GLYPH_NV 0x90AA -#define GL_PATH_ERROR_POSITION_NV 0x90AB -#define GL_PATH_FOG_GEN_MODE_NV 0x90AC -#define GL_ACCUM_ADJACENT_PAIRS_NV 0x90AD -#define GL_ADJACENT_PAIRS_NV 0x90AE -#define GL_FIRST_TO_REST_NV 0x90AF -#define GL_PATH_GEN_MODE_NV 0x90B0 -#define GL_PATH_GEN_COEFF_NV 0x90B1 -#define GL_PATH_GEN_COLOR_FORMAT_NV 0x90B2 -#define GL_PATH_GEN_COMPONENTS_NV 0x90B3 -#define GL_PATH_STENCIL_FUNC_NV 0x90B7 -#define GL_PATH_STENCIL_REF_NV 0x90B8 -#define GL_PATH_STENCIL_VALUE_MASK_NV 0x90B9 -#define GL_PATH_STENCIL_DEPTH_OFFSET_FACTOR_NV 0x90BD -#define GL_PATH_STENCIL_DEPTH_OFFSET_UNITS_NV 0x90BE -#define GL_PATH_COVER_DEPTH_FUNC_NV 0x90BF -#define GL_PATH_DASH_OFFSET_RESET_NV 0x90B4 -#define GL_MOVE_TO_RESETS_NV 0x90B5 -#define GL_MOVE_TO_CONTINUES_NV 0x90B6 -#define GL_CLOSE_PATH_NV 0x00 -#define GL_MOVE_TO_NV 0x02 -#define GL_RELATIVE_MOVE_TO_NV 0x03 -#define GL_LINE_TO_NV 0x04 -#define GL_RELATIVE_LINE_TO_NV 0x05 -#define GL_HORIZONTAL_LINE_TO_NV 0x06 -#define GL_RELATIVE_HORIZONTAL_LINE_TO_NV 0x07 -#define GL_VERTICAL_LINE_TO_NV 0x08 -#define GL_RELATIVE_VERTICAL_LINE_TO_NV 0x09 -#define GL_QUADRATIC_CURVE_TO_NV 0x0A -#define GL_RELATIVE_QUADRATIC_CURVE_TO_NV 0x0B -#define GL_CUBIC_CURVE_TO_NV 0x0C -#define GL_RELATIVE_CUBIC_CURVE_TO_NV 0x0D -#define GL_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0E -#define GL_RELATIVE_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0F -#define GL_SMOOTH_CUBIC_CURVE_TO_NV 0x10 -#define GL_RELATIVE_SMOOTH_CUBIC_CURVE_TO_NV 0x11 -#define GL_SMALL_CCW_ARC_TO_NV 0x12 -#define GL_RELATIVE_SMALL_CCW_ARC_TO_NV 0x13 -#define GL_SMALL_CW_ARC_TO_NV 0x14 -#define GL_RELATIVE_SMALL_CW_ARC_TO_NV 0x15 -#define GL_LARGE_CCW_ARC_TO_NV 0x16 -#define GL_RELATIVE_LARGE_CCW_ARC_TO_NV 0x17 -#define GL_LARGE_CW_ARC_TO_NV 0x18 -#define GL_RELATIVE_LARGE_CW_ARC_TO_NV 0x19 -#define GL_RESTART_PATH_NV 0xF0 -#define GL_DUP_FIRST_CUBIC_CURVE_TO_NV 0xF2 -#define GL_DUP_LAST_CUBIC_CURVE_TO_NV 0xF4 -#define GL_RECT_NV 0xF6 -#define GL_CIRCULAR_CCW_ARC_TO_NV 0xF8 -#define GL_CIRCULAR_CW_ARC_TO_NV 0xFA -#define GL_CIRCULAR_TANGENT_ARC_TO_NV 0xFC -#define GL_ARC_TO_NV 0xFE -#define GL_RELATIVE_ARC_TO_NV 0xFF -#define GL_BOLD_BIT_NV 0x01 -#define GL_ITALIC_BIT_NV 0x02 -#define GL_GLYPH_WIDTH_BIT_NV 0x01 -#define GL_GLYPH_HEIGHT_BIT_NV 0x02 -#define GL_GLYPH_HORIZONTAL_BEARING_X_BIT_NV 0x04 -#define GL_GLYPH_HORIZONTAL_BEARING_Y_BIT_NV 0x08 -#define GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV 0x10 -#define GL_GLYPH_VERTICAL_BEARING_X_BIT_NV 0x20 -#define GL_GLYPH_VERTICAL_BEARING_Y_BIT_NV 0x40 -#define GL_GLYPH_VERTICAL_BEARING_ADVANCE_BIT_NV 0x80 -#define GL_GLYPH_HAS_KERNING_BIT_NV 0x100 -#define GL_FONT_X_MIN_BOUNDS_BIT_NV 0x00010000 -#define GL_FONT_Y_MIN_BOUNDS_BIT_NV 0x00020000 -#define GL_FONT_X_MAX_BOUNDS_BIT_NV 0x00040000 -#define GL_FONT_Y_MAX_BOUNDS_BIT_NV 0x00080000 -#define GL_FONT_UNITS_PER_EM_BIT_NV 0x00100000 -#define GL_FONT_ASCENDER_BIT_NV 0x00200000 -#define GL_FONT_DESCENDER_BIT_NV 0x00400000 -#define GL_FONT_HEIGHT_BIT_NV 0x00800000 -#define GL_FONT_MAX_ADVANCE_WIDTH_BIT_NV 0x01000000 -#define GL_FONT_MAX_ADVANCE_HEIGHT_BIT_NV 0x02000000 -#define GL_FONT_UNDERLINE_POSITION_BIT_NV 0x04000000 -#define GL_FONT_UNDERLINE_THICKNESS_BIT_NV 0x08000000 -#define GL_FONT_HAS_KERNING_BIT_NV 0x10000000 -#define GL_PRIMARY_COLOR_NV 0x852C -#define GL_SECONDARY_COLOR_NV 0x852D -#define GL_ROUNDED_RECT_NV 0xE8 -#define GL_RELATIVE_ROUNDED_RECT_NV 0xE9 -#define GL_ROUNDED_RECT2_NV 0xEA -#define GL_RELATIVE_ROUNDED_RECT2_NV 0xEB -#define GL_ROUNDED_RECT4_NV 0xEC -#define GL_RELATIVE_ROUNDED_RECT4_NV 0xED -#define GL_ROUNDED_RECT8_NV 0xEE -#define GL_RELATIVE_ROUNDED_RECT8_NV 0xEF -#define GL_RELATIVE_RECT_NV 0xF7 -#define GL_FONT_GLYPHS_AVAILABLE_NV 0x9368 -#define GL_FONT_TARGET_UNAVAILABLE_NV 0x9369 -#define GL_FONT_UNAVAILABLE_NV 0x936A -#define GL_FONT_UNINTELLIGIBLE_NV 0x936B -#define GL_CONIC_CURVE_TO_NV 0x1A -#define GL_RELATIVE_CONIC_CURVE_TO_NV 0x1B -#define GL_FONT_NUM_GLYPH_INDICES_BIT_NV 0x20000000 -#define GL_STANDARD_FONT_FORMAT_NV 0x936C -#define GL_2_BYTES_NV 0x1407 -#define GL_3_BYTES_NV 0x1408 -#define GL_4_BYTES_NV 0x1409 -#define GL_EYE_LINEAR_NV 0x2400 -#define GL_OBJECT_LINEAR_NV 0x2401 -#define GL_CONSTANT_NV 0x8576 -#define GL_PATH_PROJECTION_NV 0x1701 -#define GL_PATH_MODELVIEW_NV 0x1700 -#define GL_PATH_MODELVIEW_STACK_DEPTH_NV 0x0BA3 -#define GL_PATH_MODELVIEW_MATRIX_NV 0x0BA6 -#define GL_PATH_MAX_MODELVIEW_STACK_DEPTH_NV 0x0D36 -#define GL_PATH_TRANSPOSE_MODELVIEW_MATRIX_NV 0x84E3 -#define GL_PATH_PROJECTION_STACK_DEPTH_NV 0x0BA4 -#define GL_PATH_PROJECTION_MATRIX_NV 0x0BA7 -#define GL_PATH_MAX_PROJECTION_STACK_DEPTH_NV 0x0D38 -#define GL_PATH_TRANSPOSE_PROJECTION_MATRIX_NV 0x84E4 -#define GL_FRAGMENT_INPUT_NV 0x936D -typedef GLuint (APIENTRYP PFNGLGENPATHSNVPROC) (GLsizei range); -typedef void (APIENTRYP PFNGLDELETEPATHSNVPROC) (GLuint path, GLsizei range); -typedef GLboolean (APIENTRYP PFNGLISPATHNVPROC) (GLuint path); -typedef void (APIENTRYP PFNGLPATHCOMMANDSNVPROC) (GLuint path, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords); -typedef void (APIENTRYP PFNGLPATHCOORDSNVPROC) (GLuint path, GLsizei numCoords, GLenum coordType, const void *coords); -typedef void (APIENTRYP PFNGLPATHSUBCOMMANDSNVPROC) (GLuint path, GLsizei commandStart, GLsizei commandsToDelete, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords); -typedef void (APIENTRYP PFNGLPATHSUBCOORDSNVPROC) (GLuint path, GLsizei coordStart, GLsizei numCoords, GLenum coordType, const void *coords); -typedef void (APIENTRYP PFNGLPATHSTRINGNVPROC) (GLuint path, GLenum format, GLsizei length, const void *pathString); -typedef void (APIENTRYP PFNGLPATHGLYPHSNVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLsizei numGlyphs, GLenum type, const void *charcodes, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale); -typedef void (APIENTRYP PFNGLPATHGLYPHRANGENVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyph, GLsizei numGlyphs, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale); -typedef void (APIENTRYP PFNGLWEIGHTPATHSNVPROC) (GLuint resultPath, GLsizei numPaths, const GLuint *paths, const GLfloat *weights); -typedef void (APIENTRYP PFNGLCOPYPATHNVPROC) (GLuint resultPath, GLuint srcPath); -typedef void (APIENTRYP PFNGLINTERPOLATEPATHSNVPROC) (GLuint resultPath, GLuint pathA, GLuint pathB, GLfloat weight); -typedef void (APIENTRYP PFNGLTRANSFORMPATHNVPROC) (GLuint resultPath, GLuint srcPath, GLenum transformType, const GLfloat *transformValues); -typedef void (APIENTRYP PFNGLPATHPARAMETERIVNVPROC) (GLuint path, GLenum pname, const GLint *value); -typedef void (APIENTRYP PFNGLPATHPARAMETERINVPROC) (GLuint path, GLenum pname, GLint value); -typedef void (APIENTRYP PFNGLPATHPARAMETERFVNVPROC) (GLuint path, GLenum pname, const GLfloat *value); -typedef void (APIENTRYP PFNGLPATHPARAMETERFNVPROC) (GLuint path, GLenum pname, GLfloat value); -typedef void (APIENTRYP PFNGLPATHDASHARRAYNVPROC) (GLuint path, GLsizei dashCount, const GLfloat *dashArray); -typedef void (APIENTRYP PFNGLPATHSTENCILFUNCNVPROC) (GLenum func, GLint ref, GLuint mask); -typedef void (APIENTRYP PFNGLPATHSTENCILDEPTHOFFSETNVPROC) (GLfloat factor, GLfloat units); -typedef void (APIENTRYP PFNGLSTENCILFILLPATHNVPROC) (GLuint path, GLenum fillMode, GLuint mask); -typedef void (APIENTRYP PFNGLSTENCILSTROKEPATHNVPROC) (GLuint path, GLint reference, GLuint mask); -typedef void (APIENTRYP PFNGLSTENCILFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum transformType, const GLfloat *transformValues); -typedef void (APIENTRYP PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum transformType, const GLfloat *transformValues); -typedef void (APIENTRYP PFNGLPATHCOVERDEPTHFUNCNVPROC) (GLenum func); -typedef void (APIENTRYP PFNGLPATHCOLORGENNVPROC) (GLenum color, GLenum genMode, GLenum colorFormat, const GLfloat *coeffs); -typedef void (APIENTRYP PFNGLPATHTEXGENNVPROC) (GLenum texCoordSet, GLenum genMode, GLint components, const GLfloat *coeffs); -typedef void (APIENTRYP PFNGLPATHFOGGENNVPROC) (GLenum genMode); -typedef void (APIENTRYP PFNGLCOVERFILLPATHNVPROC) (GLuint path, GLenum coverMode); -typedef void (APIENTRYP PFNGLCOVERSTROKEPATHNVPROC) (GLuint path, GLenum coverMode); -typedef void (APIENTRYP PFNGLCOVERFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); -typedef void (APIENTRYP PFNGLCOVERSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); -typedef void (APIENTRYP PFNGLGETPATHPARAMETERIVNVPROC) (GLuint path, GLenum pname, GLint *value); -typedef void (APIENTRYP PFNGLGETPATHPARAMETERFVNVPROC) (GLuint path, GLenum pname, GLfloat *value); -typedef void (APIENTRYP PFNGLGETPATHCOMMANDSNVPROC) (GLuint path, GLubyte *commands); -typedef void (APIENTRYP PFNGLGETPATHCOORDSNVPROC) (GLuint path, GLfloat *coords); -typedef void (APIENTRYP PFNGLGETPATHDASHARRAYNVPROC) (GLuint path, GLfloat *dashArray); -typedef void (APIENTRYP PFNGLGETPATHMETRICSNVPROC) (GLbitfield metricQueryMask, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLsizei stride, GLfloat *metrics); -typedef void (APIENTRYP PFNGLGETPATHMETRICRANGENVPROC) (GLbitfield metricQueryMask, GLuint firstPathName, GLsizei numPaths, GLsizei stride, GLfloat *metrics); -typedef void (APIENTRYP PFNGLGETPATHSPACINGNVPROC) (GLenum pathListMode, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, GLfloat *returnedSpacing); -typedef void (APIENTRYP PFNGLGETPATHCOLORGENIVNVPROC) (GLenum color, GLenum pname, GLint *value); -typedef void (APIENTRYP PFNGLGETPATHCOLORGENFVNVPROC) (GLenum color, GLenum pname, GLfloat *value); -typedef void (APIENTRYP PFNGLGETPATHTEXGENIVNVPROC) (GLenum texCoordSet, GLenum pname, GLint *value); -typedef void (APIENTRYP PFNGLGETPATHTEXGENFVNVPROC) (GLenum texCoordSet, GLenum pname, GLfloat *value); -typedef GLboolean (APIENTRYP PFNGLISPOINTINFILLPATHNVPROC) (GLuint path, GLuint mask, GLfloat x, GLfloat y); -typedef GLboolean (APIENTRYP PFNGLISPOINTINSTROKEPATHNVPROC) (GLuint path, GLfloat x, GLfloat y); -typedef GLfloat (APIENTRYP PFNGLGETPATHLENGTHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments); -typedef GLboolean (APIENTRYP PFNGLPOINTALONGPATHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments, GLfloat distance, GLfloat *x, GLfloat *y, GLfloat *tangentX, GLfloat *tangentY); -typedef void (APIENTRYP PFNGLMATRIXLOAD3X2FNVPROC) (GLenum matrixMode, const GLfloat *m); -typedef void (APIENTRYP PFNGLMATRIXLOAD3X3FNVPROC) (GLenum matrixMode, const GLfloat *m); -typedef void (APIENTRYP PFNGLMATRIXLOADTRANSPOSE3X3FNVPROC) (GLenum matrixMode, const GLfloat *m); -typedef void (APIENTRYP PFNGLMATRIXMULT3X2FNVPROC) (GLenum matrixMode, const GLfloat *m); -typedef void (APIENTRYP PFNGLMATRIXMULT3X3FNVPROC) (GLenum matrixMode, const GLfloat *m); -typedef void (APIENTRYP PFNGLMATRIXMULTTRANSPOSE3X3FNVPROC) (GLenum matrixMode, const GLfloat *m); -typedef void (APIENTRYP PFNGLSTENCILTHENCOVERFILLPATHNVPROC) (GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode); -typedef void (APIENTRYP PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC) (GLuint path, GLint reference, GLuint mask, GLenum coverMode); -typedef void (APIENTRYP PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); -typedef void (APIENTRYP PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); -typedef GLenum (APIENTRYP PFNGLPATHGLYPHINDEXRANGENVPROC) (GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint pathParameterTemplate, GLfloat emScale, GLuint baseAndCount[2]); -typedef GLenum (APIENTRYP PFNGLPATHGLYPHINDEXARRAYNVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale); -typedef GLenum (APIENTRYP PFNGLPATHMEMORYGLYPHINDEXARRAYNVPROC) (GLuint firstPathName, GLenum fontTarget, GLsizeiptr fontSize, const void *fontData, GLsizei faceIndex, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale); -typedef void (APIENTRYP PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC) (GLuint program, GLint location, GLenum genMode, GLint components, const GLfloat *coeffs); -typedef void (APIENTRYP PFNGLGETPROGRAMRESOURCEFVNVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLfloat *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLuint APIENTRY glGenPathsNV (GLsizei range); -GLAPI void APIENTRY glDeletePathsNV (GLuint path, GLsizei range); -GLAPI GLboolean APIENTRY glIsPathNV (GLuint path); -GLAPI void APIENTRY glPathCommandsNV (GLuint path, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords); -GLAPI void APIENTRY glPathCoordsNV (GLuint path, GLsizei numCoords, GLenum coordType, const void *coords); -GLAPI void APIENTRY glPathSubCommandsNV (GLuint path, GLsizei commandStart, GLsizei commandsToDelete, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords); -GLAPI void APIENTRY glPathSubCoordsNV (GLuint path, GLsizei coordStart, GLsizei numCoords, GLenum coordType, const void *coords); -GLAPI void APIENTRY glPathStringNV (GLuint path, GLenum format, GLsizei length, const void *pathString); -GLAPI void APIENTRY glPathGlyphsNV (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLsizei numGlyphs, GLenum type, const void *charcodes, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale); -GLAPI void APIENTRY glPathGlyphRangeNV (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyph, GLsizei numGlyphs, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale); -GLAPI void APIENTRY glWeightPathsNV (GLuint resultPath, GLsizei numPaths, const GLuint *paths, const GLfloat *weights); -GLAPI void APIENTRY glCopyPathNV (GLuint resultPath, GLuint srcPath); -GLAPI void APIENTRY glInterpolatePathsNV (GLuint resultPath, GLuint pathA, GLuint pathB, GLfloat weight); -GLAPI void APIENTRY glTransformPathNV (GLuint resultPath, GLuint srcPath, GLenum transformType, const GLfloat *transformValues); -GLAPI void APIENTRY glPathParameterivNV (GLuint path, GLenum pname, const GLint *value); -GLAPI void APIENTRY glPathParameteriNV (GLuint path, GLenum pname, GLint value); -GLAPI void APIENTRY glPathParameterfvNV (GLuint path, GLenum pname, const GLfloat *value); -GLAPI void APIENTRY glPathParameterfNV (GLuint path, GLenum pname, GLfloat value); -GLAPI void APIENTRY glPathDashArrayNV (GLuint path, GLsizei dashCount, const GLfloat *dashArray); -GLAPI void APIENTRY glPathStencilFuncNV (GLenum func, GLint ref, GLuint mask); -GLAPI void APIENTRY glPathStencilDepthOffsetNV (GLfloat factor, GLfloat units); -GLAPI void APIENTRY glStencilFillPathNV (GLuint path, GLenum fillMode, GLuint mask); -GLAPI void APIENTRY glStencilStrokePathNV (GLuint path, GLint reference, GLuint mask); -GLAPI void APIENTRY glStencilFillPathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum transformType, const GLfloat *transformValues); -GLAPI void APIENTRY glStencilStrokePathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum transformType, const GLfloat *transformValues); -GLAPI void APIENTRY glPathCoverDepthFuncNV (GLenum func); -GLAPI void APIENTRY glPathColorGenNV (GLenum color, GLenum genMode, GLenum colorFormat, const GLfloat *coeffs); -GLAPI void APIENTRY glPathTexGenNV (GLenum texCoordSet, GLenum genMode, GLint components, const GLfloat *coeffs); -GLAPI void APIENTRY glPathFogGenNV (GLenum genMode); -GLAPI void APIENTRY glCoverFillPathNV (GLuint path, GLenum coverMode); -GLAPI void APIENTRY glCoverStrokePathNV (GLuint path, GLenum coverMode); -GLAPI void APIENTRY glCoverFillPathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); -GLAPI void APIENTRY glCoverStrokePathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); -GLAPI void APIENTRY glGetPathParameterivNV (GLuint path, GLenum pname, GLint *value); -GLAPI void APIENTRY glGetPathParameterfvNV (GLuint path, GLenum pname, GLfloat *value); -GLAPI void APIENTRY glGetPathCommandsNV (GLuint path, GLubyte *commands); -GLAPI void APIENTRY glGetPathCoordsNV (GLuint path, GLfloat *coords); -GLAPI void APIENTRY glGetPathDashArrayNV (GLuint path, GLfloat *dashArray); -GLAPI void APIENTRY glGetPathMetricsNV (GLbitfield metricQueryMask, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLsizei stride, GLfloat *metrics); -GLAPI void APIENTRY glGetPathMetricRangeNV (GLbitfield metricQueryMask, GLuint firstPathName, GLsizei numPaths, GLsizei stride, GLfloat *metrics); -GLAPI void APIENTRY glGetPathSpacingNV (GLenum pathListMode, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, GLfloat *returnedSpacing); -GLAPI void APIENTRY glGetPathColorGenivNV (GLenum color, GLenum pname, GLint *value); -GLAPI void APIENTRY glGetPathColorGenfvNV (GLenum color, GLenum pname, GLfloat *value); -GLAPI void APIENTRY glGetPathTexGenivNV (GLenum texCoordSet, GLenum pname, GLint *value); -GLAPI void APIENTRY glGetPathTexGenfvNV (GLenum texCoordSet, GLenum pname, GLfloat *value); -GLAPI GLboolean APIENTRY glIsPointInFillPathNV (GLuint path, GLuint mask, GLfloat x, GLfloat y); -GLAPI GLboolean APIENTRY glIsPointInStrokePathNV (GLuint path, GLfloat x, GLfloat y); -GLAPI GLfloat APIENTRY glGetPathLengthNV (GLuint path, GLsizei startSegment, GLsizei numSegments); -GLAPI GLboolean APIENTRY glPointAlongPathNV (GLuint path, GLsizei startSegment, GLsizei numSegments, GLfloat distance, GLfloat *x, GLfloat *y, GLfloat *tangentX, GLfloat *tangentY); -GLAPI void APIENTRY glMatrixLoad3x2fNV (GLenum matrixMode, const GLfloat *m); -GLAPI void APIENTRY glMatrixLoad3x3fNV (GLenum matrixMode, const GLfloat *m); -GLAPI void APIENTRY glMatrixLoadTranspose3x3fNV (GLenum matrixMode, const GLfloat *m); -GLAPI void APIENTRY glMatrixMult3x2fNV (GLenum matrixMode, const GLfloat *m); -GLAPI void APIENTRY glMatrixMult3x3fNV (GLenum matrixMode, const GLfloat *m); -GLAPI void APIENTRY glMatrixMultTranspose3x3fNV (GLenum matrixMode, const GLfloat *m); -GLAPI void APIENTRY glStencilThenCoverFillPathNV (GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode); -GLAPI void APIENTRY glStencilThenCoverStrokePathNV (GLuint path, GLint reference, GLuint mask, GLenum coverMode); -GLAPI void APIENTRY glStencilThenCoverFillPathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); -GLAPI void APIENTRY glStencilThenCoverStrokePathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); -GLAPI GLenum APIENTRY glPathGlyphIndexRangeNV (GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint pathParameterTemplate, GLfloat emScale, GLuint baseAndCount[2]); -GLAPI GLenum APIENTRY glPathGlyphIndexArrayNV (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale); -GLAPI GLenum APIENTRY glPathMemoryGlyphIndexArrayNV (GLuint firstPathName, GLenum fontTarget, GLsizeiptr fontSize, const void *fontData, GLsizei faceIndex, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale); -GLAPI void APIENTRY glProgramPathFragmentInputGenNV (GLuint program, GLint location, GLenum genMode, GLint components, const GLfloat *coeffs); -GLAPI void APIENTRY glGetProgramResourcefvNV (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLfloat *params); -#endif -#endif /* GL_NV_path_rendering */ - -#ifndef GL_NV_pixel_data_range -#define GL_NV_pixel_data_range 1 -#define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878 -#define GL_READ_PIXEL_DATA_RANGE_NV 0x8879 -#define GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV 0x887A -#define GL_READ_PIXEL_DATA_RANGE_LENGTH_NV 0x887B -#define GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV 0x887C -#define GL_READ_PIXEL_DATA_RANGE_POINTER_NV 0x887D -typedef void (APIENTRYP PFNGLPIXELDATARANGENVPROC) (GLenum target, GLsizei length, const void *pointer); -typedef void (APIENTRYP PFNGLFLUSHPIXELDATARANGENVPROC) (GLenum target); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPixelDataRangeNV (GLenum target, GLsizei length, const void *pointer); -GLAPI void APIENTRY glFlushPixelDataRangeNV (GLenum target); -#endif -#endif /* GL_NV_pixel_data_range */ - -#ifndef GL_NV_point_sprite -#define GL_NV_point_sprite 1 -#define GL_POINT_SPRITE_NV 0x8861 -#define GL_COORD_REPLACE_NV 0x8862 -#define GL_POINT_SPRITE_R_MODE_NV 0x8863 -typedef void (APIENTRYP PFNGLPOINTPARAMETERINVPROC) (GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLPOINTPARAMETERIVNVPROC) (GLenum pname, const GLint *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPointParameteriNV (GLenum pname, GLint param); -GLAPI void APIENTRY glPointParameterivNV (GLenum pname, const GLint *params); -#endif -#endif /* GL_NV_point_sprite */ - -#ifndef GL_NV_present_video -#define GL_NV_present_video 1 -#define GL_FRAME_NV 0x8E26 -#define GL_FIELDS_NV 0x8E27 -#define GL_CURRENT_TIME_NV 0x8E28 -#define GL_NUM_FILL_STREAMS_NV 0x8E29 -#define GL_PRESENT_TIME_NV 0x8E2A -#define GL_PRESENT_DURATION_NV 0x8E2B -typedef void (APIENTRYP PFNGLPRESENTFRAMEKEYEDNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLuint key0, GLenum target1, GLuint fill1, GLuint key1); -typedef void (APIENTRYP PFNGLPRESENTFRAMEDUALFILLNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLenum target1, GLuint fill1, GLenum target2, GLuint fill2, GLenum target3, GLuint fill3); -typedef void (APIENTRYP PFNGLGETVIDEOIVNVPROC) (GLuint video_slot, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETVIDEOUIVNVPROC) (GLuint video_slot, GLenum pname, GLuint *params); -typedef void (APIENTRYP PFNGLGETVIDEOI64VNVPROC) (GLuint video_slot, GLenum pname, GLint64EXT *params); -typedef void (APIENTRYP PFNGLGETVIDEOUI64VNVPROC) (GLuint video_slot, GLenum pname, GLuint64EXT *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPresentFrameKeyedNV (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLuint key0, GLenum target1, GLuint fill1, GLuint key1); -GLAPI void APIENTRY glPresentFrameDualFillNV (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLenum target1, GLuint fill1, GLenum target2, GLuint fill2, GLenum target3, GLuint fill3); -GLAPI void APIENTRY glGetVideoivNV (GLuint video_slot, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetVideouivNV (GLuint video_slot, GLenum pname, GLuint *params); -GLAPI void APIENTRY glGetVideoi64vNV (GLuint video_slot, GLenum pname, GLint64EXT *params); -GLAPI void APIENTRY glGetVideoui64vNV (GLuint video_slot, GLenum pname, GLuint64EXT *params); -#endif -#endif /* GL_NV_present_video */ - -#ifndef GL_NV_primitive_restart -#define GL_NV_primitive_restart 1 -#define GL_PRIMITIVE_RESTART_NV 0x8558 -#define GL_PRIMITIVE_RESTART_INDEX_NV 0x8559 -typedef void (APIENTRYP PFNGLPRIMITIVERESTARTNVPROC) (void); -typedef void (APIENTRYP PFNGLPRIMITIVERESTARTINDEXNVPROC) (GLuint index); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPrimitiveRestartNV (void); -GLAPI void APIENTRY glPrimitiveRestartIndexNV (GLuint index); -#endif -#endif /* GL_NV_primitive_restart */ - -#ifndef GL_NV_register_combiners -#define GL_NV_register_combiners 1 -#define GL_REGISTER_COMBINERS_NV 0x8522 -#define GL_VARIABLE_A_NV 0x8523 -#define GL_VARIABLE_B_NV 0x8524 -#define GL_VARIABLE_C_NV 0x8525 -#define GL_VARIABLE_D_NV 0x8526 -#define GL_VARIABLE_E_NV 0x8527 -#define GL_VARIABLE_F_NV 0x8528 -#define GL_VARIABLE_G_NV 0x8529 -#define GL_CONSTANT_COLOR0_NV 0x852A -#define GL_CONSTANT_COLOR1_NV 0x852B -#define GL_SPARE0_NV 0x852E -#define GL_SPARE1_NV 0x852F -#define GL_DISCARD_NV 0x8530 -#define GL_E_TIMES_F_NV 0x8531 -#define GL_SPARE0_PLUS_SECONDARY_COLOR_NV 0x8532 -#define GL_UNSIGNED_IDENTITY_NV 0x8536 -#define GL_UNSIGNED_INVERT_NV 0x8537 -#define GL_EXPAND_NORMAL_NV 0x8538 -#define GL_EXPAND_NEGATE_NV 0x8539 -#define GL_HALF_BIAS_NORMAL_NV 0x853A -#define GL_HALF_BIAS_NEGATE_NV 0x853B -#define GL_SIGNED_IDENTITY_NV 0x853C -#define GL_SIGNED_NEGATE_NV 0x853D -#define GL_SCALE_BY_TWO_NV 0x853E -#define GL_SCALE_BY_FOUR_NV 0x853F -#define GL_SCALE_BY_ONE_HALF_NV 0x8540 -#define GL_BIAS_BY_NEGATIVE_ONE_HALF_NV 0x8541 -#define GL_COMBINER_INPUT_NV 0x8542 -#define GL_COMBINER_MAPPING_NV 0x8543 -#define GL_COMBINER_COMPONENT_USAGE_NV 0x8544 -#define GL_COMBINER_AB_DOT_PRODUCT_NV 0x8545 -#define GL_COMBINER_CD_DOT_PRODUCT_NV 0x8546 -#define GL_COMBINER_MUX_SUM_NV 0x8547 -#define GL_COMBINER_SCALE_NV 0x8548 -#define GL_COMBINER_BIAS_NV 0x8549 -#define GL_COMBINER_AB_OUTPUT_NV 0x854A -#define GL_COMBINER_CD_OUTPUT_NV 0x854B -#define GL_COMBINER_SUM_OUTPUT_NV 0x854C -#define GL_MAX_GENERAL_COMBINERS_NV 0x854D -#define GL_NUM_GENERAL_COMBINERS_NV 0x854E -#define GL_COLOR_SUM_CLAMP_NV 0x854F -#define GL_COMBINER0_NV 0x8550 -#define GL_COMBINER1_NV 0x8551 -#define GL_COMBINER2_NV 0x8552 -#define GL_COMBINER3_NV 0x8553 -#define GL_COMBINER4_NV 0x8554 -#define GL_COMBINER5_NV 0x8555 -#define GL_COMBINER6_NV 0x8556 -#define GL_COMBINER7_NV 0x8557 -typedef void (APIENTRYP PFNGLCOMBINERPARAMETERFVNVPROC) (GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLCOMBINERPARAMETERFNVPROC) (GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLCOMBINERPARAMETERIVNVPROC) (GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLCOMBINERPARAMETERINVPROC) (GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLCOMBINERINPUTNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); -typedef void (APIENTRYP PFNGLCOMBINEROUTPUTNVPROC) (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum); -typedef void (APIENTRYP PFNGLFINALCOMBINERINPUTNVPROC) (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); -typedef void (APIENTRYP PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC) (GLenum variable, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC) (GLenum variable, GLenum pname, GLint *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glCombinerParameterfvNV (GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glCombinerParameterfNV (GLenum pname, GLfloat param); -GLAPI void APIENTRY glCombinerParameterivNV (GLenum pname, const GLint *params); -GLAPI void APIENTRY glCombinerParameteriNV (GLenum pname, GLint param); -GLAPI void APIENTRY glCombinerInputNV (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); -GLAPI void APIENTRY glCombinerOutputNV (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum); -GLAPI void APIENTRY glFinalCombinerInputNV (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); -GLAPI void APIENTRY glGetCombinerInputParameterfvNV (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetCombinerInputParameterivNV (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetCombinerOutputParameterfvNV (GLenum stage, GLenum portion, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetCombinerOutputParameterivNV (GLenum stage, GLenum portion, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetFinalCombinerInputParameterfvNV (GLenum variable, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetFinalCombinerInputParameterivNV (GLenum variable, GLenum pname, GLint *params); -#endif -#endif /* GL_NV_register_combiners */ - -#ifndef GL_NV_register_combiners2 -#define GL_NV_register_combiners2 1 -#define GL_PER_STAGE_CONSTANTS_NV 0x8535 -typedef void (APIENTRYP PFNGLCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, GLfloat *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glCombinerStageParameterfvNV (GLenum stage, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glGetCombinerStageParameterfvNV (GLenum stage, GLenum pname, GLfloat *params); -#endif -#endif /* GL_NV_register_combiners2 */ - -#ifndef GL_NV_shader_atomic_counters -#define GL_NV_shader_atomic_counters 1 -#endif /* GL_NV_shader_atomic_counters */ - -#ifndef GL_NV_shader_atomic_float -#define GL_NV_shader_atomic_float 1 -#endif /* GL_NV_shader_atomic_float */ - -#ifndef GL_NV_shader_atomic_int64 -#define GL_NV_shader_atomic_int64 1 -#endif /* GL_NV_shader_atomic_int64 */ - -#ifndef GL_NV_shader_buffer_load -#define GL_NV_shader_buffer_load 1 -#define GL_BUFFER_GPU_ADDRESS_NV 0x8F1D -#define GL_GPU_ADDRESS_NV 0x8F34 -#define GL_MAX_SHADER_BUFFER_ADDRESS_NV 0x8F35 -typedef void (APIENTRYP PFNGLMAKEBUFFERRESIDENTNVPROC) (GLenum target, GLenum access); -typedef void (APIENTRYP PFNGLMAKEBUFFERNONRESIDENTNVPROC) (GLenum target); -typedef GLboolean (APIENTRYP PFNGLISBUFFERRESIDENTNVPROC) (GLenum target); -typedef void (APIENTRYP PFNGLMAKENAMEDBUFFERRESIDENTNVPROC) (GLuint buffer, GLenum access); -typedef void (APIENTRYP PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC) (GLuint buffer); -typedef GLboolean (APIENTRYP PFNGLISNAMEDBUFFERRESIDENTNVPROC) (GLuint buffer); -typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERUI64VNVPROC) (GLenum target, GLenum pname, GLuint64EXT *params); -typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC) (GLuint buffer, GLenum pname, GLuint64EXT *params); -typedef void (APIENTRYP PFNGLGETINTEGERUI64VNVPROC) (GLenum value, GLuint64EXT *result); -typedef void (APIENTRYP PFNGLUNIFORMUI64NVPROC) (GLint location, GLuint64EXT value); -typedef void (APIENTRYP PFNGLUNIFORMUI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMUI64NVPROC) (GLuint program, GLint location, GLuint64EXT value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMUI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glMakeBufferResidentNV (GLenum target, GLenum access); -GLAPI void APIENTRY glMakeBufferNonResidentNV (GLenum target); -GLAPI GLboolean APIENTRY glIsBufferResidentNV (GLenum target); -GLAPI void APIENTRY glMakeNamedBufferResidentNV (GLuint buffer, GLenum access); -GLAPI void APIENTRY glMakeNamedBufferNonResidentNV (GLuint buffer); -GLAPI GLboolean APIENTRY glIsNamedBufferResidentNV (GLuint buffer); -GLAPI void APIENTRY glGetBufferParameterui64vNV (GLenum target, GLenum pname, GLuint64EXT *params); -GLAPI void APIENTRY glGetNamedBufferParameterui64vNV (GLuint buffer, GLenum pname, GLuint64EXT *params); -GLAPI void APIENTRY glGetIntegerui64vNV (GLenum value, GLuint64EXT *result); -GLAPI void APIENTRY glUniformui64NV (GLint location, GLuint64EXT value); -GLAPI void APIENTRY glUniformui64vNV (GLint location, GLsizei count, const GLuint64EXT *value); -GLAPI void APIENTRY glProgramUniformui64NV (GLuint program, GLint location, GLuint64EXT value); -GLAPI void APIENTRY glProgramUniformui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); -#endif -#endif /* GL_NV_shader_buffer_load */ - -#ifndef GL_NV_shader_buffer_store -#define GL_NV_shader_buffer_store 1 -#define GL_SHADER_GLOBAL_ACCESS_BARRIER_BIT_NV 0x00000010 -#endif /* GL_NV_shader_buffer_store */ - -#ifndef GL_NV_shader_storage_buffer_object -#define GL_NV_shader_storage_buffer_object 1 -#endif /* GL_NV_shader_storage_buffer_object */ - -#ifndef GL_NV_shader_thread_group -#define GL_NV_shader_thread_group 1 -#define GL_WARP_SIZE_NV 0x9339 -#define GL_WARPS_PER_SM_NV 0x933A -#define GL_SM_COUNT_NV 0x933B -#endif /* GL_NV_shader_thread_group */ - -#ifndef GL_NV_shader_thread_shuffle -#define GL_NV_shader_thread_shuffle 1 -#endif /* GL_NV_shader_thread_shuffle */ - -#ifndef GL_NV_tessellation_program5 -#define GL_NV_tessellation_program5 1 -#define GL_MAX_PROGRAM_PATCH_ATTRIBS_NV 0x86D8 -#define GL_TESS_CONTROL_PROGRAM_NV 0x891E -#define GL_TESS_EVALUATION_PROGRAM_NV 0x891F -#define GL_TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV 0x8C74 -#define GL_TESS_EVALUATION_PROGRAM_PARAMETER_BUFFER_NV 0x8C75 -#endif /* GL_NV_tessellation_program5 */ - -#ifndef GL_NV_texgen_emboss -#define GL_NV_texgen_emboss 1 -#define GL_EMBOSS_LIGHT_NV 0x855D -#define GL_EMBOSS_CONSTANT_NV 0x855E -#define GL_EMBOSS_MAP_NV 0x855F -#endif /* GL_NV_texgen_emboss */ - -#ifndef GL_NV_texgen_reflection -#define GL_NV_texgen_reflection 1 -#define GL_NORMAL_MAP_NV 0x8511 -#define GL_REFLECTION_MAP_NV 0x8512 -#endif /* GL_NV_texgen_reflection */ - -#ifndef GL_NV_texture_barrier -#define GL_NV_texture_barrier 1 -typedef void (APIENTRYP PFNGLTEXTUREBARRIERNVPROC) (void); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTextureBarrierNV (void); -#endif -#endif /* GL_NV_texture_barrier */ - -#ifndef GL_NV_texture_compression_vtc -#define GL_NV_texture_compression_vtc 1 -#endif /* GL_NV_texture_compression_vtc */ - -#ifndef GL_NV_texture_env_combine4 -#define GL_NV_texture_env_combine4 1 -#define GL_COMBINE4_NV 0x8503 -#define GL_SOURCE3_RGB_NV 0x8583 -#define GL_SOURCE3_ALPHA_NV 0x858B -#define GL_OPERAND3_RGB_NV 0x8593 -#define GL_OPERAND3_ALPHA_NV 0x859B -#endif /* GL_NV_texture_env_combine4 */ - -#ifndef GL_NV_texture_expand_normal -#define GL_NV_texture_expand_normal 1 -#define GL_TEXTURE_UNSIGNED_REMAP_MODE_NV 0x888F -#endif /* GL_NV_texture_expand_normal */ - -#ifndef GL_NV_texture_multisample -#define GL_NV_texture_multisample 1 -#define GL_TEXTURE_COVERAGE_SAMPLES_NV 0x9045 -#define GL_TEXTURE_COLOR_SAMPLES_NV 0x9046 -typedef void (APIENTRYP PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); -typedef void (APIENTRYP PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); -typedef void (APIENTRYP PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC) (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); -typedef void (APIENTRYP PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC) (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); -typedef void (APIENTRYP PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC) (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); -typedef void (APIENTRYP PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC) (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTexImage2DMultisampleCoverageNV (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); -GLAPI void APIENTRY glTexImage3DMultisampleCoverageNV (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); -GLAPI void APIENTRY glTextureImage2DMultisampleNV (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); -GLAPI void APIENTRY glTextureImage3DMultisampleNV (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); -GLAPI void APIENTRY glTextureImage2DMultisampleCoverageNV (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); -GLAPI void APIENTRY glTextureImage3DMultisampleCoverageNV (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); -#endif -#endif /* GL_NV_texture_multisample */ - -#ifndef GL_NV_texture_rectangle -#define GL_NV_texture_rectangle 1 -#define GL_TEXTURE_RECTANGLE_NV 0x84F5 -#define GL_TEXTURE_BINDING_RECTANGLE_NV 0x84F6 -#define GL_PROXY_TEXTURE_RECTANGLE_NV 0x84F7 -#define GL_MAX_RECTANGLE_TEXTURE_SIZE_NV 0x84F8 -#endif /* GL_NV_texture_rectangle */ - -#ifndef GL_NV_texture_shader -#define GL_NV_texture_shader 1 -#define GL_OFFSET_TEXTURE_RECTANGLE_NV 0x864C -#define GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV 0x864D -#define GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV 0x864E -#define GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV 0x86D9 -#define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA -#define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB -#define GL_DSDT_MAG_INTENSITY_NV 0x86DC -#define GL_SHADER_CONSISTENT_NV 0x86DD -#define GL_TEXTURE_SHADER_NV 0x86DE -#define GL_SHADER_OPERATION_NV 0x86DF -#define GL_CULL_MODES_NV 0x86E0 -#define GL_OFFSET_TEXTURE_MATRIX_NV 0x86E1 -#define GL_OFFSET_TEXTURE_SCALE_NV 0x86E2 -#define GL_OFFSET_TEXTURE_BIAS_NV 0x86E3 -#define GL_OFFSET_TEXTURE_2D_MATRIX_NV 0x86E1 -#define GL_OFFSET_TEXTURE_2D_SCALE_NV 0x86E2 -#define GL_OFFSET_TEXTURE_2D_BIAS_NV 0x86E3 -#define GL_PREVIOUS_TEXTURE_INPUT_NV 0x86E4 -#define GL_CONST_EYE_NV 0x86E5 -#define GL_PASS_THROUGH_NV 0x86E6 -#define GL_CULL_FRAGMENT_NV 0x86E7 -#define GL_OFFSET_TEXTURE_2D_NV 0x86E8 -#define GL_DEPENDENT_AR_TEXTURE_2D_NV 0x86E9 -#define GL_DEPENDENT_GB_TEXTURE_2D_NV 0x86EA -#define GL_DOT_PRODUCT_NV 0x86EC -#define GL_DOT_PRODUCT_DEPTH_REPLACE_NV 0x86ED -#define GL_DOT_PRODUCT_TEXTURE_2D_NV 0x86EE -#define GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV 0x86F0 -#define GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV 0x86F1 -#define GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV 0x86F2 -#define GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV 0x86F3 -#define GL_HILO_NV 0x86F4 -#define GL_DSDT_NV 0x86F5 -#define GL_DSDT_MAG_NV 0x86F6 -#define GL_DSDT_MAG_VIB_NV 0x86F7 -#define GL_HILO16_NV 0x86F8 -#define GL_SIGNED_HILO_NV 0x86F9 -#define GL_SIGNED_HILO16_NV 0x86FA -#define GL_SIGNED_RGBA_NV 0x86FB -#define GL_SIGNED_RGBA8_NV 0x86FC -#define GL_SIGNED_RGB_NV 0x86FE -#define GL_SIGNED_RGB8_NV 0x86FF -#define GL_SIGNED_LUMINANCE_NV 0x8701 -#define GL_SIGNED_LUMINANCE8_NV 0x8702 -#define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703 -#define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704 -#define GL_SIGNED_ALPHA_NV 0x8705 -#define GL_SIGNED_ALPHA8_NV 0x8706 -#define GL_SIGNED_INTENSITY_NV 0x8707 -#define GL_SIGNED_INTENSITY8_NV 0x8708 -#define GL_DSDT8_NV 0x8709 -#define GL_DSDT8_MAG8_NV 0x870A -#define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B -#define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C -#define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D -#define GL_HI_SCALE_NV 0x870E -#define GL_LO_SCALE_NV 0x870F -#define GL_DS_SCALE_NV 0x8710 -#define GL_DT_SCALE_NV 0x8711 -#define GL_MAGNITUDE_SCALE_NV 0x8712 -#define GL_VIBRANCE_SCALE_NV 0x8713 -#define GL_HI_BIAS_NV 0x8714 -#define GL_LO_BIAS_NV 0x8715 -#define GL_DS_BIAS_NV 0x8716 -#define GL_DT_BIAS_NV 0x8717 -#define GL_MAGNITUDE_BIAS_NV 0x8718 -#define GL_VIBRANCE_BIAS_NV 0x8719 -#define GL_TEXTURE_BORDER_VALUES_NV 0x871A -#define GL_TEXTURE_HI_SIZE_NV 0x871B -#define GL_TEXTURE_LO_SIZE_NV 0x871C -#define GL_TEXTURE_DS_SIZE_NV 0x871D -#define GL_TEXTURE_DT_SIZE_NV 0x871E -#define GL_TEXTURE_MAG_SIZE_NV 0x871F -#endif /* GL_NV_texture_shader */ - -#ifndef GL_NV_texture_shader2 -#define GL_NV_texture_shader2 1 -#define GL_DOT_PRODUCT_TEXTURE_3D_NV 0x86EF -#endif /* GL_NV_texture_shader2 */ - -#ifndef GL_NV_texture_shader3 -#define GL_NV_texture_shader3 1 -#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV 0x8850 -#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV 0x8851 -#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8852 -#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV 0x8853 -#define GL_OFFSET_HILO_TEXTURE_2D_NV 0x8854 -#define GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV 0x8855 -#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV 0x8856 -#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8857 -#define GL_DEPENDENT_HILO_TEXTURE_2D_NV 0x8858 -#define GL_DEPENDENT_RGB_TEXTURE_3D_NV 0x8859 -#define GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV 0x885A -#define GL_DOT_PRODUCT_PASS_THROUGH_NV 0x885B -#define GL_DOT_PRODUCT_TEXTURE_1D_NV 0x885C -#define GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV 0x885D -#define GL_HILO8_NV 0x885E -#define GL_SIGNED_HILO8_NV 0x885F -#define GL_FORCE_BLUE_TO_ONE_NV 0x8860 -#endif /* GL_NV_texture_shader3 */ - -#ifndef GL_NV_transform_feedback -#define GL_NV_transform_feedback 1 -#define GL_BACK_PRIMARY_COLOR_NV 0x8C77 -#define GL_BACK_SECONDARY_COLOR_NV 0x8C78 -#define GL_TEXTURE_COORD_NV 0x8C79 -#define GL_CLIP_DISTANCE_NV 0x8C7A -#define GL_VERTEX_ID_NV 0x8C7B -#define GL_PRIMITIVE_ID_NV 0x8C7C -#define GL_GENERIC_ATTRIB_NV 0x8C7D -#define GL_TRANSFORM_FEEDBACK_ATTRIBS_NV 0x8C7E -#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_NV 0x8C7F -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV 0x8C80 -#define GL_ACTIVE_VARYINGS_NV 0x8C81 -#define GL_ACTIVE_VARYING_MAX_LENGTH_NV 0x8C82 -#define GL_TRANSFORM_FEEDBACK_VARYINGS_NV 0x8C83 -#define GL_TRANSFORM_FEEDBACK_BUFFER_START_NV 0x8C84 -#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_NV 0x8C85 -#define GL_TRANSFORM_FEEDBACK_RECORD_NV 0x8C86 -#define GL_PRIMITIVES_GENERATED_NV 0x8C87 -#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV 0x8C88 -#define GL_RASTERIZER_DISCARD_NV 0x8C89 -#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_NV 0x8C8A -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV 0x8C8B -#define GL_INTERLEAVED_ATTRIBS_NV 0x8C8C -#define GL_SEPARATE_ATTRIBS_NV 0x8C8D -#define GL_TRANSFORM_FEEDBACK_BUFFER_NV 0x8C8E -#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_NV 0x8C8F -#define GL_LAYER_NV 0x8DAA -#define GL_NEXT_BUFFER_NV -2 -#define GL_SKIP_COMPONENTS4_NV -3 -#define GL_SKIP_COMPONENTS3_NV -4 -#define GL_SKIP_COMPONENTS2_NV -5 -#define GL_SKIP_COMPONENTS1_NV -6 -typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKNVPROC) (GLenum primitiveMode); -typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKNVPROC) (void); -typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC) (GLsizei count, const GLint *attribs, GLenum bufferMode); -typedef void (APIENTRYP PFNGLBINDBUFFERRANGENVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); -typedef void (APIENTRYP PFNGLBINDBUFFEROFFSETNVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset); -typedef void (APIENTRYP PFNGLBINDBUFFERBASENVPROC) (GLenum target, GLuint index, GLuint buffer); -typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC) (GLuint program, GLsizei count, const GLint *locations, GLenum bufferMode); -typedef void (APIENTRYP PFNGLACTIVEVARYINGNVPROC) (GLuint program, const GLchar *name); -typedef GLint (APIENTRYP PFNGLGETVARYINGLOCATIONNVPROC) (GLuint program, const GLchar *name); -typedef void (APIENTRYP PFNGLGETACTIVEVARYINGNVPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); -typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC) (GLuint program, GLuint index, GLint *location); -typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKSTREAMATTRIBSNVPROC) (GLsizei count, const GLint *attribs, GLsizei nbuffers, const GLint *bufstreams, GLenum bufferMode); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBeginTransformFeedbackNV (GLenum primitiveMode); -GLAPI void APIENTRY glEndTransformFeedbackNV (void); -GLAPI void APIENTRY glTransformFeedbackAttribsNV (GLsizei count, const GLint *attribs, GLenum bufferMode); -GLAPI void APIENTRY glBindBufferRangeNV (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); -GLAPI void APIENTRY glBindBufferOffsetNV (GLenum target, GLuint index, GLuint buffer, GLintptr offset); -GLAPI void APIENTRY glBindBufferBaseNV (GLenum target, GLuint index, GLuint buffer); -GLAPI void APIENTRY glTransformFeedbackVaryingsNV (GLuint program, GLsizei count, const GLint *locations, GLenum bufferMode); -GLAPI void APIENTRY glActiveVaryingNV (GLuint program, const GLchar *name); -GLAPI GLint APIENTRY glGetVaryingLocationNV (GLuint program, const GLchar *name); -GLAPI void APIENTRY glGetActiveVaryingNV (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); -GLAPI void APIENTRY glGetTransformFeedbackVaryingNV (GLuint program, GLuint index, GLint *location); -GLAPI void APIENTRY glTransformFeedbackStreamAttribsNV (GLsizei count, const GLint *attribs, GLsizei nbuffers, const GLint *bufstreams, GLenum bufferMode); -#endif -#endif /* GL_NV_transform_feedback */ - -#ifndef GL_NV_transform_feedback2 -#define GL_NV_transform_feedback2 1 -#define GL_TRANSFORM_FEEDBACK_NV 0x8E22 -#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED_NV 0x8E23 -#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE_NV 0x8E24 -#define GL_TRANSFORM_FEEDBACK_BINDING_NV 0x8E25 -typedef void (APIENTRYP PFNGLBINDTRANSFORMFEEDBACKNVPROC) (GLenum target, GLuint id); -typedef void (APIENTRYP PFNGLDELETETRANSFORMFEEDBACKSNVPROC) (GLsizei n, const GLuint *ids); -typedef void (APIENTRYP PFNGLGENTRANSFORMFEEDBACKSNVPROC) (GLsizei n, GLuint *ids); -typedef GLboolean (APIENTRYP PFNGLISTRANSFORMFEEDBACKNVPROC) (GLuint id); -typedef void (APIENTRYP PFNGLPAUSETRANSFORMFEEDBACKNVPROC) (void); -typedef void (APIENTRYP PFNGLRESUMETRANSFORMFEEDBACKNVPROC) (void); -typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKNVPROC) (GLenum mode, GLuint id); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBindTransformFeedbackNV (GLenum target, GLuint id); -GLAPI void APIENTRY glDeleteTransformFeedbacksNV (GLsizei n, const GLuint *ids); -GLAPI void APIENTRY glGenTransformFeedbacksNV (GLsizei n, GLuint *ids); -GLAPI GLboolean APIENTRY glIsTransformFeedbackNV (GLuint id); -GLAPI void APIENTRY glPauseTransformFeedbackNV (void); -GLAPI void APIENTRY glResumeTransformFeedbackNV (void); -GLAPI void APIENTRY glDrawTransformFeedbackNV (GLenum mode, GLuint id); -#endif -#endif /* GL_NV_transform_feedback2 */ - -#ifndef GL_NV_vdpau_interop -#define GL_NV_vdpau_interop 1 -typedef GLintptr GLvdpauSurfaceNV; -#define GL_SURFACE_STATE_NV 0x86EB -#define GL_SURFACE_REGISTERED_NV 0x86FD -#define GL_SURFACE_MAPPED_NV 0x8700 -#define GL_WRITE_DISCARD_NV 0x88BE -typedef void (APIENTRYP PFNGLVDPAUINITNVPROC) (const void *vdpDevice, const void *getProcAddress); -typedef void (APIENTRYP PFNGLVDPAUFININVPROC) (void); -typedef GLvdpauSurfaceNV (APIENTRYP PFNGLVDPAUREGISTERVIDEOSURFACENVPROC) (const void *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames); -typedef GLvdpauSurfaceNV (APIENTRYP PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC) (const void *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames); -typedef GLboolean (APIENTRYP PFNGLVDPAUISSURFACENVPROC) (GLvdpauSurfaceNV surface); -typedef void (APIENTRYP PFNGLVDPAUUNREGISTERSURFACENVPROC) (GLvdpauSurfaceNV surface); -typedef void (APIENTRYP PFNGLVDPAUGETSURFACEIVNVPROC) (GLvdpauSurfaceNV surface, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); -typedef void (APIENTRYP PFNGLVDPAUSURFACEACCESSNVPROC) (GLvdpauSurfaceNV surface, GLenum access); -typedef void (APIENTRYP PFNGLVDPAUMAPSURFACESNVPROC) (GLsizei numSurfaces, const GLvdpauSurfaceNV *surfaces); -typedef void (APIENTRYP PFNGLVDPAUUNMAPSURFACESNVPROC) (GLsizei numSurface, const GLvdpauSurfaceNV *surfaces); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVDPAUInitNV (const void *vdpDevice, const void *getProcAddress); -GLAPI void APIENTRY glVDPAUFiniNV (void); -GLAPI GLvdpauSurfaceNV APIENTRY glVDPAURegisterVideoSurfaceNV (const void *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames); -GLAPI GLvdpauSurfaceNV APIENTRY glVDPAURegisterOutputSurfaceNV (const void *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames); -GLAPI GLboolean APIENTRY glVDPAUIsSurfaceNV (GLvdpauSurfaceNV surface); -GLAPI void APIENTRY glVDPAUUnregisterSurfaceNV (GLvdpauSurfaceNV surface); -GLAPI void APIENTRY glVDPAUGetSurfaceivNV (GLvdpauSurfaceNV surface, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); -GLAPI void APIENTRY glVDPAUSurfaceAccessNV (GLvdpauSurfaceNV surface, GLenum access); -GLAPI void APIENTRY glVDPAUMapSurfacesNV (GLsizei numSurfaces, const GLvdpauSurfaceNV *surfaces); -GLAPI void APIENTRY glVDPAUUnmapSurfacesNV (GLsizei numSurface, const GLvdpauSurfaceNV *surfaces); -#endif -#endif /* GL_NV_vdpau_interop */ - -#ifndef GL_NV_vertex_array_range -#define GL_NV_vertex_array_range 1 -#define GL_VERTEX_ARRAY_RANGE_NV 0x851D -#define GL_VERTEX_ARRAY_RANGE_LENGTH_NV 0x851E -#define GL_VERTEX_ARRAY_RANGE_VALID_NV 0x851F -#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV 0x8520 -#define GL_VERTEX_ARRAY_RANGE_POINTER_NV 0x8521 -typedef void (APIENTRYP PFNGLFLUSHVERTEXARRAYRANGENVPROC) (void); -typedef void (APIENTRYP PFNGLVERTEXARRAYRANGENVPROC) (GLsizei length, const void *pointer); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFlushVertexArrayRangeNV (void); -GLAPI void APIENTRY glVertexArrayRangeNV (GLsizei length, const void *pointer); -#endif -#endif /* GL_NV_vertex_array_range */ - -#ifndef GL_NV_vertex_array_range2 -#define GL_NV_vertex_array_range2 1 -#define GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV 0x8533 -#endif /* GL_NV_vertex_array_range2 */ - -#ifndef GL_NV_vertex_attrib_integer_64bit -#define GL_NV_vertex_attrib_integer_64bit 1 -typedef void (APIENTRYP PFNGLVERTEXATTRIBL1I64NVPROC) (GLuint index, GLint64EXT x); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL2I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL3I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL4I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL1I64VNVPROC) (GLuint index, const GLint64EXT *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL2I64VNVPROC) (GLuint index, const GLint64EXT *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL3I64VNVPROC) (GLuint index, const GLint64EXT *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL4I64VNVPROC) (GLuint index, const GLint64EXT *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL1UI64NVPROC) (GLuint index, GLuint64EXT x); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL2UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL3UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL4UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL1UI64VNVPROC) (GLuint index, const GLuint64EXT *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL2UI64VNVPROC) (GLuint index, const GLuint64EXT *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL3UI64VNVPROC) (GLuint index, const GLuint64EXT *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL4UI64VNVPROC) (GLuint index, const GLuint64EXT *v); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLI64VNVPROC) (GLuint index, GLenum pname, GLint64EXT *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLUI64VNVPROC) (GLuint index, GLenum pname, GLuint64EXT *params); -typedef void (APIENTRYP PFNGLVERTEXATTRIBLFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexAttribL1i64NV (GLuint index, GLint64EXT x); -GLAPI void APIENTRY glVertexAttribL2i64NV (GLuint index, GLint64EXT x, GLint64EXT y); -GLAPI void APIENTRY glVertexAttribL3i64NV (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z); -GLAPI void APIENTRY glVertexAttribL4i64NV (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); -GLAPI void APIENTRY glVertexAttribL1i64vNV (GLuint index, const GLint64EXT *v); -GLAPI void APIENTRY glVertexAttribL2i64vNV (GLuint index, const GLint64EXT *v); -GLAPI void APIENTRY glVertexAttribL3i64vNV (GLuint index, const GLint64EXT *v); -GLAPI void APIENTRY glVertexAttribL4i64vNV (GLuint index, const GLint64EXT *v); -GLAPI void APIENTRY glVertexAttribL1ui64NV (GLuint index, GLuint64EXT x); -GLAPI void APIENTRY glVertexAttribL2ui64NV (GLuint index, GLuint64EXT x, GLuint64EXT y); -GLAPI void APIENTRY glVertexAttribL3ui64NV (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); -GLAPI void APIENTRY glVertexAttribL4ui64NV (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); -GLAPI void APIENTRY glVertexAttribL1ui64vNV (GLuint index, const GLuint64EXT *v); -GLAPI void APIENTRY glVertexAttribL2ui64vNV (GLuint index, const GLuint64EXT *v); -GLAPI void APIENTRY glVertexAttribL3ui64vNV (GLuint index, const GLuint64EXT *v); -GLAPI void APIENTRY glVertexAttribL4ui64vNV (GLuint index, const GLuint64EXT *v); -GLAPI void APIENTRY glGetVertexAttribLi64vNV (GLuint index, GLenum pname, GLint64EXT *params); -GLAPI void APIENTRY glGetVertexAttribLui64vNV (GLuint index, GLenum pname, GLuint64EXT *params); -GLAPI void APIENTRY glVertexAttribLFormatNV (GLuint index, GLint size, GLenum type, GLsizei stride); -#endif -#endif /* GL_NV_vertex_attrib_integer_64bit */ - -#ifndef GL_NV_vertex_buffer_unified_memory -#define GL_NV_vertex_buffer_unified_memory 1 -#define GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV 0x8F1E -#define GL_ELEMENT_ARRAY_UNIFIED_NV 0x8F1F -#define GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV 0x8F20 -#define GL_VERTEX_ARRAY_ADDRESS_NV 0x8F21 -#define GL_NORMAL_ARRAY_ADDRESS_NV 0x8F22 -#define GL_COLOR_ARRAY_ADDRESS_NV 0x8F23 -#define GL_INDEX_ARRAY_ADDRESS_NV 0x8F24 -#define GL_TEXTURE_COORD_ARRAY_ADDRESS_NV 0x8F25 -#define GL_EDGE_FLAG_ARRAY_ADDRESS_NV 0x8F26 -#define GL_SECONDARY_COLOR_ARRAY_ADDRESS_NV 0x8F27 -#define GL_FOG_COORD_ARRAY_ADDRESS_NV 0x8F28 -#define GL_ELEMENT_ARRAY_ADDRESS_NV 0x8F29 -#define GL_VERTEX_ATTRIB_ARRAY_LENGTH_NV 0x8F2A -#define GL_VERTEX_ARRAY_LENGTH_NV 0x8F2B -#define GL_NORMAL_ARRAY_LENGTH_NV 0x8F2C -#define GL_COLOR_ARRAY_LENGTH_NV 0x8F2D -#define GL_INDEX_ARRAY_LENGTH_NV 0x8F2E -#define GL_TEXTURE_COORD_ARRAY_LENGTH_NV 0x8F2F -#define GL_EDGE_FLAG_ARRAY_LENGTH_NV 0x8F30 -#define GL_SECONDARY_COLOR_ARRAY_LENGTH_NV 0x8F31 -#define GL_FOG_COORD_ARRAY_LENGTH_NV 0x8F32 -#define GL_ELEMENT_ARRAY_LENGTH_NV 0x8F33 -#define GL_DRAW_INDIRECT_UNIFIED_NV 0x8F40 -#define GL_DRAW_INDIRECT_ADDRESS_NV 0x8F41 -#define GL_DRAW_INDIRECT_LENGTH_NV 0x8F42 -typedef void (APIENTRYP PFNGLBUFFERADDRESSRANGENVPROC) (GLenum pname, GLuint index, GLuint64EXT address, GLsizeiptr length); -typedef void (APIENTRYP PFNGLVERTEXFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); -typedef void (APIENTRYP PFNGLNORMALFORMATNVPROC) (GLenum type, GLsizei stride); -typedef void (APIENTRYP PFNGLCOLORFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); -typedef void (APIENTRYP PFNGLINDEXFORMATNVPROC) (GLenum type, GLsizei stride); -typedef void (APIENTRYP PFNGLTEXCOORDFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); -typedef void (APIENTRYP PFNGLEDGEFLAGFORMATNVPROC) (GLsizei stride); -typedef void (APIENTRYP PFNGLSECONDARYCOLORFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); -typedef void (APIENTRYP PFNGLFOGCOORDFORMATNVPROC) (GLenum type, GLsizei stride); -typedef void (APIENTRYP PFNGLVERTEXATTRIBFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride); -typedef void (APIENTRYP PFNGLVERTEXATTRIBIFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride); -typedef void (APIENTRYP PFNGLGETINTEGERUI64I_VNVPROC) (GLenum value, GLuint index, GLuint64EXT *result); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBufferAddressRangeNV (GLenum pname, GLuint index, GLuint64EXT address, GLsizeiptr length); -GLAPI void APIENTRY glVertexFormatNV (GLint size, GLenum type, GLsizei stride); -GLAPI void APIENTRY glNormalFormatNV (GLenum type, GLsizei stride); -GLAPI void APIENTRY glColorFormatNV (GLint size, GLenum type, GLsizei stride); -GLAPI void APIENTRY glIndexFormatNV (GLenum type, GLsizei stride); -GLAPI void APIENTRY glTexCoordFormatNV (GLint size, GLenum type, GLsizei stride); -GLAPI void APIENTRY glEdgeFlagFormatNV (GLsizei stride); -GLAPI void APIENTRY glSecondaryColorFormatNV (GLint size, GLenum type, GLsizei stride); -GLAPI void APIENTRY glFogCoordFormatNV (GLenum type, GLsizei stride); -GLAPI void APIENTRY glVertexAttribFormatNV (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride); -GLAPI void APIENTRY glVertexAttribIFormatNV (GLuint index, GLint size, GLenum type, GLsizei stride); -GLAPI void APIENTRY glGetIntegerui64i_vNV (GLenum value, GLuint index, GLuint64EXT *result); -#endif -#endif /* GL_NV_vertex_buffer_unified_memory */ - -#ifndef GL_NV_vertex_program -#define GL_NV_vertex_program 1 -#define GL_VERTEX_PROGRAM_NV 0x8620 -#define GL_VERTEX_STATE_PROGRAM_NV 0x8621 -#define GL_ATTRIB_ARRAY_SIZE_NV 0x8623 -#define GL_ATTRIB_ARRAY_STRIDE_NV 0x8624 -#define GL_ATTRIB_ARRAY_TYPE_NV 0x8625 -#define GL_CURRENT_ATTRIB_NV 0x8626 -#define GL_PROGRAM_LENGTH_NV 0x8627 -#define GL_PROGRAM_STRING_NV 0x8628 -#define GL_MODELVIEW_PROJECTION_NV 0x8629 -#define GL_IDENTITY_NV 0x862A -#define GL_INVERSE_NV 0x862B -#define GL_TRANSPOSE_NV 0x862C -#define GL_INVERSE_TRANSPOSE_NV 0x862D -#define GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV 0x862E -#define GL_MAX_TRACK_MATRICES_NV 0x862F -#define GL_MATRIX0_NV 0x8630 -#define GL_MATRIX1_NV 0x8631 -#define GL_MATRIX2_NV 0x8632 -#define GL_MATRIX3_NV 0x8633 -#define GL_MATRIX4_NV 0x8634 -#define GL_MATRIX5_NV 0x8635 -#define GL_MATRIX6_NV 0x8636 -#define GL_MATRIX7_NV 0x8637 -#define GL_CURRENT_MATRIX_STACK_DEPTH_NV 0x8640 -#define GL_CURRENT_MATRIX_NV 0x8641 -#define GL_VERTEX_PROGRAM_POINT_SIZE_NV 0x8642 -#define GL_VERTEX_PROGRAM_TWO_SIDE_NV 0x8643 -#define GL_PROGRAM_PARAMETER_NV 0x8644 -#define GL_ATTRIB_ARRAY_POINTER_NV 0x8645 -#define GL_PROGRAM_TARGET_NV 0x8646 -#define GL_PROGRAM_RESIDENT_NV 0x8647 -#define GL_TRACK_MATRIX_NV 0x8648 -#define GL_TRACK_MATRIX_TRANSFORM_NV 0x8649 -#define GL_VERTEX_PROGRAM_BINDING_NV 0x864A -#define GL_PROGRAM_ERROR_POSITION_NV 0x864B -#define GL_VERTEX_ATTRIB_ARRAY0_NV 0x8650 -#define GL_VERTEX_ATTRIB_ARRAY1_NV 0x8651 -#define GL_VERTEX_ATTRIB_ARRAY2_NV 0x8652 -#define GL_VERTEX_ATTRIB_ARRAY3_NV 0x8653 -#define GL_VERTEX_ATTRIB_ARRAY4_NV 0x8654 -#define GL_VERTEX_ATTRIB_ARRAY5_NV 0x8655 -#define GL_VERTEX_ATTRIB_ARRAY6_NV 0x8656 -#define GL_VERTEX_ATTRIB_ARRAY7_NV 0x8657 -#define GL_VERTEX_ATTRIB_ARRAY8_NV 0x8658 -#define GL_VERTEX_ATTRIB_ARRAY9_NV 0x8659 -#define GL_VERTEX_ATTRIB_ARRAY10_NV 0x865A -#define GL_VERTEX_ATTRIB_ARRAY11_NV 0x865B -#define GL_VERTEX_ATTRIB_ARRAY12_NV 0x865C -#define GL_VERTEX_ATTRIB_ARRAY13_NV 0x865D -#define GL_VERTEX_ATTRIB_ARRAY14_NV 0x865E -#define GL_VERTEX_ATTRIB_ARRAY15_NV 0x865F -#define GL_MAP1_VERTEX_ATTRIB0_4_NV 0x8660 -#define GL_MAP1_VERTEX_ATTRIB1_4_NV 0x8661 -#define GL_MAP1_VERTEX_ATTRIB2_4_NV 0x8662 -#define GL_MAP1_VERTEX_ATTRIB3_4_NV 0x8663 -#define GL_MAP1_VERTEX_ATTRIB4_4_NV 0x8664 -#define GL_MAP1_VERTEX_ATTRIB5_4_NV 0x8665 -#define GL_MAP1_VERTEX_ATTRIB6_4_NV 0x8666 -#define GL_MAP1_VERTEX_ATTRIB7_4_NV 0x8667 -#define GL_MAP1_VERTEX_ATTRIB8_4_NV 0x8668 -#define GL_MAP1_VERTEX_ATTRIB9_4_NV 0x8669 -#define GL_MAP1_VERTEX_ATTRIB10_4_NV 0x866A -#define GL_MAP1_VERTEX_ATTRIB11_4_NV 0x866B -#define GL_MAP1_VERTEX_ATTRIB12_4_NV 0x866C -#define GL_MAP1_VERTEX_ATTRIB13_4_NV 0x866D -#define GL_MAP1_VERTEX_ATTRIB14_4_NV 0x866E -#define GL_MAP1_VERTEX_ATTRIB15_4_NV 0x866F -#define GL_MAP2_VERTEX_ATTRIB0_4_NV 0x8670 -#define GL_MAP2_VERTEX_ATTRIB1_4_NV 0x8671 -#define GL_MAP2_VERTEX_ATTRIB2_4_NV 0x8672 -#define GL_MAP2_VERTEX_ATTRIB3_4_NV 0x8673 -#define GL_MAP2_VERTEX_ATTRIB4_4_NV 0x8674 -#define GL_MAP2_VERTEX_ATTRIB5_4_NV 0x8675 -#define GL_MAP2_VERTEX_ATTRIB6_4_NV 0x8676 -#define GL_MAP2_VERTEX_ATTRIB7_4_NV 0x8677 -#define GL_MAP2_VERTEX_ATTRIB8_4_NV 0x8678 -#define GL_MAP2_VERTEX_ATTRIB9_4_NV 0x8679 -#define GL_MAP2_VERTEX_ATTRIB10_4_NV 0x867A -#define GL_MAP2_VERTEX_ATTRIB11_4_NV 0x867B -#define GL_MAP2_VERTEX_ATTRIB12_4_NV 0x867C -#define GL_MAP2_VERTEX_ATTRIB13_4_NV 0x867D -#define GL_MAP2_VERTEX_ATTRIB14_4_NV 0x867E -#define GL_MAP2_VERTEX_ATTRIB15_4_NV 0x867F -typedef GLboolean (APIENTRYP PFNGLAREPROGRAMSRESIDENTNVPROC) (GLsizei n, const GLuint *programs, GLboolean *residences); -typedef void (APIENTRYP PFNGLBINDPROGRAMNVPROC) (GLenum target, GLuint id); -typedef void (APIENTRYP PFNGLDELETEPROGRAMSNVPROC) (GLsizei n, const GLuint *programs); -typedef void (APIENTRYP PFNGLEXECUTEPROGRAMNVPROC) (GLenum target, GLuint id, const GLfloat *params); -typedef void (APIENTRYP PFNGLGENPROGRAMSNVPROC) (GLsizei n, GLuint *programs); -typedef void (APIENTRYP PFNGLGETPROGRAMPARAMETERDVNVPROC) (GLenum target, GLuint index, GLenum pname, GLdouble *params); -typedef void (APIENTRYP PFNGLGETPROGRAMPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETPROGRAMIVNVPROC) (GLuint id, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETPROGRAMSTRINGNVPROC) (GLuint id, GLenum pname, GLubyte *program); -typedef void (APIENTRYP PFNGLGETTRACKMATRIXIVNVPROC) (GLenum target, GLuint address, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVNVPROC) (GLuint index, GLenum pname, GLdouble *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVNVPROC) (GLuint index, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVNVPROC) (GLuint index, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVNVPROC) (GLuint index, GLenum pname, void **pointer); -typedef GLboolean (APIENTRYP PFNGLISPROGRAMNVPROC) (GLuint id); -typedef void (APIENTRYP PFNGLLOADPROGRAMNVPROC) (GLenum target, GLuint id, GLsizei len, const GLubyte *program); -typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4DNVPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4DVNVPROC) (GLenum target, GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4FNVPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4FVNVPROC) (GLenum target, GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLPROGRAMPARAMETERS4DVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLdouble *v); -typedef void (APIENTRYP PFNGLPROGRAMPARAMETERS4FVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat *v); -typedef void (APIENTRYP PFNGLREQUESTRESIDENTPROGRAMSNVPROC) (GLsizei n, const GLuint *programs); -typedef void (APIENTRYP PFNGLTRACKMATRIXNVPROC) (GLenum target, GLuint address, GLenum matrix, GLenum transform); -typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERNVPROC) (GLuint index, GLint fsize, GLenum type, GLsizei stride, const void *pointer); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1DNVPROC) (GLuint index, GLdouble x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVNVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1FNVPROC) (GLuint index, GLfloat x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVNVPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1SNVPROC) (GLuint index, GLshort x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVNVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2DNVPROC) (GLuint index, GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVNVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2FNVPROC) (GLuint index, GLfloat x, GLfloat y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVNVPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2SNVPROC) (GLuint index, GLshort x, GLshort y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVNVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVNVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVNVPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVNVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVNVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVNVPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVNVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBNVPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVNVPROC) (GLuint index, const GLubyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS1DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS1FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS1SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS2DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS2FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS2SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS3DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS3FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS3SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS4DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS4FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS4SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS4UBVNVPROC) (GLuint index, GLsizei count, const GLubyte *v); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLboolean APIENTRY glAreProgramsResidentNV (GLsizei n, const GLuint *programs, GLboolean *residences); -GLAPI void APIENTRY glBindProgramNV (GLenum target, GLuint id); -GLAPI void APIENTRY glDeleteProgramsNV (GLsizei n, const GLuint *programs); -GLAPI void APIENTRY glExecuteProgramNV (GLenum target, GLuint id, const GLfloat *params); -GLAPI void APIENTRY glGenProgramsNV (GLsizei n, GLuint *programs); -GLAPI void APIENTRY glGetProgramParameterdvNV (GLenum target, GLuint index, GLenum pname, GLdouble *params); -GLAPI void APIENTRY glGetProgramParameterfvNV (GLenum target, GLuint index, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetProgramivNV (GLuint id, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetProgramStringNV (GLuint id, GLenum pname, GLubyte *program); -GLAPI void APIENTRY glGetTrackMatrixivNV (GLenum target, GLuint address, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetVertexAttribdvNV (GLuint index, GLenum pname, GLdouble *params); -GLAPI void APIENTRY glGetVertexAttribfvNV (GLuint index, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetVertexAttribivNV (GLuint index, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetVertexAttribPointervNV (GLuint index, GLenum pname, void **pointer); -GLAPI GLboolean APIENTRY glIsProgramNV (GLuint id); -GLAPI void APIENTRY glLoadProgramNV (GLenum target, GLuint id, GLsizei len, const GLubyte *program); -GLAPI void APIENTRY glProgramParameter4dNV (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void APIENTRY glProgramParameter4dvNV (GLenum target, GLuint index, const GLdouble *v); -GLAPI void APIENTRY glProgramParameter4fNV (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI void APIENTRY glProgramParameter4fvNV (GLenum target, GLuint index, const GLfloat *v); -GLAPI void APIENTRY glProgramParameters4dvNV (GLenum target, GLuint index, GLsizei count, const GLdouble *v); -GLAPI void APIENTRY glProgramParameters4fvNV (GLenum target, GLuint index, GLsizei count, const GLfloat *v); -GLAPI void APIENTRY glRequestResidentProgramsNV (GLsizei n, const GLuint *programs); -GLAPI void APIENTRY glTrackMatrixNV (GLenum target, GLuint address, GLenum matrix, GLenum transform); -GLAPI void APIENTRY glVertexAttribPointerNV (GLuint index, GLint fsize, GLenum type, GLsizei stride, const void *pointer); -GLAPI void APIENTRY glVertexAttrib1dNV (GLuint index, GLdouble x); -GLAPI void APIENTRY glVertexAttrib1dvNV (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttrib1fNV (GLuint index, GLfloat x); -GLAPI void APIENTRY glVertexAttrib1fvNV (GLuint index, const GLfloat *v); -GLAPI void APIENTRY glVertexAttrib1sNV (GLuint index, GLshort x); -GLAPI void APIENTRY glVertexAttrib1svNV (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttrib2dNV (GLuint index, GLdouble x, GLdouble y); -GLAPI void APIENTRY glVertexAttrib2dvNV (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttrib2fNV (GLuint index, GLfloat x, GLfloat y); -GLAPI void APIENTRY glVertexAttrib2fvNV (GLuint index, const GLfloat *v); -GLAPI void APIENTRY glVertexAttrib2sNV (GLuint index, GLshort x, GLshort y); -GLAPI void APIENTRY glVertexAttrib2svNV (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttrib3dNV (GLuint index, GLdouble x, GLdouble y, GLdouble z); -GLAPI void APIENTRY glVertexAttrib3dvNV (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttrib3fNV (GLuint index, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glVertexAttrib3fvNV (GLuint index, const GLfloat *v); -GLAPI void APIENTRY glVertexAttrib3sNV (GLuint index, GLshort x, GLshort y, GLshort z); -GLAPI void APIENTRY glVertexAttrib3svNV (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttrib4dNV (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void APIENTRY glVertexAttrib4dvNV (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttrib4fNV (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI void APIENTRY glVertexAttrib4fvNV (GLuint index, const GLfloat *v); -GLAPI void APIENTRY glVertexAttrib4sNV (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); -GLAPI void APIENTRY glVertexAttrib4svNV (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttrib4ubNV (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); -GLAPI void APIENTRY glVertexAttrib4ubvNV (GLuint index, const GLubyte *v); -GLAPI void APIENTRY glVertexAttribs1dvNV (GLuint index, GLsizei count, const GLdouble *v); -GLAPI void APIENTRY glVertexAttribs1fvNV (GLuint index, GLsizei count, const GLfloat *v); -GLAPI void APIENTRY glVertexAttribs1svNV (GLuint index, GLsizei count, const GLshort *v); -GLAPI void APIENTRY glVertexAttribs2dvNV (GLuint index, GLsizei count, const GLdouble *v); -GLAPI void APIENTRY glVertexAttribs2fvNV (GLuint index, GLsizei count, const GLfloat *v); -GLAPI void APIENTRY glVertexAttribs2svNV (GLuint index, GLsizei count, const GLshort *v); -GLAPI void APIENTRY glVertexAttribs3dvNV (GLuint index, GLsizei count, const GLdouble *v); -GLAPI void APIENTRY glVertexAttribs3fvNV (GLuint index, GLsizei count, const GLfloat *v); -GLAPI void APIENTRY glVertexAttribs3svNV (GLuint index, GLsizei count, const GLshort *v); -GLAPI void APIENTRY glVertexAttribs4dvNV (GLuint index, GLsizei count, const GLdouble *v); -GLAPI void APIENTRY glVertexAttribs4fvNV (GLuint index, GLsizei count, const GLfloat *v); -GLAPI void APIENTRY glVertexAttribs4svNV (GLuint index, GLsizei count, const GLshort *v); -GLAPI void APIENTRY glVertexAttribs4ubvNV (GLuint index, GLsizei count, const GLubyte *v); -#endif -#endif /* GL_NV_vertex_program */ - -#ifndef GL_NV_vertex_program1_1 -#define GL_NV_vertex_program1_1 1 -#endif /* GL_NV_vertex_program1_1 */ - -#ifndef GL_NV_vertex_program2 -#define GL_NV_vertex_program2 1 -#endif /* GL_NV_vertex_program2 */ - -#ifndef GL_NV_vertex_program2_option -#define GL_NV_vertex_program2_option 1 -#endif /* GL_NV_vertex_program2_option */ - -#ifndef GL_NV_vertex_program3 -#define GL_NV_vertex_program3 1 -#endif /* GL_NV_vertex_program3 */ - -#ifndef GL_NV_vertex_program4 -#define GL_NV_vertex_program4 1 -#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_NV 0x88FD -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IEXTPROC) (GLuint index, GLint x); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IEXTPROC) (GLuint index, GLint x, GLint y); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IEXTPROC) (GLuint index, GLint x, GLint y, GLint z); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IEXTPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIEXTPROC) (GLuint index, GLuint x); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIEXTPROC) (GLuint index, GLuint x, GLuint y); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IVEXTPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IVEXTPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IVEXTPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IVEXTPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIVEXTPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIVEXTPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIVEXTPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIVEXTPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4BVEXTPROC) (GLuint index, const GLbyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4SVEXTPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UBVEXTPROC) (GLuint index, const GLubyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4USVEXTPROC) (GLuint index, const GLushort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVEXTPROC) (GLuint index, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVEXTPROC) (GLuint index, GLenum pname, GLuint *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexAttribI1iEXT (GLuint index, GLint x); -GLAPI void APIENTRY glVertexAttribI2iEXT (GLuint index, GLint x, GLint y); -GLAPI void APIENTRY glVertexAttribI3iEXT (GLuint index, GLint x, GLint y, GLint z); -GLAPI void APIENTRY glVertexAttribI4iEXT (GLuint index, GLint x, GLint y, GLint z, GLint w); -GLAPI void APIENTRY glVertexAttribI1uiEXT (GLuint index, GLuint x); -GLAPI void APIENTRY glVertexAttribI2uiEXT (GLuint index, GLuint x, GLuint y); -GLAPI void APIENTRY glVertexAttribI3uiEXT (GLuint index, GLuint x, GLuint y, GLuint z); -GLAPI void APIENTRY glVertexAttribI4uiEXT (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -GLAPI void APIENTRY glVertexAttribI1ivEXT (GLuint index, const GLint *v); -GLAPI void APIENTRY glVertexAttribI2ivEXT (GLuint index, const GLint *v); -GLAPI void APIENTRY glVertexAttribI3ivEXT (GLuint index, const GLint *v); -GLAPI void APIENTRY glVertexAttribI4ivEXT (GLuint index, const GLint *v); -GLAPI void APIENTRY glVertexAttribI1uivEXT (GLuint index, const GLuint *v); -GLAPI void APIENTRY glVertexAttribI2uivEXT (GLuint index, const GLuint *v); -GLAPI void APIENTRY glVertexAttribI3uivEXT (GLuint index, const GLuint *v); -GLAPI void APIENTRY glVertexAttribI4uivEXT (GLuint index, const GLuint *v); -GLAPI void APIENTRY glVertexAttribI4bvEXT (GLuint index, const GLbyte *v); -GLAPI void APIENTRY glVertexAttribI4svEXT (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttribI4ubvEXT (GLuint index, const GLubyte *v); -GLAPI void APIENTRY glVertexAttribI4usvEXT (GLuint index, const GLushort *v); -GLAPI void APIENTRY glVertexAttribIPointerEXT (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); -GLAPI void APIENTRY glGetVertexAttribIivEXT (GLuint index, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetVertexAttribIuivEXT (GLuint index, GLenum pname, GLuint *params); -#endif -#endif /* GL_NV_vertex_program4 */ - -#ifndef GL_NV_video_capture -#define GL_NV_video_capture 1 -#define GL_VIDEO_BUFFER_NV 0x9020 -#define GL_VIDEO_BUFFER_BINDING_NV 0x9021 -#define GL_FIELD_UPPER_NV 0x9022 -#define GL_FIELD_LOWER_NV 0x9023 -#define GL_NUM_VIDEO_CAPTURE_STREAMS_NV 0x9024 -#define GL_NEXT_VIDEO_CAPTURE_BUFFER_STATUS_NV 0x9025 -#define GL_VIDEO_CAPTURE_TO_422_SUPPORTED_NV 0x9026 -#define GL_LAST_VIDEO_CAPTURE_STATUS_NV 0x9027 -#define GL_VIDEO_BUFFER_PITCH_NV 0x9028 -#define GL_VIDEO_COLOR_CONVERSION_MATRIX_NV 0x9029 -#define GL_VIDEO_COLOR_CONVERSION_MAX_NV 0x902A -#define GL_VIDEO_COLOR_CONVERSION_MIN_NV 0x902B -#define GL_VIDEO_COLOR_CONVERSION_OFFSET_NV 0x902C -#define GL_VIDEO_BUFFER_INTERNAL_FORMAT_NV 0x902D -#define GL_PARTIAL_SUCCESS_NV 0x902E -#define GL_SUCCESS_NV 0x902F -#define GL_FAILURE_NV 0x9030 -#define GL_YCBYCR8_422_NV 0x9031 -#define GL_YCBAYCR8A_4224_NV 0x9032 -#define GL_Z6Y10Z6CB10Z6Y10Z6CR10_422_NV 0x9033 -#define GL_Z6Y10Z6CB10Z6A10Z6Y10Z6CR10Z6A10_4224_NV 0x9034 -#define GL_Z4Y12Z4CB12Z4Y12Z4CR12_422_NV 0x9035 -#define GL_Z4Y12Z4CB12Z4A12Z4Y12Z4CR12Z4A12_4224_NV 0x9036 -#define GL_Z4Y12Z4CB12Z4CR12_444_NV 0x9037 -#define GL_VIDEO_CAPTURE_FRAME_WIDTH_NV 0x9038 -#define GL_VIDEO_CAPTURE_FRAME_HEIGHT_NV 0x9039 -#define GL_VIDEO_CAPTURE_FIELD_UPPER_HEIGHT_NV 0x903A -#define GL_VIDEO_CAPTURE_FIELD_LOWER_HEIGHT_NV 0x903B -#define GL_VIDEO_CAPTURE_SURFACE_ORIGIN_NV 0x903C -typedef void (APIENTRYP PFNGLBEGINVIDEOCAPTURENVPROC) (GLuint video_capture_slot); -typedef void (APIENTRYP PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLintptrARB offset); -typedef void (APIENTRYP PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC) (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLenum target, GLuint texture); -typedef void (APIENTRYP PFNGLENDVIDEOCAPTURENVPROC) (GLuint video_capture_slot); -typedef void (APIENTRYP PFNGLGETVIDEOCAPTUREIVNVPROC) (GLuint video_capture_slot, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETVIDEOCAPTURESTREAMIVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETVIDEOCAPTURESTREAMFVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETVIDEOCAPTURESTREAMDVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLdouble *params); -typedef GLenum (APIENTRYP PFNGLVIDEOCAPTURENVPROC) (GLuint video_capture_slot, GLuint *sequence_num, GLuint64EXT *capture_time); -typedef void (APIENTRYP PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLdouble *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBeginVideoCaptureNV (GLuint video_capture_slot); -GLAPI void APIENTRY glBindVideoCaptureStreamBufferNV (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLintptrARB offset); -GLAPI void APIENTRY glBindVideoCaptureStreamTextureNV (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLenum target, GLuint texture); -GLAPI void APIENTRY glEndVideoCaptureNV (GLuint video_capture_slot); -GLAPI void APIENTRY glGetVideoCaptureivNV (GLuint video_capture_slot, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetVideoCaptureStreamivNV (GLuint video_capture_slot, GLuint stream, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetVideoCaptureStreamfvNV (GLuint video_capture_slot, GLuint stream, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetVideoCaptureStreamdvNV (GLuint video_capture_slot, GLuint stream, GLenum pname, GLdouble *params); -GLAPI GLenum APIENTRY glVideoCaptureNV (GLuint video_capture_slot, GLuint *sequence_num, GLuint64EXT *capture_time); -GLAPI void APIENTRY glVideoCaptureStreamParameterivNV (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLint *params); -GLAPI void APIENTRY glVideoCaptureStreamParameterfvNV (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glVideoCaptureStreamParameterdvNV (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLdouble *params); -#endif -#endif /* GL_NV_video_capture */ - -#ifndef GL_OML_interlace -#define GL_OML_interlace 1 -#define GL_INTERLACE_OML 0x8980 -#define GL_INTERLACE_READ_OML 0x8981 -#endif /* GL_OML_interlace */ - -#ifndef GL_OML_resample -#define GL_OML_resample 1 -#define GL_PACK_RESAMPLE_OML 0x8984 -#define GL_UNPACK_RESAMPLE_OML 0x8985 -#define GL_RESAMPLE_REPLICATE_OML 0x8986 -#define GL_RESAMPLE_ZERO_FILL_OML 0x8987 -#define GL_RESAMPLE_AVERAGE_OML 0x8988 -#define GL_RESAMPLE_DECIMATE_OML 0x8989 -#endif /* GL_OML_resample */ - -#ifndef GL_OML_subsample -#define GL_OML_subsample 1 -#define GL_FORMAT_SUBSAMPLE_24_24_OML 0x8982 -#define GL_FORMAT_SUBSAMPLE_244_244_OML 0x8983 -#endif /* GL_OML_subsample */ - -#ifndef GL_PGI_misc_hints -#define GL_PGI_misc_hints 1 -#define GL_PREFER_DOUBLEBUFFER_HINT_PGI 0x1A1F8 -#define GL_CONSERVE_MEMORY_HINT_PGI 0x1A1FD -#define GL_RECLAIM_MEMORY_HINT_PGI 0x1A1FE -#define GL_NATIVE_GRAPHICS_HANDLE_PGI 0x1A202 -#define GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI 0x1A203 -#define GL_NATIVE_GRAPHICS_END_HINT_PGI 0x1A204 -#define GL_ALWAYS_FAST_HINT_PGI 0x1A20C -#define GL_ALWAYS_SOFT_HINT_PGI 0x1A20D -#define GL_ALLOW_DRAW_OBJ_HINT_PGI 0x1A20E -#define GL_ALLOW_DRAW_WIN_HINT_PGI 0x1A20F -#define GL_ALLOW_DRAW_FRG_HINT_PGI 0x1A210 -#define GL_ALLOW_DRAW_MEM_HINT_PGI 0x1A211 -#define GL_STRICT_DEPTHFUNC_HINT_PGI 0x1A216 -#define GL_STRICT_LIGHTING_HINT_PGI 0x1A217 -#define GL_STRICT_SCISSOR_HINT_PGI 0x1A218 -#define GL_FULL_STIPPLE_HINT_PGI 0x1A219 -#define GL_CLIP_NEAR_HINT_PGI 0x1A220 -#define GL_CLIP_FAR_HINT_PGI 0x1A221 -#define GL_WIDE_LINE_HINT_PGI 0x1A222 -#define GL_BACK_NORMALS_HINT_PGI 0x1A223 -typedef void (APIENTRYP PFNGLHINTPGIPROC) (GLenum target, GLint mode); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glHintPGI (GLenum target, GLint mode); -#endif -#endif /* GL_PGI_misc_hints */ - -#ifndef GL_PGI_vertex_hints -#define GL_PGI_vertex_hints 1 -#define GL_VERTEX_DATA_HINT_PGI 0x1A22A -#define GL_VERTEX_CONSISTENT_HINT_PGI 0x1A22B -#define GL_MATERIAL_SIDE_HINT_PGI 0x1A22C -#define GL_MAX_VERTEX_HINT_PGI 0x1A22D -#define GL_COLOR3_BIT_PGI 0x00010000 -#define GL_COLOR4_BIT_PGI 0x00020000 -#define GL_EDGEFLAG_BIT_PGI 0x00040000 -#define GL_INDEX_BIT_PGI 0x00080000 -#define GL_MAT_AMBIENT_BIT_PGI 0x00100000 -#define GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI 0x00200000 -#define GL_MAT_DIFFUSE_BIT_PGI 0x00400000 -#define GL_MAT_EMISSION_BIT_PGI 0x00800000 -#define GL_MAT_COLOR_INDEXES_BIT_PGI 0x01000000 -#define GL_MAT_SHININESS_BIT_PGI 0x02000000 -#define GL_MAT_SPECULAR_BIT_PGI 0x04000000 -#define GL_NORMAL_BIT_PGI 0x08000000 -#define GL_TEXCOORD1_BIT_PGI 0x10000000 -#define GL_TEXCOORD2_BIT_PGI 0x20000000 -#define GL_TEXCOORD3_BIT_PGI 0x40000000 -#define GL_TEXCOORD4_BIT_PGI 0x80000000 -#define GL_VERTEX23_BIT_PGI 0x00000004 -#define GL_VERTEX4_BIT_PGI 0x00000008 -#endif /* GL_PGI_vertex_hints */ - -#ifndef GL_REND_screen_coordinates -#define GL_REND_screen_coordinates 1 -#define GL_SCREEN_COORDINATES_REND 0x8490 -#define GL_INVERTED_SCREEN_W_REND 0x8491 -#endif /* GL_REND_screen_coordinates */ - -#ifndef GL_S3_s3tc -#define GL_S3_s3tc 1 -#define GL_RGB_S3TC 0x83A0 -#define GL_RGB4_S3TC 0x83A1 -#define GL_RGBA_S3TC 0x83A2 -#define GL_RGBA4_S3TC 0x83A3 -#define GL_RGBA_DXT5_S3TC 0x83A4 -#define GL_RGBA4_DXT5_S3TC 0x83A5 -#endif /* GL_S3_s3tc */ - -#ifndef GL_SGIS_detail_texture -#define GL_SGIS_detail_texture 1 -#define GL_DETAIL_TEXTURE_2D_SGIS 0x8095 -#define GL_DETAIL_TEXTURE_2D_BINDING_SGIS 0x8096 -#define GL_LINEAR_DETAIL_SGIS 0x8097 -#define GL_LINEAR_DETAIL_ALPHA_SGIS 0x8098 -#define GL_LINEAR_DETAIL_COLOR_SGIS 0x8099 -#define GL_DETAIL_TEXTURE_LEVEL_SGIS 0x809A -#define GL_DETAIL_TEXTURE_MODE_SGIS 0x809B -#define GL_DETAIL_TEXTURE_FUNC_POINTS_SGIS 0x809C -typedef void (APIENTRYP PFNGLDETAILTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points); -typedef void (APIENTRYP PFNGLGETDETAILTEXFUNCSGISPROC) (GLenum target, GLfloat *points); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDetailTexFuncSGIS (GLenum target, GLsizei n, const GLfloat *points); -GLAPI void APIENTRY glGetDetailTexFuncSGIS (GLenum target, GLfloat *points); -#endif -#endif /* GL_SGIS_detail_texture */ - -#ifndef GL_SGIS_fog_function -#define GL_SGIS_fog_function 1 -#define GL_FOG_FUNC_SGIS 0x812A -#define GL_FOG_FUNC_POINTS_SGIS 0x812B -#define GL_MAX_FOG_FUNC_POINTS_SGIS 0x812C -typedef void (APIENTRYP PFNGLFOGFUNCSGISPROC) (GLsizei n, const GLfloat *points); -typedef void (APIENTRYP PFNGLGETFOGFUNCSGISPROC) (GLfloat *points); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFogFuncSGIS (GLsizei n, const GLfloat *points); -GLAPI void APIENTRY glGetFogFuncSGIS (GLfloat *points); -#endif -#endif /* GL_SGIS_fog_function */ - -#ifndef GL_SGIS_generate_mipmap -#define GL_SGIS_generate_mipmap 1 -#define GL_GENERATE_MIPMAP_SGIS 0x8191 -#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192 -#endif /* GL_SGIS_generate_mipmap */ - -#ifndef GL_SGIS_multisample -#define GL_SGIS_multisample 1 -#define GL_MULTISAMPLE_SGIS 0x809D -#define GL_SAMPLE_ALPHA_TO_MASK_SGIS 0x809E -#define GL_SAMPLE_ALPHA_TO_ONE_SGIS 0x809F -#define GL_SAMPLE_MASK_SGIS 0x80A0 -#define GL_1PASS_SGIS 0x80A1 -#define GL_2PASS_0_SGIS 0x80A2 -#define GL_2PASS_1_SGIS 0x80A3 -#define GL_4PASS_0_SGIS 0x80A4 -#define GL_4PASS_1_SGIS 0x80A5 -#define GL_4PASS_2_SGIS 0x80A6 -#define GL_4PASS_3_SGIS 0x80A7 -#define GL_SAMPLE_BUFFERS_SGIS 0x80A8 -#define GL_SAMPLES_SGIS 0x80A9 -#define GL_SAMPLE_MASK_VALUE_SGIS 0x80AA -#define GL_SAMPLE_MASK_INVERT_SGIS 0x80AB -#define GL_SAMPLE_PATTERN_SGIS 0x80AC -typedef void (APIENTRYP PFNGLSAMPLEMASKSGISPROC) (GLclampf value, GLboolean invert); -typedef void (APIENTRYP PFNGLSAMPLEPATTERNSGISPROC) (GLenum pattern); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glSampleMaskSGIS (GLclampf value, GLboolean invert); -GLAPI void APIENTRY glSamplePatternSGIS (GLenum pattern); -#endif -#endif /* GL_SGIS_multisample */ - -#ifndef GL_SGIS_pixel_texture -#define GL_SGIS_pixel_texture 1 -#define GL_PIXEL_TEXTURE_SGIS 0x8353 -#define GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS 0x8354 -#define GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS 0x8355 -#define GL_PIXEL_GROUP_COLOR_SGIS 0x8356 -typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERISGISPROC) (GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERFSGISPROC) (GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLGETPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, GLfloat *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPixelTexGenParameteriSGIS (GLenum pname, GLint param); -GLAPI void APIENTRY glPixelTexGenParameterivSGIS (GLenum pname, const GLint *params); -GLAPI void APIENTRY glPixelTexGenParameterfSGIS (GLenum pname, GLfloat param); -GLAPI void APIENTRY glPixelTexGenParameterfvSGIS (GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glGetPixelTexGenParameterivSGIS (GLenum pname, GLint *params); -GLAPI void APIENTRY glGetPixelTexGenParameterfvSGIS (GLenum pname, GLfloat *params); -#endif -#endif /* GL_SGIS_pixel_texture */ - -#ifndef GL_SGIS_point_line_texgen -#define GL_SGIS_point_line_texgen 1 -#define GL_EYE_DISTANCE_TO_POINT_SGIS 0x81F0 -#define GL_OBJECT_DISTANCE_TO_POINT_SGIS 0x81F1 -#define GL_EYE_DISTANCE_TO_LINE_SGIS 0x81F2 -#define GL_OBJECT_DISTANCE_TO_LINE_SGIS 0x81F3 -#define GL_EYE_POINT_SGIS 0x81F4 -#define GL_OBJECT_POINT_SGIS 0x81F5 -#define GL_EYE_LINE_SGIS 0x81F6 -#define GL_OBJECT_LINE_SGIS 0x81F7 -#endif /* GL_SGIS_point_line_texgen */ - -#ifndef GL_SGIS_point_parameters -#define GL_SGIS_point_parameters 1 -#define GL_POINT_SIZE_MIN_SGIS 0x8126 -#define GL_POINT_SIZE_MAX_SGIS 0x8127 -#define GL_POINT_FADE_THRESHOLD_SIZE_SGIS 0x8128 -#define GL_DISTANCE_ATTENUATION_SGIS 0x8129 -typedef void (APIENTRYP PFNGLPOINTPARAMETERFSGISPROC) (GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLPOINTPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPointParameterfSGIS (GLenum pname, GLfloat param); -GLAPI void APIENTRY glPointParameterfvSGIS (GLenum pname, const GLfloat *params); -#endif -#endif /* GL_SGIS_point_parameters */ - -#ifndef GL_SGIS_sharpen_texture -#define GL_SGIS_sharpen_texture 1 -#define GL_LINEAR_SHARPEN_SGIS 0x80AD -#define GL_LINEAR_SHARPEN_ALPHA_SGIS 0x80AE -#define GL_LINEAR_SHARPEN_COLOR_SGIS 0x80AF -#define GL_SHARPEN_TEXTURE_FUNC_POINTS_SGIS 0x80B0 -typedef void (APIENTRYP PFNGLSHARPENTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points); -typedef void (APIENTRYP PFNGLGETSHARPENTEXFUNCSGISPROC) (GLenum target, GLfloat *points); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glSharpenTexFuncSGIS (GLenum target, GLsizei n, const GLfloat *points); -GLAPI void APIENTRY glGetSharpenTexFuncSGIS (GLenum target, GLfloat *points); -#endif -#endif /* GL_SGIS_sharpen_texture */ - -#ifndef GL_SGIS_texture4D -#define GL_SGIS_texture4D 1 -#define GL_PACK_SKIP_VOLUMES_SGIS 0x8130 -#define GL_PACK_IMAGE_DEPTH_SGIS 0x8131 -#define GL_UNPACK_SKIP_VOLUMES_SGIS 0x8132 -#define GL_UNPACK_IMAGE_DEPTH_SGIS 0x8133 -#define GL_TEXTURE_4D_SGIS 0x8134 -#define GL_PROXY_TEXTURE_4D_SGIS 0x8135 -#define GL_TEXTURE_4DSIZE_SGIS 0x8136 -#define GL_TEXTURE_WRAP_Q_SGIS 0x8137 -#define GL_MAX_4D_TEXTURE_SIZE_SGIS 0x8138 -#define GL_TEXTURE_4D_BINDING_SGIS 0x814F -typedef void (APIENTRYP PFNGLTEXIMAGE4DSGISPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLint border, GLenum format, GLenum type, const void *pixels); -typedef void (APIENTRYP PFNGLTEXSUBIMAGE4DSGISPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLenum format, GLenum type, const void *pixels); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTexImage4DSGIS (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLint border, GLenum format, GLenum type, const void *pixels); -GLAPI void APIENTRY glTexSubImage4DSGIS (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLenum format, GLenum type, const void *pixels); -#endif -#endif /* GL_SGIS_texture4D */ - -#ifndef GL_SGIS_texture_border_clamp -#define GL_SGIS_texture_border_clamp 1 -#define GL_CLAMP_TO_BORDER_SGIS 0x812D -#endif /* GL_SGIS_texture_border_clamp */ - -#ifndef GL_SGIS_texture_color_mask -#define GL_SGIS_texture_color_mask 1 -#define GL_TEXTURE_COLOR_WRITEMASK_SGIS 0x81EF -typedef void (APIENTRYP PFNGLTEXTURECOLORMASKSGISPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTextureColorMaskSGIS (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); -#endif -#endif /* GL_SGIS_texture_color_mask */ - -#ifndef GL_SGIS_texture_edge_clamp -#define GL_SGIS_texture_edge_clamp 1 -#define GL_CLAMP_TO_EDGE_SGIS 0x812F -#endif /* GL_SGIS_texture_edge_clamp */ - -#ifndef GL_SGIS_texture_filter4 -#define GL_SGIS_texture_filter4 1 -#define GL_FILTER4_SGIS 0x8146 -#define GL_TEXTURE_FILTER4_SIZE_SGIS 0x8147 -typedef void (APIENTRYP PFNGLGETTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLfloat *weights); -typedef void (APIENTRYP PFNGLTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLsizei n, const GLfloat *weights); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGetTexFilterFuncSGIS (GLenum target, GLenum filter, GLfloat *weights); -GLAPI void APIENTRY glTexFilterFuncSGIS (GLenum target, GLenum filter, GLsizei n, const GLfloat *weights); -#endif -#endif /* GL_SGIS_texture_filter4 */ - -#ifndef GL_SGIS_texture_lod -#define GL_SGIS_texture_lod 1 -#define GL_TEXTURE_MIN_LOD_SGIS 0x813A -#define GL_TEXTURE_MAX_LOD_SGIS 0x813B -#define GL_TEXTURE_BASE_LEVEL_SGIS 0x813C -#define GL_TEXTURE_MAX_LEVEL_SGIS 0x813D -#endif /* GL_SGIS_texture_lod */ - -#ifndef GL_SGIS_texture_select -#define GL_SGIS_texture_select 1 -#define GL_DUAL_ALPHA4_SGIS 0x8110 -#define GL_DUAL_ALPHA8_SGIS 0x8111 -#define GL_DUAL_ALPHA12_SGIS 0x8112 -#define GL_DUAL_ALPHA16_SGIS 0x8113 -#define GL_DUAL_LUMINANCE4_SGIS 0x8114 -#define GL_DUAL_LUMINANCE8_SGIS 0x8115 -#define GL_DUAL_LUMINANCE12_SGIS 0x8116 -#define GL_DUAL_LUMINANCE16_SGIS 0x8117 -#define GL_DUAL_INTENSITY4_SGIS 0x8118 -#define GL_DUAL_INTENSITY8_SGIS 0x8119 -#define GL_DUAL_INTENSITY12_SGIS 0x811A -#define GL_DUAL_INTENSITY16_SGIS 0x811B -#define GL_DUAL_LUMINANCE_ALPHA4_SGIS 0x811C -#define GL_DUAL_LUMINANCE_ALPHA8_SGIS 0x811D -#define GL_QUAD_ALPHA4_SGIS 0x811E -#define GL_QUAD_ALPHA8_SGIS 0x811F -#define GL_QUAD_LUMINANCE4_SGIS 0x8120 -#define GL_QUAD_LUMINANCE8_SGIS 0x8121 -#define GL_QUAD_INTENSITY4_SGIS 0x8122 -#define GL_QUAD_INTENSITY8_SGIS 0x8123 -#define GL_DUAL_TEXTURE_SELECT_SGIS 0x8124 -#define GL_QUAD_TEXTURE_SELECT_SGIS 0x8125 -#endif /* GL_SGIS_texture_select */ - -#ifndef GL_SGIX_async -#define GL_SGIX_async 1 -#define GL_ASYNC_MARKER_SGIX 0x8329 -typedef void (APIENTRYP PFNGLASYNCMARKERSGIXPROC) (GLuint marker); -typedef GLint (APIENTRYP PFNGLFINISHASYNCSGIXPROC) (GLuint *markerp); -typedef GLint (APIENTRYP PFNGLPOLLASYNCSGIXPROC) (GLuint *markerp); -typedef GLuint (APIENTRYP PFNGLGENASYNCMARKERSSGIXPROC) (GLsizei range); -typedef void (APIENTRYP PFNGLDELETEASYNCMARKERSSGIXPROC) (GLuint marker, GLsizei range); -typedef GLboolean (APIENTRYP PFNGLISASYNCMARKERSGIXPROC) (GLuint marker); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glAsyncMarkerSGIX (GLuint marker); -GLAPI GLint APIENTRY glFinishAsyncSGIX (GLuint *markerp); -GLAPI GLint APIENTRY glPollAsyncSGIX (GLuint *markerp); -GLAPI GLuint APIENTRY glGenAsyncMarkersSGIX (GLsizei range); -GLAPI void APIENTRY glDeleteAsyncMarkersSGIX (GLuint marker, GLsizei range); -GLAPI GLboolean APIENTRY glIsAsyncMarkerSGIX (GLuint marker); -#endif -#endif /* GL_SGIX_async */ - -#ifndef GL_SGIX_async_histogram -#define GL_SGIX_async_histogram 1 -#define GL_ASYNC_HISTOGRAM_SGIX 0x832C -#define GL_MAX_ASYNC_HISTOGRAM_SGIX 0x832D -#endif /* GL_SGIX_async_histogram */ - -#ifndef GL_SGIX_async_pixel -#define GL_SGIX_async_pixel 1 -#define GL_ASYNC_TEX_IMAGE_SGIX 0x835C -#define GL_ASYNC_DRAW_PIXELS_SGIX 0x835D -#define GL_ASYNC_READ_PIXELS_SGIX 0x835E -#define GL_MAX_ASYNC_TEX_IMAGE_SGIX 0x835F -#define GL_MAX_ASYNC_DRAW_PIXELS_SGIX 0x8360 -#define GL_MAX_ASYNC_READ_PIXELS_SGIX 0x8361 -#endif /* GL_SGIX_async_pixel */ - -#ifndef GL_SGIX_blend_alpha_minmax -#define GL_SGIX_blend_alpha_minmax 1 -#define GL_ALPHA_MIN_SGIX 0x8320 -#define GL_ALPHA_MAX_SGIX 0x8321 -#endif /* GL_SGIX_blend_alpha_minmax */ - -#ifndef GL_SGIX_calligraphic_fragment -#define GL_SGIX_calligraphic_fragment 1 -#define GL_CALLIGRAPHIC_FRAGMENT_SGIX 0x8183 -#endif /* GL_SGIX_calligraphic_fragment */ - -#ifndef GL_SGIX_clipmap -#define GL_SGIX_clipmap 1 -#define GL_LINEAR_CLIPMAP_LINEAR_SGIX 0x8170 -#define GL_TEXTURE_CLIPMAP_CENTER_SGIX 0x8171 -#define GL_TEXTURE_CLIPMAP_FRAME_SGIX 0x8172 -#define GL_TEXTURE_CLIPMAP_OFFSET_SGIX 0x8173 -#define GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8174 -#define GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX 0x8175 -#define GL_TEXTURE_CLIPMAP_DEPTH_SGIX 0x8176 -#define GL_MAX_CLIPMAP_DEPTH_SGIX 0x8177 -#define GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8178 -#define GL_NEAREST_CLIPMAP_NEAREST_SGIX 0x844D -#define GL_NEAREST_CLIPMAP_LINEAR_SGIX 0x844E -#define GL_LINEAR_CLIPMAP_NEAREST_SGIX 0x844F -#endif /* GL_SGIX_clipmap */ - -#ifndef GL_SGIX_convolution_accuracy -#define GL_SGIX_convolution_accuracy 1 -#define GL_CONVOLUTION_HINT_SGIX 0x8316 -#endif /* GL_SGIX_convolution_accuracy */ - -#ifndef GL_SGIX_depth_pass_instrument -#define GL_SGIX_depth_pass_instrument 1 -#endif /* GL_SGIX_depth_pass_instrument */ - -#ifndef GL_SGIX_depth_texture -#define GL_SGIX_depth_texture 1 -#define GL_DEPTH_COMPONENT16_SGIX 0x81A5 -#define GL_DEPTH_COMPONENT24_SGIX 0x81A6 -#define GL_DEPTH_COMPONENT32_SGIX 0x81A7 -#endif /* GL_SGIX_depth_texture */ - -#ifndef GL_SGIX_flush_raster -#define GL_SGIX_flush_raster 1 -typedef void (APIENTRYP PFNGLFLUSHRASTERSGIXPROC) (void); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFlushRasterSGIX (void); -#endif -#endif /* GL_SGIX_flush_raster */ - -#ifndef GL_SGIX_fog_offset -#define GL_SGIX_fog_offset 1 -#define GL_FOG_OFFSET_SGIX 0x8198 -#define GL_FOG_OFFSET_VALUE_SGIX 0x8199 -#endif /* GL_SGIX_fog_offset */ - -#ifndef GL_SGIX_fragment_lighting -#define GL_SGIX_fragment_lighting 1 -#define GL_FRAGMENT_LIGHTING_SGIX 0x8400 -#define GL_FRAGMENT_COLOR_MATERIAL_SGIX 0x8401 -#define GL_FRAGMENT_COLOR_MATERIAL_FACE_SGIX 0x8402 -#define GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_SGIX 0x8403 -#define GL_MAX_FRAGMENT_LIGHTS_SGIX 0x8404 -#define GL_MAX_ACTIVE_LIGHTS_SGIX 0x8405 -#define GL_CURRENT_RASTER_NORMAL_SGIX 0x8406 -#define GL_LIGHT_ENV_MODE_SGIX 0x8407 -#define GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_SGIX 0x8408 -#define GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_SGIX 0x8409 -#define GL_FRAGMENT_LIGHT_MODEL_AMBIENT_SGIX 0x840A -#define GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_SGIX 0x840B -#define GL_FRAGMENT_LIGHT0_SGIX 0x840C -#define GL_FRAGMENT_LIGHT1_SGIX 0x840D -#define GL_FRAGMENT_LIGHT2_SGIX 0x840E -#define GL_FRAGMENT_LIGHT3_SGIX 0x840F -#define GL_FRAGMENT_LIGHT4_SGIX 0x8410 -#define GL_FRAGMENT_LIGHT5_SGIX 0x8411 -#define GL_FRAGMENT_LIGHT6_SGIX 0x8412 -#define GL_FRAGMENT_LIGHT7_SGIX 0x8413 -typedef void (APIENTRYP PFNGLFRAGMENTCOLORMATERIALSGIXPROC) (GLenum face, GLenum mode); -typedef void (APIENTRYP PFNGLFRAGMENTLIGHTFSGIXPROC) (GLenum light, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLFRAGMENTLIGHTISGIXPROC) (GLenum light, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELFSGIXPROC) (GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELFVSGIXPROC) (GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELISGIXPROC) (GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELIVSGIXPROC) (GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLFRAGMENTMATERIALFSGIXPROC) (GLenum face, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLFRAGMENTMATERIALISGIXPROC) (GLenum face, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLGETFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLLIGHTENVISGIXPROC) (GLenum pname, GLint param); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFragmentColorMaterialSGIX (GLenum face, GLenum mode); -GLAPI void APIENTRY glFragmentLightfSGIX (GLenum light, GLenum pname, GLfloat param); -GLAPI void APIENTRY glFragmentLightfvSGIX (GLenum light, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glFragmentLightiSGIX (GLenum light, GLenum pname, GLint param); -GLAPI void APIENTRY glFragmentLightivSGIX (GLenum light, GLenum pname, const GLint *params); -GLAPI void APIENTRY glFragmentLightModelfSGIX (GLenum pname, GLfloat param); -GLAPI void APIENTRY glFragmentLightModelfvSGIX (GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glFragmentLightModeliSGIX (GLenum pname, GLint param); -GLAPI void APIENTRY glFragmentLightModelivSGIX (GLenum pname, const GLint *params); -GLAPI void APIENTRY glFragmentMaterialfSGIX (GLenum face, GLenum pname, GLfloat param); -GLAPI void APIENTRY glFragmentMaterialfvSGIX (GLenum face, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glFragmentMaterialiSGIX (GLenum face, GLenum pname, GLint param); -GLAPI void APIENTRY glFragmentMaterialivSGIX (GLenum face, GLenum pname, const GLint *params); -GLAPI void APIENTRY glGetFragmentLightfvSGIX (GLenum light, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetFragmentLightivSGIX (GLenum light, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetFragmentMaterialfvSGIX (GLenum face, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetFragmentMaterialivSGIX (GLenum face, GLenum pname, GLint *params); -GLAPI void APIENTRY glLightEnviSGIX (GLenum pname, GLint param); -#endif -#endif /* GL_SGIX_fragment_lighting */ - -#ifndef GL_SGIX_framezoom -#define GL_SGIX_framezoom 1 -#define GL_FRAMEZOOM_SGIX 0x818B -#define GL_FRAMEZOOM_FACTOR_SGIX 0x818C -#define GL_MAX_FRAMEZOOM_FACTOR_SGIX 0x818D -typedef void (APIENTRYP PFNGLFRAMEZOOMSGIXPROC) (GLint factor); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFrameZoomSGIX (GLint factor); -#endif -#endif /* GL_SGIX_framezoom */ - -#ifndef GL_SGIX_igloo_interface -#define GL_SGIX_igloo_interface 1 -typedef void (APIENTRYP PFNGLIGLOOINTERFACESGIXPROC) (GLenum pname, const void *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glIglooInterfaceSGIX (GLenum pname, const void *params); -#endif -#endif /* GL_SGIX_igloo_interface */ - -#ifndef GL_SGIX_instruments -#define GL_SGIX_instruments 1 -#define GL_INSTRUMENT_BUFFER_POINTER_SGIX 0x8180 -#define GL_INSTRUMENT_MEASUREMENTS_SGIX 0x8181 -typedef GLint (APIENTRYP PFNGLGETINSTRUMENTSSGIXPROC) (void); -typedef void (APIENTRYP PFNGLINSTRUMENTSBUFFERSGIXPROC) (GLsizei size, GLint *buffer); -typedef GLint (APIENTRYP PFNGLPOLLINSTRUMENTSSGIXPROC) (GLint *marker_p); -typedef void (APIENTRYP PFNGLREADINSTRUMENTSSGIXPROC) (GLint marker); -typedef void (APIENTRYP PFNGLSTARTINSTRUMENTSSGIXPROC) (void); -typedef void (APIENTRYP PFNGLSTOPINSTRUMENTSSGIXPROC) (GLint marker); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLint APIENTRY glGetInstrumentsSGIX (void); -GLAPI void APIENTRY glInstrumentsBufferSGIX (GLsizei size, GLint *buffer); -GLAPI GLint APIENTRY glPollInstrumentsSGIX (GLint *marker_p); -GLAPI void APIENTRY glReadInstrumentsSGIX (GLint marker); -GLAPI void APIENTRY glStartInstrumentsSGIX (void); -GLAPI void APIENTRY glStopInstrumentsSGIX (GLint marker); -#endif -#endif /* GL_SGIX_instruments */ - -#ifndef GL_SGIX_interlace -#define GL_SGIX_interlace 1 -#define GL_INTERLACE_SGIX 0x8094 -#endif /* GL_SGIX_interlace */ - -#ifndef GL_SGIX_ir_instrument1 -#define GL_SGIX_ir_instrument1 1 -#define GL_IR_INSTRUMENT1_SGIX 0x817F -#endif /* GL_SGIX_ir_instrument1 */ - -#ifndef GL_SGIX_list_priority -#define GL_SGIX_list_priority 1 -#define GL_LIST_PRIORITY_SGIX 0x8182 -typedef void (APIENTRYP PFNGLGETLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLLISTPARAMETERFSGIXPROC) (GLuint list, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLLISTPARAMETERISGIXPROC) (GLuint list, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, const GLint *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGetListParameterfvSGIX (GLuint list, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetListParameterivSGIX (GLuint list, GLenum pname, GLint *params); -GLAPI void APIENTRY glListParameterfSGIX (GLuint list, GLenum pname, GLfloat param); -GLAPI void APIENTRY glListParameterfvSGIX (GLuint list, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glListParameteriSGIX (GLuint list, GLenum pname, GLint param); -GLAPI void APIENTRY glListParameterivSGIX (GLuint list, GLenum pname, const GLint *params); -#endif -#endif /* GL_SGIX_list_priority */ - -#ifndef GL_SGIX_pixel_texture -#define GL_SGIX_pixel_texture 1 -#define GL_PIXEL_TEX_GEN_SGIX 0x8139 -#define GL_PIXEL_TEX_GEN_MODE_SGIX 0x832B -typedef void (APIENTRYP PFNGLPIXELTEXGENSGIXPROC) (GLenum mode); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPixelTexGenSGIX (GLenum mode); -#endif -#endif /* GL_SGIX_pixel_texture */ - -#ifndef GL_SGIX_pixel_tiles -#define GL_SGIX_pixel_tiles 1 -#define GL_PIXEL_TILE_BEST_ALIGNMENT_SGIX 0x813E -#define GL_PIXEL_TILE_CACHE_INCREMENT_SGIX 0x813F -#define GL_PIXEL_TILE_WIDTH_SGIX 0x8140 -#define GL_PIXEL_TILE_HEIGHT_SGIX 0x8141 -#define GL_PIXEL_TILE_GRID_WIDTH_SGIX 0x8142 -#define GL_PIXEL_TILE_GRID_HEIGHT_SGIX 0x8143 -#define GL_PIXEL_TILE_GRID_DEPTH_SGIX 0x8144 -#define GL_PIXEL_TILE_CACHE_SIZE_SGIX 0x8145 -#endif /* GL_SGIX_pixel_tiles */ - -#ifndef GL_SGIX_polynomial_ffd -#define GL_SGIX_polynomial_ffd 1 -#define GL_TEXTURE_DEFORMATION_BIT_SGIX 0x00000001 -#define GL_GEOMETRY_DEFORMATION_BIT_SGIX 0x00000002 -#define GL_GEOMETRY_DEFORMATION_SGIX 0x8194 -#define GL_TEXTURE_DEFORMATION_SGIX 0x8195 -#define GL_DEFORMATIONS_MASK_SGIX 0x8196 -#define GL_MAX_DEFORMATION_ORDER_SGIX 0x8197 -typedef void (APIENTRYP PFNGLDEFORMATIONMAP3DSGIXPROC) (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, GLdouble w1, GLdouble w2, GLint wstride, GLint worder, const GLdouble *points); -typedef void (APIENTRYP PFNGLDEFORMATIONMAP3FSGIXPROC) (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat w1, GLfloat w2, GLint wstride, GLint worder, const GLfloat *points); -typedef void (APIENTRYP PFNGLDEFORMSGIXPROC) (GLbitfield mask); -typedef void (APIENTRYP PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC) (GLbitfield mask); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDeformationMap3dSGIX (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, GLdouble w1, GLdouble w2, GLint wstride, GLint worder, const GLdouble *points); -GLAPI void APIENTRY glDeformationMap3fSGIX (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat w1, GLfloat w2, GLint wstride, GLint worder, const GLfloat *points); -GLAPI void APIENTRY glDeformSGIX (GLbitfield mask); -GLAPI void APIENTRY glLoadIdentityDeformationMapSGIX (GLbitfield mask); -#endif -#endif /* GL_SGIX_polynomial_ffd */ - -#ifndef GL_SGIX_reference_plane -#define GL_SGIX_reference_plane 1 -#define GL_REFERENCE_PLANE_SGIX 0x817D -#define GL_REFERENCE_PLANE_EQUATION_SGIX 0x817E -typedef void (APIENTRYP PFNGLREFERENCEPLANESGIXPROC) (const GLdouble *equation); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glReferencePlaneSGIX (const GLdouble *equation); -#endif -#endif /* GL_SGIX_reference_plane */ - -#ifndef GL_SGIX_resample -#define GL_SGIX_resample 1 -#define GL_PACK_RESAMPLE_SGIX 0x842C -#define GL_UNPACK_RESAMPLE_SGIX 0x842D -#define GL_RESAMPLE_REPLICATE_SGIX 0x842E -#define GL_RESAMPLE_ZERO_FILL_SGIX 0x842F -#define GL_RESAMPLE_DECIMATE_SGIX 0x8430 -#endif /* GL_SGIX_resample */ - -#ifndef GL_SGIX_scalebias_hint -#define GL_SGIX_scalebias_hint 1 -#define GL_SCALEBIAS_HINT_SGIX 0x8322 -#endif /* GL_SGIX_scalebias_hint */ - -#ifndef GL_SGIX_shadow -#define GL_SGIX_shadow 1 -#define GL_TEXTURE_COMPARE_SGIX 0x819A -#define GL_TEXTURE_COMPARE_OPERATOR_SGIX 0x819B -#define GL_TEXTURE_LEQUAL_R_SGIX 0x819C -#define GL_TEXTURE_GEQUAL_R_SGIX 0x819D -#endif /* GL_SGIX_shadow */ - -#ifndef GL_SGIX_shadow_ambient -#define GL_SGIX_shadow_ambient 1 -#define GL_SHADOW_AMBIENT_SGIX 0x80BF -#endif /* GL_SGIX_shadow_ambient */ - -#ifndef GL_SGIX_sprite -#define GL_SGIX_sprite 1 -#define GL_SPRITE_SGIX 0x8148 -#define GL_SPRITE_MODE_SGIX 0x8149 -#define GL_SPRITE_AXIS_SGIX 0x814A -#define GL_SPRITE_TRANSLATION_SGIX 0x814B -#define GL_SPRITE_AXIAL_SGIX 0x814C -#define GL_SPRITE_OBJECT_ALIGNED_SGIX 0x814D -#define GL_SPRITE_EYE_ALIGNED_SGIX 0x814E -typedef void (APIENTRYP PFNGLSPRITEPARAMETERFSGIXPROC) (GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLSPRITEPARAMETERFVSGIXPROC) (GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLSPRITEPARAMETERISGIXPROC) (GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLSPRITEPARAMETERIVSGIXPROC) (GLenum pname, const GLint *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glSpriteParameterfSGIX (GLenum pname, GLfloat param); -GLAPI void APIENTRY glSpriteParameterfvSGIX (GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glSpriteParameteriSGIX (GLenum pname, GLint param); -GLAPI void APIENTRY glSpriteParameterivSGIX (GLenum pname, const GLint *params); -#endif -#endif /* GL_SGIX_sprite */ - -#ifndef GL_SGIX_subsample -#define GL_SGIX_subsample 1 -#define GL_PACK_SUBSAMPLE_RATE_SGIX 0x85A0 -#define GL_UNPACK_SUBSAMPLE_RATE_SGIX 0x85A1 -#define GL_PIXEL_SUBSAMPLE_4444_SGIX 0x85A2 -#define GL_PIXEL_SUBSAMPLE_2424_SGIX 0x85A3 -#define GL_PIXEL_SUBSAMPLE_4242_SGIX 0x85A4 -#endif /* GL_SGIX_subsample */ - -#ifndef GL_SGIX_tag_sample_buffer -#define GL_SGIX_tag_sample_buffer 1 -typedef void (APIENTRYP PFNGLTAGSAMPLEBUFFERSGIXPROC) (void); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTagSampleBufferSGIX (void); -#endif -#endif /* GL_SGIX_tag_sample_buffer */ - -#ifndef GL_SGIX_texture_add_env -#define GL_SGIX_texture_add_env 1 -#define GL_TEXTURE_ENV_BIAS_SGIX 0x80BE -#endif /* GL_SGIX_texture_add_env */ - -#ifndef GL_SGIX_texture_coordinate_clamp -#define GL_SGIX_texture_coordinate_clamp 1 -#define GL_TEXTURE_MAX_CLAMP_S_SGIX 0x8369 -#define GL_TEXTURE_MAX_CLAMP_T_SGIX 0x836A -#define GL_TEXTURE_MAX_CLAMP_R_SGIX 0x836B -#endif /* GL_SGIX_texture_coordinate_clamp */ - -#ifndef GL_SGIX_texture_lod_bias -#define GL_SGIX_texture_lod_bias 1 -#define GL_TEXTURE_LOD_BIAS_S_SGIX 0x818E -#define GL_TEXTURE_LOD_BIAS_T_SGIX 0x818F -#define GL_TEXTURE_LOD_BIAS_R_SGIX 0x8190 -#endif /* GL_SGIX_texture_lod_bias */ - -#ifndef GL_SGIX_texture_multi_buffer -#define GL_SGIX_texture_multi_buffer 1 -#define GL_TEXTURE_MULTI_BUFFER_HINT_SGIX 0x812E -#endif /* GL_SGIX_texture_multi_buffer */ - -#ifndef GL_SGIX_texture_scale_bias -#define GL_SGIX_texture_scale_bias 1 -#define GL_POST_TEXTURE_FILTER_BIAS_SGIX 0x8179 -#define GL_POST_TEXTURE_FILTER_SCALE_SGIX 0x817A -#define GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX 0x817B -#define GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX 0x817C -#endif /* GL_SGIX_texture_scale_bias */ - -#ifndef GL_SGIX_vertex_preclip -#define GL_SGIX_vertex_preclip 1 -#define GL_VERTEX_PRECLIP_SGIX 0x83EE -#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF -#endif /* GL_SGIX_vertex_preclip */ - -#ifndef GL_SGIX_ycrcb -#define GL_SGIX_ycrcb 1 -#define GL_YCRCB_422_SGIX 0x81BB -#define GL_YCRCB_444_SGIX 0x81BC -#endif /* GL_SGIX_ycrcb */ - -#ifndef GL_SGIX_ycrcb_subsample -#define GL_SGIX_ycrcb_subsample 1 -#endif /* GL_SGIX_ycrcb_subsample */ - -#ifndef GL_SGIX_ycrcba -#define GL_SGIX_ycrcba 1 -#define GL_YCRCB_SGIX 0x8318 -#define GL_YCRCBA_SGIX 0x8319 -#endif /* GL_SGIX_ycrcba */ - -#ifndef GL_SGI_color_matrix -#define GL_SGI_color_matrix 1 -#define GL_COLOR_MATRIX_SGI 0x80B1 -#define GL_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B2 -#define GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B3 -#define GL_POST_COLOR_MATRIX_RED_SCALE_SGI 0x80B4 -#define GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI 0x80B5 -#define GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI 0x80B6 -#define GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI 0x80B7 -#define GL_POST_COLOR_MATRIX_RED_BIAS_SGI 0x80B8 -#define GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI 0x80B9 -#define GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI 0x80BA -#define GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI 0x80BB -#endif /* GL_SGI_color_matrix */ - -#ifndef GL_SGI_color_table -#define GL_SGI_color_table 1 -#define GL_COLOR_TABLE_SGI 0x80D0 -#define GL_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D1 -#define GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D2 -#define GL_PROXY_COLOR_TABLE_SGI 0x80D3 -#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D4 -#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D5 -#define GL_COLOR_TABLE_SCALE_SGI 0x80D6 -#define GL_COLOR_TABLE_BIAS_SGI 0x80D7 -#define GL_COLOR_TABLE_FORMAT_SGI 0x80D8 -#define GL_COLOR_TABLE_WIDTH_SGI 0x80D9 -#define GL_COLOR_TABLE_RED_SIZE_SGI 0x80DA -#define GL_COLOR_TABLE_GREEN_SIZE_SGI 0x80DB -#define GL_COLOR_TABLE_BLUE_SIZE_SGI 0x80DC -#define GL_COLOR_TABLE_ALPHA_SIZE_SGI 0x80DD -#define GL_COLOR_TABLE_LUMINANCE_SIZE_SGI 0x80DE -#define GL_COLOR_TABLE_INTENSITY_SIZE_SGI 0x80DF -typedef void (APIENTRYP PFNGLCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *table); -typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLCOPYCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); -typedef void (APIENTRYP PFNGLGETCOLORTABLESGIPROC) (GLenum target, GLenum format, GLenum type, void *table); -typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, GLint *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glColorTableSGI (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *table); -GLAPI void APIENTRY glColorTableParameterfvSGI (GLenum target, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glColorTableParameterivSGI (GLenum target, GLenum pname, const GLint *params); -GLAPI void APIENTRY glCopyColorTableSGI (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); -GLAPI void APIENTRY glGetColorTableSGI (GLenum target, GLenum format, GLenum type, void *table); -GLAPI void APIENTRY glGetColorTableParameterfvSGI (GLenum target, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetColorTableParameterivSGI (GLenum target, GLenum pname, GLint *params); -#endif -#endif /* GL_SGI_color_table */ - -#ifndef GL_SGI_texture_color_table -#define GL_SGI_texture_color_table 1 -#define GL_TEXTURE_COLOR_TABLE_SGI 0x80BC -#define GL_PROXY_TEXTURE_COLOR_TABLE_SGI 0x80BD -#endif /* GL_SGI_texture_color_table */ - -#ifndef GL_SUNX_constant_data -#define GL_SUNX_constant_data 1 -#define GL_UNPACK_CONSTANT_DATA_SUNX 0x81D5 -#define GL_TEXTURE_CONSTANT_DATA_SUNX 0x81D6 -typedef void (APIENTRYP PFNGLFINISHTEXTURESUNXPROC) (void); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFinishTextureSUNX (void); -#endif -#endif /* GL_SUNX_constant_data */ - -#ifndef GL_SUN_convolution_border_modes -#define GL_SUN_convolution_border_modes 1 -#define GL_WRAP_BORDER_SUN 0x81D4 -#endif /* GL_SUN_convolution_border_modes */ - -#ifndef GL_SUN_global_alpha -#define GL_SUN_global_alpha 1 -#define GL_GLOBAL_ALPHA_SUN 0x81D9 -#define GL_GLOBAL_ALPHA_FACTOR_SUN 0x81DA -typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORBSUNPROC) (GLbyte factor); -typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORSSUNPROC) (GLshort factor); -typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORISUNPROC) (GLint factor); -typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORFSUNPROC) (GLfloat factor); -typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORDSUNPROC) (GLdouble factor); -typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUBSUNPROC) (GLubyte factor); -typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUSSUNPROC) (GLushort factor); -typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUISUNPROC) (GLuint factor); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGlobalAlphaFactorbSUN (GLbyte factor); -GLAPI void APIENTRY glGlobalAlphaFactorsSUN (GLshort factor); -GLAPI void APIENTRY glGlobalAlphaFactoriSUN (GLint factor); -GLAPI void APIENTRY glGlobalAlphaFactorfSUN (GLfloat factor); -GLAPI void APIENTRY glGlobalAlphaFactordSUN (GLdouble factor); -GLAPI void APIENTRY glGlobalAlphaFactorubSUN (GLubyte factor); -GLAPI void APIENTRY glGlobalAlphaFactorusSUN (GLushort factor); -GLAPI void APIENTRY glGlobalAlphaFactoruiSUN (GLuint factor); -#endif -#endif /* GL_SUN_global_alpha */ - -#ifndef GL_SUN_mesh_array -#define GL_SUN_mesh_array 1 -#define GL_QUAD_MESH_SUN 0x8614 -#define GL_TRIANGLE_MESH_SUN 0x8615 -typedef void (APIENTRYP PFNGLDRAWMESHARRAYSSUNPROC) (GLenum mode, GLint first, GLsizei count, GLsizei width); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDrawMeshArraysSUN (GLenum mode, GLint first, GLsizei count, GLsizei width); -#endif -#endif /* GL_SUN_mesh_array */ - -#ifndef GL_SUN_slice_accum -#define GL_SUN_slice_accum 1 -#define GL_SLICE_ACCUM_SUN 0x85CC -#endif /* GL_SUN_slice_accum */ - -#ifndef GL_SUN_triangle_list -#define GL_SUN_triangle_list 1 -#define GL_RESTART_SUN 0x0001 -#define GL_REPLACE_MIDDLE_SUN 0x0002 -#define GL_REPLACE_OLDEST_SUN 0x0003 -#define GL_TRIANGLE_LIST_SUN 0x81D7 -#define GL_REPLACEMENT_CODE_SUN 0x81D8 -#define GL_REPLACEMENT_CODE_ARRAY_SUN 0x85C0 -#define GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN 0x85C1 -#define GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN 0x85C2 -#define GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN 0x85C3 -#define GL_R1UI_V3F_SUN 0x85C4 -#define GL_R1UI_C4UB_V3F_SUN 0x85C5 -#define GL_R1UI_C3F_V3F_SUN 0x85C6 -#define GL_R1UI_N3F_V3F_SUN 0x85C7 -#define GL_R1UI_C4F_N3F_V3F_SUN 0x85C8 -#define GL_R1UI_T2F_V3F_SUN 0x85C9 -#define GL_R1UI_T2F_N3F_V3F_SUN 0x85CA -#define GL_R1UI_T2F_C4F_N3F_V3F_SUN 0x85CB -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUISUNPROC) (GLuint code); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUSSUNPROC) (GLushort code); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUBSUNPROC) (GLubyte code); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVSUNPROC) (const GLuint *code); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUSVSUNPROC) (const GLushort *code); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUBVSUNPROC) (const GLubyte *code); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEPOINTERSUNPROC) (GLenum type, GLsizei stride, const void **pointer); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glReplacementCodeuiSUN (GLuint code); -GLAPI void APIENTRY glReplacementCodeusSUN (GLushort code); -GLAPI void APIENTRY glReplacementCodeubSUN (GLubyte code); -GLAPI void APIENTRY glReplacementCodeuivSUN (const GLuint *code); -GLAPI void APIENTRY glReplacementCodeusvSUN (const GLushort *code); -GLAPI void APIENTRY glReplacementCodeubvSUN (const GLubyte *code); -GLAPI void APIENTRY glReplacementCodePointerSUN (GLenum type, GLsizei stride, const void **pointer); -#endif -#endif /* GL_SUN_triangle_list */ - -#ifndef GL_SUN_vertex -#define GL_SUN_vertex 1 -typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX2FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y); -typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX2FVSUNPROC) (const GLubyte *c, const GLfloat *v); -typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX3FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX3FVSUNPROC) (const GLubyte *c, const GLfloat *v); -typedef void (APIENTRYP PFNGLCOLOR3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *v); -typedef void (APIENTRYP PFNGLNORMAL3FVERTEX3FSUNPROC) (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *n, const GLfloat *v); -typedef void (APIENTRYP PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *n, const GLfloat *v); -typedef void (APIENTRYP PFNGLTEXCOORD2FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLTEXCOORD2FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *v); -typedef void (APIENTRYP PFNGLTEXCOORD4FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLTEXCOORD4FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *v); -typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC) (const GLfloat *tc, const GLubyte *c, const GLfloat *v); -typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *v); -typedef void (APIENTRYP PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *n, const GLfloat *v); -typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); -typedef void (APIENTRYP PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC) (GLuint rc, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *v); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC) (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC) (const GLuint *rc, const GLubyte *c, const GLfloat *v); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *c, const GLfloat *v); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *n, const GLfloat *v); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *c, const GLfloat *n, const GLfloat *v); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *v); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glColor4ubVertex2fSUN (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y); -GLAPI void APIENTRY glColor4ubVertex2fvSUN (const GLubyte *c, const GLfloat *v); -GLAPI void APIENTRY glColor4ubVertex3fSUN (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glColor4ubVertex3fvSUN (const GLubyte *c, const GLfloat *v); -GLAPI void APIENTRY glColor3fVertex3fSUN (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glColor3fVertex3fvSUN (const GLfloat *c, const GLfloat *v); -GLAPI void APIENTRY glNormal3fVertex3fSUN (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glNormal3fVertex3fvSUN (const GLfloat *n, const GLfloat *v); -GLAPI void APIENTRY glColor4fNormal3fVertex3fSUN (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glColor4fNormal3fVertex3fvSUN (const GLfloat *c, const GLfloat *n, const GLfloat *v); -GLAPI void APIENTRY glTexCoord2fVertex3fSUN (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glTexCoord2fVertex3fvSUN (const GLfloat *tc, const GLfloat *v); -GLAPI void APIENTRY glTexCoord4fVertex4fSUN (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI void APIENTRY glTexCoord4fVertex4fvSUN (const GLfloat *tc, const GLfloat *v); -GLAPI void APIENTRY glTexCoord2fColor4ubVertex3fSUN (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glTexCoord2fColor4ubVertex3fvSUN (const GLfloat *tc, const GLubyte *c, const GLfloat *v); -GLAPI void APIENTRY glTexCoord2fColor3fVertex3fSUN (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glTexCoord2fColor3fVertex3fvSUN (const GLfloat *tc, const GLfloat *c, const GLfloat *v); -GLAPI void APIENTRY glTexCoord2fNormal3fVertex3fSUN (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glTexCoord2fNormal3fVertex3fvSUN (const GLfloat *tc, const GLfloat *n, const GLfloat *v); -GLAPI void APIENTRY glTexCoord2fColor4fNormal3fVertex3fSUN (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glTexCoord2fColor4fNormal3fVertex3fvSUN (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); -GLAPI void APIENTRY glTexCoord4fColor4fNormal3fVertex4fSUN (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI void APIENTRY glTexCoord4fColor4fNormal3fVertex4fvSUN (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); -GLAPI void APIENTRY glReplacementCodeuiVertex3fSUN (GLuint rc, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glReplacementCodeuiVertex3fvSUN (const GLuint *rc, const GLfloat *v); -GLAPI void APIENTRY glReplacementCodeuiColor4ubVertex3fSUN (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glReplacementCodeuiColor4ubVertex3fvSUN (const GLuint *rc, const GLubyte *c, const GLfloat *v); -GLAPI void APIENTRY glReplacementCodeuiColor3fVertex3fSUN (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glReplacementCodeuiColor3fVertex3fvSUN (const GLuint *rc, const GLfloat *c, const GLfloat *v); -GLAPI void APIENTRY glReplacementCodeuiNormal3fVertex3fSUN (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glReplacementCodeuiNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *n, const GLfloat *v); -GLAPI void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fSUN (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *c, const GLfloat *n, const GLfloat *v); -GLAPI void APIENTRY glReplacementCodeuiTexCoord2fVertex3fSUN (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glReplacementCodeuiTexCoord2fVertex3fvSUN (const GLuint *rc, const GLfloat *tc, const GLfloat *v); -GLAPI void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v); -GLAPI void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN (GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); -#endif -#endif /* GL_SUN_vertex */ - -#ifndef GL_WIN_phong_shading -#define GL_WIN_phong_shading 1 -#define GL_PHONG_WIN 0x80EA -#define GL_PHONG_HINT_WIN 0x80EB -#endif /* GL_WIN_phong_shading */ - -#ifndef GL_WIN_specular_fog -#define GL_WIN_specular_fog 1 -#define GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC -#endif /* GL_WIN_specular_fog */ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/examples/common/glfw/deps/GL/glxext.h b/examples/common/glfw/deps/GL/glxext.h deleted file mode 100644 index 174fc218..00000000 --- a/examples/common/glfw/deps/GL/glxext.h +++ /dev/null @@ -1,906 +0,0 @@ -#ifndef __glxext_h_ -#define __glxext_h_ 1 - -#ifdef __cplusplus -extern "C" { -#endif - -/* -** Copyright (c) 2013-2014 The Khronos Group Inc. -** -** Permission is hereby granted, free of charge, to any person obtaining a -** copy of this software and/or associated documentation files (the -** "Materials"), to deal in the Materials without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Materials, and to -** permit persons to whom the Materials are furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be included -** in all copies or substantial portions of the Materials. -** -** THE MATERIALS ARE 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 -** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. -*/ -/* -** This header is generated from the Khronos OpenGL / OpenGL ES XML -** API Registry. The current version of the Registry, generator scripts -** used to make the header, and the header can be found at -** http://www.opengl.org/registry/ -** -** Khronos $Revision: 27684 $ on $Date: 2014-08-11 01:21:35 -0700 (Mon, 11 Aug 2014) $ -*/ - -#define GLX_GLXEXT_VERSION 20140810 - -/* Generated C header for: - * API: glx - * Versions considered: .* - * Versions emitted: 1\.[3-9] - * Default extensions included: glx - * Additional extensions included: _nomatch_^ - * Extensions removed: _nomatch_^ - */ - -#ifndef GLX_VERSION_1_3 -#define GLX_VERSION_1_3 1 -typedef XID GLXContextID; -typedef struct __GLXFBConfigRec *GLXFBConfig; -typedef XID GLXWindow; -typedef XID GLXPbuffer; -#define GLX_WINDOW_BIT 0x00000001 -#define GLX_PIXMAP_BIT 0x00000002 -#define GLX_PBUFFER_BIT 0x00000004 -#define GLX_RGBA_BIT 0x00000001 -#define GLX_COLOR_INDEX_BIT 0x00000002 -#define GLX_PBUFFER_CLOBBER_MASK 0x08000000 -#define GLX_FRONT_LEFT_BUFFER_BIT 0x00000001 -#define GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002 -#define GLX_BACK_LEFT_BUFFER_BIT 0x00000004 -#define GLX_BACK_RIGHT_BUFFER_BIT 0x00000008 -#define GLX_AUX_BUFFERS_BIT 0x00000010 -#define GLX_DEPTH_BUFFER_BIT 0x00000020 -#define GLX_STENCIL_BUFFER_BIT 0x00000040 -#define GLX_ACCUM_BUFFER_BIT 0x00000080 -#define GLX_CONFIG_CAVEAT 0x20 -#define GLX_X_VISUAL_TYPE 0x22 -#define GLX_TRANSPARENT_TYPE 0x23 -#define GLX_TRANSPARENT_INDEX_VALUE 0x24 -#define GLX_TRANSPARENT_RED_VALUE 0x25 -#define GLX_TRANSPARENT_GREEN_VALUE 0x26 -#define GLX_TRANSPARENT_BLUE_VALUE 0x27 -#define GLX_TRANSPARENT_ALPHA_VALUE 0x28 -#define GLX_DONT_CARE 0xFFFFFFFF -#define GLX_NONE 0x8000 -#define GLX_SLOW_CONFIG 0x8001 -#define GLX_TRUE_COLOR 0x8002 -#define GLX_DIRECT_COLOR 0x8003 -#define GLX_PSEUDO_COLOR 0x8004 -#define GLX_STATIC_COLOR 0x8005 -#define GLX_GRAY_SCALE 0x8006 -#define GLX_STATIC_GRAY 0x8007 -#define GLX_TRANSPARENT_RGB 0x8008 -#define GLX_TRANSPARENT_INDEX 0x8009 -#define GLX_VISUAL_ID 0x800B -#define GLX_SCREEN 0x800C -#define GLX_NON_CONFORMANT_CONFIG 0x800D -#define GLX_DRAWABLE_TYPE 0x8010 -#define GLX_RENDER_TYPE 0x8011 -#define GLX_X_RENDERABLE 0x8012 -#define GLX_FBCONFIG_ID 0x8013 -#define GLX_RGBA_TYPE 0x8014 -#define GLX_COLOR_INDEX_TYPE 0x8015 -#define GLX_MAX_PBUFFER_WIDTH 0x8016 -#define GLX_MAX_PBUFFER_HEIGHT 0x8017 -#define GLX_MAX_PBUFFER_PIXELS 0x8018 -#define GLX_PRESERVED_CONTENTS 0x801B -#define GLX_LARGEST_PBUFFER 0x801C -#define GLX_WIDTH 0x801D -#define GLX_HEIGHT 0x801E -#define GLX_EVENT_MASK 0x801F -#define GLX_DAMAGED 0x8020 -#define GLX_SAVED 0x8021 -#define GLX_WINDOW 0x8022 -#define GLX_PBUFFER 0x8023 -#define GLX_PBUFFER_HEIGHT 0x8040 -#define GLX_PBUFFER_WIDTH 0x8041 -typedef GLXFBConfig *( *PFNGLXGETFBCONFIGSPROC) (Display *dpy, int screen, int *nelements); -typedef GLXFBConfig *( *PFNGLXCHOOSEFBCONFIGPROC) (Display *dpy, int screen, const int *attrib_list, int *nelements); -typedef int ( *PFNGLXGETFBCONFIGATTRIBPROC) (Display *dpy, GLXFBConfig config, int attribute, int *value); -typedef XVisualInfo *( *PFNGLXGETVISUALFROMFBCONFIGPROC) (Display *dpy, GLXFBConfig config); -typedef GLXWindow ( *PFNGLXCREATEWINDOWPROC) (Display *dpy, GLXFBConfig config, Window win, const int *attrib_list); -typedef void ( *PFNGLXDESTROYWINDOWPROC) (Display *dpy, GLXWindow win); -typedef GLXPixmap ( *PFNGLXCREATEPIXMAPPROC) (Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attrib_list); -typedef void ( *PFNGLXDESTROYPIXMAPPROC) (Display *dpy, GLXPixmap pixmap); -typedef GLXPbuffer ( *PFNGLXCREATEPBUFFERPROC) (Display *dpy, GLXFBConfig config, const int *attrib_list); -typedef void ( *PFNGLXDESTROYPBUFFERPROC) (Display *dpy, GLXPbuffer pbuf); -typedef void ( *PFNGLXQUERYDRAWABLEPROC) (Display *dpy, GLXDrawable draw, int attribute, unsigned int *value); -typedef GLXContext ( *PFNGLXCREATENEWCONTEXTPROC) (Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct); -typedef Bool ( *PFNGLXMAKECONTEXTCURRENTPROC) (Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx); -typedef GLXDrawable ( *PFNGLXGETCURRENTREADDRAWABLEPROC) (void); -typedef int ( *PFNGLXQUERYCONTEXTPROC) (Display *dpy, GLXContext ctx, int attribute, int *value); -typedef void ( *PFNGLXSELECTEVENTPROC) (Display *dpy, GLXDrawable draw, unsigned long event_mask); -typedef void ( *PFNGLXGETSELECTEDEVENTPROC) (Display *dpy, GLXDrawable draw, unsigned long *event_mask); -#ifdef GLX_GLXEXT_PROTOTYPES -GLXFBConfig *glXGetFBConfigs (Display *dpy, int screen, int *nelements); -GLXFBConfig *glXChooseFBConfig (Display *dpy, int screen, const int *attrib_list, int *nelements); -int glXGetFBConfigAttrib (Display *dpy, GLXFBConfig config, int attribute, int *value); -XVisualInfo *glXGetVisualFromFBConfig (Display *dpy, GLXFBConfig config); -GLXWindow glXCreateWindow (Display *dpy, GLXFBConfig config, Window win, const int *attrib_list); -void glXDestroyWindow (Display *dpy, GLXWindow win); -GLXPixmap glXCreatePixmap (Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attrib_list); -void glXDestroyPixmap (Display *dpy, GLXPixmap pixmap); -GLXPbuffer glXCreatePbuffer (Display *dpy, GLXFBConfig config, const int *attrib_list); -void glXDestroyPbuffer (Display *dpy, GLXPbuffer pbuf); -void glXQueryDrawable (Display *dpy, GLXDrawable draw, int attribute, unsigned int *value); -GLXContext glXCreateNewContext (Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct); -Bool glXMakeContextCurrent (Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx); -GLXDrawable glXGetCurrentReadDrawable (void); -int glXQueryContext (Display *dpy, GLXContext ctx, int attribute, int *value); -void glXSelectEvent (Display *dpy, GLXDrawable draw, unsigned long event_mask); -void glXGetSelectedEvent (Display *dpy, GLXDrawable draw, unsigned long *event_mask); -#endif -#endif /* GLX_VERSION_1_3 */ - -#ifndef GLX_VERSION_1_4 -#define GLX_VERSION_1_4 1 -typedef void ( *__GLXextFuncPtr)(void); -#define GLX_SAMPLE_BUFFERS 100000 -#define GLX_SAMPLES 100001 -typedef __GLXextFuncPtr ( *PFNGLXGETPROCADDRESSPROC) (const GLubyte *procName); -#ifdef GLX_GLXEXT_PROTOTYPES -__GLXextFuncPtr glXGetProcAddress (const GLubyte *procName); -#endif -#endif /* GLX_VERSION_1_4 */ - -#ifndef GLX_ARB_context_flush_control -#define GLX_ARB_context_flush_control 1 -#define GLX_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097 -#define GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0 -#define GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098 -#endif /* GLX_ARB_context_flush_control */ - -#ifndef GLX_ARB_create_context -#define GLX_ARB_create_context 1 -#define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001 -#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002 -#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 -#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 -#define GLX_CONTEXT_FLAGS_ARB 0x2094 -typedef GLXContext ( *PFNGLXCREATECONTEXTATTRIBSARBPROC) (Display *dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list); -#ifdef GLX_GLXEXT_PROTOTYPES -GLXContext glXCreateContextAttribsARB (Display *dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list); -#endif -#endif /* GLX_ARB_create_context */ - -#ifndef GLX_ARB_create_context_profile -#define GLX_ARB_create_context_profile 1 -#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 -#define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 -#define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126 -#endif /* GLX_ARB_create_context_profile */ - -#ifndef GLX_ARB_create_context_robustness -#define GLX_ARB_create_context_robustness 1 -#define GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004 -#define GLX_LOSE_CONTEXT_ON_RESET_ARB 0x8252 -#define GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 -#define GLX_NO_RESET_NOTIFICATION_ARB 0x8261 -#endif /* GLX_ARB_create_context_robustness */ - -#ifndef GLX_ARB_fbconfig_float -#define GLX_ARB_fbconfig_float 1 -#define GLX_RGBA_FLOAT_TYPE_ARB 0x20B9 -#define GLX_RGBA_FLOAT_BIT_ARB 0x00000004 -#endif /* GLX_ARB_fbconfig_float */ - -#ifndef GLX_ARB_framebuffer_sRGB -#define GLX_ARB_framebuffer_sRGB 1 -#define GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20B2 -#endif /* GLX_ARB_framebuffer_sRGB */ - -#ifndef GLX_ARB_get_proc_address -#define GLX_ARB_get_proc_address 1 -typedef __GLXextFuncPtr ( *PFNGLXGETPROCADDRESSARBPROC) (const GLubyte *procName); -#ifdef GLX_GLXEXT_PROTOTYPES -__GLXextFuncPtr glXGetProcAddressARB (const GLubyte *procName); -#endif -#endif /* GLX_ARB_get_proc_address */ - -#ifndef GLX_ARB_multisample -#define GLX_ARB_multisample 1 -#define GLX_SAMPLE_BUFFERS_ARB 100000 -#define GLX_SAMPLES_ARB 100001 -#endif /* GLX_ARB_multisample */ - -#ifndef GLX_ARB_robustness_application_isolation -#define GLX_ARB_robustness_application_isolation 1 -#define GLX_CONTEXT_RESET_ISOLATION_BIT_ARB 0x00000008 -#endif /* GLX_ARB_robustness_application_isolation */ - -#ifndef GLX_ARB_robustness_share_group_isolation -#define GLX_ARB_robustness_share_group_isolation 1 -#endif /* GLX_ARB_robustness_share_group_isolation */ - -#ifndef GLX_ARB_vertex_buffer_object -#define GLX_ARB_vertex_buffer_object 1 -#define GLX_CONTEXT_ALLOW_BUFFER_BYTE_ORDER_MISMATCH_ARB 0x2095 -#endif /* GLX_ARB_vertex_buffer_object */ - -#ifndef GLX_3DFX_multisample -#define GLX_3DFX_multisample 1 -#define GLX_SAMPLE_BUFFERS_3DFX 0x8050 -#define GLX_SAMPLES_3DFX 0x8051 -#endif /* GLX_3DFX_multisample */ - -#ifndef GLX_AMD_gpu_association -#define GLX_AMD_gpu_association 1 -#define GLX_GPU_VENDOR_AMD 0x1F00 -#define GLX_GPU_RENDERER_STRING_AMD 0x1F01 -#define GLX_GPU_OPENGL_VERSION_STRING_AMD 0x1F02 -#define GLX_GPU_FASTEST_TARGET_GPUS_AMD 0x21A2 -#define GLX_GPU_RAM_AMD 0x21A3 -#define GLX_GPU_CLOCK_AMD 0x21A4 -#define GLX_GPU_NUM_PIPES_AMD 0x21A5 -#define GLX_GPU_NUM_SIMD_AMD 0x21A6 -#define GLX_GPU_NUM_RB_AMD 0x21A7 -#define GLX_GPU_NUM_SPI_AMD 0x21A8 -#endif /* GLX_AMD_gpu_association */ - -#ifndef GLX_EXT_buffer_age -#define GLX_EXT_buffer_age 1 -#define GLX_BACK_BUFFER_AGE_EXT 0x20F4 -#endif /* GLX_EXT_buffer_age */ - -#ifndef GLX_EXT_create_context_es2_profile -#define GLX_EXT_create_context_es2_profile 1 -#define GLX_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004 -#endif /* GLX_EXT_create_context_es2_profile */ - -#ifndef GLX_EXT_create_context_es_profile -#define GLX_EXT_create_context_es_profile 1 -#define GLX_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004 -#endif /* GLX_EXT_create_context_es_profile */ - -#ifndef GLX_EXT_fbconfig_packed_float -#define GLX_EXT_fbconfig_packed_float 1 -#define GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT 0x20B1 -#define GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT 0x00000008 -#endif /* GLX_EXT_fbconfig_packed_float */ - -#ifndef GLX_EXT_framebuffer_sRGB -#define GLX_EXT_framebuffer_sRGB 1 -#define GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20B2 -#endif /* GLX_EXT_framebuffer_sRGB */ - -#ifndef GLX_EXT_import_context -#define GLX_EXT_import_context 1 -#define GLX_SHARE_CONTEXT_EXT 0x800A -#define GLX_VISUAL_ID_EXT 0x800B -#define GLX_SCREEN_EXT 0x800C -typedef Display *( *PFNGLXGETCURRENTDISPLAYEXTPROC) (void); -typedef int ( *PFNGLXQUERYCONTEXTINFOEXTPROC) (Display *dpy, GLXContext context, int attribute, int *value); -typedef GLXContextID ( *PFNGLXGETCONTEXTIDEXTPROC) (const GLXContext context); -typedef GLXContext ( *PFNGLXIMPORTCONTEXTEXTPROC) (Display *dpy, GLXContextID contextID); -typedef void ( *PFNGLXFREECONTEXTEXTPROC) (Display *dpy, GLXContext context); -#ifdef GLX_GLXEXT_PROTOTYPES -Display *glXGetCurrentDisplayEXT (void); -int glXQueryContextInfoEXT (Display *dpy, GLXContext context, int attribute, int *value); -GLXContextID glXGetContextIDEXT (const GLXContext context); -GLXContext glXImportContextEXT (Display *dpy, GLXContextID contextID); -void glXFreeContextEXT (Display *dpy, GLXContext context); -#endif -#endif /* GLX_EXT_import_context */ - -#ifndef GLX_EXT_stereo_tree -#define GLX_EXT_stereo_tree 1 -typedef struct { - int type; - unsigned long serial; - Bool send_event; - Display *display; - int extension; - int evtype; - GLXDrawable window; - Bool stereo_tree; -} GLXStereoNotifyEventEXT; -#define GLX_STEREO_TREE_EXT 0x20F5 -#define GLX_STEREO_NOTIFY_MASK_EXT 0x00000001 -#define GLX_STEREO_NOTIFY_EXT 0x00000000 -#endif /* GLX_EXT_stereo_tree */ - -#ifndef GLX_EXT_swap_control -#define GLX_EXT_swap_control 1 -#define GLX_SWAP_INTERVAL_EXT 0x20F1 -#define GLX_MAX_SWAP_INTERVAL_EXT 0x20F2 -typedef void ( *PFNGLXSWAPINTERVALEXTPROC) (Display *dpy, GLXDrawable drawable, int interval); -#ifdef GLX_GLXEXT_PROTOTYPES -void glXSwapIntervalEXT (Display *dpy, GLXDrawable drawable, int interval); -#endif -#endif /* GLX_EXT_swap_control */ - -#ifndef GLX_EXT_swap_control_tear -#define GLX_EXT_swap_control_tear 1 -#define GLX_LATE_SWAPS_TEAR_EXT 0x20F3 -#endif /* GLX_EXT_swap_control_tear */ - -#ifndef GLX_EXT_texture_from_pixmap -#define GLX_EXT_texture_from_pixmap 1 -#define GLX_TEXTURE_1D_BIT_EXT 0x00000001 -#define GLX_TEXTURE_2D_BIT_EXT 0x00000002 -#define GLX_TEXTURE_RECTANGLE_BIT_EXT 0x00000004 -#define GLX_BIND_TO_TEXTURE_RGB_EXT 0x20D0 -#define GLX_BIND_TO_TEXTURE_RGBA_EXT 0x20D1 -#define GLX_BIND_TO_MIPMAP_TEXTURE_EXT 0x20D2 -#define GLX_BIND_TO_TEXTURE_TARGETS_EXT 0x20D3 -#define GLX_Y_INVERTED_EXT 0x20D4 -#define GLX_TEXTURE_FORMAT_EXT 0x20D5 -#define GLX_TEXTURE_TARGET_EXT 0x20D6 -#define GLX_MIPMAP_TEXTURE_EXT 0x20D7 -#define GLX_TEXTURE_FORMAT_NONE_EXT 0x20D8 -#define GLX_TEXTURE_FORMAT_RGB_EXT 0x20D9 -#define GLX_TEXTURE_FORMAT_RGBA_EXT 0x20DA -#define GLX_TEXTURE_1D_EXT 0x20DB -#define GLX_TEXTURE_2D_EXT 0x20DC -#define GLX_TEXTURE_RECTANGLE_EXT 0x20DD -#define GLX_FRONT_LEFT_EXT 0x20DE -#define GLX_FRONT_RIGHT_EXT 0x20DF -#define GLX_BACK_LEFT_EXT 0x20E0 -#define GLX_BACK_RIGHT_EXT 0x20E1 -#define GLX_FRONT_EXT 0x20DE -#define GLX_BACK_EXT 0x20E0 -#define GLX_AUX0_EXT 0x20E2 -#define GLX_AUX1_EXT 0x20E3 -#define GLX_AUX2_EXT 0x20E4 -#define GLX_AUX3_EXT 0x20E5 -#define GLX_AUX4_EXT 0x20E6 -#define GLX_AUX5_EXT 0x20E7 -#define GLX_AUX6_EXT 0x20E8 -#define GLX_AUX7_EXT 0x20E9 -#define GLX_AUX8_EXT 0x20EA -#define GLX_AUX9_EXT 0x20EB -typedef void ( *PFNGLXBINDTEXIMAGEEXTPROC) (Display *dpy, GLXDrawable drawable, int buffer, const int *attrib_list); -typedef void ( *PFNGLXRELEASETEXIMAGEEXTPROC) (Display *dpy, GLXDrawable drawable, int buffer); -#ifdef GLX_GLXEXT_PROTOTYPES -void glXBindTexImageEXT (Display *dpy, GLXDrawable drawable, int buffer, const int *attrib_list); -void glXReleaseTexImageEXT (Display *dpy, GLXDrawable drawable, int buffer); -#endif -#endif /* GLX_EXT_texture_from_pixmap */ - -#ifndef GLX_EXT_visual_info -#define GLX_EXT_visual_info 1 -#define GLX_X_VISUAL_TYPE_EXT 0x22 -#define GLX_TRANSPARENT_TYPE_EXT 0x23 -#define GLX_TRANSPARENT_INDEX_VALUE_EXT 0x24 -#define GLX_TRANSPARENT_RED_VALUE_EXT 0x25 -#define GLX_TRANSPARENT_GREEN_VALUE_EXT 0x26 -#define GLX_TRANSPARENT_BLUE_VALUE_EXT 0x27 -#define GLX_TRANSPARENT_ALPHA_VALUE_EXT 0x28 -#define GLX_NONE_EXT 0x8000 -#define GLX_TRUE_COLOR_EXT 0x8002 -#define GLX_DIRECT_COLOR_EXT 0x8003 -#define GLX_PSEUDO_COLOR_EXT 0x8004 -#define GLX_STATIC_COLOR_EXT 0x8005 -#define GLX_GRAY_SCALE_EXT 0x8006 -#define GLX_STATIC_GRAY_EXT 0x8007 -#define GLX_TRANSPARENT_RGB_EXT 0x8008 -#define GLX_TRANSPARENT_INDEX_EXT 0x8009 -#endif /* GLX_EXT_visual_info */ - -#ifndef GLX_EXT_visual_rating -#define GLX_EXT_visual_rating 1 -#define GLX_VISUAL_CAVEAT_EXT 0x20 -#define GLX_SLOW_VISUAL_EXT 0x8001 -#define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D -#endif /* GLX_EXT_visual_rating */ - -#ifndef GLX_INTEL_swap_event -#define GLX_INTEL_swap_event 1 -#define GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK 0x04000000 -#define GLX_EXCHANGE_COMPLETE_INTEL 0x8180 -#define GLX_COPY_COMPLETE_INTEL 0x8181 -#define GLX_FLIP_COMPLETE_INTEL 0x8182 -#endif /* GLX_INTEL_swap_event */ - -#ifndef GLX_MESA_agp_offset -#define GLX_MESA_agp_offset 1 -typedef unsigned int ( *PFNGLXGETAGPOFFSETMESAPROC) (const void *pointer); -#ifdef GLX_GLXEXT_PROTOTYPES -unsigned int glXGetAGPOffsetMESA (const void *pointer); -#endif -#endif /* GLX_MESA_agp_offset */ - -#ifndef GLX_MESA_copy_sub_buffer -#define GLX_MESA_copy_sub_buffer 1 -typedef void ( *PFNGLXCOPYSUBBUFFERMESAPROC) (Display *dpy, GLXDrawable drawable, int x, int y, int width, int height); -#ifdef GLX_GLXEXT_PROTOTYPES -void glXCopySubBufferMESA (Display *dpy, GLXDrawable drawable, int x, int y, int width, int height); -#endif -#endif /* GLX_MESA_copy_sub_buffer */ - -#ifndef GLX_MESA_pixmap_colormap -#define GLX_MESA_pixmap_colormap 1 -typedef GLXPixmap ( *PFNGLXCREATEGLXPIXMAPMESAPROC) (Display *dpy, XVisualInfo *visual, Pixmap pixmap, Colormap cmap); -#ifdef GLX_GLXEXT_PROTOTYPES -GLXPixmap glXCreateGLXPixmapMESA (Display *dpy, XVisualInfo *visual, Pixmap pixmap, Colormap cmap); -#endif -#endif /* GLX_MESA_pixmap_colormap */ - -#ifndef GLX_MESA_query_renderer -#define GLX_MESA_query_renderer 1 -#define GLX_RENDERER_VENDOR_ID_MESA 0x8183 -#define GLX_RENDERER_DEVICE_ID_MESA 0x8184 -#define GLX_RENDERER_VERSION_MESA 0x8185 -#define GLX_RENDERER_ACCELERATED_MESA 0x8186 -#define GLX_RENDERER_VIDEO_MEMORY_MESA 0x8187 -#define GLX_RENDERER_UNIFIED_MEMORY_ARCHITECTURE_MESA 0x8188 -#define GLX_RENDERER_PREFERRED_PROFILE_MESA 0x8189 -#define GLX_RENDERER_OPENGL_CORE_PROFILE_VERSION_MESA 0x818A -#define GLX_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION_MESA 0x818B -#define GLX_RENDERER_OPENGL_ES_PROFILE_VERSION_MESA 0x818C -#define GLX_RENDERER_OPENGL_ES2_PROFILE_VERSION_MESA 0x818D -#define GLX_RENDERER_ID_MESA 0x818E -typedef Bool ( *PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC) (int attribute, unsigned int *value); -typedef const char *( *PFNGLXQUERYCURRENTRENDERERSTRINGMESAPROC) (int attribute); -typedef Bool ( *PFNGLXQUERYRENDERERINTEGERMESAPROC) (Display *dpy, int screen, int renderer, int attribute, unsigned int *value); -typedef const char *( *PFNGLXQUERYRENDERERSTRINGMESAPROC) (Display *dpy, int screen, int renderer, int attribute); -#ifdef GLX_GLXEXT_PROTOTYPES -Bool glXQueryCurrentRendererIntegerMESA (int attribute, unsigned int *value); -const char *glXQueryCurrentRendererStringMESA (int attribute); -Bool glXQueryRendererIntegerMESA (Display *dpy, int screen, int renderer, int attribute, unsigned int *value); -const char *glXQueryRendererStringMESA (Display *dpy, int screen, int renderer, int attribute); -#endif -#endif /* GLX_MESA_query_renderer */ - -#ifndef GLX_MESA_release_buffers -#define GLX_MESA_release_buffers 1 -typedef Bool ( *PFNGLXRELEASEBUFFERSMESAPROC) (Display *dpy, GLXDrawable drawable); -#ifdef GLX_GLXEXT_PROTOTYPES -Bool glXReleaseBuffersMESA (Display *dpy, GLXDrawable drawable); -#endif -#endif /* GLX_MESA_release_buffers */ - -#ifndef GLX_MESA_set_3dfx_mode -#define GLX_MESA_set_3dfx_mode 1 -#define GLX_3DFX_WINDOW_MODE_MESA 0x1 -#define GLX_3DFX_FULLSCREEN_MODE_MESA 0x2 -typedef Bool ( *PFNGLXSET3DFXMODEMESAPROC) (int mode); -#ifdef GLX_GLXEXT_PROTOTYPES -Bool glXSet3DfxModeMESA (int mode); -#endif -#endif /* GLX_MESA_set_3dfx_mode */ - -#ifndef GLX_NV_copy_buffer -#define GLX_NV_copy_buffer 1 -typedef void ( *PFNGLXCOPYBUFFERSUBDATANVPROC) (Display *dpy, GLXContext readCtx, GLXContext writeCtx, GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); -typedef void ( *PFNGLXNAMEDCOPYBUFFERSUBDATANVPROC) (Display *dpy, GLXContext readCtx, GLXContext writeCtx, GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); -#ifdef GLX_GLXEXT_PROTOTYPES -void glXCopyBufferSubDataNV (Display *dpy, GLXContext readCtx, GLXContext writeCtx, GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); -void glXNamedCopyBufferSubDataNV (Display *dpy, GLXContext readCtx, GLXContext writeCtx, GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); -#endif -#endif /* GLX_NV_copy_buffer */ - -#ifndef GLX_NV_copy_image -#define GLX_NV_copy_image 1 -typedef void ( *PFNGLXCOPYIMAGESUBDATANVPROC) (Display *dpy, GLXContext srcCtx, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLXContext dstCtx, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); -#ifdef GLX_GLXEXT_PROTOTYPES -void glXCopyImageSubDataNV (Display *dpy, GLXContext srcCtx, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLXContext dstCtx, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); -#endif -#endif /* GLX_NV_copy_image */ - -#ifndef GLX_NV_delay_before_swap -#define GLX_NV_delay_before_swap 1 -typedef Bool ( *PFNGLXDELAYBEFORESWAPNVPROC) (Display *dpy, GLXDrawable drawable, GLfloat seconds); -#ifdef GLX_GLXEXT_PROTOTYPES -Bool glXDelayBeforeSwapNV (Display *dpy, GLXDrawable drawable, GLfloat seconds); -#endif -#endif /* GLX_NV_delay_before_swap */ - -#ifndef GLX_NV_float_buffer -#define GLX_NV_float_buffer 1 -#define GLX_FLOAT_COMPONENTS_NV 0x20B0 -#endif /* GLX_NV_float_buffer */ - -#ifndef GLX_NV_multisample_coverage -#define GLX_NV_multisample_coverage 1 -#define GLX_COVERAGE_SAMPLES_NV 100001 -#define GLX_COLOR_SAMPLES_NV 0x20B3 -#endif /* GLX_NV_multisample_coverage */ - -#ifndef GLX_NV_present_video -#define GLX_NV_present_video 1 -#define GLX_NUM_VIDEO_SLOTS_NV 0x20F0 -typedef unsigned int *( *PFNGLXENUMERATEVIDEODEVICESNVPROC) (Display *dpy, int screen, int *nelements); -typedef int ( *PFNGLXBINDVIDEODEVICENVPROC) (Display *dpy, unsigned int video_slot, unsigned int video_device, const int *attrib_list); -#ifdef GLX_GLXEXT_PROTOTYPES -unsigned int *glXEnumerateVideoDevicesNV (Display *dpy, int screen, int *nelements); -int glXBindVideoDeviceNV (Display *dpy, unsigned int video_slot, unsigned int video_device, const int *attrib_list); -#endif -#endif /* GLX_NV_present_video */ - -#ifndef GLX_NV_swap_group -#define GLX_NV_swap_group 1 -typedef Bool ( *PFNGLXJOINSWAPGROUPNVPROC) (Display *dpy, GLXDrawable drawable, GLuint group); -typedef Bool ( *PFNGLXBINDSWAPBARRIERNVPROC) (Display *dpy, GLuint group, GLuint barrier); -typedef Bool ( *PFNGLXQUERYSWAPGROUPNVPROC) (Display *dpy, GLXDrawable drawable, GLuint *group, GLuint *barrier); -typedef Bool ( *PFNGLXQUERYMAXSWAPGROUPSNVPROC) (Display *dpy, int screen, GLuint *maxGroups, GLuint *maxBarriers); -typedef Bool ( *PFNGLXQUERYFRAMECOUNTNVPROC) (Display *dpy, int screen, GLuint *count); -typedef Bool ( *PFNGLXRESETFRAMECOUNTNVPROC) (Display *dpy, int screen); -#ifdef GLX_GLXEXT_PROTOTYPES -Bool glXJoinSwapGroupNV (Display *dpy, GLXDrawable drawable, GLuint group); -Bool glXBindSwapBarrierNV (Display *dpy, GLuint group, GLuint barrier); -Bool glXQuerySwapGroupNV (Display *dpy, GLXDrawable drawable, GLuint *group, GLuint *barrier); -Bool glXQueryMaxSwapGroupsNV (Display *dpy, int screen, GLuint *maxGroups, GLuint *maxBarriers); -Bool glXQueryFrameCountNV (Display *dpy, int screen, GLuint *count); -Bool glXResetFrameCountNV (Display *dpy, int screen); -#endif -#endif /* GLX_NV_swap_group */ - -#ifndef GLX_NV_video_capture -#define GLX_NV_video_capture 1 -typedef XID GLXVideoCaptureDeviceNV; -#define GLX_DEVICE_ID_NV 0x20CD -#define GLX_UNIQUE_ID_NV 0x20CE -#define GLX_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF -typedef int ( *PFNGLXBINDVIDEOCAPTUREDEVICENVPROC) (Display *dpy, unsigned int video_capture_slot, GLXVideoCaptureDeviceNV device); -typedef GLXVideoCaptureDeviceNV *( *PFNGLXENUMERATEVIDEOCAPTUREDEVICESNVPROC) (Display *dpy, int screen, int *nelements); -typedef void ( *PFNGLXLOCKVIDEOCAPTUREDEVICENVPROC) (Display *dpy, GLXVideoCaptureDeviceNV device); -typedef int ( *PFNGLXQUERYVIDEOCAPTUREDEVICENVPROC) (Display *dpy, GLXVideoCaptureDeviceNV device, int attribute, int *value); -typedef void ( *PFNGLXRELEASEVIDEOCAPTUREDEVICENVPROC) (Display *dpy, GLXVideoCaptureDeviceNV device); -#ifdef GLX_GLXEXT_PROTOTYPES -int glXBindVideoCaptureDeviceNV (Display *dpy, unsigned int video_capture_slot, GLXVideoCaptureDeviceNV device); -GLXVideoCaptureDeviceNV *glXEnumerateVideoCaptureDevicesNV (Display *dpy, int screen, int *nelements); -void glXLockVideoCaptureDeviceNV (Display *dpy, GLXVideoCaptureDeviceNV device); -int glXQueryVideoCaptureDeviceNV (Display *dpy, GLXVideoCaptureDeviceNV device, int attribute, int *value); -void glXReleaseVideoCaptureDeviceNV (Display *dpy, GLXVideoCaptureDeviceNV device); -#endif -#endif /* GLX_NV_video_capture */ - -#ifndef GLX_NV_video_out -#define GLX_NV_video_out 1 -typedef unsigned int GLXVideoDeviceNV; -#define GLX_VIDEO_OUT_COLOR_NV 0x20C3 -#define GLX_VIDEO_OUT_ALPHA_NV 0x20C4 -#define GLX_VIDEO_OUT_DEPTH_NV 0x20C5 -#define GLX_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6 -#define GLX_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7 -#define GLX_VIDEO_OUT_FRAME_NV 0x20C8 -#define GLX_VIDEO_OUT_FIELD_1_NV 0x20C9 -#define GLX_VIDEO_OUT_FIELD_2_NV 0x20CA -#define GLX_VIDEO_OUT_STACKED_FIELDS_1_2_NV 0x20CB -#define GLX_VIDEO_OUT_STACKED_FIELDS_2_1_NV 0x20CC -typedef int ( *PFNGLXGETVIDEODEVICENVPROC) (Display *dpy, int screen, int numVideoDevices, GLXVideoDeviceNV *pVideoDevice); -typedef int ( *PFNGLXRELEASEVIDEODEVICENVPROC) (Display *dpy, int screen, GLXVideoDeviceNV VideoDevice); -typedef int ( *PFNGLXBINDVIDEOIMAGENVPROC) (Display *dpy, GLXVideoDeviceNV VideoDevice, GLXPbuffer pbuf, int iVideoBuffer); -typedef int ( *PFNGLXRELEASEVIDEOIMAGENVPROC) (Display *dpy, GLXPbuffer pbuf); -typedef int ( *PFNGLXSENDPBUFFERTOVIDEONVPROC) (Display *dpy, GLXPbuffer pbuf, int iBufferType, unsigned long *pulCounterPbuffer, GLboolean bBlock); -typedef int ( *PFNGLXGETVIDEOINFONVPROC) (Display *dpy, int screen, GLXVideoDeviceNV VideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo); -#ifdef GLX_GLXEXT_PROTOTYPES -int glXGetVideoDeviceNV (Display *dpy, int screen, int numVideoDevices, GLXVideoDeviceNV *pVideoDevice); -int glXReleaseVideoDeviceNV (Display *dpy, int screen, GLXVideoDeviceNV VideoDevice); -int glXBindVideoImageNV (Display *dpy, GLXVideoDeviceNV VideoDevice, GLXPbuffer pbuf, int iVideoBuffer); -int glXReleaseVideoImageNV (Display *dpy, GLXPbuffer pbuf); -int glXSendPbufferToVideoNV (Display *dpy, GLXPbuffer pbuf, int iBufferType, unsigned long *pulCounterPbuffer, GLboolean bBlock); -int glXGetVideoInfoNV (Display *dpy, int screen, GLXVideoDeviceNV VideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo); -#endif -#endif /* GLX_NV_video_out */ - -#ifndef GLX_OML_swap_method -#define GLX_OML_swap_method 1 -#define GLX_SWAP_METHOD_OML 0x8060 -#define GLX_SWAP_EXCHANGE_OML 0x8061 -#define GLX_SWAP_COPY_OML 0x8062 -#define GLX_SWAP_UNDEFINED_OML 0x8063 -#endif /* GLX_OML_swap_method */ - -#ifndef GLX_OML_sync_control -#define GLX_OML_sync_control 1 -#ifndef GLEXT_64_TYPES_DEFINED -/* This code block is duplicated in glext.h, so must be protected */ -#define GLEXT_64_TYPES_DEFINED -/* Define int32_t, int64_t, and uint64_t types for UST/MSC */ -/* (as used in the GLX_OML_sync_control extension). */ -#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L -#include -#elif defined(__sun__) || defined(__digital__) -#include -#if defined(__STDC__) -#if defined(__arch64__) || defined(_LP64) -typedef long int int64_t; -typedef unsigned long int uint64_t; -#else -typedef long long int int64_t; -typedef unsigned long long int uint64_t; -#endif /* __arch64__ */ -#endif /* __STDC__ */ -#elif defined( __VMS ) || defined(__sgi) -#include -#elif defined(__SCO__) || defined(__USLC__) -#include -#elif defined(__UNIXOS2__) || defined(__SOL64__) -typedef long int int32_t; -typedef long long int int64_t; -typedef unsigned long long int uint64_t; -#elif defined(_WIN32) && defined(__GNUC__) -#include -#elif defined(_WIN32) -typedef __int32 int32_t; -typedef __int64 int64_t; -typedef unsigned __int64 uint64_t; -#else -/* Fallback if nothing above works */ -#include -#endif -#endif -typedef Bool ( *PFNGLXGETSYNCVALUESOMLPROC) (Display *dpy, GLXDrawable drawable, int64_t *ust, int64_t *msc, int64_t *sbc); -typedef Bool ( *PFNGLXGETMSCRATEOMLPROC) (Display *dpy, GLXDrawable drawable, int32_t *numerator, int32_t *denominator); -typedef int64_t ( *PFNGLXSWAPBUFFERSMSCOMLPROC) (Display *dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder); -typedef Bool ( *PFNGLXWAITFORMSCOMLPROC) (Display *dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc); -typedef Bool ( *PFNGLXWAITFORSBCOMLPROC) (Display *dpy, GLXDrawable drawable, int64_t target_sbc, int64_t *ust, int64_t *msc, int64_t *sbc); -#ifdef GLX_GLXEXT_PROTOTYPES -Bool glXGetSyncValuesOML (Display *dpy, GLXDrawable drawable, int64_t *ust, int64_t *msc, int64_t *sbc); -Bool glXGetMscRateOML (Display *dpy, GLXDrawable drawable, int32_t *numerator, int32_t *denominator); -int64_t glXSwapBuffersMscOML (Display *dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder); -Bool glXWaitForMscOML (Display *dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc); -Bool glXWaitForSbcOML (Display *dpy, GLXDrawable drawable, int64_t target_sbc, int64_t *ust, int64_t *msc, int64_t *sbc); -#endif -#endif /* GLX_OML_sync_control */ - -#ifndef GLX_SGIS_blended_overlay -#define GLX_SGIS_blended_overlay 1 -#define GLX_BLENDED_RGBA_SGIS 0x8025 -#endif /* GLX_SGIS_blended_overlay */ - -#ifndef GLX_SGIS_multisample -#define GLX_SGIS_multisample 1 -#define GLX_SAMPLE_BUFFERS_SGIS 100000 -#define GLX_SAMPLES_SGIS 100001 -#endif /* GLX_SGIS_multisample */ - -#ifndef GLX_SGIS_shared_multisample -#define GLX_SGIS_shared_multisample 1 -#define GLX_MULTISAMPLE_SUB_RECT_WIDTH_SGIS 0x8026 -#define GLX_MULTISAMPLE_SUB_RECT_HEIGHT_SGIS 0x8027 -#endif /* GLX_SGIS_shared_multisample */ - -#ifndef GLX_SGIX_dmbuffer -#define GLX_SGIX_dmbuffer 1 -typedef XID GLXPbufferSGIX; -#ifdef _DM_BUFFER_H_ -#define GLX_DIGITAL_MEDIA_PBUFFER_SGIX 0x8024 -typedef Bool ( *PFNGLXASSOCIATEDMPBUFFERSGIXPROC) (Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer); -#ifdef GLX_GLXEXT_PROTOTYPES -Bool glXAssociateDMPbufferSGIX (Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer); -#endif -#endif /* _DM_BUFFER_H_ */ -#endif /* GLX_SGIX_dmbuffer */ - -#ifndef GLX_SGIX_fbconfig -#define GLX_SGIX_fbconfig 1 -typedef struct __GLXFBConfigRec *GLXFBConfigSGIX; -#define GLX_WINDOW_BIT_SGIX 0x00000001 -#define GLX_PIXMAP_BIT_SGIX 0x00000002 -#define GLX_RGBA_BIT_SGIX 0x00000001 -#define GLX_COLOR_INDEX_BIT_SGIX 0x00000002 -#define GLX_DRAWABLE_TYPE_SGIX 0x8010 -#define GLX_RENDER_TYPE_SGIX 0x8011 -#define GLX_X_RENDERABLE_SGIX 0x8012 -#define GLX_FBCONFIG_ID_SGIX 0x8013 -#define GLX_RGBA_TYPE_SGIX 0x8014 -#define GLX_COLOR_INDEX_TYPE_SGIX 0x8015 -typedef int ( *PFNGLXGETFBCONFIGATTRIBSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, int attribute, int *value); -typedef GLXFBConfigSGIX *( *PFNGLXCHOOSEFBCONFIGSGIXPROC) (Display *dpy, int screen, int *attrib_list, int *nelements); -typedef GLXPixmap ( *PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap); -typedef GLXContext ( *PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct); -typedef XVisualInfo *( *PFNGLXGETVISUALFROMFBCONFIGSGIXPROC) (Display *dpy, GLXFBConfigSGIX config); -typedef GLXFBConfigSGIX ( *PFNGLXGETFBCONFIGFROMVISUALSGIXPROC) (Display *dpy, XVisualInfo *vis); -#ifdef GLX_GLXEXT_PROTOTYPES -int glXGetFBConfigAttribSGIX (Display *dpy, GLXFBConfigSGIX config, int attribute, int *value); -GLXFBConfigSGIX *glXChooseFBConfigSGIX (Display *dpy, int screen, int *attrib_list, int *nelements); -GLXPixmap glXCreateGLXPixmapWithConfigSGIX (Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap); -GLXContext glXCreateContextWithConfigSGIX (Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct); -XVisualInfo *glXGetVisualFromFBConfigSGIX (Display *dpy, GLXFBConfigSGIX config); -GLXFBConfigSGIX glXGetFBConfigFromVisualSGIX (Display *dpy, XVisualInfo *vis); -#endif -#endif /* GLX_SGIX_fbconfig */ - -#ifndef GLX_SGIX_hyperpipe -#define GLX_SGIX_hyperpipe 1 -typedef struct { - char pipeName[80]; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */ - int networkId; -} GLXHyperpipeNetworkSGIX; -typedef struct { - char pipeName[80]; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */ - int channel; - unsigned int participationType; - int timeSlice; -} GLXHyperpipeConfigSGIX; -typedef struct { - char pipeName[80]; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */ - int srcXOrigin, srcYOrigin, srcWidth, srcHeight; - int destXOrigin, destYOrigin, destWidth, destHeight; -} GLXPipeRect; -typedef struct { - char pipeName[80]; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */ - int XOrigin, YOrigin, maxHeight, maxWidth; -} GLXPipeRectLimits; -#define GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX 80 -#define GLX_BAD_HYPERPIPE_CONFIG_SGIX 91 -#define GLX_BAD_HYPERPIPE_SGIX 92 -#define GLX_HYPERPIPE_DISPLAY_PIPE_SGIX 0x00000001 -#define GLX_HYPERPIPE_RENDER_PIPE_SGIX 0x00000002 -#define GLX_PIPE_RECT_SGIX 0x00000001 -#define GLX_PIPE_RECT_LIMITS_SGIX 0x00000002 -#define GLX_HYPERPIPE_STEREO_SGIX 0x00000003 -#define GLX_HYPERPIPE_PIXEL_AVERAGE_SGIX 0x00000004 -#define GLX_HYPERPIPE_ID_SGIX 0x8030 -typedef GLXHyperpipeNetworkSGIX *( *PFNGLXQUERYHYPERPIPENETWORKSGIXPROC) (Display *dpy, int *npipes); -typedef int ( *PFNGLXHYPERPIPECONFIGSGIXPROC) (Display *dpy, int networkId, int npipes, GLXHyperpipeConfigSGIX *cfg, int *hpId); -typedef GLXHyperpipeConfigSGIX *( *PFNGLXQUERYHYPERPIPECONFIGSGIXPROC) (Display *dpy, int hpId, int *npipes); -typedef int ( *PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC) (Display *dpy, int hpId); -typedef int ( *PFNGLXBINDHYPERPIPESGIXPROC) (Display *dpy, int hpId); -typedef int ( *PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *attribList, void *returnAttribList); -typedef int ( *PFNGLXHYPERPIPEATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *attribList); -typedef int ( *PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *returnAttribList); -#ifdef GLX_GLXEXT_PROTOTYPES -GLXHyperpipeNetworkSGIX *glXQueryHyperpipeNetworkSGIX (Display *dpy, int *npipes); -int glXHyperpipeConfigSGIX (Display *dpy, int networkId, int npipes, GLXHyperpipeConfigSGIX *cfg, int *hpId); -GLXHyperpipeConfigSGIX *glXQueryHyperpipeConfigSGIX (Display *dpy, int hpId, int *npipes); -int glXDestroyHyperpipeConfigSGIX (Display *dpy, int hpId); -int glXBindHyperpipeSGIX (Display *dpy, int hpId); -int glXQueryHyperpipeBestAttribSGIX (Display *dpy, int timeSlice, int attrib, int size, void *attribList, void *returnAttribList); -int glXHyperpipeAttribSGIX (Display *dpy, int timeSlice, int attrib, int size, void *attribList); -int glXQueryHyperpipeAttribSGIX (Display *dpy, int timeSlice, int attrib, int size, void *returnAttribList); -#endif -#endif /* GLX_SGIX_hyperpipe */ - -#ifndef GLX_SGIX_pbuffer -#define GLX_SGIX_pbuffer 1 -#define GLX_PBUFFER_BIT_SGIX 0x00000004 -#define GLX_BUFFER_CLOBBER_MASK_SGIX 0x08000000 -#define GLX_FRONT_LEFT_BUFFER_BIT_SGIX 0x00000001 -#define GLX_FRONT_RIGHT_BUFFER_BIT_SGIX 0x00000002 -#define GLX_BACK_LEFT_BUFFER_BIT_SGIX 0x00000004 -#define GLX_BACK_RIGHT_BUFFER_BIT_SGIX 0x00000008 -#define GLX_AUX_BUFFERS_BIT_SGIX 0x00000010 -#define GLX_DEPTH_BUFFER_BIT_SGIX 0x00000020 -#define GLX_STENCIL_BUFFER_BIT_SGIX 0x00000040 -#define GLX_ACCUM_BUFFER_BIT_SGIX 0x00000080 -#define GLX_SAMPLE_BUFFERS_BIT_SGIX 0x00000100 -#define GLX_MAX_PBUFFER_WIDTH_SGIX 0x8016 -#define GLX_MAX_PBUFFER_HEIGHT_SGIX 0x8017 -#define GLX_MAX_PBUFFER_PIXELS_SGIX 0x8018 -#define GLX_OPTIMAL_PBUFFER_WIDTH_SGIX 0x8019 -#define GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX 0x801A -#define GLX_PRESERVED_CONTENTS_SGIX 0x801B -#define GLX_LARGEST_PBUFFER_SGIX 0x801C -#define GLX_WIDTH_SGIX 0x801D -#define GLX_HEIGHT_SGIX 0x801E -#define GLX_EVENT_MASK_SGIX 0x801F -#define GLX_DAMAGED_SGIX 0x8020 -#define GLX_SAVED_SGIX 0x8021 -#define GLX_WINDOW_SGIX 0x8022 -#define GLX_PBUFFER_SGIX 0x8023 -typedef GLXPbufferSGIX ( *PFNGLXCREATEGLXPBUFFERSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int *attrib_list); -typedef void ( *PFNGLXDESTROYGLXPBUFFERSGIXPROC) (Display *dpy, GLXPbufferSGIX pbuf); -typedef int ( *PFNGLXQUERYGLXPBUFFERSGIXPROC) (Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value); -typedef void ( *PFNGLXSELECTEVENTSGIXPROC) (Display *dpy, GLXDrawable drawable, unsigned long mask); -typedef void ( *PFNGLXGETSELECTEDEVENTSGIXPROC) (Display *dpy, GLXDrawable drawable, unsigned long *mask); -#ifdef GLX_GLXEXT_PROTOTYPES -GLXPbufferSGIX glXCreateGLXPbufferSGIX (Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int *attrib_list); -void glXDestroyGLXPbufferSGIX (Display *dpy, GLXPbufferSGIX pbuf); -int glXQueryGLXPbufferSGIX (Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value); -void glXSelectEventSGIX (Display *dpy, GLXDrawable drawable, unsigned long mask); -void glXGetSelectedEventSGIX (Display *dpy, GLXDrawable drawable, unsigned long *mask); -#endif -#endif /* GLX_SGIX_pbuffer */ - -#ifndef GLX_SGIX_swap_barrier -#define GLX_SGIX_swap_barrier 1 -typedef void ( *PFNGLXBINDSWAPBARRIERSGIXPROC) (Display *dpy, GLXDrawable drawable, int barrier); -typedef Bool ( *PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC) (Display *dpy, int screen, int *max); -#ifdef GLX_GLXEXT_PROTOTYPES -void glXBindSwapBarrierSGIX (Display *dpy, GLXDrawable drawable, int barrier); -Bool glXQueryMaxSwapBarriersSGIX (Display *dpy, int screen, int *max); -#endif -#endif /* GLX_SGIX_swap_barrier */ - -#ifndef GLX_SGIX_swap_group -#define GLX_SGIX_swap_group 1 -typedef void ( *PFNGLXJOINSWAPGROUPSGIXPROC) (Display *dpy, GLXDrawable drawable, GLXDrawable member); -#ifdef GLX_GLXEXT_PROTOTYPES -void glXJoinSwapGroupSGIX (Display *dpy, GLXDrawable drawable, GLXDrawable member); -#endif -#endif /* GLX_SGIX_swap_group */ - -#ifndef GLX_SGIX_video_resize -#define GLX_SGIX_video_resize 1 -#define GLX_SYNC_FRAME_SGIX 0x00000000 -#define GLX_SYNC_SWAP_SGIX 0x00000001 -typedef int ( *PFNGLXBINDCHANNELTOWINDOWSGIXPROC) (Display *display, int screen, int channel, Window window); -typedef int ( *PFNGLXCHANNELRECTSGIXPROC) (Display *display, int screen, int channel, int x, int y, int w, int h); -typedef int ( *PFNGLXQUERYCHANNELRECTSGIXPROC) (Display *display, int screen, int channel, int *dx, int *dy, int *dw, int *dh); -typedef int ( *PFNGLXQUERYCHANNELDELTASSGIXPROC) (Display *display, int screen, int channel, int *x, int *y, int *w, int *h); -typedef int ( *PFNGLXCHANNELRECTSYNCSGIXPROC) (Display *display, int screen, int channel, GLenum synctype); -#ifdef GLX_GLXEXT_PROTOTYPES -int glXBindChannelToWindowSGIX (Display *display, int screen, int channel, Window window); -int glXChannelRectSGIX (Display *display, int screen, int channel, int x, int y, int w, int h); -int glXQueryChannelRectSGIX (Display *display, int screen, int channel, int *dx, int *dy, int *dw, int *dh); -int glXQueryChannelDeltasSGIX (Display *display, int screen, int channel, int *x, int *y, int *w, int *h); -int glXChannelRectSyncSGIX (Display *display, int screen, int channel, GLenum synctype); -#endif -#endif /* GLX_SGIX_video_resize */ - -#ifndef GLX_SGIX_video_source -#define GLX_SGIX_video_source 1 -typedef XID GLXVideoSourceSGIX; -#ifdef _VL_H -typedef GLXVideoSourceSGIX ( *PFNGLXCREATEGLXVIDEOSOURCESGIXPROC) (Display *display, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode); -typedef void ( *PFNGLXDESTROYGLXVIDEOSOURCESGIXPROC) (Display *dpy, GLXVideoSourceSGIX glxvideosource); -#ifdef GLX_GLXEXT_PROTOTYPES -GLXVideoSourceSGIX glXCreateGLXVideoSourceSGIX (Display *display, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode); -void glXDestroyGLXVideoSourceSGIX (Display *dpy, GLXVideoSourceSGIX glxvideosource); -#endif -#endif /* _VL_H */ -#endif /* GLX_SGIX_video_source */ - -#ifndef GLX_SGIX_visual_select_group -#define GLX_SGIX_visual_select_group 1 -#define GLX_VISUAL_SELECT_GROUP_SGIX 0x8028 -#endif /* GLX_SGIX_visual_select_group */ - -#ifndef GLX_SGI_cushion -#define GLX_SGI_cushion 1 -typedef void ( *PFNGLXCUSHIONSGIPROC) (Display *dpy, Window window, float cushion); -#ifdef GLX_GLXEXT_PROTOTYPES -void glXCushionSGI (Display *dpy, Window window, float cushion); -#endif -#endif /* GLX_SGI_cushion */ - -#ifndef GLX_SGI_make_current_read -#define GLX_SGI_make_current_read 1 -typedef Bool ( *PFNGLXMAKECURRENTREADSGIPROC) (Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx); -typedef GLXDrawable ( *PFNGLXGETCURRENTREADDRAWABLESGIPROC) (void); -#ifdef GLX_GLXEXT_PROTOTYPES -Bool glXMakeCurrentReadSGI (Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx); -GLXDrawable glXGetCurrentReadDrawableSGI (void); -#endif -#endif /* GLX_SGI_make_current_read */ - -#ifndef GLX_SGI_swap_control -#define GLX_SGI_swap_control 1 -typedef int ( *PFNGLXSWAPINTERVALSGIPROC) (int interval); -#ifdef GLX_GLXEXT_PROTOTYPES -int glXSwapIntervalSGI (int interval); -#endif -#endif /* GLX_SGI_swap_control */ - -#ifndef GLX_SGI_video_sync -#define GLX_SGI_video_sync 1 -typedef int ( *PFNGLXGETVIDEOSYNCSGIPROC) (unsigned int *count); -typedef int ( *PFNGLXWAITVIDEOSYNCSGIPROC) (int divisor, int remainder, unsigned int *count); -#ifdef GLX_GLXEXT_PROTOTYPES -int glXGetVideoSyncSGI (unsigned int *count); -int glXWaitVideoSyncSGI (int divisor, int remainder, unsigned int *count); -#endif -#endif /* GLX_SGI_video_sync */ - -#ifndef GLX_SUN_get_transparent_index -#define GLX_SUN_get_transparent_index 1 -typedef Status ( *PFNGLXGETTRANSPARENTINDEXSUNPROC) (Display *dpy, Window overlay, Window underlay, long *pTransparentIndex); -#ifdef GLX_GLXEXT_PROTOTYPES -Status glXGetTransparentIndexSUN (Display *dpy, Window overlay, Window underlay, long *pTransparentIndex); -#endif -#endif /* GLX_SUN_get_transparent_index */ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/examples/common/glfw/deps/GL/wglext.h b/examples/common/glfw/deps/GL/wglext.h deleted file mode 100644 index daba4109..00000000 --- a/examples/common/glfw/deps/GL/wglext.h +++ /dev/null @@ -1,840 +0,0 @@ -#ifndef __wglext_h_ -#define __wglext_h_ 1 - -#ifdef __cplusplus -extern "C" { -#endif - -/* -** Copyright (c) 2013-2014 The Khronos Group Inc. -** -** Permission is hereby granted, free of charge, to any person obtaining a -** copy of this software and/or associated documentation files (the -** "Materials"), to deal in the Materials without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Materials, and to -** permit persons to whom the Materials are furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be included -** in all copies or substantial portions of the Materials. -** -** THE MATERIALS ARE 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 -** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. -*/ -/* -** This header is generated from the Khronos OpenGL / OpenGL ES XML -** API Registry. The current version of the Registry, generator scripts -** used to make the header, and the header can be found at -** http://www.opengl.org/registry/ -** -** Khronos $Revision: 27684 $ on $Date: 2014-08-11 01:21:35 -0700 (Mon, 11 Aug 2014) $ -*/ - -#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) -#define WIN32_LEAN_AND_MEAN 1 -#include -#endif - -#define WGL_WGLEXT_VERSION 20140810 - -/* Generated C header for: - * API: wgl - * Versions considered: .* - * Versions emitted: _nomatch_^ - * Default extensions included: wgl - * Additional extensions included: _nomatch_^ - * Extensions removed: _nomatch_^ - */ - -#ifndef WGL_ARB_buffer_region -#define WGL_ARB_buffer_region 1 -#define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001 -#define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002 -#define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004 -#define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008 -typedef HANDLE (WINAPI * PFNWGLCREATEBUFFERREGIONARBPROC) (HDC hDC, int iLayerPlane, UINT uType); -typedef VOID (WINAPI * PFNWGLDELETEBUFFERREGIONARBPROC) (HANDLE hRegion); -typedef BOOL (WINAPI * PFNWGLSAVEBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height); -typedef BOOL (WINAPI * PFNWGLRESTOREBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc); -#ifdef WGL_WGLEXT_PROTOTYPES -HANDLE WINAPI wglCreateBufferRegionARB (HDC hDC, int iLayerPlane, UINT uType); -VOID WINAPI wglDeleteBufferRegionARB (HANDLE hRegion); -BOOL WINAPI wglSaveBufferRegionARB (HANDLE hRegion, int x, int y, int width, int height); -BOOL WINAPI wglRestoreBufferRegionARB (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc); -#endif -#endif /* WGL_ARB_buffer_region */ - -#ifndef WGL_ARB_context_flush_control -#define WGL_ARB_context_flush_control 1 -#define WGL_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097 -#define WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0 -#define WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098 -#endif /* WGL_ARB_context_flush_control */ - -#ifndef WGL_ARB_create_context -#define WGL_ARB_create_context 1 -#define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001 -#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002 -#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 -#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 -#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093 -#define WGL_CONTEXT_FLAGS_ARB 0x2094 -#define ERROR_INVALID_VERSION_ARB 0x2095 -typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int *attribList); -#ifdef WGL_WGLEXT_PROTOTYPES -HGLRC WINAPI wglCreateContextAttribsARB (HDC hDC, HGLRC hShareContext, const int *attribList); -#endif -#endif /* WGL_ARB_create_context */ - -#ifndef WGL_ARB_create_context_profile -#define WGL_ARB_create_context_profile 1 -#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 -#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 -#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 -#define ERROR_INVALID_PROFILE_ARB 0x2096 -#endif /* WGL_ARB_create_context_profile */ - -#ifndef WGL_ARB_create_context_robustness -#define WGL_ARB_create_context_robustness 1 -#define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004 -#define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252 -#define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 -#define WGL_NO_RESET_NOTIFICATION_ARB 0x8261 -#endif /* WGL_ARB_create_context_robustness */ - -#ifndef WGL_ARB_extensions_string -#define WGL_ARB_extensions_string 1 -typedef const char *(WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc); -#ifdef WGL_WGLEXT_PROTOTYPES -const char *WINAPI wglGetExtensionsStringARB (HDC hdc); -#endif -#endif /* WGL_ARB_extensions_string */ - -#ifndef WGL_ARB_framebuffer_sRGB -#define WGL_ARB_framebuffer_sRGB 1 -#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9 -#endif /* WGL_ARB_framebuffer_sRGB */ - -#ifndef WGL_ARB_make_current_read -#define WGL_ARB_make_current_read 1 -#define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043 -#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054 -typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTARBPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); -typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCARBPROC) (void); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglMakeContextCurrentARB (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); -HDC WINAPI wglGetCurrentReadDCARB (void); -#endif -#endif /* WGL_ARB_make_current_read */ - -#ifndef WGL_ARB_multisample -#define WGL_ARB_multisample 1 -#define WGL_SAMPLE_BUFFERS_ARB 0x2041 -#define WGL_SAMPLES_ARB 0x2042 -#endif /* WGL_ARB_multisample */ - -#ifndef WGL_ARB_pbuffer -#define WGL_ARB_pbuffer 1 -DECLARE_HANDLE(HPBUFFERARB); -#define WGL_DRAW_TO_PBUFFER_ARB 0x202D -#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E -#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F -#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030 -#define WGL_PBUFFER_LARGEST_ARB 0x2033 -#define WGL_PBUFFER_WIDTH_ARB 0x2034 -#define WGL_PBUFFER_HEIGHT_ARB 0x2035 -#define WGL_PBUFFER_LOST_ARB 0x2036 -typedef HPBUFFERARB (WINAPI * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); -typedef HDC (WINAPI * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer); -typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC); -typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer); -typedef BOOL (WINAPI * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int *piValue); -#ifdef WGL_WGLEXT_PROTOTYPES -HPBUFFERARB WINAPI wglCreatePbufferARB (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); -HDC WINAPI wglGetPbufferDCARB (HPBUFFERARB hPbuffer); -int WINAPI wglReleasePbufferDCARB (HPBUFFERARB hPbuffer, HDC hDC); -BOOL WINAPI wglDestroyPbufferARB (HPBUFFERARB hPbuffer); -BOOL WINAPI wglQueryPbufferARB (HPBUFFERARB hPbuffer, int iAttribute, int *piValue); -#endif -#endif /* WGL_ARB_pbuffer */ - -#ifndef WGL_ARB_pixel_format -#define WGL_ARB_pixel_format 1 -#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 -#define WGL_DRAW_TO_WINDOW_ARB 0x2001 -#define WGL_DRAW_TO_BITMAP_ARB 0x2002 -#define WGL_ACCELERATION_ARB 0x2003 -#define WGL_NEED_PALETTE_ARB 0x2004 -#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 -#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 -#define WGL_SWAP_METHOD_ARB 0x2007 -#define WGL_NUMBER_OVERLAYS_ARB 0x2008 -#define WGL_NUMBER_UNDERLAYS_ARB 0x2009 -#define WGL_TRANSPARENT_ARB 0x200A -#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 -#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 -#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 -#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A -#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B -#define WGL_SHARE_DEPTH_ARB 0x200C -#define WGL_SHARE_STENCIL_ARB 0x200D -#define WGL_SHARE_ACCUM_ARB 0x200E -#define WGL_SUPPORT_GDI_ARB 0x200F -#define WGL_SUPPORT_OPENGL_ARB 0x2010 -#define WGL_DOUBLE_BUFFER_ARB 0x2011 -#define WGL_STEREO_ARB 0x2012 -#define WGL_PIXEL_TYPE_ARB 0x2013 -#define WGL_COLOR_BITS_ARB 0x2014 -#define WGL_RED_BITS_ARB 0x2015 -#define WGL_RED_SHIFT_ARB 0x2016 -#define WGL_GREEN_BITS_ARB 0x2017 -#define WGL_GREEN_SHIFT_ARB 0x2018 -#define WGL_BLUE_BITS_ARB 0x2019 -#define WGL_BLUE_SHIFT_ARB 0x201A -#define WGL_ALPHA_BITS_ARB 0x201B -#define WGL_ALPHA_SHIFT_ARB 0x201C -#define WGL_ACCUM_BITS_ARB 0x201D -#define WGL_ACCUM_RED_BITS_ARB 0x201E -#define WGL_ACCUM_GREEN_BITS_ARB 0x201F -#define WGL_ACCUM_BLUE_BITS_ARB 0x2020 -#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 -#define WGL_DEPTH_BITS_ARB 0x2022 -#define WGL_STENCIL_BITS_ARB 0x2023 -#define WGL_AUX_BUFFERS_ARB 0x2024 -#define WGL_NO_ACCELERATION_ARB 0x2025 -#define WGL_GENERIC_ACCELERATION_ARB 0x2026 -#define WGL_FULL_ACCELERATION_ARB 0x2027 -#define WGL_SWAP_EXCHANGE_ARB 0x2028 -#define WGL_SWAP_COPY_ARB 0x2029 -#define WGL_SWAP_UNDEFINED_ARB 0x202A -#define WGL_TYPE_RGBA_ARB 0x202B -#define WGL_TYPE_COLORINDEX_ARB 0x202C -typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues); -typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues); -typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglGetPixelFormatAttribivARB (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues); -BOOL WINAPI wglGetPixelFormatAttribfvARB (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues); -BOOL WINAPI wglChoosePixelFormatARB (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); -#endif -#endif /* WGL_ARB_pixel_format */ - -#ifndef WGL_ARB_pixel_format_float -#define WGL_ARB_pixel_format_float 1 -#define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0 -#endif /* WGL_ARB_pixel_format_float */ - -#ifndef WGL_ARB_render_texture -#define WGL_ARB_render_texture 1 -#define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070 -#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071 -#define WGL_TEXTURE_FORMAT_ARB 0x2072 -#define WGL_TEXTURE_TARGET_ARB 0x2073 -#define WGL_MIPMAP_TEXTURE_ARB 0x2074 -#define WGL_TEXTURE_RGB_ARB 0x2075 -#define WGL_TEXTURE_RGBA_ARB 0x2076 -#define WGL_NO_TEXTURE_ARB 0x2077 -#define WGL_TEXTURE_CUBE_MAP_ARB 0x2078 -#define WGL_TEXTURE_1D_ARB 0x2079 -#define WGL_TEXTURE_2D_ARB 0x207A -#define WGL_MIPMAP_LEVEL_ARB 0x207B -#define WGL_CUBE_MAP_FACE_ARB 0x207C -#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D -#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E -#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F -#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080 -#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081 -#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082 -#define WGL_FRONT_LEFT_ARB 0x2083 -#define WGL_FRONT_RIGHT_ARB 0x2084 -#define WGL_BACK_LEFT_ARB 0x2085 -#define WGL_BACK_RIGHT_ARB 0x2086 -#define WGL_AUX0_ARB 0x2087 -#define WGL_AUX1_ARB 0x2088 -#define WGL_AUX2_ARB 0x2089 -#define WGL_AUX3_ARB 0x208A -#define WGL_AUX4_ARB 0x208B -#define WGL_AUX5_ARB 0x208C -#define WGL_AUX6_ARB 0x208D -#define WGL_AUX7_ARB 0x208E -#define WGL_AUX8_ARB 0x208F -#define WGL_AUX9_ARB 0x2090 -typedef BOOL (WINAPI * PFNWGLBINDTEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); -typedef BOOL (WINAPI * PFNWGLRELEASETEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); -typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, const int *piAttribList); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglBindTexImageARB (HPBUFFERARB hPbuffer, int iBuffer); -BOOL WINAPI wglReleaseTexImageARB (HPBUFFERARB hPbuffer, int iBuffer); -BOOL WINAPI wglSetPbufferAttribARB (HPBUFFERARB hPbuffer, const int *piAttribList); -#endif -#endif /* WGL_ARB_render_texture */ - -#ifndef WGL_ARB_robustness_application_isolation -#define WGL_ARB_robustness_application_isolation 1 -#define WGL_CONTEXT_RESET_ISOLATION_BIT_ARB 0x00000008 -#endif /* WGL_ARB_robustness_application_isolation */ - -#ifndef WGL_ARB_robustness_share_group_isolation -#define WGL_ARB_robustness_share_group_isolation 1 -#endif /* WGL_ARB_robustness_share_group_isolation */ - -#ifndef WGL_3DFX_multisample -#define WGL_3DFX_multisample 1 -#define WGL_SAMPLE_BUFFERS_3DFX 0x2060 -#define WGL_SAMPLES_3DFX 0x2061 -#endif /* WGL_3DFX_multisample */ - -#ifndef WGL_3DL_stereo_control -#define WGL_3DL_stereo_control 1 -#define WGL_STEREO_EMITTER_ENABLE_3DL 0x2055 -#define WGL_STEREO_EMITTER_DISABLE_3DL 0x2056 -#define WGL_STEREO_POLARITY_NORMAL_3DL 0x2057 -#define WGL_STEREO_POLARITY_INVERT_3DL 0x2058 -typedef BOOL (WINAPI * PFNWGLSETSTEREOEMITTERSTATE3DLPROC) (HDC hDC, UINT uState); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglSetStereoEmitterState3DL (HDC hDC, UINT uState); -#endif -#endif /* WGL_3DL_stereo_control */ - -#ifndef WGL_AMD_gpu_association -#define WGL_AMD_gpu_association 1 -#define WGL_GPU_VENDOR_AMD 0x1F00 -#define WGL_GPU_RENDERER_STRING_AMD 0x1F01 -#define WGL_GPU_OPENGL_VERSION_STRING_AMD 0x1F02 -#define WGL_GPU_FASTEST_TARGET_GPUS_AMD 0x21A2 -#define WGL_GPU_RAM_AMD 0x21A3 -#define WGL_GPU_CLOCK_AMD 0x21A4 -#define WGL_GPU_NUM_PIPES_AMD 0x21A5 -#define WGL_GPU_NUM_SIMD_AMD 0x21A6 -#define WGL_GPU_NUM_RB_AMD 0x21A7 -#define WGL_GPU_NUM_SPI_AMD 0x21A8 -typedef UINT (WINAPI * PFNWGLGETGPUIDSAMDPROC) (UINT maxCount, UINT *ids); -typedef INT (WINAPI * PFNWGLGETGPUINFOAMDPROC) (UINT id, int property, GLenum dataType, UINT size, void *data); -typedef UINT (WINAPI * PFNWGLGETCONTEXTGPUIDAMDPROC) (HGLRC hglrc); -typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC) (UINT id); -typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC) (UINT id, HGLRC hShareContext, const int *attribList); -typedef BOOL (WINAPI * PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC) (HGLRC hglrc); -typedef BOOL (WINAPI * PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC) (HGLRC hglrc); -typedef HGLRC (WINAPI * PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC) (void); -typedef VOID (WINAPI * PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC) (HGLRC dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -#ifdef WGL_WGLEXT_PROTOTYPES -UINT WINAPI wglGetGPUIDsAMD (UINT maxCount, UINT *ids); -INT WINAPI wglGetGPUInfoAMD (UINT id, int property, GLenum dataType, UINT size, void *data); -UINT WINAPI wglGetContextGPUIDAMD (HGLRC hglrc); -HGLRC WINAPI wglCreateAssociatedContextAMD (UINT id); -HGLRC WINAPI wglCreateAssociatedContextAttribsAMD (UINT id, HGLRC hShareContext, const int *attribList); -BOOL WINAPI wglDeleteAssociatedContextAMD (HGLRC hglrc); -BOOL WINAPI wglMakeAssociatedContextCurrentAMD (HGLRC hglrc); -HGLRC WINAPI wglGetCurrentAssociatedContextAMD (void); -VOID WINAPI wglBlitContextFramebufferAMD (HGLRC dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -#endif -#endif /* WGL_AMD_gpu_association */ - -#ifndef WGL_ATI_pixel_format_float -#define WGL_ATI_pixel_format_float 1 -#define WGL_TYPE_RGBA_FLOAT_ATI 0x21A0 -#endif /* WGL_ATI_pixel_format_float */ - -#ifndef WGL_EXT_create_context_es2_profile -#define WGL_EXT_create_context_es2_profile 1 -#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004 -#endif /* WGL_EXT_create_context_es2_profile */ - -#ifndef WGL_EXT_create_context_es_profile -#define WGL_EXT_create_context_es_profile 1 -#define WGL_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004 -#endif /* WGL_EXT_create_context_es_profile */ - -#ifndef WGL_EXT_depth_float -#define WGL_EXT_depth_float 1 -#define WGL_DEPTH_FLOAT_EXT 0x2040 -#endif /* WGL_EXT_depth_float */ - -#ifndef WGL_EXT_display_color_table -#define WGL_EXT_display_color_table 1 -typedef GLboolean (WINAPI * PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC) (GLushort id); -typedef GLboolean (WINAPI * PFNWGLLOADDISPLAYCOLORTABLEEXTPROC) (const GLushort *table, GLuint length); -typedef GLboolean (WINAPI * PFNWGLBINDDISPLAYCOLORTABLEEXTPROC) (GLushort id); -typedef VOID (WINAPI * PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC) (GLushort id); -#ifdef WGL_WGLEXT_PROTOTYPES -GLboolean WINAPI wglCreateDisplayColorTableEXT (GLushort id); -GLboolean WINAPI wglLoadDisplayColorTableEXT (const GLushort *table, GLuint length); -GLboolean WINAPI wglBindDisplayColorTableEXT (GLushort id); -VOID WINAPI wglDestroyDisplayColorTableEXT (GLushort id); -#endif -#endif /* WGL_EXT_display_color_table */ - -#ifndef WGL_EXT_extensions_string -#define WGL_EXT_extensions_string 1 -typedef const char *(WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC) (void); -#ifdef WGL_WGLEXT_PROTOTYPES -const char *WINAPI wglGetExtensionsStringEXT (void); -#endif -#endif /* WGL_EXT_extensions_string */ - -#ifndef WGL_EXT_framebuffer_sRGB -#define WGL_EXT_framebuffer_sRGB 1 -#define WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20A9 -#endif /* WGL_EXT_framebuffer_sRGB */ - -#ifndef WGL_EXT_make_current_read -#define WGL_EXT_make_current_read 1 -#define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043 -typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTEXTPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); -typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCEXTPROC) (void); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglMakeContextCurrentEXT (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); -HDC WINAPI wglGetCurrentReadDCEXT (void); -#endif -#endif /* WGL_EXT_make_current_read */ - -#ifndef WGL_EXT_multisample -#define WGL_EXT_multisample 1 -#define WGL_SAMPLE_BUFFERS_EXT 0x2041 -#define WGL_SAMPLES_EXT 0x2042 -#endif /* WGL_EXT_multisample */ - -#ifndef WGL_EXT_pbuffer -#define WGL_EXT_pbuffer 1 -DECLARE_HANDLE(HPBUFFEREXT); -#define WGL_DRAW_TO_PBUFFER_EXT 0x202D -#define WGL_MAX_PBUFFER_PIXELS_EXT 0x202E -#define WGL_MAX_PBUFFER_WIDTH_EXT 0x202F -#define WGL_MAX_PBUFFER_HEIGHT_EXT 0x2030 -#define WGL_OPTIMAL_PBUFFER_WIDTH_EXT 0x2031 -#define WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032 -#define WGL_PBUFFER_LARGEST_EXT 0x2033 -#define WGL_PBUFFER_WIDTH_EXT 0x2034 -#define WGL_PBUFFER_HEIGHT_EXT 0x2035 -typedef HPBUFFEREXT (WINAPI * PFNWGLCREATEPBUFFEREXTPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); -typedef HDC (WINAPI * PFNWGLGETPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer); -typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer, HDC hDC); -typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer); -typedef BOOL (WINAPI * PFNWGLQUERYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue); -#ifdef WGL_WGLEXT_PROTOTYPES -HPBUFFEREXT WINAPI wglCreatePbufferEXT (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); -HDC WINAPI wglGetPbufferDCEXT (HPBUFFEREXT hPbuffer); -int WINAPI wglReleasePbufferDCEXT (HPBUFFEREXT hPbuffer, HDC hDC); -BOOL WINAPI wglDestroyPbufferEXT (HPBUFFEREXT hPbuffer); -BOOL WINAPI wglQueryPbufferEXT (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue); -#endif -#endif /* WGL_EXT_pbuffer */ - -#ifndef WGL_EXT_pixel_format -#define WGL_EXT_pixel_format 1 -#define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000 -#define WGL_DRAW_TO_WINDOW_EXT 0x2001 -#define WGL_DRAW_TO_BITMAP_EXT 0x2002 -#define WGL_ACCELERATION_EXT 0x2003 -#define WGL_NEED_PALETTE_EXT 0x2004 -#define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005 -#define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006 -#define WGL_SWAP_METHOD_EXT 0x2007 -#define WGL_NUMBER_OVERLAYS_EXT 0x2008 -#define WGL_NUMBER_UNDERLAYS_EXT 0x2009 -#define WGL_TRANSPARENT_EXT 0x200A -#define WGL_TRANSPARENT_VALUE_EXT 0x200B -#define WGL_SHARE_DEPTH_EXT 0x200C -#define WGL_SHARE_STENCIL_EXT 0x200D -#define WGL_SHARE_ACCUM_EXT 0x200E -#define WGL_SUPPORT_GDI_EXT 0x200F -#define WGL_SUPPORT_OPENGL_EXT 0x2010 -#define WGL_DOUBLE_BUFFER_EXT 0x2011 -#define WGL_STEREO_EXT 0x2012 -#define WGL_PIXEL_TYPE_EXT 0x2013 -#define WGL_COLOR_BITS_EXT 0x2014 -#define WGL_RED_BITS_EXT 0x2015 -#define WGL_RED_SHIFT_EXT 0x2016 -#define WGL_GREEN_BITS_EXT 0x2017 -#define WGL_GREEN_SHIFT_EXT 0x2018 -#define WGL_BLUE_BITS_EXT 0x2019 -#define WGL_BLUE_SHIFT_EXT 0x201A -#define WGL_ALPHA_BITS_EXT 0x201B -#define WGL_ALPHA_SHIFT_EXT 0x201C -#define WGL_ACCUM_BITS_EXT 0x201D -#define WGL_ACCUM_RED_BITS_EXT 0x201E -#define WGL_ACCUM_GREEN_BITS_EXT 0x201F -#define WGL_ACCUM_BLUE_BITS_EXT 0x2020 -#define WGL_ACCUM_ALPHA_BITS_EXT 0x2021 -#define WGL_DEPTH_BITS_EXT 0x2022 -#define WGL_STENCIL_BITS_EXT 0x2023 -#define WGL_AUX_BUFFERS_EXT 0x2024 -#define WGL_NO_ACCELERATION_EXT 0x2025 -#define WGL_GENERIC_ACCELERATION_EXT 0x2026 -#define WGL_FULL_ACCELERATION_EXT 0x2027 -#define WGL_SWAP_EXCHANGE_EXT 0x2028 -#define WGL_SWAP_COPY_EXT 0x2029 -#define WGL_SWAP_UNDEFINED_EXT 0x202A -#define WGL_TYPE_RGBA_EXT 0x202B -#define WGL_TYPE_COLORINDEX_EXT 0x202C -typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues); -typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues); -typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATEXTPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglGetPixelFormatAttribivEXT (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues); -BOOL WINAPI wglGetPixelFormatAttribfvEXT (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues); -BOOL WINAPI wglChoosePixelFormatEXT (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); -#endif -#endif /* WGL_EXT_pixel_format */ - -#ifndef WGL_EXT_pixel_format_packed_float -#define WGL_EXT_pixel_format_packed_float 1 -#define WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT 0x20A8 -#endif /* WGL_EXT_pixel_format_packed_float */ - -#ifndef WGL_EXT_swap_control -#define WGL_EXT_swap_control 1 -typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval); -typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglSwapIntervalEXT (int interval); -int WINAPI wglGetSwapIntervalEXT (void); -#endif -#endif /* WGL_EXT_swap_control */ - -#ifndef WGL_EXT_swap_control_tear -#define WGL_EXT_swap_control_tear 1 -#endif /* WGL_EXT_swap_control_tear */ - -#ifndef WGL_I3D_digital_video_control -#define WGL_I3D_digital_video_control 1 -#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050 -#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051 -#define WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052 -#define WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053 -typedef BOOL (WINAPI * PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue); -typedef BOOL (WINAPI * PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglGetDigitalVideoParametersI3D (HDC hDC, int iAttribute, int *piValue); -BOOL WINAPI wglSetDigitalVideoParametersI3D (HDC hDC, int iAttribute, const int *piValue); -#endif -#endif /* WGL_I3D_digital_video_control */ - -#ifndef WGL_I3D_gamma -#define WGL_I3D_gamma 1 -#define WGL_GAMMA_TABLE_SIZE_I3D 0x204E -#define WGL_GAMMA_EXCLUDE_DESKTOP_I3D 0x204F -typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue); -typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue); -typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue); -typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglGetGammaTableParametersI3D (HDC hDC, int iAttribute, int *piValue); -BOOL WINAPI wglSetGammaTableParametersI3D (HDC hDC, int iAttribute, const int *piValue); -BOOL WINAPI wglGetGammaTableI3D (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue); -BOOL WINAPI wglSetGammaTableI3D (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue); -#endif -#endif /* WGL_I3D_gamma */ - -#ifndef WGL_I3D_genlock -#define WGL_I3D_genlock 1 -#define WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044 -#define WGL_GENLOCK_SOURCE_EXTERNAL_SYNC_I3D 0x2045 -#define WGL_GENLOCK_SOURCE_EXTERNAL_FIELD_I3D 0x2046 -#define WGL_GENLOCK_SOURCE_EXTERNAL_TTL_I3D 0x2047 -#define WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048 -#define WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049 -#define WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A -#define WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B -#define WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C -typedef BOOL (WINAPI * PFNWGLENABLEGENLOCKI3DPROC) (HDC hDC); -typedef BOOL (WINAPI * PFNWGLDISABLEGENLOCKI3DPROC) (HDC hDC); -typedef BOOL (WINAPI * PFNWGLISENABLEDGENLOCKI3DPROC) (HDC hDC, BOOL *pFlag); -typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEI3DPROC) (HDC hDC, UINT uSource); -typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEI3DPROC) (HDC hDC, UINT *uSource); -typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT uEdge); -typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT *uEdge); -typedef BOOL (WINAPI * PFNWGLGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT uRate); -typedef BOOL (WINAPI * PFNWGLGETGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT *uRate); -typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT uDelay); -typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT *uDelay); -typedef BOOL (WINAPI * PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC) (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglEnableGenlockI3D (HDC hDC); -BOOL WINAPI wglDisableGenlockI3D (HDC hDC); -BOOL WINAPI wglIsEnabledGenlockI3D (HDC hDC, BOOL *pFlag); -BOOL WINAPI wglGenlockSourceI3D (HDC hDC, UINT uSource); -BOOL WINAPI wglGetGenlockSourceI3D (HDC hDC, UINT *uSource); -BOOL WINAPI wglGenlockSourceEdgeI3D (HDC hDC, UINT uEdge); -BOOL WINAPI wglGetGenlockSourceEdgeI3D (HDC hDC, UINT *uEdge); -BOOL WINAPI wglGenlockSampleRateI3D (HDC hDC, UINT uRate); -BOOL WINAPI wglGetGenlockSampleRateI3D (HDC hDC, UINT *uRate); -BOOL WINAPI wglGenlockSourceDelayI3D (HDC hDC, UINT uDelay); -BOOL WINAPI wglGetGenlockSourceDelayI3D (HDC hDC, UINT *uDelay); -BOOL WINAPI wglQueryGenlockMaxSourceDelayI3D (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay); -#endif -#endif /* WGL_I3D_genlock */ - -#ifndef WGL_I3D_image_buffer -#define WGL_I3D_image_buffer 1 -#define WGL_IMAGE_BUFFER_MIN_ACCESS_I3D 0x00000001 -#define WGL_IMAGE_BUFFER_LOCK_I3D 0x00000002 -typedef LPVOID (WINAPI * PFNWGLCREATEIMAGEBUFFERI3DPROC) (HDC hDC, DWORD dwSize, UINT uFlags); -typedef BOOL (WINAPI * PFNWGLDESTROYIMAGEBUFFERI3DPROC) (HDC hDC, LPVOID pAddress); -typedef BOOL (WINAPI * PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count); -typedef BOOL (WINAPI * PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const LPVOID *pAddress, UINT count); -#ifdef WGL_WGLEXT_PROTOTYPES -LPVOID WINAPI wglCreateImageBufferI3D (HDC hDC, DWORD dwSize, UINT uFlags); -BOOL WINAPI wglDestroyImageBufferI3D (HDC hDC, LPVOID pAddress); -BOOL WINAPI wglAssociateImageBufferEventsI3D (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count); -BOOL WINAPI wglReleaseImageBufferEventsI3D (HDC hDC, const LPVOID *pAddress, UINT count); -#endif -#endif /* WGL_I3D_image_buffer */ - -#ifndef WGL_I3D_swap_frame_lock -#define WGL_I3D_swap_frame_lock 1 -typedef BOOL (WINAPI * PFNWGLENABLEFRAMELOCKI3DPROC) (void); -typedef BOOL (WINAPI * PFNWGLDISABLEFRAMELOCKI3DPROC) (void); -typedef BOOL (WINAPI * PFNWGLISENABLEDFRAMELOCKI3DPROC) (BOOL *pFlag); -typedef BOOL (WINAPI * PFNWGLQUERYFRAMELOCKMASTERI3DPROC) (BOOL *pFlag); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglEnableFrameLockI3D (void); -BOOL WINAPI wglDisableFrameLockI3D (void); -BOOL WINAPI wglIsEnabledFrameLockI3D (BOOL *pFlag); -BOOL WINAPI wglQueryFrameLockMasterI3D (BOOL *pFlag); -#endif -#endif /* WGL_I3D_swap_frame_lock */ - -#ifndef WGL_I3D_swap_frame_usage -#define WGL_I3D_swap_frame_usage 1 -typedef BOOL (WINAPI * PFNWGLGETFRAMEUSAGEI3DPROC) (float *pUsage); -typedef BOOL (WINAPI * PFNWGLBEGINFRAMETRACKINGI3DPROC) (void); -typedef BOOL (WINAPI * PFNWGLENDFRAMETRACKINGI3DPROC) (void); -typedef BOOL (WINAPI * PFNWGLQUERYFRAMETRACKINGI3DPROC) (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglGetFrameUsageI3D (float *pUsage); -BOOL WINAPI wglBeginFrameTrackingI3D (void); -BOOL WINAPI wglEndFrameTrackingI3D (void); -BOOL WINAPI wglQueryFrameTrackingI3D (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage); -#endif -#endif /* WGL_I3D_swap_frame_usage */ - -#ifndef WGL_NV_DX_interop -#define WGL_NV_DX_interop 1 -#define WGL_ACCESS_READ_ONLY_NV 0x00000000 -#define WGL_ACCESS_READ_WRITE_NV 0x00000001 -#define WGL_ACCESS_WRITE_DISCARD_NV 0x00000002 -typedef BOOL (WINAPI * PFNWGLDXSETRESOURCESHAREHANDLENVPROC) (void *dxObject, HANDLE shareHandle); -typedef HANDLE (WINAPI * PFNWGLDXOPENDEVICENVPROC) (void *dxDevice); -typedef BOOL (WINAPI * PFNWGLDXCLOSEDEVICENVPROC) (HANDLE hDevice); -typedef HANDLE (WINAPI * PFNWGLDXREGISTEROBJECTNVPROC) (HANDLE hDevice, void *dxObject, GLuint name, GLenum type, GLenum access); -typedef BOOL (WINAPI * PFNWGLDXUNREGISTEROBJECTNVPROC) (HANDLE hDevice, HANDLE hObject); -typedef BOOL (WINAPI * PFNWGLDXOBJECTACCESSNVPROC) (HANDLE hObject, GLenum access); -typedef BOOL (WINAPI * PFNWGLDXLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE *hObjects); -typedef BOOL (WINAPI * PFNWGLDXUNLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE *hObjects); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglDXSetResourceShareHandleNV (void *dxObject, HANDLE shareHandle); -HANDLE WINAPI wglDXOpenDeviceNV (void *dxDevice); -BOOL WINAPI wglDXCloseDeviceNV (HANDLE hDevice); -HANDLE WINAPI wglDXRegisterObjectNV (HANDLE hDevice, void *dxObject, GLuint name, GLenum type, GLenum access); -BOOL WINAPI wglDXUnregisterObjectNV (HANDLE hDevice, HANDLE hObject); -BOOL WINAPI wglDXObjectAccessNV (HANDLE hObject, GLenum access); -BOOL WINAPI wglDXLockObjectsNV (HANDLE hDevice, GLint count, HANDLE *hObjects); -BOOL WINAPI wglDXUnlockObjectsNV (HANDLE hDevice, GLint count, HANDLE *hObjects); -#endif -#endif /* WGL_NV_DX_interop */ - -#ifndef WGL_NV_DX_interop2 -#define WGL_NV_DX_interop2 1 -#endif /* WGL_NV_DX_interop2 */ - -#ifndef WGL_NV_copy_image -#define WGL_NV_copy_image 1 -typedef BOOL (WINAPI * PFNWGLCOPYIMAGESUBDATANVPROC) (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglCopyImageSubDataNV (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); -#endif -#endif /* WGL_NV_copy_image */ - -#ifndef WGL_NV_delay_before_swap -#define WGL_NV_delay_before_swap 1 -typedef BOOL (WINAPI * PFNWGLDELAYBEFORESWAPNVPROC) (HDC hDC, GLfloat seconds); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglDelayBeforeSwapNV (HDC hDC, GLfloat seconds); -#endif -#endif /* WGL_NV_delay_before_swap */ - -#ifndef WGL_NV_float_buffer -#define WGL_NV_float_buffer 1 -#define WGL_FLOAT_COMPONENTS_NV 0x20B0 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV 0x20B1 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV 0x20B2 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV 0x20B3 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV 0x20B4 -#define WGL_TEXTURE_FLOAT_R_NV 0x20B5 -#define WGL_TEXTURE_FLOAT_RG_NV 0x20B6 -#define WGL_TEXTURE_FLOAT_RGB_NV 0x20B7 -#define WGL_TEXTURE_FLOAT_RGBA_NV 0x20B8 -#endif /* WGL_NV_float_buffer */ - -#ifndef WGL_NV_gpu_affinity -#define WGL_NV_gpu_affinity 1 -DECLARE_HANDLE(HGPUNV); -struct _GPU_DEVICE { - DWORD cb; - CHAR DeviceName[32]; - CHAR DeviceString[128]; - DWORD Flags; - RECT rcVirtualScreen; -}; -typedef struct _GPU_DEVICE *PGPU_DEVICE; -#define ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV 0x20D0 -#define ERROR_MISSING_AFFINITY_MASK_NV 0x20D1 -typedef BOOL (WINAPI * PFNWGLENUMGPUSNVPROC) (UINT iGpuIndex, HGPUNV *phGpu); -typedef BOOL (WINAPI * PFNWGLENUMGPUDEVICESNVPROC) (HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice); -typedef HDC (WINAPI * PFNWGLCREATEAFFINITYDCNVPROC) (const HGPUNV *phGpuList); -typedef BOOL (WINAPI * PFNWGLENUMGPUSFROMAFFINITYDCNVPROC) (HDC hAffinityDC, UINT iGpuIndex, HGPUNV *hGpu); -typedef BOOL (WINAPI * PFNWGLDELETEDCNVPROC) (HDC hdc); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglEnumGpusNV (UINT iGpuIndex, HGPUNV *phGpu); -BOOL WINAPI wglEnumGpuDevicesNV (HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice); -HDC WINAPI wglCreateAffinityDCNV (const HGPUNV *phGpuList); -BOOL WINAPI wglEnumGpusFromAffinityDCNV (HDC hAffinityDC, UINT iGpuIndex, HGPUNV *hGpu); -BOOL WINAPI wglDeleteDCNV (HDC hdc); -#endif -#endif /* WGL_NV_gpu_affinity */ - -#ifndef WGL_NV_multisample_coverage -#define WGL_NV_multisample_coverage 1 -#define WGL_COVERAGE_SAMPLES_NV 0x2042 -#define WGL_COLOR_SAMPLES_NV 0x20B9 -#endif /* WGL_NV_multisample_coverage */ - -#ifndef WGL_NV_present_video -#define WGL_NV_present_video 1 -DECLARE_HANDLE(HVIDEOOUTPUTDEVICENV); -#define WGL_NUM_VIDEO_SLOTS_NV 0x20F0 -typedef int (WINAPI * PFNWGLENUMERATEVIDEODEVICESNVPROC) (HDC hDC, HVIDEOOUTPUTDEVICENV *phDeviceList); -typedef BOOL (WINAPI * PFNWGLBINDVIDEODEVICENVPROC) (HDC hDC, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int *piAttribList); -typedef BOOL (WINAPI * PFNWGLQUERYCURRENTCONTEXTNVPROC) (int iAttribute, int *piValue); -#ifdef WGL_WGLEXT_PROTOTYPES -int WINAPI wglEnumerateVideoDevicesNV (HDC hDC, HVIDEOOUTPUTDEVICENV *phDeviceList); -BOOL WINAPI wglBindVideoDeviceNV (HDC hDC, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int *piAttribList); -BOOL WINAPI wglQueryCurrentContextNV (int iAttribute, int *piValue); -#endif -#endif /* WGL_NV_present_video */ - -#ifndef WGL_NV_render_depth_texture -#define WGL_NV_render_depth_texture 1 -#define WGL_BIND_TO_TEXTURE_DEPTH_NV 0x20A3 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV 0x20A4 -#define WGL_DEPTH_TEXTURE_FORMAT_NV 0x20A5 -#define WGL_TEXTURE_DEPTH_COMPONENT_NV 0x20A6 -#define WGL_DEPTH_COMPONENT_NV 0x20A7 -#endif /* WGL_NV_render_depth_texture */ - -#ifndef WGL_NV_render_texture_rectangle -#define WGL_NV_render_texture_rectangle 1 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1 -#define WGL_TEXTURE_RECTANGLE_NV 0x20A2 -#endif /* WGL_NV_render_texture_rectangle */ - -#ifndef WGL_NV_swap_group -#define WGL_NV_swap_group 1 -typedef BOOL (WINAPI * PFNWGLJOINSWAPGROUPNVPROC) (HDC hDC, GLuint group); -typedef BOOL (WINAPI * PFNWGLBINDSWAPBARRIERNVPROC) (GLuint group, GLuint barrier); -typedef BOOL (WINAPI * PFNWGLQUERYSWAPGROUPNVPROC) (HDC hDC, GLuint *group, GLuint *barrier); -typedef BOOL (WINAPI * PFNWGLQUERYMAXSWAPGROUPSNVPROC) (HDC hDC, GLuint *maxGroups, GLuint *maxBarriers); -typedef BOOL (WINAPI * PFNWGLQUERYFRAMECOUNTNVPROC) (HDC hDC, GLuint *count); -typedef BOOL (WINAPI * PFNWGLRESETFRAMECOUNTNVPROC) (HDC hDC); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglJoinSwapGroupNV (HDC hDC, GLuint group); -BOOL WINAPI wglBindSwapBarrierNV (GLuint group, GLuint barrier); -BOOL WINAPI wglQuerySwapGroupNV (HDC hDC, GLuint *group, GLuint *barrier); -BOOL WINAPI wglQueryMaxSwapGroupsNV (HDC hDC, GLuint *maxGroups, GLuint *maxBarriers); -BOOL WINAPI wglQueryFrameCountNV (HDC hDC, GLuint *count); -BOOL WINAPI wglResetFrameCountNV (HDC hDC); -#endif -#endif /* WGL_NV_swap_group */ - -#ifndef WGL_NV_vertex_array_range -#define WGL_NV_vertex_array_range 1 -typedef void *(WINAPI * PFNWGLALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority); -typedef void (WINAPI * PFNWGLFREEMEMORYNVPROC) (void *pointer); -#ifdef WGL_WGLEXT_PROTOTYPES -void *WINAPI wglAllocateMemoryNV (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority); -void WINAPI wglFreeMemoryNV (void *pointer); -#endif -#endif /* WGL_NV_vertex_array_range */ - -#ifndef WGL_NV_video_capture -#define WGL_NV_video_capture 1 -DECLARE_HANDLE(HVIDEOINPUTDEVICENV); -#define WGL_UNIQUE_ID_NV 0x20CE -#define WGL_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF -typedef BOOL (WINAPI * PFNWGLBINDVIDEOCAPTUREDEVICENVPROC) (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice); -typedef UINT (WINAPI * PFNWGLENUMERATEVIDEOCAPTUREDEVICESNVPROC) (HDC hDc, HVIDEOINPUTDEVICENV *phDeviceList); -typedef BOOL (WINAPI * PFNWGLLOCKVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice); -typedef BOOL (WINAPI * PFNWGLQUERYVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int *piValue); -typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglBindVideoCaptureDeviceNV (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice); -UINT WINAPI wglEnumerateVideoCaptureDevicesNV (HDC hDc, HVIDEOINPUTDEVICENV *phDeviceList); -BOOL WINAPI wglLockVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice); -BOOL WINAPI wglQueryVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int *piValue); -BOOL WINAPI wglReleaseVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice); -#endif -#endif /* WGL_NV_video_capture */ - -#ifndef WGL_NV_video_output -#define WGL_NV_video_output 1 -DECLARE_HANDLE(HPVIDEODEV); -#define WGL_BIND_TO_VIDEO_RGB_NV 0x20C0 -#define WGL_BIND_TO_VIDEO_RGBA_NV 0x20C1 -#define WGL_BIND_TO_VIDEO_RGB_AND_DEPTH_NV 0x20C2 -#define WGL_VIDEO_OUT_COLOR_NV 0x20C3 -#define WGL_VIDEO_OUT_ALPHA_NV 0x20C4 -#define WGL_VIDEO_OUT_DEPTH_NV 0x20C5 -#define WGL_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6 -#define WGL_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7 -#define WGL_VIDEO_OUT_FRAME 0x20C8 -#define WGL_VIDEO_OUT_FIELD_1 0x20C9 -#define WGL_VIDEO_OUT_FIELD_2 0x20CA -#define WGL_VIDEO_OUT_STACKED_FIELDS_1_2 0x20CB -#define WGL_VIDEO_OUT_STACKED_FIELDS_2_1 0x20CC -typedef BOOL (WINAPI * PFNWGLGETVIDEODEVICENVPROC) (HDC hDC, int numDevices, HPVIDEODEV *hVideoDevice); -typedef BOOL (WINAPI * PFNWGLRELEASEVIDEODEVICENVPROC) (HPVIDEODEV hVideoDevice); -typedef BOOL (WINAPI * PFNWGLBINDVIDEOIMAGENVPROC) (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer); -typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOIMAGENVPROC) (HPBUFFERARB hPbuffer, int iVideoBuffer); -typedef BOOL (WINAPI * PFNWGLSENDPBUFFERTOVIDEONVPROC) (HPBUFFERARB hPbuffer, int iBufferType, unsigned long *pulCounterPbuffer, BOOL bBlock); -typedef BOOL (WINAPI * PFNWGLGETVIDEOINFONVPROC) (HPVIDEODEV hpVideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglGetVideoDeviceNV (HDC hDC, int numDevices, HPVIDEODEV *hVideoDevice); -BOOL WINAPI wglReleaseVideoDeviceNV (HPVIDEODEV hVideoDevice); -BOOL WINAPI wglBindVideoImageNV (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer); -BOOL WINAPI wglReleaseVideoImageNV (HPBUFFERARB hPbuffer, int iVideoBuffer); -BOOL WINAPI wglSendPbufferToVideoNV (HPBUFFERARB hPbuffer, int iBufferType, unsigned long *pulCounterPbuffer, BOOL bBlock); -BOOL WINAPI wglGetVideoInfoNV (HPVIDEODEV hpVideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo); -#endif -#endif /* WGL_NV_video_output */ - -#ifndef WGL_OML_sync_control -#define WGL_OML_sync_control 1 -typedef BOOL (WINAPI * PFNWGLGETSYNCVALUESOMLPROC) (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc); -typedef BOOL (WINAPI * PFNWGLGETMSCRATEOMLPROC) (HDC hdc, INT32 *numerator, INT32 *denominator); -typedef INT64 (WINAPI * PFNWGLSWAPBUFFERSMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder); -typedef INT64 (WINAPI * PFNWGLSWAPLAYERBUFFERSMSCOMLPROC) (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder); -typedef BOOL (WINAPI * PFNWGLWAITFORMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc); -typedef BOOL (WINAPI * PFNWGLWAITFORSBCOMLPROC) (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglGetSyncValuesOML (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc); -BOOL WINAPI wglGetMscRateOML (HDC hdc, INT32 *numerator, INT32 *denominator); -INT64 WINAPI wglSwapBuffersMscOML (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder); -INT64 WINAPI wglSwapLayerBuffersMscOML (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder); -BOOL WINAPI wglWaitForMscOML (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc); -BOOL WINAPI wglWaitForSbcOML (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc); -#endif -#endif /* WGL_OML_sync_control */ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/examples/common/glfw/deps/KHR/khrplatform.h b/examples/common/glfw/deps/KHR/khrplatform.h deleted file mode 100644 index c9e6f17d..00000000 --- a/examples/common/glfw/deps/KHR/khrplatform.h +++ /dev/null @@ -1,282 +0,0 @@ -#ifndef __khrplatform_h_ -#define __khrplatform_h_ - -/* -** Copyright (c) 2008-2009 The Khronos Group Inc. -** -** Permission is hereby granted, free of charge, to any person obtaining a -** copy of this software and/or associated documentation files (the -** "Materials"), to deal in the Materials without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Materials, and to -** permit persons to whom the Materials are furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be included -** in all copies or substantial portions of the Materials. -** -** THE MATERIALS ARE 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 -** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. -*/ - -/* Khronos platform-specific types and definitions. - * - * $Revision: 23298 $ on $Date: 2013-09-30 17:07:13 -0700 (Mon, 30 Sep 2013) $ - * - * Adopters may modify this file to suit their platform. Adopters are - * encouraged to submit platform specific modifications to the Khronos - * group so that they can be included in future versions of this file. - * Please submit changes by sending them to the public Khronos Bugzilla - * (http://khronos.org/bugzilla) by filing a bug against product - * "Khronos (general)" component "Registry". - * - * A predefined template which fills in some of the bug fields can be - * reached using http://tinyurl.com/khrplatform-h-bugreport, but you - * must create a Bugzilla login first. - * - * - * See the Implementer's Guidelines for information about where this file - * should be located on your system and for more details of its use: - * http://www.khronos.org/registry/implementers_guide.pdf - * - * This file should be included as - * #include - * by Khronos client API header files that use its types and defines. - * - * The types in khrplatform.h should only be used to define API-specific types. - * - * Types defined in khrplatform.h: - * khronos_int8_t signed 8 bit - * khronos_uint8_t unsigned 8 bit - * khronos_int16_t signed 16 bit - * khronos_uint16_t unsigned 16 bit - * khronos_int32_t signed 32 bit - * khronos_uint32_t unsigned 32 bit - * khronos_int64_t signed 64 bit - * khronos_uint64_t unsigned 64 bit - * khronos_intptr_t signed same number of bits as a pointer - * khronos_uintptr_t unsigned same number of bits as a pointer - * khronos_ssize_t signed size - * khronos_usize_t unsigned size - * khronos_float_t signed 32 bit floating point - * khronos_time_ns_t unsigned 64 bit time in nanoseconds - * khronos_utime_nanoseconds_t unsigned time interval or absolute time in - * nanoseconds - * khronos_stime_nanoseconds_t signed time interval in nanoseconds - * khronos_boolean_enum_t enumerated boolean type. This should - * only be used as a base type when a client API's boolean type is - * an enum. Client APIs which use an integer or other type for - * booleans cannot use this as the base type for their boolean. - * - * Tokens defined in khrplatform.h: - * - * KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values. - * - * KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0. - * KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0. - * - * Calling convention macros defined in this file: - * KHRONOS_APICALL - * KHRONOS_APIENTRY - * KHRONOS_APIATTRIBUTES - * - * These may be used in function prototypes as: - * - * KHRONOS_APICALL void KHRONOS_APIENTRY funcname( - * int arg1, - * int arg2) KHRONOS_APIATTRIBUTES; - */ - -/*------------------------------------------------------------------------- - * Definition of KHRONOS_APICALL - *------------------------------------------------------------------------- - * This precedes the return type of the function in the function prototype. - */ -#if defined(_WIN32) && !defined(__SCITECH_SNAP__) -# define KHRONOS_APICALL __declspec(dllimport) -#elif defined (__SYMBIAN32__) -# define KHRONOS_APICALL IMPORT_C -#else -# define KHRONOS_APICALL -#endif - -/*------------------------------------------------------------------------- - * Definition of KHRONOS_APIENTRY - *------------------------------------------------------------------------- - * This follows the return type of the function and precedes the function - * name in the function prototype. - */ -#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__) - /* Win32 but not WinCE */ -# define KHRONOS_APIENTRY __stdcall -#else -# define KHRONOS_APIENTRY -#endif - -/*------------------------------------------------------------------------- - * Definition of KHRONOS_APIATTRIBUTES - *------------------------------------------------------------------------- - * This follows the closing parenthesis of the function prototype arguments. - */ -#if defined (__ARMCC_2__) -#define KHRONOS_APIATTRIBUTES __softfp -#else -#define KHRONOS_APIATTRIBUTES -#endif - -/*------------------------------------------------------------------------- - * basic type definitions - *-----------------------------------------------------------------------*/ -#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__) - - -/* - * Using - */ -#include -typedef int32_t khronos_int32_t; -typedef uint32_t khronos_uint32_t; -typedef int64_t khronos_int64_t; -typedef uint64_t khronos_uint64_t; -#define KHRONOS_SUPPORT_INT64 1 -#define KHRONOS_SUPPORT_FLOAT 1 - -#elif defined(__VMS ) || defined(__sgi) - -/* - * Using - */ -#include -typedef int32_t khronos_int32_t; -typedef uint32_t khronos_uint32_t; -typedef int64_t khronos_int64_t; -typedef uint64_t khronos_uint64_t; -#define KHRONOS_SUPPORT_INT64 1 -#define KHRONOS_SUPPORT_FLOAT 1 - -#elif defined(_WIN32) && !defined(__SCITECH_SNAP__) - -/* - * Win32 - */ -typedef __int32 khronos_int32_t; -typedef unsigned __int32 khronos_uint32_t; -typedef __int64 khronos_int64_t; -typedef unsigned __int64 khronos_uint64_t; -#define KHRONOS_SUPPORT_INT64 1 -#define KHRONOS_SUPPORT_FLOAT 1 - -#elif defined(__sun__) || defined(__digital__) - -/* - * Sun or Digital - */ -typedef int khronos_int32_t; -typedef unsigned int khronos_uint32_t; -#if defined(__arch64__) || defined(_LP64) -typedef long int khronos_int64_t; -typedef unsigned long int khronos_uint64_t; -#else -typedef long long int khronos_int64_t; -typedef unsigned long long int khronos_uint64_t; -#endif /* __arch64__ */ -#define KHRONOS_SUPPORT_INT64 1 -#define KHRONOS_SUPPORT_FLOAT 1 - -#elif 0 - -/* - * Hypothetical platform with no float or int64 support - */ -typedef int khronos_int32_t; -typedef unsigned int khronos_uint32_t; -#define KHRONOS_SUPPORT_INT64 0 -#define KHRONOS_SUPPORT_FLOAT 0 - -#else - -/* - * Generic fallback - */ -#include -typedef int32_t khronos_int32_t; -typedef uint32_t khronos_uint32_t; -typedef int64_t khronos_int64_t; -typedef uint64_t khronos_uint64_t; -#define KHRONOS_SUPPORT_INT64 1 -#define KHRONOS_SUPPORT_FLOAT 1 - -#endif - - -/* - * Types that are (so far) the same on all platforms - */ -typedef signed char khronos_int8_t; -typedef unsigned char khronos_uint8_t; -typedef signed short int khronos_int16_t; -typedef unsigned short int khronos_uint16_t; - -/* - * Types that differ between LLP64 and LP64 architectures - in LLP64, - * pointers are 64 bits, but 'long' is still 32 bits. Win64 appears - * to be the only LLP64 architecture in current use. - */ -#ifdef _WIN64 -typedef signed long long int khronos_intptr_t; -typedef unsigned long long int khronos_uintptr_t; -typedef signed long long int khronos_ssize_t; -typedef unsigned long long int khronos_usize_t; -#else -typedef signed long int khronos_intptr_t; -typedef unsigned long int khronos_uintptr_t; -typedef signed long int khronos_ssize_t; -typedef unsigned long int khronos_usize_t; -#endif - -#if KHRONOS_SUPPORT_FLOAT -/* - * Float type - */ -typedef float khronos_float_t; -#endif - -#if KHRONOS_SUPPORT_INT64 -/* Time types - * - * These types can be used to represent a time interval in nanoseconds or - * an absolute Unadjusted System Time. Unadjusted System Time is the number - * of nanoseconds since some arbitrary system event (e.g. since the last - * time the system booted). The Unadjusted System Time is an unsigned - * 64 bit value that wraps back to 0 every 584 years. Time intervals - * may be either signed or unsigned. - */ -typedef khronos_uint64_t khronos_utime_nanoseconds_t; -typedef khronos_int64_t khronos_stime_nanoseconds_t; -#endif - -/* - * Dummy value used to pad enum types to 32 bits. - */ -#ifndef KHRONOS_MAX_ENUM -#define KHRONOS_MAX_ENUM 0x7FFFFFFF -#endif - -/* - * Enumerated boolean type - * - * Values other than zero should be considered to be true. Therefore - * comparisons should not be made against KHRONOS_TRUE. - */ -typedef enum { - KHRONOS_FALSE = 0, - KHRONOS_TRUE = 1, - KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM -} khronos_boolean_enum_t; - -#endif /* __khrplatform_h_ */ diff --git a/examples/common/glfw/deps/getopt.c b/examples/common/glfw/deps/getopt.c deleted file mode 100644 index 9743046f..00000000 --- a/examples/common/glfw/deps/getopt.c +++ /dev/null @@ -1,230 +0,0 @@ -/* Copyright (c) 2012, Kim Gräsman - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of Kim Gräsman nor the names of contributors may be used - * to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL KIM GRÄSMAN BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "getopt.h" - -#include -#include - -const int no_argument = 0; -const int required_argument = 1; -const int optional_argument = 2; - -char* optarg; -int optopt; -/* The variable optind [...] shall be initialized to 1 by the system. */ -int optind = 1; -int opterr; - -static char* optcursor = NULL; - -/* Implemented based on [1] and [2] for optional arguments. - optopt is handled FreeBSD-style, per [3]. - Other GNU and FreeBSD extensions are purely accidental. - -[1] http://pubs.opengroup.org/onlinepubs/000095399/functions/getopt.html -[2] http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html -[3] http://www.freebsd.org/cgi/man.cgi?query=getopt&sektion=3&manpath=FreeBSD+9.0-RELEASE -*/ -int getopt(int argc, char* const argv[], const char* optstring) { - int optchar = -1; - const char* optdecl = NULL; - - optarg = NULL; - opterr = 0; - optopt = 0; - - /* Unspecified, but we need it to avoid overrunning the argv bounds. */ - if (optind >= argc) - goto no_more_optchars; - - /* If, when getopt() is called argv[optind] is a null pointer, getopt() - shall return -1 without changing optind. */ - if (argv[optind] == NULL) - goto no_more_optchars; - - /* If, when getopt() is called *argv[optind] is not the character '-', - getopt() shall return -1 without changing optind. */ - if (*argv[optind] != '-') - goto no_more_optchars; - - /* If, when getopt() is called argv[optind] points to the string "-", - getopt() shall return -1 without changing optind. */ - if (strcmp(argv[optind], "-") == 0) - goto no_more_optchars; - - /* If, when getopt() is called argv[optind] points to the string "--", - getopt() shall return -1 after incrementing optind. */ - if (strcmp(argv[optind], "--") == 0) { - ++optind; - goto no_more_optchars; - } - - if (optcursor == NULL || *optcursor == '\0') - optcursor = argv[optind] + 1; - - optchar = *optcursor; - - /* FreeBSD: The variable optopt saves the last known option character - returned by getopt(). */ - optopt = optchar; - - /* The getopt() function shall return the next option character (if one is - found) from argv that matches a character in optstring, if there is - one that matches. */ - optdecl = strchr(optstring, optchar); - if (optdecl) { - /* [I]f a character is followed by a colon, the option takes an - argument. */ - if (optdecl[1] == ':') { - optarg = ++optcursor; - if (*optarg == '\0') { - /* GNU extension: Two colons mean an option takes an - optional arg; if there is text in the current argv-element - (i.e., in the same word as the option name itself, for example, - "-oarg"), then it is returned in optarg, otherwise optarg is set - to zero. */ - if (optdecl[2] != ':') { - /* If the option was the last character in the string pointed to by - an element of argv, then optarg shall contain the next element - of argv, and optind shall be incremented by 2. If the resulting - value of optind is greater than argc, this indicates a missing - option-argument, and getopt() shall return an error indication. - - Otherwise, optarg shall point to the string following the - option character in that element of argv, and optind shall be - incremented by 1. - */ - if (++optind < argc) { - optarg = argv[optind]; - } else { - /* If it detects a missing option-argument, it shall return the - colon character ( ':' ) if the first character of optstring - was a colon, or a question-mark character ( '?' ) otherwise. - */ - optarg = NULL; - optchar = (optstring[0] == ':') ? ':' : '?'; - } - } else { - optarg = NULL; - } - } - - optcursor = NULL; - } - } else { - /* If getopt() encounters an option character that is not contained in - optstring, it shall return the question-mark ( '?' ) character. */ - optchar = '?'; - } - - if (optcursor == NULL || *++optcursor == '\0') - ++optind; - - return optchar; - -no_more_optchars: - optcursor = NULL; - return -1; -} - -/* Implementation based on [1]. - -[1] http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html -*/ -int getopt_long(int argc, char* const argv[], const char* optstring, - const struct option* longopts, int* longindex) { - const struct option* o = longopts; - const struct option* match = NULL; - int num_matches = 0; - size_t argument_name_length = 0; - const char* current_argument = NULL; - int retval = -1; - - optarg = NULL; - optopt = 0; - - if (optind >= argc) - return -1; - - if (strlen(argv[optind]) < 3 || strncmp(argv[optind], "--", 2) != 0) - return getopt(argc, argv, optstring); - - /* It's an option; starts with -- and is longer than two chars. */ - current_argument = argv[optind] + 2; - argument_name_length = strcspn(current_argument, "="); - for (; o->name; ++o) { - if (strncmp(o->name, current_argument, argument_name_length) == 0) { - match = o; - ++num_matches; - } - } - - if (num_matches == 1) { - /* If longindex is not NULL, it points to a variable which is set to the - index of the long option relative to longopts. */ - if (longindex) - *longindex = (int) (match - longopts); - - /* If flag is NULL, then getopt_long() shall return val. - Otherwise, getopt_long() returns 0, and flag shall point to a variable - which shall be set to val if the option is found, but left unchanged if - the option is not found. */ - if (match->flag) - *(match->flag) = match->val; - - retval = match->flag ? 0 : match->val; - - if (match->has_arg != no_argument) { - optarg = strchr(argv[optind], '='); - if (optarg != NULL) - ++optarg; - - if (match->has_arg == required_argument) { - /* Only scan the next argv for required arguments. Behavior is not - specified, but has been observed with Ubuntu and Mac OSX. */ - if (optarg == NULL && ++optind < argc) { - optarg = argv[optind]; - } - - if (optarg == NULL) - retval = ':'; - } - } else if (strchr(argv[optind], '=')) { - /* An argument was provided to a non-argument option. - I haven't seen this specified explicitly, but both GNU and BSD-based - implementations show this behavior. - */ - retval = '?'; - } - } else { - /* Unknown option or ambiguous match. */ - retval = '?'; - } - - ++optind; - return retval; -} diff --git a/examples/common/glfw/deps/getopt.h b/examples/common/glfw/deps/getopt.h deleted file mode 100644 index e1eb540f..00000000 --- a/examples/common/glfw/deps/getopt.h +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright (c) 2012, Kim Gräsman - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of Kim Gräsman nor the names of contributors may be used - * to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL KIM GRÄSMAN BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef INCLUDED_GETOPT_PORT_H -#define INCLUDED_GETOPT_PORT_H - -#if defined(__cplusplus) -extern "C" { -#endif - -extern const int no_argument; -extern const int required_argument; -extern const int optional_argument; - -extern char* optarg; -extern int optind, opterr, optopt; - -struct option { - const char* name; - int has_arg; - int* flag; - int val; -}; - -int getopt(int argc, char* const argv[], const char* optstring); - -int getopt_long(int argc, char* const argv[], - const char* optstring, const struct option* longopts, int* longindex); - -#if defined(__cplusplus) -} -#endif - -#endif // INCLUDED_GETOPT_PORT_H diff --git a/examples/common/glfw/deps/glad.c b/examples/common/glfw/deps/glad.c deleted file mode 100644 index da75d08d..00000000 --- a/examples/common/glfw/deps/glad.c +++ /dev/null @@ -1,728 +0,0 @@ -#include -#include - -struct gladGLversionStruct GLVersion; - -#if defined(GL_ES_VERSION_3_0) || defined(GL_VERSION_3_0) -#define _GLAD_IS_SOME_NEW_VERSION 1 -#endif - -int GLAD_GL_VERSION_1_0; -int GLAD_GL_VERSION_1_1; -int GLAD_GL_VERSION_1_2; -int GLAD_GL_VERSION_1_3; -int GLAD_GL_VERSION_1_4; -int GLAD_GL_VERSION_1_5; -int GLAD_GL_VERSION_2_0; -int GLAD_GL_VERSION_2_1; -int GLAD_GL_VERSION_3_0; -int GLAD_GL_VERSION_3_1; -int GLAD_GL_VERSION_3_2; -PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays; -PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback; -PFNGLFLUSHPROC glad_glFlush; -PFNGLCOPYTEXIMAGE1DPROC glad_glCopyTexImage1D; -PFNGLCLEARCOLORPROC glad_glClearColor; -PFNGLVERTEXATTRIBI3UIPROC glad_glVertexAttribI3ui; -PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex; -PFNGLVERTEXATTRIB4NIVPROC glad_glVertexAttrib4Niv; -PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv; -PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate; -PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv; -PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv; -PFNGLBINDFRAGDATALOCATIONPROC glad_glBindFragDataLocation; -PFNGLLINKPROGRAMPROC glad_glLinkProgram; -PFNGLBINDTEXTUREPROC glad_glBindTexture; -PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName; -PFNGLVERTEXATTRIBI2UIVPROC glad_glVertexAttribI2uiv; -PFNGLFENCESYNCPROC glad_glFenceSync; -PFNGLUNIFORM3UIPROC glad_glUniform3ui; -PFNGLUNIFORM2UIVPROC glad_glUniform2uiv; -PFNGLGETSTRINGPROC glad_glGetString; -PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D; -PFNGLDETACHSHADERPROC glad_glDetachShader; -PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv; -PFNGLGENBUFFERSPROC glad_glGenBuffers; -PFNGLENDQUERYPROC glad_glEndQuery; -PFNGLPOINTPARAMETERFVPROC glad_glPointParameterfv; -PFNGLLINEWIDTHPROC glad_glLineWidth; -PFNGLUNIFORM2FVPROC glad_glUniform2fv; -PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced; -PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v; -PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation; -PFNGLCOMPILESHADERPROC glad_glCompileShader; -PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying; -PFNGLDELETETEXTURESPROC glad_glDeleteTextures; -PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate; -PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv; -PFNGLPOLYGONMODEPROC glad_glPolygonMode; -PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange; -PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f; -PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers; -PFNGLVERTEXATTRIB4DPROC glad_glVertexAttrib4d; -PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f; -PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v; -PFNGLISSYNCPROC glad_glIsSync; -PFNGLCLAMPCOLORPROC glad_glClampColor; -PFNGLUNIFORM4IVPROC glad_glUniform4iv; -PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv; -PFNGLCLEARSTENCILPROC glad_glClearStencil; -PFNGLFRAMEBUFFERTEXTUREPROC glad_glFramebufferTexture; -PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv; -PFNGLVERTEXATTRIB4SPROC glad_glVertexAttrib4s; -PFNGLDRAWELEMENTSBASEVERTEXPROC glad_glDrawElementsBaseVertex; -PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv; -PFNGLENABLEIPROC glad_glEnablei; -PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage; -PFNGLVERTEXATTRIB4NUSVPROC glad_glVertexAttrib4Nusv; -PFNGLGENTEXTURESPROC glad_glGenTextures; -PFNGLDEPTHFUNCPROC glad_glDepthFunc; -PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D; -PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv; -PFNGLUNIFORM1FPROC glad_glUniform1f; -PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv; -PFNGLVERTEXATTRIBI4BVPROC glad_glVertexAttribI4bv; -PFNGLVERTEXATTRIB4NBVPROC glad_glVertexAttrib4Nbv; -PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv; -PFNGLGETCOMPRESSEDTEXIMAGEPROC glad_glGetCompressedTexImage; -PFNGLISVERTEXARRAYPROC glad_glIsVertexArray; -PFNGLCREATESHADERPROC glad_glCreateShader; -PFNGLISBUFFERPROC glad_glIsBuffer; -PFNGLUNIFORM1IPROC glad_glUniform1i; -PFNGLVERTEXATTRIB3SPROC glad_glVertexAttrib3s; -PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib; -PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D; -PFNGLVERTEXATTRIB3DVPROC glad_glVertexAttrib3dv; -PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D; -PFNGLDISABLEPROC glad_glDisable; -PFNGLUNIFORM2IPROC glad_glUniform2i; -PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate; -PFNGLLOGICOPPROC glad_glLogicOp; -PFNGLVERTEXATTRIBI4SVPROC glad_glVertexAttribI4sv; -PFNGLGETPROGRAMIVPROC glad_glGetProgramiv; -PFNGLCOLORMASKPROC glad_glColorMask; -PFNGLHINTPROC glad_glHint; -PFNGLVERTEXATTRIB1SPROC glad_glVertexAttrib1s; -PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer; -PFNGLTEXPARAMETERIIVPROC glad_glTexParameterIiv; -PFNGLBLENDEQUATIONPROC glad_glBlendEquation; -PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation; -PFNGLSAMPLEMASKIPROC glad_glSampleMaski; -PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer; -PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback; -PFNGLCULLFACEPROC glad_glCullFace; -PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv; -PFNGLVERTEXATTRIB4USVPROC glad_glVertexAttrib4usv; -PFNGLUNIFORM4FVPROC glad_glUniform4fv; -PFNGLGETTEXPARAMETERIUIVPROC glad_glGetTexParameterIuiv; -PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers; -PFNGLUNIFORM1UIVPROC glad_glUniform1uiv; -PFNGLPOINTSIZEPROC glad_glPointSize; -PFNGLGETSTRINGIPROC glad_glGetStringi; -PFNGLVERTEXATTRIB2DVPROC glad_glVertexAttrib2dv; -PFNGLVERTEXATTRIBI1IVPROC glad_glVertexAttribI1iv; -PFNGLDELETEPROGRAMPROC glad_glDeleteProgram; -PFNGLVERTEXATTRIB4NUIVPROC glad_glVertexAttrib4Nuiv; -PFNGLGENQUERIESPROC glad_glGenQueries; -PFNGLWAITSYNCPROC glad_glWaitSync; -PFNGLATTACHSHADERPROC glad_glAttachShader; -PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer; -PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage; -PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv; -PFNGLUNIFORM3IPROC glad_glUniform3i; -PFNGLCOMPRESSEDTEXIMAGE1DPROC glad_glCompressedTexImage1D; -PFNGLCOPYTEXSUBIMAGE1DPROC glad_glCopyTexSubImage1D; -PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex; -PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus; -PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D; -PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v; -PFNGLPROVOKINGVERTEXPROC glad_glProvokingVertex; -PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv; -PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D; -PFNGLUNIFORM3FPROC glad_glUniform3f; -PFNGLVERTEXATTRIB4UBVPROC glad_glVertexAttrib4ubv; -PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv; -PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv; -PFNGLENDCONDITIONALRENDERPROC glad_glEndConditionalRender; -PFNGLDRAWELEMENTSPROC glad_glDrawElements; -PFNGLCOLORMASKIPROC glad_glColorMaski; -PFNGLISENABLEDIPROC glad_glIsEnabledi; -PFNGLVERTEXATTRIB1DVPROC glad_glVertexAttrib1dv; -PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements; -PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv; -PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays; -PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase; -PFNGLBUFFERSUBDATAPROC glad_glBufferSubData; -PFNGLUNIFORM1IVPROC glad_glUniform1iv; -PFNGLGETQUERYOBJECTIVPROC glad_glGetQueryObjectiv; -PFNGLUNIFORM4UIVPROC glad_glUniform4uiv; -PFNGLREADBUFFERPROC glad_glReadBuffer; -PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData; -PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray; -PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync; -PFNGLBEGINCONDITIONALRENDERPROC glad_glBeginConditionalRender; -PFNGLVERTEXATTRIB3SVPROC glad_glVertexAttrib3sv; -PFNGLVERTEXATTRIBI2UIPROC glad_glVertexAttribI2ui; -PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap; -PFNGLMULTIDRAWARRAYSPROC glad_glMultiDrawArrays; -PFNGLFRAMEBUFFERTEXTURE1DPROC glad_glFramebufferTexture1D; -PFNGLGETSHADERIVPROC glad_glGetShaderiv; -PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv; -PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv; -PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f; -PFNGLVERTEXATTRIB4UIVPROC glad_glVertexAttrib4uiv; -PFNGLPOINTPARAMETERIPROC glad_glPointParameteri; -PFNGLBLENDCOLORPROC glad_glBlendColor; -PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray; -PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer; -PFNGLDEPTHMASKPROC glad_glDepthMask; -PFNGLPOINTPARAMETERFPROC glad_glPointParameterf; -PFNGLDISABLEIPROC glad_glDisablei; -PFNGLGETDOUBLEVPROC glad_glGetDoublev; -PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv; -PFNGLVERTEXATTRIB1SVPROC glad_glVertexAttrib1sv; -PFNGLSHADERSOURCEPROC glad_glShaderSource; -PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer; -PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D; -PFNGLVERTEXATTRIBI3UIVPROC glad_glVertexAttribI3uiv; -PFNGLVERTEXATTRIBI2IVPROC glad_glVertexAttribI2iv; -PFNGLDRAWARRAYSPROC glad_glDrawArrays; -PFNGLUNIFORM1UIPROC glad_glUniform1ui; -PFNGLISPROGRAMPROC glad_glIsProgram; -PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv; -PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation; -PFNGLGETSYNCIVPROC glad_glGetSynciv; -PFNGLGETUNIFORMIVPROC glad_glGetUniformiv; -PFNGLVERTEXATTRIBI2IPROC glad_glVertexAttribI2i; -PFNGLUNIFORM4IPROC glad_glUniform4i; -PFNGLVERTEXATTRIB3DPROC glad_glVertexAttrib3d; -PFNGLCLEARPROC glad_glClear; -PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv; -PFNGLGETACTIVEUNIFORMNAMEPROC glad_glGetActiveUniformName; -PFNGLUNIFORM2FPROC glad_glUniform2f; -PFNGLTEXIMAGE2DMULTISAMPLEPROC glad_glTexImage2DMultisample; -PFNGLACTIVETEXTUREPROC glad_glActiveTexture; -PFNGLBEGINQUERYPROC glad_glBeginQuery; -PFNGLUNIFORM2IVPROC glad_glUniform2iv; -PFNGLBINDBUFFERPROC glad_glBindBuffer; -PFNGLISENABLEDPROC glad_glIsEnabled; -PFNGLSTENCILOPPROC glad_glStencilOp; -PFNGLREADPIXELSPROC glad_glReadPixels; -PFNGLCLEARDEPTHPROC glad_glClearDepth; -PFNGLVERTEXATTRIBI3IVPROC glad_glVertexAttribI3iv; -PFNGLUNIFORM4FPROC glad_glUniform4f; -PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D; -PFNGLMAPBUFFERPROC glad_glMapBuffer; -PFNGLVERTEXATTRIB1DPROC glad_glVertexAttrib1d; -PFNGLVERTEXATTRIB4NUBPROC glad_glVertexAttrib4Nub; -PFNGLUNIFORM3FVPROC glad_glUniform3fv; -PFNGLGETUNIFORMFVPROC glad_glGetUniformfv; -PFNGLBUFFERDATAPROC glad_glBufferData; -PFNGLGETTEXPARAMETERIIVPROC glad_glGetTexParameterIiv; -PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D; -PFNGLTEXIMAGE1DPROC glad_glTexImage1D; -PFNGLDELETESYNCPROC glad_glDeleteSync; -PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D; -PFNGLGETERRORPROC glad_glGetError; -PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers; -PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv; -PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv; -PFNGLMULTIDRAWELEMENTSPROC glad_glMultiDrawElements; -PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv; -PFNGLGETFLOATVPROC glad_glGetFloatv; -PFNGLTEXSUBIMAGE1DPROC glad_glTexSubImage1D; -PFNGLUNIFORM3IVPROC glad_glUniform3iv; -PFNGLGETTEXIMAGEPROC glad_glGetTexImage; -PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv; -PFNGLUSEPROGRAMPROC glad_glUseProgram; -PFNGLVERTEXATTRIB4IVPROC glad_glVertexAttrib4iv; -PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv; -PFNGLVERTEXATTRIBI1IPROC glad_glVertexAttribI1i; -PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers; -PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer; -PFNGLDRAWBUFFERSPROC glad_glDrawBuffers; -PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv; -PFNGLSTENCILFUNCPROC glad_glStencilFunc; -PFNGLGETINTEGERVPROC glad_glGetIntegerv; -PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders; -PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding; -PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer; -PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv; -PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv; -PFNGLDRAWBUFFERPROC glad_glDrawBuffer; -PFNGLFRAMEBUFFERTEXTURE3DPROC glad_glFramebufferTexture3D; -PFNGLUNIFORM1FVPROC glad_glUniform1fv; -PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample; -PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange; -PFNGLISQUERYPROC glad_glIsQuery; -PFNGLVERTEXATTRIB4NUBVPROC glad_glVertexAttrib4Nubv; -PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv; -PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray; -PFNGLVERTEXATTRIB4SVPROC glad_glVertexAttrib4sv; -PFNGLGETQUERYIVPROC glad_glGetQueryiv; -PFNGLTEXIMAGE2DPROC glad_glTexImage2D; -PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog; -PFNGLSTENCILMASKPROC glad_glStencilMask; -PFNGLUNIFORM4UIPROC glad_glUniform4ui; -PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv; -PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog; -PFNGLISTEXTUREPROC glad_glIsTexture; -PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices; -PFNGLISSHADERPROC glad_glIsShader; -PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource; -PFNGLVERTEXATTRIBI4UBVPROC glad_glVertexAttribI4ubv; -PFNGLVERTEXATTRIB4BVPROC glad_glVertexAttrib4bv; -PFNGLGETINTEGER64VPROC glad_glGetInteger64v; -PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer; -PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv; -PFNGLGETBUFFERSUBDATAPROC glad_glGetBufferSubData; -PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv; -PFNGLTEXPARAMETERIUIVPROC glad_glTexParameterIuiv; -PFNGLENABLEPROC glad_glEnable; -PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv; -PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced; -PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i; -PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate; -PFNGLDELETEQUERIESPROC glad_glDeleteQueries; -PFNGLPOINTPARAMETERIVPROC glad_glPointParameteriv; -PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate; -PFNGLVERTEXATTRIBI1UIPROC glad_glVertexAttribI1ui; -PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glad_glCompressedTexSubImage1D; -PFNGLFINISHPROC glad_glFinish; -PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation; -PFNGLVERTEXATTRIB4DVPROC glad_glVertexAttrib4dv; -PFNGLVERTEXATTRIB2SVPROC glad_glVertexAttrib2sv; -PFNGLDELETESHADERPROC glad_glDeleteShader; -PFNGLBLENDFUNCPROC glad_glBlendFunc; -PFNGLCREATEPROGRAMPROC glad_glCreateProgram; -PFNGLTEXIMAGE3DPROC glad_glTexImage3D; -PFNGLVERTEXATTRIB4NSVPROC glad_glVertexAttrib4Nsv; -PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer; -PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui; -PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange; -PFNGLVIEWPORTPROC glad_glViewport; -PFNGLVERTEXATTRIBI1UIVPROC glad_glVertexAttribI1uiv; -PFNGLVERTEXATTRIB2DPROC glad_glVertexAttrib2d; -PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings; -PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f; -PFNGLGETVERTEXATTRIBDVPROC glad_glGetVertexAttribdv; -PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glad_glMultiDrawElementsBaseVertex; -PFNGLPRIMITIVERESTARTINDEXPROC glad_glPrimitiveRestartIndex; -PFNGLUNIFORM2UIPROC glad_glUniform2ui; -PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset; -PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv; -PFNGLVERTEXATTRIBI3IPROC glad_glVertexAttribI3i; -PFNGLVERTEXATTRIB2SPROC glad_glVertexAttrib2s; -PFNGLTEXIMAGE3DMULTISAMPLEPROC glad_glTexImage3DMultisample; -PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv; -PFNGLDEPTHRANGEPROC glad_glDepthRange; -PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform; -PFNGLVERTEXATTRIBI4USVPROC glad_glVertexAttribI4usv; -PFNGLTEXPARAMETERFPROC glad_glTexParameterf; -PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi; -PFNGLTEXPARAMETERIPROC glad_glTexParameteri; -PFNGLFRONTFACEPROC glad_glFrontFace; -PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers; -PFNGLSCISSORPROC glad_glScissor; -PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex; -PFNGLGETBOOLEANVPROC glad_glGetBooleanv; -PFNGLTEXBUFFERPROC glad_glTexBuffer; -PFNGLPIXELSTOREIPROC glad_glPixelStorei; -PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram; -PFNGLPIXELSTOREFPROC glad_glPixelStoref; -PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv; -PFNGLUNIFORM3UIVPROC glad_glUniform3uiv; -PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v; -PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer; -static void load_GL_VERSION_1_0(GLADloadproc load) { - if(!GLAD_GL_VERSION_1_0) return; - glad_glCullFace = (PFNGLCULLFACEPROC)load("glCullFace"); - glad_glFrontFace = (PFNGLFRONTFACEPROC)load("glFrontFace"); - glad_glHint = (PFNGLHINTPROC)load("glHint"); - glad_glLineWidth = (PFNGLLINEWIDTHPROC)load("glLineWidth"); - glad_glPointSize = (PFNGLPOINTSIZEPROC)load("glPointSize"); - glad_glPolygonMode = (PFNGLPOLYGONMODEPROC)load("glPolygonMode"); - glad_glScissor = (PFNGLSCISSORPROC)load("glScissor"); - glad_glTexParameterf = (PFNGLTEXPARAMETERFPROC)load("glTexParameterf"); - glad_glTexParameterfv = (PFNGLTEXPARAMETERFVPROC)load("glTexParameterfv"); - glad_glTexParameteri = (PFNGLTEXPARAMETERIPROC)load("glTexParameteri"); - glad_glTexParameteriv = (PFNGLTEXPARAMETERIVPROC)load("glTexParameteriv"); - glad_glTexImage1D = (PFNGLTEXIMAGE1DPROC)load("glTexImage1D"); - glad_glTexImage2D = (PFNGLTEXIMAGE2DPROC)load("glTexImage2D"); - glad_glDrawBuffer = (PFNGLDRAWBUFFERPROC)load("glDrawBuffer"); - glad_glClear = (PFNGLCLEARPROC)load("glClear"); - glad_glClearColor = (PFNGLCLEARCOLORPROC)load("glClearColor"); - glad_glClearStencil = (PFNGLCLEARSTENCILPROC)load("glClearStencil"); - glad_glClearDepth = (PFNGLCLEARDEPTHPROC)load("glClearDepth"); - glad_glStencilMask = (PFNGLSTENCILMASKPROC)load("glStencilMask"); - glad_glColorMask = (PFNGLCOLORMASKPROC)load("glColorMask"); - glad_glDepthMask = (PFNGLDEPTHMASKPROC)load("glDepthMask"); - glad_glDisable = (PFNGLDISABLEPROC)load("glDisable"); - glad_glEnable = (PFNGLENABLEPROC)load("glEnable"); - glad_glFinish = (PFNGLFINISHPROC)load("glFinish"); - glad_glFlush = (PFNGLFLUSHPROC)load("glFlush"); - glad_glBlendFunc = (PFNGLBLENDFUNCPROC)load("glBlendFunc"); - glad_glLogicOp = (PFNGLLOGICOPPROC)load("glLogicOp"); - glad_glStencilFunc = (PFNGLSTENCILFUNCPROC)load("glStencilFunc"); - glad_glStencilOp = (PFNGLSTENCILOPPROC)load("glStencilOp"); - glad_glDepthFunc = (PFNGLDEPTHFUNCPROC)load("glDepthFunc"); - glad_glPixelStoref = (PFNGLPIXELSTOREFPROC)load("glPixelStoref"); - glad_glPixelStorei = (PFNGLPIXELSTOREIPROC)load("glPixelStorei"); - glad_glReadBuffer = (PFNGLREADBUFFERPROC)load("glReadBuffer"); - glad_glReadPixels = (PFNGLREADPIXELSPROC)load("glReadPixels"); - glad_glGetBooleanv = (PFNGLGETBOOLEANVPROC)load("glGetBooleanv"); - glad_glGetDoublev = (PFNGLGETDOUBLEVPROC)load("glGetDoublev"); - glad_glGetError = (PFNGLGETERRORPROC)load("glGetError"); - glad_glGetFloatv = (PFNGLGETFLOATVPROC)load("glGetFloatv"); - glad_glGetIntegerv = (PFNGLGETINTEGERVPROC)load("glGetIntegerv"); - glad_glGetString = (PFNGLGETSTRINGPROC)load("glGetString"); - glad_glGetTexImage = (PFNGLGETTEXIMAGEPROC)load("glGetTexImage"); - glad_glGetTexParameterfv = (PFNGLGETTEXPARAMETERFVPROC)load("glGetTexParameterfv"); - glad_glGetTexParameteriv = (PFNGLGETTEXPARAMETERIVPROC)load("glGetTexParameteriv"); - glad_glGetTexLevelParameterfv = (PFNGLGETTEXLEVELPARAMETERFVPROC)load("glGetTexLevelParameterfv"); - glad_glGetTexLevelParameteriv = (PFNGLGETTEXLEVELPARAMETERIVPROC)load("glGetTexLevelParameteriv"); - glad_glIsEnabled = (PFNGLISENABLEDPROC)load("glIsEnabled"); - glad_glDepthRange = (PFNGLDEPTHRANGEPROC)load("glDepthRange"); - glad_glViewport = (PFNGLVIEWPORTPROC)load("glViewport"); -} -static void load_GL_VERSION_1_1(GLADloadproc load) { - if(!GLAD_GL_VERSION_1_1) return; - glad_glDrawArrays = (PFNGLDRAWARRAYSPROC)load("glDrawArrays"); - glad_glDrawElements = (PFNGLDRAWELEMENTSPROC)load("glDrawElements"); - glad_glPolygonOffset = (PFNGLPOLYGONOFFSETPROC)load("glPolygonOffset"); - glad_glCopyTexImage1D = (PFNGLCOPYTEXIMAGE1DPROC)load("glCopyTexImage1D"); - glad_glCopyTexImage2D = (PFNGLCOPYTEXIMAGE2DPROC)load("glCopyTexImage2D"); - glad_glCopyTexSubImage1D = (PFNGLCOPYTEXSUBIMAGE1DPROC)load("glCopyTexSubImage1D"); - glad_glCopyTexSubImage2D = (PFNGLCOPYTEXSUBIMAGE2DPROC)load("glCopyTexSubImage2D"); - glad_glTexSubImage1D = (PFNGLTEXSUBIMAGE1DPROC)load("glTexSubImage1D"); - glad_glTexSubImage2D = (PFNGLTEXSUBIMAGE2DPROC)load("glTexSubImage2D"); - glad_glBindTexture = (PFNGLBINDTEXTUREPROC)load("glBindTexture"); - glad_glDeleteTextures = (PFNGLDELETETEXTURESPROC)load("glDeleteTextures"); - glad_glGenTextures = (PFNGLGENTEXTURESPROC)load("glGenTextures"); - glad_glIsTexture = (PFNGLISTEXTUREPROC)load("glIsTexture"); -} -static void load_GL_VERSION_1_2(GLADloadproc load) { - if(!GLAD_GL_VERSION_1_2) return; - glad_glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)load("glDrawRangeElements"); - glad_glTexImage3D = (PFNGLTEXIMAGE3DPROC)load("glTexImage3D"); - glad_glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC)load("glTexSubImage3D"); - glad_glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC)load("glCopyTexSubImage3D"); -} -static void load_GL_VERSION_1_3(GLADloadproc load) { - if(!GLAD_GL_VERSION_1_3) return; - glad_glActiveTexture = (PFNGLACTIVETEXTUREPROC)load("glActiveTexture"); - glad_glSampleCoverage = (PFNGLSAMPLECOVERAGEPROC)load("glSampleCoverage"); - glad_glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC)load("glCompressedTexImage3D"); - glad_glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC)load("glCompressedTexImage2D"); - glad_glCompressedTexImage1D = (PFNGLCOMPRESSEDTEXIMAGE1DPROC)load("glCompressedTexImage1D"); - glad_glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)load("glCompressedTexSubImage3D"); - glad_glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)load("glCompressedTexSubImage2D"); - glad_glCompressedTexSubImage1D = (PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)load("glCompressedTexSubImage1D"); - glad_glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC)load("glGetCompressedTexImage"); -} -static void load_GL_VERSION_1_4(GLADloadproc load) { - if(!GLAD_GL_VERSION_1_4) return; - glad_glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC)load("glBlendFuncSeparate"); - glad_glMultiDrawArrays = (PFNGLMULTIDRAWARRAYSPROC)load("glMultiDrawArrays"); - glad_glMultiDrawElements = (PFNGLMULTIDRAWELEMENTSPROC)load("glMultiDrawElements"); - glad_glPointParameterf = (PFNGLPOINTPARAMETERFPROC)load("glPointParameterf"); - glad_glPointParameterfv = (PFNGLPOINTPARAMETERFVPROC)load("glPointParameterfv"); - glad_glPointParameteri = (PFNGLPOINTPARAMETERIPROC)load("glPointParameteri"); - glad_glPointParameteriv = (PFNGLPOINTPARAMETERIVPROC)load("glPointParameteriv"); - glad_glBlendColor = (PFNGLBLENDCOLORPROC)load("glBlendColor"); - glad_glBlendEquation = (PFNGLBLENDEQUATIONPROC)load("glBlendEquation"); -} -static void load_GL_VERSION_1_5(GLADloadproc load) { - if(!GLAD_GL_VERSION_1_5) return; - glad_glGenQueries = (PFNGLGENQUERIESPROC)load("glGenQueries"); - glad_glDeleteQueries = (PFNGLDELETEQUERIESPROC)load("glDeleteQueries"); - glad_glIsQuery = (PFNGLISQUERYPROC)load("glIsQuery"); - glad_glBeginQuery = (PFNGLBEGINQUERYPROC)load("glBeginQuery"); - glad_glEndQuery = (PFNGLENDQUERYPROC)load("glEndQuery"); - glad_glGetQueryiv = (PFNGLGETQUERYIVPROC)load("glGetQueryiv"); - glad_glGetQueryObjectiv = (PFNGLGETQUERYOBJECTIVPROC)load("glGetQueryObjectiv"); - glad_glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC)load("glGetQueryObjectuiv"); - glad_glBindBuffer = (PFNGLBINDBUFFERPROC)load("glBindBuffer"); - glad_glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)load("glDeleteBuffers"); - glad_glGenBuffers = (PFNGLGENBUFFERSPROC)load("glGenBuffers"); - glad_glIsBuffer = (PFNGLISBUFFERPROC)load("glIsBuffer"); - glad_glBufferData = (PFNGLBUFFERDATAPROC)load("glBufferData"); - glad_glBufferSubData = (PFNGLBUFFERSUBDATAPROC)load("glBufferSubData"); - glad_glGetBufferSubData = (PFNGLGETBUFFERSUBDATAPROC)load("glGetBufferSubData"); - glad_glMapBuffer = (PFNGLMAPBUFFERPROC)load("glMapBuffer"); - glad_glUnmapBuffer = (PFNGLUNMAPBUFFERPROC)load("glUnmapBuffer"); - glad_glGetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC)load("glGetBufferParameteriv"); - glad_glGetBufferPointerv = (PFNGLGETBUFFERPOINTERVPROC)load("glGetBufferPointerv"); -} -static void load_GL_VERSION_2_0(GLADloadproc load) { - if(!GLAD_GL_VERSION_2_0) return; - glad_glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC)load("glBlendEquationSeparate"); - glad_glDrawBuffers = (PFNGLDRAWBUFFERSPROC)load("glDrawBuffers"); - glad_glStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC)load("glStencilOpSeparate"); - glad_glStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC)load("glStencilFuncSeparate"); - glad_glStencilMaskSeparate = (PFNGLSTENCILMASKSEPARATEPROC)load("glStencilMaskSeparate"); - glad_glAttachShader = (PFNGLATTACHSHADERPROC)load("glAttachShader"); - glad_glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC)load("glBindAttribLocation"); - glad_glCompileShader = (PFNGLCOMPILESHADERPROC)load("glCompileShader"); - glad_glCreateProgram = (PFNGLCREATEPROGRAMPROC)load("glCreateProgram"); - glad_glCreateShader = (PFNGLCREATESHADERPROC)load("glCreateShader"); - glad_glDeleteProgram = (PFNGLDELETEPROGRAMPROC)load("glDeleteProgram"); - glad_glDeleteShader = (PFNGLDELETESHADERPROC)load("glDeleteShader"); - glad_glDetachShader = (PFNGLDETACHSHADERPROC)load("glDetachShader"); - glad_glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)load("glDisableVertexAttribArray"); - glad_glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)load("glEnableVertexAttribArray"); - glad_glGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC)load("glGetActiveAttrib"); - glad_glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC)load("glGetActiveUniform"); - glad_glGetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC)load("glGetAttachedShaders"); - glad_glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)load("glGetAttribLocation"); - glad_glGetProgramiv = (PFNGLGETPROGRAMIVPROC)load("glGetProgramiv"); - glad_glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)load("glGetProgramInfoLog"); - glad_glGetShaderiv = (PFNGLGETSHADERIVPROC)load("glGetShaderiv"); - glad_glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)load("glGetShaderInfoLog"); - glad_glGetShaderSource = (PFNGLGETSHADERSOURCEPROC)load("glGetShaderSource"); - glad_glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)load("glGetUniformLocation"); - glad_glGetUniformfv = (PFNGLGETUNIFORMFVPROC)load("glGetUniformfv"); - glad_glGetUniformiv = (PFNGLGETUNIFORMIVPROC)load("glGetUniformiv"); - glad_glGetVertexAttribdv = (PFNGLGETVERTEXATTRIBDVPROC)load("glGetVertexAttribdv"); - glad_glGetVertexAttribfv = (PFNGLGETVERTEXATTRIBFVPROC)load("glGetVertexAttribfv"); - glad_glGetVertexAttribiv = (PFNGLGETVERTEXATTRIBIVPROC)load("glGetVertexAttribiv"); - glad_glGetVertexAttribPointerv = (PFNGLGETVERTEXATTRIBPOINTERVPROC)load("glGetVertexAttribPointerv"); - glad_glIsProgram = (PFNGLISPROGRAMPROC)load("glIsProgram"); - glad_glIsShader = (PFNGLISSHADERPROC)load("glIsShader"); - glad_glLinkProgram = (PFNGLLINKPROGRAMPROC)load("glLinkProgram"); - glad_glShaderSource = (PFNGLSHADERSOURCEPROC)load("glShaderSource"); - glad_glUseProgram = (PFNGLUSEPROGRAMPROC)load("glUseProgram"); - glad_glUniform1f = (PFNGLUNIFORM1FPROC)load("glUniform1f"); - glad_glUniform2f = (PFNGLUNIFORM2FPROC)load("glUniform2f"); - glad_glUniform3f = (PFNGLUNIFORM3FPROC)load("glUniform3f"); - glad_glUniform4f = (PFNGLUNIFORM4FPROC)load("glUniform4f"); - glad_glUniform1i = (PFNGLUNIFORM1IPROC)load("glUniform1i"); - glad_glUniform2i = (PFNGLUNIFORM2IPROC)load("glUniform2i"); - glad_glUniform3i = (PFNGLUNIFORM3IPROC)load("glUniform3i"); - glad_glUniform4i = (PFNGLUNIFORM4IPROC)load("glUniform4i"); - glad_glUniform1fv = (PFNGLUNIFORM1FVPROC)load("glUniform1fv"); - glad_glUniform2fv = (PFNGLUNIFORM2FVPROC)load("glUniform2fv"); - glad_glUniform3fv = (PFNGLUNIFORM3FVPROC)load("glUniform3fv"); - glad_glUniform4fv = (PFNGLUNIFORM4FVPROC)load("glUniform4fv"); - glad_glUniform1iv = (PFNGLUNIFORM1IVPROC)load("glUniform1iv"); - glad_glUniform2iv = (PFNGLUNIFORM2IVPROC)load("glUniform2iv"); - glad_glUniform3iv = (PFNGLUNIFORM3IVPROC)load("glUniform3iv"); - glad_glUniform4iv = (PFNGLUNIFORM4IVPROC)load("glUniform4iv"); - glad_glUniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC)load("glUniformMatrix2fv"); - glad_glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC)load("glUniformMatrix3fv"); - glad_glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)load("glUniformMatrix4fv"); - glad_glValidateProgram = (PFNGLVALIDATEPROGRAMPROC)load("glValidateProgram"); - glad_glVertexAttrib1d = (PFNGLVERTEXATTRIB1DPROC)load("glVertexAttrib1d"); - glad_glVertexAttrib1dv = (PFNGLVERTEXATTRIB1DVPROC)load("glVertexAttrib1dv"); - glad_glVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC)load("glVertexAttrib1f"); - glad_glVertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC)load("glVertexAttrib1fv"); - glad_glVertexAttrib1s = (PFNGLVERTEXATTRIB1SPROC)load("glVertexAttrib1s"); - glad_glVertexAttrib1sv = (PFNGLVERTEXATTRIB1SVPROC)load("glVertexAttrib1sv"); - glad_glVertexAttrib2d = (PFNGLVERTEXATTRIB2DPROC)load("glVertexAttrib2d"); - glad_glVertexAttrib2dv = (PFNGLVERTEXATTRIB2DVPROC)load("glVertexAttrib2dv"); - glad_glVertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC)load("glVertexAttrib2f"); - glad_glVertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC)load("glVertexAttrib2fv"); - glad_glVertexAttrib2s = (PFNGLVERTEXATTRIB2SPROC)load("glVertexAttrib2s"); - glad_glVertexAttrib2sv = (PFNGLVERTEXATTRIB2SVPROC)load("glVertexAttrib2sv"); - glad_glVertexAttrib3d = (PFNGLVERTEXATTRIB3DPROC)load("glVertexAttrib3d"); - glad_glVertexAttrib3dv = (PFNGLVERTEXATTRIB3DVPROC)load("glVertexAttrib3dv"); - glad_glVertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC)load("glVertexAttrib3f"); - glad_glVertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC)load("glVertexAttrib3fv"); - glad_glVertexAttrib3s = (PFNGLVERTEXATTRIB3SPROC)load("glVertexAttrib3s"); - glad_glVertexAttrib3sv = (PFNGLVERTEXATTRIB3SVPROC)load("glVertexAttrib3sv"); - glad_glVertexAttrib4Nbv = (PFNGLVERTEXATTRIB4NBVPROC)load("glVertexAttrib4Nbv"); - glad_glVertexAttrib4Niv = (PFNGLVERTEXATTRIB4NIVPROC)load("glVertexAttrib4Niv"); - glad_glVertexAttrib4Nsv = (PFNGLVERTEXATTRIB4NSVPROC)load("glVertexAttrib4Nsv"); - glad_glVertexAttrib4Nub = (PFNGLVERTEXATTRIB4NUBPROC)load("glVertexAttrib4Nub"); - glad_glVertexAttrib4Nubv = (PFNGLVERTEXATTRIB4NUBVPROC)load("glVertexAttrib4Nubv"); - glad_glVertexAttrib4Nuiv = (PFNGLVERTEXATTRIB4NUIVPROC)load("glVertexAttrib4Nuiv"); - glad_glVertexAttrib4Nusv = (PFNGLVERTEXATTRIB4NUSVPROC)load("glVertexAttrib4Nusv"); - glad_glVertexAttrib4bv = (PFNGLVERTEXATTRIB4BVPROC)load("glVertexAttrib4bv"); - glad_glVertexAttrib4d = (PFNGLVERTEXATTRIB4DPROC)load("glVertexAttrib4d"); - glad_glVertexAttrib4dv = (PFNGLVERTEXATTRIB4DVPROC)load("glVertexAttrib4dv"); - glad_glVertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC)load("glVertexAttrib4f"); - glad_glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC)load("glVertexAttrib4fv"); - glad_glVertexAttrib4iv = (PFNGLVERTEXATTRIB4IVPROC)load("glVertexAttrib4iv"); - glad_glVertexAttrib4s = (PFNGLVERTEXATTRIB4SPROC)load("glVertexAttrib4s"); - glad_glVertexAttrib4sv = (PFNGLVERTEXATTRIB4SVPROC)load("glVertexAttrib4sv"); - glad_glVertexAttrib4ubv = (PFNGLVERTEXATTRIB4UBVPROC)load("glVertexAttrib4ubv"); - glad_glVertexAttrib4uiv = (PFNGLVERTEXATTRIB4UIVPROC)load("glVertexAttrib4uiv"); - glad_glVertexAttrib4usv = (PFNGLVERTEXATTRIB4USVPROC)load("glVertexAttrib4usv"); - glad_glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)load("glVertexAttribPointer"); -} -static void load_GL_VERSION_2_1(GLADloadproc load) { - if(!GLAD_GL_VERSION_2_1) return; - glad_glUniformMatrix2x3fv = (PFNGLUNIFORMMATRIX2X3FVPROC)load("glUniformMatrix2x3fv"); - glad_glUniformMatrix3x2fv = (PFNGLUNIFORMMATRIX3X2FVPROC)load("glUniformMatrix3x2fv"); - glad_glUniformMatrix2x4fv = (PFNGLUNIFORMMATRIX2X4FVPROC)load("glUniformMatrix2x4fv"); - glad_glUniformMatrix4x2fv = (PFNGLUNIFORMMATRIX4X2FVPROC)load("glUniformMatrix4x2fv"); - glad_glUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC)load("glUniformMatrix3x4fv"); - glad_glUniformMatrix4x3fv = (PFNGLUNIFORMMATRIX4X3FVPROC)load("glUniformMatrix4x3fv"); -} -static void load_GL_VERSION_3_0(GLADloadproc load) { - if(!GLAD_GL_VERSION_3_0) return; - glad_glColorMaski = (PFNGLCOLORMASKIPROC)load("glColorMaski"); - glad_glGetBooleani_v = (PFNGLGETBOOLEANI_VPROC)load("glGetBooleani_v"); - glad_glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC)load("glGetIntegeri_v"); - glad_glEnablei = (PFNGLENABLEIPROC)load("glEnablei"); - glad_glDisablei = (PFNGLDISABLEIPROC)load("glDisablei"); - glad_glIsEnabledi = (PFNGLISENABLEDIPROC)load("glIsEnabledi"); - glad_glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC)load("glBeginTransformFeedback"); - glad_glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC)load("glEndTransformFeedback"); - glad_glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC)load("glBindBufferRange"); - glad_glBindBufferBase = (PFNGLBINDBUFFERBASEPROC)load("glBindBufferBase"); - glad_glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC)load("glTransformFeedbackVaryings"); - glad_glGetTransformFeedbackVarying = (PFNGLGETTRANSFORMFEEDBACKVARYINGPROC)load("glGetTransformFeedbackVarying"); - glad_glClampColor = (PFNGLCLAMPCOLORPROC)load("glClampColor"); - glad_glBeginConditionalRender = (PFNGLBEGINCONDITIONALRENDERPROC)load("glBeginConditionalRender"); - glad_glEndConditionalRender = (PFNGLENDCONDITIONALRENDERPROC)load("glEndConditionalRender"); - glad_glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC)load("glVertexAttribIPointer"); - glad_glGetVertexAttribIiv = (PFNGLGETVERTEXATTRIBIIVPROC)load("glGetVertexAttribIiv"); - glad_glGetVertexAttribIuiv = (PFNGLGETVERTEXATTRIBIUIVPROC)load("glGetVertexAttribIuiv"); - glad_glVertexAttribI1i = (PFNGLVERTEXATTRIBI1IPROC)load("glVertexAttribI1i"); - glad_glVertexAttribI2i = (PFNGLVERTEXATTRIBI2IPROC)load("glVertexAttribI2i"); - glad_glVertexAttribI3i = (PFNGLVERTEXATTRIBI3IPROC)load("glVertexAttribI3i"); - glad_glVertexAttribI4i = (PFNGLVERTEXATTRIBI4IPROC)load("glVertexAttribI4i"); - glad_glVertexAttribI1ui = (PFNGLVERTEXATTRIBI1UIPROC)load("glVertexAttribI1ui"); - glad_glVertexAttribI2ui = (PFNGLVERTEXATTRIBI2UIPROC)load("glVertexAttribI2ui"); - glad_glVertexAttribI3ui = (PFNGLVERTEXATTRIBI3UIPROC)load("glVertexAttribI3ui"); - glad_glVertexAttribI4ui = (PFNGLVERTEXATTRIBI4UIPROC)load("glVertexAttribI4ui"); - glad_glVertexAttribI1iv = (PFNGLVERTEXATTRIBI1IVPROC)load("glVertexAttribI1iv"); - glad_glVertexAttribI2iv = (PFNGLVERTEXATTRIBI2IVPROC)load("glVertexAttribI2iv"); - glad_glVertexAttribI3iv = (PFNGLVERTEXATTRIBI3IVPROC)load("glVertexAttribI3iv"); - glad_glVertexAttribI4iv = (PFNGLVERTEXATTRIBI4IVPROC)load("glVertexAttribI4iv"); - glad_glVertexAttribI1uiv = (PFNGLVERTEXATTRIBI1UIVPROC)load("glVertexAttribI1uiv"); - glad_glVertexAttribI2uiv = (PFNGLVERTEXATTRIBI2UIVPROC)load("glVertexAttribI2uiv"); - glad_glVertexAttribI3uiv = (PFNGLVERTEXATTRIBI3UIVPROC)load("glVertexAttribI3uiv"); - glad_glVertexAttribI4uiv = (PFNGLVERTEXATTRIBI4UIVPROC)load("glVertexAttribI4uiv"); - glad_glVertexAttribI4bv = (PFNGLVERTEXATTRIBI4BVPROC)load("glVertexAttribI4bv"); - glad_glVertexAttribI4sv = (PFNGLVERTEXATTRIBI4SVPROC)load("glVertexAttribI4sv"); - glad_glVertexAttribI4ubv = (PFNGLVERTEXATTRIBI4UBVPROC)load("glVertexAttribI4ubv"); - glad_glVertexAttribI4usv = (PFNGLVERTEXATTRIBI4USVPROC)load("glVertexAttribI4usv"); - glad_glGetUniformuiv = (PFNGLGETUNIFORMUIVPROC)load("glGetUniformuiv"); - glad_glBindFragDataLocation = (PFNGLBINDFRAGDATALOCATIONPROC)load("glBindFragDataLocation"); - glad_glGetFragDataLocation = (PFNGLGETFRAGDATALOCATIONPROC)load("glGetFragDataLocation"); - glad_glUniform1ui = (PFNGLUNIFORM1UIPROC)load("glUniform1ui"); - glad_glUniform2ui = (PFNGLUNIFORM2UIPROC)load("glUniform2ui"); - glad_glUniform3ui = (PFNGLUNIFORM3UIPROC)load("glUniform3ui"); - glad_glUniform4ui = (PFNGLUNIFORM4UIPROC)load("glUniform4ui"); - glad_glUniform1uiv = (PFNGLUNIFORM1UIVPROC)load("glUniform1uiv"); - glad_glUniform2uiv = (PFNGLUNIFORM2UIVPROC)load("glUniform2uiv"); - glad_glUniform3uiv = (PFNGLUNIFORM3UIVPROC)load("glUniform3uiv"); - glad_glUniform4uiv = (PFNGLUNIFORM4UIVPROC)load("glUniform4uiv"); - glad_glTexParameterIiv = (PFNGLTEXPARAMETERIIVPROC)load("glTexParameterIiv"); - glad_glTexParameterIuiv = (PFNGLTEXPARAMETERIUIVPROC)load("glTexParameterIuiv"); - glad_glGetTexParameterIiv = (PFNGLGETTEXPARAMETERIIVPROC)load("glGetTexParameterIiv"); - glad_glGetTexParameterIuiv = (PFNGLGETTEXPARAMETERIUIVPROC)load("glGetTexParameterIuiv"); - glad_glClearBufferiv = (PFNGLCLEARBUFFERIVPROC)load("glClearBufferiv"); - glad_glClearBufferuiv = (PFNGLCLEARBUFFERUIVPROC)load("glClearBufferuiv"); - glad_glClearBufferfv = (PFNGLCLEARBUFFERFVPROC)load("glClearBufferfv"); - glad_glClearBufferfi = (PFNGLCLEARBUFFERFIPROC)load("glClearBufferfi"); - glad_glGetStringi = (PFNGLGETSTRINGIPROC)load("glGetStringi"); - glad_glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC)load("glIsRenderbuffer"); - glad_glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)load("glBindRenderbuffer"); - glad_glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)load("glDeleteRenderbuffers"); - glad_glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)load("glGenRenderbuffers"); - glad_glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)load("glRenderbufferStorage"); - glad_glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC)load("glGetRenderbufferParameteriv"); - glad_glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC)load("glIsFramebuffer"); - glad_glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)load("glBindFramebuffer"); - glad_glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)load("glDeleteFramebuffers"); - glad_glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)load("glGenFramebuffers"); - glad_glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)load("glCheckFramebufferStatus"); - glad_glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC)load("glFramebufferTexture1D"); - glad_glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)load("glFramebufferTexture2D"); - glad_glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC)load("glFramebufferTexture3D"); - glad_glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)load("glFramebufferRenderbuffer"); - glad_glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)load("glGetFramebufferAttachmentParameteriv"); - glad_glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC)load("glGenerateMipmap"); - glad_glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC)load("glBlitFramebuffer"); - glad_glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)load("glRenderbufferStorageMultisample"); - glad_glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC)load("glFramebufferTextureLayer"); - glad_glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC)load("glMapBufferRange"); - glad_glFlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC)load("glFlushMappedBufferRange"); - glad_glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)load("glBindVertexArray"); - glad_glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC)load("glDeleteVertexArrays"); - glad_glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)load("glGenVertexArrays"); - glad_glIsVertexArray = (PFNGLISVERTEXARRAYPROC)load("glIsVertexArray"); -} -static void load_GL_VERSION_3_1(GLADloadproc load) { - if(!GLAD_GL_VERSION_3_1) return; - glad_glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)load("glDrawArraysInstanced"); - glad_glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)load("glDrawElementsInstanced"); - glad_glTexBuffer = (PFNGLTEXBUFFERPROC)load("glTexBuffer"); - glad_glPrimitiveRestartIndex = (PFNGLPRIMITIVERESTARTINDEXPROC)load("glPrimitiveRestartIndex"); - glad_glCopyBufferSubData = (PFNGLCOPYBUFFERSUBDATAPROC)load("glCopyBufferSubData"); - glad_glGetUniformIndices = (PFNGLGETUNIFORMINDICESPROC)load("glGetUniformIndices"); - glad_glGetActiveUniformsiv = (PFNGLGETACTIVEUNIFORMSIVPROC)load("glGetActiveUniformsiv"); - glad_glGetActiveUniformName = (PFNGLGETACTIVEUNIFORMNAMEPROC)load("glGetActiveUniformName"); - glad_glGetUniformBlockIndex = (PFNGLGETUNIFORMBLOCKINDEXPROC)load("glGetUniformBlockIndex"); - glad_glGetActiveUniformBlockiv = (PFNGLGETACTIVEUNIFORMBLOCKIVPROC)load("glGetActiveUniformBlockiv"); - glad_glGetActiveUniformBlockName = (PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC)load("glGetActiveUniformBlockName"); - glad_glUniformBlockBinding = (PFNGLUNIFORMBLOCKBINDINGPROC)load("glUniformBlockBinding"); -} -static void load_GL_VERSION_3_2(GLADloadproc load) { - if(!GLAD_GL_VERSION_3_2) return; - glad_glDrawElementsBaseVertex = (PFNGLDRAWELEMENTSBASEVERTEXPROC)load("glDrawElementsBaseVertex"); - glad_glDrawRangeElementsBaseVertex = (PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC)load("glDrawRangeElementsBaseVertex"); - glad_glDrawElementsInstancedBaseVertex = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)load("glDrawElementsInstancedBaseVertex"); - glad_glMultiDrawElementsBaseVertex = (PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC)load("glMultiDrawElementsBaseVertex"); - glad_glProvokingVertex = (PFNGLPROVOKINGVERTEXPROC)load("glProvokingVertex"); - glad_glFenceSync = (PFNGLFENCESYNCPROC)load("glFenceSync"); - glad_glIsSync = (PFNGLISSYNCPROC)load("glIsSync"); - glad_glDeleteSync = (PFNGLDELETESYNCPROC)load("glDeleteSync"); - glad_glClientWaitSync = (PFNGLCLIENTWAITSYNCPROC)load("glClientWaitSync"); - glad_glWaitSync = (PFNGLWAITSYNCPROC)load("glWaitSync"); - glad_glGetInteger64v = (PFNGLGETINTEGER64VPROC)load("glGetInteger64v"); - glad_glGetSynciv = (PFNGLGETSYNCIVPROC)load("glGetSynciv"); - glad_glGetInteger64i_v = (PFNGLGETINTEGER64I_VPROC)load("glGetInteger64i_v"); - glad_glGetBufferParameteri64v = (PFNGLGETBUFFERPARAMETERI64VPROC)load("glGetBufferParameteri64v"); - glad_glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREPROC)load("glFramebufferTexture"); - glad_glTexImage2DMultisample = (PFNGLTEXIMAGE2DMULTISAMPLEPROC)load("glTexImage2DMultisample"); - glad_glTexImage3DMultisample = (PFNGLTEXIMAGE3DMULTISAMPLEPROC)load("glTexImage3DMultisample"); - glad_glGetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC)load("glGetMultisamplefv"); - glad_glSampleMaski = (PFNGLSAMPLEMASKIPROC)load("glSampleMaski"); -} -static void find_extensionsGL(void) { -} - -static void find_coreGL(void) { - const char *v = (const char *)glGetString(GL_VERSION); - int major = v[0] - '0'; - int minor = v[2] - '0'; - GLVersion.major = major; GLVersion.minor = minor; - GLAD_GL_VERSION_1_0 = (major == 1 && minor >= 0) || major > 1; - GLAD_GL_VERSION_1_1 = (major == 1 && minor >= 1) || major > 1; - GLAD_GL_VERSION_1_2 = (major == 1 && minor >= 2) || major > 1; - GLAD_GL_VERSION_1_3 = (major == 1 && minor >= 3) || major > 1; - GLAD_GL_VERSION_1_4 = (major == 1 && minor >= 4) || major > 1; - GLAD_GL_VERSION_1_5 = (major == 1 && minor >= 5) || major > 1; - GLAD_GL_VERSION_2_0 = (major == 2 && minor >= 0) || major > 2; - GLAD_GL_VERSION_2_1 = (major == 2 && minor >= 1) || major > 2; - GLAD_GL_VERSION_3_0 = (major == 3 && minor >= 0) || major > 3; - GLAD_GL_VERSION_3_1 = (major == 3 && minor >= 1) || major > 3; - GLAD_GL_VERSION_3_2 = (major == 3 && minor >= 2) || major > 3; -} - -void gladLoadGLLoader(GLADloadproc load) { - GLVersion.major = 0; GLVersion.minor = 0; - glGetString = (PFNGLGETSTRINGPROC)load("glGetString"); - if(glGetString == NULL) return; - find_coreGL(); - load_GL_VERSION_1_0(load); - load_GL_VERSION_1_1(load); - load_GL_VERSION_1_2(load); - load_GL_VERSION_1_3(load); - load_GL_VERSION_1_4(load); - load_GL_VERSION_1_5(load); - load_GL_VERSION_2_0(load); - load_GL_VERSION_2_1(load); - load_GL_VERSION_3_0(load); - load_GL_VERSION_3_1(load); - load_GL_VERSION_3_2(load); - - find_extensionsGL(); - - return; -} - diff --git a/examples/common/glfw/deps/glad/glad.h b/examples/common/glfw/deps/glad/glad.h deleted file mode 100644 index e5de4efc..00000000 --- a/examples/common/glfw/deps/glad/glad.h +++ /dev/null @@ -1,1925 +0,0 @@ - -#ifndef __glad_h_ - -#ifdef __gl_h_ -#error OpenGL header already included, remove this include, glad already provides it -#endif - -#define __glad_h_ -#define __gl_h_ - -#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN 1 -#endif -#include -#endif - -#ifndef APIENTRY -#define APIENTRY -#endif -#ifndef APIENTRYP -#define APIENTRYP APIENTRY * -#endif - -extern struct gladGLversionStruct { - int major; - int minor; -} GLVersion; - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void* (* GLADloadproc)(const char *name); - -#ifndef GLAPI -# if defined(GLAD_GLAPI_EXPORT) -# if defined(WIN32) || defined(__CYGWIN__) -# if defined(GLAD_GLAPI_EXPORT_BUILD) -# if defined(__GNUC__) -# define GLAPI __attribute__ ((dllexport)) extern -# else -# define GLAPI __declspec(dllexport) extern -# endif -# else -# if defined(__GNUC__) -# define GLAPI __attribute__ ((dllimport)) extern -# else -# define GLAPI __declspec(dllimport) extern -# endif -# endif -# elif defined(__GNUC__) && defined(GLAD_GLAPI_EXPORT_BUILD) -# define GLAPI __attribute__ ((visibility ("default"))) extern -# else -# define GLAPI extern -# endif -# else -# define GLAPI extern -# endif -#endif -GLAPI void gladLoadGLLoader(GLADloadproc); - -#include -#include -#ifndef GLEXT_64_TYPES_DEFINED -/* This code block is duplicated in glxext.h, so must be protected */ -#define GLEXT_64_TYPES_DEFINED -/* Define int32_t, int64_t, and uint64_t types for UST/MSC */ -/* (as used in the GL_EXT_timer_query extension). */ -#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L -#include -#elif defined(__sun__) || defined(__digital__) -#include -#if defined(__STDC__) -#if defined(__arch64__) || defined(_LP64) -typedef long int int64_t; -typedef unsigned long int uint64_t; -#else -typedef long long int int64_t; -typedef unsigned long long int uint64_t; -#endif /* __arch64__ */ -#endif /* __STDC__ */ -#elif defined( __VMS ) || defined(__sgi) -#include -#elif defined(__SCO__) || defined(__USLC__) -#include -#elif defined(__UNIXOS2__) || defined(__SOL64__) -typedef long int int32_t; -typedef long long int int64_t; -typedef unsigned long long int uint64_t; -#elif defined(_WIN32) && defined(__GNUC__) -#include -#elif defined(_WIN32) -typedef __int32 int32_t; -typedef __int64 int64_t; -typedef unsigned __int64 uint64_t; -#else -/* Fallback if nothing above works */ -#include -#endif -#endif -typedef unsigned int GLenum; -typedef unsigned char GLboolean; -typedef unsigned int GLbitfield; -typedef void GLvoid; -typedef signed char GLbyte; -typedef short GLshort; -typedef int GLint; -typedef int GLclampx; -typedef unsigned char GLubyte; -typedef unsigned short GLushort; -typedef unsigned int GLuint; -typedef int GLsizei; -typedef float GLfloat; -typedef float GLclampf; -typedef double GLdouble; -typedef double GLclampd; -typedef void *GLeglImageOES; -typedef char GLchar; -typedef char GLcharARB; -#ifdef __APPLE__ -typedef void *GLhandleARB; -#else -typedef unsigned int GLhandleARB; -#endif -typedef unsigned short GLhalfARB; -typedef unsigned short GLhalf; -typedef GLint GLfixed; -typedef ptrdiff_t GLintptr; -typedef ptrdiff_t GLsizeiptr; -typedef int64_t GLint64; -typedef uint64_t GLuint64; -typedef ptrdiff_t GLintptrARB; -typedef ptrdiff_t GLsizeiptrARB; -typedef int64_t GLint64EXT; -typedef uint64_t GLuint64EXT; -typedef struct __GLsync *GLsync; -struct _cl_context; -struct _cl_event; -typedef void (APIENTRY *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); -typedef void (APIENTRY *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); -typedef void (APIENTRY *GLDEBUGPROCKHR)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); -typedef void (APIENTRY *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,void *userParam); -typedef unsigned short GLhalfNV; -typedef GLintptr GLvdpauSurfaceNV; -#define GL_DEPTH_BUFFER_BIT 0x00000100 -#define GL_STENCIL_BUFFER_BIT 0x00000400 -#define GL_COLOR_BUFFER_BIT 0x00004000 -#define GL_FALSE 0 -#define GL_TRUE 1 -#define GL_POINTS 0x0000 -#define GL_LINES 0x0001 -#define GL_LINE_LOOP 0x0002 -#define GL_LINE_STRIP 0x0003 -#define GL_TRIANGLES 0x0004 -#define GL_TRIANGLE_STRIP 0x0005 -#define GL_TRIANGLE_FAN 0x0006 -#define GL_NEVER 0x0200 -#define GL_LESS 0x0201 -#define GL_EQUAL 0x0202 -#define GL_LEQUAL 0x0203 -#define GL_GREATER 0x0204 -#define GL_NOTEQUAL 0x0205 -#define GL_GEQUAL 0x0206 -#define GL_ALWAYS 0x0207 -#define GL_ZERO 0 -#define GL_ONE 1 -#define GL_SRC_COLOR 0x0300 -#define GL_ONE_MINUS_SRC_COLOR 0x0301 -#define GL_SRC_ALPHA 0x0302 -#define GL_ONE_MINUS_SRC_ALPHA 0x0303 -#define GL_DST_ALPHA 0x0304 -#define GL_ONE_MINUS_DST_ALPHA 0x0305 -#define GL_DST_COLOR 0x0306 -#define GL_ONE_MINUS_DST_COLOR 0x0307 -#define GL_SRC_ALPHA_SATURATE 0x0308 -#define GL_NONE 0 -#define GL_FRONT_LEFT 0x0400 -#define GL_FRONT_RIGHT 0x0401 -#define GL_BACK_LEFT 0x0402 -#define GL_BACK_RIGHT 0x0403 -#define GL_FRONT 0x0404 -#define GL_BACK 0x0405 -#define GL_LEFT 0x0406 -#define GL_RIGHT 0x0407 -#define GL_FRONT_AND_BACK 0x0408 -#define GL_NO_ERROR 0 -#define GL_INVALID_ENUM 0x0500 -#define GL_INVALID_VALUE 0x0501 -#define GL_INVALID_OPERATION 0x0502 -#define GL_OUT_OF_MEMORY 0x0505 -#define GL_CW 0x0900 -#define GL_CCW 0x0901 -#define GL_POINT_SIZE 0x0B11 -#define GL_POINT_SIZE_RANGE 0x0B12 -#define GL_POINT_SIZE_GRANULARITY 0x0B13 -#define GL_LINE_SMOOTH 0x0B20 -#define GL_LINE_WIDTH 0x0B21 -#define GL_LINE_WIDTH_RANGE 0x0B22 -#define GL_LINE_WIDTH_GRANULARITY 0x0B23 -#define GL_POLYGON_MODE 0x0B40 -#define GL_POLYGON_SMOOTH 0x0B41 -#define GL_CULL_FACE 0x0B44 -#define GL_CULL_FACE_MODE 0x0B45 -#define GL_FRONT_FACE 0x0B46 -#define GL_DEPTH_RANGE 0x0B70 -#define GL_DEPTH_TEST 0x0B71 -#define GL_DEPTH_WRITEMASK 0x0B72 -#define GL_DEPTH_CLEAR_VALUE 0x0B73 -#define GL_DEPTH_FUNC 0x0B74 -#define GL_STENCIL_TEST 0x0B90 -#define GL_STENCIL_CLEAR_VALUE 0x0B91 -#define GL_STENCIL_FUNC 0x0B92 -#define GL_STENCIL_VALUE_MASK 0x0B93 -#define GL_STENCIL_FAIL 0x0B94 -#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 -#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 -#define GL_STENCIL_REF 0x0B97 -#define GL_STENCIL_WRITEMASK 0x0B98 -#define GL_VIEWPORT 0x0BA2 -#define GL_DITHER 0x0BD0 -#define GL_BLEND_DST 0x0BE0 -#define GL_BLEND_SRC 0x0BE1 -#define GL_BLEND 0x0BE2 -#define GL_LOGIC_OP_MODE 0x0BF0 -#define GL_COLOR_LOGIC_OP 0x0BF2 -#define GL_DRAW_BUFFER 0x0C01 -#define GL_READ_BUFFER 0x0C02 -#define GL_SCISSOR_BOX 0x0C10 -#define GL_SCISSOR_TEST 0x0C11 -#define GL_COLOR_CLEAR_VALUE 0x0C22 -#define GL_COLOR_WRITEMASK 0x0C23 -#define GL_DOUBLEBUFFER 0x0C32 -#define GL_STEREO 0x0C33 -#define GL_LINE_SMOOTH_HINT 0x0C52 -#define GL_POLYGON_SMOOTH_HINT 0x0C53 -#define GL_UNPACK_SWAP_BYTES 0x0CF0 -#define GL_UNPACK_LSB_FIRST 0x0CF1 -#define GL_UNPACK_ROW_LENGTH 0x0CF2 -#define GL_UNPACK_SKIP_ROWS 0x0CF3 -#define GL_UNPACK_SKIP_PIXELS 0x0CF4 -#define GL_UNPACK_ALIGNMENT 0x0CF5 -#define GL_PACK_SWAP_BYTES 0x0D00 -#define GL_PACK_LSB_FIRST 0x0D01 -#define GL_PACK_ROW_LENGTH 0x0D02 -#define GL_PACK_SKIP_ROWS 0x0D03 -#define GL_PACK_SKIP_PIXELS 0x0D04 -#define GL_PACK_ALIGNMENT 0x0D05 -#define GL_MAX_TEXTURE_SIZE 0x0D33 -#define GL_MAX_VIEWPORT_DIMS 0x0D3A -#define GL_SUBPIXEL_BITS 0x0D50 -#define GL_TEXTURE_1D 0x0DE0 -#define GL_TEXTURE_2D 0x0DE1 -#define GL_POLYGON_OFFSET_UNITS 0x2A00 -#define GL_POLYGON_OFFSET_POINT 0x2A01 -#define GL_POLYGON_OFFSET_LINE 0x2A02 -#define GL_POLYGON_OFFSET_FILL 0x8037 -#define GL_POLYGON_OFFSET_FACTOR 0x8038 -#define GL_TEXTURE_BINDING_1D 0x8068 -#define GL_TEXTURE_BINDING_2D 0x8069 -#define GL_TEXTURE_WIDTH 0x1000 -#define GL_TEXTURE_HEIGHT 0x1001 -#define GL_TEXTURE_INTERNAL_FORMAT 0x1003 -#define GL_TEXTURE_BORDER_COLOR 0x1004 -#define GL_TEXTURE_RED_SIZE 0x805C -#define GL_TEXTURE_GREEN_SIZE 0x805D -#define GL_TEXTURE_BLUE_SIZE 0x805E -#define GL_TEXTURE_ALPHA_SIZE 0x805F -#define GL_DONT_CARE 0x1100 -#define GL_FASTEST 0x1101 -#define GL_NICEST 0x1102 -#define GL_BYTE 0x1400 -#define GL_UNSIGNED_BYTE 0x1401 -#define GL_SHORT 0x1402 -#define GL_UNSIGNED_SHORT 0x1403 -#define GL_INT 0x1404 -#define GL_UNSIGNED_INT 0x1405 -#define GL_FLOAT 0x1406 -#define GL_DOUBLE 0x140A -#define GL_CLEAR 0x1500 -#define GL_AND 0x1501 -#define GL_AND_REVERSE 0x1502 -#define GL_COPY 0x1503 -#define GL_AND_INVERTED 0x1504 -#define GL_NOOP 0x1505 -#define GL_XOR 0x1506 -#define GL_OR 0x1507 -#define GL_NOR 0x1508 -#define GL_EQUIV 0x1509 -#define GL_INVERT 0x150A -#define GL_OR_REVERSE 0x150B -#define GL_COPY_INVERTED 0x150C -#define GL_OR_INVERTED 0x150D -#define GL_NAND 0x150E -#define GL_SET 0x150F -#define GL_TEXTURE 0x1702 -#define GL_COLOR 0x1800 -#define GL_DEPTH 0x1801 -#define GL_STENCIL 0x1802 -#define GL_STENCIL_INDEX 0x1901 -#define GL_DEPTH_COMPONENT 0x1902 -#define GL_RED 0x1903 -#define GL_GREEN 0x1904 -#define GL_BLUE 0x1905 -#define GL_ALPHA 0x1906 -#define GL_RGB 0x1907 -#define GL_RGBA 0x1908 -#define GL_POINT 0x1B00 -#define GL_LINE 0x1B01 -#define GL_FILL 0x1B02 -#define GL_KEEP 0x1E00 -#define GL_REPLACE 0x1E01 -#define GL_INCR 0x1E02 -#define GL_DECR 0x1E03 -#define GL_VENDOR 0x1F00 -#define GL_RENDERER 0x1F01 -#define GL_VERSION 0x1F02 -#define GL_EXTENSIONS 0x1F03 -#define GL_NEAREST 0x2600 -#define GL_LINEAR 0x2601 -#define GL_NEAREST_MIPMAP_NEAREST 0x2700 -#define GL_LINEAR_MIPMAP_NEAREST 0x2701 -#define GL_NEAREST_MIPMAP_LINEAR 0x2702 -#define GL_LINEAR_MIPMAP_LINEAR 0x2703 -#define GL_TEXTURE_MAG_FILTER 0x2800 -#define GL_TEXTURE_MIN_FILTER 0x2801 -#define GL_TEXTURE_WRAP_S 0x2802 -#define GL_TEXTURE_WRAP_T 0x2803 -#define GL_PROXY_TEXTURE_1D 0x8063 -#define GL_PROXY_TEXTURE_2D 0x8064 -#define GL_REPEAT 0x2901 -#define GL_R3_G3_B2 0x2A10 -#define GL_RGB4 0x804F -#define GL_RGB5 0x8050 -#define GL_RGB8 0x8051 -#define GL_RGB10 0x8052 -#define GL_RGB12 0x8053 -#define GL_RGB16 0x8054 -#define GL_RGBA2 0x8055 -#define GL_RGBA4 0x8056 -#define GL_RGB5_A1 0x8057 -#define GL_RGBA8 0x8058 -#define GL_RGB10_A2 0x8059 -#define GL_RGBA12 0x805A -#define GL_RGBA16 0x805B -#define GL_UNSIGNED_BYTE_3_3_2 0x8032 -#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 -#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 -#define GL_UNSIGNED_INT_8_8_8_8 0x8035 -#define GL_UNSIGNED_INT_10_10_10_2 0x8036 -#define GL_TEXTURE_BINDING_3D 0x806A -#define GL_PACK_SKIP_IMAGES 0x806B -#define GL_PACK_IMAGE_HEIGHT 0x806C -#define GL_UNPACK_SKIP_IMAGES 0x806D -#define GL_UNPACK_IMAGE_HEIGHT 0x806E -#define GL_TEXTURE_3D 0x806F -#define GL_PROXY_TEXTURE_3D 0x8070 -#define GL_TEXTURE_DEPTH 0x8071 -#define GL_TEXTURE_WRAP_R 0x8072 -#define GL_MAX_3D_TEXTURE_SIZE 0x8073 -#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 -#define GL_UNSIGNED_SHORT_5_6_5 0x8363 -#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 -#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 -#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 -#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 -#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 -#define GL_BGR 0x80E0 -#define GL_BGRA 0x80E1 -#define GL_MAX_ELEMENTS_VERTICES 0x80E8 -#define GL_MAX_ELEMENTS_INDICES 0x80E9 -#define GL_CLAMP_TO_EDGE 0x812F -#define GL_TEXTURE_MIN_LOD 0x813A -#define GL_TEXTURE_MAX_LOD 0x813B -#define GL_TEXTURE_BASE_LEVEL 0x813C -#define GL_TEXTURE_MAX_LEVEL 0x813D -#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 -#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 -#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 -#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 -#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E -#define GL_TEXTURE0 0x84C0 -#define GL_TEXTURE1 0x84C1 -#define GL_TEXTURE2 0x84C2 -#define GL_TEXTURE3 0x84C3 -#define GL_TEXTURE4 0x84C4 -#define GL_TEXTURE5 0x84C5 -#define GL_TEXTURE6 0x84C6 -#define GL_TEXTURE7 0x84C7 -#define GL_TEXTURE8 0x84C8 -#define GL_TEXTURE9 0x84C9 -#define GL_TEXTURE10 0x84CA -#define GL_TEXTURE11 0x84CB -#define GL_TEXTURE12 0x84CC -#define GL_TEXTURE13 0x84CD -#define GL_TEXTURE14 0x84CE -#define GL_TEXTURE15 0x84CF -#define GL_TEXTURE16 0x84D0 -#define GL_TEXTURE17 0x84D1 -#define GL_TEXTURE18 0x84D2 -#define GL_TEXTURE19 0x84D3 -#define GL_TEXTURE20 0x84D4 -#define GL_TEXTURE21 0x84D5 -#define GL_TEXTURE22 0x84D6 -#define GL_TEXTURE23 0x84D7 -#define GL_TEXTURE24 0x84D8 -#define GL_TEXTURE25 0x84D9 -#define GL_TEXTURE26 0x84DA -#define GL_TEXTURE27 0x84DB -#define GL_TEXTURE28 0x84DC -#define GL_TEXTURE29 0x84DD -#define GL_TEXTURE30 0x84DE -#define GL_TEXTURE31 0x84DF -#define GL_ACTIVE_TEXTURE 0x84E0 -#define GL_MULTISAMPLE 0x809D -#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E -#define GL_SAMPLE_ALPHA_TO_ONE 0x809F -#define GL_SAMPLE_COVERAGE 0x80A0 -#define GL_SAMPLE_BUFFERS 0x80A8 -#define GL_SAMPLES 0x80A9 -#define GL_SAMPLE_COVERAGE_VALUE 0x80AA -#define GL_SAMPLE_COVERAGE_INVERT 0x80AB -#define GL_TEXTURE_CUBE_MAP 0x8513 -#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A -#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B -#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C -#define GL_COMPRESSED_RGB 0x84ED -#define GL_COMPRESSED_RGBA 0x84EE -#define GL_TEXTURE_COMPRESSION_HINT 0x84EF -#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 -#define GL_TEXTURE_COMPRESSED 0x86A1 -#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 -#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 -#define GL_CLAMP_TO_BORDER 0x812D -#define GL_BLEND_DST_RGB 0x80C8 -#define GL_BLEND_SRC_RGB 0x80C9 -#define GL_BLEND_DST_ALPHA 0x80CA -#define GL_BLEND_SRC_ALPHA 0x80CB -#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 -#define GL_DEPTH_COMPONENT16 0x81A5 -#define GL_DEPTH_COMPONENT24 0x81A6 -#define GL_DEPTH_COMPONENT32 0x81A7 -#define GL_MIRRORED_REPEAT 0x8370 -#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD -#define GL_TEXTURE_LOD_BIAS 0x8501 -#define GL_INCR_WRAP 0x8507 -#define GL_DECR_WRAP 0x8508 -#define GL_TEXTURE_DEPTH_SIZE 0x884A -#define GL_TEXTURE_COMPARE_MODE 0x884C -#define GL_TEXTURE_COMPARE_FUNC 0x884D -#define GL_FUNC_ADD 0x8006 -#define GL_FUNC_SUBTRACT 0x800A -#define GL_FUNC_REVERSE_SUBTRACT 0x800B -#define GL_MIN 0x8007 -#define GL_MAX 0x8008 -#define GL_CONSTANT_COLOR 0x8001 -#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 -#define GL_CONSTANT_ALPHA 0x8003 -#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 -#define GL_BUFFER_SIZE 0x8764 -#define GL_BUFFER_USAGE 0x8765 -#define GL_QUERY_COUNTER_BITS 0x8864 -#define GL_CURRENT_QUERY 0x8865 -#define GL_QUERY_RESULT 0x8866 -#define GL_QUERY_RESULT_AVAILABLE 0x8867 -#define GL_ARRAY_BUFFER 0x8892 -#define GL_ELEMENT_ARRAY_BUFFER 0x8893 -#define GL_ARRAY_BUFFER_BINDING 0x8894 -#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 -#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F -#define GL_READ_ONLY 0x88B8 -#define GL_WRITE_ONLY 0x88B9 -#define GL_READ_WRITE 0x88BA -#define GL_BUFFER_ACCESS 0x88BB -#define GL_BUFFER_MAPPED 0x88BC -#define GL_BUFFER_MAP_POINTER 0x88BD -#define GL_STREAM_DRAW 0x88E0 -#define GL_STREAM_READ 0x88E1 -#define GL_STREAM_COPY 0x88E2 -#define GL_STATIC_DRAW 0x88E4 -#define GL_STATIC_READ 0x88E5 -#define GL_STATIC_COPY 0x88E6 -#define GL_DYNAMIC_DRAW 0x88E8 -#define GL_DYNAMIC_READ 0x88E9 -#define GL_DYNAMIC_COPY 0x88EA -#define GL_SAMPLES_PASSED 0x8914 -#define GL_SRC1_ALPHA 0x8589 -#define GL_BLEND_EQUATION_RGB 0x8009 -#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 -#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 -#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 -#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 -#define GL_CURRENT_VERTEX_ATTRIB 0x8626 -#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 -#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 -#define GL_STENCIL_BACK_FUNC 0x8800 -#define GL_STENCIL_BACK_FAIL 0x8801 -#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 -#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 -#define GL_MAX_DRAW_BUFFERS 0x8824 -#define GL_DRAW_BUFFER0 0x8825 -#define GL_DRAW_BUFFER1 0x8826 -#define GL_DRAW_BUFFER2 0x8827 -#define GL_DRAW_BUFFER3 0x8828 -#define GL_DRAW_BUFFER4 0x8829 -#define GL_DRAW_BUFFER5 0x882A -#define GL_DRAW_BUFFER6 0x882B -#define GL_DRAW_BUFFER7 0x882C -#define GL_DRAW_BUFFER8 0x882D -#define GL_DRAW_BUFFER9 0x882E -#define GL_DRAW_BUFFER10 0x882F -#define GL_DRAW_BUFFER11 0x8830 -#define GL_DRAW_BUFFER12 0x8831 -#define GL_DRAW_BUFFER13 0x8832 -#define GL_DRAW_BUFFER14 0x8833 -#define GL_DRAW_BUFFER15 0x8834 -#define GL_BLEND_EQUATION_ALPHA 0x883D -#define GL_MAX_VERTEX_ATTRIBS 0x8869 -#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A -#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 -#define GL_FRAGMENT_SHADER 0x8B30 -#define GL_VERTEX_SHADER 0x8B31 -#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 -#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A -#define GL_MAX_VARYING_FLOATS 0x8B4B -#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C -#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D -#define GL_SHADER_TYPE 0x8B4F -#define GL_FLOAT_VEC2 0x8B50 -#define GL_FLOAT_VEC3 0x8B51 -#define GL_FLOAT_VEC4 0x8B52 -#define GL_INT_VEC2 0x8B53 -#define GL_INT_VEC3 0x8B54 -#define GL_INT_VEC4 0x8B55 -#define GL_BOOL 0x8B56 -#define GL_BOOL_VEC2 0x8B57 -#define GL_BOOL_VEC3 0x8B58 -#define GL_BOOL_VEC4 0x8B59 -#define GL_FLOAT_MAT2 0x8B5A -#define GL_FLOAT_MAT3 0x8B5B -#define GL_FLOAT_MAT4 0x8B5C -#define GL_SAMPLER_1D 0x8B5D -#define GL_SAMPLER_2D 0x8B5E -#define GL_SAMPLER_3D 0x8B5F -#define GL_SAMPLER_CUBE 0x8B60 -#define GL_SAMPLER_1D_SHADOW 0x8B61 -#define GL_SAMPLER_2D_SHADOW 0x8B62 -#define GL_DELETE_STATUS 0x8B80 -#define GL_COMPILE_STATUS 0x8B81 -#define GL_LINK_STATUS 0x8B82 -#define GL_VALIDATE_STATUS 0x8B83 -#define GL_INFO_LOG_LENGTH 0x8B84 -#define GL_ATTACHED_SHADERS 0x8B85 -#define GL_ACTIVE_UNIFORMS 0x8B86 -#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 -#define GL_SHADER_SOURCE_LENGTH 0x8B88 -#define GL_ACTIVE_ATTRIBUTES 0x8B89 -#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A -#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B -#define GL_SHADING_LANGUAGE_VERSION 0x8B8C -#define GL_CURRENT_PROGRAM 0x8B8D -#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 -#define GL_LOWER_LEFT 0x8CA1 -#define GL_UPPER_LEFT 0x8CA2 -#define GL_STENCIL_BACK_REF 0x8CA3 -#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 -#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 -#define GL_PIXEL_PACK_BUFFER 0x88EB -#define GL_PIXEL_UNPACK_BUFFER 0x88EC -#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED -#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF -#define GL_FLOAT_MAT2x3 0x8B65 -#define GL_FLOAT_MAT2x4 0x8B66 -#define GL_FLOAT_MAT3x2 0x8B67 -#define GL_FLOAT_MAT3x4 0x8B68 -#define GL_FLOAT_MAT4x2 0x8B69 -#define GL_FLOAT_MAT4x3 0x8B6A -#define GL_SRGB 0x8C40 -#define GL_SRGB8 0x8C41 -#define GL_SRGB_ALPHA 0x8C42 -#define GL_SRGB8_ALPHA8 0x8C43 -#define GL_COMPRESSED_SRGB 0x8C48 -#define GL_COMPRESSED_SRGB_ALPHA 0x8C49 -#define GL_COMPARE_REF_TO_TEXTURE 0x884E -#define GL_CLIP_DISTANCE0 0x3000 -#define GL_CLIP_DISTANCE1 0x3001 -#define GL_CLIP_DISTANCE2 0x3002 -#define GL_CLIP_DISTANCE3 0x3003 -#define GL_CLIP_DISTANCE4 0x3004 -#define GL_CLIP_DISTANCE5 0x3005 -#define GL_CLIP_DISTANCE6 0x3006 -#define GL_CLIP_DISTANCE7 0x3007 -#define GL_MAX_CLIP_DISTANCES 0x0D32 -#define GL_MAJOR_VERSION 0x821B -#define GL_MINOR_VERSION 0x821C -#define GL_NUM_EXTENSIONS 0x821D -#define GL_CONTEXT_FLAGS 0x821E -#define GL_COMPRESSED_RED 0x8225 -#define GL_COMPRESSED_RG 0x8226 -#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x00000001 -#define GL_RGBA32F 0x8814 -#define GL_RGB32F 0x8815 -#define GL_RGBA16F 0x881A -#define GL_RGB16F 0x881B -#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD -#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF -#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 -#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 -#define GL_CLAMP_READ_COLOR 0x891C -#define GL_FIXED_ONLY 0x891D -#define GL_MAX_VARYING_COMPONENTS 0x8B4B -#define GL_TEXTURE_1D_ARRAY 0x8C18 -#define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19 -#define GL_TEXTURE_2D_ARRAY 0x8C1A -#define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B -#define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C -#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D -#define GL_R11F_G11F_B10F 0x8C3A -#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B -#define GL_RGB9_E5 0x8C3D -#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E -#define GL_TEXTURE_SHARED_SIZE 0x8C3F -#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 -#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 -#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 -#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 -#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 -#define GL_PRIMITIVES_GENERATED 0x8C87 -#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 -#define GL_RASTERIZER_DISCARD 0x8C89 -#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B -#define GL_INTERLEAVED_ATTRIBS 0x8C8C -#define GL_SEPARATE_ATTRIBS 0x8C8D -#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E -#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F -#define GL_RGBA32UI 0x8D70 -#define GL_RGB32UI 0x8D71 -#define GL_RGBA16UI 0x8D76 -#define GL_RGB16UI 0x8D77 -#define GL_RGBA8UI 0x8D7C -#define GL_RGB8UI 0x8D7D -#define GL_RGBA32I 0x8D82 -#define GL_RGB32I 0x8D83 -#define GL_RGBA16I 0x8D88 -#define GL_RGB16I 0x8D89 -#define GL_RGBA8I 0x8D8E -#define GL_RGB8I 0x8D8F -#define GL_RED_INTEGER 0x8D94 -#define GL_GREEN_INTEGER 0x8D95 -#define GL_BLUE_INTEGER 0x8D96 -#define GL_RGB_INTEGER 0x8D98 -#define GL_RGBA_INTEGER 0x8D99 -#define GL_BGR_INTEGER 0x8D9A -#define GL_BGRA_INTEGER 0x8D9B -#define GL_SAMPLER_1D_ARRAY 0x8DC0 -#define GL_SAMPLER_2D_ARRAY 0x8DC1 -#define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3 -#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 -#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 -#define GL_UNSIGNED_INT_VEC2 0x8DC6 -#define GL_UNSIGNED_INT_VEC3 0x8DC7 -#define GL_UNSIGNED_INT_VEC4 0x8DC8 -#define GL_INT_SAMPLER_1D 0x8DC9 -#define GL_INT_SAMPLER_2D 0x8DCA -#define GL_INT_SAMPLER_3D 0x8DCB -#define GL_INT_SAMPLER_CUBE 0x8DCC -#define GL_INT_SAMPLER_1D_ARRAY 0x8DCE -#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF -#define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1 -#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 -#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 -#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 -#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6 -#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 -#define GL_QUERY_WAIT 0x8E13 -#define GL_QUERY_NO_WAIT 0x8E14 -#define GL_QUERY_BY_REGION_WAIT 0x8E15 -#define GL_QUERY_BY_REGION_NO_WAIT 0x8E16 -#define GL_BUFFER_ACCESS_FLAGS 0x911F -#define GL_BUFFER_MAP_LENGTH 0x9120 -#define GL_BUFFER_MAP_OFFSET 0x9121 -#define GL_DEPTH_COMPONENT32F 0x8CAC -#define GL_DEPTH32F_STENCIL8 0x8CAD -#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD -#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 -#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 -#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 -#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 -#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 -#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 -#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 -#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 -#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 -#define GL_FRAMEBUFFER_DEFAULT 0x8218 -#define GL_FRAMEBUFFER_UNDEFINED 0x8219 -#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A -#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 -#define GL_DEPTH_STENCIL 0x84F9 -#define GL_UNSIGNED_INT_24_8 0x84FA -#define GL_DEPTH24_STENCIL8 0x88F0 -#define GL_TEXTURE_STENCIL_SIZE 0x88F1 -#define GL_TEXTURE_RED_TYPE 0x8C10 -#define GL_TEXTURE_GREEN_TYPE 0x8C11 -#define GL_TEXTURE_BLUE_TYPE 0x8C12 -#define GL_TEXTURE_ALPHA_TYPE 0x8C13 -#define GL_TEXTURE_DEPTH_TYPE 0x8C16 -#define GL_UNSIGNED_NORMALIZED 0x8C17 -#define GL_FRAMEBUFFER_BINDING 0x8CA6 -#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6 -#define GL_RENDERBUFFER_BINDING 0x8CA7 -#define GL_READ_FRAMEBUFFER 0x8CA8 -#define GL_DRAW_FRAMEBUFFER 0x8CA9 -#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA -#define GL_RENDERBUFFER_SAMPLES 0x8CAB -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 -#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 -#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 -#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 -#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB -#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC -#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD -#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF -#define GL_COLOR_ATTACHMENT0 0x8CE0 -#define GL_COLOR_ATTACHMENT1 0x8CE1 -#define GL_COLOR_ATTACHMENT2 0x8CE2 -#define GL_COLOR_ATTACHMENT3 0x8CE3 -#define GL_COLOR_ATTACHMENT4 0x8CE4 -#define GL_COLOR_ATTACHMENT5 0x8CE5 -#define GL_COLOR_ATTACHMENT6 0x8CE6 -#define GL_COLOR_ATTACHMENT7 0x8CE7 -#define GL_COLOR_ATTACHMENT8 0x8CE8 -#define GL_COLOR_ATTACHMENT9 0x8CE9 -#define GL_COLOR_ATTACHMENT10 0x8CEA -#define GL_COLOR_ATTACHMENT11 0x8CEB -#define GL_COLOR_ATTACHMENT12 0x8CEC -#define GL_COLOR_ATTACHMENT13 0x8CED -#define GL_COLOR_ATTACHMENT14 0x8CEE -#define GL_COLOR_ATTACHMENT15 0x8CEF -#define GL_DEPTH_ATTACHMENT 0x8D00 -#define GL_STENCIL_ATTACHMENT 0x8D20 -#define GL_FRAMEBUFFER 0x8D40 -#define GL_RENDERBUFFER 0x8D41 -#define GL_RENDERBUFFER_WIDTH 0x8D42 -#define GL_RENDERBUFFER_HEIGHT 0x8D43 -#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 -#define GL_STENCIL_INDEX1 0x8D46 -#define GL_STENCIL_INDEX4 0x8D47 -#define GL_STENCIL_INDEX8 0x8D48 -#define GL_STENCIL_INDEX16 0x8D49 -#define GL_RENDERBUFFER_RED_SIZE 0x8D50 -#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 -#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 -#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 -#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 -#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 -#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 -#define GL_MAX_SAMPLES 0x8D57 -#define GL_INDEX 0x8222 -#define GL_FRAMEBUFFER_SRGB 0x8DB9 -#define GL_HALF_FLOAT 0x140B -#define GL_MAP_READ_BIT 0x0001 -#define GL_MAP_WRITE_BIT 0x0002 -#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 -#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 -#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 -#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 -#define GL_COMPRESSED_RED_RGTC1 0x8DBB -#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC -#define GL_COMPRESSED_RG_RGTC2 0x8DBD -#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE -#define GL_RG 0x8227 -#define GL_RG_INTEGER 0x8228 -#define GL_R8 0x8229 -#define GL_R16 0x822A -#define GL_RG8 0x822B -#define GL_RG16 0x822C -#define GL_R16F 0x822D -#define GL_R32F 0x822E -#define GL_RG16F 0x822F -#define GL_RG32F 0x8230 -#define GL_R8I 0x8231 -#define GL_R8UI 0x8232 -#define GL_R16I 0x8233 -#define GL_R16UI 0x8234 -#define GL_R32I 0x8235 -#define GL_R32UI 0x8236 -#define GL_RG8I 0x8237 -#define GL_RG8UI 0x8238 -#define GL_RG16I 0x8239 -#define GL_RG16UI 0x823A -#define GL_RG32I 0x823B -#define GL_RG32UI 0x823C -#define GL_VERTEX_ARRAY_BINDING 0x85B5 -#define GL_SAMPLER_2D_RECT 0x8B63 -#define GL_SAMPLER_2D_RECT_SHADOW 0x8B64 -#define GL_SAMPLER_BUFFER 0x8DC2 -#define GL_INT_SAMPLER_2D_RECT 0x8DCD -#define GL_INT_SAMPLER_BUFFER 0x8DD0 -#define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5 -#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8 -#define GL_TEXTURE_BUFFER 0x8C2A -#define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B -#define GL_TEXTURE_BINDING_BUFFER 0x8C2C -#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D -#define GL_TEXTURE_RECTANGLE 0x84F5 -#define GL_TEXTURE_BINDING_RECTANGLE 0x84F6 -#define GL_PROXY_TEXTURE_RECTANGLE 0x84F7 -#define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8 -#define GL_R8_SNORM 0x8F94 -#define GL_RG8_SNORM 0x8F95 -#define GL_RGB8_SNORM 0x8F96 -#define GL_RGBA8_SNORM 0x8F97 -#define GL_R16_SNORM 0x8F98 -#define GL_RG16_SNORM 0x8F99 -#define GL_RGB16_SNORM 0x8F9A -#define GL_RGBA16_SNORM 0x8F9B -#define GL_SIGNED_NORMALIZED 0x8F9C -#define GL_PRIMITIVE_RESTART 0x8F9D -#define GL_PRIMITIVE_RESTART_INDEX 0x8F9E -#define GL_COPY_READ_BUFFER 0x8F36 -#define GL_COPY_WRITE_BUFFER 0x8F37 -#define GL_UNIFORM_BUFFER 0x8A11 -#define GL_UNIFORM_BUFFER_BINDING 0x8A28 -#define GL_UNIFORM_BUFFER_START 0x8A29 -#define GL_UNIFORM_BUFFER_SIZE 0x8A2A -#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B -#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D -#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E -#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F -#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 -#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 -#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 -#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34 -#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35 -#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 -#define GL_UNIFORM_TYPE 0x8A37 -#define GL_UNIFORM_SIZE 0x8A38 -#define GL_UNIFORM_NAME_LENGTH 0x8A39 -#define GL_UNIFORM_BLOCK_INDEX 0x8A3A -#define GL_UNIFORM_OFFSET 0x8A3B -#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C -#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D -#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E -#define GL_UNIFORM_BLOCK_BINDING 0x8A3F -#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 -#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41 -#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 -#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43 -#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 -#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 -#define GL_INVALID_INDEX 0xFFFFFFFF -#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001 -#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002 -#define GL_LINES_ADJACENCY 0x000A -#define GL_LINE_STRIP_ADJACENCY 0x000B -#define GL_TRIANGLES_ADJACENCY 0x000C -#define GL_TRIANGLE_STRIP_ADJACENCY 0x000D -#define GL_PROGRAM_POINT_SIZE 0x8642 -#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29 -#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7 -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8 -#define GL_GEOMETRY_SHADER 0x8DD9 -#define GL_GEOMETRY_VERTICES_OUT 0x8916 -#define GL_GEOMETRY_INPUT_TYPE 0x8917 -#define GL_GEOMETRY_OUTPUT_TYPE 0x8918 -#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF -#define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0 -#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1 -#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 -#define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123 -#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124 -#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 -#define GL_CONTEXT_PROFILE_MASK 0x9126 -#define GL_DEPTH_CLAMP 0x864F -#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C -#define GL_FIRST_VERTEX_CONVENTION 0x8E4D -#define GL_LAST_VERTEX_CONVENTION 0x8E4E -#define GL_PROVOKING_VERTEX 0x8E4F -#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F -#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111 -#define GL_OBJECT_TYPE 0x9112 -#define GL_SYNC_CONDITION 0x9113 -#define GL_SYNC_STATUS 0x9114 -#define GL_SYNC_FLAGS 0x9115 -#define GL_SYNC_FENCE 0x9116 -#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 -#define GL_UNSIGNALED 0x9118 -#define GL_SIGNALED 0x9119 -#define GL_ALREADY_SIGNALED 0x911A -#define GL_TIMEOUT_EXPIRED 0x911B -#define GL_CONDITION_SATISFIED 0x911C -#define GL_WAIT_FAILED 0x911D -#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFF -#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 -#define GL_SAMPLE_POSITION 0x8E50 -#define GL_SAMPLE_MASK 0x8E51 -#define GL_SAMPLE_MASK_VALUE 0x8E52 -#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59 -#define GL_TEXTURE_2D_MULTISAMPLE 0x9100 -#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101 -#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102 -#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103 -#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104 -#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105 -#define GL_TEXTURE_SAMPLES 0x9106 -#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107 -#define GL_SAMPLER_2D_MULTISAMPLE 0x9108 -#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 -#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A -#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B -#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C -#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D -#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E -#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F -#define GL_MAX_INTEGER_SAMPLES 0x9110 -#ifndef GL_VERSION_1_0 -#define GL_VERSION_1_0 1 -GLAPI int GLAD_GL_VERSION_1_0; -typedef void (APIENTRYP PFNGLCULLFACEPROC)(GLenum); -GLAPI PFNGLCULLFACEPROC glad_glCullFace; -#define glCullFace glad_glCullFace -typedef void (APIENTRYP PFNGLFRONTFACEPROC)(GLenum); -GLAPI PFNGLFRONTFACEPROC glad_glFrontFace; -#define glFrontFace glad_glFrontFace -typedef void (APIENTRYP PFNGLHINTPROC)(GLenum, GLenum); -GLAPI PFNGLHINTPROC glad_glHint; -#define glHint glad_glHint -typedef void (APIENTRYP PFNGLLINEWIDTHPROC)(GLfloat); -GLAPI PFNGLLINEWIDTHPROC glad_glLineWidth; -#define glLineWidth glad_glLineWidth -typedef void (APIENTRYP PFNGLPOINTSIZEPROC)(GLfloat); -GLAPI PFNGLPOINTSIZEPROC glad_glPointSize; -#define glPointSize glad_glPointSize -typedef void (APIENTRYP PFNGLPOLYGONMODEPROC)(GLenum, GLenum); -GLAPI PFNGLPOLYGONMODEPROC glad_glPolygonMode; -#define glPolygonMode glad_glPolygonMode -typedef void (APIENTRYP PFNGLSCISSORPROC)(GLint, GLint, GLsizei, GLsizei); -GLAPI PFNGLSCISSORPROC glad_glScissor; -#define glScissor glad_glScissor -typedef void (APIENTRYP PFNGLTEXPARAMETERFPROC)(GLenum, GLenum, GLfloat); -GLAPI PFNGLTEXPARAMETERFPROC glad_glTexParameterf; -#define glTexParameterf glad_glTexParameterf -typedef void (APIENTRYP PFNGLTEXPARAMETERFVPROC)(GLenum, GLenum, const GLfloat*); -GLAPI PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv; -#define glTexParameterfv glad_glTexParameterfv -typedef void (APIENTRYP PFNGLTEXPARAMETERIPROC)(GLenum, GLenum, GLint); -GLAPI PFNGLTEXPARAMETERIPROC glad_glTexParameteri; -#define glTexParameteri glad_glTexParameteri -typedef void (APIENTRYP PFNGLTEXPARAMETERIVPROC)(GLenum, GLenum, const GLint*); -GLAPI PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv; -#define glTexParameteriv glad_glTexParameteriv -typedef void (APIENTRYP PFNGLTEXIMAGE1DPROC)(GLenum, GLint, GLint, GLsizei, GLint, GLenum, GLenum, const void*); -GLAPI PFNGLTEXIMAGE1DPROC glad_glTexImage1D; -#define glTexImage1D glad_glTexImage1D -typedef void (APIENTRYP PFNGLTEXIMAGE2DPROC)(GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const void*); -GLAPI PFNGLTEXIMAGE2DPROC glad_glTexImage2D; -#define glTexImage2D glad_glTexImage2D -typedef void (APIENTRYP PFNGLDRAWBUFFERPROC)(GLenum); -GLAPI PFNGLDRAWBUFFERPROC glad_glDrawBuffer; -#define glDrawBuffer glad_glDrawBuffer -typedef void (APIENTRYP PFNGLCLEARPROC)(GLbitfield); -GLAPI PFNGLCLEARPROC glad_glClear; -#define glClear glad_glClear -typedef void (APIENTRYP PFNGLCLEARCOLORPROC)(GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI PFNGLCLEARCOLORPROC glad_glClearColor; -#define glClearColor glad_glClearColor -typedef void (APIENTRYP PFNGLCLEARSTENCILPROC)(GLint); -GLAPI PFNGLCLEARSTENCILPROC glad_glClearStencil; -#define glClearStencil glad_glClearStencil -typedef void (APIENTRYP PFNGLCLEARDEPTHPROC)(GLdouble); -GLAPI PFNGLCLEARDEPTHPROC glad_glClearDepth; -#define glClearDepth glad_glClearDepth -typedef void (APIENTRYP PFNGLSTENCILMASKPROC)(GLuint); -GLAPI PFNGLSTENCILMASKPROC glad_glStencilMask; -#define glStencilMask glad_glStencilMask -typedef void (APIENTRYP PFNGLCOLORMASKPROC)(GLboolean, GLboolean, GLboolean, GLboolean); -GLAPI PFNGLCOLORMASKPROC glad_glColorMask; -#define glColorMask glad_glColorMask -typedef void (APIENTRYP PFNGLDEPTHMASKPROC)(GLboolean); -GLAPI PFNGLDEPTHMASKPROC glad_glDepthMask; -#define glDepthMask glad_glDepthMask -typedef void (APIENTRYP PFNGLDISABLEPROC)(GLenum); -GLAPI PFNGLDISABLEPROC glad_glDisable; -#define glDisable glad_glDisable -typedef void (APIENTRYP PFNGLENABLEPROC)(GLenum); -GLAPI PFNGLENABLEPROC glad_glEnable; -#define glEnable glad_glEnable -typedef void (APIENTRYP PFNGLFINISHPROC)(); -GLAPI PFNGLFINISHPROC glad_glFinish; -#define glFinish glad_glFinish -typedef void (APIENTRYP PFNGLFLUSHPROC)(); -GLAPI PFNGLFLUSHPROC glad_glFlush; -#define glFlush glad_glFlush -typedef void (APIENTRYP PFNGLBLENDFUNCPROC)(GLenum, GLenum); -GLAPI PFNGLBLENDFUNCPROC glad_glBlendFunc; -#define glBlendFunc glad_glBlendFunc -typedef void (APIENTRYP PFNGLLOGICOPPROC)(GLenum); -GLAPI PFNGLLOGICOPPROC glad_glLogicOp; -#define glLogicOp glad_glLogicOp -typedef void (APIENTRYP PFNGLSTENCILFUNCPROC)(GLenum, GLint, GLuint); -GLAPI PFNGLSTENCILFUNCPROC glad_glStencilFunc; -#define glStencilFunc glad_glStencilFunc -typedef void (APIENTRYP PFNGLSTENCILOPPROC)(GLenum, GLenum, GLenum); -GLAPI PFNGLSTENCILOPPROC glad_glStencilOp; -#define glStencilOp glad_glStencilOp -typedef void (APIENTRYP PFNGLDEPTHFUNCPROC)(GLenum); -GLAPI PFNGLDEPTHFUNCPROC glad_glDepthFunc; -#define glDepthFunc glad_glDepthFunc -typedef void (APIENTRYP PFNGLPIXELSTOREFPROC)(GLenum, GLfloat); -GLAPI PFNGLPIXELSTOREFPROC glad_glPixelStoref; -#define glPixelStoref glad_glPixelStoref -typedef void (APIENTRYP PFNGLPIXELSTOREIPROC)(GLenum, GLint); -GLAPI PFNGLPIXELSTOREIPROC glad_glPixelStorei; -#define glPixelStorei glad_glPixelStorei -typedef void (APIENTRYP PFNGLREADBUFFERPROC)(GLenum); -GLAPI PFNGLREADBUFFERPROC glad_glReadBuffer; -#define glReadBuffer glad_glReadBuffer -typedef void (APIENTRYP PFNGLREADPIXELSPROC)(GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, void*); -GLAPI PFNGLREADPIXELSPROC glad_glReadPixels; -#define glReadPixels glad_glReadPixels -typedef void (APIENTRYP PFNGLGETBOOLEANVPROC)(GLenum, GLboolean*); -GLAPI PFNGLGETBOOLEANVPROC glad_glGetBooleanv; -#define glGetBooleanv glad_glGetBooleanv -typedef void (APIENTRYP PFNGLGETDOUBLEVPROC)(GLenum, GLdouble*); -GLAPI PFNGLGETDOUBLEVPROC glad_glGetDoublev; -#define glGetDoublev glad_glGetDoublev -typedef GLenum (APIENTRYP PFNGLGETERRORPROC)(); -GLAPI PFNGLGETERRORPROC glad_glGetError; -#define glGetError glad_glGetError -typedef void (APIENTRYP PFNGLGETFLOATVPROC)(GLenum, GLfloat*); -GLAPI PFNGLGETFLOATVPROC glad_glGetFloatv; -#define glGetFloatv glad_glGetFloatv -typedef void (APIENTRYP PFNGLGETINTEGERVPROC)(GLenum, GLint*); -GLAPI PFNGLGETINTEGERVPROC glad_glGetIntegerv; -#define glGetIntegerv glad_glGetIntegerv -typedef const GLubyte* (APIENTRYP PFNGLGETSTRINGPROC)(GLenum); -GLAPI PFNGLGETSTRINGPROC glad_glGetString; -#define glGetString glad_glGetString -typedef void (APIENTRYP PFNGLGETTEXIMAGEPROC)(GLenum, GLint, GLenum, GLenum, void*); -GLAPI PFNGLGETTEXIMAGEPROC glad_glGetTexImage; -#define glGetTexImage glad_glGetTexImage -typedef void (APIENTRYP PFNGLGETTEXPARAMETERFVPROC)(GLenum, GLenum, GLfloat*); -GLAPI PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv; -#define glGetTexParameterfv glad_glGetTexParameterfv -typedef void (APIENTRYP PFNGLGETTEXPARAMETERIVPROC)(GLenum, GLenum, GLint*); -GLAPI PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv; -#define glGetTexParameteriv glad_glGetTexParameteriv -typedef void (APIENTRYP PFNGLGETTEXLEVELPARAMETERFVPROC)(GLenum, GLint, GLenum, GLfloat*); -GLAPI PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv; -#define glGetTexLevelParameterfv glad_glGetTexLevelParameterfv -typedef void (APIENTRYP PFNGLGETTEXLEVELPARAMETERIVPROC)(GLenum, GLint, GLenum, GLint*); -GLAPI PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv; -#define glGetTexLevelParameteriv glad_glGetTexLevelParameteriv -typedef GLboolean (APIENTRYP PFNGLISENABLEDPROC)(GLenum); -GLAPI PFNGLISENABLEDPROC glad_glIsEnabled; -#define glIsEnabled glad_glIsEnabled -typedef void (APIENTRYP PFNGLDEPTHRANGEPROC)(GLdouble, GLdouble); -GLAPI PFNGLDEPTHRANGEPROC glad_glDepthRange; -#define glDepthRange glad_glDepthRange -typedef void (APIENTRYP PFNGLVIEWPORTPROC)(GLint, GLint, GLsizei, GLsizei); -GLAPI PFNGLVIEWPORTPROC glad_glViewport; -#define glViewport glad_glViewport -#endif -#ifndef GL_VERSION_1_1 -#define GL_VERSION_1_1 1 -GLAPI int GLAD_GL_VERSION_1_1; -typedef void (APIENTRYP PFNGLDRAWARRAYSPROC)(GLenum, GLint, GLsizei); -GLAPI PFNGLDRAWARRAYSPROC glad_glDrawArrays; -#define glDrawArrays glad_glDrawArrays -typedef void (APIENTRYP PFNGLDRAWELEMENTSPROC)(GLenum, GLsizei, GLenum, const void*); -GLAPI PFNGLDRAWELEMENTSPROC glad_glDrawElements; -#define glDrawElements glad_glDrawElements -typedef void (APIENTRYP PFNGLPOLYGONOFFSETPROC)(GLfloat, GLfloat); -GLAPI PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset; -#define glPolygonOffset glad_glPolygonOffset -typedef void (APIENTRYP PFNGLCOPYTEXIMAGE1DPROC)(GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLint); -GLAPI PFNGLCOPYTEXIMAGE1DPROC glad_glCopyTexImage1D; -#define glCopyTexImage1D glad_glCopyTexImage1D -typedef void (APIENTRYP PFNGLCOPYTEXIMAGE2DPROC)(GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint); -GLAPI PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D; -#define glCopyTexImage2D glad_glCopyTexImage2D -typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE1DPROC)(GLenum, GLint, GLint, GLint, GLint, GLsizei); -GLAPI PFNGLCOPYTEXSUBIMAGE1DPROC glad_glCopyTexSubImage1D; -#define glCopyTexSubImage1D glad_glCopyTexSubImage1D -typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE2DPROC)(GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); -GLAPI PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D; -#define glCopyTexSubImage2D glad_glCopyTexSubImage2D -typedef void (APIENTRYP PFNGLTEXSUBIMAGE1DPROC)(GLenum, GLint, GLint, GLsizei, GLenum, GLenum, const void*); -GLAPI PFNGLTEXSUBIMAGE1DPROC glad_glTexSubImage1D; -#define glTexSubImage1D glad_glTexSubImage1D -typedef void (APIENTRYP PFNGLTEXSUBIMAGE2DPROC)(GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const void*); -GLAPI PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D; -#define glTexSubImage2D glad_glTexSubImage2D -typedef void (APIENTRYP PFNGLBINDTEXTUREPROC)(GLenum, GLuint); -GLAPI PFNGLBINDTEXTUREPROC glad_glBindTexture; -#define glBindTexture glad_glBindTexture -typedef void (APIENTRYP PFNGLDELETETEXTURESPROC)(GLsizei, const GLuint*); -GLAPI PFNGLDELETETEXTURESPROC glad_glDeleteTextures; -#define glDeleteTextures glad_glDeleteTextures -typedef void (APIENTRYP PFNGLGENTEXTURESPROC)(GLsizei, GLuint*); -GLAPI PFNGLGENTEXTURESPROC glad_glGenTextures; -#define glGenTextures glad_glGenTextures -typedef GLboolean (APIENTRYP PFNGLISTEXTUREPROC)(GLuint); -GLAPI PFNGLISTEXTUREPROC glad_glIsTexture; -#define glIsTexture glad_glIsTexture -#endif -#ifndef GL_VERSION_1_2 -#define GL_VERSION_1_2 1 -GLAPI int GLAD_GL_VERSION_1_2; -typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSPROC)(GLenum, GLuint, GLuint, GLsizei, GLenum, const void*); -GLAPI PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements; -#define glDrawRangeElements glad_glDrawRangeElements -typedef void (APIENTRYP PFNGLTEXIMAGE3DPROC)(GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const void*); -GLAPI PFNGLTEXIMAGE3DPROC glad_glTexImage3D; -#define glTexImage3D glad_glTexImage3D -typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DPROC)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const void*); -GLAPI PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D; -#define glTexSubImage3D glad_glTexSubImage3D -typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DPROC)(GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); -GLAPI PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D; -#define glCopyTexSubImage3D glad_glCopyTexSubImage3D -#endif -#ifndef GL_VERSION_1_3 -#define GL_VERSION_1_3 1 -GLAPI int GLAD_GL_VERSION_1_3; -typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC)(GLenum); -GLAPI PFNGLACTIVETEXTUREPROC glad_glActiveTexture; -#define glActiveTexture glad_glActiveTexture -typedef void (APIENTRYP PFNGLSAMPLECOVERAGEPROC)(GLfloat, GLboolean); -GLAPI PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage; -#define glSampleCoverage glad_glSampleCoverage -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const void*); -GLAPI PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D; -#define glCompressedTexImage3D glad_glCompressedTexImage3D -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const void*); -GLAPI PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D; -#define glCompressedTexImage2D glad_glCompressedTexImage2D -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DPROC)(GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const void*); -GLAPI PFNGLCOMPRESSEDTEXIMAGE1DPROC glad_glCompressedTexImage1D; -#define glCompressedTexImage1D glad_glCompressedTexImage1D -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const void*); -GLAPI PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D; -#define glCompressedTexSubImage3D glad_glCompressedTexSubImage3D -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)(GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const void*); -GLAPI PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D; -#define glCompressedTexSubImage2D glad_glCompressedTexSubImage2D -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)(GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const void*); -GLAPI PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glad_glCompressedTexSubImage1D; -#define glCompressedTexSubImage1D glad_glCompressedTexSubImage1D -typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC)(GLenum, GLint, void*); -GLAPI PFNGLGETCOMPRESSEDTEXIMAGEPROC glad_glGetCompressedTexImage; -#define glGetCompressedTexImage glad_glGetCompressedTexImage -#endif -#ifndef GL_VERSION_1_4 -#define GL_VERSION_1_4 1 -GLAPI int GLAD_GL_VERSION_1_4; -typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC)(GLenum, GLenum, GLenum, GLenum); -GLAPI PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate; -#define glBlendFuncSeparate glad_glBlendFuncSeparate -typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSPROC)(GLenum, const GLint*, const GLsizei*, GLsizei); -GLAPI PFNGLMULTIDRAWARRAYSPROC glad_glMultiDrawArrays; -#define glMultiDrawArrays glad_glMultiDrawArrays -typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSPROC)(GLenum, const GLsizei*, GLenum, const void**, GLsizei); -GLAPI PFNGLMULTIDRAWELEMENTSPROC glad_glMultiDrawElements; -#define glMultiDrawElements glad_glMultiDrawElements -typedef void (APIENTRYP PFNGLPOINTPARAMETERFPROC)(GLenum, GLfloat); -GLAPI PFNGLPOINTPARAMETERFPROC glad_glPointParameterf; -#define glPointParameterf glad_glPointParameterf -typedef void (APIENTRYP PFNGLPOINTPARAMETERFVPROC)(GLenum, const GLfloat*); -GLAPI PFNGLPOINTPARAMETERFVPROC glad_glPointParameterfv; -#define glPointParameterfv glad_glPointParameterfv -typedef void (APIENTRYP PFNGLPOINTPARAMETERIPROC)(GLenum, GLint); -GLAPI PFNGLPOINTPARAMETERIPROC glad_glPointParameteri; -#define glPointParameteri glad_glPointParameteri -typedef void (APIENTRYP PFNGLPOINTPARAMETERIVPROC)(GLenum, const GLint*); -GLAPI PFNGLPOINTPARAMETERIVPROC glad_glPointParameteriv; -#define glPointParameteriv glad_glPointParameteriv -typedef void (APIENTRYP PFNGLBLENDCOLORPROC)(GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI PFNGLBLENDCOLORPROC glad_glBlendColor; -#define glBlendColor glad_glBlendColor -typedef void (APIENTRYP PFNGLBLENDEQUATIONPROC)(GLenum); -GLAPI PFNGLBLENDEQUATIONPROC glad_glBlendEquation; -#define glBlendEquation glad_glBlendEquation -#endif -#ifndef GL_VERSION_1_5 -#define GL_VERSION_1_5 1 -GLAPI int GLAD_GL_VERSION_1_5; -typedef void (APIENTRYP PFNGLGENQUERIESPROC)(GLsizei, GLuint*); -GLAPI PFNGLGENQUERIESPROC glad_glGenQueries; -#define glGenQueries glad_glGenQueries -typedef void (APIENTRYP PFNGLDELETEQUERIESPROC)(GLsizei, const GLuint*); -GLAPI PFNGLDELETEQUERIESPROC glad_glDeleteQueries; -#define glDeleteQueries glad_glDeleteQueries -typedef GLboolean (APIENTRYP PFNGLISQUERYPROC)(GLuint); -GLAPI PFNGLISQUERYPROC glad_glIsQuery; -#define glIsQuery glad_glIsQuery -typedef void (APIENTRYP PFNGLBEGINQUERYPROC)(GLenum, GLuint); -GLAPI PFNGLBEGINQUERYPROC glad_glBeginQuery; -#define glBeginQuery glad_glBeginQuery -typedef void (APIENTRYP PFNGLENDQUERYPROC)(GLenum); -GLAPI PFNGLENDQUERYPROC glad_glEndQuery; -#define glEndQuery glad_glEndQuery -typedef void (APIENTRYP PFNGLGETQUERYIVPROC)(GLenum, GLenum, GLint*); -GLAPI PFNGLGETQUERYIVPROC glad_glGetQueryiv; -#define glGetQueryiv glad_glGetQueryiv -typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVPROC)(GLuint, GLenum, GLint*); -GLAPI PFNGLGETQUERYOBJECTIVPROC glad_glGetQueryObjectiv; -#define glGetQueryObjectiv glad_glGetQueryObjectiv -typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVPROC)(GLuint, GLenum, GLuint*); -GLAPI PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv; -#define glGetQueryObjectuiv glad_glGetQueryObjectuiv -typedef void (APIENTRYP PFNGLBINDBUFFERPROC)(GLenum, GLuint); -GLAPI PFNGLBINDBUFFERPROC glad_glBindBuffer; -#define glBindBuffer glad_glBindBuffer -typedef void (APIENTRYP PFNGLDELETEBUFFERSPROC)(GLsizei, const GLuint*); -GLAPI PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers; -#define glDeleteBuffers glad_glDeleteBuffers -typedef void (APIENTRYP PFNGLGENBUFFERSPROC)(GLsizei, GLuint*); -GLAPI PFNGLGENBUFFERSPROC glad_glGenBuffers; -#define glGenBuffers glad_glGenBuffers -typedef GLboolean (APIENTRYP PFNGLISBUFFERPROC)(GLuint); -GLAPI PFNGLISBUFFERPROC glad_glIsBuffer; -#define glIsBuffer glad_glIsBuffer -typedef void (APIENTRYP PFNGLBUFFERDATAPROC)(GLenum, GLsizeiptr, const void*, GLenum); -GLAPI PFNGLBUFFERDATAPROC glad_glBufferData; -#define glBufferData glad_glBufferData -typedef void (APIENTRYP PFNGLBUFFERSUBDATAPROC)(GLenum, GLintptr, GLsizeiptr, const void*); -GLAPI PFNGLBUFFERSUBDATAPROC glad_glBufferSubData; -#define glBufferSubData glad_glBufferSubData -typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAPROC)(GLenum, GLintptr, GLsizeiptr, void*); -GLAPI PFNGLGETBUFFERSUBDATAPROC glad_glGetBufferSubData; -#define glGetBufferSubData glad_glGetBufferSubData -typedef void* (APIENTRYP PFNGLMAPBUFFERPROC)(GLenum, GLenum); -GLAPI PFNGLMAPBUFFERPROC glad_glMapBuffer; -#define glMapBuffer glad_glMapBuffer -typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERPROC)(GLenum); -GLAPI PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer; -#define glUnmapBuffer glad_glUnmapBuffer -typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC)(GLenum, GLenum, GLint*); -GLAPI PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv; -#define glGetBufferParameteriv glad_glGetBufferParameteriv -typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVPROC)(GLenum, GLenum, void**); -GLAPI PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv; -#define glGetBufferPointerv glad_glGetBufferPointerv -#endif -#ifndef GL_VERSION_2_0 -#define GL_VERSION_2_0 1 -GLAPI int GLAD_GL_VERSION_2_0; -typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC)(GLenum, GLenum); -GLAPI PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate; -#define glBlendEquationSeparate glad_glBlendEquationSeparate -typedef void (APIENTRYP PFNGLDRAWBUFFERSPROC)(GLsizei, const GLenum*); -GLAPI PFNGLDRAWBUFFERSPROC glad_glDrawBuffers; -#define glDrawBuffers glad_glDrawBuffers -typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEPROC)(GLenum, GLenum, GLenum, GLenum); -GLAPI PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate; -#define glStencilOpSeparate glad_glStencilOpSeparate -typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC)(GLenum, GLenum, GLint, GLuint); -GLAPI PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate; -#define glStencilFuncSeparate glad_glStencilFuncSeparate -typedef void (APIENTRYP PFNGLSTENCILMASKSEPARATEPROC)(GLenum, GLuint); -GLAPI PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate; -#define glStencilMaskSeparate glad_glStencilMaskSeparate -typedef void (APIENTRYP PFNGLATTACHSHADERPROC)(GLuint, GLuint); -GLAPI PFNGLATTACHSHADERPROC glad_glAttachShader; -#define glAttachShader glad_glAttachShader -typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONPROC)(GLuint, GLuint, const GLchar*); -GLAPI PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation; -#define glBindAttribLocation glad_glBindAttribLocation -typedef void (APIENTRYP PFNGLCOMPILESHADERPROC)(GLuint); -GLAPI PFNGLCOMPILESHADERPROC glad_glCompileShader; -#define glCompileShader glad_glCompileShader -typedef GLuint (APIENTRYP PFNGLCREATEPROGRAMPROC)(); -GLAPI PFNGLCREATEPROGRAMPROC glad_glCreateProgram; -#define glCreateProgram glad_glCreateProgram -typedef GLuint (APIENTRYP PFNGLCREATESHADERPROC)(GLenum); -GLAPI PFNGLCREATESHADERPROC glad_glCreateShader; -#define glCreateShader glad_glCreateShader -typedef void (APIENTRYP PFNGLDELETEPROGRAMPROC)(GLuint); -GLAPI PFNGLDELETEPROGRAMPROC glad_glDeleteProgram; -#define glDeleteProgram glad_glDeleteProgram -typedef void (APIENTRYP PFNGLDELETESHADERPROC)(GLuint); -GLAPI PFNGLDELETESHADERPROC glad_glDeleteShader; -#define glDeleteShader glad_glDeleteShader -typedef void (APIENTRYP PFNGLDETACHSHADERPROC)(GLuint, GLuint); -GLAPI PFNGLDETACHSHADERPROC glad_glDetachShader; -#define glDetachShader glad_glDetachShader -typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC)(GLuint); -GLAPI PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray; -#define glDisableVertexAttribArray glad_glDisableVertexAttribArray -typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC)(GLuint); -GLAPI PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray; -#define glEnableVertexAttribArray glad_glEnableVertexAttribArray -typedef void (APIENTRYP PFNGLGETACTIVEATTRIBPROC)(GLuint, GLuint, GLsizei, GLsizei*, GLint*, GLenum*, GLchar*); -GLAPI PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib; -#define glGetActiveAttrib glad_glGetActiveAttrib -typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMPROC)(GLuint, GLuint, GLsizei, GLsizei*, GLint*, GLenum*, GLchar*); -GLAPI PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform; -#define glGetActiveUniform glad_glGetActiveUniform -typedef void (APIENTRYP PFNGLGETATTACHEDSHADERSPROC)(GLuint, GLsizei, GLsizei*, GLuint*); -GLAPI PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders; -#define glGetAttachedShaders glad_glGetAttachedShaders -typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONPROC)(GLuint, const GLchar*); -GLAPI PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation; -#define glGetAttribLocation glad_glGetAttribLocation -typedef void (APIENTRYP PFNGLGETPROGRAMIVPROC)(GLuint, GLenum, GLint*); -GLAPI PFNGLGETPROGRAMIVPROC glad_glGetProgramiv; -#define glGetProgramiv glad_glGetProgramiv -typedef void (APIENTRYP PFNGLGETPROGRAMINFOLOGPROC)(GLuint, GLsizei, GLsizei*, GLchar*); -GLAPI PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog; -#define glGetProgramInfoLog glad_glGetProgramInfoLog -typedef void (APIENTRYP PFNGLGETSHADERIVPROC)(GLuint, GLenum, GLint*); -GLAPI PFNGLGETSHADERIVPROC glad_glGetShaderiv; -#define glGetShaderiv glad_glGetShaderiv -typedef void (APIENTRYP PFNGLGETSHADERINFOLOGPROC)(GLuint, GLsizei, GLsizei*, GLchar*); -GLAPI PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog; -#define glGetShaderInfoLog glad_glGetShaderInfoLog -typedef void (APIENTRYP PFNGLGETSHADERSOURCEPROC)(GLuint, GLsizei, GLsizei*, GLchar*); -GLAPI PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource; -#define glGetShaderSource glad_glGetShaderSource -typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONPROC)(GLuint, const GLchar*); -GLAPI PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation; -#define glGetUniformLocation glad_glGetUniformLocation -typedef void (APIENTRYP PFNGLGETUNIFORMFVPROC)(GLuint, GLint, GLfloat*); -GLAPI PFNGLGETUNIFORMFVPROC glad_glGetUniformfv; -#define glGetUniformfv glad_glGetUniformfv -typedef void (APIENTRYP PFNGLGETUNIFORMIVPROC)(GLuint, GLint, GLint*); -GLAPI PFNGLGETUNIFORMIVPROC glad_glGetUniformiv; -#define glGetUniformiv glad_glGetUniformiv -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVPROC)(GLuint, GLenum, GLdouble*); -GLAPI PFNGLGETVERTEXATTRIBDVPROC glad_glGetVertexAttribdv; -#define glGetVertexAttribdv glad_glGetVertexAttribdv -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVPROC)(GLuint, GLenum, GLfloat*); -GLAPI PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv; -#define glGetVertexAttribfv glad_glGetVertexAttribfv -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVPROC)(GLuint, GLenum, GLint*); -GLAPI PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv; -#define glGetVertexAttribiv glad_glGetVertexAttribiv -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC)(GLuint, GLenum, void**); -GLAPI PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv; -#define glGetVertexAttribPointerv glad_glGetVertexAttribPointerv -typedef GLboolean (APIENTRYP PFNGLISPROGRAMPROC)(GLuint); -GLAPI PFNGLISPROGRAMPROC glad_glIsProgram; -#define glIsProgram glad_glIsProgram -typedef GLboolean (APIENTRYP PFNGLISSHADERPROC)(GLuint); -GLAPI PFNGLISSHADERPROC glad_glIsShader; -#define glIsShader glad_glIsShader -typedef void (APIENTRYP PFNGLLINKPROGRAMPROC)(GLuint); -GLAPI PFNGLLINKPROGRAMPROC glad_glLinkProgram; -#define glLinkProgram glad_glLinkProgram -typedef void (APIENTRYP PFNGLSHADERSOURCEPROC)(GLuint, GLsizei, const GLchar**, const GLint*); -GLAPI PFNGLSHADERSOURCEPROC glad_glShaderSource; -#define glShaderSource glad_glShaderSource -typedef void (APIENTRYP PFNGLUSEPROGRAMPROC)(GLuint); -GLAPI PFNGLUSEPROGRAMPROC glad_glUseProgram; -#define glUseProgram glad_glUseProgram -typedef void (APIENTRYP PFNGLUNIFORM1FPROC)(GLint, GLfloat); -GLAPI PFNGLUNIFORM1FPROC glad_glUniform1f; -#define glUniform1f glad_glUniform1f -typedef void (APIENTRYP PFNGLUNIFORM2FPROC)(GLint, GLfloat, GLfloat); -GLAPI PFNGLUNIFORM2FPROC glad_glUniform2f; -#define glUniform2f glad_glUniform2f -typedef void (APIENTRYP PFNGLUNIFORM3FPROC)(GLint, GLfloat, GLfloat, GLfloat); -GLAPI PFNGLUNIFORM3FPROC glad_glUniform3f; -#define glUniform3f glad_glUniform3f -typedef void (APIENTRYP PFNGLUNIFORM4FPROC)(GLint, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI PFNGLUNIFORM4FPROC glad_glUniform4f; -#define glUniform4f glad_glUniform4f -typedef void (APIENTRYP PFNGLUNIFORM1IPROC)(GLint, GLint); -GLAPI PFNGLUNIFORM1IPROC glad_glUniform1i; -#define glUniform1i glad_glUniform1i -typedef void (APIENTRYP PFNGLUNIFORM2IPROC)(GLint, GLint, GLint); -GLAPI PFNGLUNIFORM2IPROC glad_glUniform2i; -#define glUniform2i glad_glUniform2i -typedef void (APIENTRYP PFNGLUNIFORM3IPROC)(GLint, GLint, GLint, GLint); -GLAPI PFNGLUNIFORM3IPROC glad_glUniform3i; -#define glUniform3i glad_glUniform3i -typedef void (APIENTRYP PFNGLUNIFORM4IPROC)(GLint, GLint, GLint, GLint, GLint); -GLAPI PFNGLUNIFORM4IPROC glad_glUniform4i; -#define glUniform4i glad_glUniform4i -typedef void (APIENTRYP PFNGLUNIFORM1FVPROC)(GLint, GLsizei, const GLfloat*); -GLAPI PFNGLUNIFORM1FVPROC glad_glUniform1fv; -#define glUniform1fv glad_glUniform1fv -typedef void (APIENTRYP PFNGLUNIFORM2FVPROC)(GLint, GLsizei, const GLfloat*); -GLAPI PFNGLUNIFORM2FVPROC glad_glUniform2fv; -#define glUniform2fv glad_glUniform2fv -typedef void (APIENTRYP PFNGLUNIFORM3FVPROC)(GLint, GLsizei, const GLfloat*); -GLAPI PFNGLUNIFORM3FVPROC glad_glUniform3fv; -#define glUniform3fv glad_glUniform3fv -typedef void (APIENTRYP PFNGLUNIFORM4FVPROC)(GLint, GLsizei, const GLfloat*); -GLAPI PFNGLUNIFORM4FVPROC glad_glUniform4fv; -#define glUniform4fv glad_glUniform4fv -typedef void (APIENTRYP PFNGLUNIFORM1IVPROC)(GLint, GLsizei, const GLint*); -GLAPI PFNGLUNIFORM1IVPROC glad_glUniform1iv; -#define glUniform1iv glad_glUniform1iv -typedef void (APIENTRYP PFNGLUNIFORM2IVPROC)(GLint, GLsizei, const GLint*); -GLAPI PFNGLUNIFORM2IVPROC glad_glUniform2iv; -#define glUniform2iv glad_glUniform2iv -typedef void (APIENTRYP PFNGLUNIFORM3IVPROC)(GLint, GLsizei, const GLint*); -GLAPI PFNGLUNIFORM3IVPROC glad_glUniform3iv; -#define glUniform3iv glad_glUniform3iv -typedef void (APIENTRYP PFNGLUNIFORM4IVPROC)(GLint, GLsizei, const GLint*); -GLAPI PFNGLUNIFORM4IVPROC glad_glUniform4iv; -#define glUniform4iv glad_glUniform4iv -typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVPROC)(GLint, GLsizei, GLboolean, const GLfloat*); -GLAPI PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv; -#define glUniformMatrix2fv glad_glUniformMatrix2fv -typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVPROC)(GLint, GLsizei, GLboolean, const GLfloat*); -GLAPI PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv; -#define glUniformMatrix3fv glad_glUniformMatrix3fv -typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVPROC)(GLint, GLsizei, GLboolean, const GLfloat*); -GLAPI PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv; -#define glUniformMatrix4fv glad_glUniformMatrix4fv -typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPROC)(GLuint); -GLAPI PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram; -#define glValidateProgram glad_glValidateProgram -typedef void (APIENTRYP PFNGLVERTEXATTRIB1DPROC)(GLuint, GLdouble); -GLAPI PFNGLVERTEXATTRIB1DPROC glad_glVertexAttrib1d; -#define glVertexAttrib1d glad_glVertexAttrib1d -typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVPROC)(GLuint, const GLdouble*); -GLAPI PFNGLVERTEXATTRIB1DVPROC glad_glVertexAttrib1dv; -#define glVertexAttrib1dv glad_glVertexAttrib1dv -typedef void (APIENTRYP PFNGLVERTEXATTRIB1FPROC)(GLuint, GLfloat); -GLAPI PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f; -#define glVertexAttrib1f glad_glVertexAttrib1f -typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVPROC)(GLuint, const GLfloat*); -GLAPI PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv; -#define glVertexAttrib1fv glad_glVertexAttrib1fv -typedef void (APIENTRYP PFNGLVERTEXATTRIB1SPROC)(GLuint, GLshort); -GLAPI PFNGLVERTEXATTRIB1SPROC glad_glVertexAttrib1s; -#define glVertexAttrib1s glad_glVertexAttrib1s -typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVPROC)(GLuint, const GLshort*); -GLAPI PFNGLVERTEXATTRIB1SVPROC glad_glVertexAttrib1sv; -#define glVertexAttrib1sv glad_glVertexAttrib1sv -typedef void (APIENTRYP PFNGLVERTEXATTRIB2DPROC)(GLuint, GLdouble, GLdouble); -GLAPI PFNGLVERTEXATTRIB2DPROC glad_glVertexAttrib2d; -#define glVertexAttrib2d glad_glVertexAttrib2d -typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVPROC)(GLuint, const GLdouble*); -GLAPI PFNGLVERTEXATTRIB2DVPROC glad_glVertexAttrib2dv; -#define glVertexAttrib2dv glad_glVertexAttrib2dv -typedef void (APIENTRYP PFNGLVERTEXATTRIB2FPROC)(GLuint, GLfloat, GLfloat); -GLAPI PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f; -#define glVertexAttrib2f glad_glVertexAttrib2f -typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVPROC)(GLuint, const GLfloat*); -GLAPI PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv; -#define glVertexAttrib2fv glad_glVertexAttrib2fv -typedef void (APIENTRYP PFNGLVERTEXATTRIB2SPROC)(GLuint, GLshort, GLshort); -GLAPI PFNGLVERTEXATTRIB2SPROC glad_glVertexAttrib2s; -#define glVertexAttrib2s glad_glVertexAttrib2s -typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVPROC)(GLuint, const GLshort*); -GLAPI PFNGLVERTEXATTRIB2SVPROC glad_glVertexAttrib2sv; -#define glVertexAttrib2sv glad_glVertexAttrib2sv -typedef void (APIENTRYP PFNGLVERTEXATTRIB3DPROC)(GLuint, GLdouble, GLdouble, GLdouble); -GLAPI PFNGLVERTEXATTRIB3DPROC glad_glVertexAttrib3d; -#define glVertexAttrib3d glad_glVertexAttrib3d -typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVPROC)(GLuint, const GLdouble*); -GLAPI PFNGLVERTEXATTRIB3DVPROC glad_glVertexAttrib3dv; -#define glVertexAttrib3dv glad_glVertexAttrib3dv -typedef void (APIENTRYP PFNGLVERTEXATTRIB3FPROC)(GLuint, GLfloat, GLfloat, GLfloat); -GLAPI PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f; -#define glVertexAttrib3f glad_glVertexAttrib3f -typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVPROC)(GLuint, const GLfloat*); -GLAPI PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv; -#define glVertexAttrib3fv glad_glVertexAttrib3fv -typedef void (APIENTRYP PFNGLVERTEXATTRIB3SPROC)(GLuint, GLshort, GLshort, GLshort); -GLAPI PFNGLVERTEXATTRIB3SPROC glad_glVertexAttrib3s; -#define glVertexAttrib3s glad_glVertexAttrib3s -typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVPROC)(GLuint, const GLshort*); -GLAPI PFNGLVERTEXATTRIB3SVPROC glad_glVertexAttrib3sv; -#define glVertexAttrib3sv glad_glVertexAttrib3sv -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVPROC)(GLuint, const GLbyte*); -GLAPI PFNGLVERTEXATTRIB4NBVPROC glad_glVertexAttrib4Nbv; -#define glVertexAttrib4Nbv glad_glVertexAttrib4Nbv -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVPROC)(GLuint, const GLint*); -GLAPI PFNGLVERTEXATTRIB4NIVPROC glad_glVertexAttrib4Niv; -#define glVertexAttrib4Niv glad_glVertexAttrib4Niv -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVPROC)(GLuint, const GLshort*); -GLAPI PFNGLVERTEXATTRIB4NSVPROC glad_glVertexAttrib4Nsv; -#define glVertexAttrib4Nsv glad_glVertexAttrib4Nsv -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBPROC)(GLuint, GLubyte, GLubyte, GLubyte, GLubyte); -GLAPI PFNGLVERTEXATTRIB4NUBPROC glad_glVertexAttrib4Nub; -#define glVertexAttrib4Nub glad_glVertexAttrib4Nub -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVPROC)(GLuint, const GLubyte*); -GLAPI PFNGLVERTEXATTRIB4NUBVPROC glad_glVertexAttrib4Nubv; -#define glVertexAttrib4Nubv glad_glVertexAttrib4Nubv -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVPROC)(GLuint, const GLuint*); -GLAPI PFNGLVERTEXATTRIB4NUIVPROC glad_glVertexAttrib4Nuiv; -#define glVertexAttrib4Nuiv glad_glVertexAttrib4Nuiv -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVPROC)(GLuint, const GLushort*); -GLAPI PFNGLVERTEXATTRIB4NUSVPROC glad_glVertexAttrib4Nusv; -#define glVertexAttrib4Nusv glad_glVertexAttrib4Nusv -typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVPROC)(GLuint, const GLbyte*); -GLAPI PFNGLVERTEXATTRIB4BVPROC glad_glVertexAttrib4bv; -#define glVertexAttrib4bv glad_glVertexAttrib4bv -typedef void (APIENTRYP PFNGLVERTEXATTRIB4DPROC)(GLuint, GLdouble, GLdouble, GLdouble, GLdouble); -GLAPI PFNGLVERTEXATTRIB4DPROC glad_glVertexAttrib4d; -#define glVertexAttrib4d glad_glVertexAttrib4d -typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVPROC)(GLuint, const GLdouble*); -GLAPI PFNGLVERTEXATTRIB4DVPROC glad_glVertexAttrib4dv; -#define glVertexAttrib4dv glad_glVertexAttrib4dv -typedef void (APIENTRYP PFNGLVERTEXATTRIB4FPROC)(GLuint, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f; -#define glVertexAttrib4f glad_glVertexAttrib4f -typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVPROC)(GLuint, const GLfloat*); -GLAPI PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv; -#define glVertexAttrib4fv glad_glVertexAttrib4fv -typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVPROC)(GLuint, const GLint*); -GLAPI PFNGLVERTEXATTRIB4IVPROC glad_glVertexAttrib4iv; -#define glVertexAttrib4iv glad_glVertexAttrib4iv -typedef void (APIENTRYP PFNGLVERTEXATTRIB4SPROC)(GLuint, GLshort, GLshort, GLshort, GLshort); -GLAPI PFNGLVERTEXATTRIB4SPROC glad_glVertexAttrib4s; -#define glVertexAttrib4s glad_glVertexAttrib4s -typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVPROC)(GLuint, const GLshort*); -GLAPI PFNGLVERTEXATTRIB4SVPROC glad_glVertexAttrib4sv; -#define glVertexAttrib4sv glad_glVertexAttrib4sv -typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVPROC)(GLuint, const GLubyte*); -GLAPI PFNGLVERTEXATTRIB4UBVPROC glad_glVertexAttrib4ubv; -#define glVertexAttrib4ubv glad_glVertexAttrib4ubv -typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVPROC)(GLuint, const GLuint*); -GLAPI PFNGLVERTEXATTRIB4UIVPROC glad_glVertexAttrib4uiv; -#define glVertexAttrib4uiv glad_glVertexAttrib4uiv -typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVPROC)(GLuint, const GLushort*); -GLAPI PFNGLVERTEXATTRIB4USVPROC glad_glVertexAttrib4usv; -#define glVertexAttrib4usv glad_glVertexAttrib4usv -typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC)(GLuint, GLint, GLenum, GLboolean, GLsizei, const void*); -GLAPI PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer; -#define glVertexAttribPointer glad_glVertexAttribPointer -#endif -#ifndef GL_VERSION_2_1 -#define GL_VERSION_2_1 1 -GLAPI int GLAD_GL_VERSION_2_1; -typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3FVPROC)(GLint, GLsizei, GLboolean, const GLfloat*); -GLAPI PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv; -#define glUniformMatrix2x3fv glad_glUniformMatrix2x3fv -typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2FVPROC)(GLint, GLsizei, GLboolean, const GLfloat*); -GLAPI PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv; -#define glUniformMatrix3x2fv glad_glUniformMatrix3x2fv -typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4FVPROC)(GLint, GLsizei, GLboolean, const GLfloat*); -GLAPI PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv; -#define glUniformMatrix2x4fv glad_glUniformMatrix2x4fv -typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2FVPROC)(GLint, GLsizei, GLboolean, const GLfloat*); -GLAPI PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv; -#define glUniformMatrix4x2fv glad_glUniformMatrix4x2fv -typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4FVPROC)(GLint, GLsizei, GLboolean, const GLfloat*); -GLAPI PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv; -#define glUniformMatrix3x4fv glad_glUniformMatrix3x4fv -typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3FVPROC)(GLint, GLsizei, GLboolean, const GLfloat*); -GLAPI PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv; -#define glUniformMatrix4x3fv glad_glUniformMatrix4x3fv -#endif -#ifndef GL_VERSION_3_0 -#define GL_VERSION_3_0 1 -GLAPI int GLAD_GL_VERSION_3_0; -typedef void (APIENTRYP PFNGLCOLORMASKIPROC)(GLuint, GLboolean, GLboolean, GLboolean, GLboolean); -GLAPI PFNGLCOLORMASKIPROC glad_glColorMaski; -#define glColorMaski glad_glColorMaski -typedef void (APIENTRYP PFNGLGETBOOLEANI_VPROC)(GLenum, GLuint, GLboolean*); -GLAPI PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v; -#define glGetBooleani_v glad_glGetBooleani_v -typedef void (APIENTRYP PFNGLGETINTEGERI_VPROC)(GLenum, GLuint, GLint*); -GLAPI PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v; -#define glGetIntegeri_v glad_glGetIntegeri_v -typedef void (APIENTRYP PFNGLENABLEIPROC)(GLenum, GLuint); -GLAPI PFNGLENABLEIPROC glad_glEnablei; -#define glEnablei glad_glEnablei -typedef void (APIENTRYP PFNGLDISABLEIPROC)(GLenum, GLuint); -GLAPI PFNGLDISABLEIPROC glad_glDisablei; -#define glDisablei glad_glDisablei -typedef GLboolean (APIENTRYP PFNGLISENABLEDIPROC)(GLenum, GLuint); -GLAPI PFNGLISENABLEDIPROC glad_glIsEnabledi; -#define glIsEnabledi glad_glIsEnabledi -typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKPROC)(GLenum); -GLAPI PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback; -#define glBeginTransformFeedback glad_glBeginTransformFeedback -typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKPROC)(); -GLAPI PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback; -#define glEndTransformFeedback glad_glEndTransformFeedback -typedef void (APIENTRYP PFNGLBINDBUFFERRANGEPROC)(GLenum, GLuint, GLuint, GLintptr, GLsizeiptr); -GLAPI PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange; -#define glBindBufferRange glad_glBindBufferRange -typedef void (APIENTRYP PFNGLBINDBUFFERBASEPROC)(GLenum, GLuint, GLuint); -GLAPI PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase; -#define glBindBufferBase glad_glBindBufferBase -typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSPROC)(GLuint, GLsizei, const GLchar**, GLenum); -GLAPI PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings; -#define glTransformFeedbackVaryings glad_glTransformFeedbackVaryings -typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGPROC)(GLuint, GLuint, GLsizei, GLsizei*, GLsizei*, GLenum*, GLchar*); -GLAPI PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying; -#define glGetTransformFeedbackVarying glad_glGetTransformFeedbackVarying -typedef void (APIENTRYP PFNGLCLAMPCOLORPROC)(GLenum, GLenum); -GLAPI PFNGLCLAMPCOLORPROC glad_glClampColor; -#define glClampColor glad_glClampColor -typedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERPROC)(GLuint, GLenum); -GLAPI PFNGLBEGINCONDITIONALRENDERPROC glad_glBeginConditionalRender; -#define glBeginConditionalRender glad_glBeginConditionalRender -typedef void (APIENTRYP PFNGLENDCONDITIONALRENDERPROC)(); -GLAPI PFNGLENDCONDITIONALRENDERPROC glad_glEndConditionalRender; -#define glEndConditionalRender glad_glEndConditionalRender -typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTERPROC)(GLuint, GLint, GLenum, GLsizei, const void*); -GLAPI PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer; -#define glVertexAttribIPointer glad_glVertexAttribIPointer -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVPROC)(GLuint, GLenum, GLint*); -GLAPI PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv; -#define glGetVertexAttribIiv glad_glGetVertexAttribIiv -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVPROC)(GLuint, GLenum, GLuint*); -GLAPI PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv; -#define glGetVertexAttribIuiv glad_glGetVertexAttribIuiv -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IPROC)(GLuint, GLint); -GLAPI PFNGLVERTEXATTRIBI1IPROC glad_glVertexAttribI1i; -#define glVertexAttribI1i glad_glVertexAttribI1i -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IPROC)(GLuint, GLint, GLint); -GLAPI PFNGLVERTEXATTRIBI2IPROC glad_glVertexAttribI2i; -#define glVertexAttribI2i glad_glVertexAttribI2i -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IPROC)(GLuint, GLint, GLint, GLint); -GLAPI PFNGLVERTEXATTRIBI3IPROC glad_glVertexAttribI3i; -#define glVertexAttribI3i glad_glVertexAttribI3i -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IPROC)(GLuint, GLint, GLint, GLint, GLint); -GLAPI PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i; -#define glVertexAttribI4i glad_glVertexAttribI4i -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIPROC)(GLuint, GLuint); -GLAPI PFNGLVERTEXATTRIBI1UIPROC glad_glVertexAttribI1ui; -#define glVertexAttribI1ui glad_glVertexAttribI1ui -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIPROC)(GLuint, GLuint, GLuint); -GLAPI PFNGLVERTEXATTRIBI2UIPROC glad_glVertexAttribI2ui; -#define glVertexAttribI2ui glad_glVertexAttribI2ui -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIPROC)(GLuint, GLuint, GLuint, GLuint); -GLAPI PFNGLVERTEXATTRIBI3UIPROC glad_glVertexAttribI3ui; -#define glVertexAttribI3ui glad_glVertexAttribI3ui -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIPROC)(GLuint, GLuint, GLuint, GLuint, GLuint); -GLAPI PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui; -#define glVertexAttribI4ui glad_glVertexAttribI4ui -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IVPROC)(GLuint, const GLint*); -GLAPI PFNGLVERTEXATTRIBI1IVPROC glad_glVertexAttribI1iv; -#define glVertexAttribI1iv glad_glVertexAttribI1iv -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IVPROC)(GLuint, const GLint*); -GLAPI PFNGLVERTEXATTRIBI2IVPROC glad_glVertexAttribI2iv; -#define glVertexAttribI2iv glad_glVertexAttribI2iv -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IVPROC)(GLuint, const GLint*); -GLAPI PFNGLVERTEXATTRIBI3IVPROC glad_glVertexAttribI3iv; -#define glVertexAttribI3iv glad_glVertexAttribI3iv -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IVPROC)(GLuint, const GLint*); -GLAPI PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv; -#define glVertexAttribI4iv glad_glVertexAttribI4iv -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIVPROC)(GLuint, const GLuint*); -GLAPI PFNGLVERTEXATTRIBI1UIVPROC glad_glVertexAttribI1uiv; -#define glVertexAttribI1uiv glad_glVertexAttribI1uiv -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIVPROC)(GLuint, const GLuint*); -GLAPI PFNGLVERTEXATTRIBI2UIVPROC glad_glVertexAttribI2uiv; -#define glVertexAttribI2uiv glad_glVertexAttribI2uiv -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIVPROC)(GLuint, const GLuint*); -GLAPI PFNGLVERTEXATTRIBI3UIVPROC glad_glVertexAttribI3uiv; -#define glVertexAttribI3uiv glad_glVertexAttribI3uiv -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIVPROC)(GLuint, const GLuint*); -GLAPI PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv; -#define glVertexAttribI4uiv glad_glVertexAttribI4uiv -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4BVPROC)(GLuint, const GLbyte*); -GLAPI PFNGLVERTEXATTRIBI4BVPROC glad_glVertexAttribI4bv; -#define glVertexAttribI4bv glad_glVertexAttribI4bv -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4SVPROC)(GLuint, const GLshort*); -GLAPI PFNGLVERTEXATTRIBI4SVPROC glad_glVertexAttribI4sv; -#define glVertexAttribI4sv glad_glVertexAttribI4sv -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UBVPROC)(GLuint, const GLubyte*); -GLAPI PFNGLVERTEXATTRIBI4UBVPROC glad_glVertexAttribI4ubv; -#define glVertexAttribI4ubv glad_glVertexAttribI4ubv -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4USVPROC)(GLuint, const GLushort*); -GLAPI PFNGLVERTEXATTRIBI4USVPROC glad_glVertexAttribI4usv; -#define glVertexAttribI4usv glad_glVertexAttribI4usv -typedef void (APIENTRYP PFNGLGETUNIFORMUIVPROC)(GLuint, GLint, GLuint*); -GLAPI PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv; -#define glGetUniformuiv glad_glGetUniformuiv -typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONPROC)(GLuint, GLuint, const GLchar*); -GLAPI PFNGLBINDFRAGDATALOCATIONPROC glad_glBindFragDataLocation; -#define glBindFragDataLocation glad_glBindFragDataLocation -typedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONPROC)(GLuint, const GLchar*); -GLAPI PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation; -#define glGetFragDataLocation glad_glGetFragDataLocation -typedef void (APIENTRYP PFNGLUNIFORM1UIPROC)(GLint, GLuint); -GLAPI PFNGLUNIFORM1UIPROC glad_glUniform1ui; -#define glUniform1ui glad_glUniform1ui -typedef void (APIENTRYP PFNGLUNIFORM2UIPROC)(GLint, GLuint, GLuint); -GLAPI PFNGLUNIFORM2UIPROC glad_glUniform2ui; -#define glUniform2ui glad_glUniform2ui -typedef void (APIENTRYP PFNGLUNIFORM3UIPROC)(GLint, GLuint, GLuint, GLuint); -GLAPI PFNGLUNIFORM3UIPROC glad_glUniform3ui; -#define glUniform3ui glad_glUniform3ui -typedef void (APIENTRYP PFNGLUNIFORM4UIPROC)(GLint, GLuint, GLuint, GLuint, GLuint); -GLAPI PFNGLUNIFORM4UIPROC glad_glUniform4ui; -#define glUniform4ui glad_glUniform4ui -typedef void (APIENTRYP PFNGLUNIFORM1UIVPROC)(GLint, GLsizei, const GLuint*); -GLAPI PFNGLUNIFORM1UIVPROC glad_glUniform1uiv; -#define glUniform1uiv glad_glUniform1uiv -typedef void (APIENTRYP PFNGLUNIFORM2UIVPROC)(GLint, GLsizei, const GLuint*); -GLAPI PFNGLUNIFORM2UIVPROC glad_glUniform2uiv; -#define glUniform2uiv glad_glUniform2uiv -typedef void (APIENTRYP PFNGLUNIFORM3UIVPROC)(GLint, GLsizei, const GLuint*); -GLAPI PFNGLUNIFORM3UIVPROC glad_glUniform3uiv; -#define glUniform3uiv glad_glUniform3uiv -typedef void (APIENTRYP PFNGLUNIFORM4UIVPROC)(GLint, GLsizei, const GLuint*); -GLAPI PFNGLUNIFORM4UIVPROC glad_glUniform4uiv; -#define glUniform4uiv glad_glUniform4uiv -typedef void (APIENTRYP PFNGLTEXPARAMETERIIVPROC)(GLenum, GLenum, const GLint*); -GLAPI PFNGLTEXPARAMETERIIVPROC glad_glTexParameterIiv; -#define glTexParameterIiv glad_glTexParameterIiv -typedef void (APIENTRYP PFNGLTEXPARAMETERIUIVPROC)(GLenum, GLenum, const GLuint*); -GLAPI PFNGLTEXPARAMETERIUIVPROC glad_glTexParameterIuiv; -#define glTexParameterIuiv glad_glTexParameterIuiv -typedef void (APIENTRYP PFNGLGETTEXPARAMETERIIVPROC)(GLenum, GLenum, GLint*); -GLAPI PFNGLGETTEXPARAMETERIIVPROC glad_glGetTexParameterIiv; -#define glGetTexParameterIiv glad_glGetTexParameterIiv -typedef void (APIENTRYP PFNGLGETTEXPARAMETERIUIVPROC)(GLenum, GLenum, GLuint*); -GLAPI PFNGLGETTEXPARAMETERIUIVPROC glad_glGetTexParameterIuiv; -#define glGetTexParameterIuiv glad_glGetTexParameterIuiv -typedef void (APIENTRYP PFNGLCLEARBUFFERIVPROC)(GLenum, GLint, const GLint*); -GLAPI PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv; -#define glClearBufferiv glad_glClearBufferiv -typedef void (APIENTRYP PFNGLCLEARBUFFERUIVPROC)(GLenum, GLint, const GLuint*); -GLAPI PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv; -#define glClearBufferuiv glad_glClearBufferuiv -typedef void (APIENTRYP PFNGLCLEARBUFFERFVPROC)(GLenum, GLint, const GLfloat*); -GLAPI PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv; -#define glClearBufferfv glad_glClearBufferfv -typedef void (APIENTRYP PFNGLCLEARBUFFERFIPROC)(GLenum, GLint, GLfloat, GLint); -GLAPI PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi; -#define glClearBufferfi glad_glClearBufferfi -typedef const GLubyte* (APIENTRYP PFNGLGETSTRINGIPROC)(GLenum, GLuint); -GLAPI PFNGLGETSTRINGIPROC glad_glGetStringi; -#define glGetStringi glad_glGetStringi -typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFERPROC)(GLuint); -GLAPI PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer; -#define glIsRenderbuffer glad_glIsRenderbuffer -typedef void (APIENTRYP PFNGLBINDRENDERBUFFERPROC)(GLenum, GLuint); -GLAPI PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer; -#define glBindRenderbuffer glad_glBindRenderbuffer -typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSPROC)(GLsizei, const GLuint*); -GLAPI PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers; -#define glDeleteRenderbuffers glad_glDeleteRenderbuffers -typedef void (APIENTRYP PFNGLGENRENDERBUFFERSPROC)(GLsizei, GLuint*); -GLAPI PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers; -#define glGenRenderbuffers glad_glGenRenderbuffers -typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEPROC)(GLenum, GLenum, GLsizei, GLsizei); -GLAPI PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage; -#define glRenderbufferStorage glad_glRenderbufferStorage -typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVPROC)(GLenum, GLenum, GLint*); -GLAPI PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv; -#define glGetRenderbufferParameteriv glad_glGetRenderbufferParameteriv -typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFERPROC)(GLuint); -GLAPI PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer; -#define glIsFramebuffer glad_glIsFramebuffer -typedef void (APIENTRYP PFNGLBINDFRAMEBUFFERPROC)(GLenum, GLuint); -GLAPI PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer; -#define glBindFramebuffer glad_glBindFramebuffer -typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSPROC)(GLsizei, const GLuint*); -GLAPI PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers; -#define glDeleteFramebuffers glad_glDeleteFramebuffers -typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSPROC)(GLsizei, GLuint*); -GLAPI PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers; -#define glGenFramebuffers glad_glGenFramebuffers -typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSPROC)(GLenum); -GLAPI PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus; -#define glCheckFramebufferStatus glad_glCheckFramebufferStatus -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DPROC)(GLenum, GLenum, GLenum, GLuint, GLint); -GLAPI PFNGLFRAMEBUFFERTEXTURE1DPROC glad_glFramebufferTexture1D; -#define glFramebufferTexture1D glad_glFramebufferTexture1D -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DPROC)(GLenum, GLenum, GLenum, GLuint, GLint); -GLAPI PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D; -#define glFramebufferTexture2D glad_glFramebufferTexture2D -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DPROC)(GLenum, GLenum, GLenum, GLuint, GLint, GLint); -GLAPI PFNGLFRAMEBUFFERTEXTURE3DPROC glad_glFramebufferTexture3D; -#define glFramebufferTexture3D glad_glFramebufferTexture3D -typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFERPROC)(GLenum, GLenum, GLenum, GLuint); -GLAPI PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer; -#define glFramebufferRenderbuffer glad_glFramebufferRenderbuffer -typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)(GLenum, GLenum, GLenum, GLint*); -GLAPI PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv; -#define glGetFramebufferAttachmentParameteriv glad_glGetFramebufferAttachmentParameteriv -typedef void (APIENTRYP PFNGLGENERATEMIPMAPPROC)(GLenum); -GLAPI PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap; -#define glGenerateMipmap glad_glGenerateMipmap -typedef void (APIENTRYP PFNGLBLITFRAMEBUFFERPROC)(GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum); -GLAPI PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer; -#define glBlitFramebuffer glad_glBlitFramebuffer -typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)(GLenum, GLsizei, GLenum, GLsizei, GLsizei); -GLAPI PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample; -#define glRenderbufferStorageMultisample glad_glRenderbufferStorageMultisample -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERPROC)(GLenum, GLenum, GLuint, GLint, GLint); -GLAPI PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer; -#define glFramebufferTextureLayer glad_glFramebufferTextureLayer -typedef void* (APIENTRYP PFNGLMAPBUFFERRANGEPROC)(GLenum, GLintptr, GLsizeiptr, GLbitfield); -GLAPI PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange; -#define glMapBufferRange glad_glMapBufferRange -typedef void (APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEPROC)(GLenum, GLintptr, GLsizeiptr); -GLAPI PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange; -#define glFlushMappedBufferRange glad_glFlushMappedBufferRange -typedef void (APIENTRYP PFNGLBINDVERTEXARRAYPROC)(GLuint); -GLAPI PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray; -#define glBindVertexArray glad_glBindVertexArray -typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSPROC)(GLsizei, const GLuint*); -GLAPI PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays; -#define glDeleteVertexArrays glad_glDeleteVertexArrays -typedef void (APIENTRYP PFNGLGENVERTEXARRAYSPROC)(GLsizei, GLuint*); -GLAPI PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays; -#define glGenVertexArrays glad_glGenVertexArrays -typedef GLboolean (APIENTRYP PFNGLISVERTEXARRAYPROC)(GLuint); -GLAPI PFNGLISVERTEXARRAYPROC glad_glIsVertexArray; -#define glIsVertexArray glad_glIsVertexArray -#endif -#ifndef GL_VERSION_3_1 -#define GL_VERSION_3_1 1 -GLAPI int GLAD_GL_VERSION_3_1; -typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDPROC)(GLenum, GLint, GLsizei, GLsizei); -GLAPI PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced; -#define glDrawArraysInstanced glad_glDrawArraysInstanced -typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDPROC)(GLenum, GLsizei, GLenum, const void*, GLsizei); -GLAPI PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced; -#define glDrawElementsInstanced glad_glDrawElementsInstanced -typedef void (APIENTRYP PFNGLTEXBUFFERPROC)(GLenum, GLenum, GLuint); -GLAPI PFNGLTEXBUFFERPROC glad_glTexBuffer; -#define glTexBuffer glad_glTexBuffer -typedef void (APIENTRYP PFNGLPRIMITIVERESTARTINDEXPROC)(GLuint); -GLAPI PFNGLPRIMITIVERESTARTINDEXPROC glad_glPrimitiveRestartIndex; -#define glPrimitiveRestartIndex glad_glPrimitiveRestartIndex -typedef void (APIENTRYP PFNGLCOPYBUFFERSUBDATAPROC)(GLenum, GLenum, GLintptr, GLintptr, GLsizeiptr); -GLAPI PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData; -#define glCopyBufferSubData glad_glCopyBufferSubData -typedef void (APIENTRYP PFNGLGETUNIFORMINDICESPROC)(GLuint, GLsizei, const GLchar**, GLuint*); -GLAPI PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices; -#define glGetUniformIndices glad_glGetUniformIndices -typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMSIVPROC)(GLuint, GLsizei, const GLuint*, GLenum, GLint*); -GLAPI PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv; -#define glGetActiveUniformsiv glad_glGetActiveUniformsiv -typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMNAMEPROC)(GLuint, GLuint, GLsizei, GLsizei*, GLchar*); -GLAPI PFNGLGETACTIVEUNIFORMNAMEPROC glad_glGetActiveUniformName; -#define glGetActiveUniformName glad_glGetActiveUniformName -typedef GLuint (APIENTRYP PFNGLGETUNIFORMBLOCKINDEXPROC)(GLuint, const GLchar*); -GLAPI PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex; -#define glGetUniformBlockIndex glad_glGetUniformBlockIndex -typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKIVPROC)(GLuint, GLuint, GLenum, GLint*); -GLAPI PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv; -#define glGetActiveUniformBlockiv glad_glGetActiveUniformBlockiv -typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC)(GLuint, GLuint, GLsizei, GLsizei*, GLchar*); -GLAPI PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName; -#define glGetActiveUniformBlockName glad_glGetActiveUniformBlockName -typedef void (APIENTRYP PFNGLUNIFORMBLOCKBINDINGPROC)(GLuint, GLuint, GLuint); -GLAPI PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding; -#define glUniformBlockBinding glad_glUniformBlockBinding -#endif -#ifndef GL_VERSION_3_2 -#define GL_VERSION_3_2 1 -GLAPI int GLAD_GL_VERSION_3_2; -typedef void (APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXPROC)(GLenum, GLsizei, GLenum, const void*, GLint); -GLAPI PFNGLDRAWELEMENTSBASEVERTEXPROC glad_glDrawElementsBaseVertex; -#define glDrawElementsBaseVertex glad_glDrawElementsBaseVertex -typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC)(GLenum, GLuint, GLuint, GLsizei, GLenum, const void*, GLint); -GLAPI PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex; -#define glDrawRangeElementsBaseVertex glad_glDrawRangeElementsBaseVertex -typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)(GLenum, GLsizei, GLenum, const void*, GLsizei, GLint); -GLAPI PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex; -#define glDrawElementsInstancedBaseVertex glad_glDrawElementsInstancedBaseVertex -typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC)(GLenum, const GLsizei*, GLenum, const void**, GLsizei, const GLint*); -GLAPI PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glad_glMultiDrawElementsBaseVertex; -#define glMultiDrawElementsBaseVertex glad_glMultiDrawElementsBaseVertex -typedef void (APIENTRYP PFNGLPROVOKINGVERTEXPROC)(GLenum); -GLAPI PFNGLPROVOKINGVERTEXPROC glad_glProvokingVertex; -#define glProvokingVertex glad_glProvokingVertex -typedef GLsync (APIENTRYP PFNGLFENCESYNCPROC)(GLenum, GLbitfield); -GLAPI PFNGLFENCESYNCPROC glad_glFenceSync; -#define glFenceSync glad_glFenceSync -typedef GLboolean (APIENTRYP PFNGLISSYNCPROC)(GLsync); -GLAPI PFNGLISSYNCPROC glad_glIsSync; -#define glIsSync glad_glIsSync -typedef void (APIENTRYP PFNGLDELETESYNCPROC)(GLsync); -GLAPI PFNGLDELETESYNCPROC glad_glDeleteSync; -#define glDeleteSync glad_glDeleteSync -typedef GLenum (APIENTRYP PFNGLCLIENTWAITSYNCPROC)(GLsync, GLbitfield, GLuint64); -GLAPI PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync; -#define glClientWaitSync glad_glClientWaitSync -typedef void (APIENTRYP PFNGLWAITSYNCPROC)(GLsync, GLbitfield, GLuint64); -GLAPI PFNGLWAITSYNCPROC glad_glWaitSync; -#define glWaitSync glad_glWaitSync -typedef void (APIENTRYP PFNGLGETINTEGER64VPROC)(GLenum, GLint64*); -GLAPI PFNGLGETINTEGER64VPROC glad_glGetInteger64v; -#define glGetInteger64v glad_glGetInteger64v -typedef void (APIENTRYP PFNGLGETSYNCIVPROC)(GLsync, GLenum, GLsizei, GLsizei*, GLint*); -GLAPI PFNGLGETSYNCIVPROC glad_glGetSynciv; -#define glGetSynciv glad_glGetSynciv -typedef void (APIENTRYP PFNGLGETINTEGER64I_VPROC)(GLenum, GLuint, GLint64*); -GLAPI PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v; -#define glGetInteger64i_v glad_glGetInteger64i_v -typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERI64VPROC)(GLenum, GLenum, GLint64*); -GLAPI PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v; -#define glGetBufferParameteri64v glad_glGetBufferParameteri64v -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREPROC)(GLenum, GLenum, GLuint, GLint); -GLAPI PFNGLFRAMEBUFFERTEXTUREPROC glad_glFramebufferTexture; -#define glFramebufferTexture glad_glFramebufferTexture -typedef void (APIENTRYP PFNGLTEXIMAGE2DMULTISAMPLEPROC)(GLenum, GLsizei, GLenum, GLsizei, GLsizei, GLboolean); -GLAPI PFNGLTEXIMAGE2DMULTISAMPLEPROC glad_glTexImage2DMultisample; -#define glTexImage2DMultisample glad_glTexImage2DMultisample -typedef void (APIENTRYP PFNGLTEXIMAGE3DMULTISAMPLEPROC)(GLenum, GLsizei, GLenum, GLsizei, GLsizei, GLsizei, GLboolean); -GLAPI PFNGLTEXIMAGE3DMULTISAMPLEPROC glad_glTexImage3DMultisample; -#define glTexImage3DMultisample glad_glTexImage3DMultisample -typedef void (APIENTRYP PFNGLGETMULTISAMPLEFVPROC)(GLenum, GLuint, GLfloat*); -GLAPI PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv; -#define glGetMultisamplefv glad_glGetMultisamplefv -typedef void (APIENTRYP PFNGLSAMPLEMASKIPROC)(GLuint, GLbitfield); -GLAPI PFNGLSAMPLEMASKIPROC glad_glSampleMaski; -#define glSampleMaski glad_glSampleMaski -#endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/examples/common/glfw/deps/tinycthread.c b/examples/common/glfw/deps/tinycthread.c deleted file mode 100644 index 670857eb..00000000 --- a/examples/common/glfw/deps/tinycthread.c +++ /dev/null @@ -1,593 +0,0 @@ -/* -*- mode: c; tab-width: 2; indent-tabs-mode: nil; -*- -Copyright (c) 2012 Marcus Geelnard - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any damages -arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - - 3. This notice may not be removed or altered from any source - distribution. -*/ - -/* 2013-01-06 Camilla Berglund - * - * Added casts from time_t to DWORD to avoid warnings on VC++. - */ - -#include "tinycthread.h" -#include - -/* Platform specific includes */ -#if defined(_TTHREAD_POSIX_) - #include - #include - #include - #include - #include -#elif defined(_TTHREAD_WIN32_) - #include - #include -#endif - -/* Standard, good-to-have defines */ -#ifndef NULL - #define NULL (void*)0 -#endif -#ifndef TRUE - #define TRUE 1 -#endif -#ifndef FALSE - #define FALSE 0 -#endif - -int mtx_init(mtx_t *mtx, int type) -{ -#if defined(_TTHREAD_WIN32_) - mtx->mAlreadyLocked = FALSE; - mtx->mRecursive = type & mtx_recursive; - InitializeCriticalSection(&mtx->mHandle); - return thrd_success; -#else - int ret; - pthread_mutexattr_t attr; - pthread_mutexattr_init(&attr); - if (type & mtx_recursive) - { - pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); - } - ret = pthread_mutex_init(mtx, &attr); - pthread_mutexattr_destroy(&attr); - return ret == 0 ? thrd_success : thrd_error; -#endif -} - -void mtx_destroy(mtx_t *mtx) -{ -#if defined(_TTHREAD_WIN32_) - DeleteCriticalSection(&mtx->mHandle); -#else - pthread_mutex_destroy(mtx); -#endif -} - -int mtx_lock(mtx_t *mtx) -{ -#if defined(_TTHREAD_WIN32_) - EnterCriticalSection(&mtx->mHandle); - if (!mtx->mRecursive) - { - while(mtx->mAlreadyLocked) Sleep(1000); /* Simulate deadlock... */ - mtx->mAlreadyLocked = TRUE; - } - return thrd_success; -#else - return pthread_mutex_lock(mtx) == 0 ? thrd_success : thrd_error; -#endif -} - -int mtx_timedlock(mtx_t *mtx, const struct timespec *ts) -{ - /* FIXME! */ - (void)mtx; - (void)ts; - return thrd_error; -} - -int mtx_trylock(mtx_t *mtx) -{ -#if defined(_TTHREAD_WIN32_) - int ret = TryEnterCriticalSection(&mtx->mHandle) ? thrd_success : thrd_busy; - if ((!mtx->mRecursive) && (ret == thrd_success) && mtx->mAlreadyLocked) - { - LeaveCriticalSection(&mtx->mHandle); - ret = thrd_busy; - } - return ret; -#else - return (pthread_mutex_trylock(mtx) == 0) ? thrd_success : thrd_busy; -#endif -} - -int mtx_unlock(mtx_t *mtx) -{ -#if defined(_TTHREAD_WIN32_) - mtx->mAlreadyLocked = FALSE; - LeaveCriticalSection(&mtx->mHandle); - return thrd_success; -#else - return pthread_mutex_unlock(mtx) == 0 ? thrd_success : thrd_error;; -#endif -} - -#if defined(_TTHREAD_WIN32_) -#define _CONDITION_EVENT_ONE 0 -#define _CONDITION_EVENT_ALL 1 -#endif - -int cnd_init(cnd_t *cond) -{ -#if defined(_TTHREAD_WIN32_) - cond->mWaitersCount = 0; - - /* Init critical section */ - InitializeCriticalSection(&cond->mWaitersCountLock); - - /* Init events */ - cond->mEvents[_CONDITION_EVENT_ONE] = CreateEvent(NULL, FALSE, FALSE, NULL); - if (cond->mEvents[_CONDITION_EVENT_ONE] == NULL) - { - cond->mEvents[_CONDITION_EVENT_ALL] = NULL; - return thrd_error; - } - cond->mEvents[_CONDITION_EVENT_ALL] = CreateEvent(NULL, TRUE, FALSE, NULL); - if (cond->mEvents[_CONDITION_EVENT_ALL] == NULL) - { - CloseHandle(cond->mEvents[_CONDITION_EVENT_ONE]); - cond->mEvents[_CONDITION_EVENT_ONE] = NULL; - return thrd_error; - } - - return thrd_success; -#else - return pthread_cond_init(cond, NULL) == 0 ? thrd_success : thrd_error; -#endif -} - -void cnd_destroy(cnd_t *cond) -{ -#if defined(_TTHREAD_WIN32_) - if (cond->mEvents[_CONDITION_EVENT_ONE] != NULL) - { - CloseHandle(cond->mEvents[_CONDITION_EVENT_ONE]); - } - if (cond->mEvents[_CONDITION_EVENT_ALL] != NULL) - { - CloseHandle(cond->mEvents[_CONDITION_EVENT_ALL]); - } - DeleteCriticalSection(&cond->mWaitersCountLock); -#else - pthread_cond_destroy(cond); -#endif -} - -int cnd_signal(cnd_t *cond) -{ -#if defined(_TTHREAD_WIN32_) - int haveWaiters; - - /* Are there any waiters? */ - EnterCriticalSection(&cond->mWaitersCountLock); - haveWaiters = (cond->mWaitersCount > 0); - LeaveCriticalSection(&cond->mWaitersCountLock); - - /* If we have any waiting threads, send them a signal */ - if(haveWaiters) - { - if (SetEvent(cond->mEvents[_CONDITION_EVENT_ONE]) == 0) - { - return thrd_error; - } - } - - return thrd_success; -#else - return pthread_cond_signal(cond) == 0 ? thrd_success : thrd_error; -#endif -} - -int cnd_broadcast(cnd_t *cond) -{ -#if defined(_TTHREAD_WIN32_) - int haveWaiters; - - /* Are there any waiters? */ - EnterCriticalSection(&cond->mWaitersCountLock); - haveWaiters = (cond->mWaitersCount > 0); - LeaveCriticalSection(&cond->mWaitersCountLock); - - /* If we have any waiting threads, send them a signal */ - if(haveWaiters) - { - if (SetEvent(cond->mEvents[_CONDITION_EVENT_ALL]) == 0) - { - return thrd_error; - } - } - - return thrd_success; -#else - return pthread_cond_signal(cond) == 0 ? thrd_success : thrd_error; -#endif -} - -#if defined(_TTHREAD_WIN32_) -static int _cnd_timedwait_win32(cnd_t *cond, mtx_t *mtx, DWORD timeout) -{ - int result, lastWaiter; - - /* Increment number of waiters */ - EnterCriticalSection(&cond->mWaitersCountLock); - ++ cond->mWaitersCount; - LeaveCriticalSection(&cond->mWaitersCountLock); - - /* Release the mutex while waiting for the condition (will decrease - the number of waiters when done)... */ - mtx_unlock(mtx); - - /* Wait for either event to become signaled due to cnd_signal() or - cnd_broadcast() being called */ - result = WaitForMultipleObjects(2, cond->mEvents, FALSE, timeout); - if (result == WAIT_TIMEOUT) - { - return thrd_timeout; - } - else if (result == (int)WAIT_FAILED) - { - return thrd_error; - } - - /* Check if we are the last waiter */ - EnterCriticalSection(&cond->mWaitersCountLock); - -- cond->mWaitersCount; - lastWaiter = (result == (WAIT_OBJECT_0 + _CONDITION_EVENT_ALL)) && - (cond->mWaitersCount == 0); - LeaveCriticalSection(&cond->mWaitersCountLock); - - /* If we are the last waiter to be notified to stop waiting, reset the event */ - if (lastWaiter) - { - if (ResetEvent(cond->mEvents[_CONDITION_EVENT_ALL]) == 0) - { - return thrd_error; - } - } - - /* Re-acquire the mutex */ - mtx_lock(mtx); - - return thrd_success; -} -#endif - -int cnd_wait(cnd_t *cond, mtx_t *mtx) -{ -#if defined(_TTHREAD_WIN32_) - return _cnd_timedwait_win32(cond, mtx, INFINITE); -#else - return pthread_cond_wait(cond, mtx) == 0 ? thrd_success : thrd_error; -#endif -} - -int cnd_timedwait(cnd_t *cond, mtx_t *mtx, const struct timespec *ts) -{ -#if defined(_TTHREAD_WIN32_) - struct timespec now; - if (clock_gettime(TIME_UTC, &now) == 0) - { - DWORD delta = (DWORD) ((ts->tv_sec - now.tv_sec) * 1000 + - (ts->tv_nsec - now.tv_nsec + 500000) / 1000000); - return _cnd_timedwait_win32(cond, mtx, delta); - } - else - return thrd_error; -#else - int ret; - ret = pthread_cond_timedwait(cond, mtx, ts); - if (ret == ETIMEDOUT) - { - return thrd_timeout; - } - return ret == 0 ? thrd_success : thrd_error; -#endif -} - - -/** Information to pass to the new thread (what to run). */ -typedef struct { - thrd_start_t mFunction; /**< Pointer to the function to be executed. */ - void * mArg; /**< Function argument for the thread function. */ -} _thread_start_info; - -/* Thread wrapper function. */ -#if defined(_TTHREAD_WIN32_) -static unsigned WINAPI _thrd_wrapper_function(void * aArg) -#elif defined(_TTHREAD_POSIX_) -static void * _thrd_wrapper_function(void * aArg) -#endif -{ - thrd_start_t fun; - void *arg; - int res; -#if defined(_TTHREAD_POSIX_) - void *pres; -#endif - - /* Get thread startup information */ - _thread_start_info *ti = (_thread_start_info *) aArg; - fun = ti->mFunction; - arg = ti->mArg; - - /* The thread is responsible for freeing the startup information */ - free((void *)ti); - - /* Call the actual client thread function */ - res = fun(arg); - -#if defined(_TTHREAD_WIN32_) - return res; -#else - pres = malloc(sizeof(int)); - if (pres != NULL) - { - *(int*)pres = res; - } - return pres; -#endif -} - -int thrd_create(thrd_t *thr, thrd_start_t func, void *arg) -{ - /* Fill out the thread startup information (passed to the thread wrapper, - which will eventually free it) */ - _thread_start_info* ti = (_thread_start_info*)malloc(sizeof(_thread_start_info)); - if (ti == NULL) - { - return thrd_nomem; - } - ti->mFunction = func; - ti->mArg = arg; - - /* Create the thread */ -#if defined(_TTHREAD_WIN32_) - *thr = (HANDLE)_beginthreadex(NULL, 0, _thrd_wrapper_function, (void *)ti, 0, NULL); -#elif defined(_TTHREAD_POSIX_) - if(pthread_create(thr, NULL, _thrd_wrapper_function, (void *)ti) != 0) - { - *thr = 0; - } -#endif - - /* Did we fail to create the thread? */ - if(!*thr) - { - free(ti); - return thrd_error; - } - - return thrd_success; -} - -thrd_t thrd_current(void) -{ -#if defined(_TTHREAD_WIN32_) - return GetCurrentThread(); -#else - return pthread_self(); -#endif -} - -int thrd_detach(thrd_t thr) -{ - /* FIXME! */ - (void)thr; - return thrd_error; -} - -int thrd_equal(thrd_t thr0, thrd_t thr1) -{ -#if defined(_TTHREAD_WIN32_) - return thr0 == thr1; -#else - return pthread_equal(thr0, thr1); -#endif -} - -void thrd_exit(int res) -{ -#if defined(_TTHREAD_WIN32_) - ExitThread(res); -#else - void *pres = malloc(sizeof(int)); - if (pres != NULL) - { - *(int*)pres = res; - } - pthread_exit(pres); -#endif -} - -int thrd_join(thrd_t thr, int *res) -{ -#if defined(_TTHREAD_WIN32_) - if (WaitForSingleObject(thr, INFINITE) == WAIT_FAILED) - { - return thrd_error; - } - if (res != NULL) - { - DWORD dwRes; - GetExitCodeThread(thr, &dwRes); - *res = dwRes; - } -#elif defined(_TTHREAD_POSIX_) - void *pres; - int ires = 0; - if (pthread_join(thr, &pres) != 0) - { - return thrd_error; - } - if (pres != NULL) - { - ires = *(int*)pres; - free(pres); - } - if (res != NULL) - { - *res = ires; - } -#endif - return thrd_success; -} - -int thrd_sleep(const struct timespec *time_point, struct timespec *remaining) -{ - struct timespec now; -#if defined(_TTHREAD_WIN32_) - DWORD delta; -#else - long delta; -#endif - - /* Get the current time */ - if (clock_gettime(TIME_UTC, &now) != 0) - return -2; // FIXME: Some specific error code? - -#if defined(_TTHREAD_WIN32_) - /* Delta in milliseconds */ - delta = (DWORD) ((time_point->tv_sec - now.tv_sec) * 1000 + - (time_point->tv_nsec - now.tv_nsec + 500000) / 1000000); - if (delta > 0) - { - Sleep(delta); - } -#else - /* Delta in microseconds */ - delta = (time_point->tv_sec - now.tv_sec) * 1000000L + - (time_point->tv_nsec - now.tv_nsec + 500L) / 1000L; - - /* On some systems, the usleep argument must be < 1000000 */ - while (delta > 999999L) - { - usleep(999999); - delta -= 999999L; - } - if (delta > 0L) - { - usleep((useconds_t)delta); - } -#endif - - /* We don't support waking up prematurely (yet) */ - if (remaining) - { - remaining->tv_sec = 0; - remaining->tv_nsec = 0; - } - return 0; -} - -void thrd_yield(void) -{ -#if defined(_TTHREAD_WIN32_) - Sleep(0); -#else - sched_yield(); -#endif -} - -int tss_create(tss_t *key, tss_dtor_t dtor) -{ -#if defined(_TTHREAD_WIN32_) - /* FIXME: The destructor function is not supported yet... */ - if (dtor != NULL) - { - return thrd_error; - } - *key = TlsAlloc(); - if (*key == TLS_OUT_OF_INDEXES) - { - return thrd_error; - } -#else - if (pthread_key_create(key, dtor) != 0) - { - return thrd_error; - } -#endif - return thrd_success; -} - -void tss_delete(tss_t key) -{ -#if defined(_TTHREAD_WIN32_) - TlsFree(key); -#else - pthread_key_delete(key); -#endif -} - -void *tss_get(tss_t key) -{ -#if defined(_TTHREAD_WIN32_) - return TlsGetValue(key); -#else - return pthread_getspecific(key); -#endif -} - -int tss_set(tss_t key, void *val) -{ -#if defined(_TTHREAD_WIN32_) - if (TlsSetValue(key, val) == 0) - { - return thrd_error; - } -#else - if (pthread_setspecific(key, val) != 0) - { - return thrd_error; - } -#endif - return thrd_success; -} - -#if defined(_TTHREAD_EMULATE_CLOCK_GETTIME_) -int _tthread_clock_gettime(clockid_t clk_id, struct timespec *ts) -{ -#if defined(_TTHREAD_WIN32_) - struct _timeb tb; - _ftime(&tb); - ts->tv_sec = (time_t)tb.time; - ts->tv_nsec = 1000000L * (long)tb.millitm; -#else - struct timeval tv; - gettimeofday(&tv, NULL); - ts->tv_sec = (time_t)tv.tv_sec; - ts->tv_nsec = 1000L * (long)tv.tv_usec; -#endif - return 0; -} -#endif // _TTHREAD_EMULATE_CLOCK_GETTIME_ - diff --git a/examples/common/glfw/deps/tinycthread.h b/examples/common/glfw/deps/tinycthread.h deleted file mode 100644 index 86a90804..00000000 --- a/examples/common/glfw/deps/tinycthread.h +++ /dev/null @@ -1,440 +0,0 @@ -/* -*- mode: c; tab-width: 2; indent-tabs-mode: nil; -*- -Copyright (c) 2012 Marcus Geelnard - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any damages -arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - - 3. This notice may not be removed or altered from any source - distribution. -*/ - -#ifndef _TINYCTHREAD_H_ -#define _TINYCTHREAD_H_ - -/** -* @file -* @mainpage TinyCThread API Reference -* -* @section intro_sec Introduction -* TinyCThread is a minimal, portable implementation of basic threading -* classes for C. -* -* They closely mimic the functionality and naming of the C11 standard, and -* should be easily replaceable with the corresponding standard variants. -* -* @section port_sec Portability -* The Win32 variant uses the native Win32 API for implementing the thread -* classes, while for other systems, the POSIX threads API (pthread) is used. -* -* @section misc_sec Miscellaneous -* The following special keywords are available: #_Thread_local. -* -* For more detailed information, browse the different sections of this -* documentation. A good place to start is: -* tinycthread.h. -*/ - -/* Which platform are we on? */ -#if !defined(_TTHREAD_PLATFORM_DEFINED_) - #if defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__) - #define _TTHREAD_WIN32_ - #else - #define _TTHREAD_POSIX_ - #endif - #define _TTHREAD_PLATFORM_DEFINED_ -#endif - -/* Activate some POSIX functionality (e.g. clock_gettime and recursive mutexes) */ -#if defined(_TTHREAD_POSIX_) - #undef _FEATURES_H - #if !defined(_GNU_SOURCE) - #define _GNU_SOURCE - #endif - #if !defined(_POSIX_C_SOURCE) || ((_POSIX_C_SOURCE - 0) < 199309L) - #undef _POSIX_C_SOURCE - #define _POSIX_C_SOURCE 199309L - #endif - #if !defined(_XOPEN_SOURCE) || ((_XOPEN_SOURCE - 0) < 500) - #undef _XOPEN_SOURCE - #define _XOPEN_SOURCE 500 - #endif -#endif - -/* Generic includes */ -#include - -/* Platform specific includes */ -#if defined(_TTHREAD_POSIX_) - #include -#elif defined(_TTHREAD_WIN32_) - #ifndef WIN32_LEAN_AND_MEAN - #define WIN32_LEAN_AND_MEAN - #define __UNDEF_LEAN_AND_MEAN - #endif - #include - #ifdef __UNDEF_LEAN_AND_MEAN - #undef WIN32_LEAN_AND_MEAN - #undef __UNDEF_LEAN_AND_MEAN - #endif -#endif - -/* Workaround for missing TIME_UTC: If time.h doesn't provide TIME_UTC, - it's quite likely that libc does not support it either. Hence, fall back to - the only other supported time specifier: CLOCK_REALTIME (and if that fails, - we're probably emulating clock_gettime anyway, so anything goes). */ -#ifndef TIME_UTC - #ifdef CLOCK_REALTIME - #define TIME_UTC CLOCK_REALTIME - #else - #define TIME_UTC 0 - #endif -#endif - -/* Workaround for missing clock_gettime (most Windows compilers, afaik) */ -#if defined(_TTHREAD_WIN32_) || defined(__APPLE_CC__) -#define _TTHREAD_EMULATE_CLOCK_GETTIME_ -/* Emulate struct timespec */ -#if defined(_TTHREAD_WIN32_) -struct _ttherad_timespec { - time_t tv_sec; - long tv_nsec; -}; -#define timespec _ttherad_timespec -#endif - -/* Emulate clockid_t */ -typedef int _tthread_clockid_t; -#define clockid_t _tthread_clockid_t - -/* Emulate clock_gettime */ -int _tthread_clock_gettime(clockid_t clk_id, struct timespec *ts); -#define clock_gettime _tthread_clock_gettime -#define CLOCK_REALTIME 0 -#endif - - -/** TinyCThread version (major number). */ -#define TINYCTHREAD_VERSION_MAJOR 1 -/** TinyCThread version (minor number). */ -#define TINYCTHREAD_VERSION_MINOR 1 -/** TinyCThread version (full version). */ -#define TINYCTHREAD_VERSION (TINYCTHREAD_VERSION_MAJOR * 100 + TINYCTHREAD_VERSION_MINOR) - -/** -* @def _Thread_local -* Thread local storage keyword. -* A variable that is declared with the @c _Thread_local keyword makes the -* value of the variable local to each thread (known as thread-local storage, -* or TLS). Example usage: -* @code -* // This variable is local to each thread. -* _Thread_local int variable; -* @endcode -* @note The @c _Thread_local keyword is a macro that maps to the corresponding -* compiler directive (e.g. @c __declspec(thread)). -* @note This directive is currently not supported on Mac OS X (it will give -* a compiler error), since compile-time TLS is not supported in the Mac OS X -* executable format. Also, some older versions of MinGW (before GCC 4.x) do -* not support this directive. -* @hideinitializer -*/ - -/* FIXME: Check for a PROPER value of __STDC_VERSION__ to know if we have C11 */ -#if !(defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201102L)) && !defined(_Thread_local) - #if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_CC) || defined(__IBMCPP__) - #define _Thread_local __thread - #else - #define _Thread_local __declspec(thread) - #endif -#endif - -/* Macros */ -#define TSS_DTOR_ITERATIONS 0 - -/* Function return values */ -#define thrd_error 0 /**< The requested operation failed */ -#define thrd_success 1 /**< The requested operation succeeded */ -#define thrd_timeout 2 /**< The time specified in the call was reached without acquiring the requested resource */ -#define thrd_busy 3 /**< The requested operation failed because a tesource requested by a test and return function is already in use */ -#define thrd_nomem 4 /**< The requested operation failed because it was unable to allocate memory */ - -/* Mutex types */ -#define mtx_plain 1 -#define mtx_timed 2 -#define mtx_try 4 -#define mtx_recursive 8 - -/* Mutex */ -#if defined(_TTHREAD_WIN32_) -typedef struct { - CRITICAL_SECTION mHandle; /* Critical section handle */ - int mAlreadyLocked; /* TRUE if the mutex is already locked */ - int mRecursive; /* TRUE if the mutex is recursive */ -} mtx_t; -#else -typedef pthread_mutex_t mtx_t; -#endif - -/** Create a mutex object. -* @param mtx A mutex object. -* @param type Bit-mask that must have one of the following six values: -* @li @c mtx_plain for a simple non-recursive mutex -* @li @c mtx_timed for a non-recursive mutex that supports timeout -* @li @c mtx_try for a non-recursive mutex that supports test and return -* @li @c mtx_plain | @c mtx_recursive (same as @c mtx_plain, but recursive) -* @li @c mtx_timed | @c mtx_recursive (same as @c mtx_timed, but recursive) -* @li @c mtx_try | @c mtx_recursive (same as @c mtx_try, but recursive) -* @return @ref thrd_success on success, or @ref thrd_error if the request could -* not be honored. -*/ -int mtx_init(mtx_t *mtx, int type); - -/** Release any resources used by the given mutex. -* @param mtx A mutex object. -*/ -void mtx_destroy(mtx_t *mtx); - -/** Lock the given mutex. -* Blocks until the given mutex can be locked. If the mutex is non-recursive, and -* the calling thread already has a lock on the mutex, this call will block -* forever. -* @param mtx A mutex object. -* @return @ref thrd_success on success, or @ref thrd_error if the request could -* not be honored. -*/ -int mtx_lock(mtx_t *mtx); - -/** NOT YET IMPLEMENTED. -*/ -int mtx_timedlock(mtx_t *mtx, const struct timespec *ts); - -/** Try to lock the given mutex. -* The specified mutex shall support either test and return or timeout. If the -* mutex is already locked, the function returns without blocking. -* @param mtx A mutex object. -* @return @ref thrd_success on success, or @ref thrd_busy if the resource -* requested is already in use, or @ref thrd_error if the request could not be -* honored. -*/ -int mtx_trylock(mtx_t *mtx); - -/** Unlock the given mutex. -* @param mtx A mutex object. -* @return @ref thrd_success on success, or @ref thrd_error if the request could -* not be honored. -*/ -int mtx_unlock(mtx_t *mtx); - -/* Condition variable */ -#if defined(_TTHREAD_WIN32_) -typedef struct { - HANDLE mEvents[2]; /* Signal and broadcast event HANDLEs. */ - unsigned int mWaitersCount; /* Count of the number of waiters. */ - CRITICAL_SECTION mWaitersCountLock; /* Serialize access to mWaitersCount. */ -} cnd_t; -#else -typedef pthread_cond_t cnd_t; -#endif - -/** Create a condition variable object. -* @param cond A condition variable object. -* @return @ref thrd_success on success, or @ref thrd_error if the request could -* not be honored. -*/ -int cnd_init(cnd_t *cond); - -/** Release any resources used by the given condition variable. -* @param cond A condition variable object. -*/ -void cnd_destroy(cnd_t *cond); - -/** Signal a condition variable. -* Unblocks one of the threads that are blocked on the given condition variable -* at the time of the call. If no threads are blocked on the condition variable -* at the time of the call, the function does nothing and return success. -* @param cond A condition variable object. -* @return @ref thrd_success on success, or @ref thrd_error if the request could -* not be honored. -*/ -int cnd_signal(cnd_t *cond); - -/** Broadcast a condition variable. -* Unblocks all of the threads that are blocked on the given condition variable -* at the time of the call. If no threads are blocked on the condition variable -* at the time of the call, the function does nothing and return success. -* @param cond A condition variable object. -* @return @ref thrd_success on success, or @ref thrd_error if the request could -* not be honored. -*/ -int cnd_broadcast(cnd_t *cond); - -/** Wait for a condition variable to become signaled. -* The function atomically unlocks the given mutex and endeavors to block until -* the given condition variable is signaled by a call to cnd_signal or to -* cnd_broadcast. When the calling thread becomes unblocked it locks the mutex -* before it returns. -* @param cond A condition variable object. -* @param mtx A mutex object. -* @return @ref thrd_success on success, or @ref thrd_error if the request could -* not be honored. -*/ -int cnd_wait(cnd_t *cond, mtx_t *mtx); - -/** Wait for a condition variable to become signaled. -* The function atomically unlocks the given mutex and endeavors to block until -* the given condition variable is signaled by a call to cnd_signal or to -* cnd_broadcast, or until after the specified time. When the calling thread -* becomes unblocked it locks the mutex before it returns. -* @param cond A condition variable object. -* @param mtx A mutex object. -* @param xt A point in time at which the request will time out (absolute time). -* @return @ref thrd_success upon success, or @ref thrd_timeout if the time -* specified in the call was reached without acquiring the requested resource, or -* @ref thrd_error if the request could not be honored. -*/ -int cnd_timedwait(cnd_t *cond, mtx_t *mtx, const struct timespec *ts); - -/* Thread */ -#if defined(_TTHREAD_WIN32_) -typedef HANDLE thrd_t; -#else -typedef pthread_t thrd_t; -#endif - -/** Thread start function. -* Any thread that is started with the @ref thrd_create() function must be -* started through a function of this type. -* @param arg The thread argument (the @c arg argument of the corresponding -* @ref thrd_create() call). -* @return The thread return value, which can be obtained by another thread -* by using the @ref thrd_join() function. -*/ -typedef int (*thrd_start_t)(void *arg); - -/** Create a new thread. -* @param thr Identifier of the newly created thread. -* @param func A function pointer to the function that will be executed in -* the new thread. -* @param arg An argument to the thread function. -* @return @ref thrd_success on success, or @ref thrd_nomem if no memory could -* be allocated for the thread requested, or @ref thrd_error if the request -* could not be honored. -* @note A thread’s identifier may be reused for a different thread once the -* original thread has exited and either been detached or joined to another -* thread. -*/ -int thrd_create(thrd_t *thr, thrd_start_t func, void *arg); - -/** Identify the calling thread. -* @return The identifier of the calling thread. -*/ -thrd_t thrd_current(void); - -/** NOT YET IMPLEMENTED. -*/ -int thrd_detach(thrd_t thr); - -/** Compare two thread identifiers. -* The function determines if two thread identifiers refer to the same thread. -* @return Zero if the two thread identifiers refer to different threads. -* Otherwise a nonzero value is returned. -*/ -int thrd_equal(thrd_t thr0, thrd_t thr1); - -/** Terminate execution of the calling thread. -* @param res Result code of the calling thread. -*/ -void thrd_exit(int res); - -/** Wait for a thread to terminate. -* The function joins the given thread with the current thread by blocking -* until the other thread has terminated. -* @param thr The thread to join with. -* @param res If this pointer is not NULL, the function will store the result -* code of the given thread in the integer pointed to by @c res. -* @return @ref thrd_success on success, or @ref thrd_error if the request could -* not be honored. -*/ -int thrd_join(thrd_t thr, int *res); - -/** Put the calling thread to sleep. -* Suspend execution of the calling thread. -* @param time_point A point in time at which the thread will resume (absolute time). -* @param remaining If non-NULL, this parameter will hold the remaining time until -* time_point upon return. This will typically be zero, but if -* the thread was woken up by a signal that is not ignored before -* time_point was reached @c remaining will hold a positive -* time. -* @return 0 (zero) on successful sleep, or -1 if an interrupt occurred. -*/ -int thrd_sleep(const struct timespec *time_point, struct timespec *remaining); - -/** Yield execution to another thread. -* Permit other threads to run, even if the current thread would ordinarily -* continue to run. -*/ -void thrd_yield(void); - -/* Thread local storage */ -#if defined(_TTHREAD_WIN32_) -typedef DWORD tss_t; -#else -typedef pthread_key_t tss_t; -#endif - -/** Destructor function for a thread-specific storage. -* @param val The value of the destructed thread-specific storage. -*/ -typedef void (*tss_dtor_t)(void *val); - -/** Create a thread-specific storage. -* @param key The unique key identifier that will be set if the function is -* successful. -* @param dtor Destructor function. This can be NULL. -* @return @ref thrd_success on success, or @ref thrd_error if the request could -* not be honored. -* @note The destructor function is not supported under Windows. If @c dtor is -* not NULL when calling this function under Windows, the function will fail -* and return @ref thrd_error. -*/ -int tss_create(tss_t *key, tss_dtor_t dtor); - -/** Delete a thread-specific storage. -* The function releases any resources used by the given thread-specific -* storage. -* @param key The key that shall be deleted. -*/ -void tss_delete(tss_t key); - -/** Get the value for a thread-specific storage. -* @param key The thread-specific storage identifier. -* @return The value for the current thread held in the given thread-specific -* storage. -*/ -void *tss_get(tss_t key); - -/** Set the value for a thread-specific storage. -* @param key The thread-specific storage identifier. -* @param val The value of the thread-specific storage to set for the current -* thread. -* @return @ref thrd_success on success, or @ref thrd_error if the request could -* not be honored. -*/ -int tss_set(tss_t key, void *val); - - -#endif /* _TINYTHREAD_H_ */ - diff --git a/examples/common/glfw/docs/CMakeLists.txt b/examples/common/glfw/docs/CMakeLists.txt deleted file mode 100644 index 45a6162e..00000000 --- a/examples/common/glfw/docs/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ - -add_custom_target(docs ALL ${DOXYGEN_EXECUTABLE} - WORKING_DIRECTORY ${GLFW_BINARY_DIR}/docs - COMMENT "Generating HTML documentation" VERBATIM) - diff --git a/examples/common/glfw/docs/Doxyfile.in b/examples/common/glfw/docs/Doxyfile.in deleted file mode 100644 index 8410a850..00000000 --- a/examples/common/glfw/docs/Doxyfile.in +++ /dev/null @@ -1,1863 +0,0 @@ -# Doxyfile 1.8.3.1 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project. -# -# All text after a hash (#) is considered a comment and will be ignored. -# The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" "). - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all -# text before the first occurrence of this tag. Doxygen uses libiconv (or the -# iconv built into libc) for the transcoding. See -# http://www.gnu.org/software/libiconv for the list of possible encodings. - -DOXYFILE_ENCODING = UTF-8 - -# The PROJECT_NAME tag is a single word (or sequence of words) that should -# identify the project. Note that if you do not use Doxywizard you need -# to put quotes around the project name if it contains spaces. - -PROJECT_NAME = "GLFW" - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. - -PROJECT_NUMBER = @GLFW_VERSION_FULL@ - -# Using the PROJECT_BRIEF tag one can provide an optional one line description -# for a project that appears at the top of each page and should give viewer -# a quick idea about the purpose of the project. Keep the description short. - -PROJECT_BRIEF = "A multi-platform library for OpenGL, window and input" - -# With the PROJECT_LOGO tag one can specify an logo or icon that is -# included in the documentation. The maximum height of the logo should not -# exceed 55 pixels and the maximum width should not exceed 200 pixels. -# Doxygen will copy the logo to the output directory. - -PROJECT_LOGO = - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. - -OUTPUT_DIRECTORY = @GLFW_BINARY_DIR@/docs - -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would -# otherwise cause performance problems for the file system. - -CREATE_SUBDIRS = NO - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, -# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, -# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English -# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, -# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, -# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. - -OUTPUT_LANGUAGE = English - -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. - -REPEAT_BRIEF = NO - -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" -# "represents" "a" "an" "the" - -ABBREVIATE_BRIEF = - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief -# description. - -ALWAYS_DETAILED_SEC = YES - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. - -FULL_PATH_NAMES = NO - -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the -# path to strip. Note that you specify absolute paths here, but also -# relative paths, which will be relative from the directory where doxygen is -# started. - -STRIP_FROM_PATH = - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that -# are normally passed to the compiler using the -I flag. - -STRIP_FROM_INC_PATH = - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful if your file system -# doesn't support long names like on DOS, Mac, or CD-ROM. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like regular Qt-style comments -# (thus requiring an explicit @brief command for a brief description.) - -JAVADOC_AUTOBRIEF = NO - -# If the QT_AUTOBRIEF tag is set to YES then Doxygen will -# interpret the first line (until the first dot) of a Qt-style -# comment as the brief description. If set to NO, the comments -# will behave just like regular Qt-style comments (thus requiring -# an explicit \brief command for a brief description.) - -QT_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed -# description. Set this tag to YES if you prefer the old behaviour instead. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# re-implements. - -INHERIT_DOCS = YES - -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will -# be part of the file/class/namespace that contains it. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. - -TAB_SIZE = 8 - -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. - -ALIASES = - -# This tag can be used to specify a number of word-keyword mappings (TCL only). -# A mapping has the form "name=value". For example adding -# "class=itcl::class" will allow you to use the command class in the -# itcl::class meaning. - -TCL_SUBST = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list -# of all members will be omitted, etc. - -OPTIMIZE_OUTPUT_FOR_C = YES - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java -# sources only. Doxygen will then generate output that is more tailored for -# Java. For instance, namespaces will be presented as packages, qualified -# scopes will look different, etc. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources only. Doxygen will then generate output that is more tailored for -# Fortran. - -OPTIMIZE_FOR_FORTRAN = NO - -# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for -# VHDL. - -OPTIMIZE_OUTPUT_VHDL = NO - -# Doxygen selects the parser to use depending on the extension of the files it -# parses. With this tag you can assign which parser to use for a given -# extension. Doxygen has a built-in mapping, but you can override or extend it -# using this tag. The format is ext=language, where ext is a file extension, -# and language is one of the parsers supported by doxygen: IDL, Java, -# Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, -# C++. For instance to make doxygen treat .inc files as Fortran files (default -# is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note -# that for custom extensions you also need to set FILE_PATTERNS otherwise the -# files are not read by doxygen. - -EXTENSION_MAPPING = - -# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all -# comments according to the Markdown format, which allows for more readable -# documentation. See http://daringfireball.net/projects/markdown/ for details. -# The output of markdown processing is further processed by doxygen, so you -# can mix doxygen, HTML, and XML commands with Markdown formatting. -# Disable only in case of backward compatibilities issues. - -MARKDOWN_SUPPORT = YES - -# When enabled doxygen tries to link words that correspond to documented classes, -# or namespaces to their corresponding documentation. Such a link can be -# prevented in individual cases by by putting a % sign in front of the word or -# globally by setting AUTOLINK_SUPPORT to NO. - -AUTOLINK_SUPPORT = YES - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should -# set this tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also makes the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. - -BUILTIN_STL_SUPPORT = NO - -# If you use Microsoft's C++/CLI language, you should set this option to YES to -# enable parsing support. - -CPP_CLI_SUPPORT = NO - -# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. -# Doxygen will parse them like normal C++ but will assume all classes use public -# instead of private inheritance when no explicit protection keyword is present. - -SIP_SUPPORT = NO - -# For Microsoft's IDL there are propget and propput attributes to indicate -# getter and setter methods for a property. Setting this option to YES (the -# default) will make doxygen replace the get and set methods by a property in -# the documentation. This will only work if the methods are indeed getting or -# setting a simple type. If this is not the case, or you want to show the -# methods anyway, you should set this option to NO. - -IDL_PROPERTY_SUPPORT = NO - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. - -DISTRIBUTE_GROUP_DOC = NO - -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using -# the \nosubgrouping command. - -SUBGROUPING = YES - -# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and -# unions are shown inside the group in which they are included (e.g. using -# @ingroup) instead of on a separate page (for HTML and Man pages) or -# section (for LaTeX and RTF). - -INLINE_GROUPED_CLASSES = NO - -# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and -# unions with only public data fields will be shown inline in the documentation -# of the scope in which they are defined (i.e. file, namespace, or group -# documentation), provided this scope is documented. If set to NO (the default), -# structs, classes, and unions are shown on a separate page (for HTML and Man -# pages) or section (for LaTeX and RTF). - -INLINE_SIMPLE_STRUCTS = NO - -# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum -# is documented as struct, union, or enum with the name of the typedef. So -# typedef struct TypeS {} TypeT, will appear in the documentation as a struct -# with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically -# be useful for C code in case the coding convention dictates that all compound -# types are typedef'ed and only the typedef is referenced, never the tag name. - -TYPEDEF_HIDES_STRUCT = NO - -# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be -# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given -# their name and scope. Since this can be an expensive process and often the -# same symbol appear multiple times in the code, doxygen keeps a cache of -# pre-resolved symbols. If the cache is too small doxygen will become slower. -# If the cache is too large, memory is wasted. The cache size is given by this -# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, -# corresponding to a cache size of 2^16 = 65536 symbols. - -LOOKUP_CACHE_SIZE = 0 - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES - -EXTRACT_ALL = YES - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = NO - -# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal -# scope will be included in the documentation. - -EXTRACT_PACKAGE = NO - -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. - -EXTRACT_STATIC = NO - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. - -EXTRACT_LOCAL_CLASSES = YES - -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. -# If set to NO (the default) only methods in the interface are included. - -EXTRACT_LOCAL_METHODS = NO - -# If this flag is set to YES, the members of anonymous namespaces will be -# extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base -# name of the file that contains the anonymous namespace. By default -# anonymous namespaces are hidden. - -EXTRACT_ANON_NSPACES = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the -# documentation. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the -# function's detailed documentation block. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. - -INTERNAL_DOCS = NO - -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. - -CASE_SENSE_NAMES = YES - -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. - -HIDE_SCOPE_NAMES = NO - -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation -# of that file. - -SHOW_INCLUDE_FILES = NO - -# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen -# will list include files with double quotes in the documentation -# rather than with sharp brackets. - -FORCE_LOCAL_INCLUDES = NO - -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] -# is inserted in the documentation for inline members. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. - -SORT_MEMBER_DOCS = YES - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in -# declaration order. - -SORT_BRIEF_DOCS = NO - -# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen -# will sort the (brief and detailed) documentation of class members so that -# constructors and destructors are listed first. If set to NO (the default) -# the constructors will appear in the respective orders defined by -# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. -# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO -# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. - -SORT_MEMBERS_CTORS_1ST = NO - -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the -# hierarchy of group names into alphabetical order. If set to NO (the default) -# the group names will appear in their defined order. - -SORT_GROUP_NAMES = YES - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the -# alphabetical list. - -SORT_BY_SCOPE_NAME = NO - -# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to -# do proper type resolution of all parameters of a function it will reject a -# match between the prototype and the implementation of a member function even -# if there is only one candidate or it is obvious which candidate to choose -# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen -# will still accept a match between prototype and implementation in such cases. - -STRICT_PROTO_MATCHING = NO - -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug -# commands in the documentation. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting -# \deprecated commands in the documentation. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if section-label ... \endif -# and \cond section-label ... \endcond blocks. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or macro consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and macros in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the -# list will mention the files that were used to generate the documentation. - -SHOW_USED_FILES = YES - -# Set the SHOW_FILES tag to NO to disable the generation of the Files page. -# This will remove the Files entry from the Quick Index and from the -# Folder Tree View (if specified). The default is YES. - -SHOW_FILES = YES - -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the -# Namespaces page. -# This will remove the Namespaces entry from the Quick Index -# and from the Folder Tree View (if specified). The default is YES. - -SHOW_NAMESPACES = NO - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from -# the version control system). Doxygen will invoke the program by executing (via -# popen()) the command , where is the value of -# the FILE_VERSION_FILTER tag, and is the name of an input file -# provided by doxygen. Whatever the program writes to standard output -# is used as the file version. See the manual for examples. - -FILE_VERSION_FILTER = - -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed -# by doxygen. The layout file controls the global structure of the generated -# output files in an output format independent way. To create the layout file -# that represents doxygen's defaults, run doxygen with the -l option. -# You can optionally specify a file name after the option, if omitted -# DoxygenLayout.xml will be used as the name of the layout file. - -LAYOUT_FILE = - -# The CITE_BIB_FILES tag can be used to specify one or more bib files -# containing the references data. This must be a list of .bib files. The -# .bib extension is automatically appended if omitted. Using this command -# requires the bibtex tool to be installed. See also -# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style -# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this -# feature you need bibtex and perl available in the search path. Do not use -# file names with spaces, bibtex cannot handle them. - -CITE_BIB_FILES = - -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. - -QUIET = YES - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. - -WARNINGS = YES - -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. - -WARN_IF_UNDOCUMENTED = YES - -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that -# don't exist or using markup commands wrongly. - -WARN_IF_DOC_ERROR = YES - -# The WARN_NO_PARAMDOC option can be enabled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of -# documentation. - -WARN_NO_PARAMDOC = YES - -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could -# be obtained via FILE_VERSION_FILTER) - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. - -WARN_LOGFILE = @GLFW_BINARY_DIR@/docs/warnings.txt - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. - -INPUT = @GLFW_INTERNAL_DOCS@ \ - @GLFW_SOURCE_DIR@/include/GLFW/glfw3.h \ - @GLFW_SOURCE_DIR@/include/GLFW/glfw3native.h \ - @GLFW_SOURCE_DIR@/docs/main.dox \ - @GLFW_SOURCE_DIR@/docs/news.dox \ - @GLFW_SOURCE_DIR@/docs/moving.dox \ - @GLFW_SOURCE_DIR@/docs/quick.dox \ - @GLFW_SOURCE_DIR@/docs/compile.dox \ - @GLFW_SOURCE_DIR@/docs/build.dox \ - @GLFW_SOURCE_DIR@/docs/intro.dox \ - @GLFW_SOURCE_DIR@/docs/context.dox \ - @GLFW_SOURCE_DIR@/docs/monitor.dox \ - @GLFW_SOURCE_DIR@/docs/window.dox \ - @GLFW_SOURCE_DIR@/docs/input.dox \ - @GLFW_SOURCE_DIR@/docs/rift.dox \ - @GLFW_SOURCE_DIR@/docs/compat.dox - -# This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is -# also the default input encoding. Doxygen uses libiconv (or the iconv built -# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for -# the list of possible encodings. - -INPUT_ENCODING = UTF-8 - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh -# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py -# *.f90 *.f *.for *.vhd *.vhdl - -FILE_PATTERNS = *.h *.dox - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - -RECURSIVE = NO - -# The EXCLUDE tag can be used to specify files and/or directories that should be -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. -# Note that relative paths are relative to the directory from which doxygen is -# run. - -EXCLUDE = - -# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or -# directories that are symbolic links (a Unix file system feature) are excluded -# from the input. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. Note that the wildcards are matched -# against the file with absolute path, so to exclude all test directories -# for example use the pattern */test/* - -EXCLUDE_PATTERNS = - -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test - -EXCLUDE_SYMBOLS = APIENTRY GLFWAPI - -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). - -EXAMPLE_PATH = @GLFW_SOURCE_DIR@/examples - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -EXAMPLE_PATTERNS = - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. -# Possible values are YES and NO. If left blank NO is used. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command , where -# is the value of the INPUT_FILTER tag, and is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. -# If FILTER_PATTERNS is specified, this tag will be -# ignored. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. -# Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. -# The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty or if -# non of the patterns match the file name, INPUT_FILTER is applied. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse (i.e. when SOURCE_BROWSER is set to YES). - -FILTER_SOURCE_FILES = NO - -# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file -# pattern. A pattern will override the setting for FILTER_PATTERN (if any) -# and it is also possible to disable source filtering for a specific pattern -# using *.ext= (so without naming a filter). This option only has effect when -# FILTER_SOURCE_FILES is enabled. - -FILTER_SOURCE_PATTERNS = - -# If the USE_MD_FILE_AS_MAINPAGE tag refers to the name of a markdown file that -# is part of the input, its contents will be placed on the main page (index.html). -# This can be useful if you have a project on for instance GitHub and want reuse -# the introduction page also for the doxygen output. - -USE_MDFILE_AS_MAINPAGE = - -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also -# VERBATIM_HEADERS is set to NO. - -SOURCE_BROWSER = NO - -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C, C++ and Fortran comments will always remain visible. - -STRIP_CODE_COMMENTS = YES - -# If the REFERENCED_BY_RELATION tag is set to YES -# then for each documented function all documented -# functions referencing it will be listed. - -REFERENCED_BY_RELATION = NO - -# If the REFERENCES_RELATION tag is set to YES -# then for each documented function all documented entities -# called/used by that function will be listed. - -REFERENCES_RELATION = NO - -# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) -# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from -# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will -# link to the source code. -# Otherwise they will link to the documentation. - -REFERENCES_LINK_SOURCE = YES - -# If the USE_HTAGS tag is set to YES then the references to source code -# will point to the HTML generated by the htags(1) tool instead of doxygen -# built-in source browser. The htags tool is part of GNU's global source -# tagging system (see http://www.gnu.org/software/global/global.html). You -# will need version 4.8.6 or higher. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. - -VERBATIM_HEADERS = YES - -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. - -ALPHABETICAL_INDEX = YES - -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns -# in which this list will be split (can be a number in the range [1..20]) - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. - -IGNORE_PREFIX = glfw GLFW_ - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. - -HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. Note that when using a custom header you are responsible -# for the proper inclusion of any scripts and style sheets that doxygen -# needs, which is dependent on the configuration options used. -# It is advised to generate a default header using "doxygen -w html -# header.html footer.html stylesheet.css YourConfigFile" and then modify -# that header. Note that the header is subject to change so you typically -# have to redo this when upgrading to a newer version of doxygen or when -# changing the value of configuration settings such as GENERATE_TREEVIEW! - -HTML_HEADER = @GLFW_SOURCE_DIR@/docs/header.html - -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. - -HTML_FOOTER = @GLFW_SOURCE_DIR@/docs/footer.html - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If left blank doxygen will -# generate a default style sheet. Note that it is recommended to use -# HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this -# tag will in the future become obsolete. - -HTML_STYLESHEET = - -# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional -# user-defined cascading style sheet that is included after the standard -# style sheets created by doxygen. Using this option one can overrule -# certain style aspects. This is preferred over using HTML_STYLESHEET -# since it does not replace the standard style sheet and is therefor more -# robust against future updates. Doxygen will copy the style sheet file to -# the output directory. - -HTML_EXTRA_STYLESHEET = @GLFW_SOURCE_DIR@/docs/extra.css - -# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or -# other source files which should be copied to the HTML output directory. Note -# that these files will be copied to the base HTML output directory. Use the -# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these -# files. In the HTML_STYLESHEET file, use the file name only. Also note that -# the files will be copied as-is; there are no commands or markers available. - -HTML_EXTRA_FILES = @GLFW_SOURCE_DIR@/docs/spaces.svg - -# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. -# Doxygen will adjust the colors in the style sheet and background images -# according to this color. Hue is specified as an angle on a colorwheel, -# see http://en.wikipedia.org/wiki/Hue for more information. -# For instance the value 0 represents red, 60 is yellow, 120 is green, -# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. -# The allowed range is 0 to 359. - -HTML_COLORSTYLE_HUE = 220 - -# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of -# the colors in the HTML output. For a value of 0 the output will use -# grayscales only. A value of 255 will produce the most vivid colors. - -HTML_COLORSTYLE_SAT = 100 - -# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to -# the luminance component of the colors in the HTML output. Values below -# 100 gradually make the output lighter, whereas values above 100 make -# the output darker. The value divided by 100 is the actual gamma applied, -# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, -# and 100 does not change the gamma. - -HTML_COLORSTYLE_GAMMA = 80 - -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting -# this to NO can help when comparing the output of multiple runs. - -HTML_TIMESTAMP = YES - -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. - -HTML_DYNAMIC_SECTIONS = NO - -# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of -# entries shown in the various tree structured indices initially; the user -# can expand and collapse entries dynamically later on. Doxygen will expand -# the tree to such a level that at most the specified number of entries are -# visible (unless a fully collapsed tree already exceeds this amount). -# So setting the number of entries 1 will produce a full collapsed tree by -# default. 0 is a special value representing an infinite number of entries -# and will result in a full expanded tree by default. - -HTML_INDEX_NUM_ENTRIES = 100 - -# If the GENERATE_DOCSET tag is set to YES, additional index files -# will be generated that can be used as input for Apple's Xcode 3 -# integrated development environment, introduced with OSX 10.5 (Leopard). -# To create a documentation set, doxygen will generate a Makefile in the -# HTML output directory. Running make will produce the docset in that -# directory and running "make install" will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find -# it at startup. -# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html -# for more information. - -GENERATE_DOCSET = NO - -# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the -# feed. A documentation feed provides an umbrella under which multiple -# documentation sets from a single provider (such as a company or product suite) -# can be grouped. - -DOCSET_FEEDNAME = "Doxygen generated docs" - -# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that -# should uniquely identify the documentation set bundle. This should be a -# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen -# will append .docset to the name. - -DOCSET_BUNDLE_ID = org.doxygen.Project - -# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely -# identify the documentation publisher. This should be a reverse domain-name -# style string, e.g. com.mycompany.MyDocSet.documentation. - -DOCSET_PUBLISHER_ID = org.doxygen.Publisher - -# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. - -DOCSET_PUBLISHER_NAME = Publisher - -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) -# of the generated HTML documentation. - -GENERATE_HTMLHELP = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be -# written to the html output directory. - -CHM_FILE = - -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run -# the HTML help compiler on the generated index.hhp. - -HHC_LOCATION = - -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). - -GENERATE_CHI = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING -# is used to encode HtmlHelp index (hhk), content (hhc) and project file -# content. - -CHM_INDEX_ENCODING = - -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the HTML help documentation and to the tree view. - -TOC_EXPAND = NO - -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and -# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated -# that can be used as input for Qt's qhelpgenerator to generate a -# Qt Compressed Help (.qch) of the generated HTML documentation. - -GENERATE_QHP = NO - -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can -# be used to specify the file name of the resulting .qch file. -# The path specified is relative to the HTML output folder. - -QCH_FILE = - -# The QHP_NAMESPACE tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#namespace - -QHP_NAMESPACE = org.doxygen.Project - -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#virtual-folders - -QHP_VIRTUAL_FOLDER = doc - -# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to -# add. For more information please see -# http://doc.trolltech.com/qthelpproject.html#custom-filters - -QHP_CUST_FILTER_NAME = - -# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the -# custom filter to add. For more information please see -# -# Qt Help Project / Custom Filters. - -QHP_CUST_FILTER_ATTRS = - -# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this -# project's -# filter section matches. -# -# Qt Help Project / Filter Attributes. - -QHP_SECT_FILTER_ATTRS = - -# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can -# be used to specify the location of Qt's qhelpgenerator. -# If non-empty doxygen will try to run qhelpgenerator on the generated -# .qhp file. - -QHG_LOCATION = - -# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files -# will be generated, which together with the HTML files, form an Eclipse help -# plugin. To install this plugin and make it available under the help contents -# menu in Eclipse, the contents of the directory containing the HTML and XML -# files needs to be copied into the plugins directory of eclipse. The name of -# the directory within the plugins directory should be the same as -# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before -# the help appears. - -GENERATE_ECLIPSEHELP = NO - -# A unique identifier for the eclipse help plugin. When installing the plugin -# the directory name containing the HTML and XML files should also have -# this name. - -ECLIPSE_DOC_ID = org.doxygen.Project - -# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) -# at top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. Since the tabs have the same information as the -# navigation tree you can set this option to NO if you already set -# GENERATE_TREEVIEW to YES. - -DISABLE_INDEX = NO - -# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index -# structure should be generated to display hierarchical information. -# If the tag value is set to YES, a side panel will be generated -# containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). -# Windows users are probably better off using the HTML help feature. -# Since the tree basically has the same information as the tab index you -# could consider to set DISABLE_INDEX to NO when enabling this option. - -GENERATE_TREEVIEW = NO - -# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values -# (range [0,1..20]) that doxygen will group on one line in the generated HTML -# documentation. Note that a value of 0 will completely suppress the enum -# values from appearing in the overview section. - -ENUM_VALUES_PER_LINE = 4 - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. - -TREEVIEW_WIDTH = 300 - -# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open -# links to external symbols imported via tag files in a separate window. - -EXT_LINKS_IN_WINDOW = NO - -# Use this tag to change the font size of Latex formulas included -# as images in the HTML documentation. The default is 10. Note that -# when you change the font size after a successful doxygen run you need -# to manually remove any form_*.png images from the HTML output directory -# to force them to be regenerated. - -FORMULA_FONTSIZE = 10 - -# Use the FORMULA_TRANPARENT tag to determine whether or not the images -# generated for formulas are transparent PNGs. Transparent PNGs are -# not supported properly for IE 6.0, but are supported on all modern browsers. -# Note that when changing this option you need to delete any form_*.png files -# in the HTML output before the changes have effect. - -FORMULA_TRANSPARENT = YES - -# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax -# (see http://www.mathjax.org) which uses client side Javascript for the -# rendering instead of using prerendered bitmaps. Use this if you do not -# have LaTeX installed or if you want to formulas look prettier in the HTML -# output. When enabled you may also need to install MathJax separately and -# configure the path to it using the MATHJAX_RELPATH option. - -USE_MATHJAX = NO - -# When MathJax is enabled you can set the default output format to be used for -# thA MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and -# SVG. The default value is HTML-CSS, which is slower, but has the best -# compatibility. - -MATHJAX_FORMAT = HTML-CSS - -# When MathJax is enabled you need to specify the location relative to the -# HTML output directory using the MATHJAX_RELPATH option. The destination -# directory should contain the MathJax.js script. For instance, if the mathjax -# directory is located at the same level as the HTML output directory, then -# MATHJAX_RELPATH should be ../mathjax. The default value points to -# the MathJax Content Delivery Network so you can quickly see the result without -# installing MathJax. -# However, it is strongly recommended to install a local -# copy of MathJax from http://www.mathjax.org before deployment. - -MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest - -# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension -# names that should be enabled during MathJax rendering. - -MATHJAX_EXTENSIONS = - -# When the SEARCHENGINE tag is enabled doxygen will generate a search box -# for the HTML output. The underlying search engine uses javascript -# and DHTML and should work on any modern browser. Note that when using -# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets -# (GENERATE_DOCSET) there is already a search function so this one should -# typically be disabled. For large projects the javascript based search engine -# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. - -SEARCHENGINE = YES - -# When the SERVER_BASED_SEARCH tag is enabled the search engine will be -# implemented using a web server instead of a web client using Javascript. -# There are two flavours of web server based search depending on the -# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for -# searching and an index file used by the script. When EXTERNAL_SEARCH is -# enabled the indexing and searching needs to be provided by external tools. -# See the manual for details. - -SERVER_BASED_SEARCH = NO - -# When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP -# script for searching. Instead the search results are written to an XML file -# which needs to be processed by an external indexer. Doxygen will invoke an -# external search engine pointed to by the SEARCHENGINE_URL option to obtain -# the search results. Doxygen ships with an example indexer (doxyindexer) and -# search engine (doxysearch.cgi) which are based on the open source search engine -# library Xapian. See the manual for configuration details. - -EXTERNAL_SEARCH = NO - -# The SEARCHENGINE_URL should point to a search engine hosted by a web server -# which will returned the search results when EXTERNAL_SEARCH is enabled. -# Doxygen ships with an example search engine (doxysearch) which is based on -# the open source search engine library Xapian. See the manual for configuration -# details. - -SEARCHENGINE_URL = - -# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed -# search data is written to a file for indexing by an external tool. With the -# SEARCHDATA_FILE tag the name of this file can be specified. - -SEARCHDATA_FILE = searchdata.xml - -# When SERVER_BASED_SEARCH AND EXTERNAL_SEARCH are both enabled the -# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is -# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple -# projects and redirect the results back to the right project. - -EXTERNAL_SEARCH_ID = - -# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen -# projects other than the one defined by this configuration file, but that are -# all added to the same external search index. Each project needs to have a -# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id -# of to a relative location where the documentation can be found. -# The format is: EXTRA_SEARCH_MAPPINGS = id1=loc1 id2=loc2 ... - -EXTRA_SEARCH_MAPPINGS = - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will -# generate Latex output. - -GENERATE_LATEX = NO - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `latex' will be used as the default path. - -LATEX_OUTPUT = latex - -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be -# invoked. If left blank `latex' will be used as the default command name. -# Note that when enabling USE_PDFLATEX this option is only used for -# generating bitmaps for formulas in the HTML output, but not in the -# Makefile that is written to the output directory. - -LATEX_CMD_NAME = latex - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the -# default command name. - -MAKEINDEX_CMD_NAME = makeindex - -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, letter, legal and -# executive. If left blank a4wide will be used. - -PAPER_TYPE = a4 - -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX -# packages that should be included in the LaTeX output. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a -# standard header. Notice: only use this tag if you know what you are doing! - -LATEX_HEADER = - -# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for -# the generated latex document. The footer should contain everything after -# the last chapter. If it is left blank doxygen will generate a -# standard footer. Notice: only use this tag if you know what you are doing! - -LATEX_FOOTER = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references -# This makes the output suitable for online browsing using a pdf viewer. - -PDF_HYPERLINKS = YES - -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a -# higher quality PDF documentation. - -USE_PDFLATEX = YES - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. -# This option is also used when generating formulas in HTML. - -LATEX_BATCHMODE = NO - -# If LATEX_HIDE_INDICES is set to YES then doxygen will not -# include the index chapters (such as File Index, Compound Index, etc.) -# in the output. - -LATEX_HIDE_INDICES = NO - -# If LATEX_SOURCE_CODE is set to YES then doxygen will include -# source code with syntax highlighting in the LaTeX output. -# Note that which sources are shown also depends on other settings -# such as SOURCE_BROWSER. - -LATEX_SOURCE_CODE = NO - -# The LATEX_BIB_STYLE tag can be used to specify the style to use for the -# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See -# http://en.wikipedia.org/wiki/BibTeX for more info. - -LATEX_BIB_STYLE = plain - -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimized for Word 97 and may not look very pretty with -# other RTF readers or editors. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `rtf' will be used as the default path. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_RTF = NO - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. -# Note: wordpad (write) and others do not support links. - -RTF_HYPERLINKS = NO - -# Load style sheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assignments. You only have to provide -# replacements, missing definitions are set to their default value. - -RTF_STYLESHEET_FILE = - -# Set optional variables used in the generation of an rtf document. -# Syntax is similar to doxygen's config file. - -RTF_EXTENSIONS_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will -# generate man pages - -GENERATE_MAN = NO - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `man' will be used as the default path. - -MAN_OUTPUT = man - -# The MAN_EXTENSION tag determines the extension that is added to -# the generated man pages (default is the subroutine's section .3) - -MAN_EXTENSION = .3 - -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command -# would be unable to find the correct page. The default is NO. - -MAN_LINKS = NO - -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of -# the code including all documentation. - -GENERATE_XML = NO - -# The XML_OUTPUT tag is used to specify where the XML pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `xml' will be used as the default path. - -XML_OUTPUT = xml - -# If the XML_PROGRAMLISTING tag is set to YES Doxygen will -# dump the program listings (including syntax highlighting -# and cross-referencing information) to the XML output. Note that -# enabling this will significantly increase the size of the XML output. - -XML_PROGRAMLISTING = YES - -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- - -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental -# and incomplete at the moment. - -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- - -# If the GENERATE_PERLMOD tag is set to YES Doxygen will -# generate a Perl module file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the -# moment. - -GENERATE_PERLMOD = NO - -# If the PERLMOD_LATEX tag is set to YES Doxygen will generate -# the necessary Makefile rules, Perl scripts and LaTeX code to be able -# to generate PDF and DVI output from the Perl module output. - -PERLMOD_LATEX = NO - -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. -# This is useful -# if you want to understand what is going on. -# On the other hand, if this -# tag is set to NO the size of the Perl module output will be much smaller -# and Perl will parse it just the same. - -PERLMOD_PRETTY = YES - -# The names of the make variables in the generated doxyrules.make file -# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. -# This is useful so different doxyrules.make files included by the same -# Makefile don't overwrite each other's variables. - -PERLMOD_MAKEVAR_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include -# files. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled -# way by setting EXPAND_ONLY_PREDEF to YES. - -MACRO_EXPANSION = YES - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the -# PREDEFINED and EXPAND_AS_DEFINED tags. - -EXPAND_ONLY_PREDEF = YES - -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# pointed to by INCLUDE_PATH will be searched when a #include is found. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by -# the preprocessor. - -INCLUDE_PATH = - -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will -# be used. - -INCLUDE_FILE_PATTERNS = - -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. To prevent a macro definition from being -# undefined via #undef or recursively expanded use the := operator -# instead of the = operator. - -PREDEFINED = GLFWAPI= \ - GLFW_EXPOSE_NATIVE_WIN32 \ - GLFW_EXPOSE_NATIVE_WGL \ - GLFW_EXPOSE_NATIVE_X11 \ - GLFW_EXPOSE_NATIVE_GLX \ - GLFW_EXPOSE_NATIVE_COCOA \ - GLFW_EXPOSE_NATIVE_NSGL \ - GLFW_EXPOSE_NATIVE_EGL - -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition that -# overrules the definition found in the source code. - -EXPAND_AS_DEFINED = - -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all references to function-like macros -# that are alone on a line, have an all uppercase name, and do not end with a -# semicolon, because these will confuse the parser if not removed. - -SKIP_FUNCTION_MACROS = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES option can be used to specify one or more tagfiles. For each -# tag file the location of the external documentation should be added. The -# format of a tag file without this location is as follows: -# -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths -# or URLs. Note that each tag file must have a unique name (where the name does -# NOT include the path). If a tag file is not located in the directory in which -# doxygen is run, you must also specify the path to the tagfile here. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create -# a tag file that is based on the input files it reads. - -GENERATE_TAGFILE = - -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes -# will be listed. - -ALLEXTERNALS = NO - -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will -# be listed. - -EXTERNAL_GROUPS = YES - -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = /usr/bin/perl - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base -# or super classes. Setting the tag to NO turns the diagrams off. Note that -# this option also works with HAVE_DOT disabled, but it is recommended to -# install and use dot, since it yields more powerful graphs. - -CLASS_DIAGRAMS = YES - -# You can define message sequence charts within doxygen comments using the \msc -# command. Doxygen will then run the mscgen tool (see -# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the -# documentation. The MSCGEN_PATH tag allows you to specify the directory where -# the mscgen tool resides. If left empty the tool is assumed to be found in the -# default search path. - -MSCGEN_PATH = - -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented -# or is not a class. - -HIDE_UNDOC_RELATIONS = YES - -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section -# have no effect if this option is set to NO (the default) - -HAVE_DOT = NO - -# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is -# allowed to run in parallel. When set to 0 (the default) doxygen will -# base this on the number of processors available in the system. You can set it -# explicitly to a value larger than 0 to get control over the balance -# between CPU load and processing speed. - -DOT_NUM_THREADS = 0 - -# By default doxygen will use the Helvetica font for all dot files that -# doxygen generates. When you want a differently looking font you can specify -# the font name using DOT_FONTNAME. You need to make sure dot is able to find -# the font, which can be done by putting it in a standard location or by setting -# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the -# directory containing the font. - -DOT_FONTNAME = Helvetica - -# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. -# The default size is 10pt. - -DOT_FONTSIZE = 10 - -# By default doxygen will tell dot to use the Helvetica font. -# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to -# set the path where dot can find it. - -DOT_FONTPATH = - -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the -# CLASS_DIAGRAMS tag to NO. - -CLASS_GRAPH = YES - -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and -# class references variables) of the class with other documented classes. - -COLLABORATION_GRAPH = YES - -# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for groups, showing the direct groups dependencies - -GROUP_GRAPHS = YES - -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling -# Language. - -UML_LOOK = NO - -# If the UML_LOOK tag is enabled, the fields and methods are shown inside -# the class node. If there are many fields or methods and many nodes the -# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS -# threshold limits the number of items for each type to make the size more -# managable. Set this to 0 for no limit. Note that the threshold may be -# exceeded by 50% before the limit is enforced. - -UML_LIMIT_NUM_FIELDS = 10 - -# If set to YES, the inheritance and collaboration graphs will show the -# relations between templates and their instances. - -TEMPLATE_RELATIONS = NO - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with -# other documented files. - -INCLUDE_GRAPH = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or -# indirectly include this file. - -INCLUDED_BY_GRAPH = YES - -# If the CALL_GRAPH and HAVE_DOT options are set to YES then -# doxygen will generate a call dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable call graphs -# for selected functions only using the \callgraph command. - -CALL_GRAPH = NO - -# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then -# doxygen will generate a caller dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable caller -# graphs for selected functions only using the \callergraph command. - -CALLER_GRAPH = NO - -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will generate a graphical hierarchy of all classes instead of a textual one. - -GRAPHICAL_HIERARCHY = YES - -# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES -# then doxygen will show the dependencies a directory has on other directories -# in a graphical way. The dependency relations are determined by the #include -# relations between the files in the directories. - -DIRECTORY_GRAPH = YES - -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are svg, png, jpg, or gif. -# If left blank png will be used. If you choose svg you need to set -# HTML_FILE_EXTENSION to xhtml in order to make the SVG files -# visible in IE 9+ (other browsers do not have this requirement). - -DOT_IMAGE_FORMAT = png - -# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to -# enable generation of interactive SVG images that allow zooming and panning. -# Note that this requires a modern browser other than Internet Explorer. -# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you -# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files -# visible. Older versions of IE do not have SVG support. - -INTERACTIVE_SVG = NO - -# The tag DOT_PATH can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found in the path. - -DOT_PATH = - -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the -# \dotfile command). - -DOTFILE_DIRS = - -# The MSCFILE_DIRS tag can be used to specify one or more directories that -# contain msc files that are included in the documentation (see the -# \mscfile command). - -MSCFILE_DIRS = - -# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of -# nodes that will be shown in the graph. If the number of nodes in a graph -# becomes larger than this value, doxygen will truncate the graph, which is -# visualized by representing a node as a red box. Note that doxygen if the -# number of direct children of the root node in a graph is already larger than -# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note -# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. - -DOT_GRAPH_MAX_NODES = 50 - -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the -# graphs generated by dot. A depth value of 3 means that only nodes reachable -# from the root by following a path via at most 3 edges will be shown. Nodes -# that lay further from the root node will be omitted. Note that setting this -# option to 1 or 2 may greatly reduce the computation time needed for large -# code bases. Also note that the size of a graph can be further restricted by -# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. - -MAX_DOT_GRAPH_DEPTH = 0 - -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, because dot on Windows does not -# seem to support this out of the box. Warning: Depending on the platform used, -# enabling this option may lead to badly anti-aliased labels on the edges of -# a graph (i.e. they become hard to read). - -DOT_TRANSPARENT = NO - -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) -# support this, this feature is disabled by default. - -DOT_MULTI_TARGETS = NO - -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and -# arrows in the dot generated graphs. - -GENERATE_LEGEND = YES - -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermediate dot files that are used to generate -# the various graphs. - -DOT_CLEANUP = YES diff --git a/examples/common/glfw/docs/DoxygenLayout.xml b/examples/common/glfw/docs/DoxygenLayout.xml deleted file mode 100644 index 7917f91e..00000000 --- a/examples/common/glfw/docs/DoxygenLayout.xml +++ /dev/null @@ -1,188 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/common/glfw/docs/build.dox b/examples/common/glfw/docs/build.dox deleted file mode 100644 index 4ee79387..00000000 --- a/examples/common/glfw/docs/build.dox +++ /dev/null @@ -1,303 +0,0 @@ -/*! - -@page build Building applications - -@tableofcontents - -This is about compiling and linking applications that use GLFW. For information on -how to write such applications, start with the [introductory tutorial](@ref quick). -For information on how to compile the GLFW library itself, see the @ref compile -guide. - -This is not a tutorial on compilation or linking. It assumes basic -understanding of how to compile and link a C program as well as how to use the -specific compiler of your chosen development environment. The compilation -and linking process should be explained in your C programming material and in -the documentation for your development environment. - -@section build_include Including the GLFW header file - -In the source files of your application where you use OpenGL or GLFW, you should -include the GLFW header file, i.e.: - -@code -#include -@endcode - -The GLFW header declares the GLFW API and by default also includes the OpenGL -header of your development environment, which in turn defines all the constants, -types and function prototypes of the OpenGL API. - -The GLFW header also defines everything necessary for your OpenGL header to -function. For example, under Windows you are normally required to include -`windows.h` before the OpenGL header, which would pollute your code namespace -with the entire Win32 API. - -Instead, the GLFW header takes care of this for you, not by including -`windows.h`, but by duplicating only the very few necessary parts of it. It -does this only when needed, so if `windows.h` _is_ included, the GLFW header -does not try to redefine those symbols. The reverse is not true, i.e. -`windows.h` cannot cope if any of its symbols have already been defined. - -In other words: - - - Do _not_ include the OpenGL headers yourself, as GLFW does this for you - - Do _not_ include `windows.h` or other platform-specific headers unless you - plan on using those APIs directly - - If you _do_ need to include such headers, do it _before_ including - the GLFW header and it will handle this - -If you are using an OpenGL extension loading library such as -[glad](https://github.com/Dav1dde/glad), the extension loader header should -either be included _before_ the GLFW one, or the `GLFW_INCLUDE_NONE` macro -(described below) should be defined. - - -@subsection build_macros GLFW header option macros - -These macros may be defined before the inclusion of the GLFW header and affect -its behavior. - -`GLFW_DLL` is required on Windows when using the GLFW DLL, to tell the compiler -that the GLFW functions are defined in a DLL. - -The following macros control which OpenGL or OpenGL ES API header is included. - -`GLFW_INCLUDE_GLCOREARB` makes the GLFW header include the modern -`GL/glcorearb.h` header (`OpenGL/gl3.h` on OS X) instead of the regular OpenGL -header. - -`GLFW_INCLUDE_ES1` makes the GLFW header include the OpenGL ES 1.x `GLES/gl.h` -header instead of the regular OpenGL header. - -`GLFW_INCLUDE_ES2` makes the GLFW header include the OpenGL ES 2.0 `GLES2/gl2.h` -header instead of the regular OpenGL header. - -`GLFW_INCLUDE_ES3` makes the GLFW header include the OpenGL ES 3.0 `GLES3/gl3.h` -header instead of the regular OpenGL header. - -`GLFW_INCLUDE_ES31` makes the GLFW header include the OpenGL ES 3.1 `GLES3/gl31.h` -header instead of the regular OpenGL header. - -`GLFW_INCLUDE_NONE` makes the GLFW header not include any OpenGL or OpenGL ES API -header. This is useful in combination with an extension loading library. - -If none of the above inclusion macros are defined, the standard OpenGL `GL/gl.h` -header (`OpenGL/gl.h` on OS X) is included. - -`GLFW_INCLUDE_GLEXT` makes the GLFW header include the appropriate extension -header for the OpenGL or OpenGL ES header selected above after and _in addition -to_ that header. - -`GLFW_INCLUDE_GLU` makes the header include the GLU header _in addition to_ the -header selected above. This should only be used with the standard OpenGL header -and only for legacy code. GLU has been deprecated and should not be used in new -code. - -@note GLFW does not provide any of the API headers mentioned above. They must -be provided by your development environment or your OpenGL or OpenGL ES SDK. - - -@section build_link Link with the right libraries - -GLFW is essentially a wrapper of various platform-specific APIs and therefore -needs to link against many different system libraries. If you are using GLFW as -a shared library / dynamic library / DLL then it takes care of these links. -However, if you are using GLFW as a static library then your executable will -need to link against these libraries. - -On Windows and OS X, the list of system libraries is static and can be -hard-coded into your build environment. See the section for your development -environment below. On Linux and other Unix-like operating systems, the list -varies but can be retrieved in various ways as described below. - -A good general introduction to linking is -[Beginner's Guide to Linkers](http://www.lurklurk.org/linkers/linkers.html) by -David Drysdale. - - -@subsection build_link_win32 With MinGW or Visual C++ on Windows - -The static version of the GLFW library is named `glfw3`. When using this -version, it is also necessary to link with some libraries that GLFW uses. - -When linking an application under Windows that uses the static version of GLFW, -you must link with `opengl32`. On some versions of MinGW, you must also -explicitly link with `gdi32`, while other versions of MinGW include it in the -set of default libraries along with other dependencies like `user32` and -`kernel32`. If you are using GLU, you must also link with `glu32`. - -The link library for the GLFW DLL is named `glfw3dll`. When compiling an -application that uses the DLL version of GLFW, you need to define the `GLFW_DLL` -macro _before_ any inclusion of the GLFW header. This can be done either with -a compiler switch or by defining it in your source code. - -An application using the GLFW DLL does not need to link against any of its -dependencies, but you still have to link against `opengl32` if your application -uses OpenGL and `glu32` if it uses GLU. - - -@subsection build_link_cmake_source With CMake and GLFW source - -With just a few changes to your `CMakeLists.txt` you can have the GLFW source -tree built along with your application. - -Firstly, add the root directory of the GLFW source tree to your project. This -will add the `glfw` target and the necessary cache variables to your project. - -@code{.cmake} -add_subdirectory(path/to/glfw) -@endcode - -To be able to include the GLFW header from your code, you need to tell the -compiler where to find it. - -@code{.cmake} -include_directories(path/to/glfw/include) -@endcode - -Once GLFW has been added to the project, the `GLFW_LIBRARIES` cache variable -contains all link-time dependencies of GLFW as it is currently configured. To -link against GLFW, link against them and the `glfw` target. - -@code{.cmake} -target_link_libraries(myapp glfw ${GLFW_LIBRARIES}) -@endcode - -Note that `GLFW_LIBRARIES` does not include GLU, as GLFW does not use it. If -your application needs GLU, you can add it to the list of dependencies with the -`OPENGL_glu_LIBRARY` cache variable, which is implicitly created when the GLFW -CMake files look for OpenGL. - -@code{.cmake} -target_link_libraries(myapp glfw ${OPENGL_glu_LIBRARY} ${GLFW_LIBRARIES}) -@endcode - - -@subsection build_link_cmake_pkgconfig With CMake on Unix and installed GLFW binaries - -CMake can import settings from pkg-config, which GLFW supports. When you -installed GLFW, the pkg-config file `glfw3.pc` was installed along with it. - -First you need to find the PkgConfig package. If this fails, you may need to -install the pkg-config package for your distribution. - -@code{.cmake} -find_package(PkgConfig REQUIRED) -@endcode - -This creates the CMake commands to find pkg-config packages. Then you need to -find the GLFW package. - -@code{.cmake} -pkg_search_module(GLFW REQUIRED glfw3) -@endcode - -This creates the CMake variables you need to use GLFW. To be able to include -the GLFW header, you need to tell your compiler where it is. - -@code{.cmake} -include_directories(${GLFW_INCLUDE_DIRS}) -@endcode - -You also need to link against the correct libraries. If you are using the -shared library version of GLFW, use the `GLFW_LIBRARIES` variable. - -@code{.cmake} -target_link_libraries(simple ${GLFW_LIBRARIES}) -@endcode - -If you are using the static library version of GLFW, use the -`GLFW_STATIC_LIBRARIES` variable instead. - -@code{.cmake} -target_link_libraries(simple ${GLFW_STATIC_LIBRARIES}) -@endcode - - -@subsection build_link_pkgconfig With pkg-config on OS X or other Unix - -GLFW supports [pkg-config](http://www.freedesktop.org/wiki/Software/pkg-config/), -and the `glfw3.pc` pkf-config file is generated when the GLFW library is built -and is installed along with it. A pkg-config file describes all necessary -compile-time and link-time flags and dependencies needed to use a library. When -they are updated or if they differ between systems, you will get the correct -ones automatically. - -A typical compile and link command-line when using the static version of the -GLFW library may look like this: - -@code{.sh} -cc `pkg-config --cflags glfw3` -o myprog myprog.c `pkg-config --static --libs glfw3` -@endcode - -If you are using the shared version of the GLFW library, simply omit the -`--static` flag. - -@code{.sh} -cc `pkg-config --cflags glfw3` -o myprog myprog.c `pkg-config --libs glfw3` -@endcode - -You can also use the `glfw3.pc` file without installing it first, by using the -`PKG_CONFIG_PATH` environment variable. - -@code{.sh} -env PKG_CONFIG_PATH=path/to/glfw/src cc `pkg-config --cflags glfw3` -o myprog myprog.c `pkg-config --libs glfw3` -@endcode - -The dependencies do not include GLU, as GLFW does not need it. On OS X, GLU is -built into the OpenGL framework, so if you need GLU you don't need to do -anything extra. If you need GLU and are using Linux or BSD, you should add the -`glu` pkg-config module. - -@code{.sh} -cc `pkg-config --cflags glfw3 glu` -o myprog myprog.c `pkg-config --libs glfw3 glu` -@endcode - -If you are using the static version of the GLFW library, make sure you don't link statically against GLU. - -@code{.sh} -cc `pkg-config --cflags glfw3 glu` -o myprog myprog.c `pkg-config --static --libs glfw3` `pkg-config --libs glu` -@endcode - - -@subsection build_link_xcode With Xcode on OS X - -If you are using the dynamic library version of GLFW, simply add it to the -project dependencies. - -If you are using the static library version of GLFW, add it and the Cocoa, -OpenGL, IOKit, CoreVideo and Carbon frameworks to the project as dependencies. -They can all be found in `/System/Library/Frameworks`. - -@note GLFW needs the Carbon framework only to access the current keyboard layout -via the Text Input Source Services. This is one of the non-deprecated parts of -the Carbon API and the only way to access this information on OS X. - - -@subsection build_link_osx With command-line on OS X - -It is recommended that you use [pkg-config](@ref build_link_pkgconfig) when -building from the command line on OS X. That way you will get any new -dependencies added automatically. If you still wish to build manually, you need -to add the required frameworks and libraries to your command-line yourself using -the `-l` and `-framework` switches. - -If you are using the dynamic GLFW library, which is named `libglfw.3.dylib`, do: - -@code{.sh} -cc -o myprog myprog.c -lglfw -framework Cocoa -framework OpenGL -framework IOKit -framework CoreVideo -@endcode - -If you are using the static library, named `libglfw3.a`, substitute `-lglfw3` -for `-lglfw`. - -Note that you do not add the `.framework` extension to a framework when linking -against it from the command-line. - -The OpenGL framework contains both the OpenGL and GLU APIs, so there is nothing -special to do when using GLU. Also note that even though your machine may have -`libGL`-style OpenGL libraries, they are for use with the X Window System and -will _not_ work with the OS X native version of GLFW. - -*/ diff --git a/examples/common/glfw/docs/compat.dox b/examples/common/glfw/docs/compat.dox deleted file mode 100644 index 7ff4ab04..00000000 --- a/examples/common/glfw/docs/compat.dox +++ /dev/null @@ -1,179 +0,0 @@ -/*! - -@page compat Standards conformance - -@tableofcontents - -This guide describes the various API extensions used by this version of GLFW. -It lists what are essentially implementation details, but which are nonetheless -vital knowledge for developers intending to deploy their applications on a wide -range of machines. - -The information in this guide is not a part of GLFW API, but merely -preconditions for some parts of the library to function on a given machine. Any -part of this information may change in future versions of GLFW and that will not -be considered a breaking API change. - - -@section compat_x11 X11 extensions, protocols and IPC standards - -As GLFW uses Xlib directly, without any intervening toolkit -library, it has sole responsibility for interacting well with the many and -varied window managers in use on Unix-like systems. In order for applications -and window managers to work well together, a number of standards and -conventions have been developed that regulate behavior outside the scope of the -X11 API; most importantly the -[Inter-Client Communication Conventions Manual](http://www.tronche.com/gui/x/icccm/) -(ICCCM) and -[Extended Window Manager Hints](http://standards.freedesktop.org/wm-spec/wm-spec-latest.html) -(EWMH) standards. - -GLFW uses the `_MOTIF_WM_HINTS` window property to support borderless windows. -If the running window manager does not support this property, the -`GLFW_DECORATED` hint will have no effect. - -GLFW uses the ICCCM `WM_DELETE_WINDOW` protocol to intercept the user -attempting to close the GLFW window. If the running window manager does not -support this protocol, the close callback will never be called. - -GLFW uses the EWMH `_NET_WM_PING` protocol, allowing the window manager notify -the user when the application has stopped responding, i.e. when it has ceased to -process events. If the running window manager does not support this protocol, -the user will not be notified if the application locks up. - -GLFW uses the EWMH `_NET_WM_STATE_FULLSCREEN` window state to tell the window -manager to make the GLFW window full screen. If the running window manager does -not support this state, full screen windows may not work properly. GLFW has -a fallback code path in case this state is unavailable, but every window manager -behaves slightly differently in this regard. - -GLFW uses the EWMH `_NET_WM_BYPASS_COMPOSITOR` window property to tell a -compositing window manager to un-redirect full screen GLFW windows. If the -running window manager uses compositing but does not support this property then -additional copying may be performed for each buffer swap of full screen windows. - -GLFW uses the -[clipboard manager protocol](http://www.freedesktop.org/wiki/ClipboardManager/) -to push a clipboard string (i.e. selection) owned by a GLFW window about to be -destroyed to the clipboard manager. If there is no running clipboard manager, -the clipboard string will be unavailable once the window has been destroyed. - -GLFW uses the -[X drag-and-drop protocol](http://www.freedesktop.org/wiki/Specifications/XDND/) -to provide file drop events. If the application originating the drag does not -support this protocol, drag and drop will not work. - -GLFW uses the XInput 2 extension to provide sub-pixel cursor motion events. If -the running X server does not support this version of this extension, cursor -motion will be snapped to the pixel grid. - -GLFW uses the XRandR 1.3 extension to provide multi-monitor support. If the -running X server does not support this version of this extension, multi-monitor -support will not function and only a single, desktop-spanning monitor will be -reported. - -GLFW uses the XRandR 1.3 and Xf86vidmode extensions to provide gamma ramp -support. If the running X server does not support either or both of these -extensions, gamma ramp support will not function. - -GLFW uses the Xkb extension and detectable auto-repeat to provide keyboard -input. If the running X server does not support this extension, a non-Xkb -fallback path is used. - - -@section compat_glx GLX extensions - -The GLX API is the default API used to create OpenGL contexts on Unix-like -systems using the X Window System. - -GLFW uses the GLX 1.3 `GLXFBConfig` functions to enumerate and select framebuffer pixel -formats. If GLX 1.3 is not supported, @ref glfwInit will fail. - -GLFW uses the `GLX_MESA_swap_control,` `GLX_EXT_swap_control` and -`GLX_SGI_swap_control` extensions to provide vertical retrace synchronization -(or _vsync_), in that order of preference. Where none of these extension are -available, calling @ref glfwSwapInterval will have no effect. - -GLFW uses the `GLX_ARB_multisample` extension to create contexts with -multisampling anti-aliasing. Where this extension is unavailable, the -`GLFW_SAMPLES` hint will have no effect. - -GLFW uses the `GLX_ARB_create_context` extension when available, even when -creating OpenGL contexts of version 2.1 and below. Where this extension is -unavailable, the `GLFW_CONTEXT_VERSION_MAJOR` and `GLFW_CONTEXT_VERSION_MINOR` -hints will only be partially supported, the `GLFW_OPENGL_DEBUG_CONTEXT` hint -will have no effect, and setting the `GLFW_OPENGL_PROFILE` or -`GLFW_OPENGL_FORWARD_COMPAT` hints to `GL_TRUE` will cause @ref -glfwCreateWindow to fail. - -GLFW uses the `GLX_ARB_create_context_profile` extension to provide support for -context profiles. Where this extension is unavailable, setting the -`GLFW_OPENGL_PROFILE` hint to anything but `GLFW_OPENGL_ANY_PROFILE`, or setting -`GLFW_CLIENT_API` to anything but `GLFW_OPENGL_API` will cause @ref -glfwCreateWindow to fail. - -GLFW uses the `GLX_ARB_context_flush_control` extension to provide control over -whether a context is flushed when it is released (made non-current). Where this -extension is unavailable, the `GLFW_CONTEXT_RELEASE_BEHAVIOR` hint will have no -effect and the context will always be flushed when released. - -@section compat_wgl WGL extensions - -The WGL API is used to create OpenGL contexts on Microsoft Windows and other -implementations of the Win32 API, such as Wine. - -GLFW uses either the `WGL_EXT_extension_string` or the -`WGL_ARB_extension_string` extension to check for the presence of all other WGL -extensions listed below. If both are available, the EXT one is preferred. If -neither is available, no other extensions are used and many GLFW features -related to context creation will have no effect or cause errors when used. - -GLFW uses the `WGL_EXT_swap_control` extension to provide vertical retrace -synchronization (or _vsync_). Where this extension is unavailable, calling @ref -glfwSwapInterval will have no effect. - -GLFW uses the `WGL_ARB_pixel_format` and `WGL_ARB_multisample` extensions to -create contexts with multisampling anti-aliasing. Where these extensions are -unavailable, the `GLFW_SAMPLES` hint will have no effect. - -GLFW uses the `WGL_ARB_create_context` extension when available, even when -creating OpenGL contexts of version 2.1 and below. Where this extension is -unavailable, the `GLFW_CONTEXT_VERSION_MAJOR` and `GLFW_CONTEXT_VERSION_MINOR` -hints will only be partially supported, the `GLFW_OPENGL_DEBUG_CONTEXT` hint -will have no effect, and setting the `GLFW_OPENGL_PROFILE` or -`GLFW_OPENGL_FORWARD_COMPAT` hints to `GL_TRUE` will cause @ref -glfwCreateWindow to fail. - -GLFW uses the `WGL_ARB_create_context_profile` extension to provide support for -context profiles. Where this extension is unavailable, setting the -`GLFW_OPENGL_PROFILE` hint to anything but `GLFW_OPENGL_ANY_PROFILE` will cause -@ref glfwCreateWindow to fail. - -GLFW uses the `WGL_ARB_context_flush_control` extension to provide control over -whether a context is flushed when it is released (made non-current). Where this -extension is unavailable, the `GLFW_CONTEXT_RELEASE_BEHAVIOR` hint will have no -effect and the context will always be flushed when released. - -@section compat_osx OpenGL 3.2 and later on OS X - -Support for OpenGL 3.2 and above was introduced with OS X 10.7 and even then -only forward-compatible, core profile contexts are supported. Support for -OpenGL 4.1 was introduced with OS X 10.9, also limited to forward-compatible, -core profile contexts. There is also still no mechanism for requesting debug -contexts. Versions of Mac OS X earlier than 10.7 support at most OpenGL -version 2.1. - -Because of this, on OS X 10.7 and later, the `GLFW_CONTEXT_VERSION_MAJOR` and -`GLFW_CONTEXT_VERSION_MINOR` hints will cause @ref glfwCreateWindow to fail if -given version 3.0 or 3.1, the `GLFW_OPENGL_FORWARD_COMPAT` hint must be set to -`GL_TRUE` and the `GLFW_OPENGL_PROFILE` hint must be set to -`GLFW_OPENGL_CORE_PROFILE` when creating OpenGL 3.2 and later contexts and the -`GLFW_OPENGL_DEBUG_CONTEXT` hint is ignored. - -Also, on Mac OS X 10.6 and below, the `GLFW_CONTEXT_VERSION_MAJOR` and -`GLFW_CONTEXT_VERSION_MINOR` hints will fail if given a version above 2.1, -setting the `GLFW_OPENGL_PROFILE` or `GLFW_OPENGL_FORWARD_COMPAT` hints to -a non-default value will cause @ref glfwCreateWindow to fail and the -`GLFW_OPENGL_DEBUG_CONTEXT` hint is ignored. - -*/ diff --git a/examples/common/glfw/docs/compile.dox b/examples/common/glfw/docs/compile.dox deleted file mode 100644 index c7b01e34..00000000 --- a/examples/common/glfw/docs/compile.dox +++ /dev/null @@ -1,315 +0,0 @@ -/*! - -@page compile Compiling GLFW - -@tableofcontents - -This is about compiling the GLFW library itself. For information on how to -build applications that use GLFW, see the @ref build guide. - - -@section compile_cmake Using CMake - -GLFW uses [CMake](http://www.cmake.org/) to generate project files or makefiles -for a particular development environment. If you are on a Unix-like system such -as Linux or FreeBSD or have a package system like Fink, MacPorts, Cygwin or -Homebrew, you can simply install its CMake package. If not, you can download -installers for Windows and OS X from the [CMake website](http://www.cmake.org/). - -@note CMake only generates project files or makefiles. It does not compile the -actual GLFW library. To compile GLFW, first generate these files and then use -them in your chosen development environment to compile the actual GLFW library. - - -@subsection compile_deps Dependencies - -Once you have installed CMake, make sure that all other dependencies are -available. On some platforms, GLFW needs a few additional packages to be -installed. See the section for your chosen platform and development environment -below. - - -@subsubsection compile_deps_msvc Dependencies for Visual C++ on Windows - -The Microsoft Platform SDK that is installed along with Visual C++ already -contains all the necessary headers, link libraries and tools except for CMake. -Move on to @ref compile_generate. - - -@subsubsection compile_deps_mingw Dependencies for MinGW or MinGW-w64 on Windows - -Both the MinGW and the MinGW-w64 packages already contain all the necessary -headers, link libraries and tools except for CMake. Move on to @ref -compile_generate. - - -@subsubsection compile_deps_mingw_cross Dependencies for MinGW or MinGW-w64 cross-compilation - -Both Cygwin and many Linux distributions have MinGW or MinGW-w64 packages. For -example, Cygwin has the `mingw64-i686-gcc` and `mingw64-x86_64-gcc` packages -for 32- and 64-bit version of MinGW-w64, while Debian GNU/Linux and derivatives -like Ubuntu have the `mingw-w64` package for both. - -GLFW has CMake toolchain files in the `CMake/` directory that allow for easy -cross-compilation of Windows binaries. To use these files you need to add a -special parameter when generating the project files or makefiles: - -@code{.sh} -cmake -DCMAKE_TOOLCHAIN_FILE= . -@endcode - -The exact toolchain file to use depends on the prefix used by the MinGW or -MinGW-w64 binaries on your system. You can usually see this in the /usr -directory. For example, both the Debian/Ubuntu and Cygwin MinGW-w64 packages -have `/usr/x86_64-w64-mingw32` for the 64-bit compilers, so the correct -invocation would be: - -@code{.sh} -cmake -DCMAKE_TOOLCHAIN_FILE=CMake/x86_64-w64-mingw32.cmake . -@endcode - -For more details see the article -[CMake Cross Compiling](http://www.paraview.org/Wiki/CMake_Cross_Compiling) on -the CMake wiki. - -Once you have this set up, move on to @ref compile_generate. - - -@subsubsection compile_deps_xcode Dependencies for Xcode on OS X - -Xcode comes with all necessary tools except for CMake. The required headers -and libraries are included in the core OS X frameworks. Xcode can be downloaded -from the Mac App Store or from the ADC Member Center. - -Once you have Xcode installed, move on to @ref compile_generate. - - -@subsubsection compile_deps_x11 Dependencies for Linux and X11 - -To compile GLFW for X11, you need to have the X11 and OpenGL header packages -installed, as well as the basic development tools like GCC and make. For -example, on Ubuntu and other distributions based on Debian GNU/Linux, you need -to install the `xorg-dev` and `libglu1-mesa-dev` packages. The former pulls in -all X.org header packages and the latter pulls in the Mesa OpenGL and GLU -packages. GLFW itself doesn't need or use GLU, but some of the examples do. -Note that using header files and libraries from Mesa during compilation -_will not_ tie your binaries to the Mesa implementation of OpenGL. - -Once you have installed the necessary packages, move on to @ref -compile_generate. - - -@subsection compile_generate Generating build files with CMake - -Once you have all necessary dependencies it is time to generate the project -files or makefiles for your development environment. CMake needs to know two -paths for this: the path to the _root_ directory of the GLFW source tree (i.e. -_not_ the `src` subdirectory) and the target path for the generated files and -compiled binaries. If these are the same, it is called an in-tree build, -otherwise it is called an out-of-tree build. - -One of several advantages of out-of-tree builds is that you can generate files -and compile for different development environments using a single source tree. - -@note This section is about generating the project files or makefiles necessary -to compile the GLFW library, not about compiling the actual library. - - -@subsubsection compile_generate_cli Generating files with the CMake command-line tool - -To make an in-tree build, enter the _root_ directory of the GLFW source tree -(i.e. _not_ the `src` subdirectory) and run CMake. The current directory is -used as target path, while the path provided as an argument is used to find the -source tree. - -@code{.sh} -cd -cmake . -@endcode - -To make an out-of-tree build, make another directory, enter it and run CMake -with the (relative or absolute) path to the root of the source tree as an -argument. - -@code{.sh} -cd -mkdir build -cd build -cmake .. -@endcode - -Once you have generated the project files or makefiles for your chosen -development environment, move on to @ref compile_compile. - - -@subsubsection compile_generate_gui Generating files with the CMake GUI - -If you are using the GUI version, choose the root of the GLFW source tree as -source location and the same directory or another, empty directory as the -destination for binaries. Choose _Configure_, change any options you wish to, -_Configure_ again to let the changes take effect and then _Generate_. - -Once you have generated the project files or makefiles for your chosen -development environment, move on to @ref compile_compile. - - -@subsection compile_compile Compiling the library - -You should now have all required dependencies and the project files or makefiles -necessary to compile GLFW. Go ahead and compile the actual GLFW library with -these files, as you would with any other project. - -Once the GLFW library is compiled, you are ready to build your applications, -linking it to the GLFW library. See the @ref build guide for more information. - - -@subsection compile_options CMake options - -The CMake files for GLFW provide a number of options, although not all are -available on all supported platforms. Some of these are de facto standards -among projects using CMake and so have no `GLFW_` prefix. - -If you are using the GUI version of CMake, these are listed and can be changed -from there. If you are using the command-line version, use the `ccmake` tool. -Some package systems like Ubuntu and other distributions based on Debian -GNU/Linux have this tool in a separate `cmake-curses-gui` package. - - -@subsubsection compile_options_shared Shared CMake options - -`BUILD_SHARED_LIBS` determines whether GLFW is built as a static -library or as a DLL / shared library / dynamic library. - -`LIB_SUFFIX` affects where the GLFW shared /dynamic library is installed. If it -is empty, it is installed to `${CMAKE_INSTALL_PREFIX}/lib`. If it is set to -`64`, it is installed to `${CMAKE_INSTALL_PREFIX}/lib64`. - -`GLFW_CLIENT_LIBRARY` determines which client API library to use. If set to -`opengl` the OpenGL library is used, if set to `glesv1` for the OpenGL ES 1.x -library is used, or if set to `glesv2` the OpenGL ES 2.0 library is used. The -selected library and its header files must be present on the system for this to -work. - -`GLFW_BUILD_EXAMPLES` determines whether the GLFW examples are built -along with the library. - -`GLFW_BUILD_TESTS` determines whether the GLFW test programs are -built along with the library. - -`GLFW_BUILD_DOCS` determines whether the GLFW documentation is built along with -the library. - - -@subsubsection compile_options_osx OS X specific CMake options - -`GLFW_USE_CHDIR` determines whether `glfwInit` changes the current -directory of bundled applications to the `Contents/Resources` directory. - -`GLFW_USE_MENUBAR` determines whether the first call to -`glfwCreateWindow` sets up a minimal menu bar. - -`GLFW_USE_RETINA` determines whether windows will use the full resolution of -Retina displays. - -`GLFW_BUILD_UNIVERSAL` determines whether to build Universal Binaries. - - -@subsubsection compile_options_win32 Windows specific CMake options - -`USE_MSVC_RUNTIME_LIBRARY_DLL` determines whether to use the DLL version or the -static library version of the Visual C++ runtime library. If set to `ON`, the -DLL version of the Visual C++ library is used. It is recommended to set this to -`ON`, as this keeps the executable smaller and benefits from security and bug -fix updates of the Visual C++ runtime. - -`GLFW_USE_DWM_SWAP_INTERVAL` determines whether the swap interval is set even -when DWM compositing is enabled. If this is `ON`, the swap interval is set even -if DWM is enabled. It is recommended to set this to `OFF`, as doing otherwise -can lead to severe jitter. - -`GLFW_USE_OPTIMUS_HPG` determines whether to export the `NvOptimusEnablement` -symbol, which forces the use of the high-performance GPU on Nvidia Optimus -systems. This symbol needs to be exported by the EXE to be detected by the -driver, so the override will not work if GLFW is built as a DLL. See _Enabling -High Performance Graphics Rendering on Optimus Systems_ for more details. - - -@subsubsection compile_options_egl EGL specific CMake options - -`GLFW_USE_EGL` determines whether to use EGL instead of the platform-specific -context creation API. Note that EGL is not yet provided on all supported -platforms. - - -@section compile_manual Compiling GLFW manually - -If you wish to compile GLFW without its CMake build environment then you will -have to do at least some of the platform detection yourself. GLFW needs -a number of configuration macros to be defined in order to know what it's being -compiled for and has many optional, platform-specific ones for various features. - -When building with CMake, the `glfw_config.h` configuration header is generated -based on the current platform and CMake options. The GLFW CMake environment -defines `_GLFW_USE_CONFIG_H`, which causes this header to be included by -`internal.h`. Without this macro, GLFW will expect the necessary configuration -macros to be defined on the command-line. - -Three macros _must_ be defined when compiling GLFW: one selecting the window -creation API, one selecting the context creation API and one client library. -Exactly one of each kind must be defined for GLFW to compile and link. - -The window creation API is used to create windows, handle input, monitors, gamma -ramps and clipboard. The options are: - - - `_GLFW_COCOA` to use the Cocoa frameworks - - `_GLFW_WIN32` to use the Win32 API - - `_GLFW_X11` to use the X Window System - - `_GLFW_WAYLAND` to use the Wayland API (experimental and incomplete) - - `_GLFW_MIR` to use the Mir API (experimental and incomplete) - -The context creation API is used to enumerate pixel formats / framebuffer -configurations and to create contexts. The options are: - - - `_GLFW_NSGL` to use the Cocoa OpenGL framework - - `_GLFW_WGL` to use the Win32 WGL API - - `_GLFW_GLX` to use the X11 GLX API - - `_GLFW_EGL` to use the EGL API - -Wayland and Mir both require the EGL backend. - -The client library is the one providing the OpenGL or OpenGL ES API, which is -used by GLFW to probe the created context. This is not the same thing as the -client API, as many desktop OpenGL client libraries now expose the OpenGL ES API -through extensions. The options are: - - - `_GLFW_USE_OPENGL` for the desktop OpenGL (opengl32.dll, libGL.so or - OpenGL.framework) - - `_GLFW_USE_GLESV1` for OpenGL ES 1.x (experimental) - - `_GLFW_USE_GLESV2` for OpenGL ES 2.x (experimental) - -Note that `_GLFW_USE_GLESV1` and `_GLFW_USE_GLESV2` may only be used with EGL, -as the other context creation APIs do not interface with OpenGL ES client -libraries. - -If you are building GLFW as a shared library / dynamic library / DLL then you -must also define `_GLFW_BUILD_DLL`. Otherwise, you may not define it. - -If you are using the X11 window creation API then you _must_ also select an entry -point retrieval mechanism. - - - `_GLFW_HAS_GLXGETPROCADDRESS` to use `glXGetProcAddress` (recommended) - - `_GLFW_HAS_GLXGETPROCADDRESSARB` to use `glXGetProcAddressARB` (legacy) - - `_GLFW_HAS_GLXGETPROCADDRESSEXT` to use `glXGetProcAddressEXT` (legacy) - - `_GLFW_HAS_DLOPEN` to do manual retrieval with `dlopen` (fallback) - -If you are using the Cocoa window creation API, the following options are -available: - - - `_GLFW_USE_CHDIR` to `chdir` to the `Resources` subdirectory of the - application bundle during @ref glfwInit (recommended) - - `_GLFW_USE_MENUBAR` to create and populate the menu bar when the first window - is created (recommended) - - `_GLFW_USE_RETINA` to have windows use the full resolution of Retina displays - (recommended) - -*/ diff --git a/examples/common/glfw/docs/context.dox b/examples/common/glfw/docs/context.dox deleted file mode 100644 index eaa754b8..00000000 --- a/examples/common/glfw/docs/context.dox +++ /dev/null @@ -1,329 +0,0 @@ -/*! - -@page context Context guide - -@tableofcontents - -This guide introduces the OpenGL and OpenGL ES context related functions of -GLFW. There are also guides for the other areas of the GLFW API. - - - @ref intro - - @ref window - - @ref monitor - - @ref input - - -@section context_object Context objects - -A window object encapsulates both a top-level window and an OpenGL or OpenGL ES -context. It is created with @ref glfwCreateWindow and destroyed with @ref -glfwDestroyWindow or @ref glfwTerminate. See @ref window_creation for more -information. - -As the window and context are inseparably linked, the window object also serves -as the context handle. - -To test the creation of various kinds of contexts and see their properties, run -the `glfwinfo` test program. - - -@subsection context_hints Context creation hints - -There are a number of hints, specified using @ref glfwWindowHint, related to -what kind of context is created. See -[context related hints](@ref window_hints_ctx) in the window guide. - - -@subsection context_sharing Context object sharing - -When creating a window and its OpenGL or OpenGL ES context with @ref -glfwCreateWindow, you can specify another window whose context the new one -should share its objects (textures, vertex and element buffers, etc.) with. - -@code -GLFWwindow* second_window = glfwCreateWindow(640, 480, "Second Window", NULL, first_window); -@endcode - -Object sharing is implemented by the operating system and graphics driver. On -platforms where it is possible to choose which types of objects are shared, GLFW -requests that all types are shared. - -See the relevant chapter of the [OpenGL](https://www.opengl.org/registry/) or -[OpenGL ES](http://www.khronos.org/opengles/) reference documents for more -information. The name and number of this chapter unfortunately varies between -versions and APIs, but has at times been named _Shared Objects and Multiple -Contexts_. - -GLFW comes with a simple object sharing test program called `sharing`. - - -@subsection context_offscreen Offscreen contexts - -GLFW doesn't support creating contexts without an associated window. However, -contexts with hidden windows can be created with the -[GLFW_VISIBLE](@ref window_hints_wnd) window hint. - -@code -glfwWindowHint(GLFW_VISIBLE, GL_FALSE); - -GLFWwindow* offscreen_context = glfwCreateWindow(640, 480, "", NULL, NULL); -@endcode - -The window never needs to be shown and its context can be used as a plain -offscreen context. Depending on the window manager, the size of a hidden -window's framebuffer may not be usable or modifiable, so framebuffer -objects are recommended for rendering with such contexts. - -__OS X:__ The first time a window is created the menu bar is populated with -common commands like Hide, Quit and About. This is not desirable for example -when writing a command-line only application. The menu bar setup can be -disabled with a [compile-time option](@ref compile_options_osx). - - -@section context_current Current context - -Before you can make OpenGL or OpenGL ES calls, you need to have a current -context of the correct type. A context can only be current for a single thread -at a time, and a thread can only have a single context current at a time. - -The context of a window is made current with @ref glfwMakeContextCurrent. - -@code -glfwMakeContextCurrent(window); -@endcode - -The window of the current context is returned by @ref glfwGetCurrentContext. - -@code -GLFWwindow* window = glfwGetCurrentContext(); -@endcode - -The following GLFW functions require a context to be current. Calling any these -functions without a current context will generate a @ref GLFW_NO_CURRENT_CONTEXT -error. - - - @ref glfwSwapInterval - - @ref glfwExtensionSupported - - @ref glfwGetProcAddress - - -@section context_swap Buffer swapping - -Buffer swapping is part of the window and framebuffer, not the context. See -@ref buffer_swap. - - -@section context_glext OpenGL and OpenGL ES extensions - -One of the benefits of OpenGL and OpenGL ES are their extensibility. -Hardware vendors may include extensions in their implementations that extend the -API before that functionality is included in a new version of the OpenGL or -OpenGL ES specification, and some extensions are never included and remain -as extensions until they become obsolete. - -An extension is defined by: - -- An extension name (e.g. `GL_ARB_debug_output`) -- New OpenGL tokens (e.g. `GL_DEBUG_SEVERITY_HIGH_ARB`) -- New OpenGL functions (e.g. `glGetDebugMessageLogARB`) - -Note the `ARB` affix, which stands for Architecture Review Board and is used -for official extensions. The extension above was created by the ARB, but there -are many different affixes, like `NV` for Nvidia and `AMD` for, well, AMD. Any -group may also use the generic `EXT` affix. Lists of extensions, together with -their specifications, can be found at the -[OpenGL Registry](http://www.opengl.org/registry/) and -[OpenGL ES Registry](https://www.khronos.org/registry/gles/). - - -@subsection context_glext_auto Loading extension with a loader library - -An extension loader library is the easiest and best way to access both OpenGL and -OpenGL ES extensions and modern versions of the core OpenGL or OpenGL ES APIs. -They will take care of all the details of declaring and loading everything you -need. One such library is [glad](https://github.com/Dav1dde/glad) and there are -several others. - -The following example will use glad but all extension loader libraries work -similarly. - -First you need to generate the source files using the glad Python script. This -example generates a loader for any version of OpenGL, which is the default for -both GLFW and glad, but loaders for OpenGL ES, as well as loaders for specific -API versions and extension sets can be generated. The generated files are -written to the `output` directory. - -@code{.sh} -python main.py --generator c --no-loader --out-path output -@endcode - -The `--no-loader` option is added because GLFW already provides a function for -loading OpenGL and OpenGL ES function pointers and glad can call this instead of -having to implement its own. There are several other command-line options as -well. See the glad documentation for details. - -Add the generated `output/src/glad.c`, `output/include/glad/glad.h` and -`output/include/KHR/khrplatform.h` files to your build. Then you need to -include the glad header file, which will replace the OpenGL header of your -development environment. By including the glad header before the GLFW header, -it suppresses the development environment's OpenGL or OpenGL ES header. - -@code -#include -#include -@endcode - -Finally you need to initialize glad once you have a suitable current context. - -@code -window = glfwCreateWindow(640, 480, "My Window", NULL, NULL); -if (!window) -{ - ... -} - -glfwMakeContextCurrent(window); - -gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); -@endcode - -Once glad has been loaded, you have access to all OpenGL core and extension -functions supported by both the context you created and the glad loader you -generated and you are ready to start rendering. - -You can specify a minimum required OpenGL or OpenGL ES version with -[context hints](@ref window_hints_ctx). If your needs are more complex, you can -check the actual OpenGL or OpenGL ES version with -[context attributes](@ref window_attribs_ctx), or you can check whether -a specific version is supported by the current context with the -`GLAD_GL_VERSION_x_x` booleans. - -@code -if (GLAD_GL_VERSION_3_2) -{ - // Call OpenGL 3.2+ specific code -} -@endcode - -To check whether a specific extension is supported, use the `GLAD_GL_xxx` -booleans. - -@code -if (GLAD_GL_ARB_debug_output) -{ - // Use GL_ARB_debug_output -} -@endcode - - -@subsection context_glext_manual Loading extensions manually - -__Do not use this technique__ unless it is absolutely necessary. An -[extension loader library](@ref context_glext_auto) will save you a ton of -tedious, repetitive, error prone work. - -To use a certain extension, you must first check whether the context supports -that extension and then, if it introduces new functions, retrieve the pointers -to those functions. GLFW provides @ref glfwExtensionSupported and @ref -glfwGetProcAddress for manual loading of extensions and new API functions. - -This section will demonstrate manual loading of OpenGL extensions. The loading -of OpenGL ES extensions is identical except for the name of the extension header. - - -@subsubsection context_glext_header The glext.h header - -The `glext.h` extension header is a continually updated file that defines the -interfaces for all OpenGL extensions. The latest version of this can always be -found at the [OpenGL Registry](http://www.opengl.org/registry/). There are also -extension headers for the various versions of OpenGL ES at the -[OpenGL ES Registry](https://www.khronos.org/registry/gles/). It it strongly -recommended that you use your own copy of the extension header, as the one -included in your development environment may be several years out of date and -may not include the extensions you wish to use. - -The header defines function pointer types for all functions of all extensions it -supports. These have names like `PFNGLGETDEBUGMESSAGELOGARBPROC` (for -`glGetDebugMessageLogARB`), i.e. the name is made uppercase and `PFN` (pointer -to function) and `PROC` (procedure) are added to the ends. - -To include the extension header, define [GLFW_INCLUDE_GLEXT](@ref build_macros) -before including the GLFW header. - -@code -#define GLFW_INCLUDE_GLEXT -#include -@endcode - - -@subsubsection context_glext_string Checking for extensions - -A given machine may not actually support the extension (it may have older -drivers or a graphics card that lacks the necessary hardware features), so it -is necessary to check at run-time whether the context supports the extension. -This is done with @ref glfwExtensionSupported. - -@code -if (glfwExtensionSupported("GL_ARB_debug_output")) -{ - // The extension is supported by the current context -} -@endcode - -The argument is a null terminated ASCII string with the extension name. If the -extension is supported, @ref glfwExtensionSupported returns `GL_TRUE`, otherwise -it returns `GL_FALSE`. - - -@subsubsection context_glext_proc Fetching function pointers - -Many extensions, though not all, require the use of new OpenGL functions. -These functions often do not have entry points in the client API libraries of -your operating system, making it necessary to fetch them at run time. You can -retrieve pointers to these functions with @ref glfwGetProcAddress. - -@code -PFNGLGETDEBUGMESSAGELOGARBPROC pfnGetDebugMessageLog = glfwGetProcAddress("glGetDebugMessageLogARB"); -@endcode - -In general, you should avoid giving the function pointer variables the (exact) -same name as the function, as this may confuse your linker. Instead, you can -use a different prefix, like above, or some other naming scheme. - -Now that all the pieces have been introduced, here is what they might look like -when used together. - -@code -#define GLFW_INCLUDE_GLEXT -#include - -#define glGetDebugMessageLogARB pfnGetDebugMessageLog -PFNGLGETDEBUGMESSAGELOGARBPROC pfnGetDebugMessageLog; - -// Flag indicating whether the extension is supported -int has_ARB_debug_output = 0; - -void load_extensions(void) -{ - if (glfwExtensionSupported("GL_ARB_debug_output")) - { - pfnGetDebugMessageLog = (PFNGLGETDEBUGMESSAGELOGARBPROC) glfwGetProcAddress("glGetDebugMessageLogARB"); - if (pfnGetDebugMessageLog) - { - // Both the extension name and the function pointer are present - has_ARB_debug_output = 1; - } - } -} - -void some_function(void) -{ - if (has_ARB_debug_output) - { - // Now the extension function can be called as usual - glGetDebugMessageLogARB(...); - } -} -@endcode - -*/ diff --git a/examples/common/glfw/docs/extra.css b/examples/common/glfw/docs/extra.css deleted file mode 100644 index e9896fae..00000000 --- a/examples/common/glfw/docs/extra.css +++ /dev/null @@ -1 +0,0 @@ -#navrow1,#navrow2,#navrow3,#navrow4,.tablist a,.tablist a:visited,.tablist a:hover,.tablist li,.tablist li.current a,.memdoc,dl.reflist dd,div.toc li,.ah,span.lineno,span.lineno a,span.lineno a:hover,.note code,.pre code,.post code,.invariant code,.warning code,.attention code,.deprecated code,.bug code,.todo code,.test code,.doxtable code{background:none}#titlearea,.footer,.contents,div.header,.memdoc,table.doxtable td,table.doxtable th,hr,.memSeparator{border:none}.tablist a,.tablist a:visited,.tablist a:hover,.tablist li,.tablist li.current a,.reflist dt a.el,.levels span,.directory .levels span{text-shadow:none}.memdoc,dl.reflist dd{box-shadow:none}div.headertitle,.note code,.pre code,.post code,.invariant code,.warning code,.attention code,.deprecated code,.bug code,.todo code,.test code,table.doxtable code{padding:0}#nav-path,.directory .levels,span.lineno{display:none}html,#titlearea,.footer,tr.even,.directory tr.even,.doxtable tr:nth-child(even),.mdescLeft,.mdescRight,.memItemLeft,.memItemRight,code{background:#f2f2f2}body{color:#4d4d4d}h1,h2,h2.groupheader,h3,div.toc h3,h4,h5,h6,strong,em{color:#1a1a1a;border-bottom:none}h1{padding-top:0.5em;font-size:180%}h2{padding-top:0.5em;margin-bottom:0;font-size:140%}h3{padding-top:0.5em;margin-bottom:0;font-size:110%}.glfwheader{font-size:16px;height:64px;max-width:920px;min-width:800px;padding:0 32px;margin:0 auto}#glfwhome{line-height:64px;padding-right:48px;color:#666;font-size:2.5em;background:url("http://www.glfw.org/css/arrow.png") no-repeat right}.glfwnavbar{list-style-type:none;margin:0 auto;float:right}#glfwhome,.glfwnavbar li{float:left}.glfwnavbar a,.glfwnavbar a:visited{line-height:64px;margin-left:2em;display:block;color:#666}#glfwhome,.glfwnavbar a,.glfwnavbar a:visited{transition:.35s ease}#titlearea,.footer{color:#666}address.footer{text-align:center;padding:2em;margin-top:3em}#top{background:#666}#navrow1,#navrow2,#navrow3,#navrow4{max-width:920px;min-width:800px;margin:0 auto;font-size:13px}.tablist{height:36px;display:block;position:relative}.tablist a,.tablist a:visited,.tablist a:hover,.tablist li,.tablist li.current a{color:#f2f2f2}.tablist li.current a{background:linear-gradient(to bottom, #ffa733 0, #f60 100%);box-shadow:inset 0 0 32px #f60;text-shadow:0 -1px 1px #b34700;color:#fff}.contents{min-height:590px}div.contents,div.header{max-width:920px;margin:0 auto;padding:0 32px;background:#fff none}table.doxtable th,dl.reflist dt{background:linear-gradient(to bottom, #ffa733 0, #f60 100%);box-shadow:inset 0 0 32px #f60;text-shadow:0 -1px 1px #b34700;color:#fff}dl.reflist dt a.el{color:#f60;padding:.2em;border-radius:4px;background-color:#ffe0cc}div.toc{float:none;width:auto}div.toc h3{font-size:1.17em}div.toc ul{padding-left:1.5em}div.toc li{font-size:1em;padding-left:0;list-style-type:disc}div.toc,.memproto,div.qindex,div.ah{background:linear-gradient(to bottom, #f2f2f2 0, #e6e6e6 100%);box-shadow:inset 0 0 32px #e6e6e6;text-shadow:0 1px 1px #fff;color:#1a1a1a;border:2px solid #e6e6e6;border-radius:4px}.paramname{color:#803300}dl.reflist dt{border:2px solid #f60;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom:none}dl.reflist dd{border:2px solid #f60;border-bottom-right-radius:4px;border-bottom-left-radius:4px;border-top:none}table.doxtable{border-collapse:inherit;border-spacing:0;border:2px solid #f60;border-radius:4px}a,a:hover,a:visited,a:visited:hover,.contents a:visited,.el,a.el:visited,#glfwhome:hover,.tablist a:hover,span.lineno a:hover{color:#f60;text-decoration:none}div.directory{border-collapse:inherit;border-spacing:0;border:2px solid #f60;border-radius:4px}hr,.memSeparator{height:2px;background:linear-gradient(to right, #f2f2f2 0, #d9d9d9 50%, #f2f2f2 100%)}dl.note,dl.pre,dl.post,dl.invariant{background:linear-gradient(to bottom, #ddfad1 0, #cbf7ba 100%);box-shadow:inset 0 0 32px #baf5a3;color:#1e5309;border:2px solid #afe599}dl.warning,dl.attention{background:linear-gradient(to bottom, #fae8d1 0, #f7ddba 100%);box-shadow:inset 0 0 32px #f5d1a3;color:#533309;border:2px solid #e5c499}dl.deprecated,dl.bug{background:linear-gradient(to bottom, #fad1e3 0, #f7bad6 100%);box-shadow:inset 0 0 32px #f5a3c8;color:#53092a;border:2px solid #e599bb}dl.todo,dl.test{background:linear-gradient(to bottom, #d1ecfa 0, #bae3f7 100%);box-shadow:inset 0 0 32px #a3daf5;color:#093a53;border:2px solid #99cce5}dl.note,dl.pre,dl.post,dl.invariant,dl.warning,dl.attention,dl.deprecated,dl.bug,dl.todo,dl.test{border-radius:4px;padding:1em;text-shadow:0 1px 1px #fff;margin:1em 0}.note a,.pre a,.post a,.invariant a,.warning a,.attention a,.deprecated a,.bug a,.todo a,.test a,.note a:visited,.pre a:visited,.post a:visited,.invariant a:visited,.warning a:visited,.attention a:visited,.deprecated a:visited,.bug a:visited,.todo a:visited,.test a:visited{color:inherit}div.line{line-height:inherit}div.fragment,pre.fragment{background:#f2f2f2;border-radius:4px;border:none;padding:1em;overflow:auto;border-left:4px solid #ccc;margin:1em 0}.lineno a,.lineno a:visited,.line,pre.fragment{color:#4d4d4d}span.preprocessor,span.comment{color:#007899}a.code,a.code:visited{color:#e64500}span.keyword,span.keywordtype,span.keywordflow{color:#404040;font-weight:bold}span.stringliteral{color:#360099}code{padding:.1em;border-radius:4px} diff --git a/examples/common/glfw/docs/extra.less b/examples/common/glfw/docs/extra.less deleted file mode 100644 index 9d0ce975..00000000 --- a/examples/common/glfw/docs/extra.less +++ /dev/null @@ -1,370 +0,0 @@ -// NOTE: Please use this file to perform modifications on default style sheets. -// -// You need to install a few Ruby gems to generate extra.css from this file: -// gem install less therubyracer -// -// Run this command to regenerate extra.css after you're finished with changes: -// lessc --compress extra.less > extra.css -// -// Alternatively you can use online services to regenerate extra.css. - - -// Default text color for page contents -@default-text-color: hsl(0,0%,30%); - -// Page header, footer, table rows, inline codes and definition lists -@header-footer-background-color: hsl(0,0%,95%); - -// Page header, footer links and navigation bar background -@header-footer-link-color: hsl(0,0%,40%); - -// Doxygen navigation bar links -@navbar-link-color: @header-footer-background-color; - -// Page content background color -@content-background-color: hsl(0,0%,100%); - -// Bold, italic, h1, h2, ... and table of contents -@heading-color: hsl(0,0%,10%); - -// Function, enum and macro definition separator -@def-separator-color: @header-footer-background-color; - -// Base color hue -@base-hue: 24; - -// Default color used for links -@default-link-color: hsl(@base-hue,100%,50%); - -// Doxygen navigation bar active tab -@tab-text-color: hsl(0,0%,100%); -@tab-background-color1: @default-link-color; -@tab-background-color2: lighten(spin(@tab-background-color1, 10), 10%); - -// Table borders -@default-border-color: @default-link-color; - -// Table header -@table-text-color: @tab-text-color; -@table-background-color1: @tab-background-color1; -@table-background-color2: @tab-background-color2; - -// Table of contents, data structure index and prototypes -@toc-background-color1: hsl(0,0%,90%); -@toc-background-color2: lighten(@toc-background-color1, 5%); - -// Function prototype parameters color -@prototype-param-color: darken(@default-link-color, 25%); - -// Message box color: note, pre, post and invariant -@box-note-color: hsl(103,80%,85%); - -// Message box color: warning and attention -@box-warning-color: hsl(34,80%,85%); - -// Message box color: deprecated and bug -@box-bug-color: hsl(333,80%,85%); - -// Message box color: todo and test -@box-todo-color: hsl(200,80%,85%); - -// Message box helper function -.message-box(@base-color) { - background:linear-gradient(to bottom,lighten(@base-color, 5%) 0%,@base-color 100%); - box-shadow:inset 0 0 32px darken(@base-color, 5%); - color:darken(@base-color, 67%); - border:2px solid desaturate(darken(@base-color, 10%), 20%); -} - - -#navrow1,#navrow2,#navrow3,#navrow4,.tablist a,.tablist a:visited,.tablist a:hover,.tablist li,.tablist li.current a,.memdoc,dl.reflist dd,div.toc li,.ah,span.lineno,span.lineno a,span.lineno a:hover,.note code,.pre code,.post code,.invariant code,.warning code,.attention code,.deprecated code,.bug code,.todo code,.test code,.doxtable code { - background:none; -} - -#titlearea,.footer,.contents,div.header,.memdoc,table.doxtable td,table.doxtable th,hr,.memSeparator { - border:none; -} - -.tablist a,.tablist a:visited,.tablist a:hover,.tablist li,.tablist li.current a,.reflist dt a.el,.levels span,.directory .levels span { - text-shadow:none; -} - -.memdoc,dl.reflist dd { - box-shadow:none; -} - -div.headertitle,.note code,.pre code,.post code,.invariant code,.warning code,.attention code,.deprecated code,.bug code,.todo code,.test code,table.doxtable code { - padding:0; -} - -#nav-path,.directory .levels,span.lineno { - display:none; -} - -html,#titlearea,.footer,tr.even,.directory tr.even,.doxtable tr:nth-child(even),.mdescLeft,.mdescRight,.memItemLeft,.memItemRight,code { - background:@header-footer-background-color; -} - -body { - color:@default-text-color; -} - -h1,h2,h2.groupheader,h3,div.toc h3,h4,h5,h6,strong,em { - color:@heading-color; - border-bottom:none; -} - -h1 { - padding-top:0.5em; - font-size:180%; -} - -h2 { - padding-top:0.5em; - margin-bottom:0; - font-size:140%; -} - -h3 { - padding-top:0.5em; - margin-bottom:0; - font-size:110%; -} - -.glfwheader { - font-size:16px; - height:64px; - max-width:920px; - min-width:800px; - padding:0 32px; - margin:0 auto; -} - -#glfwhome { - line-height:64px; - padding-right:48px; - color:@header-footer-link-color; - font-size:2.5em; - background:url("http://www.glfw.org/css/arrow.png") no-repeat right; -} - -.glfwnavbar { - list-style-type:none; - margin:0 auto; - float:right; -} - -#glfwhome,.glfwnavbar li { - float:left; -} - -.glfwnavbar a,.glfwnavbar a:visited { - line-height:64px; - margin-left:2em; - display:block; - color:@header-footer-link-color; -} - -#glfwhome,.glfwnavbar a,.glfwnavbar a:visited { - transition:.35s ease; -} - -#titlearea,.footer { - color:@header-footer-link-color; -} - -address.footer { - text-align:center; - padding:2em; - margin-top:3em; -} - -#top { - background:@header-footer-link-color; -} - -#navrow1,#navrow2,#navrow3,#navrow4 { - max-width:920px; - min-width:800px; - margin:0 auto; - font-size:13px; -} - -.tablist { - height:36px; - display:block; - position:relative; -} - -.tablist a,.tablist a:visited,.tablist a:hover,.tablist li,.tablist li.current a { - color:@navbar-link-color; -} - -.tablist li.current a { - background:linear-gradient(to bottom,@tab-background-color2 0%,@tab-background-color1 100%); - box-shadow:inset 0 0 32px @tab-background-color1; - text-shadow:0 -1px 1px darken(@tab-background-color1, 15%); - color:@tab-text-color; -} - -.contents { - min-height:590px; -} - -div.contents,div.header { - max-width:920px; - margin:0 auto; - padding:0 32px; - background:@content-background-color none; -} - -table.doxtable th,dl.reflist dt { - background:linear-gradient(to bottom,@table-background-color2 0%,@table-background-color1 100%); - box-shadow:inset 0 0 32px @table-background-color1; - text-shadow:0 -1px 1px darken(@table-background-color1, 15%); - color:@table-text-color; -} - -dl.reflist dt a.el { - color:@default-link-color; - padding:.2em; - border-radius:4px; - background-color:lighten(@default-link-color, 40%); -} - -div.toc { - float:none; - width:auto; -} - -div.toc h3 { - font-size:1.17em; -} - -div.toc ul { - padding-left:1.5em; -} - -div.toc li { - font-size:1em; - padding-left:0; - list-style-type:disc; -} - -div.toc,.memproto,div.qindex,div.ah { - background:linear-gradient(to bottom,@toc-background-color2 0%,@toc-background-color1 100%); - box-shadow:inset 0 0 32px @toc-background-color1; - text-shadow:0 1px 1px lighten(@toc-background-color2, 10%); - color:@heading-color; - border:2px solid @toc-background-color1; - border-radius:4px; -} - -.paramname { - color:@prototype-param-color; -} - -dl.reflist dt { - border:2px solid @default-border-color; - border-top-left-radius:4px; - border-top-right-radius:4px; - border-bottom:none; -} - -dl.reflist dd { - border:2px solid @default-border-color; - border-bottom-right-radius:4px; - border-bottom-left-radius:4px; - border-top:none; -} - -table.doxtable { - border-collapse:inherit; - border-spacing:0; - border:2px solid @default-border-color; - border-radius:4px; -} - -a,a:hover,a:visited,a:visited:hover,.contents a:visited,.el,a.el:visited,#glfwhome:hover,.tablist a:hover,span.lineno a:hover { - color:@default-link-color; - text-decoration:none; -} - -div.directory { - border-collapse:inherit; - border-spacing:0; - border:2px solid @default-border-color; - border-radius:4px; -} - -hr,.memSeparator { - height:2px; - background:linear-gradient(to right,@def-separator-color 0%,darken(@def-separator-color, 10%) 50%,@def-separator-color 100%); -} - -dl.note,dl.pre,dl.post,dl.invariant { - .message-box(@box-note-color); -} - -dl.warning,dl.attention { - .message-box(@box-warning-color); -} - -dl.deprecated,dl.bug { - .message-box(@box-bug-color); -} - -dl.todo,dl.test { - .message-box(@box-todo-color); -} - -dl.note,dl.pre,dl.post,dl.invariant,dl.warning,dl.attention,dl.deprecated,dl.bug,dl.todo,dl.test { - border-radius:4px; - padding:1em; - text-shadow:0 1px 1px hsl(0,0%,100%); - margin:1em 0; -} - -.note a,.pre a,.post a,.invariant a,.warning a,.attention a,.deprecated a,.bug a,.todo a,.test a,.note a:visited,.pre a:visited,.post a:visited,.invariant a:visited,.warning a:visited,.attention a:visited,.deprecated a:visited,.bug a:visited,.todo a:visited,.test a:visited { - color:inherit; -} - -div.line { - line-height:inherit; -} - -div.fragment,pre.fragment { - background:hsl(0,0%,95%); - border-radius:4px; - border:none; - padding:1em; - overflow:auto; - border-left:4px solid hsl(0,0%,80%); - margin:1em 0; -} - -.lineno a,.lineno a:visited,.line,pre.fragment { - color:@default-text-color; -} - -span.preprocessor,span.comment { - color:hsl(193,100%,30%); -} - -a.code,a.code:visited { - color:hsl(18,100%,45%); -} - -span.keyword,span.keywordtype,span.keywordflow { - color:darken(@default-text-color, 5%); - font-weight:bold; -} - -span.stringliteral { - color:hsl(261,100%,30%); -} - -code { - padding:.1em; - border-radius:4px; -} diff --git a/examples/common/glfw/docs/footer.html b/examples/common/glfw/docs/footer.html deleted file mode 100644 index b0434ca1..00000000 --- a/examples/common/glfw/docs/footer.html +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/examples/common/glfw/docs/header.html b/examples/common/glfw/docs/header.html deleted file mode 100644 index 9759d8b0..00000000 --- a/examples/common/glfw/docs/header.html +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - -$projectname: $title -$title - - - -$treeview -$search -$mathjax - -$extrastylesheet - - -
- - - - - diff --git a/examples/common/glfw/docs/input.dox b/examples/common/glfw/docs/input.dox deleted file mode 100644 index fb38808b..00000000 --- a/examples/common/glfw/docs/input.dox +++ /dev/null @@ -1,588 +0,0 @@ -/*! - -@page input Input guide - -@tableofcontents - -This guide introduces the input related functions of GLFW. There are also -guides for the other areas of GLFW. - - - @ref intro - - @ref window - - @ref context - - @ref monitor - -GLFW provides many kinds of input. While some can only be polled, like time, or -only received via callbacks, like scrolling, there are those that provide both -callbacks and polling. Where a callback is provided, that is the recommended -way to receive that kind of input. The more you can use callbacks the less time -your users' machines will need to spend polling. - -All input callbacks receive a window handle. By using the -[window user pointer](@ref window_userptr), you can access non-global structures -or objects from your callbacks. - -To get a better feel for how the various events callbacks behave, run the -`events` test program. It register every callback supported by GLFW and prints -out all arguments provided for every event, along with time and sequence -information. - - -@section events Event processing - -GLFW needs to communicate regularly with the window system both in order to -receive events and to show that the application hasn't locked up. Event -processing must be done regularly while you have visible windows and is normally -done each frame after [buffer swapping](@ref buffer_swap). - -There are two functions for processing pending events. @ref glfwPollEvents, -processes only those events that have already been received and then returns -immediately. - -@code -glfwPollEvents(); -@endcode - -This is the best choice when rendering continually, like most games do. - -If you only need to update the contents of the window when you receive new -input, @ref glfwWaitEvents is a better choice. - -@code -glfwWaitEvents(); -@endcode - -It puts the thread to sleep until at least one event has been received and then -processes all received events. This saves a great deal of CPU cycles and is -useful for, for example, editing tools. There must be at least one GLFW window -for this function to sleep. - -If the main thread is sleeping in @ref glfwWaitEvents, you can wake it from -another thread by posting an empty event to the event queue with @ref -glfwPostEmptyEvent. - -@code -glfwPostEmptyEvent(); -@endcode - -Do not assume that callbacks will _only_ be called through either of the above -functions. While it is necessary to process events in the event queue, some -window systems will send some events directly to the application, which in turn -causes callbacks to be called outside of regular event processing. - - -@section input_keyboard Keyboard input - -GLFW divides keyboard input into two categories; key events and character -events. Key events relate to actual physical keyboard keys, whereas character -events relate to the Unicode code points generated by pressing some of them. - -Keys and characters do not map 1:1. A single key press may produce several -characters, and a single character may require several keys to produce. This -may not be the case on your machine, but your users are likely not all using the -same keyboard layout, input method or even operating system as you. - - -@subsection input_key Key input - -If you wish to be notified when a physical key is pressed or released or when it -repeats, set a key callback. - -@code -glfwSetKeyCallback(window, key_callback); -@endcode - -The callback function receives the [keyboard key](@ref keys), platform-specific -scancode, key action and [modifier bits](@ref mods). - -@code -void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) -{ - if (key == GLFW_KEY_E && action == GLFW_PRESS) - activate_airship(); -} -@endcode - -The action is one of `GLFW_PRESS`, `GLFW_REPEAT` or `GLFW_RELEASE`. The key -will be `GLFW_KEY_UNKNOWN` if GLFW lacks a key token for it. These keys still -have unique, if platform-specific scancodes. - -The scancode is unique for every key but is platform-specific, so a scancode -will map to different keys on different platforms. - -The key will be `GLFW_KEY_UNKNOWN` for special keys like _E-mail_ or _Play_ that -don't have a key token. Those keys will still have unique, if platform-specific -scancodes. - -Key states for [named keys](@ref keys) are also saved in per-window state arrays -that can be polled with @ref glfwGetKey. - -@code -int state = glfwGetKey(window, GLFW_KEY_E); -if (state == GLFW_PRESS) - activate_airship(); -@endcode - -The returned state is one of `GLFW_PRESS` or `GLFW_RELEASE`. - -This function only returns cached key event state. It does not poll the -system for the current state of the key. - -Whenever you poll state, you risk missing the state change you are looking for. -If a pressed key is released again before you poll its state, you will have -missed the key press. The recommended solution for this is to use a -key callback, but there is also the `GLFW_STICKY_KEYS` input mode. - -@code -glfwSetInputMode(window, GLFW_STICKY_KEYS, 1); -@endcode - -When sticky keys mode is enabled, the pollable state of a key will remain -`GLFW_PRESS` until the state of that key is polled with @ref glfwGetKey. Once -it has been polled, if a key release event had been processed in the meantime, -the state will reset to `GLFW_RELEASE`, otherwise it will remain `GLFW_PRESS`. - -The `GLFW_KEY_LAST` constant holds the highest value of any -[named key](@ref keys). - - -@subsection input_char Text input - -GLFW supports text input in the form of a stream of -[Unicode code points](https://en.wikipedia.org/wiki/Unicode), as produced by the -operating system text input system. Unlike key input, text input obeys keyboard -layouts and modifier keys and supports composing characters using -[dead keys](https://en.wikipedia.org/wiki/Dead_key). Once received, you can -encode the code points into -[UTF-8](https://en.wikipedia.org/wiki/UTF-8) or any other encoding you prefer. - -Because an `unsigned int` is 32 bits long on all platforms supported by GLFW, -you can treat the code point argument as native endian -[UTF-32](https://en.wikipedia.org/wiki/UTF-32). - -There are two callbacks for receiving Unicode code points. If you wish to -offer regular text input, set a character callback. - -@code -glfwSetCharCallback(window, character_callback); -@endcode - -The callback function receives Unicode code points for key events that would -have led to regular text input and generally behaves as a standard text field on -that platform. - -@code -void character_callback(GLFWwindow* window, unsigned int codepoint) -{ -} -@endcode - -If you wish to receive even those Unicode code points generated with modifier -key combinations that a plain text field would ignore, or just want to know -exactly what modifier keys were used, set a character with modifiers callback. - -@code -glfwSetCharModsCallback(window, charmods_callback); -@endcode - -The callback function receives Unicode code points and -[modifier bits](@ref mods). - -@code -void charmods_callback(GLFWwindow* window, unsigned int codepoint, int mods) -{ -} -@endcode - - -@section input_mouse Mouse input - -Mouse input comes in many forms, including cursor motion, button presses and -scrolling offsets. The cursor appearance can also be changed, either to -a custom image or a standard cursor shape from the system theme. - - -@subsection cursor_pos Cursor position - -If you wish to be notified when the cursor moves over the window, set a cursor -position callback. - -@code -glfwSetCursorPosCallback(window, cursor_pos_callback); -@endcode - -The callback functions receives the cursor position. On platforms that provide -it, the full sub-pixel cursor position is passed on. - -@code -static void cursor_position_callback(GLFWwindow* window, double xpos, double ypos) -{ -} -@endcode - -The cursor position is also saved per-window and can be polled with @ref -glfwGetCursorPos. - -@code -double xpos, ypos; -glfwGetCursorPos(window, &xpos, &ypos); -@endcode - - -@subsection cursor_mode Cursor modes - -The `GLFW_CURSOR` input mode provides several cursor modes for special forms of -mouse motion input. By default, the cursor mode is `GLFW_CURSOR_NORMAL`, -meaning the regular arrow cursor (or another cursor set with @ref glfwSetCursor) -is used and cursor motion is not limited. - -If you wish to implement mouse motion based camera controls or other input -schemes that require unlimited mouse movement, set the cursor mode to -`GLFW_CURSOR_DISABLED`. - -@code -glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); -@endcode - -This will hide the cursor and lock it to the specified window. GLFW will then -take care of all the details of cursor re-centering and offset calculation and -providing the application with a virtual cursor position. This virtual position -is provided normally via both the cursor position callback and through polling. - -@note You should not implement your own version of this functionality using -other features of GLFW. It is not supported and will not work as robustly as -`GLFW_CURSOR_DISABLED`. - -If you just wish the cursor to become hidden when it is over a window, set -the cursor mode to `GLFW_CURSOR_HIDDEN`. - -@code -glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); -@endcode - -This mode puts no limit on the motion of the cursor. - -To exit out of either of these special modes, restore the `GLFW_CURSOR_NORMAL` -cursor mode. - -@code -glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); -@endcode - - -@subsection cursor_object Cursor objects - -GLFW supports creating both custom and system theme cursor images, encapsulated -as @ref GLFWcursor objects. They are created with @ref glfwCreateCursor or @ref -glfwCreateStandardCursor and destroyed with @ref glfwDestroyCursor, or @ref -glfwTerminate, if any remain. - - -@subsubsection cursor_custom Custom cursor creation - -A custom cursor is created with @ref glfwCreateCursor, which returns a handle to -the created cursor object. For example, this creates a 16x16 white square -cursor with the hot-spot in the upper-left corner: - -@code -unsigned char pixels[16 * 16 * 4]; -memset(pixels, 0xff, sizeof(pixels)); - -GLFWimage image; -image.width = 16; -image.height = 16; -image.pixels = pixels; - -GLFWcursor* cursor = glfwCreateCursor(&image, 0, 0); -@endcode - -If cursor creation fails, `NULL` will be returned, so it is necessary to check -the return value. - -The image data is 32-bit RGBA, i.e. eight bits per channel. The pixels are -arranged canonically as sequential rows, starting from the top-left corner. - - -@subsubsection cursor_standard Standard cursor creation - -A cursor with a [standard shape](@ref shapes) from the current system cursor -theme can be can be created with @ref glfwCreateStandardCursor. - -@code -GLFWcursor* cursor = glfwCreateStandardCursor(GLFW_HRESIZE_CURSOR); -@endcode - -These cursor objects behave in the exact same way as those created with @ref -glfwCreateCursor except that the system cursor theme provides the actual image. - - -@subsubsection cursor_destruction Cursor destruction - -When a cursor is no longer needed, destroy it with @ref glfwDestroyCursor. - -@code -glfwDestroyCursor(cursor); -@endcode - -Cursor destruction always succeeds. All cursors remaining when @ref -glfwTerminate is called are destroyed as well. - - -@subsubsection cursor_set Cursor setting - -A cursor can be set as current for a window with @ref glfwSetCursor. - -@code -glfwSetCursor(window, cursor); -@endcode - -Once set, the cursor image will be used as long as the system cursor is over the -client area of the window and the [cursor mode](@ref cursor_mode) is set -to `GLFW_CURSOR_NORMAL`. - -A single cursor may be set for any number of windows. - -To remove a cursor from a window, set the cursor of that window to `NULL`. - -@code -glfwSetCursor(window, NULL); -@endcode - -When a cursor is destroyed, it is removed from any window where it is set. This -does not affect the cursor modes of those windows. - - -@subsection cursor_enter Cursor enter/leave events - -If you wish to be notified when the cursor enters or leaves the client area of -a window, set a cursor enter/leave callback. - -@code -glfwSetCursorEnterCallback(window, cursor_enter_callback); -@endcode - -The callback function receives the new classification of the cursor. - -@code -void cursor_enter_callback(GLFWwindow* window, int entered) -{ - if (entered) - { - // The cursor entered the client area of the window - } - else - { - // The cursor left the client area of the window - } -} -@endcode - - -@subsection input_mouse_button Mouse button input - -If you wish to be notified when a mouse button is pressed or released, set -a mouse button callback. - -@code -glfwSetMouseButtonCallback(window, mouse_button_callback); -@endcode - -The callback function receives the [mouse button](@ref buttons), button action -and [modifier bits](@ref mods). - -@code -void mouse_button_callback(GLFWwindow* window, int button, int action, int mods) -{ - if (button == GLFW_MOUSE_BUTTON_RIGHT && action == GLFW_PRESS) - popup_menu(); -} -@endcode - -The action is one of `GLFW_PRESS` or `GLFW_RELEASE`. - -Mouse button states for [named buttons](@ref buttons) are also saved in -per-window state arrays that can be polled with @ref glfwGetMouseButton. - -@code -int state = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT); -if (state == GLFW_PRESS) - upgrade_cow(); -@endcode - -The returned state is one of `GLFW_PRESS` or `GLFW_RELEASE`. - -This function only returns cached mouse button event state. It does not poll -the system for the current state of the mouse button. - -Whenever you poll state, you risk missing the state change you are looking for. -If a pressed mouse button is released again before you poll its state, you will have -missed the button press. The recommended solution for this is to use a -mouse button callback, but there is also the `GLFW_STICKY_MOUSE_BUTTONS` -input mode. - -@code -glfwSetInputMode(window, GLFW_STICKY_MOUSE_BUTTONS, 1); -@endcode - -When sticky mouse buttons mode is enabled, the pollable state of a mouse button -will remain `GLFW_PRESS` until the state of that button is polled with @ref -glfwGetMouseButton. Once it has been polled, if a mouse button release event -had been processed in the meantime, the state will reset to `GLFW_RELEASE`, -otherwise it will remain `GLFW_PRESS`. - -The `GLFW_MOUSE_BUTTON_LAST` constant holds the highest value of any -[named button](@ref buttons). - - -@subsection scrolling Scroll input - -If you wish to be notified when the user scrolls, whether with a mouse wheel or -touchpad gesture, set a scroll callback. - -@code -glfwSetScrollCallback(window, scroll_callback); -@endcode - -The callback function receives two-dimensional scroll offsets. - -@code -void scroll_callback(GLFWwindow* window, double xoffset, double yoffset) -{ -} -@endcode - -A simple mouse wheel, being vertical, provides offsets along the Y-axis. - - -@section joystick Joystick input - -The joystick functions expose connected joysticks and controllers, with both -referred to as joysticks. It supports up to sixteen joysticks, ranging from -`GLFW_JOYSTICK_1`, `GLFW_JOYSTICK_2` up to `GLFW_JOYSTICK_LAST`. You can test -whether a [joystick](@ref joysticks) is present with @ref glfwJoystickPresent. - -@code -int present = glfwJoystickPresent(GLFW_JOYSTICK_1); -@endcode - -When GLFW is initialized, detected joysticks are added to to the beginning of -the array, starting with `GLFW_JOYSTICK_1`. Once a joystick is detected, it -keeps its assigned index until it is disconnected, so as joysticks are connected -and disconnected, they will become spread out. - -Joystick state is updated as needed when a joystick function is called and does -not require a window to be created or @ref glfwPollEvents or @ref glfwWaitEvents -to be called. - - -@subsection joystick_axis Joystick axis states - -The positions of all axes of a joystick are returned by @ref -glfwGetJoystickAxes. See the reference documentation for the lifetime of the -returned array. - -@code -int count; -const float* axes = glfwGetJoystickAxes(GLFW_JOYSTICK_1, &count); -@endcode - -Each element in the returned array is a value between -1.0 and 1.0. - - -@subsection joystick_button Joystick button states - -The states of all buttons of a joystick are returned by @ref -glfwGetJoystickButtons. See the reference documentation for the lifetime of the -returned array. - -@code -int count; -const unsigned char* axes = glfwGetJoystickButtons(GLFW_JOYSTICK_1, &count); -@endcode - -Each element in the returned array is either `GLFW_PRESS` or `GLFW_RELEASE`. - - -@subsection joystick_name Joystick name - -The human-readable, UTF-8 encoded name of a joystick is returned by @ref -glfwGetJoystickName. See the reference documentation for the lifetime of the -returned string. - -@code -const char* name = glfwGetJoystickName(GLFW_JOYSTICK_1); -@endcode - -Joystick names are not guaranteed to be unique. Two joysticks of the same model -and make may have the same name. Only the [joystick token](@ref joysticks) is -guaranteed to be unique, and only until that joystick is disconnected. - - -@section time Time input - -GLFW provides high-resolution time input, in seconds, with @ref glfwGetTime. - -@code -double seconds = glfwGetTime(); -@endcode - -It returns the number of seconds since the timer was started when the library -was initialized with @ref glfwInit. The platform-specific time sources used -usually have micro- or nanosecond resolution. - -You can modify the reference time with @ref glfwSetTime. - -@code -glfwSetTime(4.0); -@endcode - -This sets the timer to the specified time, in seconds. - - -@section clipboard Clipboard input and output - -If the system clipboard contains a UTF-8 encoded string or if it can be -converted to one, you can retrieve it with @ref glfwGetClipboardString. See the -reference documentation for the lifetime of the returned string. - -@code -const char* clipboard = glfwGetClipboardString(window); -@endcode - -The contents of the system clipboard can be set to a UTF-8 encoded string with -@ref glfwSetClipboardString. - -@code -glfwSetClipboardString(window, "A string with words in it"); -@endcode - -The clipboard functions take a window handle argument because some window -systems require a window to communicate with the system clipboard. Any valid -window may be used. - - -@section path_drop Path drop input - -If you wish to receive the paths of files and/or directories dropped on -a window, set a file drop callback. - -@code -glfwSetDropCallback(window, drop_callback); -@endcode - -The callback function receives an array of paths encoded as UTF-8. - -@code -void drop_callback(GLFWwindow* window, int count, const char** paths) -{ - int i; - for (i = 0; i < count; i++) - handle_dropped_file(paths[i]); -} -@endcode - -The path array and its strings are only valid until the file drop callback -returns, as they may have been generated specifically for that event. You need -to make a deep copy of the array if you want to keep the paths. - -*/ diff --git a/examples/common/glfw/docs/internal.dox b/examples/common/glfw/docs/internal.dox deleted file mode 100644 index 0389af6e..00000000 --- a/examples/common/glfw/docs/internal.dox +++ /dev/null @@ -1,116 +0,0 @@ -/*! - -@page internals Internal structure - -@tableofcontents - -There are several interfaces inside GLFW. Each interface has its own area of -responsibility and its own naming conventions. - - -@section internals_public Public interface - -The most well-known is the public interface, described in the glfw3.h header -file. This is implemented in source files shared by all platforms and these -files contain no platform-specific code. This code usually ends up calling the -platform and internal interfaces to do the actual work. - -The public interface uses the OpenGL naming conventions except with GLFW and -glfw instead of GL and gl. For struct members, where OpenGL sets no precedent, -it use headless camel case. - -Examples: @ref glfwCreateWindow, @ref GLFWwindow, @ref GLFWvidmode.redBits, -`GLFW_RED_BITS` - - -@section internals_native Native interface - -The [native interface](@ref native) is a small set of publicly available -but platform-specific functions, described in the glfw3native.h header file and -used to gain access to the underlying window, context and (on some platforms) -display handles used by the platform interface. - -The function names of the native interface are similar to those of the public -interface, but embeds the name of the interface that the returned handle is -from. - -Examples: @ref glfwGetX11Window, @ref glfwGetWGLContext - - -@section internals_internal Internal interface - -The internal interface consists of utility functions used by all other -interfaces. It is shared code implemented in the same shared source files as -the public and event interfaces. The internal interface is described in the -internal.h header file. - -The internal interface is in charge of GLFW's global data, which it stores in -a `_GLFWlibrary` struct named `_glfw`. - -The internal interface uses the same style as the public interface, except all -global names have a leading underscore. - -Examples: @ref _glfwIsValidContextConfig, @ref _GLFWwindow, `_glfw.currentRamp` - - -@section internals_platform Platform interface - -The platform interface implements all platform-specific operations as a service -to the public interface. This includes event processing. The platform -interface is never directly called by application code and never directly calls -application-provided callbacks. It is also prohibited from modifying the -platform-independent part of the internal structs. Instead, it calls the event -interface when events interesting to GLFW are received. - -The platform interface mirrors those parts of the public interface that needs to -perform platform-specific operations on some or all platforms. The are also -named the same except that the glfw function prefix is replaced by -_glfwPlatform. - -Examples: @ref _glfwPlatformCreateWindow - -The platform interface also defines structs that contain platform-specific -global and per-object state. Their names mirror those of the internal -interface, except that an interface-specific suffix is added. - -Examples: `_GLFWwindowX11`, `_GLFWcontextWGL` - -These structs are incorporated as members into the internal interface structs -using special macros that name them after the specific interface used. This -prevents shared code from accidentally using these members. - -Examples: `window.win32.handle`, `_glfw.x11.display` - - -@section internals_event Event interface - -The event interface is implemented in the same shared source files as the public -interface and is responsible for delivering the events it receives to the -application, either via callbacks, via window state changes or both. - -The function names of the event interface use a `_glfwInput` prefix and the -ObjectEvent pattern. - -Examples: @ref _glfwInputWindowFocus, @ref _glfwInputCursorMotion - - -@section internals_static Static functions - -Static functions may be used by any interface and have no prefixes or suffixes. -These use headless camel case. - -Examples: `clearScrollOffsets` - - -@section internals_config Configuration macros - -GLFW uses a number of configuration macros to select at compile time which -interfaces and code paths to use. They are defined in the glfw_config.h header file, -which is generated from the `glfw_config.h.in` file by CMake. - -Configuration macros the same style as tokens in the public interface, except -with a leading underscore. - -Examples: `_GLFW_HAS_GLXGETPROCADDRESS` - -*/ diff --git a/examples/common/glfw/docs/intro.dox b/examples/common/glfw/docs/intro.dox deleted file mode 100644 index 7888e5fd..00000000 --- a/examples/common/glfw/docs/intro.dox +++ /dev/null @@ -1,347 +0,0 @@ -/*! - -@page intro Introduction to the API - -@tableofcontents - -This guide introduces the basic concepts of GLFW and describes initialization, -error handling and API guarantees and limitations. For a broad but shallow -tutorial, see @ref quick instead. There are also guides for the other areas of -GLFW. - - - @ref window - - @ref context - - @ref monitor - - @ref input - - -@section intro_init Initialization and termination - -Before most GLFW functions may be called, the library must be initialized. -This initialization checks what features are available on the machine, -enumerates monitors and joysticks, initializes the timer and performs any -required platform-specific initialization. - -Only the following functions may be called before the library has been -successfully initialized, and only from the main thread. - - - @ref glfwGetVersion - - @ref glfwGetVersionString - - @ref glfwSetErrorCallback - - @ref glfwInit - - @ref glfwTerminate - -Calling any other function before that time will cause a @ref -GLFW_NOT_INITIALIZED error. - - -@subsection intro_init_init Initializing GLFW - -The library is initialized with @ref glfwInit, which returns `GL_FALSE` if an -error occurred. - -@code -if (!glfwInit()) -{ - // Handle initialization failure -} -@endcode - -If any part of initialization fails, all remaining bits are terminated as if -@ref glfwTerminate was called. The library only needs to be initialized once -and additional calls to an already initialized library will simply return -`GL_TRUE` immediately. - -Once the library has been successfully initialized, it should be terminated -before the application exits. - - -@subsection intro_init_terminate Terminating GLFW - -Before your application exits, you should terminate the GLFW library if it has -been initialized. This is done with @ref glfwTerminate. - -@code -glfwTerminate(); -@endcode - -This will destroy any remaining window, monitor and cursor objects, restore any -modified gamma ramps, re-enable the screensaver if it had been disabled and free -any resources allocated by GLFW. - -Once the library is terminated, it is as if it had never been initialized and -you will need to initialize it again before being able to use GLFW. If the -library was not initialized or had already been terminated, it return -immediately. - - -@section error_handling Error handling - -Some GLFW functions have return values that indicate an error, but this is often -not very helpful when trying to figure out _why_ the error occurred. Some -functions also return otherwise valid values on error. Finally, far from all -GLFW functions have return values. - -This is where the error callback comes in. This callback is called whenever an -error occurs. It is set with @ref glfwSetErrorCallback, a function that may be -called regardless of whether GLFW is initialized. - -@code -glfwSetErrorCallback(error_callback); -@endcode - -The error callback receives a human-readable description of the error and (when -possible) its cause. The description encoded as UTF-8. The callback is also -provided with an [error code](@ref errors). - -@code -void error_callback(int error, const char* description) -{ - puts(description); -} -@endcode - -The error code indicates the general category of the error. Some error codes, -such as @ref GLFW_NOT_INITIALIZED has only a single meaning, whereas others like -@ref GLFW_PLATFORM_ERROR are used for many different errors. - -The description string is only valid until the error callback returns, as it may -have been generated specifically for that error. This lets GLFW provide much -more specific error descriptions but means you must make a copy if you want to -keep the description string. - - -@section coordinate_systems Coordinate systems - -GLFW has two primary coordinate systems: the _virtual screen_ and the window -_client area_ or _content area_. Both use the same unit: _virtual screen -coordinates_, or just _screen coordinates_, which don't necessarily correspond -to pixels. - - - -Both the virtual screen and the client area coordinate systems have the X-axis -pointing to the right and the Y-axis pointing down. - -Window and monitor positions are specified as the position of the upper-left -corners of their content areas relative to the virtual screen, while cursor -positions are specified relative to a window's client area. - -Because the origin of the window's client area coordinate system is also the -point from which the window position is specified, you can translate client area -coordinates to the virtual screen by adding the window position. The window -frame, when present, extends out from the client area but does not affect the -window position. - -Almost all positions and sizes in GLFW are measured in screen coordinates -relative to one of the two origins above. This includes cursor positions, -window positions and sizes, window frame sizes, monitor positions and video mode -resolutions. - -Two exceptions are the [monitor physical size](@ref monitor_size), which is -measured in millimetres, and [framebuffer size](@ref window_fbsize), which is -measured in pixels. - -Pixels and screen coordinates may map 1:1 on your machine, but they won't on -every other machine, for example on a Mac with a Retina display. The ratio -between screen coordinates and pixels may also change at run-time depending on -which monitor the window is currently considered to be on. - - -@section guarantees_limitations Guarantees and limitations - -This section describes the conditions under which GLFW can be expected to -function, barring bugs in the operating system or drivers. Use of GLFW outside -of these limits may work on some platforms, or on some machines, or some of the -time, or on some versions of GLFW, but it may break at any time and this will -not be considered a bug. - - -@subsection lifetime Pointer lifetimes - -GLFW will never free any pointer you provide to it and you must never free any -pointer it provides to you. - -Many GLFW functions return pointers to dynamically allocated structures, strings -or arrays, and some callbacks are provided with strings or arrays. These are -always managed by GLFW and should never be freed by the application. The -lifetime of these pointers is documented for each GLFW function and callback. -If you need to keep this data, you must copy it before its lifetime expires. - -Many GLFW functions accept pointers to structures or strings allocated by the -application. These are never freed by GLFW and are always the responsibility of -the application. If GLFW needs to keep the data in these structures or strings, -it is copied before the function returns. - -Pointer lifetimes are guaranteed not to be shortened in future minor or patch -releases. - - -@subsection reentrancy Reentrancy - -GLFW event processing and object creation and destruction are not reentrant. -This means that the following functions may not be called from any callback -function: - - - @ref glfwCreateWindow - - @ref glfwDestroyWindow - - @ref glfwCreateCursor - - @ref glfwCreateStandardCursor - - @ref glfwDestroyCursor - - @ref glfwPollEvents - - @ref glfwWaitEvents - - @ref glfwTerminate - -These functions may be made reentrant in future minor or patch releases, but -functions not on this list will not be made non-reentrant. - - -@subsection thread_safety Thread safety - -Most GLFW functions may only be called from the main thread, but some may be -called from any thread. However, no GLFW function may be called from any other -thread until GLFW has been successfully initialized on the main thread, -including functions that may called before initialization. - -The reference documentation for every GLFW function states whether it is limited -to the main thread. - -The following categories of functions are and will remain limited to the main -thread due to the limitations of one or several platforms: - - - Initialization and termination - - Event processing - - Creation and destruction of window, context and cursor objects - -Because event processing must be performed on the main thread, all callbacks -except for the error callback will only be called on that thread. The error -callback may be called on any thread, as any GLFW function may generate errors. - -The posting of empty events may be done from any thread. The window user -pointer and close flag may also be accessed and modified from any thread, but -this is not synchronized by GLFW. The following window related functions may -be called from any thread: - - - @ref glfwPostEmptyEvent - - @ref glfwGetWindowUserPointer - - @ref glfwSetWindowUserPointer - - @ref glfwWindowShouldClose - - @ref glfwSetWindowShouldClose - -Rendering may be done on any thread. The following context related functions -may be called from any thread: - - - @ref glfwMakeContextCurrent - - @ref glfwGetCurrentContext - - @ref glfwSwapBuffers - - @ref glfwSwapInterval - - @ref glfwExtensionSupported - - @ref glfwGetProcAddress - -The timer may be accessed from any thread, but this is not synchronized by GLFW. -The following timer related functions may be called from any thread: - - - @ref glfwGetTime - -Library version information may be queried from any thread. The following -version related functions may be called from any thread: - - - @ref glfwGetVersion - - @ref glfwGetVersionString - -GLFW uses no synchronization objects internally except for thread-local storage -to keep track of the current context for each thread. Synchronization is left -to the application. - -Functions that may currently be called from any thread will always remain so, -but functions that are currently limited to the main may be updated to allow -calls from any thread in future releases. - - -@subsection compatibility Version compatibility - -GLFW guarantees binary backward compatibility with earlier minor versions of the -API. This means that you can drop in a newer version of the GLFW DLL / shared -library / dynamic library and existing applications will continue to run. - -Once a function or constant has been added, the signature of that function or -value of that constant will remain unchanged until the next major version of -GLFW. No compatibility of any kind is guaranteed between major versions. - -Undocumented behavior, i.e. behavior that is not described in the documentation, -may change at any time until it is documented. - -If the reference documentation and the implementation differ, the reference -documentation is correct and the implementation will be fixed in the next -release. - - -@subsection event_order Event order - -The order of arrival of related events is not guaranteed to be consistent -across platforms. The exception is synthetic key and mouse button release -events, which are always delivered after the window defocus event. - - -@section intro_version Version management - -GLFW provides mechanisms for identifying what version of GLFW your application -was compiled against as well as what version it is currently running against. -If you are loading GLFW dynamically (not just linking dynamically), you can use -this to verify that the library binary is compatible with your application. - - -@subsection intro_version_compile Compile-time version - -The compile-time version of GLFW is provided by the GLFW header with the -`GLFW_VERSION_MAJOR`, `GLFW_VERSION_MINOR` and `GLFW_VERSION_REVISION` macros. - -@code -printf("Compiled against GLFW %i.%i.%i\n", - GLFW_VERSION_MAJOR, - GLFW_VERSION_MINOR, - GLFW_VERSION_REVISION); -@endcode - - -@subsection intro_version_runtime Run-time version - -The run-time version can be retrieved with @ref glfwGetVersion, a function that -may be called regardless of whether GLFW is initialized. - -@code -int major, minor, revision; -glfwGetVersion(&major, &minor, &revision); - -printf("Running against GLFW %i.%i.%i\n", major, minor, revision); -@endcode - - -@subsection intro_version_string Version string - -GLFW 3 also provides a compile-time generated version string that describes the -version, platform, compiler and any platform-specific compile-time options. -This is primarily intended for submitting bug reports, to allow developers to -see which code paths are enabled in a binary. - -The version string is returned by @ref glfwGetVersionString, a function that may -be called regardless of whether GLFW is initialized. - -__Do not use the version string__ to parse the GLFW library version. The @ref -glfwGetVersion function already provides the version of the running library -binary. - -The format of the string is as follows: - - The version of GLFW - - The name of the window system API - - The name of the context creation API - - Any additional options or APIs - -For example, when compiling GLFW 3.0 with MinGW using the Win32 and WGL -back ends, the version string may look something like this: - -@code -3.0.0 Win32 WGL MinGW -@endcode - -*/ diff --git a/examples/common/glfw/docs/main.dox b/examples/common/glfw/docs/main.dox deleted file mode 100644 index e5caae0d..00000000 --- a/examples/common/glfw/docs/main.dox +++ /dev/null @@ -1,47 +0,0 @@ -/*! - -@mainpage notitle - -@section main_intro Introduction - -__GLFW__ is a free, Open Source, multi-platform library for creating windows -with OpenGL or OpenGL ES contexts and receiving many kinds of input. It is easy -to integrate into existing applications and does not lay claim to the main loop. - -See @ref news_31 for release highlights or the -[version history](http://www.glfw.org/changelog.html) for details. - -@ref quick is a guide for those new to GLFW. It takes you through how to write -a small but complete program. For people coming from GLFW 2, the @ref moving -guide explains what has changed and how to update existing code to use the new -API. - -There are guides for each of the various areas of the API. - - - @ref intro – initialization, error handling and high-level design - - @ref window – creating and working with windows and framebuffers - - @ref context – working with OpenGL and OpenGL ES contexts - - @ref monitor – enumerating and working with monitors and video modes - - @ref input – receiving events, polling and processing input - -Once you have written a program, see the @ref compile and @ref build guides. - -The [reference documentation](modules.html) provides more detailed information -about specific functions. - -There is a section on @ref guarantees_limitations for pointer lifetimes, -reentrancy, thread safety, event order and backward and forward compatibility. - -The @ref rift fills in the gaps for how to use LibOVR with GLFW. - -The [FAQ](http://www.glfw.org/faq.html) answers many common questions about the -design, implementation and use of GLFW. - -Finally, the @ref compat guide explains what APIs, standards and protocols GLFW -uses and what happens when they are not present on a given machine. - -This documentation was generated with Doxygen. The sources for it are available -in both the [source distribution](http://www.glfw.org/download.html) and -[GitHub repository](https://github.com/glfw/glfw). - -*/ diff --git a/examples/common/glfw/docs/monitor.dox b/examples/common/glfw/docs/monitor.dox deleted file mode 100644 index 8a5c5d90..00000000 --- a/examples/common/glfw/docs/monitor.dox +++ /dev/null @@ -1,204 +0,0 @@ -/*! - -@page monitor Monitor guide - -@tableofcontents - -This guide introduces the monitor related functions of GLFW. There are also -guides for the other areas of GLFW. - - - @ref intro - - @ref window - - @ref context - - @ref input - - -@section monitor_object Monitor objects - -A monitor object represents a currently connected monitor and is represented as -a pointer to the [opaque](https://en.wikipedia.org/wiki/Opaque_data_type) type -@ref GLFWmonitor. Monitor objects cannot be created or destroyed by the -application and retain their addresses until the monitors they represent are -disconnected or until the library is [terminated](@ref intro_init_terminate). - -Each monitor has a current video mode, a list of supported video modes, -a virtual position, a human-readable name, an estimated physical size and -a gamma ramp. One of the monitors is the primary monitor. - -The virtual position of a monitor is in -[screen coordinates](@ref coordinate_systems) and, together with the current -video mode, describes the viewports that the connected monitors provide into the -virtual desktop that spans them. - -To see how GLFW views your monitor setup and its available video modes, run the -`modes` test program. - - -@subsection monitor_monitors Retrieving monitors - -The primary monitor is returned by @ref glfwGetPrimaryMonitor. It is the user's -preferred monitor and is usually the one with global UI elements like task bar -or menu bar. - -@code -GLFWmonitor* primary = glfwGetPrimaryMonitor(); -@endcode - -You can retrieve all currently connected monitors with @ref glfwGetMonitors. -See the reference documentation for the lifetime of the returned array. - -@code -int count; -GLFWmonitor** monitors = glfwGetMonitors(&count); -@endcode - -The primary monitor is always the first monitor in the returned array, but other -monitors may be moved to a different index when a monitor is connected or -disconnected. - - -@subsection monitor_event Monitor configuration changes - -If you wish to be notified when a monitor is connected or disconnected, set -a monitor callback. - -@code -glfwSetMonitorCallback(monitor_callback); -@endcode - -The callback function receives the handle for the monitor that has been -connected or disconnected and a monitor action. - -@code -void monitor_callback(GLFWmonitor* monitor, int event) -{ -} -@endcode - -The action is one of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`. - - -@section monitor_properties Monitor properties - -Each monitor has a current video mode, a list of supported video modes, -a virtual position, a human-readable name, an estimated physical size and -a gamma ramp. - - -@subsection monitor_modes Video modes - -GLFW generally does a good job selecting a suitable video mode when you create -a full screen window, but it is sometimes useful to know exactly which video -modes are supported. - -Video modes are represented as @ref GLFWvidmode structures. You can get an -array of the video modes supported by a monitor with @ref glfwGetVideoModes. -See the reference documentation for the lifetime of the returned array. - -@code -int count; -GLFWvidmode* modes = glfwGetVideoModes(monitor, &count); -@endcode - -To get the current video mode of a monitor call @ref glfwGetVideoMode. See the -reference documentation for the lifetime of the returned pointer. - -@code -const GLFWvidmode* mode = glfwGetVideoMode(monitor); -@endcode - -The resolution of a video mode is specified in -[screen coordinates](@ref coordinate_systems), not pixels. - - -@subsection monitor_size Physical size - -The physical size of a monitor in millimetres, or an estimation of it, can be -retrieved with @ref glfwGetMonitorPhysicalSize. This has no relation to its -current _resolution_, i.e. the width and height of its current -[video mode](@ref monitor_modes). - -@code -int widthMM, heightMM; -glfwGetMonitorPhysicalSize(monitor, &widthMM, &heightMM); -@endcode - -This can, for example, be used together with the current video mode to calculate -the DPI of a monitor. - -@code -const double dpi = mode->width / (widthMM / 25.4); -@endcode - - -@subsection monitor_pos Virtual position - -The position of the monitor on the virtual desktop, in -[screen coordinates](@ref coordinate_systems), can be retrieved with @ref -glfwGetMonitorPos. - -@code -int xpos, ypos; -glfwGetMonitorPos(monitor, &xpos, &ypos); -@endcode - - -@subsection monitor_name Human-readable name - -The human-readable, UTF-8 encoded name of a monitor is returned by @ref -glfwGetMonitorName. See the reference documentation for the lifetime of the -returned string. - -@code -const char* name = glfwGetMonitorName(monitor); -@endcode - -Monitor names are not guaranteed to be unique. Two monitors of the same model -and make may have the same name. Only the monitor handle is guaranteed to be -unique, and only until that monitor is disconnected. - - -@subsection monitor_gamma Gamma ramp - -The gamma ramp of a monitor can be set with @ref glfwSetGammaRamp, which accepts -a monitor handle and a pointer to a @ref GLFWgammaramp structure. - -@code -GLFWgammaramp ramp; -unsigned short red[256], green[256], blue[256]; - -ramp.size = 256; -ramp.red = red; -ramp.green = green; -ramp.blue = blue; - -for (i = 0; i < ramp.size; i++) -{ - // Fill out gamma ramp arrays as desired -} - -glfwSetGammaRamp(monitor, &ramp); -@endcode - -The gamma ramp data is copied before the function returns, so there is no need -to keep it around once the ramp has been set. - -@note It is recommended to use gamma ramps of size 256, as that is the size -supported by all graphics cards on all platforms. - -The current gamma ramp for a monitor is returned by @ref glfwGetGammaRamp. See -the reference documentation for the lifetime of the returned structure. - -@code -const GLFWgammaramp* ramp = glfwGetGammaRamp(monitor); -@endcode - -If you wish to set a regular gamma ramp, you can have GLFW calculate it for you -from the desired exponent with @ref glfwSetGamma, which in turn calls @ref -glfwSetGammaRamp with the resulting ramp. - -@code -glfwSetGamma(monitor, 1.0); -@endcode - -*/ diff --git a/examples/common/glfw/docs/moving.dox b/examples/common/glfw/docs/moving.dox deleted file mode 100644 index 0e7ed5e3..00000000 --- a/examples/common/glfw/docs/moving.dox +++ /dev/null @@ -1,494 +0,0 @@ -/*! - -@page moving Moving from GLFW 2 to 3 - -@tableofcontents - -This is a transition guide for moving from GLFW 2 to 3. It describes what has -changed or been removed, but does _not_ include -[new features](@ref news) unless they are required when moving an existing code -base onto the new API. For example, the new multi-monitor functions are -required to create full screen windows with GLFW 3. - - -@section moving_removed Changed and removed features - -@subsection moving_renamed_files Renamed library and header file - -The GLFW 3 header is named @ref glfw3.h and moved to the `GLFW` directory, to -avoid collisions with the headers of other major versions. Similarly, the GLFW -3 library is named `glfw3,` except when it's installed as a shared library on -Unix-like systems, where it uses the -[soname](https://en.wikipedia.org/wiki/soname) `libglfw.so.3`. - -@par Old syntax -@code -#include -@endcode - -@par New syntax -@code -#include -@endcode - - -@subsection moving_threads Removal of threading functions - -The threading functions have been removed, including the per-thread sleep -function. They were fairly primitive, under-used, poorly integrated and took -time away from the focus of GLFW (i.e. context, input and window). There are -better threading libraries available and native threading support is available -in both [C++11](http://en.cppreference.com/w/cpp/thread) and -[C11](http://en.cppreference.com/w/c/thread), both of which are gaining -traction. - -If you wish to use the C++11 or C11 facilities but your compiler doesn't yet -support them, see the -[TinyThread++](https://gitorious.org/tinythread/tinythreadpp) and -[TinyCThread](https://github.com/tinycthread/tinycthread) projects created by -the original author of GLFW. These libraries implement a usable subset of the -threading APIs in C++11 and C11, and in fact some GLFW 3 test programs use -TinyCThread. - -However, GLFW 3 has better support for _use from multiple threads_ than GLFW -2 had. Contexts can be made current on any thread, although only a single -thread at a time, and the documentation explicitly states which functions may be -used from any thread and which may only be used from the main thread. - -@par Removed functions -`glfwSleep`, `glfwCreateThread`, `glfwDestroyThread`, `glfwWaitThread`, -`glfwGetThreadID`, `glfwCreateMutex`, `glfwDestroyMutex`, `glfwLockMutex`, -`glfwUnlockMutex`, `glfwCreateCond`, `glfwDestroyCond`, `glfwWaitCond`, -`glfwSignalCond`, `glfwBroadcastCond` and `glfwGetNumberOfProcessors`. - - -@subsection moving_image Removal of image and texture loading - -The image and texture loading functions have been removed. They only supported -the Targa image format, making them mostly useful for beginner level examples. -To become of sufficiently high quality to warrant keeping them in GLFW 3, they -would need not only to support other formats, but also modern extensions to -OpenGL texturing. This would either add a number of external -dependencies (libjpeg, libpng, etc.), or force GLFW to ship with inline versions -of these libraries. - -As there already are libraries doing this, it is unnecessary both to duplicate -the work and to tie the duplicate to GLFW. The resulting library would also be -platform-independent, as both OpenGL and stdio are available wherever GLFW is. - -@par Removed functions -`glfwReadImage`, `glfwReadMemoryImage`, `glfwFreeImage`, `glfwLoadTexture2D`, -`glfwLoadMemoryTexture2D` and `glfwLoadTextureImage2D`. - - -@subsection moving_stdcall Removal of GLFWCALL macro - -The `GLFWCALL` macro, which made callback functions use -[__stdcall](http://msdn.microsoft.com/en-us/library/zxk0tw93.aspx) on Windows, -has been removed. GLFW is written in C, not Pascal. Removing this macro means -there's one less thing for application programmers to remember, i.e. the -requirement to mark all callback functions with `GLFWCALL`. It also simplifies -the creation of DLLs and DLL link libraries, as there's no need to explicitly -disable `@n` entry point suffixes. - -@par Old syntax -@code -void GLFWCALL callback_function(...); -@endcode - -@par New syntax -@code -void callback_function(...); -@endcode - - -@subsection moving_window_handles Window handle parameters - -Because GLFW 3 supports multiple windows, window handle parameters have been -added to all window-related GLFW functions and callbacks. The handle of -a newly created window is returned by @ref glfwCreateWindow (formerly -`glfwOpenWindow`). Window handles are pointers to the -[opaque](https://en.wikipedia.org/wiki/Opaque_data_type) type @ref GLFWwindow. - -@par Old syntax -@code -glfwSetWindowTitle("New Window Title"); -@endcode - -@par New syntax -@code -glfwSetWindowTitle(window, "New Window Title"); -@endcode - - -@subsection moving_monitor Explicit monitor selection - -GLFW 3 provides support for multiple monitors. To request a full screen mode window, -instead of passing `GLFW_FULLSCREEN` you specify which monitor you wish the -window to use. The @ref glfwGetPrimaryMonitor function returns the monitor that -GLFW 2 would have selected, but there are many other -[monitor functions](@ref monitor). Monitor handles are pointers to the -[opaque](https://en.wikipedia.org/wiki/Opaque_data_type) type @ref GLFWmonitor. - -@par Old basic full screen -@code -glfwOpenWindow(640, 480, 8, 8, 8, 0, 24, 0, GLFW_FULLSCREEN); -@endcode - -@par New basic full screen -@code -window = glfwCreateWindow(640, 480, "My Window", glfwGetPrimaryMonitor(), NULL); -@endcode - -@note The framebuffer bit depth parameters of `glfwOpenWindow` have been turned -into [window hints](@ref window_hints), but as they have been given -[sane defaults](@ref window_hints_values) you rarely need to set these hints. - - -@subsection moving_autopoll Removal of automatic event polling - -GLFW 3 does not automatically poll for events in @ref glfwSwapBuffers, meaning -you need to call @ref glfwPollEvents or @ref glfwWaitEvents yourself. Unlike -buffer swap, which acts on a single window, the event processing functions act -on all windows at once. - -@par Old basic main loop -@code -while (...) -{ - // Process input - // Render output - glfwSwapBuffers(); -} -@endcode - -@par New basic main loop -@code -while (...) -{ - // Process input - // Render output - glfwSwapBuffers(window); - glfwPollEvents(); -} -@endcode - - -@subsection moving_context Explicit context management - -Each GLFW 3 window has its own OpenGL context and only you, the application -programmer, can know which context should be current on which thread at any -given time. Therefore, GLFW 3 leaves that decision to you. - -This means that you need to call @ref glfwMakeContextCurrent after creating -a window before you can call any OpenGL functions. - - -@subsection moving_hidpi Separation of window and framebuffer sizes - -Window positions and sizes now use screen coordinates, which may not be the same -as pixels on machines with high-DPI monitors. This is important as OpenGL uses -pixels, not screen coordinates. For example, the rectangle specified with -`glViewport` needs to use pixels. Therefore, framebuffer size functions have -been added. You can retrieve the size of the framebuffer of a window with @ref -glfwGetFramebufferSize function. A framebuffer size callback has also been -added, which can be set with @ref glfwSetFramebufferSizeCallback. - -@par Old basic viewport setup -@code -glfwGetWindowSize(&width, &height); -glViewport(0, 0, width, height); -@endcode - -@par New basic viewport setup -@code -glfwGetFramebufferSize(window, &width, &height); -glViewport(0, 0, width, height); -@endcode - - -@subsection moving_window_close Window closing changes - -The `GLFW_OPENED` window parameter has been removed. As long as the window has -not been destroyed, whether through @ref glfwDestroyWindow or @ref -glfwTerminate, the window is "open". - -A user attempting to close a window is now just an event like any other. Unlike -GLFW 2, windows and contexts created with GLFW 3 will never be destroyed unless -you choose them to be. Each window now has a close flag that is set to -`GL_TRUE` when the user attempts to close that window. By default, nothing else -happens and the window stays visible. It is then up to you to either destroy -the window, take some other action or simply ignore the request. - -You can query the close flag at any time with @ref glfwWindowShouldClose and set -it at any time with @ref glfwSetWindowShouldClose. - -@par Old basic main loop -@code -while (glfwGetWindowParam(GLFW_OPENED)) -{ - ... -} -@endcode - -@par New basic main loop -@code -while (!glfwWindowShouldClose(window)) -{ - ... -} -@endcode - -The close callback no longer returns a value. Instead, it is called after the -close flag has been set so it can override its value, if it chooses to, before -event processing completes. You may however not call @ref glfwDestroyWindow -from the close callback (or any other window related callback). - -@par Old syntax -@code -int GLFWCALL window_close_callback(void); -@endcode - -@par New syntax -@code -void window_close_callback(GLFWwindow* window); -@endcode - -@note GLFW never clears the close flag to `GL_FALSE`, meaning you can use it -for other reasons to close the window as well, for example the user choosing -Quit from an in-game menu. - - -@subsection moving_hints Persistent window hints - -The `glfwOpenWindowHint` function has been renamed to @ref glfwWindowHint. - -Window hints are no longer reset to their default values on window creation, but -instead retain their values until modified by @ref glfwWindowHint or @ref -glfwDefaultWindowHints, or until the library is terminated and re-initialized. - - -@subsection moving_video_modes Video mode enumeration - -Video mode enumeration is now per-monitor. The @ref glfwGetVideoModes function -now returns all available modes for a specific monitor instead of requiring you -to guess how large an array you need. The `glfwGetDesktopMode` function, which -had poorly defined behavior, has been replaced by @ref glfwGetVideoMode, which -returns the current mode of a monitor. - - -@subsection moving_char_up Removal of character actions - -The action parameter of the [character callback](@ref GLFWcharfun) has been -removed. This was an artefact of the origin of GLFW, i.e. being developed in -English by a Swede. However, many keyboard layouts require more than one key to -produce characters with diacritical marks. Even the Swedish keyboard layout -requires this for uncommon cases like ü. - -@par Old syntax -@code -void GLFWCALL character_callback(int character, int action); -@endcode - -@par New syntax -@code -void character_callback(GLFWwindow* window, int character); -@endcode - - -@subsection moving_cursorpos Cursor position changes - -The `glfwGetMousePos` function has been renamed to @ref glfwGetCursorPos, -`glfwSetMousePos` to @ref glfwSetCursorPos and `glfwSetMousePosCallback` to @ref -glfwSetCursorPosCallback. - -The cursor position is now `double` instead of `int`, both for the direct -functions and for the callback. Some platforms can provide sub-pixel cursor -movement and this data is now passed on to the application where available. On -platforms where this is not provided, the decimal part is zero. - -GLFW 3 only allows you to position the cursor within a window using @ref -glfwSetCursorPos (formerly `glfwSetMousePos`) when that window is active. -Unless the window is active, the function fails silently. - - -@subsection moving_wheel Wheel position replaced by scroll offsets - -The `glfwGetMouseWheel` function has been removed. Scrolling is the input of -offsets and has no absolute position. The mouse wheel callback has been -replaced by a [scroll callback](@ref GLFWscrollfun) that receives -two-dimensional floating point scroll offsets. This allows you to receive -precise scroll data from for example modern touchpads. - -@par Old syntax -@code -void GLFWCALL mouse_wheel_callback(int position); -@endcode - -@par New syntax -@code -void scroll_callback(GLFWwindow* window, double xoffset, double yoffset); -@endcode - -@par Removed functions -`glfwGetMouseWheel` - - -@subsection moving_repeat Key repeat action - -The `GLFW_KEY_REPEAT` enable has been removed and key repeat is always enabled -for both keys and characters. A new key action, `GLFW_REPEAT`, has been added -to allow the [key callback](@ref GLFWkeyfun) to distinguish an initial key press -from a repeat. Note that @ref glfwGetKey still returns only `GLFW_PRESS` or -`GLFW_RELEASE`. - - -@subsection moving_keys Physical key input - -GLFW 3 key tokens map to physical keys, unlike in GLFW 2 where they mapped to -the values generated by the current keyboard layout. The tokens are named -according to the values they would have using the standard US layout, but this -is only a convenience, as most programmers are assumed to know that layout. -This means that (for example) `GLFW_KEY_LEFT_BRACKET` is always a single key and -is the same key in the same place regardless of what keyboard layouts the users -of your program has. - -The key input facility was never meant for text input, although using it that -way worked slightly better in GLFW 2. If you were using it to input text, you -should be using the character callback instead, on both GLFW 2 and 3. This will -give you the characters being input, as opposed to the keys being pressed. - -GLFW 3 has key tokens for all keys on a standard 105 key keyboard, so instead of -having to remember whether to check for `'a'` or `'A'`, you now check for -`GLFW_KEY_A`. - - -@subsection moving_joystick Joystick function changes - -The `glfwGetJoystickPos` function has been renamed to @ref glfwGetJoystickAxes. - -The `glfwGetJoystickParam` function and the `GLFW_PRESENT`, `GLFW_AXES` and -`GLFW_BUTTONS` tokens have been replaced by the @ref glfwJoystickPresent -function as well as axis and button counts returned by the @ref -glfwGetJoystickAxes and @ref glfwGetJoystickButtons functions. - - -@subsection moving_mbcs Win32 MBCS support - -The Win32 port of GLFW 3 will not compile in -[MBCS mode](http://msdn.microsoft.com/en-us/library/5z097dxa.aspx). -However, because the use of the Unicode version of the Win32 API doesn't affect -the process as a whole, but only those windows created using it, it's perfectly -possible to call MBCS functions from other parts of the same application. -Therefore, even if an application using GLFW has MBCS mode code, there's no need -for GLFW itself to support it. - - -@subsection moving_windows Support for versions of Windows older than XP - -All explicit support for version of Windows older than XP has been removed. -There is no code that actively prevents GLFW 3 from running on these earlier -versions, but it uses Win32 functions that those versions lack. - -Windows XP was released in 2001, and by now (January 2015) it has not only -replaced almost all earlier versions of Windows, but is itself rapidly being -replaced by Windows 7 and 8. The MSDN library doesn't even provide -documentation for version older than Windows 2000, making it difficult to -maintain compatibility with these versions even if it was deemed worth the -effort. - -The Win32 API has also not stood still, and GLFW 3 uses many functions only -present on Windows XP or later. Even supporting an OS as new as XP (new -from the perspective of GLFW 2, which still supports Windows 95) requires -runtime checking for a number of functions that are present only on modern -version of Windows. - - -@subsection moving_syskeys Capture of system-wide hotkeys - -The ability to disable and capture system-wide hotkeys like Alt+Tab has been -removed. Modern applications, whether they're games, scientific visualisations -or something else, are nowadays expected to be good desktop citizens and allow -these hotkeys to function even when running in full screen mode. - - -@subsection moving_terminate Automatic termination - -GLFW 3 does not register @ref glfwTerminate with `atexit` at initialization, -because `exit` calls registered functions from the calling thread and while it -is permitted to call `exit` from any thread, @ref glfwTerminate may only be -called from the main thread. - -To release all resources allocated by GLFW, you should call @ref glfwTerminate -yourself, from the main thread, before the program terminates. Note that this -destroys all windows not already destroyed with @ref glfwDestroyWindow, -invalidating any window handles you may still have. - - -@subsection moving_glu GLU header inclusion - -GLFW 3 does not by default include the GLU header and GLU itself has been -deprecated by [Khronos](https://en.wikipedia.org/wiki/Khronos_Group). __New -projects should avoid using GLU__, but if you need to compile legacy code that -has been moved to GLFW 3, you can request that the GLFW header includes it by -defining `GLFW_INCLUDE_GLU` before the inclusion of the GLFW header. - -@par Old syntax -@code -#include -@endcode - -@par New syntax -@code -#define GLFW_INCLUDE_GLU -#include -@endcode - - -@section moving_tables Name change tables - - -@subsection moving_renamed_functions Renamed functions - -| GLFW 2 | GLFW 3 | Notes | -| --------------------------- | ----------------------------- | ----- | -| `glfwOpenWindow` | @ref glfwCreateWindow | All channel bit depths are now hints -| `glfwCloseWindow` | @ref glfwDestroyWindow | | -| `glfwOpenWindowHint` | @ref glfwWindowHint | Now accepts all `GLFW_*_BITS` tokens | -| `glfwEnable` | @ref glfwSetInputMode | | -| `glfwDisable` | @ref glfwSetInputMode | | -| `glfwGetMousePos` | @ref glfwGetCursorPos | | -| `glfwSetMousePos` | @ref glfwSetCursorPos | | -| `glfwSetMousePosCallback` | @ref glfwSetCursorPosCallback | | -| `glfwSetMouseWheelCallback` | @ref glfwSetScrollCallback | Accepts two-dimensional scroll offsets as doubles | -| `glfwGetJoystickPos` | @ref glfwGetJoystickAxes | | -| `glfwGetWindowParam` | @ref glfwGetWindowAttrib | | -| `glfwGetGLVersion` | @ref glfwGetWindowAttrib | Use `GLFW_CONTEXT_VERSION_MAJOR`, `GLFW_CONTEXT_VERSION_MINOR` and `GLFW_CONTEXT_REVISION` | -| `glfwGetDesktopMode` | @ref glfwGetVideoMode | Returns the current mode of a monitor | -| `glfwGetJoystickParam` | @ref glfwJoystickPresent | The axis and button counts are provided by @ref glfwGetJoystickAxes and @ref glfwGetJoystickButtons | - -@subsection moving_renamed_tokens Renamed tokens - -| GLFW 2 | GLFW 3 | Notes | -| --------------------------- | ---------------------------- | ----- | -| `GLFW_OPENGL_VERSION_MAJOR` | `GLFW_CONTEXT_VERSION_MAJOR` | Renamed as it applies to OpenGL ES as well | -| `GLFW_OPENGL_VERSION_MINOR` | `GLFW_CONTEXT_VERSION_MINOR` | Renamed as it applies to OpenGL ES as well | -| `GLFW_FSAA_SAMPLES` | `GLFW_SAMPLES` | Renamed to match the OpenGL API | -| `GLFW_ACTIVE` | `GLFW_FOCUSED` | Renamed to match the window focus callback | -| `GLFW_WINDOW_NO_RESIZE` | `GLFW_RESIZABLE` | The default has been inverted | -| `GLFW_MOUSE_CURSOR` | `GLFW_CURSOR` | Used with @ref glfwSetInputMode | -| `GLFW_KEY_ESC` | `GLFW_KEY_ESCAPE` | | -| `GLFW_KEY_DEL` | `GLFW_KEY_DELETE` | | -| `GLFW_KEY_PAGEUP` | `GLFW_KEY_PAGE_UP` | | -| `GLFW_KEY_PAGEDOWN` | `GLFW_KEY_PAGE_DOWN` | | -| `GLFW_KEY_KP_NUM_LOCK` | `GLFW_KEY_NUM_LOCK` | | -| `GLFW_KEY_LCTRL` | `GLFW_KEY_LEFT_CONTROL` | | -| `GLFW_KEY_LSHIFT` | `GLFW_KEY_LEFT_SHIFT` | | -| `GLFW_KEY_LALT` | `GLFW_KEY_LEFT_ALT` | | -| `GLFW_KEY_LSUPER` | `GLFW_KEY_LEFT_SUPER` | | -| `GLFW_KEY_RCTRL` | `GLFW_KEY_RIGHT_CONTROL` | | -| `GLFW_KEY_RSHIFT` | `GLFW_KEY_RIGHT_SHIFT` | | -| `GLFW_KEY_RALT` | `GLFW_KEY_RIGHT_ALT` | | -| `GLFW_KEY_RSUPER` | `GLFW_KEY_RIGHT_SUPER` | | - -*/ diff --git a/examples/common/glfw/docs/news.dox b/examples/common/glfw/docs/news.dox deleted file mode 100644 index 8ae36aa1..00000000 --- a/examples/common/glfw/docs/news.dox +++ /dev/null @@ -1,292 +0,0 @@ -/*! - -@page news New features - -@section news_31 New features in 3.1 - -These are the release highlights. For a full list of changes see the -[version history](http://www.glfw.org/changelog.html). - - -@subsection news_31_cursor Custom mouse cursor images - -GLFW now supports creating and setting both custom cursor images and standard -cursor shapes. They are created with @ref glfwCreateCursor or @ref -glfwCreateStandardCursor, set with @ref glfwSetCursor and destroyed with @ref -glfwDestroyCursor. - -@see @ref cursor_object - - -@subsection news_31_drop Path drop event - -GLFW now provides a callback for receiving the paths of files and directories -dropped onto GLFW windows. The callback is set with @ref glfwSetDropCallback. - -@see @ref path_drop - - -@subsection news_31_emptyevent Main thread wake-up - -GLFW now provides the @ref glfwPostEmptyEvent function for posting an empty -event from another thread to the main thread event queue, causing @ref -glfwWaitEvents to return. - -@see @ref events - - -@subsection news_31_framesize Window frame size query - -GLFW now supports querying the size, on each side, of the frame around the -client area of a window, with @ref glfwGetWindowFrameSize. - -@see [Window size](@ref window_size) - - -@subsection news_31_autoiconify Simultaneous multi-monitor rendering - -GLFW now supports disabling auto-iconification of full screen windows with -the [GLFW_AUTO_ICONIFY](@ref window_hints_wnd) window hint. This is intended -for people building multi-monitor installations, where you need windows to stay -in full screen despite losing input focus. - - -@subsection news_31_floating Floating windows - -GLFW now supports floating windows, also called topmost or always on top, for -easier debugging with the [GLFW_FLOATING](@ref window_hints_wnd) window hint. - - -@subsection news_31_focused Initially unfocused windows - -GLFW now supports preventing a windowed mode window from gaining input focus on -creation, with the [GLFW_FOCUSED](@ref window_hints_wnd) window hint. - - -@subsection news_31_direct Direct access for window attributes and cursor position - -GLFW now queries the window input focus, visibility and iconification attributes -and the cursor position directly instead of returning cached data. - - -@subsection news_31_libovr Better interoperability with Oculus Rift - -GLFW now provides native access functions for the OS level handles corresponding -to monitor objects, as well as a [brief guide](@ref rift). It is also regularly -tested for compatibility with the latest version of LibOVR (0.4.4 on release). - - -@subsection news_31_charmods Character with modifiers callback - -GLFW now provides a callback for character events with modifier key bits. The -callback is set with @ref glfwSetCharModsCallback. Unlike the regular character -callback, this will report character events that will not result in a character -being input, for example if the Control key is held down. - -@see @ref input_char - - -@subsection news_31_single Single buffered framebuffers - -GLFW now supports the creation of single buffered windows, with the -[GLFW_DOUBLEBUFFER](@ref window_hints_fb) window hint. - - -@subsection news_31_glext Macro for including extension header - -GLFW now includes the extension header appropriate for the chosen OpenGL or -OpenGL ES header when [GLFW_INCLUDE_GLEXT](@ref build_macros) is defined. GLFW -does not provide these headers. They must be provided by your development -environment or your OpenGL or OpenGL ES SDK. - - -@subsection news_31_release Context release behaviors - -GLFW now supports controlling whether the pipeline is flushed when a context is -made non-current, with the -[GLFW_CONTEXT_RELEASE_BEHAVIOR](@ref window_hints_ctx) window hint, provided the -machine supports the `GL_KHR_context_flush_control` extension. - - -@subsection news_31_wayland (Experimental) Wayland support - -GLFW now has an _experimental_ Wayland display protocol backend that can be -selected on Linux with a CMake option. - - -@subsection news_31_mir (Experimental) Mir support - -GLFW now has an _experimental_ Mir display server backend that can be selected -on Linux with a CMake option. - - -@section news_30 New features in 3.0 - -These are the release highlights. For a full list of changes see the -[version history](http://www.glfw.org/changelog.html). - - -@subsection news_30_cmake CMake build system - -GLFW now uses the CMake build system instead of the various makefiles and -project files used by earlier versions. CMake is available for all platforms -supported by GLFW, is present in most package systems and can generate -makefiles and/or project files for most popular development environments. - -For more information on how to use CMake, see the -[CMake manual](http://cmake.org/cmake/help/documentation.html). - - -@subsection news_30_multiwnd Multi-window support - -GLFW now supports the creation of multiple windows, each with their own OpenGL -or OpenGL ES context, and all window functions now take a window handle. Event -callbacks are now per-window and are provided with the handle of the window that -received the event. The @ref glfwMakeContextCurrent function has been added to -select which context is current on a given thread. - - -@subsection news_30_multimon Multi-monitor support - -GLFW now explicitly supports multiple monitors. They can be enumerated with -@ref glfwGetMonitors, queried with @ref glfwGetVideoModes, @ref -glfwGetMonitorPos, @ref glfwGetMonitorName and @ref glfwGetMonitorPhysicalSize, -and specified at window creation to make the newly created window full screen on -that specific monitor. - - -@subsection news_30_unicode Unicode support - -All string arguments to GLFW functions and all strings returned by GLFW now use -the UTF-8 encoding. This includes the window title, error string, clipboard -text, monitor and joystick names as well as the extension function arguments (as -ASCII is a subset of UTF-8). - - -@subsection news_30_clipboard Clipboard text I/O - -GLFW now supports reading and writing plain text to and from the system -clipboard, with the @ref glfwGetClipboardString and @ref glfwSetClipboardString -functions. - - -@subsection news_30_gamma Gamma ramp support - -GLFW now supports setting and reading back the gamma ramp of monitors, with the -@ref glfwGetGammaRamp and @ref glfwSetGammaRamp functions. There is also @ref -glfwSetGamma, which generates a ramp from a gamma value and then sets it. - - -@subsection news_30_gles OpenGL ES support - -GLFW now supports the creation of OpenGL ES contexts, by setting the -`GLFW_CLIENT_API` window hint to `GLFW_OPENGL_ES_API`, where creation of such -contexts are supported. Note that GLFW _does not implement_ OpenGL ES, so your -driver must provide support in a way usable by GLFW. Modern Nvidia and Intel -drivers support creation of OpenGL ES context using the GLX and WGL APIs, while -AMD provides an EGL implementation instead. - - -@subsection news_30_egl (Experimental) EGL support - -GLFW now has an experimental EGL context creation back end that can be selected -through CMake options. - - -@subsection news_30_hidpi High-DPI support - -GLFW now supports high-DPI monitors on both Windows and OS X, giving windows full -resolution framebuffers where other UI elements are scaled up. To achieve this, -@ref glfwGetFramebufferSize and @ref glfwSetFramebufferSizeCallback have been -added. These work with pixels, while the rest of the GLFW API works with screen -coordinates. This is important as OpenGL uses pixels, not screen coordinates. - - -@subsection news_30_error Error callback - -GLFW now has an error callback, which can provide your application with much -more detailed diagnostics than was previously possible. The callback is passed -an error code and a description string. - - -@subsection news_30_wndptr Per-window user pointer - -Each window now has a user-defined pointer, retrieved with @ref -glfwGetWindowUserPointer and set with @ref glfwSetWindowUserPointer, to make it -easier to integrate GLFW into C++ code. - - -@subsection news_30_iconifyfun Window iconification callback - -Each window now has a callback for iconification and restoration events, -which is set with @ref glfwSetWindowIconifyCallback. - - -@subsection news_30_wndposfun Window position callback - -Each window now has a callback for position events, which is set with @ref -glfwSetWindowPosCallback. - - -@subsection news_30_wndpos Window position query - -The position of a window can now be retrieved using @ref glfwGetWindowPos. - - -@subsection news_30_focusfun Window focus callback - -Each windows now has a callback for focus events, which is set with @ref -glfwSetWindowFocusCallback. - - -@subsection news_30_enterleave Cursor enter/leave callback - -Each window now has a callback for when the mouse cursor enters or leaves its -client area, which is set with @ref glfwSetCursorEnterCallback. - - -@subsection news_30_wndtitle Initial window title - -The title of a window is now specified at creation time, as one of the arguments -to @ref glfwCreateWindow. - - -@subsection news_30_hidden Hidden windows - -Windows can now be hidden with @ref glfwHideWindow, shown using @ref -glfwShowWindow and created initially hidden with the `GLFW_VISIBLE` window hint. -This allows for off-screen rendering in a way compatible with most drivers, as -well as moving a window to a specific position before showing it. - - -@subsection news_30_undecorated Undecorated windows - -Windowed mode windows can now be created without decorations, i.e. things like -a frame, a title bar, with the `GLFW_DECORATED` window hint. This allows for -the creation of things like splash screens. - - -@subsection news_30_keymods Modifier key bit masks - -[Modifier key bit mask](@ref mods) parameters have been added to the -[mouse button](@ref GLFWmousebuttonfun) and [key](@ref GLFWkeyfun) callbacks. - - -@subsection news_30_scancode Platform-specific scancodes - -A scancode parameter has been added to the [key callback](@ref GLFWkeyfun). Keys -that don't have a [key token](@ref keys) still get passed on with the key -parameter set to `GLFW_KEY_UNKNOWN`. These scancodes will vary between machines -and are intended to be used for key bindings. - - -@subsection news_30_jsname Joystick names - -The name of a joystick can now be retrieved using @ref glfwGetJoystickName. - - -@subsection news_30_doxygen Doxygen documentation - -You are reading it. - -*/ diff --git a/examples/common/glfw/docs/quick.dox b/examples/common/glfw/docs/quick.dox deleted file mode 100644 index 12283a15..00000000 --- a/examples/common/glfw/docs/quick.dox +++ /dev/null @@ -1,328 +0,0 @@ -/*! - -@page quick Getting started - -@tableofcontents - -This guide takes you through writing a simple application using GLFW 3. The -application will create a window and OpenGL context, render a rotating triangle -and exit when the user closes the window or presses Escape. This guide will -introduce a few of the most commonly used functions, but there are many more. - -This guide assumes no experience with earlier versions of GLFW. If you -have used GLFW 2 in the past, read the @ref moving guide, as some functions -behave differently in GLFW 3. - - -@section quick_steps Step by step - -@subsection quick_include Including the GLFW header - -In the source files of your application where you use OpenGL or GLFW, you need -to include the GLFW 3 header file. - -@code -#include -@endcode - -This defines all the constants, types and function prototypes of the GLFW API. -It also includes the OpenGL header, and defines all the constants and types -necessary for it to work on your platform. - -For example, under Windows you are normally required to include `windows.h` -before including `GL/gl.h`. This would make your source file tied to Windows -and pollute your code's namespace with the whole Win32 API. - -Instead, the GLFW header takes care of this for you, not by including -`windows.h`, but rather by itself duplicating only the necessary parts of it. -It does this only where needed, so if `windows.h` _is_ included, the GLFW header -does not try to redefine those symbols. - -In other words: - -- Do _not_ include the OpenGL headers yourself, as GLFW does this for you -- Do _not_ include `windows.h` or other platform-specific headers unless - you plan on using those APIs directly -- If you _do_ need to include such headers, do it _before_ including the - GLFW one and it will detect this - -Starting with version 3.0, the GLU header `glu.h` is no longer included by -default. If you wish to include it, define `GLFW_INCLUDE_GLU` before the -inclusion of the GLFW header. - -@code -#define GLFW_INCLUDE_GLU -#include -@endcode - - -@subsection quick_init_term Initializing and terminating GLFW - -Before you can use most GLFW functions, the library must be initialized. On -successful initialization, `GL_TRUE` is returned. If an error occurred, -`GL_FALSE` is returned. - -@code -if (!glfwInit()) - exit(EXIT_FAILURE); -@endcode - -When you are done using GLFW, typically just before the application exits, you -need to terminate GLFW. - -@code -glfwTerminate(); -@endcode - -This destroys any remaining windows and releases any other resources allocated by -GLFW. After this call, you must initialize GLFW again before using any GLFW -functions that require it. - - -@subsection quick_capture_error Setting an error callback - -Most events are reported through callbacks, whether it's a key being pressed, -a GLFW window being moved, or an error occurring. Callbacks are simply -C functions (or C++ static methods) that are called by GLFW with arguments -describing the event. - -In case a GLFW function fails, an error is reported to the GLFW error callback. -You can receive these reports with an error callback. This function must have -the signature below. This simple error callback just prints the error -description to `stderr`. - -@code -void error_callback(int error, const char* description) -{ - fputs(description, stderr); -} -@endcode - -Callback functions must be set, so GLFW knows to call them. The function to set -the error callback is one of the few GLFW functions that may be called before -initialization, which lets you be notified of errors both during and after -initialization. - -@code -glfwSetErrorCallback(error_callback); -@endcode - - -@subsection quick_create_window Creating a window and context - -The window and its OpenGL context are created with a single call, which returns -a handle to the created combined window and context object. For example, this -creates a 640 by 480 windowed mode window with an OpenGL context: - -@code -GLFWwindow* window = glfwCreateWindow(640, 480, "My Title", NULL, NULL); -@endcode - -If window or context creation fails, `NULL` will be returned, so it is necessary -to check the return value. - -@code -if (!window) -{ - glfwTerminate(); - exit(EXIT_FAILURE); -} -@endcode - -The window handle is passed to all window related functions and is provided to -along to all window related callbacks, so they can tell which window received -the event. - -When a window is no longer needed, destroy it. - -@code -glfwDestroyWindow(window); -@endcode - -Once this function is called, no more events will be delivered for that window -and its handle becomes invalid. - - -@subsection quick_context_current Making the OpenGL context current - -Before you can use the OpenGL API, you must have a current OpenGL context. - -@code -glfwMakeContextCurrent(window); -@endcode - -The context will remain current until you make another context current or until -the window owning the current context is destroyed. - - -@subsection quick_window_close Checking the window close flag - -Each window has a flag indicating whether the window should be closed. - -When the user attempts to close the window, either by pressing the close widget -in the title bar or using a key combination like Alt+F4, this flag is set to 1. -Note that __the window isn't actually closed__, so you are expected to monitor -this flag and either destroy the window or give some kind of feedback to the -user. - -@code -while (!glfwWindowShouldClose(window)) -{ - // Keep running -} -@endcode - -You can be notified when the user is attempting to close the window by setting -a close callback with @ref glfwSetWindowCloseCallback. The callback will be -called immediately after the close flag has been set. - -You can also set it yourself with @ref glfwSetWindowShouldClose. This can be -useful if you want to interpret other kinds of input as closing the window, like -for example pressing the escape key. - - -@subsection quick_key_input Receiving input events - -Each window has a large number of callbacks that can be set to receive all the -various kinds of events. To receive key press and release events, create a key -callback function. - -@code -static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) -{ - if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) - glfwSetWindowShouldClose(window, GL_TRUE); -} -@endcode - -The key callback, like other window related callbacks, are set per-window. - -@code -glfwSetKeyCallback(window, key_callback); -@endcode - -In order for event callbacks to be called when events occur, you need to process -events as described below. - - -@subsection quick_render Rendering with OpenGL - -Once you have a current OpenGL context, you can use OpenGL normally. In this -tutorial, a multi-colored rotating triangle will be rendered. The framebuffer -size needs to be retrieved for `glViewport`. - -@code -int width, height; -glfwGetFramebufferSize(window, &width, &height); -glViewport(0, 0, width, height); -@endcode - -You can also set a framebuffer size callback using @ref -glfwSetFramebufferSizeCallback and call `glViewport` from there. - - -@subsection quick_timer Reading the timer - -To create smooth animation, a time source is needed. GLFW provides a timer that -returns the number of seconds since initialization. The time source used is the -most accurate on each platform and generally has micro- or nanosecond -resolution. - -@code -double time = glfwGetTime(); -@endcode - - -@subsection quick_swap_buffers Swapping buffers - -GLFW windows by default use double buffering. That means that each window has -two rendering buffers; a front buffer and a back buffer. The front buffer is -the one being displayed and the back buffer the one you render to. - -When the entire frame has been rendered, the buffers need to be swapped with one -another, so the back buffer becomes the front buffer and vice versa. - -@code -glfwSwapBuffers(window); -@endcode - -The swap interval indicates how many frames to wait until swapping the buffers, -commonly known as _vsync_. By default, the swap interval is zero, meaning -buffer swapping will occur immediately. On fast machines, many of those frames -will never be seen, as the screen is still only updated typically 60-75 times -per second, so this wastes a lot of CPU and GPU cycles. - -Also, because the buffers will be swapped in the middle the screen update, -leading to [screen tearing](https://en.wikipedia.org/wiki/Screen_tearing). - -For these reasons, applications will typically want to set the swap interval to -one. It can be set to higher values, but this is usually not recommended, -because of the input latency it leads to. - -@code -glfwSwapInterval(1); -@endcode - -This function acts on the current context and will fail unless a context is -current. - - -@subsection quick_process_events Processing events - -GLFW needs to communicate regularly with the window system both in order to -receive events and to show that the application hasn't locked up. Event -processing must be done regularly while you have visible windows and is normally -done each frame after buffer swapping. - -There are two methods for processing pending events; polling and waiting. This -example will use event polling, which processes only those events that have -already been received and then returns immediately. - -@code -glfwPollEvents(); -@endcode - -This is the best choice when rendering continually, like most games do. If -instead you only need to update your rendering once you have received new input, -@ref glfwWaitEvents is a better choice. It waits until at least one event has -been received, putting the thread to sleep in the meantime, and then processes -all received events. This saves a great deal of CPU cycles and is useful for, -for example, many kinds of editing tools. - - -@section quick_example Putting it together - -Now that you know how to initialize GLFW, create a window and poll for -keyboard input, it's possible to create a simple program. - -@snippet simple.c code - -This program creates a 640 by 480 windowed mode window and starts a loop that -clears the screen, renders a triangle and processes events until the user either -presses Escape or closes the window. - -This program uses only a few of the many functions GLFW provides. There are -guides for each of the areas covered by GLFW. Each guide will introduce all the -functions for that category. - - - @ref intro - - @ref window - - @ref context - - @ref monitor - - @ref input - - -@section quick_build Compiling and linking the program - -The complete program above can be found in the source distribution as -`examples/simple.c` and is compiled along with all other examples when you -build GLFW. That is, if you have compiled GLFW then you have already built this -as `simple.exe` on Windows, `simple` on Linux or `simple.app` on OS X. - -This tutorial ends here. Once you have written a program that uses GLFW, you -will need to compile and link it. How to do that depends on the development -environment you are using and is best explained by the documentation for that -environment. To learn about the details that are specific to GLFW, see -@ref build. - -*/ diff --git a/examples/common/glfw/docs/rift.dox b/examples/common/glfw/docs/rift.dox deleted file mode 100644 index edf206f7..00000000 --- a/examples/common/glfw/docs/rift.dox +++ /dev/null @@ -1,199 +0,0 @@ -/*! - -@page rift Oculus Rift guide - -@tableofcontents - -This guide is intended to fill in the gaps between the -[Oculus PC SDK documentation](https://developer.oculus.com/documentation/) and -the rest of the GLFW documentation and is not a replacement for either. It -requires you to use [native access](@ref native) and assumes a certain level of -proficiency with LibOVR, platform specific APIs and your chosen development -environment. - -While GLFW has no explicit support for LibOVR, it is tested with and tries to -interoperate well with it. - -@note Because of the speed of development of the Oculus SDK, this guide may -become outdated before the next release. If this is a local copy of the -documentation, you may want to check the GLFW website for updates. This -revision of the guide is written against version 0.4.4 of the SDK. - - -@section rift_include Including the LibOVR and GLFW header files - -Both the OpenGL LibOVR header and the GLFW native header need macros telling -them what OS you are building for. Because LibOVR only supports three major -desktop platforms, this can be solved with canonical predefined macros. - -@code -#if defined(_WIN32) - #define GLFW_EXPOSE_NATIVE_WIN32 - #define GLFW_EXPOSE_NATIVE_WGL - #define OVR_OS_WIN32 -#elif defined(__APPLE__) - #define GLFW_EXPOSE_NATIVE_COCOA - #define GLFW_EXPOSE_NATIVE_NSGL - #define OVR_OS_MAC -#elif defined(__linux__) - #define GLFW_EXPOSE_NATIVE_X11 - #define GLFW_EXPOSE_NATIVE_GLX - #define OVR_OS_LINUX -#endif - -#include -#include - -#include -@endcode - -Both the GLFW and LibOVR headers by default attempt to include the standard -OpenGL `GL/gl.h` header (`OpenGL/gl.h` on OS X). If you wish to use a different -standard header or an [extension loading library](@ref context_glext_auto), -include that header before these. - - -@section rift_init Initializing LibOVR and GLFW - -LibOVR needs to be initialized before GLFW. This means calling at least -`ovr_Initialize`, `ovrHmd_Create` and `ovrHmd_ConfigureTracking` before @ref -glfwInit. Similarly, LibOVR must be shut down after GLFW. This means calling -`ovrHmd_Destroy` and `ovr_Shutdown` after @ref glfwTerminate. - - -@section rift_direct Direct HMD mode - -Direct HMD mode is the recommended display mode for new applications, but the -Oculus Rift runtime currently (January 2015) only supports this mode on Windows. -In direct mode the HMD is not detectable as a GLFW monitor. - - -@subsection rift_direct_create Creating a window and context - -If the HMD is in direct mode you can use either a full screen or a windowed mode -window, but full screen is only recommended if there is a monitor that supports -the resolution of the HMD. Due to limitations in LibOVR, the size of the client -area of the window must equal the resolution of the HMD. - -If the resolution of the HMD is much larger than the regular monitor, the window -may be resized by the window manager on creation. One way to avoid this is to -make it undecorated with the [GLFW_DECORATED](@ref window_hints_wnd) window -hint. - - -@subsection rift_direct_attach Attaching the window to the HMD - -Once you have created the window and context, you need to attach the native -handle of the GLFW window to the HMD. - -@code -ovrHmd_AttachToWindow(hmd, glfwGetWin32Window(window), NULL, NULL); -@endcode - - -@section rift_extend Extend Desktop mode - -Extend desktop mode is a legacy display mode, but is still (January 2015) the -only available mode on OS X and Linux, as well as on Windows machines that for -technical reasons do not yet support direct HMD mode. - - -@subsection rift_extend_detect Detecting a HMD with GLFW - -If the HMD is in extend desktop mode you can deduce which GLFW monitor it -corresponds to and create a full screen window on that monitor. - -On Windows, the native display device name of a GLFW monitor corresponds to the -display device name of the detected HMD as stored, in the `DisplayDeviceName` -member of `ovrHmdDesc`. - -On OS X, the native display ID of a GLFW monitor corresponds to the display ID -of the detected HMD, as stored in the `DisplayId` member of `ovrHmdDesc`. - -At the time of writing (January 2015), the Oculus SDK does not support detecting -which monitor corresponds to the HMD in any sane fashion, but as long as the HMD -is set up and rotated properly it can be found via the screen position and -resolution provided by LibOVR. This method may instead find another monitor -that is mirroring the HMD, but this only matters if you intend to change its -video mode. - -@code -int i, count; -GLFWmonitor** monitors = glfwGetMonitors(&count); - -for (i = 0; i < count; i++) -{ -#if defined(_WIN32) - if (strcmp(glfwGetWin32Monitor(monitors[i]), hmd->DisplayDeviceName) == 0) - return monitors[i]; -#elif defined(__APPLE__) - if (glfwGetCocoaMonitor(monitors[i]) == hmd->DisplayId) - return monitors[i]; -#elif defined(__linux__) - int xpos, ypos; - const GLFWvidmode* mode = glfwGetVideoMode(monitors[i]); - glfwGetMonitorPos(monitors[i], &xpos, &ypos); - - if (hmd->WindowsPos.x == xpos && - hmd->WindowsPos.y == ypos && - hmd->Resolution.w == mode->width && - hmd->Resolution.h == mode->height) - { - return monitors[i]; - } -#endif -} -@endcode - - -@subsection rift_extend_create Creating a window and context - -The window is created as a regular full screen window on the found monitor. It -is usually a good idea to create a -[windowed full screen](@ref window_windowed_full_screen) window, as the HMD will -very likely already be set to the correct video mode. However, in extend -desktop mode it behaves like a regular monitor and any supported video mode can -be requested. - -If other monitors are mirroring the HMD and you request a different video mode, -all monitors in the mirroring set will get the new video mode. - - -@section rift_render Rendering to the HMD - -@subsection rift_render_sdk SDK distortion rendering - -If you wish to use SDK distortion rendering you will need some information from -GLFW to configure the renderer. Below are the parts of the `ovrGLConfig` union -that need to be filled with from GLFW. Note that there are other fields that -also need to be filled for `ovrHmd_ConfigureRendering` to succeed. - -Before configuring SDK distortion rendering you should make your context -current. - -@code - int width, height; - union ovrGLConfig config; - - glfwGetFramebufferSize(window, &width, &height); - - config.OGL.Header.BackBufferSize.w = width; - config.OGL.Header.BackBufferSize.h = height; -#if defined(_WIN32) - config.OGL.Window = glfwGetWin32Window(window); -#elif defined(__APPLE__) -#elif defined(__linux__) - config.OGL.Disp = glfwGetX11Display(); -#endif -@endcode - -When using SDK distortion rendering you should not swap the buffers yourself, as -the HMD is updated by `ovrHmd_EndFrame`. - - -@subsection rift_render_custom Client distortion rendering - -With client distortion rendering you are in full control of the contents of the -HMD and should render and swap the buffers normally. - -*/ diff --git a/examples/common/glfw/docs/spaces.svg b/examples/common/glfw/docs/spaces.svg deleted file mode 100644 index 562fa8be..00000000 --- a/examples/common/glfw/docs/spaces.svg +++ /dev/null @@ -1,872 +0,0 @@ - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/common/glfw/docs/window.dox b/examples/common/glfw/docs/window.dox deleted file mode 100644 index 9aae404e..00000000 --- a/examples/common/glfw/docs/window.dox +++ /dev/null @@ -1,803 +0,0 @@ -/*! - -@page window Window guide - -@tableofcontents - -This guide introduces the window related functions of GLFW. There are also -guides for the other areas of GLFW. - - - @ref intro - - @ref context - - @ref monitor - - @ref input - - -@section window_object Window objects - -The @ref GLFWwindow object encapsulates both a window and a context. They are -created with @ref glfwCreateWindow and destroyed with @ref glfwDestroyWindow, or -@ref glfwTerminate, if any remain. As the window and context are inseparably -linked, the object pointer is used as both a context and window handle. - -To see the event stream provided to the various window related callbacks, run -the `events` test program. - - -@subsection window_creation Window creation - -A window and its OpenGL or OpenGL ES context are created with @ref -glfwCreateWindow, which returns a handle to the created window object. For -example, this creates a 640 by 480 windowed mode window: - -@code -GLFWwindow* window = glfwCreateWindow(640, 480, "My Title", NULL, NULL); -@endcode - -If window creation fails, `NULL` will be returned, so it is necessary to check -the return value. - -The window handle is passed to all window related functions and is provided to -along with all input events, so event handlers can tell which window received -the event. - - -@subsubsection window_full_screen Full screen windows - -To create a full screen window, you need to specify which monitor the window -should use. In most cases, the user's primary monitor is a good choice. -For more information about retrieving monitors, see @ref monitor_monitors. - -@code -GLFWwindow* window = glfwCreateWindow(640, 480, "My Title", glfwGetPrimaryMonitor(), NULL); -@endcode - -Full screen windows cover the entire display area of a monitor, have no border -or decorations. - -Each field of the @ref GLFWvidmode structure corresponds to a function parameter -or window hint and combine to form the _desired video mode_ for that window. -The supported video mode most closely matching the desired video mode will be -set for the chosen monitor as long as the window has input focus. For more -information about retrieving video modes, see @ref monitor_modes. - -Video mode field | Corresponds to ------------------------ | ------------------------ -GLFWvidmode.width | `width` parameter -GLFWvidmode.height | `height` parameter -GLFWvidmode.redBits | `GLFW_RED_BITS` hint -GLFWvidmode.greenBits | `GLFW_GREEN_BITS` hint -GLFWvidmode.blueBits | `GLFW_BLUE_BITS` hint -GLFWvidmode.refreshRate | `GLFW_REFRESH_RATE` hint - -Once you have a full screen window, you can change its resolution with @ref -glfwSetWindowSize. The new video mode will be selected and set the same way as -the video mode chosen by @ref glfwCreateWindow. - -By default, the original video mode of the monitor will be restored and the -window iconified if it loses input focus, to allow the user to switch back to -the desktop. This behavior can be disabled with the `GLFW_AUTO_ICONIFY` window -hint, for example if you wish to simultaneously cover multiple windows with full -screen windows. - - -@subsubsection window_windowed_full_screen "Windowed full screen" windows - -To create a so called _windowed full screen_ or _borderless full screen_ window, -i.e. a full screen window that doesn't change the video mode of the monitor, you -need to request the current video mode of the chosen monitor. - -@code -const GLFWvidmode* mode = glfwGetVideoMode(monitor); - -glfwWindowHint(GLFW_RED_BITS, mode->redBits); -glfwWindowHint(GLFW_GREEN_BITS, mode->greenBits); -glfwWindowHint(GLFW_BLUE_BITS, mode->blueBits); -glfwWindowHint(GLFW_REFRESH_RATE, mode->refreshRate); - -GLFWwindow* window = glfwCreateWindow(mode->width, mode->height, "My Title", monitor, NULL); -@endcode - -GLFW will detect this and will not perform any mode setting for that window. - - -@subsection window_destruction Window destruction - -When a window is no longer needed, destroy it with @ref glfwDestroyWindow. - -@code -glfwDestroyWindow(window); -@endcode - -Window destruction always succeeds. Before the actual destruction, all -callbacks are removed so no further events will be delivered for the window. -All windows remaining when @ref glfwTerminate is called are destroyed as well. - -When a full screen window is destroyed, the original video mode of its monitor -is restored, but the gamma ramp is left untouched. - - -@subsection window_hints Window creation hints - -There are a number of hints that can be set before the creation of a window and -context. Some affect the window itself, others affect the framebuffer or -context. These hints are set to their default values each time the library is -initialized with @ref glfwInit, can be set individually with @ref glfwWindowHint -and reset all at once to their defaults with @ref glfwDefaultWindowHints. - -Note that hints need to be set _before_ the creation of the window and context -you wish to have the specified attributes. - - -@subsubsection window_hints_hard Hard and soft constraints - -Some window hints are hard constraints. These must match the available -capabilities _exactly_ for window and context creation to succeed. Hints -that are not hard constraints are matched as closely as possible, but the -resulting window and context may differ from what these hints requested. To -find out the actual attributes of the created window and context, use the -@ref glfwGetWindowAttrib function. - -The following hints are always hard constraints: -- `GLFW_STEREO` -- `GLFW_DOUBLEBUFFER` -- `GLFW_CLIENT_API` - -The following additional hints are hard constraints when requesting an OpenGL -context, but are ignored when requesting an OpenGL ES context: -- `GLFW_OPENGL_FORWARD_COMPAT` -- `GLFW_OPENGL_PROFILE` - - -@subsubsection window_hints_wnd Window related hints - -`GLFW_RESIZABLE` specifies whether the (windowed mode) window will be resizable -_by the user_. The window will still be resizable using the @ref -glfwSetWindowSize function. This hint is ignored for full screen windows. - -`GLFW_VISIBLE` specifies whether the (windowed mode) window will be initially -visible. This hint is ignored for full screen windows. - -`GLFW_DECORATED` specifies whether the (windowed mode) window will have window -decorations such as a border, a close widget, etc. This hint is ignored for -full screen windows. Note that even though a window may lack a close widget, it -is usually still possible for the user to generate close events. - -`GLFW_FOCUSED` specifies whether the (windowed mode) window will be given input -focus when created. This hint is ignored for full screen and initially hidden -windows. - -`GLFW_AUTO_ICONIFY` specifies whether the (full screen) window will -automatically iconify and restore the previous video mode on input focus loss. -This hint is ignored for windowed mode windows. - -`GLFW_FLOATING` specifies whether the window will be floating above other -regular windows, also called topmost or always-on-top. This is intended -primarily for debugging purposes and cannot be used to implement proper full -screen windows. This hint is ignored for full screen windows. - - -@subsubsection window_hints_fb Framebuffer related hints - -`GLFW_RED_BITS`, `GLFW_GREEN_BITS`, `GLFW_BLUE_BITS`, `GLFW_ALPHA_BITS`, -`GLFW_DEPTH_BITS` and `GLFW_STENCIL_BITS` specify the desired bit depths of the -various components of the default framebuffer. `GLFW_DONT_CARE` means the -application has no preference. - -`GLFW_ACCUM_RED_BITS`, `GLFW_ACCUM_GREEN_BITS`, `GLFW_ACCUM_BLUE_BITS` and -`GLFW_ACCUM_ALPHA_BITS` specify the desired bit depths of the various components -of the accumulation buffer. `GLFW_DONT_CARE` means the application has no -preference. - -@par -Accumulation buffers are a legacy OpenGL feature and should not be used in new -code. - -`GLFW_AUX_BUFFERS` specifies the desired number of auxiliary buffers. -`GLFW_DONT_CARE` means the application has no preference. - -@par -Auxiliary buffers are a legacy OpenGL feature and should not be used in new -code. - -`GLFW_STEREO` specifies whether to use stereoscopic rendering. This is a hard -constraint. - -`GLFW_SAMPLES` specifies the desired number of samples to use for multisampling. -Zero disables multisampling. `GLFW_DONT_CARE` means the application has no -preference. - -`GLFW_SRGB_CAPABLE` specifies whether the framebuffer should be sRGB capable. - -`GLFW_DOUBLEBUFFER` specifies whether the framebuffer should be double buffered. -You nearly always want to use double buffering. This is a hard constraint. - - -@subsubsection window_hints_mtr Monitor related hints - -`GLFW_REFRESH_RATE` specifies the desired refresh rate for full screen windows. -If set to `GLFW_DONT_CARE`, the highest available refresh rate will be used. -This hint is ignored for windowed mode windows. - - -@subsubsection window_hints_ctx Context related hints - -`GLFW_CLIENT_API` specifies which client API to create the context for. -Possible values are `GLFW_OPENGL_API` and `GLFW_OPENGL_ES_API`. This is a hard -constraint. - -`GLFW_CONTEXT_VERSION_MAJOR` and `GLFW_CONTEXT_VERSION_MINOR` specify the client -API version that the created context must be compatible with. The exact -behavior of these hints depend on the requested client API. - -@par -__OpenGL:__ `GLFW_CONTEXT_VERSION_MAJOR` and `GLFW_CONTEXT_VERSION_MINOR` are not hard -constraints, but creation will fail if the OpenGL version of the created context -is less than the one requested. It is therefore perfectly safe to use the -default of version 1.0 for legacy code and you may still get -backwards-compatible contexts of version 3.0 and above when available. - -@par -While there is no way to ask the driver for a context of the highest supported -version, GLFW will attempt to provide this when you ask for a version 1.0 -context, which is the default for these hints. - -@par -__OpenGL ES:__ `GLFW_CONTEXT_VERSION_MAJOR` and `GLFW_CONTEXT_VERSION_MINOR` are not hard -constraints, but creation will fail if the OpenGL ES version of the created -context is less than the one requested. Additionally, OpenGL ES 1.x cannot be -returned if 2.0 or later was requested, and vice versa. This is because OpenGL -ES 3.x is backward compatible with 2.0, but OpenGL ES 2.0 is not backward -compatible with 1.x. - -`GLFW_OPENGL_FORWARD_COMPAT` specifies whether the OpenGL context should be -forward-compatible, i.e. one where all functionality deprecated in the requested -version of OpenGL is removed. This may only be used if the requested OpenGL -version is 3.0 or above. If OpenGL ES is requested, this hint is ignored. - -@par -Forward-compatibility is described in detail in the -[OpenGL Reference Manual](https://www.opengl.org/registry/). - -`GLFW_OPENGL_DEBUG_CONTEXT` specifies whether to create a debug OpenGL context, -which may have additional error and performance issue reporting functionality. -If OpenGL ES is requested, this hint is ignored. - -`GLFW_OPENGL_PROFILE` specifies which OpenGL profile to create the context for. -Possible values are one of `GLFW_OPENGL_CORE_PROFILE` or -`GLFW_OPENGL_COMPAT_PROFILE`, or `GLFW_OPENGL_ANY_PROFILE` to not request -a specific profile. If requesting an OpenGL version below 3.2, -`GLFW_OPENGL_ANY_PROFILE` must be used. If another OpenGL ES is requested, -this hint is ignored. - -@par -OpenGL profiles are described in detail in the -[OpenGL Reference Manual](https://www.opengl.org/registry/). - -`GLFW_CONTEXT_ROBUSTNESS` specifies the robustness strategy to be used by the -context. This can be one of `GLFW_NO_RESET_NOTIFICATION` or -`GLFW_LOSE_CONTEXT_ON_RESET`, or `GLFW_NO_ROBUSTNESS` to not request -a robustness strategy. - -`GLFW_CONTEXT_RELEASE_BEHAVIOR` specifies the release behavior to be -used by the context. Possible values are one of `GLFW_ANY_RELEASE_BEHAVIOR`, -`GLFW_RELEASE_BEHAVIOR_FLUSH` or `GLFW_RELEASE_BEHAVIOR_NONE`. If the -behavior is `GLFW_ANY_RELEASE_BEHAVIOR`, the default behavior of the context -creation API will be used. If the behavior is `GLFW_RELEASE_BEHAVIOR_FLUSH`, -the pipeline will be flushed whenever the context is released from being the -current one. If the behavior is `GLFW_RELEASE_BEHAVIOR_NONE`, the pipeline will -not be flushed on release. - -@par -Context release behaviors are described in detail by the -[GL_KHR_context_flush_control](https://www.opengl.org/registry/specs/KHR/context_flush_control.txt) -extension. - - -@subsubsection window_hints_values Supported and default values - -Window hint | Default value | Supported values -------------------------------- | --------------------------- | ---------------- -`GLFW_RESIZABLE` | `GL_TRUE` | `GL_TRUE` or `GL_FALSE` -`GLFW_VISIBLE` | `GL_TRUE` | `GL_TRUE` or `GL_FALSE` -`GLFW_DECORATED` | `GL_TRUE` | `GL_TRUE` or `GL_FALSE` -`GLFW_FOCUSED` | `GL_TRUE` | `GL_TRUE` or `GL_FALSE` -`GLFW_AUTO_ICONIFY` | `GL_TRUE` | `GL_TRUE` or `GL_FALSE` -`GLFW_FLOATING` | `GL_FALSE` | `GL_TRUE` or `GL_FALSE` -`GLFW_RED_BITS` | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE` -`GLFW_GREEN_BITS` | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE` -`GLFW_BLUE_BITS` | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE` -`GLFW_ALPHA_BITS` | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE` -`GLFW_DEPTH_BITS` | 24 | 0 to `INT_MAX` or `GLFW_DONT_CARE` -`GLFW_STENCIL_BITS` | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE` -`GLFW_ACCUM_RED_BITS` | 0 | 0 to `INT_MAX` or `GLFW_DONT_CARE` -`GLFW_ACCUM_GREEN_BITS` | 0 | 0 to `INT_MAX` or `GLFW_DONT_CARE` -`GLFW_ACCUM_BLUE_BITS` | 0 | 0 to `INT_MAX` or `GLFW_DONT_CARE` -`GLFW_ACCUM_ALPHA_BITS` | 0 | 0 to `INT_MAX` or `GLFW_DONT_CARE` -`GLFW_AUX_BUFFERS` | 0 | 0 to `INT_MAX` or `GLFW_DONT_CARE` -`GLFW_SAMPLES` | 0 | 0 to `INT_MAX` or `GLFW_DONT_CARE` -`GLFW_REFRESH_RATE` | `GLFW_DONT_CARE` | 0 to `INT_MAX` or `GLFW_DONT_CARE` -`GLFW_STEREO` | `GL_FALSE` | `GL_TRUE` or `GL_FALSE` -`GLFW_SRGB_CAPABLE` | `GL_FALSE` | `GL_TRUE` or `GL_FALSE` -`GLFW_DOUBLEBUFFER` | `GL_TRUE` | `GL_TRUE` or `GL_FALSE` -`GLFW_CLIENT_API` | `GLFW_OPENGL_API` | `GLFW_OPENGL_API` or `GLFW_OPENGL_ES_API` -`GLFW_CONTEXT_VERSION_MAJOR` | 1 | Any valid major version number of the chosen client API -`GLFW_CONTEXT_VERSION_MINOR` | 0 | Any valid minor version number of the chosen client API -`GLFW_CONTEXT_ROBUSTNESS` | `GLFW_NO_ROBUSTNESS` | `GLFW_NO_ROBUSTNESS`, `GLFW_NO_RESET_NOTIFICATION` or `GLFW_LOSE_CONTEXT_ON_RESET` -`GLFW_CONTEXT_RELEASE_BEHAVIOR` | `GLFW_ANY_RELEASE_BEHAVIOR` | `GLFW_ANY_RELEASE_BEHAVIOR`, `GLFW_RELEASE_BEHAVIOR_FLUSH` or `GLFW_RELEASE_BEHAVIOR_NONE` -`GLFW_OPENGL_FORWARD_COMPAT` | `GL_FALSE` | `GL_TRUE` or `GL_FALSE` -`GLFW_OPENGL_DEBUG_CONTEXT` | `GL_FALSE` | `GL_TRUE` or `GL_FALSE` -`GLFW_OPENGL_PROFILE` | `GLFW_OPENGL_ANY_PROFILE` | `GLFW_OPENGL_ANY_PROFILE`, `GLFW_OPENGL_COMPAT_PROFILE` or `GLFW_OPENGL_CORE_PROFILE` - - -@section window_events Window event processing - -See @ref events. - - -@section window_properties Window properties and events - -@subsection window_userptr User pointer - -Each window has a user pointer that can be set with @ref -glfwSetWindowUserPointer and fetched with @ref glfwGetWindowUserPointer. This -can be used for any purpose you need and will not be modified by GLFW throughout -the life-time of the window. - -The initial value of the pointer is `NULL`. - - -@subsection window_close Window closing and close flag - -When the user attempts to close the window, for example by clicking the close -widget or using a key chord like Alt+F4, the _close flag_ of the window is set. -The window is however not actually destroyed and, unless you watch for this -state change, nothing further happens. - -The current state of the close flag is returned by @ref glfwWindowShouldClose -and can be set or cleared directly with @ref glfwSetWindowShouldClose. A common -pattern is to use the close flag as a main loop condition. - -@code -while (!glfwWindowShouldClose(window)) -{ - render(window); - - glfwSwapBuffers(window); - glfwPollEvents(); -} -@endcode - -If you wish to be notified when the user attempts to close a window, set a close -callback. - -@code -glfwSetWindowCloseCallback(window, window_close_callback); -@endcode - -The callback function is called directly _after_ the close flag has been set. -It can be used for example to filter close requests and clear the close flag -again unless certain conditions are met. - -@code -void window_close_callback(GLFWwindow* window) -{ - if (!time_to_close) - glfwSetWindowShouldClose(window, GL_FALSE); -} -@endcode - - -@subsection window_size Window size - -The size of a window can be changed with @ref glfwSetWindowSize. For windowed -mode windows, this sets the size, in -[screen coordinates](@ref coordinate_systems) of the _client area_ or _content -area_ of the window. The window system may impose limits on window size. - -@code -glfwSetWindowSize(window, 640, 480); -@endcode - -For full screen windows, the specified size becomes the new resolution of the -window's *desired video mode*. The video mode most closely matching the new -desired video mode is set immediately. The window is resized to fit the -resolution of the set video mode. - -If you wish to be notified when a window is resized, whether by the user or -the system, set a size callback. - -@code -glfwSetWindowSizeCallback(window, window_size_callback); -@endcode - -The callback function receives the new size, in screen coordinates, of the -client area of the window when it is resized. - -@code -void window_size_callback(GLFWwindow* window, int width, int height) -{ -} -@endcode - -There is also @ref glfwGetWindowSize for directly retrieving the current size of -a window. - -@code -int width, height; -glfwGetWindowSize(window, &width, &height); -@endcode - -@note Do not pass the window size to `glViewport` or other pixel-based OpenGL -calls. The window size is in screen coordinates, not pixels. Use the -[framebuffer size](@ref window_fbsize), which is in pixels, for pixel-based -calls. - -The above functions work with the size of the client area, but decorated windows -typically have title bars and window frames around this rectangle. You can -retrieve the extents of these with @ref glfwGetWindowFrameSize. - -@code -int left, top, right, bottom; -glfwGetWindowFrameSize(window, &left, &top, &right, &bottom); -@endcode - -The returned values are the distances, in screen coordinates, from the edges of -the client area to the corresponding edges of the full window. As they are -distances and not coordinates, they are always zero or positive. - - -@subsection window_fbsize Framebuffer size - -While the size of a window is measured in screen coordinates, OpenGL works with -pixels. The size you pass into `glViewport`, for example, should be in pixels. -On some machines screen coordinates and pixels are the same, but on others they -will not be. There is a second set of functions to retrieve the size, in -pixels, of the framebuffer of a window. - -If you wish to be notified when the framebuffer of a window is resized, whether -by the user or the system, set a size callback. - -@code -glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); -@endcode - -The callback function receives the new size of the framebuffer when it is -resized, which can for example be used to update the OpenGL viewport. - -@code -void framebuffer_size_callback(GLFWwindow* window, int width, int height) -{ - glViewport(0, 0, width, height); -} -@endcode - -There is also @ref glfwGetFramebufferSize for directly retrieving the current -size of the framebuffer of a window. - -@code -int width, height; -glfwGetFramebufferSize(window, &width, &height); -glViewport(0, 0, width, height); -@endcode - -The size of a framebuffer may change independently of the size of a window, for -example if the window is dragged between a regular monitor and a high-DPI one. - - -@subsection window_pos Window position - -The position of a windowed-mode window can be changed with @ref -glfwSetWindowPos. This moves the window so that the upper-left corner of its -client area has the specified [screen coordinates](@ref coordinate_systems). -The window system may put limitations on window placement. - -@code -glfwSetWindowPos(window, 100, 100); -@endcode - -If you wish to be notified when a window is moved, whether by the user, system -or your own code, set a position callback. - -@code -glfwSetWindowPosCallback(window, window_pos_callback); -@endcode - -The callback function receives the new position of the upper-left corner of the -client area when the window is moved. - -@code -void window_pos_callback(GLFWwindow* window, int xpos, int ypos) -{ -} -@endcode - -There is also @ref glfwGetWindowPos for directly retrieving the current position -of the client area of the window. - -@code -int xpos, ypos; -glfwGetWindowPos(window, &xpos, &ypos); -@endcode - - -@subsection window_title Window title - -All GLFW windows have a title, although undecorated or full screen windows may -not display it or only display it in a task bar or similar interface. You can -set a UTF-8 encoded window title with @ref glfwSetWindowTitle. - -@code -glfwSetWindowTitle(window, "My Window"); -@endcode - -The specified string is copied before the function returns, so there is no need -to keep it around. - -As long as your source file is encoded as UTF-8, you can use any Unicode -characters directly in the source. - -@code -glfwSetWindowTitle(window, "ヒカルの碁"); -@endcode - - -@subsection window_monitor Window monitor - -Full screen windows are associated with a specific monitor. You can get the -handle for this monitor with @ref glfwGetWindowMonitor. - -@code -GLFWmonitor* monitor = glfwGetWindowMonitor(window); -@endcode - -This monitor handle is one of those returned by @ref glfwGetMonitors. - -For windowed mode windows, this function returns `NULL`. This is the -recommended way to tell full screen windows from windowed mode windows. - - -@subsection window_iconify Window iconification - -Windows can be iconified (i.e. minimized) with @ref glfwIconifyWindow. - -@code -glfwIconifyWindow(window); -@endcode - -When a full screen window is iconified, the original video mode of its monitor -is restored until the user or application restores the window. - -Iconified windows can be restored with @ref glfwRestoreWindow. - -@code -glfwRestoreWindow(window); -@endcode - -When a full screen window is restored, the desired video mode is restored to its -monitor as well. - -If you wish to be notified when a window is iconified or restored, whether by -the user, system or your own code, set a iconify callback. - -@code -glfwSetWindowIconifyCallback(window, window_iconify_callback); -@endcode - -The callback function receives changes in the iconification state of the window. - -@code -void window_iconify_callback(GLFWwindow* window, int iconified) -{ - if (iconified) - { - // The window was iconified - } - else - { - // The window was restored - } -} -@endcode - -You can also get the current iconification state with @ref glfwGetWindowAttrib. - -@code -int iconified = glfwGetWindowAttrib(window, GLFW_ICONIFIED); -@endcode - - -@subsection window_hide Window visibility - -Windowed mode windows can be hidden with @ref glfwHideWindow. - -@code -glfwHideWindow(window); -@endcode - -This makes the window completely invisible to the user, including removing it -from the task bar, dock or window list. Full screen windows cannot be hidden -and calling @ref glfwHideWindow on a full screen window does nothing. - -Hidden windows can be shown with @ref glfwShowWindow. - -@code -glfwShowWindow(window); -@endcode - -Windowed mode windows can be created initially hidden with the `GLFW_VISIBLE` -[window hint](@ref window_hints_wnd). Windows created hidden are completely -invisible to the user until shown. This can be useful if you need to set up -your window further before showing it, for example moving it to a specific -location. - -You can also get the current visibility state with @ref glfwGetWindowAttrib. - -@code -int visible = glfwGetWindowAttrib(window, GLFW_VISIBLE); -@endcode - - -@subsection window_focus Window input focus - -If you wish to be notified when a window gains or loses input focus, whether by -the user, system or your own code, set a focus callback. - -@code -glfwSetWindowFocusCallback(window, window_focus_callback); -@endcode - -The callback function receives changes in the input focus state of the window. - -@code -void window_focus_callback(GLFWwindow* window, int focused) -{ - if (focused) - { - // The window gained input focus - } - else - { - // The window lost input focus - } -} -@endcode - -You can also get the current input focus state with @ref glfwGetWindowAttrib. - -@code -int focused = glfwGetWindowAttrib(window, GLFW_FOCUSED); -@endcode - - -@subsection window_refresh Window damage and refresh - -If you wish to be notified when the contents of a window is damaged and needs -to be refreshed, set a window refresh callback. - -@code -glfwSetWindowRefreshCallback(m_handle, window_refresh_callback); -@endcode - -The callback function is called when the contents of the window needs to be -refreshed. - -@code -void window_refresh_callback(GLFWwindow* window) -{ - draw_editor_ui(window); - glfwSwapBuffers(window); -} -@endcode - -@note On compositing window systems such as Aero, Compiz or Aqua, where the -window contents are saved off-screen, this callback might only be called when -the window or framebuffer is resized. - - -@subsection window_attribs Window attributes - -Windows have a number of attributes that can be returned using @ref -glfwGetWindowAttrib. Some reflect state that may change during the lifetime of -the window, while others reflect the corresponding hints and are fixed at the -time of creation. Some are related to the actual window and others to its -context. - -@code -if (glfwGetWindowAttrib(window, GLFW_FOCUSED)) -{ - // window has input focus -} -@endcode - - -@subsubsection window_attribs_wnd Window related attributes - -`GLFW_FOCUSED` indicates whether the specified window has input focus. Initial -input focus is controlled by the [window hint](@ref window_hints_wnd) with the -same name. - -`GLFW_ICONIFIED` indicates whether the specified window is iconified, whether by -the user or with @ref glfwIconifyWindow. - -`GLFW_VISIBLE` indicates whether the specified window is visible. Window -visibility can be controlled with @ref glfwShowWindow and @ref glfwHideWindow -and initial visibility is controlled by the [window hint](@ref window_hints_wnd) -with the same name. - -`GLFW_RESIZABLE` indicates whether the specified window is resizable _by the -user_. This is set on creation with the [window hint](@ref window_hints_wnd) - with the same name. - -`GLFW_DECORATED` indicates whether the specified window has decorations such as -a border, a close widget, etc. This is set on creation with the -[window hint](@ref window_hints_wnd) with the same name. - -`GLFW_FLOATING` indicates whether the specified window is floating, also called -topmost or always-on-top. This is controlled by the -[window hint](@ref window_hints_wnd) with the same name. - - -@subsubsection window_attribs_ctx Context related attributes - -`GLFW_CLIENT_API` indicates the client API provided by the window's context; -either `GLFW_OPENGL_API` or `GLFW_OPENGL_ES_API`. - -`GLFW_CONTEXT_VERSION_MAJOR`, `GLFW_CONTEXT_VERSION_MINOR` and -`GLFW_CONTEXT_REVISION` indicate the client API version of the window's context. - -`GLFW_OPENGL_FORWARD_COMPAT` is `GL_TRUE` if the window's context is an OpenGL -forward-compatible one, or `GL_FALSE` otherwise. - -`GLFW_OPENGL_DEBUG_CONTEXT` is `GL_TRUE` if the window's context is an OpenGL -debug context, or `GL_FALSE` otherwise. - -`GLFW_OPENGL_PROFILE` indicates the OpenGL profile used by the context. This is -`GLFW_OPENGL_CORE_PROFILE` or `GLFW_OPENGL_COMPAT_PROFILE` if the context uses -a known profile, or `GLFW_OPENGL_ANY_PROFILE` if the OpenGL profile is unknown -or the context is an OpenGL ES context. Note that the returned profile may not -match the profile bits of the context flags, as GLFW will try other means of -detecting the profile when no bits are set. - -`GLFW_CONTEXT_ROBUSTNESS` indicates the robustness strategy used by the context. -This is `GLFW_LOSE_CONTEXT_ON_RESET` or `GLFW_NO_RESET_NOTIFICATION` if the -window's context supports robustness, or `GLFW_NO_ROBUSTNESS` otherwise. - - -@section buffer_swap Buffer swapping - -GLFW windows are by default double buffered. That means that you have two -rendering buffers; a front buffer and a back buffer. The front buffer is -the one being displayed and the back buffer the one you render to. - -When the entire frame has been rendered, it is time to swap the back and the -front buffers in order to display what has been rendered and begin rendering -a new frame. This is done with @ref glfwSwapBuffers. - -@code -glfwSwapBuffers(window); -@endcode - -Sometimes it can be useful to select when the buffer swap will occur. With the -function @ref glfwSwapInterval it is possible to select the minimum number of -monitor refreshes the driver wait should from the time @ref glfwSwapBuffers was -called before swapping the buffers: - -@code -glfwSwapInterval(1); -@endcode - -If the interval is zero, the swap will take place immediately when @ref -glfwSwapBuffers is called without waiting for a refresh. Otherwise at least -interval retraces will pass between each buffer swap. Using a swap interval of -zero can be useful for benchmarking purposes, when it is not desirable to -measure the time it takes to wait for the vertical retrace. However, a swap -interval of one lets you avoid tearing. - -Note that this may not work on all machines, as some drivers have -user-controlled settings that override any swap interval the application -requests. It is also by default disabled on Windows Vista and later when using -DWM (Aero), as using it there sometimes leads to severe jitter. You can -forcibly enable it for machines using DWM using @ref compile_options_win32. - -*/ diff --git a/examples/common/glfw/examples/CMakeLists.txt b/examples/common/glfw/examples/CMakeLists.txt deleted file mode 100644 index 229c4a72..00000000 --- a/examples/common/glfw/examples/CMakeLists.txt +++ /dev/null @@ -1,80 +0,0 @@ - -link_libraries(glfw "${OPENGL_glu_LIBRARY}") - -if (BUILD_SHARED_LIBS) - add_definitions(-DGLFW_DLL) - link_libraries("${OPENGL_gl_LIBRARY}" "${MATH_LIBRARY}") -else() - link_libraries(${glfw_LIBRARIES}) -endif() - -include_directories("${GLFW_SOURCE_DIR}/include" - "${GLFW_SOURCE_DIR}/deps") - -if ("${OPENGL_INCLUDE_DIR}") - include_directories("${OPENGL_INCLUDE_DIR}") -endif() - -set(GLAD "${GLFW_SOURCE_DIR}/deps/glad/glad.h" - "${GLFW_SOURCE_DIR}/deps/glad.c") -set(GETOPT "${GLFW_SOURCE_DIR}/deps/getopt.h" - "${GLFW_SOURCE_DIR}/deps/getopt.c") -set(TINYCTHREAD "${GLFW_SOURCE_DIR}/deps/tinycthread.h" - "${GLFW_SOURCE_DIR}/deps/tinycthread.c") - -if (APPLE) - # Set fancy names for bundles - add_executable(Boing MACOSX_BUNDLE boing.c) - add_executable(Gears MACOSX_BUNDLE gears.c) - add_executable(Heightmap MACOSX_BUNDLE heightmap.c ${GLAD}) - add_executable(Particles MACOSX_BUNDLE particles.c ${TINYCTHREAD}) - add_executable(Simple MACOSX_BUNDLE simple.c) - add_executable(SplitView MACOSX_BUNDLE splitview.c) - add_executable(Wave MACOSX_BUNDLE wave.c) - - set_target_properties(Boing PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Boing") - set_target_properties(Gears PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Gears") - set_target_properties(Heightmap PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Heightmap") - set_target_properties(Particles PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Particles") - set_target_properties(Simple PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Simple") - set_target_properties(SplitView PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Split View") - set_target_properties(Wave PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Wave") - - set_target_properties(Boing Gears Heightmap Particles Simple SplitView Wave PROPERTIES - FOLDER "GLFW3/Examples") -else() - # Set boring names for executables - add_executable(boing WIN32 boing.c) - add_executable(gears WIN32 gears.c) - add_executable(heightmap WIN32 heightmap.c ${GLAD}) - add_executable(particles WIN32 particles.c ${TINYCTHREAD} ${GETOPT}) - add_executable(simple WIN32 simple.c) - add_executable(splitview WIN32 splitview.c) - add_executable(wave WIN32 wave.c) - - set_target_properties(boing gears heightmap particles simple splitview wave PROPERTIES - FOLDER "GLFW3/Examples") -endif() - -if (APPLE) - target_link_libraries(Particles "${CMAKE_THREAD_LIBS_INIT}") -elseif (UNIX) - target_link_libraries(particles "${CMAKE_THREAD_LIBS_INIT}" "${RT_LIBRARY}") -endif() - -if (MSVC) - set(WINDOWS_BINARIES boing gears heightmap particles simple splitview wave) - - # Tell MSVC to use main instead of WinMain for Windows subsystem executables - set_target_properties(${WINDOWS_BINARIES} PROPERTIES - LINK_FLAGS "/ENTRY:mainCRTStartup") -endif() - -if (APPLE) - set(BUNDLE_BINARIES Boing Gears Heightmap Particles Simple SplitView Wave) - - set_target_properties(${BUNDLE_BINARIES} PROPERTIES - MACOSX_BUNDLE_SHORT_VERSION_STRING ${GLFW_VERSION} - MACOSX_BUNDLE_LONG_VERSION_STRING ${GLFW_VERSION_FULL}) -endif() - diff --git a/examples/common/glfw/examples/boing.c b/examples/common/glfw/examples/boing.c deleted file mode 100644 index ec313596..00000000 --- a/examples/common/glfw/examples/boing.c +++ /dev/null @@ -1,669 +0,0 @@ -/***************************************************************************** - * Title: GLBoing - * Desc: Tribute to Amiga Boing. - * Author: Jim Brooks - * Original Amiga authors were R.J. Mical and Dale Luck. - * GLFW conversion by Marcus Geelnard - * Notes: - 360' = 2*PI [radian] - * - * - Distances between objects are created by doing a relative - * Z translations. - * - * - Although OpenGL enticingly supports alpha-blending, - * the shadow of the original Boing didn't affect the color - * of the grid. - * - * - [Marcus] Changed timing scheme from interval driven to frame- - * time based animation steps (which results in much smoother - * movement) - * - * History of Amiga Boing: - * - * Boing was demonstrated on the prototype Amiga (codenamed "Lorraine") in - * 1985. According to legend, it was written ad-hoc in one night by - * R. J. Mical and Dale Luck. Because the bouncing ball animation was so fast - * and smooth, attendees did not believe the Amiga prototype was really doing - * the rendering. Suspecting a trick, they began looking around the booth for - * a hidden computer or VCR. - *****************************************************************************/ - -#include -#include -#include - -#define GLFW_INCLUDE_GLU -#include - - -/***************************************************************************** - * Various declarations and macros - *****************************************************************************/ - -/* Prototypes */ -void init( void ); -void display( void ); -void reshape( GLFWwindow* window, int w, int h ); -void key_callback( GLFWwindow* window, int key, int scancode, int action, int mods ); -void mouse_button_callback( GLFWwindow* window, int button, int action, int mods ); -void cursor_position_callback( GLFWwindow* window, double x, double y ); -void DrawBoingBall( void ); -void BounceBall( double dt ); -void DrawBoingBallBand( GLfloat long_lo, GLfloat long_hi ); -void DrawGrid( void ); - -#define RADIUS 70.f -#define STEP_LONGITUDE 22.5f /* 22.5 makes 8 bands like original Boing */ -#define STEP_LATITUDE 22.5f - -#define DIST_BALL (RADIUS * 2.f + RADIUS * 0.1f) - -#define VIEW_SCENE_DIST (DIST_BALL * 3.f + 200.f)/* distance from viewer to middle of boing area */ -#define GRID_SIZE (RADIUS * 4.5f) /* length (width) of grid */ -#define BOUNCE_HEIGHT (RADIUS * 2.1f) -#define BOUNCE_WIDTH (RADIUS * 2.1f) - -#define SHADOW_OFFSET_X -20.f -#define SHADOW_OFFSET_Y 10.f -#define SHADOW_OFFSET_Z 0.f - -#define WALL_L_OFFSET 0.f -#define WALL_R_OFFSET 5.f - -/* Animation speed (50.0 mimics the original GLUT demo speed) */ -#define ANIMATION_SPEED 50.f - -/* Maximum allowed delta time per physics iteration */ -#define MAX_DELTA_T 0.02f - -/* Draw ball, or its shadow */ -typedef enum { DRAW_BALL, DRAW_BALL_SHADOW } DRAW_BALL_ENUM; - -/* Vertex type */ -typedef struct {float x; float y; float z;} vertex_t; - -/* Global vars */ -int width, height; -GLfloat deg_rot_y = 0.f; -GLfloat deg_rot_y_inc = 2.f; -GLboolean override_pos = GL_FALSE; -GLfloat cursor_x = 0.f; -GLfloat cursor_y = 0.f; -GLfloat ball_x = -RADIUS; -GLfloat ball_y = -RADIUS; -GLfloat ball_x_inc = 1.f; -GLfloat ball_y_inc = 2.f; -DRAW_BALL_ENUM drawBallHow; -double t; -double t_old = 0.f; -double dt; - -/* Random number generator */ -#ifndef RAND_MAX - #define RAND_MAX 4095 -#endif - -/* PI */ -#ifndef M_PI - #define M_PI 3.1415926535897932384626433832795 -#endif - - -/***************************************************************************** - * Truncate a degree. - *****************************************************************************/ -GLfloat TruncateDeg( GLfloat deg ) -{ - if ( deg >= 360.f ) - return (deg - 360.f); - else - return deg; -} - -/***************************************************************************** - * Convert a degree (360-based) into a radian. - * 360' = 2 * PI - *****************************************************************************/ -double deg2rad( double deg ) -{ - return deg / 360 * (2 * M_PI); -} - -/***************************************************************************** - * 360' sin(). - *****************************************************************************/ -double sin_deg( double deg ) -{ - return sin( deg2rad( deg ) ); -} - -/***************************************************************************** - * 360' cos(). - *****************************************************************************/ -double cos_deg( double deg ) -{ - return cos( deg2rad( deg ) ); -} - -/***************************************************************************** - * Compute a cross product (for a normal vector). - * - * c = a x b - *****************************************************************************/ -void CrossProduct( vertex_t a, vertex_t b, vertex_t c, vertex_t *n ) -{ - GLfloat u1, u2, u3; - GLfloat v1, v2, v3; - - u1 = b.x - a.x; - u2 = b.y - a.y; - u3 = b.y - a.z; - - v1 = c.x - a.x; - v2 = c.y - a.y; - v3 = c.z - a.z; - - n->x = u2 * v3 - v2 * v3; - n->y = u3 * v1 - v3 * u1; - n->z = u1 * v2 - v1 * u2; -} - -/***************************************************************************** - * Calculate the angle to be passed to gluPerspective() so that a scene - * is visible. This function originates from the OpenGL Red Book. - * - * Parms : size - * The size of the segment when the angle is intersected at "dist" - * (ie at the outermost edge of the angle of vision). - * - * dist - * Distance from viewpoint to scene. - *****************************************************************************/ -GLfloat PerspectiveAngle( GLfloat size, - GLfloat dist ) -{ - GLfloat radTheta, degTheta; - - radTheta = 2.f * (GLfloat) atan2( size / 2.f, dist ); - degTheta = (180.f * radTheta) / (GLfloat) M_PI; - return degTheta; -} - - - -#define BOING_DEBUG 0 - - -/***************************************************************************** - * init() - *****************************************************************************/ -void init( void ) -{ - /* - * Clear background. - */ - glClearColor( 0.55f, 0.55f, 0.55f, 0.f ); - - glShadeModel( GL_FLAT ); -} - - -/***************************************************************************** - * display() - *****************************************************************************/ -void display(void) -{ - glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); - glPushMatrix(); - - drawBallHow = DRAW_BALL_SHADOW; - DrawBoingBall(); - - DrawGrid(); - - drawBallHow = DRAW_BALL; - DrawBoingBall(); - - glPopMatrix(); - glFlush(); -} - - -/***************************************************************************** - * reshape() - *****************************************************************************/ -void reshape( GLFWwindow* window, int w, int h ) -{ - glViewport( 0, 0, (GLsizei)w, (GLsizei)h ); - - glMatrixMode( GL_PROJECTION ); - glLoadIdentity(); - - gluPerspective( PerspectiveAngle( RADIUS * 2, 200 ), - (GLfloat)w / (GLfloat)h, - 1.0, - VIEW_SCENE_DIST ); - - glMatrixMode( GL_MODELVIEW ); - glLoadIdentity(); - - gluLookAt( 0.0, 0.0, VIEW_SCENE_DIST,/* eye */ - 0.0, 0.0, 0.0, /* center of vision */ - 0.0, -1.0, 0.0 ); /* up vector */ -} - -void key_callback( GLFWwindow* window, int key, int scancode, int action, int mods ) -{ - if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) - glfwSetWindowShouldClose(window, GL_TRUE); -} - -static void set_ball_pos ( GLfloat x, GLfloat y ) -{ - ball_x = (width / 2) - x; - ball_y = y - (height / 2); -} - -void mouse_button_callback( GLFWwindow* window, int button, int action, int mods ) -{ - if (button != GLFW_MOUSE_BUTTON_LEFT) - return; - - if (action == GLFW_PRESS) - { - override_pos = GL_TRUE; - set_ball_pos(cursor_x, cursor_y); - } - else - { - override_pos = GL_FALSE; - } -} - -void cursor_position_callback( GLFWwindow* window, double x, double y ) -{ - cursor_x = (float) x; - cursor_y = (float) y; - - if ( override_pos ) - set_ball_pos(cursor_x, cursor_y); -} - -/***************************************************************************** - * Draw the Boing ball. - * - * The Boing ball is sphere in which each facet is a rectangle. - * Facet colors alternate between red and white. - * The ball is built by stacking latitudinal circles. Each circle is composed - * of a widely-separated set of points, so that each facet is noticably large. - *****************************************************************************/ -void DrawBoingBall( void ) -{ - GLfloat lon_deg; /* degree of longitude */ - double dt_total, dt2; - - glPushMatrix(); - glMatrixMode( GL_MODELVIEW ); - - /* - * Another relative Z translation to separate objects. - */ - glTranslatef( 0.0, 0.0, DIST_BALL ); - - /* Update ball position and rotation (iterate if necessary) */ - dt_total = dt; - while( dt_total > 0.0 ) - { - dt2 = dt_total > MAX_DELTA_T ? MAX_DELTA_T : dt_total; - dt_total -= dt2; - BounceBall( dt2 ); - deg_rot_y = TruncateDeg( deg_rot_y + deg_rot_y_inc*((float)dt2*ANIMATION_SPEED) ); - } - - /* Set ball position */ - glTranslatef( ball_x, ball_y, 0.0 ); - - /* - * Offset the shadow. - */ - if ( drawBallHow == DRAW_BALL_SHADOW ) - { - glTranslatef( SHADOW_OFFSET_X, - SHADOW_OFFSET_Y, - SHADOW_OFFSET_Z ); - } - - /* - * Tilt the ball. - */ - glRotatef( -20.0, 0.0, 0.0, 1.0 ); - - /* - * Continually rotate ball around Y axis. - */ - glRotatef( deg_rot_y, 0.0, 1.0, 0.0 ); - - /* - * Set OpenGL state for Boing ball. - */ - glCullFace( GL_FRONT ); - glEnable( GL_CULL_FACE ); - glEnable( GL_NORMALIZE ); - - /* - * Build a faceted latitude slice of the Boing ball, - * stepping same-sized vertical bands of the sphere. - */ - for ( lon_deg = 0; - lon_deg < 180; - lon_deg += STEP_LONGITUDE ) - { - /* - * Draw a latitude circle at this longitude. - */ - DrawBoingBallBand( lon_deg, - lon_deg + STEP_LONGITUDE ); - } - - glPopMatrix(); - - return; -} - - -/***************************************************************************** - * Bounce the ball. - *****************************************************************************/ -void BounceBall( double delta_t ) -{ - GLfloat sign; - GLfloat deg; - - if ( override_pos ) - return; - - /* Bounce on walls */ - if ( ball_x > (BOUNCE_WIDTH/2 + WALL_R_OFFSET ) ) - { - ball_x_inc = -0.5f - 0.75f * (GLfloat)rand() / (GLfloat)RAND_MAX; - deg_rot_y_inc = -deg_rot_y_inc; - } - if ( ball_x < -(BOUNCE_HEIGHT/2 + WALL_L_OFFSET) ) - { - ball_x_inc = 0.5f + 0.75f * (GLfloat)rand() / (GLfloat)RAND_MAX; - deg_rot_y_inc = -deg_rot_y_inc; - } - - /* Bounce on floor / roof */ - if ( ball_y > BOUNCE_HEIGHT/2 ) - { - ball_y_inc = -0.75f - 1.f * (GLfloat)rand() / (GLfloat)RAND_MAX; - } - if ( ball_y < -BOUNCE_HEIGHT/2*0.85 ) - { - ball_y_inc = 0.75f + 1.f * (GLfloat)rand() / (GLfloat)RAND_MAX; - } - - /* Update ball position */ - ball_x += ball_x_inc * ((float)delta_t*ANIMATION_SPEED); - ball_y += ball_y_inc * ((float)delta_t*ANIMATION_SPEED); - - /* - * Simulate the effects of gravity on Y movement. - */ - if ( ball_y_inc < 0 ) sign = -1.0; else sign = 1.0; - - deg = (ball_y + BOUNCE_HEIGHT/2) * 90 / BOUNCE_HEIGHT; - if ( deg > 80 ) deg = 80; - if ( deg < 10 ) deg = 10; - - ball_y_inc = sign * 4.f * (float) sin_deg( deg ); -} - - -/***************************************************************************** - * Draw a faceted latitude band of the Boing ball. - * - * Parms: long_lo, long_hi - * Low and high longitudes of slice, resp. - *****************************************************************************/ -void DrawBoingBallBand( GLfloat long_lo, - GLfloat long_hi ) -{ - vertex_t vert_ne; /* "ne" means south-east, so on */ - vertex_t vert_nw; - vertex_t vert_sw; - vertex_t vert_se; - vertex_t vert_norm; - GLfloat lat_deg; - static int colorToggle = 0; - - /* - * Iterate thru the points of a latitude circle. - * A latitude circle is a 2D set of X,Z points. - */ - for ( lat_deg = 0; - lat_deg <= (360 - STEP_LATITUDE); - lat_deg += STEP_LATITUDE ) - { - /* - * Color this polygon with red or white. - */ - if ( colorToggle ) - glColor3f( 0.8f, 0.1f, 0.1f ); - else - glColor3f( 0.95f, 0.95f, 0.95f ); -#if 0 - if ( lat_deg >= 180 ) - if ( colorToggle ) - glColor3f( 0.1f, 0.8f, 0.1f ); - else - glColor3f( 0.5f, 0.5f, 0.95f ); -#endif - colorToggle = ! colorToggle; - - /* - * Change color if drawing shadow. - */ - if ( drawBallHow == DRAW_BALL_SHADOW ) - glColor3f( 0.35f, 0.35f, 0.35f ); - - /* - * Assign each Y. - */ - vert_ne.y = vert_nw.y = (float) cos_deg(long_hi) * RADIUS; - vert_sw.y = vert_se.y = (float) cos_deg(long_lo) * RADIUS; - - /* - * Assign each X,Z with sin,cos values scaled by latitude radius indexed by longitude. - * Eg, long=0 and long=180 are at the poles, so zero scale is sin(longitude), - * while long=90 (sin(90)=1) is at equator. - */ - vert_ne.x = (float) cos_deg( lat_deg ) * (RADIUS * (float) sin_deg( long_lo + STEP_LONGITUDE )); - vert_se.x = (float) cos_deg( lat_deg ) * (RADIUS * (float) sin_deg( long_lo )); - vert_nw.x = (float) cos_deg( lat_deg + STEP_LATITUDE ) * (RADIUS * (float) sin_deg( long_lo + STEP_LONGITUDE )); - vert_sw.x = (float) cos_deg( lat_deg + STEP_LATITUDE ) * (RADIUS * (float) sin_deg( long_lo )); - - vert_ne.z = (float) sin_deg( lat_deg ) * (RADIUS * (float) sin_deg( long_lo + STEP_LONGITUDE )); - vert_se.z = (float) sin_deg( lat_deg ) * (RADIUS * (float) sin_deg( long_lo )); - vert_nw.z = (float) sin_deg( lat_deg + STEP_LATITUDE ) * (RADIUS * (float) sin_deg( long_lo + STEP_LONGITUDE )); - vert_sw.z = (float) sin_deg( lat_deg + STEP_LATITUDE ) * (RADIUS * (float) sin_deg( long_lo )); - - /* - * Draw the facet. - */ - glBegin( GL_POLYGON ); - - CrossProduct( vert_ne, vert_nw, vert_sw, &vert_norm ); - glNormal3f( vert_norm.x, vert_norm.y, vert_norm.z ); - - glVertex3f( vert_ne.x, vert_ne.y, vert_ne.z ); - glVertex3f( vert_nw.x, vert_nw.y, vert_nw.z ); - glVertex3f( vert_sw.x, vert_sw.y, vert_sw.z ); - glVertex3f( vert_se.x, vert_se.y, vert_se.z ); - - glEnd(); - -#if BOING_DEBUG - printf( "----------------------------------------------------------- \n" ); - printf( "lat = %f long_lo = %f long_hi = %f \n", lat_deg, long_lo, long_hi ); - printf( "vert_ne x = %.8f y = %.8f z = %.8f \n", vert_ne.x, vert_ne.y, vert_ne.z ); - printf( "vert_nw x = %.8f y = %.8f z = %.8f \n", vert_nw.x, vert_nw.y, vert_nw.z ); - printf( "vert_se x = %.8f y = %.8f z = %.8f \n", vert_se.x, vert_se.y, vert_se.z ); - printf( "vert_sw x = %.8f y = %.8f z = %.8f \n", vert_sw.x, vert_sw.y, vert_sw.z ); -#endif - - } - - /* - * Toggle color so that next band will opposite red/white colors than this one. - */ - colorToggle = ! colorToggle; - - /* - * This circular band is done. - */ - return; -} - - -/***************************************************************************** - * Draw the purple grid of lines, behind the Boing ball. - * When the Workbench is dropped to the bottom, Boing shows 12 rows. - *****************************************************************************/ -void DrawGrid( void ) -{ - int row, col; - const int rowTotal = 12; /* must be divisible by 2 */ - const int colTotal = rowTotal; /* must be same as rowTotal */ - const GLfloat widthLine = 2.0; /* should be divisible by 2 */ - const GLfloat sizeCell = GRID_SIZE / rowTotal; - const GLfloat z_offset = -40.0; - GLfloat xl, xr; - GLfloat yt, yb; - - glPushMatrix(); - glDisable( GL_CULL_FACE ); - - /* - * Another relative Z translation to separate objects. - */ - glTranslatef( 0.0, 0.0, DIST_BALL ); - - /* - * Draw vertical lines (as skinny 3D rectangles). - */ - for ( col = 0; col <= colTotal; col++ ) - { - /* - * Compute co-ords of line. - */ - xl = -GRID_SIZE / 2 + col * sizeCell; - xr = xl + widthLine; - - yt = GRID_SIZE / 2; - yb = -GRID_SIZE / 2 - widthLine; - - glBegin( GL_POLYGON ); - - glColor3f( 0.6f, 0.1f, 0.6f ); /* purple */ - - glVertex3f( xr, yt, z_offset ); /* NE */ - glVertex3f( xl, yt, z_offset ); /* NW */ - glVertex3f( xl, yb, z_offset ); /* SW */ - glVertex3f( xr, yb, z_offset ); /* SE */ - - glEnd(); - } - - /* - * Draw horizontal lines (as skinny 3D rectangles). - */ - for ( row = 0; row <= rowTotal; row++ ) - { - /* - * Compute co-ords of line. - */ - yt = GRID_SIZE / 2 - row * sizeCell; - yb = yt - widthLine; - - xl = -GRID_SIZE / 2; - xr = GRID_SIZE / 2 + widthLine; - - glBegin( GL_POLYGON ); - - glColor3f( 0.6f, 0.1f, 0.6f ); /* purple */ - - glVertex3f( xr, yt, z_offset ); /* NE */ - glVertex3f( xl, yt, z_offset ); /* NW */ - glVertex3f( xl, yb, z_offset ); /* SW */ - glVertex3f( xr, yb, z_offset ); /* SE */ - - glEnd(); - } - - glPopMatrix(); - - return; -} - - -/*======================================================================* - * main() - *======================================================================*/ - -int main( void ) -{ - GLFWwindow* window; - - /* Init GLFW */ - if( !glfwInit() ) - exit( EXIT_FAILURE ); - - glfwWindowHint(GLFW_DEPTH_BITS, 16); - - window = glfwCreateWindow( 400, 400, "Boing (classic Amiga demo)", NULL, NULL ); - if (!window) - { - glfwTerminate(); - exit( EXIT_FAILURE ); - } - - glfwSetFramebufferSizeCallback(window, reshape); - glfwSetKeyCallback(window, key_callback); - glfwSetMouseButtonCallback(window, mouse_button_callback); - glfwSetCursorPosCallback(window, cursor_position_callback); - - glfwMakeContextCurrent(window); - glfwSwapInterval( 1 ); - - glfwGetFramebufferSize(window, &width, &height); - reshape(window, width, height); - - glfwSetTime( 0.0 ); - - init(); - - /* Main loop */ - for (;;) - { - /* Timing */ - t = glfwGetTime(); - dt = t - t_old; - t_old = t; - - /* Draw one frame */ - display(); - - /* Swap buffers */ - glfwSwapBuffers(window); - glfwPollEvents(); - - /* Check if we are still running */ - if (glfwWindowShouldClose(window)) - break; - } - - glfwTerminate(); - exit( EXIT_SUCCESS ); -} - diff --git a/examples/common/glfw/examples/gears.c b/examples/common/glfw/examples/gears.c deleted file mode 100644 index 2d445964..00000000 --- a/examples/common/glfw/examples/gears.c +++ /dev/null @@ -1,372 +0,0 @@ -/* - * 3-D gear wheels. This program is in the public domain. - * - * Command line options: - * -info print GL implementation information - * -exit automatically exit after 30 seconds - * - * - * Brian Paul - * - * - * Marcus Geelnard: - * - Conversion to GLFW - * - Time based rendering (frame rate independent) - * - Slightly modified camera that should work better for stereo viewing - * - * - * Camilla Berglund: - * - Removed FPS counter (this is not a benchmark) - * - Added a few comments - * - Enabled vsync - */ - - -#include -#include -#include -#include -#include - -#ifndef M_PI -#define M_PI 3.141592654 -#endif - -/* If non-zero, the program exits after that many seconds - */ -static int autoexit = 0; - -/** - - Draw a gear wheel. You'll probably want to call this function when - building a display list since we do a lot of trig here. - - Input: inner_radius - radius of hole at center - outer_radius - radius at center of teeth - width - width of gear teeth - number of teeth - tooth_depth - depth of tooth - - **/ - -static void -gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width, - GLint teeth, GLfloat tooth_depth) -{ - GLint i; - GLfloat r0, r1, r2; - GLfloat angle, da; - GLfloat u, v, len; - - r0 = inner_radius; - r1 = outer_radius - tooth_depth / 2.f; - r2 = outer_radius + tooth_depth / 2.f; - - da = 2.f * (float) M_PI / teeth / 4.f; - - glShadeModel(GL_FLAT); - - glNormal3f(0.f, 0.f, 1.f); - - /* draw front face */ - glBegin(GL_QUAD_STRIP); - for (i = 0; i <= teeth; i++) { - angle = i * 2.f * (float) M_PI / teeth; - glVertex3f(r0 * (float) cos(angle), r0 * (float) sin(angle), width * 0.5f); - glVertex3f(r1 * (float) cos(angle), r1 * (float) sin(angle), width * 0.5f); - if (i < teeth) { - glVertex3f(r0 * (float) cos(angle), r0 * (float) sin(angle), width * 0.5f); - glVertex3f(r1 * (float) cos(angle + 3 * da), r1 * (float) sin(angle + 3 * da), width * 0.5f); - } - } - glEnd(); - - /* draw front sides of teeth */ - glBegin(GL_QUADS); - da = 2.f * (float) M_PI / teeth / 4.f; - for (i = 0; i < teeth; i++) { - angle = i * 2.f * (float) M_PI / teeth; - - glVertex3f(r1 * (float) cos(angle), r1 * (float) sin(angle), width * 0.5f); - glVertex3f(r2 * (float) cos(angle + da), r2 * (float) sin(angle + da), width * 0.5f); - glVertex3f(r2 * (float) cos(angle + 2 * da), r2 * (float) sin(angle + 2 * da), width * 0.5f); - glVertex3f(r1 * (float) cos(angle + 3 * da), r1 * (float) sin(angle + 3 * da), width * 0.5f); - } - glEnd(); - - glNormal3f(0.0, 0.0, -1.0); - - /* draw back face */ - glBegin(GL_QUAD_STRIP); - for (i = 0; i <= teeth; i++) { - angle = i * 2.f * (float) M_PI / teeth; - glVertex3f(r1 * (float) cos(angle), r1 * (float) sin(angle), -width * 0.5f); - glVertex3f(r0 * (float) cos(angle), r0 * (float) sin(angle), -width * 0.5f); - if (i < teeth) { - glVertex3f(r1 * (float) cos(angle + 3 * da), r1 * (float) sin(angle + 3 * da), -width * 0.5f); - glVertex3f(r0 * (float) cos(angle), r0 * (float) sin(angle), -width * 0.5f); - } - } - glEnd(); - - /* draw back sides of teeth */ - glBegin(GL_QUADS); - da = 2.f * (float) M_PI / teeth / 4.f; - for (i = 0; i < teeth; i++) { - angle = i * 2.f * (float) M_PI / teeth; - - glVertex3f(r1 * (float) cos(angle + 3 * da), r1 * (float) sin(angle + 3 * da), -width * 0.5f); - glVertex3f(r2 * (float) cos(angle + 2 * da), r2 * (float) sin(angle + 2 * da), -width * 0.5f); - glVertex3f(r2 * (float) cos(angle + da), r2 * (float) sin(angle + da), -width * 0.5f); - glVertex3f(r1 * (float) cos(angle), r1 * (float) sin(angle), -width * 0.5f); - } - glEnd(); - - /* draw outward faces of teeth */ - glBegin(GL_QUAD_STRIP); - for (i = 0; i < teeth; i++) { - angle = i * 2.f * (float) M_PI / teeth; - - glVertex3f(r1 * (float) cos(angle), r1 * (float) sin(angle), width * 0.5f); - glVertex3f(r1 * (float) cos(angle), r1 * (float) sin(angle), -width * 0.5f); - u = r2 * (float) cos(angle + da) - r1 * (float) cos(angle); - v = r2 * (float) sin(angle + da) - r1 * (float) sin(angle); - len = (float) sqrt(u * u + v * v); - u /= len; - v /= len; - glNormal3f(v, -u, 0.0); - glVertex3f(r2 * (float) cos(angle + da), r2 * (float) sin(angle + da), width * 0.5f); - glVertex3f(r2 * (float) cos(angle + da), r2 * (float) sin(angle + da), -width * 0.5f); - glNormal3f((float) cos(angle), (float) sin(angle), 0.f); - glVertex3f(r2 * (float) cos(angle + 2 * da), r2 * (float) sin(angle + 2 * da), width * 0.5f); - glVertex3f(r2 * (float) cos(angle + 2 * da), r2 * (float) sin(angle + 2 * da), -width * 0.5f); - u = r1 * (float) cos(angle + 3 * da) - r2 * (float) cos(angle + 2 * da); - v = r1 * (float) sin(angle + 3 * da) - r2 * (float) sin(angle + 2 * da); - glNormal3f(v, -u, 0.f); - glVertex3f(r1 * (float) cos(angle + 3 * da), r1 * (float) sin(angle + 3 * da), width * 0.5f); - glVertex3f(r1 * (float) cos(angle + 3 * da), r1 * (float) sin(angle + 3 * da), -width * 0.5f); - glNormal3f((float) cos(angle), (float) sin(angle), 0.f); - } - - glVertex3f(r1 * (float) cos(0), r1 * (float) sin(0), width * 0.5f); - glVertex3f(r1 * (float) cos(0), r1 * (float) sin(0), -width * 0.5f); - - glEnd(); - - glShadeModel(GL_SMOOTH); - - /* draw inside radius cylinder */ - glBegin(GL_QUAD_STRIP); - for (i = 0; i <= teeth; i++) { - angle = i * 2.f * (float) M_PI / teeth; - glNormal3f(-(float) cos(angle), -(float) sin(angle), 0.f); - glVertex3f(r0 * (float) cos(angle), r0 * (float) sin(angle), -width * 0.5f); - glVertex3f(r0 * (float) cos(angle), r0 * (float) sin(angle), width * 0.5f); - } - glEnd(); - -} - - -static GLfloat view_rotx = 20.f, view_roty = 30.f, view_rotz = 0.f; -static GLint gear1, gear2, gear3; -static GLfloat angle = 0.f; - -/* OpenGL draw function & timing */ -static void draw(void) -{ - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glPushMatrix(); - glRotatef(view_rotx, 1.0, 0.0, 0.0); - glRotatef(view_roty, 0.0, 1.0, 0.0); - glRotatef(view_rotz, 0.0, 0.0, 1.0); - - glPushMatrix(); - glTranslatef(-3.0, -2.0, 0.0); - glRotatef(angle, 0.0, 0.0, 1.0); - glCallList(gear1); - glPopMatrix(); - - glPushMatrix(); - glTranslatef(3.1f, -2.f, 0.f); - glRotatef(-2.f * angle - 9.f, 0.f, 0.f, 1.f); - glCallList(gear2); - glPopMatrix(); - - glPushMatrix(); - glTranslatef(-3.1f, 4.2f, 0.f); - glRotatef(-2.f * angle - 25.f, 0.f, 0.f, 1.f); - glCallList(gear3); - glPopMatrix(); - - glPopMatrix(); -} - - -/* update animation parameters */ -static void animate(void) -{ - angle = 100.f * (float) glfwGetTime(); -} - - -/* change view angle, exit upon ESC */ -void key( GLFWwindow* window, int k, int s, int action, int mods ) -{ - if( action != GLFW_PRESS ) return; - - switch (k) { - case GLFW_KEY_Z: - if( mods & GLFW_MOD_SHIFT ) - view_rotz -= 5.0; - else - view_rotz += 5.0; - break; - case GLFW_KEY_ESCAPE: - glfwSetWindowShouldClose(window, GL_TRUE); - break; - case GLFW_KEY_UP: - view_rotx += 5.0; - break; - case GLFW_KEY_DOWN: - view_rotx -= 5.0; - break; - case GLFW_KEY_LEFT: - view_roty += 5.0; - break; - case GLFW_KEY_RIGHT: - view_roty -= 5.0; - break; - default: - return; - } -} - - -/* new window size */ -void reshape( GLFWwindow* window, int width, int height ) -{ - GLfloat h = (GLfloat) height / (GLfloat) width; - GLfloat xmax, znear, zfar; - - znear = 5.0f; - zfar = 30.0f; - xmax = znear * 0.5f; - - glViewport( 0, 0, (GLint) width, (GLint) height ); - glMatrixMode( GL_PROJECTION ); - glLoadIdentity(); - glFrustum( -xmax, xmax, -xmax*h, xmax*h, znear, zfar ); - glMatrixMode( GL_MODELVIEW ); - glLoadIdentity(); - glTranslatef( 0.0, 0.0, -20.0 ); -} - - -/* program & OpenGL initialization */ -static void init(int argc, char *argv[]) -{ - static GLfloat pos[4] = {5.f, 5.f, 10.f, 0.f}; - static GLfloat red[4] = {0.8f, 0.1f, 0.f, 1.f}; - static GLfloat green[4] = {0.f, 0.8f, 0.2f, 1.f}; - static GLfloat blue[4] = {0.2f, 0.2f, 1.f, 1.f}; - GLint i; - - glLightfv(GL_LIGHT0, GL_POSITION, pos); - glEnable(GL_CULL_FACE); - glEnable(GL_LIGHTING); - glEnable(GL_LIGHT0); - glEnable(GL_DEPTH_TEST); - - /* make the gears */ - gear1 = glGenLists(1); - glNewList(gear1, GL_COMPILE); - glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red); - gear(1.f, 4.f, 1.f, 20, 0.7f); - glEndList(); - - gear2 = glGenLists(1); - glNewList(gear2, GL_COMPILE); - glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green); - gear(0.5f, 2.f, 2.f, 10, 0.7f); - glEndList(); - - gear3 = glGenLists(1); - glNewList(gear3, GL_COMPILE); - glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue); - gear(1.3f, 2.f, 0.5f, 10, 0.7f); - glEndList(); - - glEnable(GL_NORMALIZE); - - for ( i=1; i -#include -#include -#include -#include - -#include -#include - -/* Map height updates */ -#define MAX_CIRCLE_SIZE (5.0f) -#define MAX_DISPLACEMENT (1.0f) -#define DISPLACEMENT_SIGN_LIMIT (0.3f) -#define MAX_ITER (200) -#define NUM_ITER_AT_A_TIME (1) - -/* Map general information */ -#define MAP_SIZE (10.0f) -#define MAP_NUM_VERTICES (80) -#define MAP_NUM_TOTAL_VERTICES (MAP_NUM_VERTICES*MAP_NUM_VERTICES) -#define MAP_NUM_LINES (3* (MAP_NUM_VERTICES - 1) * (MAP_NUM_VERTICES - 1) + \ - 2 * (MAP_NUM_VERTICES - 1)) - - -/********************************************************************** - * Default shader programs - *********************************************************************/ - -static const char* vertex_shader_text = -"#version 150\n" -"uniform mat4 project;\n" -"uniform mat4 modelview;\n" -"in float x;\n" -"in float y;\n" -"in float z;\n" -"\n" -"void main()\n" -"{\n" -" gl_Position = project * modelview * vec4(x, y, z, 1.0);\n" -"}\n"; - -static const char* fragment_shader_text = -"#version 150\n" -"out vec4 color;\n" -"void main()\n" -"{\n" -" color = vec4(0.2, 1.0, 0.2, 1.0); \n" -"}\n"; - -/********************************************************************** - * Values for shader uniforms - *********************************************************************/ - -/* Frustum configuration */ -static GLfloat view_angle = 45.0f; -static GLfloat aspect_ratio = 4.0f/3.0f; -static GLfloat z_near = 1.0f; -static GLfloat z_far = 100.f; - -/* Projection matrix */ -static GLfloat projection_matrix[16] = { - 1.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f -}; - -/* Model view matrix */ -static GLfloat modelview_matrix[16] = { - 1.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f -}; - -/********************************************************************** - * Heightmap vertex and index data - *********************************************************************/ - -static GLfloat map_vertices[3][MAP_NUM_TOTAL_VERTICES]; -static GLuint map_line_indices[2*MAP_NUM_LINES]; - -/* Store uniform location for the shaders - * Those values are setup as part of the process of creating - * the shader program. They should not be used before creating - * the program. - */ -static GLuint mesh; -static GLuint mesh_vbo[4]; - -/********************************************************************** - * OpenGL helper functions - *********************************************************************/ - -/* Creates a shader object of the specified type using the specified text - */ -static GLuint make_shader(GLenum type, const char* text) -{ - GLuint shader; - GLint shader_ok; - GLsizei log_length; - char info_log[8192]; - - shader = glCreateShader(type); - if (shader != 0) - { - glShaderSource(shader, 1, (const GLchar**)&text, NULL); - glCompileShader(shader); - glGetShaderiv(shader, GL_COMPILE_STATUS, &shader_ok); - if (shader_ok != GL_TRUE) - { - fprintf(stderr, "ERROR: Failed to compile %s shader\n", (type == GL_FRAGMENT_SHADER) ? "fragment" : "vertex" ); - glGetShaderInfoLog(shader, 8192, &log_length,info_log); - fprintf(stderr, "ERROR: \n%s\n\n", info_log); - glDeleteShader(shader); - shader = 0; - } - } - return shader; -} - -/* Creates a program object using the specified vertex and fragment text - */ -static GLuint make_shader_program(const char* vs_text, const char* fs_text) -{ - GLuint program = 0u; - GLint program_ok; - GLuint vertex_shader = 0u; - GLuint fragment_shader = 0u; - GLsizei log_length; - char info_log[8192]; - - vertex_shader = make_shader(GL_VERTEX_SHADER, vs_text); - if (vertex_shader != 0u) - { - fragment_shader = make_shader(GL_FRAGMENT_SHADER, fs_text); - if (fragment_shader != 0u) - { - /* make the program that connect the two shader and link it */ - program = glCreateProgram(); - if (program != 0u) - { - /* attach both shader and link */ - glAttachShader(program, vertex_shader); - glAttachShader(program, fragment_shader); - glLinkProgram(program); - glGetProgramiv(program, GL_LINK_STATUS, &program_ok); - - if (program_ok != GL_TRUE) - { - fprintf(stderr, "ERROR, failed to link shader program\n"); - glGetProgramInfoLog(program, 8192, &log_length, info_log); - fprintf(stderr, "ERROR: \n%s\n\n", info_log); - glDeleteProgram(program); - glDeleteShader(fragment_shader); - glDeleteShader(vertex_shader); - program = 0u; - } - } - } - else - { - fprintf(stderr, "ERROR: Unable to load fragment shader\n"); - glDeleteShader(vertex_shader); - } - } - else - { - fprintf(stderr, "ERROR: Unable to load vertex shader\n"); - } - return program; -} - -/********************************************************************** - * Geometry creation functions - *********************************************************************/ - -/* Generate vertices and indices for the heightmap - */ -static void init_map(void) -{ - int i; - int j; - int k; - GLfloat step = MAP_SIZE / (MAP_NUM_VERTICES - 1); - GLfloat x = 0.0f; - GLfloat z = 0.0f; - /* Create a flat grid */ - k = 0; - for (i = 0 ; i < MAP_NUM_VERTICES ; ++i) - { - for (j = 0 ; j < MAP_NUM_VERTICES ; ++j) - { - map_vertices[0][k] = x; - map_vertices[1][k] = 0.0f; - map_vertices[2][k] = z; - z += step; - ++k; - } - x += step; - z = 0.0f; - } -#if DEBUG_ENABLED - for (i = 0 ; i < MAP_NUM_TOTAL_VERTICES ; ++i) - { - printf ("Vertice %d (%f, %f, %f)\n", - i, map_vertices[0][i], map_vertices[1][i], map_vertices[2][i]); - - } -#endif - /* create indices */ - /* line fan based on i - * i+1 - * | / i + n + 1 - * | / - * |/ - * i --- i + n - */ - - /* close the top of the square */ - k = 0; - for (i = 0 ; i < MAP_NUM_VERTICES -1 ; ++i) - { - map_line_indices[k++] = (i + 1) * MAP_NUM_VERTICES -1; - map_line_indices[k++] = (i + 2) * MAP_NUM_VERTICES -1; - } - /* close the right of the square */ - for (i = 0 ; i < MAP_NUM_VERTICES -1 ; ++i) - { - map_line_indices[k++] = (MAP_NUM_VERTICES - 1) * MAP_NUM_VERTICES + i; - map_line_indices[k++] = (MAP_NUM_VERTICES - 1) * MAP_NUM_VERTICES + i + 1; - } - - for (i = 0 ; i < (MAP_NUM_VERTICES - 1) ; ++i) - { - for (j = 0 ; j < (MAP_NUM_VERTICES - 1) ; ++j) - { - int ref = i * (MAP_NUM_VERTICES) + j; - map_line_indices[k++] = ref; - map_line_indices[k++] = ref + 1; - - map_line_indices[k++] = ref; - map_line_indices[k++] = ref + MAP_NUM_VERTICES; - - map_line_indices[k++] = ref; - map_line_indices[k++] = ref + MAP_NUM_VERTICES + 1; - } - } - -#ifdef DEBUG_ENABLED - for (k = 0 ; k < 2 * MAP_NUM_LINES ; k += 2) - { - int beg, end; - beg = map_line_indices[k]; - end = map_line_indices[k+1]; - printf ("Line %d: %d -> %d (%f, %f, %f) -> (%f, %f, %f)\n", - k / 2, beg, end, - map_vertices[0][beg], map_vertices[1][beg], map_vertices[2][beg], - map_vertices[0][end], map_vertices[1][end], map_vertices[2][end]); - } -#endif -} - -static void generate_heightmap__circle(float* center_x, float* center_y, - float* size, float* displacement) -{ - float sign; - /* random value for element in between [0-1.0] */ - *center_x = (MAP_SIZE * rand()) / (1.0f * RAND_MAX); - *center_y = (MAP_SIZE * rand()) / (1.0f * RAND_MAX); - *size = (MAX_CIRCLE_SIZE * rand()) / (1.0f * RAND_MAX); - sign = (1.0f * rand()) / (1.0f * RAND_MAX); - sign = (sign < DISPLACEMENT_SIGN_LIMIT) ? -1.0f : 1.0f; - *displacement = (sign * (MAX_DISPLACEMENT * rand())) / (1.0f * RAND_MAX); -} - -/* Run the specified number of iterations of the generation process for the - * heightmap - */ -static void update_map(int num_iter) -{ - assert(num_iter > 0); - while(num_iter) - { - /* center of the circle */ - float center_x; - float center_z; - float circle_size; - float disp; - size_t ii; - generate_heightmap__circle(¢er_x, ¢er_z, &circle_size, &disp); - disp = disp / 2.0f; - for (ii = 0u ; ii < MAP_NUM_TOTAL_VERTICES ; ++ii) - { - GLfloat dx = center_x - map_vertices[0][ii]; - GLfloat dz = center_z - map_vertices[2][ii]; - GLfloat pd = (2.0f * sqrtf((dx * dx) + (dz * dz))) / circle_size; - if (fabs(pd) <= 1.0f) - { - /* tx,tz is within the circle */ - GLfloat new_height = disp + (float) (cos(pd*3.14f)*disp); - map_vertices[1][ii] += new_height; - } - } - --num_iter; - } -} - -/********************************************************************** - * OpenGL helper functions - *********************************************************************/ - -/* Create VBO, IBO and VAO objects for the heightmap geometry and bind them to - * the specified program object - */ -static void make_mesh(GLuint program) -{ - GLuint attrloc; - - glGenVertexArrays(1, &mesh); - glGenBuffers(4, mesh_vbo); - glBindVertexArray(mesh); - /* Prepare the data for drawing through a buffer inidices */ - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh_vbo[3]); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint)* MAP_NUM_LINES * 2, map_line_indices, GL_STATIC_DRAW); - - /* Prepare the attributes for rendering */ - attrloc = glGetAttribLocation(program, "x"); - glBindBuffer(GL_ARRAY_BUFFER, mesh_vbo[0]); - glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * MAP_NUM_TOTAL_VERTICES, &map_vertices[0][0], GL_STATIC_DRAW); - glEnableVertexAttribArray(attrloc); - glVertexAttribPointer(attrloc, 1, GL_FLOAT, GL_FALSE, 0, 0); - - attrloc = glGetAttribLocation(program, "z"); - glBindBuffer(GL_ARRAY_BUFFER, mesh_vbo[2]); - glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * MAP_NUM_TOTAL_VERTICES, &map_vertices[2][0], GL_STATIC_DRAW); - glEnableVertexAttribArray(attrloc); - glVertexAttribPointer(attrloc, 1, GL_FLOAT, GL_FALSE, 0, 0); - - attrloc = glGetAttribLocation(program, "y"); - glBindBuffer(GL_ARRAY_BUFFER, mesh_vbo[1]); - glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * MAP_NUM_TOTAL_VERTICES, &map_vertices[1][0], GL_DYNAMIC_DRAW); - glEnableVertexAttribArray(attrloc); - glVertexAttribPointer(attrloc, 1, GL_FLOAT, GL_FALSE, 0, 0); -} - -/* Update VBO vertices from source data - */ -static void update_mesh(void) -{ - glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(GLfloat) * MAP_NUM_TOTAL_VERTICES, &map_vertices[1][0]); -} - -/********************************************************************** - * GLFW callback functions - *********************************************************************/ - -static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) -{ - switch(key) - { - case GLFW_KEY_ESCAPE: - /* Exit program on Escape */ - glfwSetWindowShouldClose(window, GL_TRUE); - break; - } -} - -static void error_callback(int error, const char* description) -{ - fprintf(stderr, "Error: %s\n", description); -} - -int main(int argc, char** argv) -{ - GLFWwindow* window; - int iter; - double dt; - double last_update_time; - int frame; - float f; - GLint uloc_modelview; - GLint uloc_project; - - GLuint shader_program; - - glfwSetErrorCallback(error_callback); - - if (!glfwInit()) - exit(EXIT_FAILURE); - - glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); - - window = glfwCreateWindow(800, 600, "GLFW OpenGL3 Heightmap demo", NULL, NULL); - if (! window ) - { - glfwTerminate(); - exit(EXIT_FAILURE); - } - - /* Register events callback */ - glfwSetKeyCallback(window, key_callback); - - glfwMakeContextCurrent(window); - gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); - - /* Prepare opengl resources for rendering */ - shader_program = make_shader_program(vertex_shader_text, fragment_shader_text); - - if (shader_program == 0u) - { - glfwTerminate(); - exit(EXIT_FAILURE); - } - - glUseProgram(shader_program); - uloc_project = glGetUniformLocation(shader_program, "project"); - uloc_modelview = glGetUniformLocation(shader_program, "modelview"); - - /* Compute the projection matrix */ - f = 1.0f / tanf(view_angle / 2.0f); - projection_matrix[0] = f / aspect_ratio; - projection_matrix[5] = f; - projection_matrix[10] = (z_far + z_near)/ (z_near - z_far); - projection_matrix[11] = -1.0f; - projection_matrix[14] = 2.0f * (z_far * z_near) / (z_near - z_far); - glUniformMatrix4fv(uloc_project, 1, GL_FALSE, projection_matrix); - - /* Set the camera position */ - modelview_matrix[12] = -5.0f; - modelview_matrix[13] = -5.0f; - modelview_matrix[14] = -20.0f; - glUniformMatrix4fv(uloc_modelview, 1, GL_FALSE, modelview_matrix); - - /* Create mesh data */ - init_map(); - make_mesh(shader_program); - - /* Create vao + vbo to store the mesh */ - /* Create the vbo to store all the information for the grid and the height */ - - /* setup the scene ready for rendering */ - glViewport(0, 0, 800, 600); - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - - /* main loop */ - frame = 0; - iter = 0; - last_update_time = glfwGetTime(); - - while (!glfwWindowShouldClose(window)) - { - ++frame; - /* render the next frame */ - glClear(GL_COLOR_BUFFER_BIT); - glDrawElements(GL_LINES, 2* MAP_NUM_LINES , GL_UNSIGNED_INT, 0); - - /* display and process events through callbacks */ - glfwSwapBuffers(window); - glfwPollEvents(); - /* Check the frame rate and update the heightmap if needed */ - dt = glfwGetTime(); - if ((dt - last_update_time) > 0.2) - { - /* generate the next iteration of the heightmap */ - if (iter < MAX_ITER) - { - update_map(NUM_ITER_AT_A_TIME); - update_mesh(); - iter += NUM_ITER_AT_A_TIME; - } - last_update_time = dt; - frame = 0; - } - } - - glfwTerminate(); - exit(EXIT_SUCCESS); -} - diff --git a/examples/common/glfw/examples/particles.c b/examples/common/glfw/examples/particles.c deleted file mode 100644 index dc9e9fc8..00000000 --- a/examples/common/glfw/examples/particles.c +++ /dev/null @@ -1,1061 +0,0 @@ -//======================================================================== -// A simple particle engine with threaded physics -// Copyright (c) Marcus Geelnard -// Copyright (c) Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#include -#include -#include -#include -#include - -#include -#include - -#define GLFW_INCLUDE_GLU -#include - -// Define tokens for GL_EXT_separate_specular_color if not already defined -#ifndef GL_EXT_separate_specular_color -#define GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8 -#define GL_SINGLE_COLOR_EXT 0x81F9 -#define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA -#endif // GL_EXT_separate_specular_color - -// Some 's do not define M_PI -#ifndef M_PI -#define M_PI 3.141592654 -#endif - - -//======================================================================== -// Type definitions -//======================================================================== - -typedef struct -{ - float x, y, z; -} Vec3; - -// This structure is used for interleaved vertex arrays (see the -// draw_particles function) -// -// NOTE: This structure SHOULD be packed on most systems. It uses 32-bit fields -// on 32-bit boundaries, and is a multiple of 64 bits in total (6x32=3x64). If -// it does not work, try using pragmas or whatever to force the structure to be -// packed. -typedef struct -{ - GLfloat s, t; // Texture coordinates - GLuint rgba; // Color (four ubytes packed into an uint) - GLfloat x, y, z; // Vertex coordinates -} Vertex; - - -//======================================================================== -// Program control global variables -//======================================================================== - -// Window dimensions -float aspect_ratio; - -// "wireframe" flag (true if we use wireframe view) -int wireframe; - -// Thread synchronization -struct { - double t; // Time (s) - float dt; // Time since last frame (s) - int p_frame; // Particle physics frame number - int d_frame; // Particle draw frame number - cnd_t p_done; // Condition: particle physics done - cnd_t d_done; // Condition: particle draw done - mtx_t particles_lock; // Particles data sharing mutex -} thread_sync; - - -//======================================================================== -// Texture declarations (we hard-code them into the source code, since -// they are so simple) -//======================================================================== - -#define P_TEX_WIDTH 8 // Particle texture dimensions -#define P_TEX_HEIGHT 8 -#define F_TEX_WIDTH 16 // Floor texture dimensions -#define F_TEX_HEIGHT 16 - -// Texture object IDs -GLuint particle_tex_id, floor_tex_id; - -// Particle texture (a simple spot) -const unsigned char particle_texture[ P_TEX_WIDTH * P_TEX_HEIGHT ] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x11, 0x22, 0x22, 0x11, 0x00, 0x00, - 0x00, 0x11, 0x33, 0x88, 0x77, 0x33, 0x11, 0x00, - 0x00, 0x22, 0x88, 0xff, 0xee, 0x77, 0x22, 0x00, - 0x00, 0x22, 0x77, 0xee, 0xff, 0x88, 0x22, 0x00, - 0x00, 0x11, 0x33, 0x77, 0x88, 0x33, 0x11, 0x00, - 0x00, 0x00, 0x11, 0x33, 0x22, 0x11, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -// Floor texture (your basic checkered floor) -const unsigned char floor_texture[ F_TEX_WIDTH * F_TEX_HEIGHT ] = { - 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0xff, 0xf0, 0xcc, 0xf0, 0xf0, 0xf0, 0xff, 0xf0, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0xf0, 0xcc, 0xee, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 0x30, 0x66, 0x30, 0x30, 0x30, 0x20, 0x30, 0x30, - 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xee, 0xf0, 0xf0, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0xf0, 0xf0, 0xf0, 0xf0, 0xcc, 0xf0, 0xf0, 0xf0, 0x30, 0x30, 0x55, 0x30, 0x30, 0x44, 0x30, 0x30, - 0xf0, 0xdd, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0x33, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xff, 0xf0, 0xf0, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x60, 0x30, - 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0x33, 0x33, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, 0x30, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x20, 0x30, 0x30, 0xf0, 0xff, 0xf0, 0xf0, 0xdd, 0xf0, 0xf0, 0xff, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x55, 0x33, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xff, 0xf0, 0xf0, - 0x30, 0x44, 0x66, 0x30, 0x30, 0x30, 0x30, 0x30, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0xf0, 0xf0, 0xf0, 0xaa, 0xf0, 0xf0, 0xcc, 0xf0, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0xff, 0xf0, 0xf0, 0xf0, 0xff, 0xf0, 0xdd, 0xf0, - 0x30, 0x30, 0x30, 0x77, 0x30, 0x30, 0x30, 0x30, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, -}; - - -//======================================================================== -// These are fixed constants that control the particle engine. In a -// modular world, these values should be variables... -//======================================================================== - -// Maximum number of particles -#define MAX_PARTICLES 3000 - -// Life span of a particle (in seconds) -#define LIFE_SPAN 8.f - -// A new particle is born every [BIRTH_INTERVAL] second -#define BIRTH_INTERVAL (LIFE_SPAN/(float)MAX_PARTICLES) - -// Particle size (meters) -#define PARTICLE_SIZE 0.7f - -// Gravitational constant (m/s^2) -#define GRAVITY 9.8f - -// Base initial velocity (m/s) -#define VELOCITY 8.f - -// Bounce friction (1.0 = no friction, 0.0 = maximum friction) -#define FRICTION 0.75f - -// "Fountain" height (m) -#define FOUNTAIN_HEIGHT 3.f - -// Fountain radius (m) -#define FOUNTAIN_RADIUS 1.6f - -// Minimum delta-time for particle phisics (s) -#define MIN_DELTA_T (BIRTH_INTERVAL * 0.5f) - - -//======================================================================== -// Particle system global variables -//======================================================================== - -// This structure holds all state for a single particle -typedef struct { - float x,y,z; // Position in space - float vx,vy,vz; // Velocity vector - float r,g,b; // Color of particle - float life; // Life of particle (1.0 = newborn, < 0.0 = dead) - int active; // Tells if this particle is active -} PARTICLE; - -// Global vectors holding all particles. We use two vectors for double -// buffering. -static PARTICLE particles[MAX_PARTICLES]; - -// Global variable holding the age of the youngest particle -static float min_age; - -// Color of latest born particle (used for fountain lighting) -static float glow_color[4]; - -// Position of latest born particle (used for fountain lighting) -static float glow_pos[4]; - - -//======================================================================== -// Object material and fog configuration constants -//======================================================================== - -const GLfloat fountain_diffuse[4] = { 0.7f, 1.f, 1.f, 1.f }; -const GLfloat fountain_specular[4] = { 1.f, 1.f, 1.f, 1.f }; -const GLfloat fountain_shininess = 12.f; -const GLfloat floor_diffuse[4] = { 1.f, 0.6f, 0.6f, 1.f }; -const GLfloat floor_specular[4] = { 0.6f, 0.6f, 0.6f, 1.f }; -const GLfloat floor_shininess = 18.f; -const GLfloat fog_color[4] = { 0.1f, 0.1f, 0.1f, 1.f }; - - -//======================================================================== -// Print usage information -//======================================================================== - -static void usage(void) -{ - printf("Usage: particles [-bfhs]\n"); - printf("Options:\n"); - printf(" -f Run in full screen\n"); - printf(" -h Display this help\n"); - printf(" -s Run program as single thread (default is to use two threads)\n"); - printf("\n"); - printf("Program runtime controls:\n"); - printf(" W Toggle wireframe mode\n"); - printf(" Esc Exit program\n"); -} - - -//======================================================================== -// Initialize a new particle -//======================================================================== - -static void init_particle(PARTICLE *p, double t) -{ - float xy_angle, velocity; - - // Start position of particle is at the fountain blow-out - p->x = 0.f; - p->y = 0.f; - p->z = FOUNTAIN_HEIGHT; - - // Start velocity is up (Z)... - p->vz = 0.7f + (0.3f / 4096.f) * (float) (rand() & 4095); - - // ...and a randomly chosen X/Y direction - xy_angle = (2.f * (float) M_PI / 4096.f) * (float) (rand() & 4095); - p->vx = 0.4f * (float) cos(xy_angle); - p->vy = 0.4f * (float) sin(xy_angle); - - // Scale velocity vector according to a time-varying velocity - velocity = VELOCITY * (0.8f + 0.1f * (float) (sin(0.5 * t) + sin(1.31 * t))); - p->vx *= velocity; - p->vy *= velocity; - p->vz *= velocity; - - // Color is time-varying - p->r = 0.7f + 0.3f * (float) sin(0.34 * t + 0.1); - p->g = 0.6f + 0.4f * (float) sin(0.63 * t + 1.1); - p->b = 0.6f + 0.4f * (float) sin(0.91 * t + 2.1); - - // Store settings for fountain glow lighting - glow_pos[0] = 0.4f * (float) sin(1.34 * t); - glow_pos[1] = 0.4f * (float) sin(3.11 * t); - glow_pos[2] = FOUNTAIN_HEIGHT + 1.f; - glow_pos[3] = 1.f; - glow_color[0] = p->r; - glow_color[1] = p->g; - glow_color[2] = p->b; - glow_color[3] = 1.f; - - // The particle is new-born and active - p->life = 1.f; - p->active = 1; -} - - -//======================================================================== -// Update a particle -//======================================================================== - -#define FOUNTAIN_R2 (FOUNTAIN_RADIUS+PARTICLE_SIZE/2)*(FOUNTAIN_RADIUS+PARTICLE_SIZE/2) - -static void update_particle(PARTICLE *p, float dt) -{ - // If the particle is not active, we need not do anything - if (!p->active) - return; - - // The particle is getting older... - p->life -= dt * (1.f / LIFE_SPAN); - - // Did the particle die? - if (p->life <= 0.f) - { - p->active = 0; - return; - } - - // Apply gravity - p->vz = p->vz - GRAVITY * dt; - - // Update particle position - p->x = p->x + p->vx * dt; - p->y = p->y + p->vy * dt; - p->z = p->z + p->vz * dt; - - // Simple collision detection + response - if (p->vz < 0.f) - { - // Particles should bounce on the fountain (with friction) - if ((p->x * p->x + p->y * p->y) < FOUNTAIN_R2 && - p->z < (FOUNTAIN_HEIGHT + PARTICLE_SIZE / 2)) - { - p->vz = -FRICTION * p->vz; - p->z = FOUNTAIN_HEIGHT + PARTICLE_SIZE / 2 + - FRICTION * (FOUNTAIN_HEIGHT + - PARTICLE_SIZE / 2 - p->z); - } - - // Particles should bounce on the floor (with friction) - else if (p->z < PARTICLE_SIZE / 2) - { - p->vz = -FRICTION * p->vz; - p->z = PARTICLE_SIZE / 2 + - FRICTION * (PARTICLE_SIZE / 2 - p->z); - } - } -} - - -//======================================================================== -// The main frame for the particle engine. Called once per frame. -//======================================================================== - -static void particle_engine(double t, float dt) -{ - int i; - float dt2; - - // Update particles (iterated several times per frame if dt is too large) - while (dt > 0.f) - { - // Calculate delta time for this iteration - dt2 = dt < MIN_DELTA_T ? dt : MIN_DELTA_T; - - for (i = 0; i < MAX_PARTICLES; i++) - update_particle(&particles[i], dt2); - - min_age += dt2; - - // Should we create any new particle(s)? - while (min_age >= BIRTH_INTERVAL) - { - min_age -= BIRTH_INTERVAL; - - // Find a dead particle to replace with a new one - for (i = 0; i < MAX_PARTICLES; i++) - { - if (!particles[i].active) - { - init_particle(&particles[i], t + min_age); - update_particle(&particles[i], min_age); - break; - } - } - } - - dt -= dt2; - } -} - - -//======================================================================== -// Draw all active particles. We use OpenGL 1.1 vertex -// arrays for this in order to accelerate the drawing. -//======================================================================== - -#define BATCH_PARTICLES 70 // Number of particles to draw in each batch - // (70 corresponds to 7.5 KB = will not blow - // the L1 data cache on most CPUs) -#define PARTICLE_VERTS 4 // Number of vertices per particle - -static void draw_particles(GLFWwindow* window, double t, float dt) -{ - int i, particle_count; - Vertex vertex_array[BATCH_PARTICLES * PARTICLE_VERTS]; - Vertex* vptr; - float alpha; - GLuint rgba; - Vec3 quad_lower_left, quad_lower_right; - GLfloat mat[16]; - PARTICLE* pptr; - - // Here comes the real trick with flat single primitive objects (s.c. - // "billboards"): We must rotate the textured primitive so that it - // always faces the viewer (is coplanar with the view-plane). - // We: - // 1) Create the primitive around origo (0,0,0) - // 2) Rotate it so that it is coplanar with the view plane - // 3) Translate it according to the particle position - // Note that 1) and 2) is the same for all particles (done only once). - - // Get modelview matrix. We will only use the upper left 3x3 part of - // the matrix, which represents the rotation. - glGetFloatv(GL_MODELVIEW_MATRIX, mat); - - // 1) & 2) We do it in one swift step: - // Although not obvious, the following six lines represent two matrix/ - // vector multiplications. The matrix is the inverse 3x3 rotation - // matrix (i.e. the transpose of the same matrix), and the two vectors - // represent the lower left corner of the quad, PARTICLE_SIZE/2 * - // (-1,-1,0), and the lower right corner, PARTICLE_SIZE/2 * (1,-1,0). - // The upper left/right corners of the quad is always the negative of - // the opposite corners (regardless of rotation). - quad_lower_left.x = (-PARTICLE_SIZE / 2) * (mat[0] + mat[1]); - quad_lower_left.y = (-PARTICLE_SIZE / 2) * (mat[4] + mat[5]); - quad_lower_left.z = (-PARTICLE_SIZE / 2) * (mat[8] + mat[9]); - quad_lower_right.x = (PARTICLE_SIZE / 2) * (mat[0] - mat[1]); - quad_lower_right.y = (PARTICLE_SIZE / 2) * (mat[4] - mat[5]); - quad_lower_right.z = (PARTICLE_SIZE / 2) * (mat[8] - mat[9]); - - // Don't update z-buffer, since all particles are transparent! - glDepthMask(GL_FALSE); - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE); - - // Select particle texture - if (!wireframe) - { - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, particle_tex_id); - } - - // Set up vertex arrays. We use interleaved arrays, which is easier to - // handle (in most situations) and it gives a linear memeory access - // access pattern (which may give better performance in some - // situations). GL_T2F_C4UB_V3F means: 2 floats for texture coords, - // 4 ubytes for color and 3 floats for vertex coord (in that order). - // Most OpenGL cards / drivers are optimized for this format. - glInterleavedArrays(GL_T2F_C4UB_V3F, 0, vertex_array); - - // Wait for particle physics thread to be done - mtx_lock(&thread_sync.particles_lock); - while (!glfwWindowShouldClose(window) && - thread_sync.p_frame <= thread_sync.d_frame) - { - struct timespec ts; - clock_gettime(CLOCK_REALTIME, &ts); - ts.tv_nsec += 100000000; - cnd_timedwait(&thread_sync.p_done, &thread_sync.particles_lock, &ts); - } - - // Store the frame time and delta time for the physics thread - thread_sync.t = t; - thread_sync.dt = dt; - - // Update frame counter - thread_sync.d_frame++; - - // Loop through all particles and build vertex arrays. - particle_count = 0; - vptr = vertex_array; - pptr = particles; - - for (i = 0; i < MAX_PARTICLES; i++) - { - if (pptr->active) - { - // Calculate particle intensity (we set it to max during 75% - // of its life, then it fades out) - alpha = 4.f * pptr->life; - if (alpha > 1.f) - alpha = 1.f; - - // Convert color from float to 8-bit (store it in a 32-bit - // integer using endian independent type casting) - ((GLubyte*) &rgba)[0] = (GLubyte)(pptr->r * 255.f); - ((GLubyte*) &rgba)[1] = (GLubyte)(pptr->g * 255.f); - ((GLubyte*) &rgba)[2] = (GLubyte)(pptr->b * 255.f); - ((GLubyte*) &rgba)[3] = (GLubyte)(alpha * 255.f); - - // 3) Translate the quad to the correct position in modelview - // space and store its parameters in vertex arrays (we also - // store texture coord and color information for each vertex). - - // Lower left corner - vptr->s = 0.f; - vptr->t = 0.f; - vptr->rgba = rgba; - vptr->x = pptr->x + quad_lower_left.x; - vptr->y = pptr->y + quad_lower_left.y; - vptr->z = pptr->z + quad_lower_left.z; - vptr ++; - - // Lower right corner - vptr->s = 1.f; - vptr->t = 0.f; - vptr->rgba = rgba; - vptr->x = pptr->x + quad_lower_right.x; - vptr->y = pptr->y + quad_lower_right.y; - vptr->z = pptr->z + quad_lower_right.z; - vptr ++; - - // Upper right corner - vptr->s = 1.f; - vptr->t = 1.f; - vptr->rgba = rgba; - vptr->x = pptr->x - quad_lower_left.x; - vptr->y = pptr->y - quad_lower_left.y; - vptr->z = pptr->z - quad_lower_left.z; - vptr ++; - - // Upper left corner - vptr->s = 0.f; - vptr->t = 1.f; - vptr->rgba = rgba; - vptr->x = pptr->x - quad_lower_right.x; - vptr->y = pptr->y - quad_lower_right.y; - vptr->z = pptr->z - quad_lower_right.z; - vptr ++; - - // Increase count of drawable particles - particle_count ++; - } - - // If we have filled up one batch of particles, draw it as a set - // of quads using glDrawArrays. - if (particle_count >= BATCH_PARTICLES) - { - // The first argument tells which primitive type we use (QUAD) - // The second argument tells the index of the first vertex (0) - // The last argument is the vertex count - glDrawArrays(GL_QUADS, 0, PARTICLE_VERTS * particle_count); - particle_count = 0; - vptr = vertex_array; - } - - // Next particle - pptr++; - } - - // We are done with the particle data - mtx_unlock(&thread_sync.particles_lock); - cnd_signal(&thread_sync.d_done); - - // Draw final batch of particles (if any) - glDrawArrays(GL_QUADS, 0, PARTICLE_VERTS * particle_count); - - // Disable vertex arrays (Note: glInterleavedArrays implicitly called - // glEnableClientState for vertex, texture coord and color arrays) - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - - glDisable(GL_TEXTURE_2D); - glDisable(GL_BLEND); - - glDepthMask(GL_TRUE); -} - - -//======================================================================== -// Fountain geometry specification -//======================================================================== - -#define FOUNTAIN_SIDE_POINTS 14 -#define FOUNTAIN_SWEEP_STEPS 32 - -static const float fountain_side[FOUNTAIN_SIDE_POINTS * 2] = -{ - 1.2f, 0.f, 1.f, 0.2f, 0.41f, 0.3f, 0.4f, 0.35f, - 0.4f, 1.95f, 0.41f, 2.f, 0.8f, 2.2f, 1.2f, 2.4f, - 1.5f, 2.7f, 1.55f,2.95f, 1.6f, 3.f, 1.f, 3.f, - 0.5f, 3.f, 0.f, 3.f -}; - -static const float fountain_normal[FOUNTAIN_SIDE_POINTS * 2] = -{ - 1.0000f, 0.0000f, 0.6428f, 0.7660f, 0.3420f, 0.9397f, 1.0000f, 0.0000f, - 1.0000f, 0.0000f, 0.3420f,-0.9397f, 0.4226f,-0.9063f, 0.5000f,-0.8660f, - 0.7660f,-0.6428f, 0.9063f,-0.4226f, 0.0000f,1.00000f, 0.0000f,1.00000f, - 0.0000f,1.00000f, 0.0000f,1.00000f -}; - - -//======================================================================== -// Draw a fountain -//======================================================================== - -static void draw_fountain(void) -{ - static GLuint fountain_list = 0; - double angle; - float x, y; - int m, n; - - // The first time, we build the fountain display list - if (!fountain_list) - { - fountain_list = glGenLists(1); - glNewList(fountain_list, GL_COMPILE_AND_EXECUTE); - - glMaterialfv(GL_FRONT, GL_DIFFUSE, fountain_diffuse); - glMaterialfv(GL_FRONT, GL_SPECULAR, fountain_specular); - glMaterialf(GL_FRONT, GL_SHININESS, fountain_shininess); - - // Build fountain using triangle strips - for (n = 0; n < FOUNTAIN_SIDE_POINTS - 1; n++) - { - glBegin(GL_TRIANGLE_STRIP); - for (m = 0; m <= FOUNTAIN_SWEEP_STEPS; m++) - { - angle = (double) m * (2.0 * M_PI / (double) FOUNTAIN_SWEEP_STEPS); - x = (float) cos(angle); - y = (float) sin(angle); - - // Draw triangle strip - glNormal3f(x * fountain_normal[n * 2 + 2], - y * fountain_normal[n * 2 + 2], - fountain_normal[n * 2 + 3]); - glVertex3f(x * fountain_side[n * 2 + 2], - y * fountain_side[n * 2 + 2], - fountain_side[n * 2 +3 ]); - glNormal3f(x * fountain_normal[n * 2], - y * fountain_normal[n * 2], - fountain_normal[n * 2 + 1]); - glVertex3f(x * fountain_side[n * 2], - y * fountain_side[n * 2], - fountain_side[n * 2 + 1]); - } - - glEnd(); - } - - glEndList(); - } - else - glCallList(fountain_list); -} - - -//======================================================================== -// Recursive function for building variable tesselated floor -//======================================================================== - -static void tessellate_floor(float x1, float y1, float x2, float y2, int depth) -{ - float delta, x, y; - - // Last recursion? - if (depth >= 5) - delta = 999999.f; - else - { - x = (float) (fabs(x1) < fabs(x2) ? fabs(x1) : fabs(x2)); - y = (float) (fabs(y1) < fabs(y2) ? fabs(y1) : fabs(y2)); - delta = x*x + y*y; - } - - // Recurse further? - if (delta < 0.1f) - { - x = (x1 + x2) * 0.5f; - y = (y1 + y2) * 0.5f; - tessellate_floor(x1, y1, x, y, depth + 1); - tessellate_floor(x, y1, x2, y, depth + 1); - tessellate_floor(x1, y, x, y2, depth + 1); - tessellate_floor(x, y, x2, y2, depth + 1); - } - else - { - glTexCoord2f(x1 * 30.f, y1 * 30.f); - glVertex3f( x1 * 80.f, y1 * 80.f, 0.f); - glTexCoord2f(x2 * 30.f, y1 * 30.f); - glVertex3f( x2 * 80.f, y1 * 80.f, 0.f); - glTexCoord2f(x2 * 30.f, y2 * 30.f); - glVertex3f( x2 * 80.f, y2 * 80.f, 0.f); - glTexCoord2f(x1 * 30.f, y2 * 30.f); - glVertex3f( x1 * 80.f, y2 * 80.f, 0.f); - } -} - - -//======================================================================== -// Draw floor. We build the floor recursively and let the tessellation in the -// center (near x,y=0,0) be high, while the tessellation around the edges be -// low. -//======================================================================== - -static void draw_floor(void) -{ - static GLuint floor_list = 0; - - if (!wireframe) - { - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, floor_tex_id); - } - - // The first time, we build the floor display list - if (!floor_list) - { - floor_list = glGenLists(1); - glNewList(floor_list, GL_COMPILE_AND_EXECUTE); - - glMaterialfv(GL_FRONT, GL_DIFFUSE, floor_diffuse); - glMaterialfv(GL_FRONT, GL_SPECULAR, floor_specular); - glMaterialf(GL_FRONT, GL_SHININESS, floor_shininess); - - // Draw floor as a bunch of triangle strips (high tesselation - // improves lighting) - glNormal3f(0.f, 0.f, 1.f); - glBegin(GL_QUADS); - tessellate_floor(-1.f, -1.f, 0.f, 0.f, 0); - tessellate_floor( 0.f, -1.f, 1.f, 0.f, 0); - tessellate_floor( 0.f, 0.f, 1.f, 1.f, 0); - tessellate_floor(-1.f, 0.f, 0.f, 1.f, 0); - glEnd(); - - glEndList(); - } - else - glCallList(floor_list); - - glDisable(GL_TEXTURE_2D); - -} - - -//======================================================================== -// Position and configure light sources -//======================================================================== - -static void setup_lights(void) -{ - float l1pos[4], l1amb[4], l1dif[4], l1spec[4]; - float l2pos[4], l2amb[4], l2dif[4], l2spec[4]; - - // Set light source 1 parameters - l1pos[0] = 0.f; l1pos[1] = -9.f; l1pos[2] = 8.f; l1pos[3] = 1.f; - l1amb[0] = 0.2f; l1amb[1] = 0.2f; l1amb[2] = 0.2f; l1amb[3] = 1.f; - l1dif[0] = 0.8f; l1dif[1] = 0.4f; l1dif[2] = 0.2f; l1dif[3] = 1.f; - l1spec[0] = 1.f; l1spec[1] = 0.6f; l1spec[2] = 0.2f; l1spec[3] = 0.f; - - // Set light source 2 parameters - l2pos[0] = -15.f; l2pos[1] = 12.f; l2pos[2] = 1.5f; l2pos[3] = 1.f; - l2amb[0] = 0.f; l2amb[1] = 0.f; l2amb[2] = 0.f; l2amb[3] = 1.f; - l2dif[0] = 0.2f; l2dif[1] = 0.4f; l2dif[2] = 0.8f; l2dif[3] = 1.f; - l2spec[0] = 0.2f; l2spec[1] = 0.6f; l2spec[2] = 1.f; l2spec[3] = 0.f; - - glLightfv(GL_LIGHT1, GL_POSITION, l1pos); - glLightfv(GL_LIGHT1, GL_AMBIENT, l1amb); - glLightfv(GL_LIGHT1, GL_DIFFUSE, l1dif); - glLightfv(GL_LIGHT1, GL_SPECULAR, l1spec); - glLightfv(GL_LIGHT2, GL_POSITION, l2pos); - glLightfv(GL_LIGHT2, GL_AMBIENT, l2amb); - glLightfv(GL_LIGHT2, GL_DIFFUSE, l2dif); - glLightfv(GL_LIGHT2, GL_SPECULAR, l2spec); - glLightfv(GL_LIGHT3, GL_POSITION, glow_pos); - glLightfv(GL_LIGHT3, GL_DIFFUSE, glow_color); - glLightfv(GL_LIGHT3, GL_SPECULAR, glow_color); - - glEnable(GL_LIGHT1); - glEnable(GL_LIGHT2); - glEnable(GL_LIGHT3); -} - - -//======================================================================== -// Main rendering function -//======================================================================== - -static void draw_scene(GLFWwindow* window, double t) -{ - double xpos, ypos, zpos, angle_x, angle_y, angle_z; - static double t_old = 0.0; - float dt; - - // Calculate frame-to-frame delta time - dt = (float) (t - t_old); - t_old = t; - - glClearColor(0.1f, 0.1f, 0.1f, 1.f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(65.0, aspect_ratio, 1.0, 60.0); - - // Setup camera - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - // Rotate camera - angle_x = 90.0 - 10.0; - angle_y = 10.0 * sin(0.3 * t); - angle_z = 10.0 * t; - glRotated(-angle_x, 1.0, 0.0, 0.0); - glRotated(-angle_y, 0.0, 1.0, 0.0); - glRotated(-angle_z, 0.0, 0.0, 1.0); - - // Translate camera - xpos = 15.0 * sin((M_PI / 180.0) * angle_z) + - 2.0 * sin((M_PI / 180.0) * 3.1 * t); - ypos = -15.0 * cos((M_PI / 180.0) * angle_z) + - 2.0 * cos((M_PI / 180.0) * 2.9 * t); - zpos = 4.0 + 2.0 * cos((M_PI / 180.0) * 4.9 * t); - glTranslated(-xpos, -ypos, -zpos); - - glFrontFace(GL_CCW); - glCullFace(GL_BACK); - glEnable(GL_CULL_FACE); - - setup_lights(); - glEnable(GL_LIGHTING); - - glEnable(GL_FOG); - glFogi(GL_FOG_MODE, GL_EXP); - glFogf(GL_FOG_DENSITY, 0.05f); - glFogfv(GL_FOG_COLOR, fog_color); - - draw_floor(); - - glEnable(GL_DEPTH_TEST); - glDepthFunc(GL_LEQUAL); - glDepthMask(GL_TRUE); - - draw_fountain(); - - glDisable(GL_LIGHTING); - glDisable(GL_FOG); - - // Particles must be drawn after all solid objects have been drawn - draw_particles(window, t, dt); - - // Z-buffer not needed anymore - glDisable(GL_DEPTH_TEST); -} - - -//======================================================================== -// Window resize callback function -//======================================================================== - -static void resize_callback(GLFWwindow* window, int width, int height) -{ - glViewport(0, 0, width, height); - aspect_ratio = height ? width / (float) height : 1.f; -} - - -//======================================================================== -// Key callback functions -//======================================================================== - -static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) -{ - if (action == GLFW_PRESS) - { - switch (key) - { - case GLFW_KEY_ESCAPE: - glfwSetWindowShouldClose(window, GL_TRUE); - break; - case GLFW_KEY_W: - wireframe = !wireframe; - glPolygonMode(GL_FRONT_AND_BACK, - wireframe ? GL_LINE : GL_FILL); - break; - default: - break; - } - } -} - - -//======================================================================== -// Thread for updating particle physics -//======================================================================== - -static int physics_thread_main(void* arg) -{ - GLFWwindow* window = arg; - - for (;;) - { - mtx_lock(&thread_sync.particles_lock); - - // Wait for particle drawing to be done - while (!glfwWindowShouldClose(window) && - thread_sync.p_frame > thread_sync.d_frame) - { - struct timespec ts; - clock_gettime(CLOCK_REALTIME, &ts); - ts.tv_nsec += 100000000; - cnd_timedwait(&thread_sync.d_done, &thread_sync.particles_lock, &ts); - } - - if (glfwWindowShouldClose(window)) - break; - - // Update particles - particle_engine(thread_sync.t, thread_sync.dt); - - // Update frame counter - thread_sync.p_frame++; - - // Unlock mutex and signal drawing thread - mtx_unlock(&thread_sync.particles_lock); - cnd_signal(&thread_sync.p_done); - } - - return 0; -} - - -//======================================================================== -// main -//======================================================================== - -int main(int argc, char** argv) -{ - int ch, width, height; - thrd_t physics_thread = 0; - GLFWwindow* window; - GLFWmonitor* monitor = NULL; - - if (!glfwInit()) - { - fprintf(stderr, "Failed to initialize GLFW\n"); - exit(EXIT_FAILURE); - } - - while ((ch = getopt(argc, argv, "fh")) != -1) - { - switch (ch) - { - case 'f': - monitor = glfwGetPrimaryMonitor(); - break; - case 'h': - usage(); - exit(EXIT_SUCCESS); - } - } - - if (monitor) - { - const GLFWvidmode* mode = glfwGetVideoMode(monitor); - - glfwWindowHint(GLFW_RED_BITS, mode->redBits); - glfwWindowHint(GLFW_GREEN_BITS, mode->greenBits); - glfwWindowHint(GLFW_BLUE_BITS, mode->blueBits); - glfwWindowHint(GLFW_REFRESH_RATE, mode->refreshRate); - - width = mode->width; - height = mode->height; - } - else - { - width = 640; - height = 480; - } - - window = glfwCreateWindow(width, height, "Particle Engine", monitor, NULL); - if (!window) - { - fprintf(stderr, "Failed to create GLFW window\n"); - glfwTerminate(); - exit(EXIT_FAILURE); - } - - if (monitor) - glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); - - glfwMakeContextCurrent(window); - glfwSwapInterval(1); - - glfwSetWindowSizeCallback(window, resize_callback); - glfwSetKeyCallback(window, key_callback); - - // Set initial aspect ratio - glfwGetWindowSize(window, &width, &height); - resize_callback(window, width, height); - - // Upload particle texture - glGenTextures(1, &particle_tex_id); - glBindTexture(GL_TEXTURE_2D, particle_tex_id); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, P_TEX_WIDTH, P_TEX_HEIGHT, - 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, particle_texture); - - // Upload floor texture - glGenTextures(1, &floor_tex_id); - glBindTexture(GL_TEXTURE_2D, floor_tex_id); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, F_TEX_WIDTH, F_TEX_HEIGHT, - 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, floor_texture); - - if (glfwExtensionSupported("GL_EXT_separate_specular_color")) - { - glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL_EXT, - GL_SEPARATE_SPECULAR_COLOR_EXT); - } - - // Set filled polygon mode as default (not wireframe) - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - wireframe = 0; - - // Set initial times - thread_sync.t = 0.0; - thread_sync.dt = 0.001f; - thread_sync.p_frame = 0; - thread_sync.d_frame = 0; - - mtx_init(&thread_sync.particles_lock, mtx_timed); - cnd_init(&thread_sync.p_done); - cnd_init(&thread_sync.d_done); - - if (thrd_create(&physics_thread, physics_thread_main, window) != thrd_success) - { - glfwTerminate(); - exit(EXIT_FAILURE); - } - - glfwSetTime(0.0); - - while (!glfwWindowShouldClose(window)) - { - draw_scene(window, glfwGetTime()); - - glfwSwapBuffers(window); - glfwPollEvents(); - } - - thrd_join(physics_thread, NULL); - - glfwDestroyWindow(window); - glfwTerminate(); - - exit(EXIT_SUCCESS); -} - diff --git a/examples/common/glfw/examples/simple.c b/examples/common/glfw/examples/simple.c deleted file mode 100644 index c39be574..00000000 --- a/examples/common/glfw/examples/simple.c +++ /dev/null @@ -1,102 +0,0 @@ -//======================================================================== -// Simple GLFW example -// Copyright (c) Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== -//! [code] - -#include - -#include -#include - -static void error_callback(int error, const char* description) -{ - fputs(description, stderr); -} - -static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) -{ - if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) - glfwSetWindowShouldClose(window, GL_TRUE); -} - -int main(void) -{ - GLFWwindow* window; - - glfwSetErrorCallback(error_callback); - - if (!glfwInit()) - exit(EXIT_FAILURE); - - window = glfwCreateWindow(640, 480, "Simple example", NULL, NULL); - if (!window) - { - glfwTerminate(); - exit(EXIT_FAILURE); - } - - glfwMakeContextCurrent(window); - glfwSwapInterval(1); - - glfwSetKeyCallback(window, key_callback); - - while (!glfwWindowShouldClose(window)) - { - float ratio; - int width, height; - - glfwGetFramebufferSize(window, &width, &height); - ratio = width / (float) height; - - glViewport(0, 0, width, height); - glClear(GL_COLOR_BUFFER_BIT); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(-ratio, ratio, -1.f, 1.f, 1.f, -1.f); - glMatrixMode(GL_MODELVIEW); - - glLoadIdentity(); - glRotatef((float) glfwGetTime() * 50.f, 0.f, 0.f, 1.f); - - glBegin(GL_TRIANGLES); - glColor3f(1.f, 0.f, 0.f); - glVertex3f(-0.6f, -0.4f, 0.f); - glColor3f(0.f, 1.f, 0.f); - glVertex3f(0.6f, -0.4f, 0.f); - glColor3f(0.f, 0.f, 1.f); - glVertex3f(0.f, 0.6f, 0.f); - glEnd(); - - glfwSwapBuffers(window); - glfwPollEvents(); - } - - glfwDestroyWindow(window); - - glfwTerminate(); - exit(EXIT_SUCCESS); -} - -//! [code] diff --git a/examples/common/glfw/examples/splitview.c b/examples/common/glfw/examples/splitview.c deleted file mode 100644 index 30b093b1..00000000 --- a/examples/common/glfw/examples/splitview.c +++ /dev/null @@ -1,511 +0,0 @@ -//======================================================================== -// This is an example program for the GLFW library -// -// The program uses a "split window" view, rendering four views of the -// same scene in one window (e.g. uesful for 3D modelling software). This -// demo uses scissors to separete the four different rendering areas from -// each other. -// -// (If the code seems a little bit strange here and there, it may be -// because I am not a friend of orthogonal projections) -//======================================================================== - -#define GLFW_INCLUDE_GLU -#include - -#include -#include -#include - -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif - - -//======================================================================== -// Global variables -//======================================================================== - -// Mouse position -static double xpos = 0, ypos = 0; - -// Window size -static int width, height; - -// Active view: 0 = none, 1 = upper left, 2 = upper right, 3 = lower left, -// 4 = lower right -static int active_view = 0; - -// Rotation around each axis -static int rot_x = 0, rot_y = 0, rot_z = 0; - -// Do redraw? -static int do_redraw = 1; - - -//======================================================================== -// Draw a solid torus (use a display list for the model) -//======================================================================== - -#define TORUS_MAJOR 1.5 -#define TORUS_MINOR 0.5 -#define TORUS_MAJOR_RES 32 -#define TORUS_MINOR_RES 32 - -static void drawTorus(void) -{ - static GLuint torus_list = 0; - int i, j, k; - double s, t, x, y, z, nx, ny, nz, scale, twopi; - - if (!torus_list) - { - // Start recording displaylist - torus_list = glGenLists(1); - glNewList(torus_list, GL_COMPILE_AND_EXECUTE); - - // Draw torus - twopi = 2.0 * M_PI; - for (i = 0; i < TORUS_MINOR_RES; i++) - { - glBegin(GL_QUAD_STRIP); - for (j = 0; j <= TORUS_MAJOR_RES; j++) - { - for (k = 1; k >= 0; k--) - { - s = (i + k) % TORUS_MINOR_RES + 0.5; - t = j % TORUS_MAJOR_RES; - - // Calculate point on surface - x = (TORUS_MAJOR + TORUS_MINOR * cos(s * twopi / TORUS_MINOR_RES)) * cos(t * twopi / TORUS_MAJOR_RES); - y = TORUS_MINOR * sin(s * twopi / TORUS_MINOR_RES); - z = (TORUS_MAJOR + TORUS_MINOR * cos(s * twopi / TORUS_MINOR_RES)) * sin(t * twopi / TORUS_MAJOR_RES); - - // Calculate surface normal - nx = x - TORUS_MAJOR * cos(t * twopi / TORUS_MAJOR_RES); - ny = y; - nz = z - TORUS_MAJOR * sin(t * twopi / TORUS_MAJOR_RES); - scale = 1.0 / sqrt(nx*nx + ny*ny + nz*nz); - nx *= scale; - ny *= scale; - nz *= scale; - - glNormal3f((float) nx, (float) ny, (float) nz); - glVertex3f((float) x, (float) y, (float) z); - } - } - - glEnd(); - } - - // Stop recording displaylist - glEndList(); - } - else - { - // Playback displaylist - glCallList(torus_list); - } -} - - -//======================================================================== -// Draw the scene (a rotating torus) -//======================================================================== - -static void drawScene(void) -{ - const GLfloat model_diffuse[4] = {1.0f, 0.8f, 0.8f, 1.0f}; - const GLfloat model_specular[4] = {0.6f, 0.6f, 0.6f, 1.0f}; - const GLfloat model_shininess = 20.0f; - - glPushMatrix(); - - // Rotate the object - glRotatef((GLfloat) rot_x * 0.5f, 1.0f, 0.0f, 0.0f); - glRotatef((GLfloat) rot_y * 0.5f, 0.0f, 1.0f, 0.0f); - glRotatef((GLfloat) rot_z * 0.5f, 0.0f, 0.0f, 1.0f); - - // Set model color (used for orthogonal views, lighting disabled) - glColor4fv(model_diffuse); - - // Set model material (used for perspective view, lighting enabled) - glMaterialfv(GL_FRONT, GL_DIFFUSE, model_diffuse); - glMaterialfv(GL_FRONT, GL_SPECULAR, model_specular); - glMaterialf(GL_FRONT, GL_SHININESS, model_shininess); - - // Draw torus - drawTorus(); - - glPopMatrix(); -} - - -//======================================================================== -// Draw a 2D grid (used for orthogonal views) -//======================================================================== - -static void drawGrid(float scale, int steps) -{ - int i; - float x, y; - - glPushMatrix(); - - // Set background to some dark bluish grey - glClearColor(0.05f, 0.05f, 0.2f, 0.0f); - glClear(GL_COLOR_BUFFER_BIT); - - // Setup modelview matrix (flat XY view) - glLoadIdentity(); - gluLookAt(0.0, 0.0, 1.0, - 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0); - - // We don't want to update the Z-buffer - glDepthMask(GL_FALSE); - - // Set grid color - glColor3f(0.0f, 0.5f, 0.5f); - - glBegin(GL_LINES); - - // Horizontal lines - x = scale * 0.5f * (float) (steps - 1); - y = -scale * 0.5f * (float) (steps - 1); - for (i = 0; i < steps; i++) - { - glVertex3f(-x, y, 0.0f); - glVertex3f(x, y, 0.0f); - y += scale; - } - - // Vertical lines - x = -scale * 0.5f * (float) (steps - 1); - y = scale * 0.5f * (float) (steps - 1); - for (i = 0; i < steps; i++) - { - glVertex3f(x, -y, 0.0f); - glVertex3f(x, y, 0.0f); - x += scale; - } - - glEnd(); - - // Enable Z-buffer writing again - glDepthMask(GL_TRUE); - - glPopMatrix(); -} - - -//======================================================================== -// Draw all views -//======================================================================== - -static void drawAllViews(void) -{ - const GLfloat light_position[4] = {0.0f, 8.0f, 8.0f, 1.0f}; - const GLfloat light_diffuse[4] = {1.0f, 1.0f, 1.0f, 1.0f}; - const GLfloat light_specular[4] = {1.0f, 1.0f, 1.0f, 1.0f}; - const GLfloat light_ambient[4] = {0.2f, 0.2f, 0.3f, 1.0f}; - double aspect; - - // Calculate aspect of window - if (height > 0) - aspect = (double) width / (double) height; - else - aspect = 1.0; - - // Clear screen - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - // Enable scissor test - glEnable(GL_SCISSOR_TEST); - - // Enable depth test - glEnable(GL_DEPTH_TEST); - glDepthFunc(GL_LEQUAL); - - // ** ORTHOGONAL VIEWS ** - - // For orthogonal views, use wireframe rendering - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - - // Enable line anti-aliasing - glEnable(GL_LINE_SMOOTH); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - // Setup orthogonal projection matrix - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(-3.0 * aspect, 3.0 * aspect, -3.0, 3.0, 1.0, 50.0); - - // Upper left view (TOP VIEW) - glViewport(0, height / 2, width / 2, height / 2); - glScissor(0, height / 2, width / 2, height / 2); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - gluLookAt(0.0f, 10.0f, 1e-3f, // Eye-position (above) - 0.0f, 0.0f, 0.0f, // View-point - 0.0f, 1.0f, 0.0f); // Up-vector - drawGrid(0.5, 12); - drawScene(); - - // Lower left view (FRONT VIEW) - glViewport(0, 0, width / 2, height / 2); - glScissor(0, 0, width / 2, height / 2); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - gluLookAt(0.0f, 0.0f, 10.0f, // Eye-position (in front of) - 0.0f, 0.0f, 0.0f, // View-point - 0.0f, 1.0f, 0.0f); // Up-vector - drawGrid(0.5, 12); - drawScene(); - - // Lower right view (SIDE VIEW) - glViewport(width / 2, 0, width / 2, height / 2); - glScissor(width / 2, 0, width / 2, height / 2); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - gluLookAt(10.0f, 0.0f, 0.0f, // Eye-position (to the right) - 0.0f, 0.0f, 0.0f, // View-point - 0.0f, 1.0f, 0.0f); // Up-vector - drawGrid(0.5, 12); - drawScene(); - - // Disable line anti-aliasing - glDisable(GL_LINE_SMOOTH); - glDisable(GL_BLEND); - - // ** PERSPECTIVE VIEW ** - - // For perspective view, use solid rendering - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - - // Enable face culling (faster rendering) - glEnable(GL_CULL_FACE); - glCullFace(GL_BACK); - glFrontFace(GL_CW); - - // Setup perspective projection matrix - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(65.0f, aspect, 1.0f, 50.0f); - - // Upper right view (PERSPECTIVE VIEW) - glViewport(width / 2, height / 2, width / 2, height / 2); - glScissor(width / 2, height / 2, width / 2, height / 2); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - gluLookAt(3.0f, 1.5f, 3.0f, // Eye-position - 0.0f, 0.0f, 0.0f, // View-point - 0.0f, 1.0f, 0.0f); // Up-vector - - // Configure and enable light source 1 - glLightfv(GL_LIGHT1, GL_POSITION, light_position); - glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient); - glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse); - glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular); - glEnable(GL_LIGHT1); - glEnable(GL_LIGHTING); - - // Draw scene - drawScene(); - - // Disable lighting - glDisable(GL_LIGHTING); - - // Disable face culling - glDisable(GL_CULL_FACE); - - // Disable depth test - glDisable(GL_DEPTH_TEST); - - // Disable scissor test - glDisable(GL_SCISSOR_TEST); - - // Draw a border around the active view - if (active_view > 0 && active_view != 2) - { - glViewport(0, 0, width, height); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0.0, 2.0, 0.0, 2.0, 0.0, 1.0); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glTranslatef((GLfloat) ((active_view - 1) & 1), (GLfloat) (1 - (active_view - 1) / 2), 0.0f); - - glColor3f(1.0f, 1.0f, 0.6f); - - glBegin(GL_LINE_STRIP); - glVertex2i(0, 0); - glVertex2i(1, 0); - glVertex2i(1, 1); - glVertex2i(0, 1); - glVertex2i(0, 0); - glEnd(); - } -} - - -//======================================================================== -// Framebuffer size callback function -//======================================================================== - -static void framebufferSizeFun(GLFWwindow* window, int w, int h) -{ - width = w; - height = h > 0 ? h : 1; - do_redraw = 1; -} - - -//======================================================================== -// Window refresh callback function -//======================================================================== - -static void windowRefreshFun(GLFWwindow* window) -{ - do_redraw = 1; -} - - -//======================================================================== -// Mouse position callback function -//======================================================================== - -static void cursorPosFun(GLFWwindow* window, double x, double y) -{ - // Depending on which view was selected, rotate around different axes - switch (active_view) - { - case 1: - rot_x += (int) (y - ypos); - rot_z += (int) (x - xpos); - do_redraw = 1; - break; - case 3: - rot_x += (int) (y - ypos); - rot_y += (int) (x - xpos); - do_redraw = 1; - break; - case 4: - rot_y += (int) (x - xpos); - rot_z += (int) (y - ypos); - do_redraw = 1; - break; - default: - // Do nothing for perspective view, or if no view is selected - break; - } - - // Remember cursor position - xpos = x; - ypos = y; -} - - -//======================================================================== -// Mouse button callback function -//======================================================================== - -static void mouseButtonFun(GLFWwindow* window, int button, int action, int mods) -{ - if ((button == GLFW_MOUSE_BUTTON_LEFT) && action == GLFW_PRESS) - { - // Detect which of the four views was clicked - active_view = 1; - if (xpos >= width / 2) - active_view += 1; - if (ypos >= height / 2) - active_view += 2; - } - else if (button == GLFW_MOUSE_BUTTON_LEFT) - { - // Deselect any previously selected view - active_view = 0; - } - - do_redraw = 1; -} - -static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) -{ - if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) - glfwSetWindowShouldClose(window, GL_TRUE); -} - - -//======================================================================== -// main -//======================================================================== - -int main(void) -{ - GLFWwindow* window; - - // Initialise GLFW - if (!glfwInit()) - { - fprintf(stderr, "Failed to initialize GLFW\n"); - exit(EXIT_FAILURE); - } - - // Open OpenGL window - window = glfwCreateWindow(500, 500, "Split view demo", NULL, NULL); - if (!window) - { - fprintf(stderr, "Failed to open GLFW window\n"); - - glfwTerminate(); - exit(EXIT_FAILURE); - } - - // Set callback functions - glfwSetFramebufferSizeCallback(window, framebufferSizeFun); - glfwSetWindowRefreshCallback(window, windowRefreshFun); - glfwSetCursorPosCallback(window, cursorPosFun); - glfwSetMouseButtonCallback(window, mouseButtonFun); - glfwSetKeyCallback(window, key_callback); - - // Enable vsync - glfwMakeContextCurrent(window); - glfwSwapInterval(1); - - glfwGetFramebufferSize(window, &width, &height); - framebufferSizeFun(window, width, height); - - // Main loop - for (;;) - { - // Only redraw if we need to - if (do_redraw) - { - // Draw all views - drawAllViews(); - - // Swap buffers - glfwSwapBuffers(window); - - do_redraw = 0; - } - - // Wait for new events - glfwWaitEvents(); - - // Check if the window should be closed - if (glfwWindowShouldClose(window)) - break; - } - - // Close OpenGL window and terminate GLFW - glfwTerminate(); - - exit(EXIT_SUCCESS); -} - diff --git a/examples/common/glfw/examples/wave.c b/examples/common/glfw/examples/wave.c deleted file mode 100644 index bafe4652..00000000 --- a/examples/common/glfw/examples/wave.c +++ /dev/null @@ -1,452 +0,0 @@ -/***************************************************************************** - * Wave Simulation in OpenGL - * (C) 2002 Jakob Thomsen - * http://home.in.tum.de/~thomsen - * Modified for GLFW by Sylvain Hellegouarch - sh@programmationworld.com - * Modified for variable frame rate by Marcus Geelnard - * 2003-Jan-31: Minor cleanups and speedups / MG - * 2010-10-24: Formatting and cleanup - Camilla Berglund - *****************************************************************************/ - -#include -#include -#include - -#define GLFW_INCLUDE_GLU -#include - -#ifndef M_PI - #define M_PI 3.1415926535897932384626433832795 -#endif - -// Maximum delta T to allow for differential calculations -#define MAX_DELTA_T 0.01 - -// Animation speed (10.0 looks good) -#define ANIMATION_SPEED 10.0 - -GLfloat alpha = 210.f, beta = -70.f; -GLfloat zoom = 2.f; - -double cursorX; -double cursorY; - -struct Vertex -{ - GLfloat x, y, z; - GLfloat r, g, b; -}; - -#define GRIDW 50 -#define GRIDH 50 -#define VERTEXNUM (GRIDW*GRIDH) - -#define QUADW (GRIDW - 1) -#define QUADH (GRIDH - 1) -#define QUADNUM (QUADW*QUADH) - -GLuint quad[4 * QUADNUM]; -struct Vertex vertex[VERTEXNUM]; - -/* The grid will look like this: - * - * 3 4 5 - * *---*---* - * | | | - * | 0 | 1 | - * | | | - * *---*---* - * 0 1 2 - */ - -//======================================================================== -// Initialize grid geometry -//======================================================================== - -void init_vertices(void) -{ - int x, y, p; - - // Place the vertices in a grid - for (y = 0; y < GRIDH; y++) - { - for (x = 0; x < GRIDW; x++) - { - p = y * GRIDW + x; - - vertex[p].x = (GLfloat) (x - GRIDW / 2) / (GLfloat) (GRIDW / 2); - vertex[p].y = (GLfloat) (y - GRIDH / 2) / (GLfloat) (GRIDH / 2); - vertex[p].z = 0; - - if ((x % 4 < 2) ^ (y % 4 < 2)) - vertex[p].r = 0.0; - else - vertex[p].r = 1.0; - - vertex[p].g = (GLfloat) y / (GLfloat) GRIDH; - vertex[p].b = 1.f - ((GLfloat) x / (GLfloat) GRIDW + (GLfloat) y / (GLfloat) GRIDH) / 2.f; - } - } - - for (y = 0; y < QUADH; y++) - { - for (x = 0; x < QUADW; x++) - { - p = 4 * (y * QUADW + x); - - quad[p + 0] = y * GRIDW + x; // Some point - quad[p + 1] = y * GRIDW + x + 1; // Neighbor at the right side - quad[p + 2] = (y + 1) * GRIDW + x + 1; // Upper right neighbor - quad[p + 3] = (y + 1) * GRIDW + x; // Upper neighbor - } - } -} - -double dt; -double p[GRIDW][GRIDH]; -double vx[GRIDW][GRIDH], vy[GRIDW][GRIDH]; -double ax[GRIDW][GRIDH], ay[GRIDW][GRIDH]; - -//======================================================================== -// Initialize grid -//======================================================================== - -void init_grid(void) -{ - int x, y; - double dx, dy, d; - - for (y = 0; y < GRIDH; y++) - { - for (x = 0; x < GRIDW; x++) - { - dx = (double) (x - GRIDW / 2); - dy = (double) (y - GRIDH / 2); - d = sqrt(dx * dx + dy * dy); - if (d < 0.1 * (double) (GRIDW / 2)) - { - d = d * 10.0; - p[x][y] = -cos(d * (M_PI / (double)(GRIDW * 4))) * 100.0; - } - else - p[x][y] = 0.0; - - vx[x][y] = 0.0; - vy[x][y] = 0.0; - } - } -} - - -//======================================================================== -// Draw scene -//======================================================================== - -void draw_scene(GLFWwindow* window) -{ - // Clear the color and depth buffers - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - // We don't want to modify the projection matrix - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - // Move back - glTranslatef(0.0, 0.0, -zoom); - // Rotate the view - glRotatef(beta, 1.0, 0.0, 0.0); - glRotatef(alpha, 0.0, 0.0, 1.0); - - glDrawElements(GL_QUADS, 4 * QUADNUM, GL_UNSIGNED_INT, quad); - - glfwSwapBuffers(window); -} - - -//======================================================================== -// Initialize Miscellaneous OpenGL state -//======================================================================== - -void init_opengl(void) -{ - // Use Gouraud (smooth) shading - glShadeModel(GL_SMOOTH); - - // Switch on the z-buffer - glEnable(GL_DEPTH_TEST); - - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - glVertexPointer(3, GL_FLOAT, sizeof(struct Vertex), vertex); - glColorPointer(3, GL_FLOAT, sizeof(struct Vertex), &vertex[0].r); // Pointer to the first color - - glPointSize(2.0); - - // Background color is black - glClearColor(0, 0, 0, 0); -} - - -//======================================================================== -// Modify the height of each vertex according to the pressure -//======================================================================== - -void adjust_grid(void) -{ - int pos; - int x, y; - - for (y = 0; y < GRIDH; y++) - { - for (x = 0; x < GRIDW; x++) - { - pos = y * GRIDW + x; - vertex[pos].z = (float) (p[x][y] * (1.0 / 50.0)); - } - } -} - - -//======================================================================== -// Calculate wave propagation -//======================================================================== - -void calc_grid(void) -{ - int x, y, x2, y2; - double time_step = dt * ANIMATION_SPEED; - - // Compute accelerations - for (x = 0; x < GRIDW; x++) - { - x2 = (x + 1) % GRIDW; - for(y = 0; y < GRIDH; y++) - ax[x][y] = p[x][y] - p[x2][y]; - } - - for (y = 0; y < GRIDH; y++) - { - y2 = (y + 1) % GRIDH; - for(x = 0; x < GRIDW; x++) - ay[x][y] = p[x][y] - p[x][y2]; - } - - // Compute speeds - for (x = 0; x < GRIDW; x++) - { - for (y = 0; y < GRIDH; y++) - { - vx[x][y] = vx[x][y] + ax[x][y] * time_step; - vy[x][y] = vy[x][y] + ay[x][y] * time_step; - } - } - - // Compute pressure - for (x = 1; x < GRIDW; x++) - { - x2 = x - 1; - for (y = 1; y < GRIDH; y++) - { - y2 = y - 1; - p[x][y] = p[x][y] + (vx[x2][y] - vx[x][y] + vy[x][y2] - vy[x][y]) * time_step; - } - } -} - - -//======================================================================== -// Print errors -//======================================================================== - -static void error_callback(int error, const char* description) -{ - fprintf(stderr, "Error: %s\n", description); -} - - -//======================================================================== -// Handle key strokes -//======================================================================== - -void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) -{ - if (action != GLFW_PRESS) - return; - - switch (key) - { - case GLFW_KEY_ESCAPE: - glfwSetWindowShouldClose(window, GL_TRUE); - break; - case GLFW_KEY_SPACE: - init_grid(); - break; - case GLFW_KEY_LEFT: - alpha += 5; - break; - case GLFW_KEY_RIGHT: - alpha -= 5; - break; - case GLFW_KEY_UP: - beta -= 5; - break; - case GLFW_KEY_DOWN: - beta += 5; - break; - case GLFW_KEY_PAGE_UP: - zoom -= 0.25f; - if (zoom < 0.f) - zoom = 0.f; - break; - case GLFW_KEY_PAGE_DOWN: - zoom += 0.25f; - break; - default: - break; - } -} - - -//======================================================================== -// Callback function for mouse button events -//======================================================================== - -void mouse_button_callback(GLFWwindow* window, int button, int action, int mods) -{ - if (button != GLFW_MOUSE_BUTTON_LEFT) - return; - - if (action == GLFW_PRESS) - { - glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); - glfwGetCursorPos(window, &cursorX, &cursorY); - } - else - glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); -} - - -//======================================================================== -// Callback function for cursor motion events -//======================================================================== - -void cursor_position_callback(GLFWwindow* window, double x, double y) -{ - if (glfwGetInputMode(window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED) - { - alpha += (GLfloat) (x - cursorX) / 10.f; - beta += (GLfloat) (y - cursorY) / 10.f; - - cursorX = x; - cursorY = y; - } -} - - -//======================================================================== -// Callback function for scroll events -//======================================================================== - -void scroll_callback(GLFWwindow* window, double x, double y) -{ - zoom += (float) y / 4.f; - if (zoom < 0) - zoom = 0; -} - - -//======================================================================== -// Callback function for framebuffer resize events -//======================================================================== - -void framebuffer_size_callback(GLFWwindow* window, int width, int height) -{ - float ratio = 1.f; - - if (height > 0) - ratio = (float) width / (float) height; - - // Setup viewport - glViewport(0, 0, width, height); - - // Change to the projection matrix and set our viewing volume - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(60.0, ratio, 1.0, 1024.0); -} - - -//======================================================================== -// main -//======================================================================== - -int main(int argc, char* argv[]) -{ - GLFWwindow* window; - double t, dt_total, t_old; - int width, height; - - glfwSetErrorCallback(error_callback); - - if (!glfwInit()) - exit(EXIT_FAILURE); - - window = glfwCreateWindow(640, 480, "Wave Simulation", NULL, NULL); - if (!window) - { - glfwTerminate(); - exit(EXIT_FAILURE); - } - - glfwSetKeyCallback(window, key_callback); - glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); - glfwSetMouseButtonCallback(window, mouse_button_callback); - glfwSetCursorPosCallback(window, cursor_position_callback); - glfwSetScrollCallback(window, scroll_callback); - - glfwMakeContextCurrent(window); - glfwSwapInterval(1); - - glfwGetFramebufferSize(window, &width, &height); - framebuffer_size_callback(window, width, height); - - // Initialize OpenGL - init_opengl(); - - // Initialize simulation - init_vertices(); - init_grid(); - adjust_grid(); - - // Initialize timer - t_old = glfwGetTime() - 0.01; - - while (!glfwWindowShouldClose(window)) - { - t = glfwGetTime(); - dt_total = t - t_old; - t_old = t; - - // Safety - iterate if dt_total is too large - while (dt_total > 0.f) - { - // Select iteration time step - dt = dt_total > MAX_DELTA_T ? MAX_DELTA_T : dt_total; - dt_total -= dt; - - // Calculate wave propagation - calc_grid(); - } - - // Compute height of each vertex - adjust_grid(); - - // Draw wave grid to OpenGL display - draw_scene(window); - - glfwPollEvents(); - } - - exit(EXIT_SUCCESS); -} - diff --git a/examples/common/glfw/include/GLFW/glfw3.h b/examples/common/glfw/include/GLFW/glfw3.h deleted file mode 100644 index 89414491..00000000 --- a/examples/common/glfw/include/GLFW/glfw3.h +++ /dev/null @@ -1,3355 +0,0 @@ -/************************************************************************* - * GLFW 3.1 - www.glfw.org - * A library for OpenGL, window and input - *------------------------------------------------------------------------ - * Copyright (c) 2002-2006 Marcus Geelnard - * Copyright (c) 2006-2010 Camilla Berglund - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would - * be appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not - * be misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source - * distribution. - * - *************************************************************************/ - -#ifndef _glfw3_h_ -#define _glfw3_h_ - -#ifdef __cplusplus -extern "C" { -#endif - - -/************************************************************************* - * Doxygen documentation - *************************************************************************/ - -/*! @defgroup context Context handling - * - * This is the reference documentation for context related functions. For more - * information, see the @ref context. - */ -/*! @defgroup init Initialization, version and errors - * - * This is the reference documentation for initialization and termination of - * the library, version management and error handling. For more information, - * see the @ref intro. - */ -/*! @defgroup input Input handling - * - * This is the reference documentation for input related functions and types. - * For more information, see the @ref input. - */ -/*! @defgroup monitor Monitor handling - * - * This is the reference documentation for monitor related functions and types. - * For more information, see the @ref monitor. - */ -/*! @defgroup window Window handling - * - * This is the reference documentation for window related functions and types, - * including creation, deletion and event polling. For more information, see - * the @ref window. - */ - - -/************************************************************************* - * Global definitions - *************************************************************************/ - -/* ------------------- BEGIN SYSTEM/COMPILER SPECIFIC -------------------- */ - -/* Please report any problems that you find with your compiler, which may - * be solved in this section! There are several compilers that I have not - * been able to test this file with yet. - * - * First: If we are we on Windows, we want a single define for it (_WIN32) - * (Note: For Cygwin the compiler flag -mwin32 should be used, but to - * make sure that things run smoothly for Cygwin users, we add __CYGWIN__ - * to the list of "valid Win32 identifiers", which removes the need for - * -mwin32) - */ -#if !defined(_WIN32) && (defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__)) - #define _WIN32 -#endif /* _WIN32 */ - -/* In order for extension support to be portable, we need to define an - * OpenGL function call method. We use the keyword APIENTRY, which is - * defined for Win32. (Note: Windows also needs this for ) - */ -#ifndef APIENTRY - #ifdef _WIN32 - #define APIENTRY __stdcall - #else - #define APIENTRY - #endif -#endif /* APIENTRY */ - -/* The following three defines are here solely to make some Windows-based - * files happy. Theoretically we could include , but - * it has the major drawback of severely polluting our namespace. - */ - -/* Under Windows, we need WINGDIAPI defined */ -#if !defined(WINGDIAPI) && defined(_WIN32) - #if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__POCC__) - /* Microsoft Visual C++, Borland C++ Builder and Pelles C */ - #define WINGDIAPI __declspec(dllimport) - #elif defined(__LCC__) - /* LCC-Win32 */ - #define WINGDIAPI __stdcall - #else - /* Others (e.g. MinGW, Cygwin) */ - #define WINGDIAPI extern - #endif - #define GLFW_WINGDIAPI_DEFINED -#endif /* WINGDIAPI */ - -/* Some files also need CALLBACK defined */ -#if !defined(CALLBACK) && defined(_WIN32) - #if defined(_MSC_VER) - /* Microsoft Visual C++ */ - #if (defined(_M_MRX000) || defined(_M_IX86) || defined(_M_ALPHA) || defined(_M_PPC)) && !defined(MIDL_PASS) - #define CALLBACK __stdcall - #else - #define CALLBACK - #endif - #else - /* Other Windows compilers */ - #define CALLBACK __stdcall - #endif - #define GLFW_CALLBACK_DEFINED -#endif /* CALLBACK */ - -/* Most GL/glu.h variants on Windows need wchar_t - * OpenGL/gl.h blocks the definition of ptrdiff_t by glext.h on OS X */ -#if !defined(GLFW_INCLUDE_NONE) - #include -#endif - -/* Include the chosen client API headers. - */ -#if defined(__APPLE_CC__) - #if defined(GLFW_INCLUDE_GLCOREARB) - #include - #if defined(GLFW_INCLUDE_GLEXT) - #include - #endif - #elif !defined(GLFW_INCLUDE_NONE) - #if !defined(GLFW_INCLUDE_GLEXT) - #define GL_GLEXT_LEGACY - #endif - #include - #endif - #if defined(GLFW_INCLUDE_GLU) - #include - #endif -#else - #if defined(GLFW_INCLUDE_GLCOREARB) - #include - #elif defined(GLFW_INCLUDE_ES1) - #include - #if defined(GLFW_INCLUDE_GLEXT) - #include - #endif - #elif defined(GLFW_INCLUDE_ES2) - #include - #if defined(GLFW_INCLUDE_GLEXT) - #include - #endif - #elif defined(GLFW_INCLUDE_ES3) - #include - #if defined(GLFW_INCLUDE_GLEXT) - #include - #endif - #elif defined(GLFW_INCLUDE_ES31) - #include - #if defined(GLFW_INCLUDE_GLEXT) - #include - #endif - #elif !defined(GLFW_INCLUDE_NONE) - #include - #if defined(GLFW_INCLUDE_GLEXT) - #include - #endif - #endif - #if defined(GLFW_INCLUDE_GLU) - #include - #endif -#endif - -#if defined(GLFW_DLL) && defined(_GLFW_BUILD_DLL) - /* GLFW_DLL must be defined by applications that are linking against the DLL - * version of the GLFW library. _GLFW_BUILD_DLL is defined by the GLFW - * configuration header when compiling the DLL version of the library. - */ - #error "You must not have both GLFW_DLL and _GLFW_BUILD_DLL defined" -#endif - -/* GLFWAPI is used to declare public API functions for export - * from the DLL / shared library / dynamic library. - */ -#if defined(_WIN32) && defined(_GLFW_BUILD_DLL) - /* We are building GLFW as a Win32 DLL */ - #define GLFWAPI __declspec(dllexport) -#elif defined(_WIN32) && defined(GLFW_DLL) - /* We are calling GLFW as a Win32 DLL */ - #if defined(__LCC__) - #define GLFWAPI extern - #else - #define GLFWAPI __declspec(dllimport) - #endif -#elif defined(__GNUC__) && defined(_GLFW_BUILD_DLL) - /* We are building GLFW as a shared / dynamic library */ - #define GLFWAPI __attribute__((visibility("default"))) -#else - /* We are building or calling GLFW as a static library */ - #define GLFWAPI -#endif - -/* -------------------- END SYSTEM/COMPILER SPECIFIC --------------------- */ - - -/************************************************************************* - * GLFW API tokens - *************************************************************************/ - -/*! @name GLFW version macros - * @{ */ -/*! @brief The major version number of the GLFW library. - * - * This is incremented when the API is changed in non-compatible ways. - * @ingroup init - */ -#define GLFW_VERSION_MAJOR 3 -/*! @brief The minor version number of the GLFW library. - * - * This is incremented when features are added to the API but it remains - * backward-compatible. - * @ingroup init - */ -#define GLFW_VERSION_MINOR 1 -/*! @brief The revision number of the GLFW library. - * - * This is incremented when a bug fix release is made that does not contain any - * API changes. - * @ingroup init - */ -#define GLFW_VERSION_REVISION 0 -/*! @} */ - -/*! @name Key and button actions - * @{ */ -/*! @brief The key or mouse button was released. - * - * The key or mouse button was released. - * - * @ingroup input - */ -#define GLFW_RELEASE 0 -/*! @brief The key or mouse button was pressed. - * - * The key or mouse button was pressed. - * - * @ingroup input - */ -#define GLFW_PRESS 1 -/*! @brief The key was held down until it repeated. - * - * The key was held down until it repeated. - * - * @ingroup input - */ -#define GLFW_REPEAT 2 -/*! @} */ - -/*! @defgroup keys Keyboard keys - * - * See [key input](@ref input_key) for how these are used. - * - * These key codes are inspired by the _USB HID Usage Tables v1.12_ (p. 53-60), - * but re-arranged to map to 7-bit ASCII for printable keys (function keys are - * put in the 256+ range). - * - * The naming of the key codes follow these rules: - * - The US keyboard layout is used - * - Names of printable alpha-numeric characters are used (e.g. "A", "R", - * "3", etc.) - * - For non-alphanumeric characters, Unicode:ish names are used (e.g. - * "COMMA", "LEFT_SQUARE_BRACKET", etc.). Note that some names do not - * correspond to the Unicode standard (usually for brevity) - * - Keys that lack a clear US mapping are named "WORLD_x" - * - For non-printable keys, custom names are used (e.g. "F4", - * "BACKSPACE", etc.) - * - * @ingroup input - * @{ - */ - -/* The unknown key */ -#define GLFW_KEY_UNKNOWN -1 - -/* Printable keys */ -#define GLFW_KEY_SPACE 32 -#define GLFW_KEY_APOSTROPHE 39 /* ' */ -#define GLFW_KEY_COMMA 44 /* , */ -#define GLFW_KEY_MINUS 45 /* - */ -#define GLFW_KEY_PERIOD 46 /* . */ -#define GLFW_KEY_SLASH 47 /* / */ -#define GLFW_KEY_0 48 -#define GLFW_KEY_1 49 -#define GLFW_KEY_2 50 -#define GLFW_KEY_3 51 -#define GLFW_KEY_4 52 -#define GLFW_KEY_5 53 -#define GLFW_KEY_6 54 -#define GLFW_KEY_7 55 -#define GLFW_KEY_8 56 -#define GLFW_KEY_9 57 -#define GLFW_KEY_SEMICOLON 59 /* ; */ -#define GLFW_KEY_EQUAL 61 /* = */ -#define GLFW_KEY_A 65 -#define GLFW_KEY_B 66 -#define GLFW_KEY_C 67 -#define GLFW_KEY_D 68 -#define GLFW_KEY_E 69 -#define GLFW_KEY_F 70 -#define GLFW_KEY_G 71 -#define GLFW_KEY_H 72 -#define GLFW_KEY_I 73 -#define GLFW_KEY_J 74 -#define GLFW_KEY_K 75 -#define GLFW_KEY_L 76 -#define GLFW_KEY_M 77 -#define GLFW_KEY_N 78 -#define GLFW_KEY_O 79 -#define GLFW_KEY_P 80 -#define GLFW_KEY_Q 81 -#define GLFW_KEY_R 82 -#define GLFW_KEY_S 83 -#define GLFW_KEY_T 84 -#define GLFW_KEY_U 85 -#define GLFW_KEY_V 86 -#define GLFW_KEY_W 87 -#define GLFW_KEY_X 88 -#define GLFW_KEY_Y 89 -#define GLFW_KEY_Z 90 -#define GLFW_KEY_LEFT_BRACKET 91 /* [ */ -#define GLFW_KEY_BACKSLASH 92 /* \ */ -#define GLFW_KEY_RIGHT_BRACKET 93 /* ] */ -#define GLFW_KEY_GRAVE_ACCENT 96 /* ` */ -#define GLFW_KEY_WORLD_1 161 /* non-US #1 */ -#define GLFW_KEY_WORLD_2 162 /* non-US #2 */ - -/* Function keys */ -#define GLFW_KEY_ESCAPE 256 -#define GLFW_KEY_ENTER 257 -#define GLFW_KEY_TAB 258 -#define GLFW_KEY_BACKSPACE 259 -#define GLFW_KEY_INSERT 260 -#define GLFW_KEY_DELETE 261 -#define GLFW_KEY_RIGHT 262 -#define GLFW_KEY_LEFT 263 -#define GLFW_KEY_DOWN 264 -#define GLFW_KEY_UP 265 -#define GLFW_KEY_PAGE_UP 266 -#define GLFW_KEY_PAGE_DOWN 267 -#define GLFW_KEY_HOME 268 -#define GLFW_KEY_END 269 -#define GLFW_KEY_CAPS_LOCK 280 -#define GLFW_KEY_SCROLL_LOCK 281 -#define GLFW_KEY_NUM_LOCK 282 -#define GLFW_KEY_PRINT_SCREEN 283 -#define GLFW_KEY_PAUSE 284 -#define GLFW_KEY_F1 290 -#define GLFW_KEY_F2 291 -#define GLFW_KEY_F3 292 -#define GLFW_KEY_F4 293 -#define GLFW_KEY_F5 294 -#define GLFW_KEY_F6 295 -#define GLFW_KEY_F7 296 -#define GLFW_KEY_F8 297 -#define GLFW_KEY_F9 298 -#define GLFW_KEY_F10 299 -#define GLFW_KEY_F11 300 -#define GLFW_KEY_F12 301 -#define GLFW_KEY_F13 302 -#define GLFW_KEY_F14 303 -#define GLFW_KEY_F15 304 -#define GLFW_KEY_F16 305 -#define GLFW_KEY_F17 306 -#define GLFW_KEY_F18 307 -#define GLFW_KEY_F19 308 -#define GLFW_KEY_F20 309 -#define GLFW_KEY_F21 310 -#define GLFW_KEY_F22 311 -#define GLFW_KEY_F23 312 -#define GLFW_KEY_F24 313 -#define GLFW_KEY_F25 314 -#define GLFW_KEY_KP_0 320 -#define GLFW_KEY_KP_1 321 -#define GLFW_KEY_KP_2 322 -#define GLFW_KEY_KP_3 323 -#define GLFW_KEY_KP_4 324 -#define GLFW_KEY_KP_5 325 -#define GLFW_KEY_KP_6 326 -#define GLFW_KEY_KP_7 327 -#define GLFW_KEY_KP_8 328 -#define GLFW_KEY_KP_9 329 -#define GLFW_KEY_KP_DECIMAL 330 -#define GLFW_KEY_KP_DIVIDE 331 -#define GLFW_KEY_KP_MULTIPLY 332 -#define GLFW_KEY_KP_SUBTRACT 333 -#define GLFW_KEY_KP_ADD 334 -#define GLFW_KEY_KP_ENTER 335 -#define GLFW_KEY_KP_EQUAL 336 -#define GLFW_KEY_LEFT_SHIFT 340 -#define GLFW_KEY_LEFT_CONTROL 341 -#define GLFW_KEY_LEFT_ALT 342 -#define GLFW_KEY_LEFT_SUPER 343 -#define GLFW_KEY_RIGHT_SHIFT 344 -#define GLFW_KEY_RIGHT_CONTROL 345 -#define GLFW_KEY_RIGHT_ALT 346 -#define GLFW_KEY_RIGHT_SUPER 347 -#define GLFW_KEY_MENU 348 -#define GLFW_KEY_LAST GLFW_KEY_MENU - -/*! @} */ - -/*! @defgroup mods Modifier key flags - * - * See [key input](@ref input_key) for how these are used. - * - * @ingroup input - * @{ */ - -/*! @brief If this bit is set one or more Shift keys were held down. - */ -#define GLFW_MOD_SHIFT 0x0001 -/*! @brief If this bit is set one or more Control keys were held down. - */ -#define GLFW_MOD_CONTROL 0x0002 -/*! @brief If this bit is set one or more Alt keys were held down. - */ -#define GLFW_MOD_ALT 0x0004 -/*! @brief If this bit is set one or more Super keys were held down. - */ -#define GLFW_MOD_SUPER 0x0008 - -/*! @} */ - -/*! @defgroup buttons Mouse buttons - * - * See [mouse button input](@ref input_mouse_button) for how these are used. - * - * @ingroup input - * @{ */ -#define GLFW_MOUSE_BUTTON_1 0 -#define GLFW_MOUSE_BUTTON_2 1 -#define GLFW_MOUSE_BUTTON_3 2 -#define GLFW_MOUSE_BUTTON_4 3 -#define GLFW_MOUSE_BUTTON_5 4 -#define GLFW_MOUSE_BUTTON_6 5 -#define GLFW_MOUSE_BUTTON_7 6 -#define GLFW_MOUSE_BUTTON_8 7 -#define GLFW_MOUSE_BUTTON_LAST GLFW_MOUSE_BUTTON_8 -#define GLFW_MOUSE_BUTTON_LEFT GLFW_MOUSE_BUTTON_1 -#define GLFW_MOUSE_BUTTON_RIGHT GLFW_MOUSE_BUTTON_2 -#define GLFW_MOUSE_BUTTON_MIDDLE GLFW_MOUSE_BUTTON_3 -/*! @} */ - -/*! @defgroup joysticks Joysticks - * - * See [joystick input](@ref joystick) for how these are used. - * - * @ingroup input - * @{ */ -#define GLFW_JOYSTICK_1 0 -#define GLFW_JOYSTICK_2 1 -#define GLFW_JOYSTICK_3 2 -#define GLFW_JOYSTICK_4 3 -#define GLFW_JOYSTICK_5 4 -#define GLFW_JOYSTICK_6 5 -#define GLFW_JOYSTICK_7 6 -#define GLFW_JOYSTICK_8 7 -#define GLFW_JOYSTICK_9 8 -#define GLFW_JOYSTICK_10 9 -#define GLFW_JOYSTICK_11 10 -#define GLFW_JOYSTICK_12 11 -#define GLFW_JOYSTICK_13 12 -#define GLFW_JOYSTICK_14 13 -#define GLFW_JOYSTICK_15 14 -#define GLFW_JOYSTICK_16 15 -#define GLFW_JOYSTICK_LAST GLFW_JOYSTICK_16 -/*! @} */ - -/*! @defgroup errors Error codes - * - * See [error handling](@ref error_handling) for how these are used. - * - * @ingroup init - * @{ */ -/*! @brief GLFW has not been initialized. - * - * This occurs if a GLFW function was called that may not be called unless the - * library is [initialized](@ref intro_init). - * - * @par Analysis - * Application programmer error. Initialize GLFW before calling any function - * that requires initialization. - */ -#define GLFW_NOT_INITIALIZED 0x00010001 -/*! @brief No context is current for this thread. - * - * This occurs if a GLFW function was called that needs and operates on the - * current OpenGL or OpenGL ES context but no context is current on the calling - * thread. One such function is @ref glfwSwapInterval. - * - * @par Analysis - * Application programmer error. Ensure a context is current before calling - * functions that require a current context. - */ -#define GLFW_NO_CURRENT_CONTEXT 0x00010002 -/*! @brief One of the arguments to the function was an invalid enum value. - * - * One of the arguments to the function was an invalid enum value, for example - * requesting [GLFW_RED_BITS](@ref window_hints_fb) with @ref - * glfwGetWindowAttrib. - * - * @par Analysis - * Application programmer error. Fix the offending call. - */ -#define GLFW_INVALID_ENUM 0x00010003 -/*! @brief One of the arguments to the function was an invalid value. - * - * One of the arguments to the function was an invalid value, for example - * requesting a non-existent OpenGL or OpenGL ES version like 2.7. - * - * Requesting a valid but unavailable OpenGL or OpenGL ES version will instead - * result in a @ref GLFW_VERSION_UNAVAILABLE error. - * - * @par Analysis - * Application programmer error. Fix the offending call. - */ -#define GLFW_INVALID_VALUE 0x00010004 -/*! @brief A memory allocation failed. - * - * A memory allocation failed. - * - * @par Analysis - * A bug in GLFW or the underlying operating system. Report the bug to our - * [issue tracker](https://github.com/glfw/glfw/issues). - */ -#define GLFW_OUT_OF_MEMORY 0x00010005 -/*! @brief GLFW could not find support for the requested client API on the - * system. - * - * GLFW could not find support for the requested client API on the system. - * - * @par Analysis - * The installed graphics driver does not support the requested client API, or - * does not support it via the chosen context creation backend. Below are - * a few examples. - * - * @par - * Some pre-installed Windows graphics drivers do not support OpenGL. AMD only - * supports OpenGL ES via EGL, while Nvidia and Intel only supports it via - * a WGL or GLX extension. OS X does not provide OpenGL ES at all. The Mesa - * EGL, OpenGL and OpenGL ES libraries do not interface with the Nvidia binary - * driver. - */ -#define GLFW_API_UNAVAILABLE 0x00010006 -/*! @brief The requested OpenGL or OpenGL ES version is not available. - * - * The requested OpenGL or OpenGL ES version (including any requested profile - * or context option) is not available on this machine. - * - * @par Analysis - * The machine does not support your requirements. If your application is - * sufficiently flexible, downgrade your requirements and try again. - * Otherwise, inform the user that their machine does not match your - * requirements. - * - * @par - * Future invalid OpenGL and OpenGL ES versions, for example OpenGL 4.8 if 5.0 - * comes out before the 4.x series gets that far, also fail with this error and - * not @ref GLFW_INVALID_VALUE, because GLFW cannot know what future versions - * will exist. - */ -#define GLFW_VERSION_UNAVAILABLE 0x00010007 -/*! @brief A platform-specific error occurred that does not match any of the - * more specific categories. - * - * A platform-specific error occurred that does not match any of the more - * specific categories. - * - * @par Analysis - * A bug in GLFW or the underlying operating system. Report the bug to our - * [issue tracker](https://github.com/glfw/glfw/issues). - */ -#define GLFW_PLATFORM_ERROR 0x00010008 -/*! @brief The requested format is not supported or available. - * - * If emitted during window creation, the requested pixel format is not - * supported. - * - * If emitted when querying the clipboard, the contents of the clipboard could - * not be converted to the requested format. - * - * @par Analysis - * If emitted during window creation, one or more - * [hard constraints](@ref window_hints_hard) did not match any of the - * available pixel formats. If your application is sufficiently flexible, - * downgrade your requirements and try again. Otherwise, inform the user that - * their machine does not match your requirements. - * - * @par - * If emitted when querying the clipboard, ignore the error or report it to - * the user, as appropriate. - */ -#define GLFW_FORMAT_UNAVAILABLE 0x00010009 -/*! @} */ - -#define GLFW_FOCUSED 0x00020001 -#define GLFW_ICONIFIED 0x00020002 -#define GLFW_RESIZABLE 0x00020003 -#define GLFW_VISIBLE 0x00020004 -#define GLFW_DECORATED 0x00020005 -#define GLFW_AUTO_ICONIFY 0x00020006 -#define GLFW_FLOATING 0x00020007 - -#define GLFW_RED_BITS 0x00021001 -#define GLFW_GREEN_BITS 0x00021002 -#define GLFW_BLUE_BITS 0x00021003 -#define GLFW_ALPHA_BITS 0x00021004 -#define GLFW_DEPTH_BITS 0x00021005 -#define GLFW_STENCIL_BITS 0x00021006 -#define GLFW_ACCUM_RED_BITS 0x00021007 -#define GLFW_ACCUM_GREEN_BITS 0x00021008 -#define GLFW_ACCUM_BLUE_BITS 0x00021009 -#define GLFW_ACCUM_ALPHA_BITS 0x0002100A -#define GLFW_AUX_BUFFERS 0x0002100B -#define GLFW_STEREO 0x0002100C -#define GLFW_SAMPLES 0x0002100D -#define GLFW_SRGB_CAPABLE 0x0002100E -#define GLFW_REFRESH_RATE 0x0002100F -#define GLFW_DOUBLEBUFFER 0x00021010 - -#define GLFW_CLIENT_API 0x00022001 -#define GLFW_CONTEXT_VERSION_MAJOR 0x00022002 -#define GLFW_CONTEXT_VERSION_MINOR 0x00022003 -#define GLFW_CONTEXT_REVISION 0x00022004 -#define GLFW_CONTEXT_ROBUSTNESS 0x00022005 -#define GLFW_OPENGL_FORWARD_COMPAT 0x00022006 -#define GLFW_OPENGL_DEBUG_CONTEXT 0x00022007 -#define GLFW_OPENGL_PROFILE 0x00022008 -#define GLFW_CONTEXT_RELEASE_BEHAVIOR 0x00022009 - -#define GLFW_OPENGL_API 0x00030001 -#define GLFW_OPENGL_ES_API 0x00030002 - -#define GLFW_NO_ROBUSTNESS 0 -#define GLFW_NO_RESET_NOTIFICATION 0x00031001 -#define GLFW_LOSE_CONTEXT_ON_RESET 0x00031002 - -#define GLFW_OPENGL_ANY_PROFILE 0 -#define GLFW_OPENGL_CORE_PROFILE 0x00032001 -#define GLFW_OPENGL_COMPAT_PROFILE 0x00032002 - -#define GLFW_CURSOR 0x00033001 -#define GLFW_STICKY_KEYS 0x00033002 -#define GLFW_STICKY_MOUSE_BUTTONS 0x00033003 - -#define GLFW_CURSOR_NORMAL 0x00034001 -#define GLFW_CURSOR_HIDDEN 0x00034002 -#define GLFW_CURSOR_DISABLED 0x00034003 - -#define GLFW_ANY_RELEASE_BEHAVIOR 0 -#define GLFW_RELEASE_BEHAVIOR_FLUSH 0x00035001 -#define GLFW_RELEASE_BEHAVIOR_NONE 0x00035002 - -/*! @defgroup shapes Standard cursor shapes - * - * See [standard cursor creation](@ref cursor_standard) for how these are used. - * - * @ingroup input - * @{ */ - -/*! @brief The regular arrow cursor shape. - * - * The regular arrow cursor. - */ -#define GLFW_ARROW_CURSOR 0x00036001 -/*! @brief The text input I-beam cursor shape. - * - * The text input I-beam cursor shape. - */ -#define GLFW_IBEAM_CURSOR 0x00036002 -/*! @brief The crosshair shape. - * - * The crosshair shape. - */ -#define GLFW_CROSSHAIR_CURSOR 0x00036003 -/*! @brief The hand shape. - * - * The hand shape. - */ -#define GLFW_HAND_CURSOR 0x00036004 -/*! @brief The horizontal resize arrow shape. - * - * The horizontal resize arrow shape. - */ -#define GLFW_HRESIZE_CURSOR 0x00036005 -/*! @brief The vertical resize arrow shape. - * - * The vertical resize arrow shape. - */ -#define GLFW_VRESIZE_CURSOR 0x00036006 -/*! @} */ - -#define GLFW_CONNECTED 0x00040001 -#define GLFW_DISCONNECTED 0x00040002 - -#define GLFW_DONT_CARE -1 - - -/************************************************************************* - * GLFW API types - *************************************************************************/ - -/*! @brief Client API function pointer type. - * - * Generic function pointer used for returning client API function pointers - * without forcing a cast from a regular pointer. - * - * @ingroup context - */ -typedef void (*GLFWglproc)(void); - -/*! @brief Opaque monitor object. - * - * Opaque monitor object. - * - * @ingroup monitor - */ -typedef struct GLFWmonitor GLFWmonitor; - -/*! @brief Opaque window object. - * - * Opaque window object. - * - * @ingroup window - */ -typedef struct GLFWwindow GLFWwindow; - -/*! @brief Opaque cursor object. - * - * Opaque cursor object. - * - * @ingroup cursor - */ -typedef struct GLFWcursor GLFWcursor; - -/*! @brief The function signature for error callbacks. - * - * This is the function signature for error callback functions. - * - * @param[in] error An [error code](@ref errors). - * @param[in] description A UTF-8 encoded string describing the error. - * - * @sa glfwSetErrorCallback - * - * @ingroup init - */ -typedef void (* GLFWerrorfun)(int,const char*); - -/*! @brief The function signature for window position callbacks. - * - * This is the function signature for window position callback functions. - * - * @param[in] window The window that was moved. - * @param[in] xpos The new x-coordinate, in screen coordinates, of the - * upper-left corner of the client area of the window. - * @param[in] ypos The new y-coordinate, in screen coordinates, of the - * upper-left corner of the client area of the window. - * - * @sa glfwSetWindowPosCallback - * - * @ingroup window - */ -typedef void (* GLFWwindowposfun)(GLFWwindow*,int,int); - -/*! @brief The function signature for window resize callbacks. - * - * This is the function signature for window size callback functions. - * - * @param[in] window The window that was resized. - * @param[in] width The new width, in screen coordinates, of the window. - * @param[in] height The new height, in screen coordinates, of the window. - * - * @sa glfwSetWindowSizeCallback - * - * @ingroup window - */ -typedef void (* GLFWwindowsizefun)(GLFWwindow*,int,int); - -/*! @brief The function signature for window close callbacks. - * - * This is the function signature for window close callback functions. - * - * @param[in] window The window that the user attempted to close. - * - * @sa glfwSetWindowCloseCallback - * - * @ingroup window - */ -typedef void (* GLFWwindowclosefun)(GLFWwindow*); - -/*! @brief The function signature for window content refresh callbacks. - * - * This is the function signature for window refresh callback functions. - * - * @param[in] window The window whose content needs to be refreshed. - * - * @sa glfwSetWindowRefreshCallback - * - * @ingroup window - */ -typedef void (* GLFWwindowrefreshfun)(GLFWwindow*); - -/*! @brief The function signature for window focus/defocus callbacks. - * - * This is the function signature for window focus callback functions. - * - * @param[in] window The window that gained or lost input focus. - * @param[in] focused `GL_TRUE` if the window was given input focus, or - * `GL_FALSE` if it lost it. - * - * @sa glfwSetWindowFocusCallback - * - * @ingroup window - */ -typedef void (* GLFWwindowfocusfun)(GLFWwindow*,int); - -/*! @brief The function signature for window iconify/restore callbacks. - * - * This is the function signature for window iconify/restore callback - * functions. - * - * @param[in] window The window that was iconified or restored. - * @param[in] iconified `GL_TRUE` if the window was iconified, or `GL_FALSE` - * if it was restored. - * - * @sa glfwSetWindowIconifyCallback - * - * @ingroup window - */ -typedef void (* GLFWwindowiconifyfun)(GLFWwindow*,int); - -/*! @brief The function signature for framebuffer resize callbacks. - * - * This is the function signature for framebuffer resize callback - * functions. - * - * @param[in] window The window whose framebuffer was resized. - * @param[in] width The new width, in pixels, of the framebuffer. - * @param[in] height The new height, in pixels, of the framebuffer. - * - * @sa glfwSetFramebufferSizeCallback - * - * @ingroup window - */ -typedef void (* GLFWframebuffersizefun)(GLFWwindow*,int,int); - -/*! @brief The function signature for mouse button callbacks. - * - * This is the function signature for mouse button callback functions. - * - * @param[in] window The window that received the event. - * @param[in] button The [mouse button](@ref buttons) that was pressed or - * released. - * @param[in] action One of `GLFW_PRESS` or `GLFW_RELEASE`. - * @param[in] mods Bit field describing which [modifier keys](@ref mods) were - * held down. - * - * @sa glfwSetMouseButtonCallback - * - * @ingroup input - */ -typedef void (* GLFWmousebuttonfun)(GLFWwindow*,int,int,int); - -/*! @brief The function signature for cursor position callbacks. - * - * This is the function signature for cursor position callback functions. - * - * @param[in] window The window that received the event. - * @param[in] xpos The new x-coordinate, in screen coordinates, of the cursor. - * @param[in] ypos The new y-coordinate, in screen coordinates, of the cursor. - * - * @sa glfwSetCursorPosCallback - * - * @ingroup input - */ -typedef void (* GLFWcursorposfun)(GLFWwindow*,double,double); - -/*! @brief The function signature for cursor enter/leave callbacks. - * - * This is the function signature for cursor enter/leave callback functions. - * - * @param[in] window The window that received the event. - * @param[in] entered `GL_TRUE` if the cursor entered the window's client - * area, or `GL_FALSE` if it left it. - * - * @sa glfwSetCursorEnterCallback - * - * @ingroup input - */ -typedef void (* GLFWcursorenterfun)(GLFWwindow*,int); - -/*! @brief The function signature for scroll callbacks. - * - * This is the function signature for scroll callback functions. - * - * @param[in] window The window that received the event. - * @param[in] xoffset The scroll offset along the x-axis. - * @param[in] yoffset The scroll offset along the y-axis. - * - * @sa glfwSetScrollCallback - * - * @ingroup input - */ -typedef void (* GLFWscrollfun)(GLFWwindow*,double,double); - -/*! @brief The function signature for keyboard key callbacks. - * - * This is the function signature for keyboard key callback functions. - * - * @param[in] window The window that received the event. - * @param[in] key The [keyboard key](@ref keys) that was pressed or released. - * @param[in] scancode The system-specific scancode of the key. - * @param[in] action `GLFW_PRESS`, `GLFW_RELEASE` or `GLFW_REPEAT`. - * @param[in] mods Bit field describing which [modifier keys](@ref mods) were - * held down. - * - * @sa glfwSetKeyCallback - * - * @ingroup input - */ -typedef void (* GLFWkeyfun)(GLFWwindow*,int,int,int,int); - -/*! @brief The function signature for Unicode character callbacks. - * - * This is the function signature for Unicode character callback functions. - * - * @param[in] window The window that received the event. - * @param[in] codepoint The Unicode code point of the character. - * - * @sa glfwSetCharCallback - * - * @ingroup input - */ -typedef void (* GLFWcharfun)(GLFWwindow*,unsigned int); - -/*! @brief The function signature for Unicode character with modifiers - * callbacks. - * - * This is the function signature for Unicode character with modifiers callback - * functions. It is called for each input character, regardless of what - * modifier keys are held down. - * - * @param[in] window The window that received the event. - * @param[in] codepoint The Unicode code point of the character. - * @param[in] mods Bit field describing which [modifier keys](@ref mods) were - * held down. - * - * @sa glfwSetCharModsCallback - * - * @ingroup input - */ -typedef void (* GLFWcharmodsfun)(GLFWwindow*,unsigned int,int); - -/*! @brief The function signature for file drop callbacks. - * - * This is the function signature for file drop callbacks. - * - * @param[in] window The window that received the event. - * @param[in] count The number of dropped files. - * @param[in] names The UTF-8 encoded path names of the dropped files. - * - * @sa glfwSetDropCallback - * - * @ingroup input - */ -typedef void (* GLFWdropfun)(GLFWwindow*,int,const char**); - -/*! @brief The function signature for monitor configuration callbacks. - * - * This is the function signature for monitor configuration callback functions. - * - * @param[in] monitor The monitor that was connected or disconnected. - * @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`. - * - * @sa glfwSetMonitorCallback - * - * @ingroup monitor - */ -typedef void (* GLFWmonitorfun)(GLFWmonitor*,int); - -/*! @brief Video mode type. - * - * This describes a single video mode. - * - * @ingroup monitor - */ -typedef struct GLFWvidmode -{ - /*! The width, in screen coordinates, of the video mode. - */ - int width; - /*! The height, in screen coordinates, of the video mode. - */ - int height; - /*! The bit depth of the red channel of the video mode. - */ - int redBits; - /*! The bit depth of the green channel of the video mode. - */ - int greenBits; - /*! The bit depth of the blue channel of the video mode. - */ - int blueBits; - /*! The refresh rate, in Hz, of the video mode. - */ - int refreshRate; -} GLFWvidmode; - -/*! @brief Gamma ramp. - * - * This describes the gamma ramp for a monitor. - * - * @sa glfwGetGammaRamp glfwSetGammaRamp - * - * @ingroup monitor - */ -typedef struct GLFWgammaramp -{ - /*! An array of value describing the response of the red channel. - */ - unsigned short* red; - /*! An array of value describing the response of the green channel. - */ - unsigned short* green; - /*! An array of value describing the response of the blue channel. - */ - unsigned short* blue; - /*! The number of elements in each array. - */ - unsigned int size; -} GLFWgammaramp; - -/*! @brief Image data. - */ -typedef struct GLFWimage -{ - /*! The width, in pixels, of this image. - */ - int width; - /*! The height, in pixels, of this image. - */ - int height; - /*! The pixel data of this image, arranged left-to-right, top-to-bottom. - */ - unsigned char* pixels; -} GLFWimage; - - -/************************************************************************* - * GLFW API functions - *************************************************************************/ - -/*! @brief Initializes the GLFW library. - * - * This function initializes the GLFW library. Before most GLFW functions can - * be used, GLFW must be initialized, and before an application terminates GLFW - * should be terminated in order to free any resources allocated during or - * after initialization. - * - * If this function fails, it calls @ref glfwTerminate before returning. If it - * succeeds, you should call @ref glfwTerminate before the application exits. - * - * Additional calls to this function after successful initialization but before - * termination will return `GL_TRUE` immediately. - * - * @return `GL_TRUE` if successful, or `GL_FALSE` if an - * [error](@ref error_handling) occurred. - * - * @remarks __OS X:__ This function will change the current directory of the - * application to the `Contents/Resources` subdirectory of the application's - * bundle, if present. This can be disabled with a - * [compile-time option](@ref compile_options_osx). - * - * @remarks __X11:__ If the `LC_CTYPE` category of the current locale is set to - * `"C"` then the environment's locale will be applied to that category. This - * is done because character input will not function when `LC_CTYPE` is set to - * `"C"`. If another locale was set before this function was called, it will - * be left untouched. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref intro_init - * @sa glfwTerminate - * - * @since Added in GLFW 1.0. - * - * @ingroup init - */ -GLFWAPI int glfwInit(void); - -/*! @brief Terminates the GLFW library. - * - * This function destroys all remaining windows and cursors, restores any - * modified gamma ramps and frees any other allocated resources. Once this - * function is called, you must again call @ref glfwInit successfully before - * you will be able to use most GLFW functions. - * - * If GLFW has been successfully initialized, this function should be called - * before the application exits. If initialization fails, there is no need to - * call this function, as it is called by @ref glfwInit before it returns - * failure. - * - * @remarks This function may be called before @ref glfwInit. - * - * @warning No window's context may be current on another thread when this - * function is called. - * - * @par Reentrancy - * This function may not be called from a callback. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref intro_init - * @sa glfwInit - * - * @since Added in GLFW 1.0. - * - * @ingroup init - */ -GLFWAPI void glfwTerminate(void); - -/*! @brief Retrieves the version of the GLFW library. - * - * This function retrieves the major, minor and revision numbers of the GLFW - * library. It is intended for when you are using GLFW as a shared library and - * want to ensure that you are using the minimum required version. - * - * Any or all of the version arguments may be `NULL`. This function always - * succeeds. - * - * @param[out] major Where to store the major version number, or `NULL`. - * @param[out] minor Where to store the minor version number, or `NULL`. - * @param[out] rev Where to store the revision number, or `NULL`. - * - * @remarks This function may be called before @ref glfwInit. - * - * @par Thread Safety - * This function may be called from any thread. - * - * @sa @ref intro_version - * @sa glfwGetVersionString - * - * @since Added in GLFW 1.0. - * - * @ingroup init - */ -GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev); - -/*! @brief Returns a string describing the compile-time configuration. - * - * This function returns the compile-time generated - * [version string](@ref intro_version_string) of the GLFW library binary. It - * describes the version, platform, compiler and any platform-specific - * compile-time options. - * - * __Do not use the version string__ to parse the GLFW library version. The - * @ref glfwGetVersion function already provides the version of the running - * library binary. - * - * This function always succeeds. - * - * @return The GLFW version string. - * - * @remarks This function may be called before @ref glfwInit. - * - * @par Pointer Lifetime - * The returned string is static and compile-time generated. - * - * @par Thread Safety - * This function may be called from any thread. - * - * @sa @ref intro_version - * @sa glfwGetVersion - * - * @since Added in GLFW 3.0. - * - * @ingroup init - */ -GLFWAPI const char* glfwGetVersionString(void); - -/*! @brief Sets the error callback. - * - * This function sets the error callback, which is called with an error code - * and a human-readable description each time a GLFW error occurs. - * - * The error callback is called on the thread where the error occurred. If you - * are using GLFW from multiple threads, your error callback needs to be - * written accordingly. - * - * Because the description string may have been generated specifically for that - * error, it is not guaranteed to be valid after the callback has returned. If - * you wish to use it after the callback returns, you need to make a copy. - * - * Once set, the error callback remains set even after the library has been - * terminated. - * - * @param[in] cbfun The new callback, or `NULL` to remove the currently set - * callback. - * @return The previously set callback, or `NULL` if no callback was set. - * - * @remarks This function may be called before @ref glfwInit. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref error_handling - * - * @since Added in GLFW 3.0. - * - * @ingroup init - */ -GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun); - -/*! @brief Returns the currently connected monitors. - * - * This function returns an array of handles for all currently connected - * monitors. - * - * @param[out] count Where to store the number of monitors in the returned - * array. This is set to zero if an error occurred. - * @return An array of monitor handles, or `NULL` if an - * [error](@ref error_handling) occurred. - * - * @par Pointer Lifetime - * The returned array is allocated and freed by GLFW. You should not free it - * yourself. It is guaranteed to be valid only until the monitor configuration - * changes or the library is terminated. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref monitor_monitors - * @sa @ref monitor_event - * @sa glfwGetPrimaryMonitor - * - * @since Added in GLFW 3.0. - * - * @ingroup monitor - */ -GLFWAPI GLFWmonitor** glfwGetMonitors(int* count); - -/*! @brief Returns the primary monitor. - * - * This function returns the primary monitor. This is usually the monitor - * where elements like the Windows task bar or the OS X menu bar is located. - * - * @return The primary monitor, or `NULL` if an [error](@ref error_handling) - * occurred. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref monitor_monitors - * @sa glfwGetMonitors - * - * @since Added in GLFW 3.0. - * - * @ingroup monitor - */ -GLFWAPI GLFWmonitor* glfwGetPrimaryMonitor(void); - -/*! @brief Returns the position of the monitor's viewport on the virtual screen. - * - * This function returns the position, in screen coordinates, of the upper-left - * corner of the specified monitor. - * - * Any or all of the position arguments may be `NULL`. If an error occurs, all - * non-`NULL` position arguments will be set to zero. - * - * @param[in] monitor The monitor to query. - * @param[out] xpos Where to store the monitor x-coordinate, or `NULL`. - * @param[out] ypos Where to store the monitor y-coordinate, or `NULL`. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref monitor_properties - * - * @since Added in GLFW 3.0. - * - * @ingroup monitor - */ -GLFWAPI void glfwGetMonitorPos(GLFWmonitor* monitor, int* xpos, int* ypos); - -/*! @brief Returns the physical size of the monitor. - * - * This function returns the size, in millimetres, of the display area of the - * specified monitor. - * - * Some systems do not provide accurate monitor size information, either - * because the monitor - * [EDID](https://en.wikipedia.org/wiki/Extended_display_identification_data) - * data is incorrect or because the driver does not report it accurately. - * - * Any or all of the size arguments may be `NULL`. If an error occurs, all - * non-`NULL` size arguments will be set to zero. - * - * @param[in] monitor The monitor to query. - * @param[out] widthMM Where to store the width, in millimetres, of the - * monitor's display area, or `NULL`. - * @param[out] heightMM Where to store the height, in millimetres, of the - * monitor's display area, or `NULL`. - * - * @remarks __Windows:__ The OS calculates the returned physical size from the - * current resolution and system DPI instead of querying the monitor EDID data. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref monitor_properties - * - * @since Added in GLFW 3.0. - * - * @ingroup monitor - */ -GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* monitor, int* widthMM, int* heightMM); - -/*! @brief Returns the name of the specified monitor. - * - * This function returns a human-readable name, encoded as UTF-8, of the - * specified monitor. The name typically reflects the make and model of the - * monitor and is not guaranteed to be unique among the connected monitors. - * - * @param[in] monitor The monitor to query. - * @return The UTF-8 encoded name of the monitor, or `NULL` if an - * [error](@ref error_handling) occurred. - * - * @par Pointer Lifetime - * The returned string is allocated and freed by GLFW. You should not free it - * yourself. It is valid until the specified monitor is disconnected or the - * library is terminated. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref monitor_properties - * - * @since Added in GLFW 3.0. - * - * @ingroup monitor - */ -GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* monitor); - -/*! @brief Sets the monitor configuration callback. - * - * This function sets the monitor configuration callback, or removes the - * currently set callback. This is called when a monitor is connected to or - * disconnected from the system. - * - * @param[in] cbfun The new callback, or `NULL` to remove the currently set - * callback. - * @return The previously set callback, or `NULL` if no callback was set or the - * library had not been [initialized](@ref intro_init). - * - * @bug __X11:__ This callback is not yet called on monitor configuration - * changes. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref monitor_event - * - * @since Added in GLFW 3.0. - * - * @ingroup monitor - */ -GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun cbfun); - -/*! @brief Returns the available video modes for the specified monitor. - * - * This function returns an array of all video modes supported by the specified - * monitor. The returned array is sorted in ascending order, first by color - * bit depth (the sum of all channel depths) and then by resolution area (the - * product of width and height). - * - * @param[in] monitor The monitor to query. - * @param[out] count Where to store the number of video modes in the returned - * array. This is set to zero if an error occurred. - * @return An array of video modes, or `NULL` if an - * [error](@ref error_handling) occurred. - * - * @par Pointer Lifetime - * The returned array is allocated and freed by GLFW. You should not free it - * yourself. It is valid until the specified monitor is disconnected, this - * function is called again for that monitor or the library is terminated. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref monitor_modes - * @sa glfwGetVideoMode - * - * @since Added in GLFW 1.0. - * - * @par - * __GLFW 3:__ Changed to return an array of modes for a specific monitor. - * - * @ingroup monitor - */ -GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* monitor, int* count); - -/*! @brief Returns the current mode of the specified monitor. - * - * This function returns the current video mode of the specified monitor. If - * you have created a full screen window for that monitor, the return value - * will depend on whether that window is iconified. - * - * @param[in] monitor The monitor to query. - * @return The current mode of the monitor, or `NULL` if an - * [error](@ref error_handling) occurred. - * - * @par Pointer Lifetime - * The returned array is allocated and freed by GLFW. You should not free it - * yourself. It is valid until the specified monitor is disconnected or the - * library is terminated. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref monitor_modes - * @sa glfwGetVideoModes - * - * @since Added in GLFW 3.0. Replaces `glfwGetDesktopMode`. - * - * @ingroup monitor - */ -GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor); - -/*! @brief Generates a gamma ramp and sets it for the specified monitor. - * - * This function generates a 256-element gamma ramp from the specified exponent - * and then calls @ref glfwSetGammaRamp with it. - * - * @param[in] monitor The monitor whose gamma ramp to set. - * @param[in] gamma The desired exponent. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref monitor_gamma - * - * @since Added in GLFW 3.0. - * - * @ingroup monitor - */ -GLFWAPI void glfwSetGamma(GLFWmonitor* monitor, float gamma); - -/*! @brief Returns the current gamma ramp for the specified monitor. - * - * This function returns the current gamma ramp of the specified monitor. - * - * @param[in] monitor The monitor to query. - * @return The current gamma ramp, or `NULL` if an - * [error](@ref error_handling) occurred. - * - * @par Pointer Lifetime - * The returned structure and its arrays are allocated and freed by GLFW. You - * should not free them yourself. They are valid until the specified monitor - * is disconnected, this function is called again for that monitor or the - * library is terminated. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref monitor_gamma - * - * @since Added in GLFW 3.0. - * - * @ingroup monitor - */ -GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* monitor); - -/*! @brief Sets the current gamma ramp for the specified monitor. - * - * This function sets the current gamma ramp for the specified monitor. The - * original gamma ramp for that monitor is saved by GLFW the first time this - * function is called and is restored by @ref glfwTerminate. - * - * @param[in] monitor The monitor whose gamma ramp to set. - * @param[in] ramp The gamma ramp to use. - * - * @note Gamma ramp sizes other than 256 are not supported by all hardware. - * - * @par Pointer Lifetime - * The specified gamma ramp is copied before this function returns. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref monitor_gamma - * - * @since Added in GLFW 3.0. - * - * @ingroup monitor - */ -GLFWAPI void glfwSetGammaRamp(GLFWmonitor* monitor, const GLFWgammaramp* ramp); - -/*! @brief Resets all window hints to their default values. - * - * This function resets all window hints to their - * [default values](@ref window_hints_values). - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref window_hints - * @sa glfwWindowHint - * - * @since Added in GLFW 3.0. - * - * @ingroup window - */ -GLFWAPI void glfwDefaultWindowHints(void); - -/*! @brief Sets the specified window hint to the desired value. - * - * This function sets hints for the next call to @ref glfwCreateWindow. The - * hints, once set, retain their values until changed by a call to @ref - * glfwWindowHint or @ref glfwDefaultWindowHints, or until the library is - * terminated. - * - * @param[in] target The [window hint](@ref window_hints) to set. - * @param[in] hint The new value of the window hint. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref window_hints - * @sa glfwDefaultWindowHints - * - * @since Added in GLFW 3.0. Replaces `glfwOpenWindowHint`. - * - * @ingroup window - */ -GLFWAPI void glfwWindowHint(int target, int hint); - -/*! @brief Creates a window and its associated context. - * - * This function creates a window and its associated OpenGL or OpenGL ES - * context. Most of the options controlling how the window and its context - * should be created are specified with [window hints](@ref window_hints). - * - * Successful creation does not change which context is current. Before you - * can use the newly created context, you need to - * [make it current](@ref context_current). For information about the `share` - * parameter, see @ref context_sharing. - * - * The created window, framebuffer and context may differ from what you - * requested, as not all parameters and hints are - * [hard constraints](@ref window_hints_hard). This includes the size of the - * window, especially for full screen windows. To query the actual attributes - * of the created window, framebuffer and context, use queries like @ref - * glfwGetWindowAttrib and @ref glfwGetWindowSize. - * - * To create a full screen window, you need to specify the monitor the window - * will cover. If no monitor is specified, windowed mode will be used. Unless - * you have a way for the user to choose a specific monitor, it is recommended - * that you pick the primary monitor. For more information on how to query - * connected monitors, see @ref monitor_monitors. - * - * For full screen windows, the specified size becomes the resolution of the - * window's _desired video mode_. As long as a full screen window has input - * focus, the supported video mode most closely matching the desired video mode - * is set for the specified monitor. For more information about full screen - * windows, including the creation of so called _windowed full screen_ or - * _borderless full screen_ windows, see @ref window_windowed_full_screen. - * - * By default, newly created windows use the placement recommended by the - * window system. To create the window at a specific position, make it - * initially invisible using the [GLFW_VISIBLE](@ref window_hints_wnd) window - * hint, set its [position](@ref window_pos) and then [show](@ref window_hide) - * it. - * - * If a full screen window has input focus, the screensaver is prohibited from - * starting. - * - * Window systems put limits on window sizes. Very large or very small window - * dimensions may be overridden by the window system on creation. Check the - * actual [size](@ref window_size) after creation. - * - * The [swap interval](@ref buffer_swap) is not set during window creation and - * the initial value may vary depending on driver settings and defaults. - * - * @param[in] width The desired width, in screen coordinates, of the window. - * This must be greater than zero. - * @param[in] height The desired height, in screen coordinates, of the window. - * This must be greater than zero. - * @param[in] title The initial, UTF-8 encoded window title. - * @param[in] monitor The monitor to use for full screen mode, or `NULL` to use - * windowed mode. - * @param[in] share The window whose context to share resources with, or `NULL` - * to not share resources. - * @return The handle of the created window, or `NULL` if an - * [error](@ref error_handling) occurred. - * - * @remarks __Windows:__ Window creation will fail if the Microsoft GDI - * software OpenGL implementation is the only one available. - * - * @remarks __Windows:__ If the executable has an icon resource named - * `GLFW_ICON,` it will be set as the icon for the window. If no such icon is - * present, the `IDI_WINLOGO` icon will be used instead. - * - * @remarks __Windows:__ The context to share resources with may not be current - * on any other thread. - * - * @remarks __OS X:__ The GLFW window has no icon, as it is not a document - * window, but the dock icon will be the same as the application bundle's icon. - * For more information on bundles, see the - * [Bundle Programming Guide](https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/) - * in the Mac Developer Library. - * - * @remarks __OS X:__ The first time a window is created the menu bar is - * populated with common commands like Hide, Quit and About. The About entry - * opens a minimal about dialog with information from the application's bundle. - * The menu bar can be disabled with a - * [compile-time option](@ref compile_options_osx). - * - * @remarks __X11:__ There is no mechanism for setting the window icon yet. - * - * @remarks __X11:__ Some window managers will not respect the placement of - * initially hidden windows. - * - * @par Reentrancy - * This function may not be called from a callback. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref window_creation - * @sa glfwDestroyWindow - * - * @since Added in GLFW 3.0. Replaces `glfwOpenWindow`. - * - * @ingroup window - */ -GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, const char* title, GLFWmonitor* monitor, GLFWwindow* share); - -/*! @brief Destroys the specified window and its context. - * - * This function destroys the specified window and its context. On calling - * this function, no further callbacks will be called for that window. - * - * If the context of the specified window is current on the main thread, it is - * detached before being destroyed. - * - * @param[in] window The window to destroy. - * - * @note The context of the specified window must not be current on any other - * thread when this function is called. - * - * @par Reentrancy - * This function may not be called from a callback. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref window_creation - * @sa glfwCreateWindow - * - * @since Added in GLFW 3.0. Replaces `glfwCloseWindow`. - * - * @ingroup window - */ -GLFWAPI void glfwDestroyWindow(GLFWwindow* window); - -/*! @brief Checks the close flag of the specified window. - * - * This function returns the value of the close flag of the specified window. - * - * @param[in] window The window to query. - * @return The value of the close flag. - * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. - * - * @sa @ref window_close - * - * @since Added in GLFW 3.0. - * - * @ingroup window - */ -GLFWAPI int glfwWindowShouldClose(GLFWwindow* window); - -/*! @brief Sets the close flag of the specified window. - * - * This function sets the value of the close flag of the specified window. - * This can be used to override the user's attempt to close the window, or - * to signal that it should be closed. - * - * @param[in] window The window whose flag to change. - * @param[in] value The new value. - * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. - * - * @sa @ref window_close - * - * @since Added in GLFW 3.0. - * - * @ingroup window - */ -GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* window, int value); - -/*! @brief Sets the title of the specified window. - * - * This function sets the window title, encoded as UTF-8, of the specified - * window. - * - * @param[in] window The window whose title to change. - * @param[in] title The UTF-8 encoded window title. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref window_title - * - * @since Added in GLFW 1.0. - * - * @par - * __GLFW 3:__ Added window handle parameter. - * - * @ingroup window - */ -GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title); - -/*! @brief Retrieves the position of the client area of the specified window. - * - * This function retrieves the position, in screen coordinates, of the - * upper-left corner of the client area of the specified window. - * - * Any or all of the position arguments may be `NULL`. If an error occurs, all - * non-`NULL` position arguments will be set to zero. - * - * @param[in] window The window to query. - * @param[out] xpos Where to store the x-coordinate of the upper-left corner of - * the client area, or `NULL`. - * @param[out] ypos Where to store the y-coordinate of the upper-left corner of - * the client area, or `NULL`. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref window_pos - * @sa glfwSetWindowPos - * - * @since Added in GLFW 3.0. - * - * @ingroup window - */ -GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos); - -/*! @brief Sets the position of the client area of the specified window. - * - * This function sets the position, in screen coordinates, of the upper-left - * corner of the client area of the specified windowed mode window. If the - * window is a full screen window, this function does nothing. - * - * __Do not use this function__ to move an already visible window unless you - * have very good reasons for doing so, as it will confuse and annoy the user. - * - * The window manager may put limits on what positions are allowed. GLFW - * cannot and should not override these limits. - * - * @param[in] window The window to query. - * @param[in] xpos The x-coordinate of the upper-left corner of the client area. - * @param[in] ypos The y-coordinate of the upper-left corner of the client area. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref window_pos - * @sa glfwGetWindowPos - * - * @since Added in GLFW 1.0. - * - * @par - * __GLFW 3:__ Added window handle parameter. - * - * @ingroup window - */ -GLFWAPI void glfwSetWindowPos(GLFWwindow* window, int xpos, int ypos); - -/*! @brief Retrieves the size of the client area of the specified window. - * - * This function retrieves the size, in screen coordinates, of the client area - * of the specified window. If you wish to retrieve the size of the - * framebuffer of the window in pixels, see @ref glfwGetFramebufferSize. - * - * Any or all of the size arguments may be `NULL`. If an error occurs, all - * non-`NULL` size arguments will be set to zero. - * - * @param[in] window The window whose size to retrieve. - * @param[out] width Where to store the width, in screen coordinates, of the - * client area, or `NULL`. - * @param[out] height Where to store the height, in screen coordinates, of the - * client area, or `NULL`. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref window_size - * @sa glfwSetWindowSize - * - * @since Added in GLFW 1.0. - * - * @par - * __GLFW 3:__ Added window handle parameter. - * - * @ingroup window - */ -GLFWAPI void glfwGetWindowSize(GLFWwindow* window, int* width, int* height); - -/*! @brief Sets the size of the client area of the specified window. - * - * This function sets the size, in screen coordinates, of the client area of - * the specified window. - * - * For full screen windows, this function selects and switches to the resolution - * closest to the specified size, without affecting the window's context. As - * the context is unaffected, the bit depths of the framebuffer remain - * unchanged. - * - * The window manager may put limits on what sizes are allowed. GLFW cannot - * and should not override these limits. - * - * @param[in] window The window to resize. - * @param[in] width The desired width of the specified window. - * @param[in] height The desired height of the specified window. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref window_size - * @sa glfwGetWindowSize - * - * @since Added in GLFW 1.0. - * - * @par - * __GLFW 3:__ Added window handle parameter. - * - * @ingroup window - */ -GLFWAPI void glfwSetWindowSize(GLFWwindow* window, int width, int height); - -/*! @brief Retrieves the size of the framebuffer of the specified window. - * - * This function retrieves the size, in pixels, of the framebuffer of the - * specified window. If you wish to retrieve the size of the window in screen - * coordinates, see @ref glfwGetWindowSize. - * - * Any or all of the size arguments may be `NULL`. If an error occurs, all - * non-`NULL` size arguments will be set to zero. - * - * @param[in] window The window whose framebuffer to query. - * @param[out] width Where to store the width, in pixels, of the framebuffer, - * or `NULL`. - * @param[out] height Where to store the height, in pixels, of the framebuffer, - * or `NULL`. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref window_fbsize - * @sa glfwSetFramebufferSizeCallback - * - * @since Added in GLFW 3.0. - * - * @ingroup window - */ -GLFWAPI void glfwGetFramebufferSize(GLFWwindow* window, int* width, int* height); - -/*! @brief Retrieves the size of the frame of the window. - * - * This function retrieves the size, in screen coordinates, of each edge of the - * frame of the specified window. This size includes the title bar, if the - * window has one. The size of the frame may vary depending on the - * [window-related hints](@ref window_hints_wnd) used to create it. - * - * Because this function retrieves the size of each window frame edge and not - * the offset along a particular coordinate axis, the retrieved values will - * always be zero or positive. - * - * Any or all of the size arguments may be `NULL`. If an error occurs, all - * non-`NULL` size arguments will be set to zero. - * - * @param[in] window The window whose frame size to query. - * @param[out] left Where to store the size, in screen coordinates, of the left - * edge of the window frame, or `NULL`. - * @param[out] top Where to store the size, in screen coordinates, of the top - * edge of the window frame, or `NULL`. - * @param[out] right Where to store the size, in screen coordinates, of the - * right edge of the window frame, or `NULL`. - * @param[out] bottom Where to store the size, in screen coordinates, of the - * bottom edge of the window frame, or `NULL`. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref window_size - * - * @since Added in GLFW 3.1. - * - * @ingroup window - */ -GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* window, int* left, int* top, int* right, int* bottom); - -/*! @brief Iconifies the specified window. - * - * This function iconifies (minimizes) the specified window if it was - * previously restored. If the window is already iconified, this function does - * nothing. - * - * If the specified window is a full screen window, the original monitor - * resolution is restored until the window is restored. - * - * @param[in] window The window to iconify. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref window_iconify - * @sa glfwRestoreWindow - * - * @since Added in GLFW 2.1. - * - * @par - * __GLFW 3:__ Added window handle parameter. - * - * @ingroup window - */ -GLFWAPI void glfwIconifyWindow(GLFWwindow* window); - -/*! @brief Restores the specified window. - * - * This function restores the specified window if it was previously iconified - * (minimized). If the window is already restored, this function does nothing. - * - * If the specified window is a full screen window, the resolution chosen for - * the window is restored on the selected monitor. - * - * @param[in] window The window to restore. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref window_iconify - * @sa glfwIconifyWindow - * - * @since Added in GLFW 2.1. - * - * @par - * __GLFW 3:__ Added window handle parameter. - * - * @ingroup window - */ -GLFWAPI void glfwRestoreWindow(GLFWwindow* window); - -/*! @brief Makes the specified window visible. - * - * This function makes the specified window visible if it was previously - * hidden. If the window is already visible or is in full screen mode, this - * function does nothing. - * - * @param[in] window The window to make visible. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref window_hide - * @sa glfwHideWindow - * - * @since Added in GLFW 3.0. - * - * @ingroup window - */ -GLFWAPI void glfwShowWindow(GLFWwindow* window); - -/*! @brief Hides the specified window. - * - * This function hides the specified window if it was previously visible. If - * the window is already hidden or is in full screen mode, this function does - * nothing. - * - * @param[in] window The window to hide. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref window_hide - * @sa glfwShowWindow - * - * @since Added in GLFW 3.0. - * - * @ingroup window - */ -GLFWAPI void glfwHideWindow(GLFWwindow* window); - -/*! @brief Returns the monitor that the window uses for full screen mode. - * - * This function returns the handle of the monitor that the specified window is - * in full screen on. - * - * @param[in] window The window to query. - * @return The monitor, or `NULL` if the window is in windowed mode or an error - * occurred. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref window_monitor - * - * @since Added in GLFW 3.0. - * - * @ingroup window - */ -GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* window); - -/*! @brief Returns an attribute of the specified window. - * - * This function returns the value of an attribute of the specified window or - * its OpenGL or OpenGL ES context. - * - * @param[in] window The window to query. - * @param[in] attrib The [window attribute](@ref window_attribs) whose value to - * return. - * @return The value of the attribute, or zero if an - * [error](@ref error_handling) occurred. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref window_attribs - * - * @since Added in GLFW 3.0. Replaces `glfwGetWindowParam` and - * `glfwGetGLVersion`. - * - * @ingroup window - */ -GLFWAPI int glfwGetWindowAttrib(GLFWwindow* window, int attrib); - -/*! @brief Sets the user pointer of the specified window. - * - * This function sets the user-defined pointer of the specified window. The - * current value is retained until the window is destroyed. The initial value - * is `NULL`. - * - * @param[in] window The window whose pointer to set. - * @param[in] pointer The new value. - * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. - * - * @sa @ref window_userptr - * @sa glfwGetWindowUserPointer - * - * @since Added in GLFW 3.0. - * - * @ingroup window - */ -GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* window, void* pointer); - -/*! @brief Returns the user pointer of the specified window. - * - * This function returns the current value of the user-defined pointer of the - * specified window. The initial value is `NULL`. - * - * @param[in] window The window whose pointer to return. - * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. - * - * @sa @ref window_userptr - * @sa glfwSetWindowUserPointer - * - * @since Added in GLFW 3.0. - * - * @ingroup window - */ -GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* window); - -/*! @brief Sets the position callback for the specified window. - * - * This function sets the position callback of the specified window, which is - * called when the window is moved. The callback is provided with the screen - * position of the upper-left corner of the client area of the window. - * - * @param[in] window The window whose callback to set. - * @param[in] cbfun The new callback, or `NULL` to remove the currently set - * callback. - * @return The previously set callback, or `NULL` if no callback was set or the - * library had not been [initialized](@ref intro_init). - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref window_pos - * - * @since Added in GLFW 3.0. - * - * @ingroup window - */ -GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* window, GLFWwindowposfun cbfun); - -/*! @brief Sets the size callback for the specified window. - * - * This function sets the size callback of the specified window, which is - * called when the window is resized. The callback is provided with the size, - * in screen coordinates, of the client area of the window. - * - * @param[in] window The window whose callback to set. - * @param[in] cbfun The new callback, or `NULL` to remove the currently set - * callback. - * @return The previously set callback, or `NULL` if no callback was set or the - * library had not been [initialized](@ref intro_init). - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref window_size - * - * @since Added in GLFW 1.0. - * - * @par - * __GLFW 3:__ Added window handle parameter. Updated callback signature. - * - * @ingroup window - */ -GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* window, GLFWwindowsizefun cbfun); - -/*! @brief Sets the close callback for the specified window. - * - * This function sets the close callback of the specified window, which is - * called when the user attempts to close the window, for example by clicking - * the close widget in the title bar. - * - * The close flag is set before this callback is called, but you can modify it - * at any time with @ref glfwSetWindowShouldClose. - * - * The close callback is not triggered by @ref glfwDestroyWindow. - * - * @param[in] window The window whose callback to set. - * @param[in] cbfun The new callback, or `NULL` to remove the currently set - * callback. - * @return The previously set callback, or `NULL` if no callback was set or the - * library had not been [initialized](@ref intro_init). - * - * @remarks __OS X:__ Selecting Quit from the application menu will - * trigger the close callback for all windows. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref window_close - * - * @since Added in GLFW 2.5. - * - * @par - * __GLFW 3:__ Added window handle parameter. Updated callback signature. - * - * @ingroup window - */ -GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* window, GLFWwindowclosefun cbfun); - -/*! @brief Sets the refresh callback for the specified window. - * - * This function sets the refresh callback of the specified window, which is - * called when the client area of the window needs to be redrawn, for example - * if the window has been exposed after having been covered by another window. - * - * On compositing window systems such as Aero, Compiz or Aqua, where the window - * contents are saved off-screen, this callback may be called only very - * infrequently or never at all. - * - * @param[in] window The window whose callback to set. - * @param[in] cbfun The new callback, or `NULL` to remove the currently set - * callback. - * @return The previously set callback, or `NULL` if no callback was set or the - * library had not been [initialized](@ref intro_init). - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref window_refresh - * - * @since Added in GLFW 2.5. - * - * @par - * __GLFW 3:__ Added window handle parameter. Updated callback signature. - * - * @ingroup window - */ -GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* window, GLFWwindowrefreshfun cbfun); - -/*! @brief Sets the focus callback for the specified window. - * - * This function sets the focus callback of the specified window, which is - * called when the window gains or loses input focus. - * - * After the focus callback is called for a window that lost input focus, - * synthetic key and mouse button release events will be generated for all such - * that had been pressed. For more information, see @ref glfwSetKeyCallback - * and @ref glfwSetMouseButtonCallback. - * - * @param[in] window The window whose callback to set. - * @param[in] cbfun The new callback, or `NULL` to remove the currently set - * callback. - * @return The previously set callback, or `NULL` if no callback was set or the - * library had not been [initialized](@ref intro_init). - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref window_focus - * - * @since Added in GLFW 3.0. - * - * @ingroup window - */ -GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* window, GLFWwindowfocusfun cbfun); - -/*! @brief Sets the iconify callback for the specified window. - * - * This function sets the iconification callback of the specified window, which - * is called when the window is iconified or restored. - * - * @param[in] window The window whose callback to set. - * @param[in] cbfun The new callback, or `NULL` to remove the currently set - * callback. - * @return The previously set callback, or `NULL` if no callback was set or the - * library had not been [initialized](@ref intro_init). - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref window_iconify - * - * @since Added in GLFW 3.0. - * - * @ingroup window - */ -GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* window, GLFWwindowiconifyfun cbfun); - -/*! @brief Sets the framebuffer resize callback for the specified window. - * - * This function sets the framebuffer resize callback of the specified window, - * which is called when the framebuffer of the specified window is resized. - * - * @param[in] window The window whose callback to set. - * @param[in] cbfun The new callback, or `NULL` to remove the currently set - * callback. - * @return The previously set callback, or `NULL` if no callback was set or the - * library had not been [initialized](@ref intro_init). - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref window_fbsize - * - * @since Added in GLFW 3.0. - * - * @ingroup window - */ -GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* window, GLFWframebuffersizefun cbfun); - -/*! @brief Processes all pending events. - * - * This function processes only those events that are already in the event - * queue and then returns immediately. Processing events will cause the window - * and input callbacks associated with those events to be called. - * - * On some platforms, a window move, resize or menu operation will cause event - * processing to block. This is due to how event processing is designed on - * those platforms. You can use the - * [window refresh callback](@ref window_refresh) to redraw the contents of - * your window when necessary during such operations. - * - * On some platforms, certain events are sent directly to the application - * without going through the event queue, causing callbacks to be called - * outside of a call to one of the event processing functions. - * - * Event processing is not required for joystick input to work. - * - * @par Reentrancy - * This function may not be called from a callback. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref events - * @sa glfwWaitEvents - * - * @since Added in GLFW 1.0. - * - * @ingroup window - */ -GLFWAPI void glfwPollEvents(void); - -/*! @brief Waits until events are queued and processes them. - * - * This function puts the calling thread to sleep until at least one event is - * available in the event queue. Once one or more events are available, - * it behaves exactly like @ref glfwPollEvents, i.e. the events in the queue - * are processed and the function then returns immediately. Processing events - * will cause the window and input callbacks associated with those events to be - * called. - * - * Since not all events are associated with callbacks, this function may return - * without a callback having been called even if you are monitoring all - * callbacks. - * - * On some platforms, a window move, resize or menu operation will cause event - * processing to block. This is due to how event processing is designed on - * those platforms. You can use the - * [window refresh callback](@ref window_refresh) to redraw the contents of - * your window when necessary during such operations. - * - * On some platforms, certain callbacks may be called outside of a call to one - * of the event processing functions. - * - * If no windows exist, this function returns immediately. For synchronization - * of threads in applications that do not create windows, use your threading - * library of choice. - * - * Event processing is not required for joystick input to work. - * - * @par Reentrancy - * This function may not be called from a callback. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref events - * @sa glfwPollEvents - * - * @since Added in GLFW 2.5. - * - * @ingroup window - */ -GLFWAPI void glfwWaitEvents(void); - -/*! @brief Posts an empty event to the event queue. - * - * This function posts an empty event from the current thread to the event - * queue, causing @ref glfwWaitEvents to return. - * - * If no windows exist, this function returns immediately. For synchronization - * of threads in applications that do not create windows, use your threading - * library of choice. - * - * @par Thread Safety - * This function may be called from any thread. - * - * @sa @ref events - * @sa glfwWaitEvents - * - * @since Added in GLFW 3.1. - * - * @ingroup window - */ -GLFWAPI void glfwPostEmptyEvent(void); - -/*! @brief Returns the value of an input option for the specified window. - * - * This function returns the value of an input option for the specified window. - * The mode must be one of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or - * `GLFW_STICKY_MOUSE_BUTTONS`. - * - * @param[in] window The window to query. - * @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or - * `GLFW_STICKY_MOUSE_BUTTONS`. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa glfwSetInputMode - * - * @since Added in GLFW 3.0. - * - * @ingroup input - */ -GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode); - -/*! @brief Sets an input option for the specified window. - * - * This function sets an input mode option for the specified window. The mode - * must be one of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or - * `GLFW_STICKY_MOUSE_BUTTONS`. - * - * If the mode is `GLFW_CURSOR`, the value must be one of the following cursor - * modes: - * - `GLFW_CURSOR_NORMAL` makes the cursor visible and behaving normally. - * - `GLFW_CURSOR_HIDDEN` makes the cursor invisible when it is over the client - * area of the window but does not restrict the cursor from leaving. - * - `GLFW_CURSOR_DISABLED` hides and grabs the cursor, providing virtual - * and unlimited cursor movement. This is useful for implementing for - * example 3D camera controls. - * - * If the mode is `GLFW_STICKY_KEYS`, the value must be either `GL_TRUE` to - * enable sticky keys, or `GL_FALSE` to disable it. If sticky keys are - * enabled, a key press will ensure that @ref glfwGetKey returns `GLFW_PRESS` - * the next time it is called even if the key had been released before the - * call. This is useful when you are only interested in whether keys have been - * pressed but not when or in which order. - * - * If the mode is `GLFW_STICKY_MOUSE_BUTTONS`, the value must be either - * `GL_TRUE` to enable sticky mouse buttons, or `GL_FALSE` to disable it. If - * sticky mouse buttons are enabled, a mouse button press will ensure that @ref - * glfwGetMouseButton returns `GLFW_PRESS` the next time it is called even if - * the mouse button had been released before the call. This is useful when you - * are only interested in whether mouse buttons have been pressed but not when - * or in which order. - * - * @param[in] window The window whose input mode to set. - * @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or - * `GLFW_STICKY_MOUSE_BUTTONS`. - * @param[in] value The new value of the specified input mode. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa glfwGetInputMode - * - * @since Added in GLFW 3.0. Replaces `glfwEnable` and `glfwDisable`. - * - * @ingroup input - */ -GLFWAPI void glfwSetInputMode(GLFWwindow* window, int mode, int value); - -/*! @brief Returns the last reported state of a keyboard key for the specified - * window. - * - * This function returns the last state reported for the specified key to the - * specified window. The returned state is one of `GLFW_PRESS` or - * `GLFW_RELEASE`. The higher-level action `GLFW_REPEAT` is only reported to - * the key callback. - * - * If the `GLFW_STICKY_KEYS` input mode is enabled, this function returns - * `GLFW_PRESS` the first time you call it for a key that was pressed, even if - * that key has already been released. - * - * The key functions deal with physical keys, with [key tokens](@ref keys) - * named after their use on the standard US keyboard layout. If you want to - * input text, use the Unicode character callback instead. - * - * The [modifier key bit masks](@ref mods) are not key tokens and cannot be - * used with this function. - * - * @param[in] window The desired window. - * @param[in] key The desired [keyboard key](@ref keys). `GLFW_KEY_UNKNOWN` is - * not a valid key for this function. - * @return One of `GLFW_PRESS` or `GLFW_RELEASE`. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref input_key - * - * @since Added in GLFW 1.0. - * - * @par - * __GLFW 3:__ Added window handle parameter. - * - * @ingroup input - */ -GLFWAPI int glfwGetKey(GLFWwindow* window, int key); - -/*! @brief Returns the last reported state of a mouse button for the specified - * window. - * - * This function returns the last state reported for the specified mouse button - * to the specified window. The returned state is one of `GLFW_PRESS` or - * `GLFW_RELEASE`. - * - * If the `GLFW_STICKY_MOUSE_BUTTONS` input mode is enabled, this function - * `GLFW_PRESS` the first time you call it for a mouse button that was pressed, - * even if that mouse button has already been released. - * - * @param[in] window The desired window. - * @param[in] button The desired [mouse button](@ref buttons). - * @return One of `GLFW_PRESS` or `GLFW_RELEASE`. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref input_mouse_button - * - * @since Added in GLFW 1.0. - * - * @par - * __GLFW 3:__ Added window handle parameter. - * - * @ingroup input - */ -GLFWAPI int glfwGetMouseButton(GLFWwindow* window, int button); - -/*! @brief Retrieves the position of the cursor relative to the client area of - * the window. - * - * This function returns the position of the cursor, in screen coordinates, - * relative to the upper-left corner of the client area of the specified - * window. - * - * If the cursor is disabled (with `GLFW_CURSOR_DISABLED`) then the cursor - * position is unbounded and limited only by the minimum and maximum values of - * a `double`. - * - * The coordinate can be converted to their integer equivalents with the - * `floor` function. Casting directly to an integer type works for positive - * coordinates, but fails for negative ones. - * - * Any or all of the position arguments may be `NULL`. If an error occurs, all - * non-`NULL` position arguments will be set to zero. - * - * @param[in] window The desired window. - * @param[out] xpos Where to store the cursor x-coordinate, relative to the - * left edge of the client area, or `NULL`. - * @param[out] ypos Where to store the cursor y-coordinate, relative to the to - * top edge of the client area, or `NULL`. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref cursor_pos - * @sa glfwSetCursorPos - * - * @since Added in GLFW 3.0. Replaces `glfwGetMousePos`. - * - * @ingroup input - */ -GLFWAPI void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos); - -/*! @brief Sets the position of the cursor, relative to the client area of the - * window. - * - * This function sets the position, in screen coordinates, of the cursor - * relative to the upper-left corner of the client area of the specified - * window. The window must have input focus. If the window does not have - * input focus when this function is called, it fails silently. - * - * __Do not use this function__ to implement things like camera controls. GLFW - * already provides the `GLFW_CURSOR_DISABLED` cursor mode that hides the - * cursor, transparently re-centers it and provides unconstrained cursor - * motion. See @ref glfwSetInputMode for more information. - * - * If the cursor mode is `GLFW_CURSOR_DISABLED` then the cursor position is - * unconstrained and limited only by the minimum and maximum values of - * a `double`. - * - * @param[in] window The desired window. - * @param[in] xpos The desired x-coordinate, relative to the left edge of the - * client area. - * @param[in] ypos The desired y-coordinate, relative to the top edge of the - * client area. - * - * @remarks __X11:__ Due to the asynchronous nature of a modern X desktop, it - * may take a moment for the window focus event to arrive. This means you will - * not be able to set the cursor position directly after window creation. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref cursor_pos - * @sa glfwGetCursorPos - * - * @since Added in GLFW 3.0. Replaces `glfwSetMousePos`. - * - * @ingroup input - */ -GLFWAPI void glfwSetCursorPos(GLFWwindow* window, double xpos, double ypos); - -/*! @brief Creates a custom cursor. - * - * Creates a new custom cursor image that can be set for a window with @ref - * glfwSetCursor. The cursor can be destroyed with @ref glfwDestroyCursor. - * Any remaining cursors are destroyed by @ref glfwTerminate. - * - * The pixels are 32-bit little-endian RGBA, i.e. eight bits per channel. They - * are arranged canonically as packed sequential rows, starting from the - * top-left corner. - * - * The cursor hotspot is specified in pixels, relative to the upper-left corner - * of the cursor image. Like all other coordinate systems in GLFW, the X-axis - * points to the right and the Y-axis points down. - * - * @param[in] image The desired cursor image. - * @param[in] xhot The desired x-coordinate, in pixels, of the cursor hotspot. - * @param[in] yhot The desired y-coordinate, in pixels, of the cursor hotspot. - * - * @return The handle of the created cursor, or `NULL` if an - * [error](@ref error_handling) occurred. - * - * @par Pointer Lifetime - * The specified image data is copied before this function returns. - * - * @par Reentrancy - * This function may not be called from a callback. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref cursor_object - * @sa glfwDestroyCursor - * @sa glfwCreateStandardCursor - * - * @since Added in GLFW 3.1. - * - * @ingroup input - */ -GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot); - -/*! @brief Creates a cursor with a standard shape. - * - * Returns a cursor with a [standard shape](@ref shapes), that can be set for - * a window with @ref glfwSetCursor. - * - * @param[in] shape One of the [standard shapes](@ref shapes). - * - * @return A new cursor ready to use or `NULL` if an - * [error](@ref error_handling) occurred. - * - * @par Reentrancy - * This function may not be called from a callback. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref cursor_object - * @sa glfwCreateCursor - * - * @since Added in GLFW 3.1. - * - * @ingroup input - */ -GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape); - -/*! @brief Destroys a cursor. - * - * This function destroys a cursor previously created with @ref - * glfwCreateCursor. Any remaining cursors will be destroyed by @ref - * glfwTerminate. - * - * @param[in] cursor The cursor object to destroy. - * - * @par Reentrancy - * This function may not be called from a callback. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref cursor_object - * @sa glfwCreateCursor - * - * @since Added in GLFW 3.1. - * - * @ingroup input - */ -GLFWAPI void glfwDestroyCursor(GLFWcursor* cursor); - -/*! @brief Sets the cursor for the window. - * - * This function sets the cursor image to be used when the cursor is over the - * client area of the specified window. The set cursor will only be visible - * when the [cursor mode](@ref cursor_mode) of the window is - * `GLFW_CURSOR_NORMAL`. - * - * On some platforms, the set cursor may not be visible unless the window also - * has input focus. - * - * @param[in] window The window to set the cursor for. - * @param[in] cursor The cursor to set, or `NULL` to switch back to the default - * arrow cursor. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref cursor_object - * - * @since Added in GLFW 3.1. - * - * @ingroup input - */ -GLFWAPI void glfwSetCursor(GLFWwindow* window, GLFWcursor* cursor); - -/*! @brief Sets the key callback. - * - * This function sets the key callback of the specified window, which is called - * when a key is pressed, repeated or released. - * - * The key functions deal with physical keys, with layout independent - * [key tokens](@ref keys) named after their values in the standard US keyboard - * layout. If you want to input text, use the - * [character callback](@ref glfwSetCharCallback) instead. - * - * When a window loses input focus, it will generate synthetic key release - * events for all pressed keys. You can tell these events from user-generated - * events by the fact that the synthetic ones are generated after the focus - * loss event has been processed, i.e. after the - * [window focus callback](@ref glfwSetWindowFocusCallback) has been called. - * - * The scancode of a key is specific to that platform or sometimes even to that - * machine. Scancodes are intended to allow users to bind keys that don't have - * a GLFW key token. Such keys have `key` set to `GLFW_KEY_UNKNOWN`, their - * state is not saved and so it cannot be queried with @ref glfwGetKey. - * - * Sometimes GLFW needs to generate synthetic key events, in which case the - * scancode may be zero. - * - * @param[in] window The window whose callback to set. - * @param[in] cbfun The new key callback, or `NULL` to remove the currently - * set callback. - * @return The previously set callback, or `NULL` if no callback was set or the - * library had not been [initialized](@ref intro_init). - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref input_key - * - * @since Added in GLFW 1.0. - * - * @par - * __GLFW 3:__ Added window handle parameter. Updated callback signature. - * - * @ingroup input - */ -GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* window, GLFWkeyfun cbfun); - -/*! @brief Sets the Unicode character callback. - * - * This function sets the character callback of the specified window, which is - * called when a Unicode character is input. - * - * The character callback is intended for Unicode text input. As it deals with - * characters, it is keyboard layout dependent, whereas the - * [key callback](@ref glfwSetKeyCallback) is not. Characters do not map 1:1 - * to physical keys, as a key may produce zero, one or more characters. If you - * want to know whether a specific physical key was pressed or released, see - * the key callback instead. - * - * The character callback behaves as system text input normally does and will - * not be called if modifier keys are held down that would prevent normal text - * input on that platform, for example a Super (Command) key on OS X or Alt key - * on Windows. There is a - * [character with modifiers callback](@ref glfwSetCharModsCallback) that - * receives these events. - * - * @param[in] window The window whose callback to set. - * @param[in] cbfun The new callback, or `NULL` to remove the currently set - * callback. - * @return The previously set callback, or `NULL` if no callback was set or the - * library had not been [initialized](@ref intro_init). - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref input_char - * - * @since Added in GLFW 2.4. - * - * @par - * __GLFW 3:__ Added window handle parameter. Updated callback signature. - * - * @ingroup input - */ -GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* window, GLFWcharfun cbfun); - -/*! @brief Sets the Unicode character with modifiers callback. - * - * This function sets the character with modifiers callback of the specified - * window, which is called when a Unicode character is input regardless of what - * modifier keys are used. - * - * The character with modifiers callback is intended for implementing custom - * Unicode character input. For regular Unicode text input, see the - * [character callback](@ref glfwSetCharCallback). Like the character - * callback, the character with modifiers callback deals with characters and is - * keyboard layout dependent. Characters do not map 1:1 to physical keys, as - * a key may produce zero, one or more characters. If you want to know whether - * a specific physical key was pressed or released, see the - * [key callback](@ref glfwSetKeyCallback) instead. - * - * @param[in] window The window whose callback to set. - * @param[in] cbfun The new callback, or `NULL` to remove the currently set - * callback. - * @return The previously set callback, or `NULL` if no callback was set or an - * error occurred. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref input_char - * - * @since Added in GLFW 3.1. - * - * @ingroup input - */ -GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* window, GLFWcharmodsfun cbfun); - -/*! @brief Sets the mouse button callback. - * - * This function sets the mouse button callback of the specified window, which - * is called when a mouse button is pressed or released. - * - * When a window loses input focus, it will generate synthetic mouse button - * release events for all pressed mouse buttons. You can tell these events - * from user-generated events by the fact that the synthetic ones are generated - * after the focus loss event has been processed, i.e. after the - * [window focus callback](@ref glfwSetWindowFocusCallback) has been called. - * - * @param[in] window The window whose callback to set. - * @param[in] cbfun The new callback, or `NULL` to remove the currently set - * callback. - * @return The previously set callback, or `NULL` if no callback was set or the - * library had not been [initialized](@ref intro_init). - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref input_mouse_button - * - * @since Added in GLFW 1.0. - * - * @par - * __GLFW 3:__ Added window handle parameter. Updated callback signature. - * - * @ingroup input - */ -GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* window, GLFWmousebuttonfun cbfun); - -/*! @brief Sets the cursor position callback. - * - * This function sets the cursor position callback of the specified window, - * which is called when the cursor is moved. The callback is provided with the - * position, in screen coordinates, relative to the upper-left corner of the - * client area of the window. - * - * @param[in] window The window whose callback to set. - * @param[in] cbfun The new callback, or `NULL` to remove the currently set - * callback. - * @return The previously set callback, or `NULL` if no callback was set or the - * library had not been [initialized](@ref intro_init). - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref cursor_pos - * - * @since Added in GLFW 3.0. Replaces `glfwSetMousePosCallback`. - * - * @ingroup input - */ -GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* window, GLFWcursorposfun cbfun); - -/*! @brief Sets the cursor enter/exit callback. - * - * This function sets the cursor boundary crossing callback of the specified - * window, which is called when the cursor enters or leaves the client area of - * the window. - * - * @param[in] window The window whose callback to set. - * @param[in] cbfun The new callback, or `NULL` to remove the currently set - * callback. - * @return The previously set callback, or `NULL` if no callback was set or the - * library had not been [initialized](@ref intro_init). - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref cursor_enter - * - * @since Added in GLFW 3.0. - * - * @ingroup input - */ -GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* window, GLFWcursorenterfun cbfun); - -/*! @brief Sets the scroll callback. - * - * This function sets the scroll callback of the specified window, which is - * called when a scrolling device is used, such as a mouse wheel or scrolling - * area of a touchpad. - * - * The scroll callback receives all scrolling input, like that from a mouse - * wheel or a touchpad scrolling area. - * - * @param[in] window The window whose callback to set. - * @param[in] cbfun The new scroll callback, or `NULL` to remove the currently - * set callback. - * @return The previously set callback, or `NULL` if no callback was set or the - * library had not been [initialized](@ref intro_init). - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref scrolling - * - * @since Added in GLFW 3.0. Replaces `glfwSetMouseWheelCallback`. - * - * @ingroup input - */ -GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* window, GLFWscrollfun cbfun); - -/*! @brief Sets the file drop callback. - * - * This function sets the file drop callback of the specified window, which is - * called when one or more dragged files are dropped on the window. - * - * Because the path array and its strings may have been generated specifically - * for that event, they are not guaranteed to be valid after the callback has - * returned. If you wish to use them after the callback returns, you need to - * make a deep copy. - * - * @param[in] window The window whose callback to set. - * @param[in] cbfun The new file drop callback, or `NULL` to remove the - * currently set callback. - * @return The previously set callback, or `NULL` if no callback was set or the - * library had not been [initialized](@ref intro_init). - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref path_drop - * - * @since Added in GLFW 3.1. - * - * @ingroup input - */ -GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* window, GLFWdropfun cbfun); - -/*! @brief Returns whether the specified joystick is present. - * - * This function returns whether the specified joystick is present. - * - * @param[in] joy The [joystick](@ref joysticks) to query. - * @return `GL_TRUE` if the joystick is present, or `GL_FALSE` otherwise. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref joystick - * - * @since Added in GLFW 3.0. Replaces `glfwGetJoystickParam`. - * - * @ingroup input - */ -GLFWAPI int glfwJoystickPresent(int joy); - -/*! @brief Returns the values of all axes of the specified joystick. - * - * This function returns the values of all axes of the specified joystick. - * Each element in the array is a value between -1.0 and 1.0. - * - * @param[in] joy The [joystick](@ref joysticks) to query. - * @param[out] count Where to store the number of axis values in the returned - * array. This is set to zero if an error occurred. - * @return An array of axis values, or `NULL` if the joystick is not present. - * - * @par Pointer Lifetime - * The returned array is allocated and freed by GLFW. You should not free it - * yourself. It is valid until the specified joystick is disconnected, this - * function is called again for that joystick or the library is terminated. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref joystick_axis - * - * @since Added in GLFW 3.0. Replaces `glfwGetJoystickPos`. - * - * @ingroup input - */ -GLFWAPI const float* glfwGetJoystickAxes(int joy, int* count); - -/*! @brief Returns the state of all buttons of the specified joystick. - * - * This function returns the state of all buttons of the specified joystick. - * Each element in the array is either `GLFW_PRESS` or `GLFW_RELEASE`. - * - * @param[in] joy The [joystick](@ref joysticks) to query. - * @param[out] count Where to store the number of button states in the returned - * array. This is set to zero if an error occurred. - * @return An array of button states, or `NULL` if the joystick is not present. - * - * @par Pointer Lifetime - * The returned array is allocated and freed by GLFW. You should not free it - * yourself. It is valid until the specified joystick is disconnected, this - * function is called again for that joystick or the library is terminated. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref joystick_button - * - * @since Added in GLFW 2.2. - * - * @par - * __GLFW 3:__ Changed to return a dynamic array. - * - * @ingroup input - */ -GLFWAPI const unsigned char* glfwGetJoystickButtons(int joy, int* count); - -/*! @brief Returns the name of the specified joystick. - * - * This function returns the name, encoded as UTF-8, of the specified joystick. - * The returned string is allocated and freed by GLFW. You should not free it - * yourself. - * - * @param[in] joy The [joystick](@ref joysticks) to query. - * @return The UTF-8 encoded name of the joystick, or `NULL` if the joystick - * is not present. - * - * @par Pointer Lifetime - * The returned string is allocated and freed by GLFW. You should not free it - * yourself. It is valid until the specified joystick is disconnected, this - * function is called again for that joystick or the library is terminated. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref joystick_name - * - * @since Added in GLFW 3.0. - * - * @ingroup input - */ -GLFWAPI const char* glfwGetJoystickName(int joy); - -/*! @brief Sets the clipboard to the specified string. - * - * This function sets the system clipboard to the specified, UTF-8 encoded - * string. - * - * @param[in] window The window that will own the clipboard contents. - * @param[in] string A UTF-8 encoded string. - * - * @par Pointer Lifetime - * The specified string is copied before this function returns. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref clipboard - * @sa glfwGetClipboardString - * - * @since Added in GLFW 3.0. - * - * @ingroup input - */ -GLFWAPI void glfwSetClipboardString(GLFWwindow* window, const char* string); - -/*! @brief Returns the contents of the clipboard as a string. - * - * This function returns the contents of the system clipboard, if it contains - * or is convertible to a UTF-8 encoded string. - * - * @param[in] window The window that will request the clipboard contents. - * @return The contents of the clipboard as a UTF-8 encoded string, or `NULL` - * if an [error](@ref error_handling) occurred. - * - * @par Pointer Lifetime - * The returned string is allocated and freed by GLFW. You should not free it - * yourself. It is valid until the next call to @ref - * glfwGetClipboardString or @ref glfwSetClipboardString, or until the library - * is terminated. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref clipboard - * @sa glfwSetClipboardString - * - * @since Added in GLFW 3.0. - * - * @ingroup input - */ -GLFWAPI const char* glfwGetClipboardString(GLFWwindow* window); - -/*! @brief Returns the value of the GLFW timer. - * - * This function returns the value of the GLFW timer. Unless the timer has - * been set using @ref glfwSetTime, the timer measures time elapsed since GLFW - * was initialized. - * - * The resolution of the timer is system dependent, but is usually on the order - * of a few micro- or nanoseconds. It uses the highest-resolution monotonic - * time source on each supported platform. - * - * @return The current value, in seconds, or zero if an - * [error](@ref error_handling) occurred. - * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. - * - * @sa @ref time - * - * @since Added in GLFW 1.0. - * - * @ingroup input - */ -GLFWAPI double glfwGetTime(void); - -/*! @brief Sets the GLFW timer. - * - * This function sets the value of the GLFW timer. It then continues to count - * up from that value. - * - * @param[in] time The new value, in seconds. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref time - * - * @since Added in GLFW 2.2. - * - * @ingroup input - */ -GLFWAPI void glfwSetTime(double time); - -/*! @brief Makes the context of the specified window current for the calling - * thread. - * - * This function makes the OpenGL or OpenGL ES context of the specified window - * current on the calling thread. A context can only be made current on - * a single thread at a time and each thread can have only a single current - * context at a time. - * - * By default, making a context non-current implicitly forces a pipeline flush. - * On machines that support `GL_KHR_context_flush_control`, you can control - * whether a context performs this flush by setting the - * [GLFW_CONTEXT_RELEASE_BEHAVIOR](@ref window_hints_ctx) window hint. - * - * @param[in] window The window whose context to make current, or `NULL` to - * detach the current context. - * - * @par Thread Safety - * This function may be called from any thread. - * - * @sa @ref context_current - * @sa glfwGetCurrentContext - * - * @since Added in GLFW 3.0. - * - * @ingroup context - */ -GLFWAPI void glfwMakeContextCurrent(GLFWwindow* window); - -/*! @brief Returns the window whose context is current on the calling thread. - * - * This function returns the window whose OpenGL or OpenGL ES context is - * current on the calling thread. - * - * @return The window whose context is current, or `NULL` if no window's - * context is current. - * - * @par Thread Safety - * This function may be called from any thread. - * - * @sa @ref context_current - * @sa glfwMakeContextCurrent - * - * @since Added in GLFW 3.0. - * - * @ingroup context - */ -GLFWAPI GLFWwindow* glfwGetCurrentContext(void); - -/*! @brief Swaps the front and back buffers of the specified window. - * - * This function swaps the front and back buffers of the specified window. If - * the swap interval is greater than zero, the GPU driver waits the specified - * number of screen updates before swapping the buffers. - * - * @param[in] window The window whose buffers to swap. - * - * @par Thread Safety - * This function may be called from any thread. - * - * @sa @ref buffer_swap - * @sa glfwSwapInterval - * - * @since Added in GLFW 1.0. - * - * @par - * __GLFW 3:__ Added window handle parameter. - * - * @ingroup window - */ -GLFWAPI void glfwSwapBuffers(GLFWwindow* window); - -/*! @brief Sets the swap interval for the current context. - * - * This function sets the swap interval for the current context, i.e. the - * number of screen updates to wait from the time @ref glfwSwapBuffers was - * called before swapping the buffers and returning. This is sometimes called - * _vertical synchronization_, _vertical retrace synchronization_ or just - * _vsync_. - * - * Contexts that support either of the `WGL_EXT_swap_control_tear` and - * `GLX_EXT_swap_control_tear` extensions also accept negative swap intervals, - * which allow the driver to swap even if a frame arrives a little bit late. - * You can check for the presence of these extensions using @ref - * glfwExtensionSupported. For more information about swap tearing, see the - * extension specifications. - * - * A context must be current on the calling thread. Calling this function - * without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error. - * - * @param[in] interval The minimum number of screen updates to wait for - * until the buffers are swapped by @ref glfwSwapBuffers. - * - * @note This function is not called during window creation, leaving the swap - * interval set to whatever is the default on that platform. This is done - * because some swap interval extensions used by GLFW do not allow the swap - * interval to be reset to zero once it has been set to a non-zero value. - * - * @note Some GPU drivers do not honor the requested swap interval, either - * because of user settings that override the request or due to bugs in the - * driver. - * - * @par Thread Safety - * This function may be called from any thread. - * - * @sa @ref buffer_swap - * @sa glfwSwapBuffers - * - * @since Added in GLFW 1.0. - * - * @ingroup context - */ -GLFWAPI void glfwSwapInterval(int interval); - -/*! @brief Returns whether the specified extension is available. - * - * This function returns whether the specified - * [API extension](@ref context_glext) is supported by the current OpenGL or - * OpenGL ES context. It searches both for OpenGL and OpenGL ES extension and - * platform-specific context creation API extensions. - * - * A context must be current on the calling thread. Calling this function - * without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error. - * - * As this functions retrieves and searches one or more extension strings each - * call, it is recommended that you cache its results if it is going to be used - * frequently. The extension strings will not change during the lifetime of - * a context, so there is no danger in doing this. - * - * @param[in] extension The ASCII encoded name of the extension. - * @return `GL_TRUE` if the extension is available, or `GL_FALSE` otherwise. - * - * @par Thread Safety - * This function may be called from any thread. - * - * @sa @ref context_glext - * @sa glfwGetProcAddress - * - * @since Added in GLFW 1.0. - * - * @ingroup context - */ -GLFWAPI int glfwExtensionSupported(const char* extension); - -/*! @brief Returns the address of the specified function for the current - * context. - * - * This function returns the address of the specified - * [client API or extension function](@ref context_glext), if it is supported - * by the current context. - * - * A context must be current on the calling thread. Calling this function - * without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error. - * - * @param[in] procname The ASCII encoded name of the function. - * @return The address of the function, or `NULL` if the function is - * unavailable or an [error](@ref error_handling) occurred. - * - * @note The addresses of a given function is not guaranteed to be the same - * between contexts. - * - * @par Pointer Lifetime - * The returned function pointer is valid until the context is destroyed or the - * library is terminated. - * - * @par Thread Safety - * This function may be called from any thread. - * - * @sa @ref context_glext - * @sa glfwExtensionSupported - * - * @since Added in GLFW 1.0. - * - * @ingroup context - */ -GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname); - - -/************************************************************************* - * Global definition cleanup - *************************************************************************/ - -/* ------------------- BEGIN SYSTEM/COMPILER SPECIFIC -------------------- */ - -#ifdef GLFW_WINGDIAPI_DEFINED - #undef WINGDIAPI - #undef GLFW_WINGDIAPI_DEFINED -#endif - -#ifdef GLFW_CALLBACK_DEFINED - #undef CALLBACK - #undef GLFW_CALLBACK_DEFINED -#endif - -/* -------------------- END SYSTEM/COMPILER SPECIFIC --------------------- */ - - -#ifdef __cplusplus -} -#endif - -#endif /* _glfw3_h_ */ - diff --git a/examples/common/glfw/include/GLFW/glfw3native.h b/examples/common/glfw/include/GLFW/glfw3native.h deleted file mode 100644 index b3ce7482..00000000 --- a/examples/common/glfw/include/GLFW/glfw3native.h +++ /dev/null @@ -1,356 +0,0 @@ -/************************************************************************* - * GLFW 3.1 - www.glfw.org - * A library for OpenGL, window and input - *------------------------------------------------------------------------ - * Copyright (c) 2002-2006 Marcus Geelnard - * Copyright (c) 2006-2010 Camilla Berglund - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would - * be appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not - * be misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source - * distribution. - * - *************************************************************************/ - -#ifndef _glfw3_native_h_ -#define _glfw3_native_h_ - -#ifdef __cplusplus -extern "C" { -#endif - - -/************************************************************************* - * Doxygen documentation - *************************************************************************/ - -/*! @defgroup native Native access - * - * **By using the native access functions you assert that you know what you're - * doing and how to fix problems caused by using them. If you don't, you - * shouldn't be using them.** - * - * Before the inclusion of @ref glfw3native.h, you must define exactly one - * window system API macro and exactly one context creation API macro. Failure - * to do this will cause a compile-time error. - * - * The available window API macros are: - * * `GLFW_EXPOSE_NATIVE_WIN32` - * * `GLFW_EXPOSE_NATIVE_COCOA` - * * `GLFW_EXPOSE_NATIVE_X11` - * - * The available context API macros are: - * * `GLFW_EXPOSE_NATIVE_WGL` - * * `GLFW_EXPOSE_NATIVE_NSGL` - * * `GLFW_EXPOSE_NATIVE_GLX` - * * `GLFW_EXPOSE_NATIVE_EGL` - * - * These macros select which of the native access functions that are declared - * and which platform-specific headers to include. It is then up your (by - * definition platform-specific) code to handle which of these should be - * defined. - */ - - -/************************************************************************* - * System headers and types - *************************************************************************/ - -#if defined(GLFW_EXPOSE_NATIVE_WIN32) - // This is a workaround for the fact that glfw3.h needs to export APIENTRY (for - // example to allow applications to correctly declare a GL_ARB_debug_output - // callback) but windows.h assumes no one will define APIENTRY before it does - #undef APIENTRY - #include -#elif defined(GLFW_EXPOSE_NATIVE_COCOA) - #include - #if defined(__OBJC__) - #import - #else - typedef void* id; - #endif -#elif defined(GLFW_EXPOSE_NATIVE_X11) - #include - #include -#else - #error "No window API selected" -#endif - -#if defined(GLFW_EXPOSE_NATIVE_WGL) - /* WGL is declared by windows.h */ -#elif defined(GLFW_EXPOSE_NATIVE_NSGL) - /* NSGL is declared by Cocoa.h */ -#elif defined(GLFW_EXPOSE_NATIVE_GLX) - #include -#elif defined(GLFW_EXPOSE_NATIVE_EGL) - #include -#else - #error "No context API selected" -#endif - - -/************************************************************************* - * Functions - *************************************************************************/ - -#if defined(GLFW_EXPOSE_NATIVE_WIN32) -/*! @brief Returns the adapter device name of the specified monitor. - * - * @return The UTF-8 encoded adapter device name (for example `\\.\DISPLAY1`) - * of the specified monitor, or `NULL` if an [error](@ref error_handling) - * occurred. - * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. - * - * @par History - * Added in GLFW 3.1. - * - * @ingroup native - */ -GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* monitor); - -/*! @brief Returns the display device name of the specified monitor. - * - * @return The UTF-8 encoded display device name (for example - * `\\.\DISPLAY1\Monitor0`) of the specified monitor, or `NULL` if an - * [error](@ref error_handling) occurred. - * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. - * - * @par History - * Added in GLFW 3.1. - * - * @ingroup native - */ -GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* monitor); - -/*! @brief Returns the `HWND` of the specified window. - * - * @return The `HWND` of the specified window, or `NULL` if an - * [error](@ref error_handling) occurred. - * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. - * - * @par History - * Added in GLFW 3.0. - * - * @ingroup native - */ -GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window); -#endif - -#if defined(GLFW_EXPOSE_NATIVE_WGL) -/*! @brief Returns the `HGLRC` of the specified window. - * - * @return The `HGLRC` of the specified window, or `NULL` if an - * [error](@ref error_handling) occurred. - * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. - * - * @par History - * Added in GLFW 3.0. - * - * @ingroup native - */ -GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* window); -#endif - -#if defined(GLFW_EXPOSE_NATIVE_COCOA) -/*! @brief Returns the `CGDirectDisplayID` of the specified monitor. - * - * @return The `CGDirectDisplayID` of the specified monitor, or - * `kCGNullDirectDisplay` if an [error](@ref error_handling) occurred. - * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. - * - * @par History - * Added in GLFW 3.1. - * - * @ingroup native - */ -GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor); - -/*! @brief Returns the `NSWindow` of the specified window. - * - * @return The `NSWindow` of the specified window, or `nil` if an - * [error](@ref error_handling) occurred. - * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. - * - * @par History - * Added in GLFW 3.0. - * - * @ingroup native - */ -GLFWAPI id glfwGetCocoaWindow(GLFWwindow* window); -#endif - -#if defined(GLFW_EXPOSE_NATIVE_NSGL) -/*! @brief Returns the `NSOpenGLContext` of the specified window. - * - * @return The `NSOpenGLContext` of the specified window, or `nil` if an - * [error](@ref error_handling) occurred. - * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. - * - * @par History - * Added in GLFW 3.0. - * - * @ingroup native - */ -GLFWAPI id glfwGetNSGLContext(GLFWwindow* window); -#endif - -#if defined(GLFW_EXPOSE_NATIVE_X11) -/*! @brief Returns the `Display` used by GLFW. - * - * @return The `Display` used by GLFW, or `NULL` if an - * [error](@ref error_handling) occurred. - * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. - * - * @par History - * Added in GLFW 3.0. - * - * @ingroup native - */ -GLFWAPI Display* glfwGetX11Display(void); - -/*! @brief Returns the `RRCrtc` of the specified monitor. - * - * @return The `RRCrtc` of the specified monitor, or `None` if an - * [error](@ref error_handling) occurred. - * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. - * - * @par History - * Added in GLFW 3.1. - * - * @ingroup native - */ -GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* monitor); - -/*! @brief Returns the `RROutput` of the specified monitor. - * - * @return The `RROutput` of the specified monitor, or `None` if an - * [error](@ref error_handling) occurred. - * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. - * - * @par History - * Added in GLFW 3.1. - * - * @ingroup native - */ -GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* monitor); - -/*! @brief Returns the `Window` of the specified window. - * - * @return The `Window` of the specified window, or `None` if an - * [error](@ref error_handling) occurred. - * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. - * - * @par History - * Added in GLFW 3.0. - * - * @ingroup native - */ -GLFWAPI Window glfwGetX11Window(GLFWwindow* window); -#endif - -#if defined(GLFW_EXPOSE_NATIVE_GLX) -/*! @brief Returns the `GLXContext` of the specified window. - * - * @return The `GLXContext` of the specified window, or `NULL` if an - * [error](@ref error_handling) occurred. - * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. - * - * @par History - * Added in GLFW 3.0. - * - * @ingroup native - */ -GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window); -#endif - -#if defined(GLFW_EXPOSE_NATIVE_EGL) -/*! @brief Returns the `EGLDisplay` used by GLFW. - * - * @return The `EGLDisplay` used by GLFW, or `EGL_NO_DISPLAY` if an - * [error](@ref error_handling) occurred. - * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. - * - * @par History - * Added in GLFW 3.0. - * - * @ingroup native - */ -GLFWAPI EGLDisplay glfwGetEGLDisplay(void); - -/*! @brief Returns the `EGLContext` of the specified window. - * - * @return The `EGLContext` of the specified window, or `EGL_NO_CONTEXT` if an - * [error](@ref error_handling) occurred. - * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. - * - * @par History - * Added in GLFW 3.0. - * - * @ingroup native - */ -GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window); - -/*! @brief Returns the `EGLSurface` of the specified window. - * - * @return The `EGLSurface` of the specified window, or `EGL_NO_SURFACE` if an - * [error](@ref error_handling) occurred. - * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. - * - * @par History - * Added in GLFW 3.0. - * - * @ingroup native - */ -GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* window); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* _glfw3_native_h_ */ - diff --git a/examples/common/glfw/src/CMakeLists.txt b/examples/common/glfw/src/CMakeLists.txt deleted file mode 100644 index e247a5ba..00000000 --- a/examples/common/glfw/src/CMakeLists.txt +++ /dev/null @@ -1,95 +0,0 @@ - -include_directories("${GLFW_SOURCE_DIR}/src" - "${GLFW_BINARY_DIR}/src" - ${glfw_INCLUDE_DIRS}) - -add_definitions(-D_GLFW_USE_CONFIG_H) - -set(common_HEADERS internal.h - "${GLFW_BINARY_DIR}/src/glfw_config.h" - "${GLFW_SOURCE_DIR}/include/GLFW/glfw3.h" - "${GLFW_SOURCE_DIR}/include/GLFW/glfw3native.h") -set(common_SOURCES context.c init.c input.c monitor.c window.c) - -if (_GLFW_COCOA) - set(glfw_HEADERS ${common_HEADERS} cocoa_platform.h iokit_joystick.h - posix_tls.h) - set(glfw_SOURCES ${common_SOURCES} cocoa_init.m cocoa_monitor.m - cocoa_window.m iokit_joystick.m mach_time.c posix_tls.c) -elseif (_GLFW_WIN32) - set(glfw_HEADERS ${common_HEADERS} win32_platform.h win32_tls.h - winmm_joystick.h) - set(glfw_SOURCES ${common_SOURCES} win32_init.c win32_monitor.c win32_time.c - win32_tls.c win32_window.c winmm_joystick.c) -elseif (_GLFW_X11) - set(glfw_HEADERS ${common_HEADERS} x11_platform.h xkb_unicode.h - linux_joystick.h posix_time.h posix_tls.h) - set(glfw_SOURCES ${common_SOURCES} x11_init.c x11_monitor.c x11_window.c - xkb_unicode.c linux_joystick.c posix_time.c posix_tls.c) -elseif (_GLFW_WAYLAND) - set(glfw_HEADERS ${common_HEADERS} wl_platform.h linux_joystick.h - posix_time.h posix_tls.h xkb_unicode.h) - set(glfw_SOURCES ${common_SOURCES} wl_init.c wl_monitor.c wl_window.c - linux_joystick.c posix_time.c posix_tls.c xkb_unicode.c) -elseif (_GLFW_MIR) - set(glfw_HEADERS ${common_HEADERS} mir_platform.h linux_joystick.h - posix_time.h posix_tls.h xkb_unicode.h) - set(glfw_SOURCES ${common_SOURCES} mir_init.c mir_monitor.c mir_window.c - linux_joystick.c posix_time.c posix_tls.c xkb_unicode.c) -endif() - -if (_GLFW_EGL) - list(APPEND glfw_HEADERS ${common_HEADERS} egl_context.h) - list(APPEND glfw_SOURCES ${common_SOURCES} egl_context.c) -elseif (_GLFW_NSGL) - list(APPEND glfw_HEADERS ${common_HEADERS} nsgl_context.h) - list(APPEND glfw_SOURCES ${common_SOURCES} nsgl_context.m) -elseif (_GLFW_WGL) - list(APPEND glfw_HEADERS ${common_HEADERS} wgl_context.h) - list(APPEND glfw_SOURCES ${common_SOURCES} wgl_context.c) -elseif (_GLFW_X11) - list(APPEND glfw_HEADERS ${common_HEADERS} glx_context.h) - list(APPEND glfw_SOURCES ${common_SOURCES} glx_context.c) -endif() - -if (APPLE) - # For some reason, CMake doesn't know about .m - set_source_files_properties(${glfw_SOURCES} PROPERTIES LANGUAGE C) -endif() - -add_library(glfw ${glfw_SOURCES} ${glfw_HEADERS}) -set_target_properties(glfw PROPERTIES - OUTPUT_NAME "${GLFW_LIB_NAME}" - VERSION ${GLFW_VERSION} - SOVERSION ${GLFW_VERSION_MAJOR} - POSITION_INDEPENDENT_CODE ON - FOLDER "GLFW3") - -if (BUILD_SHARED_LIBS) - if (WIN32) - # The GLFW DLL needs a special compile-time macro and import library name - set_target_properties(glfw PROPERTIES PREFIX "" IMPORT_PREFIX "") - - if (MINGW) - set_target_properties(glfw PROPERTIES IMPORT_SUFFIX "dll.a") - else() - set_target_properties(glfw PROPERTIES IMPORT_SUFFIX "dll.lib") - endif() - elseif (APPLE) - # Append -fno-common to the compile flags to work around a bug in - # Apple's GCC - get_target_property(glfw_CFLAGS glfw COMPILE_FLAGS) - if (NOT glfw_CFLAGS) - set(glfw_CFLAGS "") - endif() - set_target_properties(glfw PROPERTIES - COMPILE_FLAGS "${glfw_CFLAGS} -fno-common" - INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}") - endif() - target_link_libraries(glfw ${glfw_LIBRARIES}) -endif() - -if (GLFW_INSTALL) - install(TARGETS glfw EXPORT glfwTargets DESTINATION lib${LIB_SUFFIX}) -endif() - diff --git a/examples/common/glfw/src/cocoa_init.m b/examples/common/glfw/src/cocoa_init.m deleted file mode 100644 index 8779cdfa..00000000 --- a/examples/common/glfw/src/cocoa_init.m +++ /dev/null @@ -1,272 +0,0 @@ -//======================================================================== -// GLFW 3.1 OS X - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2009-2010 Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#include "internal.h" -#include // For MAXPATHLEN - - -#if defined(_GLFW_USE_CHDIR) - -// Change to our application bundle's resources directory, if present -// -static void changeToResourcesDirectory(void) -{ - char resourcesPath[MAXPATHLEN]; - - CFBundleRef bundle = CFBundleGetMainBundle(); - if (!bundle) - return; - - CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(bundle); - - CFStringRef last = CFURLCopyLastPathComponent(resourcesURL); - if (CFStringCompare(CFSTR("Resources"), last, 0) != kCFCompareEqualTo) - { - CFRelease(last); - CFRelease(resourcesURL); - return; - } - - CFRelease(last); - - if (!CFURLGetFileSystemRepresentation(resourcesURL, - true, - (UInt8*) resourcesPath, - MAXPATHLEN)) - { - CFRelease(resourcesURL); - return; - } - - CFRelease(resourcesURL); - - chdir(resourcesPath); -} - -#endif /* _GLFW_USE_CHDIR */ - -// Create key code translation tables -// -static void createKeyTables(void) -{ - memset(_glfw.ns.publicKeys, -1, sizeof(_glfw.ns.publicKeys)); - - _glfw.ns.publicKeys[0x1D] = GLFW_KEY_0; - _glfw.ns.publicKeys[0x12] = GLFW_KEY_1; - _glfw.ns.publicKeys[0x13] = GLFW_KEY_2; - _glfw.ns.publicKeys[0x14] = GLFW_KEY_3; - _glfw.ns.publicKeys[0x15] = GLFW_KEY_4; - _glfw.ns.publicKeys[0x17] = GLFW_KEY_5; - _glfw.ns.publicKeys[0x16] = GLFW_KEY_6; - _glfw.ns.publicKeys[0x1A] = GLFW_KEY_7; - _glfw.ns.publicKeys[0x1C] = GLFW_KEY_8; - _glfw.ns.publicKeys[0x19] = GLFW_KEY_9; - _glfw.ns.publicKeys[0x00] = GLFW_KEY_A; - _glfw.ns.publicKeys[0x0B] = GLFW_KEY_B; - _glfw.ns.publicKeys[0x08] = GLFW_KEY_C; - _glfw.ns.publicKeys[0x02] = GLFW_KEY_D; - _glfw.ns.publicKeys[0x0E] = GLFW_KEY_E; - _glfw.ns.publicKeys[0x03] = GLFW_KEY_F; - _glfw.ns.publicKeys[0x05] = GLFW_KEY_G; - _glfw.ns.publicKeys[0x04] = GLFW_KEY_H; - _glfw.ns.publicKeys[0x22] = GLFW_KEY_I; - _glfw.ns.publicKeys[0x26] = GLFW_KEY_J; - _glfw.ns.publicKeys[0x28] = GLFW_KEY_K; - _glfw.ns.publicKeys[0x25] = GLFW_KEY_L; - _glfw.ns.publicKeys[0x2E] = GLFW_KEY_M; - _glfw.ns.publicKeys[0x2D] = GLFW_KEY_N; - _glfw.ns.publicKeys[0x1F] = GLFW_KEY_O; - _glfw.ns.publicKeys[0x23] = GLFW_KEY_P; - _glfw.ns.publicKeys[0x0C] = GLFW_KEY_Q; - _glfw.ns.publicKeys[0x0F] = GLFW_KEY_R; - _glfw.ns.publicKeys[0x01] = GLFW_KEY_S; - _glfw.ns.publicKeys[0x11] = GLFW_KEY_T; - _glfw.ns.publicKeys[0x20] = GLFW_KEY_U; - _glfw.ns.publicKeys[0x09] = GLFW_KEY_V; - _glfw.ns.publicKeys[0x0D] = GLFW_KEY_W; - _glfw.ns.publicKeys[0x07] = GLFW_KEY_X; - _glfw.ns.publicKeys[0x10] = GLFW_KEY_Y; - _glfw.ns.publicKeys[0x06] = GLFW_KEY_Z; - - _glfw.ns.publicKeys[0x27] = GLFW_KEY_APOSTROPHE; - _glfw.ns.publicKeys[0x2A] = GLFW_KEY_BACKSLASH; - _glfw.ns.publicKeys[0x2B] = GLFW_KEY_COMMA; - _glfw.ns.publicKeys[0x18] = GLFW_KEY_EQUAL; - _glfw.ns.publicKeys[0x32] = GLFW_KEY_GRAVE_ACCENT; - _glfw.ns.publicKeys[0x21] = GLFW_KEY_LEFT_BRACKET; - _glfw.ns.publicKeys[0x1B] = GLFW_KEY_MINUS; - _glfw.ns.publicKeys[0x2F] = GLFW_KEY_PERIOD; - _glfw.ns.publicKeys[0x1E] = GLFW_KEY_RIGHT_BRACKET; - _glfw.ns.publicKeys[0x29] = GLFW_KEY_SEMICOLON; - _glfw.ns.publicKeys[0x2C] = GLFW_KEY_SLASH; - _glfw.ns.publicKeys[0x0A] = GLFW_KEY_WORLD_1; - - _glfw.ns.publicKeys[0x33] = GLFW_KEY_BACKSPACE; - _glfw.ns.publicKeys[0x39] = GLFW_KEY_CAPS_LOCK; - _glfw.ns.publicKeys[0x75] = GLFW_KEY_DELETE; - _glfw.ns.publicKeys[0x7D] = GLFW_KEY_DOWN; - _glfw.ns.publicKeys[0x77] = GLFW_KEY_END; - _glfw.ns.publicKeys[0x24] = GLFW_KEY_ENTER; - _glfw.ns.publicKeys[0x35] = GLFW_KEY_ESCAPE; - _glfw.ns.publicKeys[0x7A] = GLFW_KEY_F1; - _glfw.ns.publicKeys[0x78] = GLFW_KEY_F2; - _glfw.ns.publicKeys[0x63] = GLFW_KEY_F3; - _glfw.ns.publicKeys[0x76] = GLFW_KEY_F4; - _glfw.ns.publicKeys[0x60] = GLFW_KEY_F5; - _glfw.ns.publicKeys[0x61] = GLFW_KEY_F6; - _glfw.ns.publicKeys[0x62] = GLFW_KEY_F7; - _glfw.ns.publicKeys[0x64] = GLFW_KEY_F8; - _glfw.ns.publicKeys[0x65] = GLFW_KEY_F9; - _glfw.ns.publicKeys[0x6D] = GLFW_KEY_F10; - _glfw.ns.publicKeys[0x67] = GLFW_KEY_F11; - _glfw.ns.publicKeys[0x6F] = GLFW_KEY_F12; - _glfw.ns.publicKeys[0x69] = GLFW_KEY_F13; - _glfw.ns.publicKeys[0x6B] = GLFW_KEY_F14; - _glfw.ns.publicKeys[0x71] = GLFW_KEY_F15; - _glfw.ns.publicKeys[0x6A] = GLFW_KEY_F16; - _glfw.ns.publicKeys[0x40] = GLFW_KEY_F17; - _glfw.ns.publicKeys[0x4F] = GLFW_KEY_F18; - _glfw.ns.publicKeys[0x50] = GLFW_KEY_F19; - _glfw.ns.publicKeys[0x5A] = GLFW_KEY_F20; - _glfw.ns.publicKeys[0x73] = GLFW_KEY_HOME; - _glfw.ns.publicKeys[0x72] = GLFW_KEY_INSERT; - _glfw.ns.publicKeys[0x7B] = GLFW_KEY_LEFT; - _glfw.ns.publicKeys[0x3A] = GLFW_KEY_LEFT_ALT; - _glfw.ns.publicKeys[0x3B] = GLFW_KEY_LEFT_CONTROL; - _glfw.ns.publicKeys[0x38] = GLFW_KEY_LEFT_SHIFT; - _glfw.ns.publicKeys[0x37] = GLFW_KEY_LEFT_SUPER; - _glfw.ns.publicKeys[0x6E] = GLFW_KEY_MENU; - _glfw.ns.publicKeys[0x47] = GLFW_KEY_NUM_LOCK; - _glfw.ns.publicKeys[0x79] = GLFW_KEY_PAGE_DOWN; - _glfw.ns.publicKeys[0x74] = GLFW_KEY_PAGE_UP; - _glfw.ns.publicKeys[0x7C] = GLFW_KEY_RIGHT; - _glfw.ns.publicKeys[0x3D] = GLFW_KEY_RIGHT_ALT; - _glfw.ns.publicKeys[0x3E] = GLFW_KEY_RIGHT_CONTROL; - _glfw.ns.publicKeys[0x3C] = GLFW_KEY_RIGHT_SHIFT; - _glfw.ns.publicKeys[0x36] = GLFW_KEY_RIGHT_SUPER; - _glfw.ns.publicKeys[0x31] = GLFW_KEY_SPACE; - _glfw.ns.publicKeys[0x30] = GLFW_KEY_TAB; - _glfw.ns.publicKeys[0x7E] = GLFW_KEY_UP; - - _glfw.ns.publicKeys[0x52] = GLFW_KEY_KP_0; - _glfw.ns.publicKeys[0x53] = GLFW_KEY_KP_1; - _glfw.ns.publicKeys[0x54] = GLFW_KEY_KP_2; - _glfw.ns.publicKeys[0x55] = GLFW_KEY_KP_3; - _glfw.ns.publicKeys[0x56] = GLFW_KEY_KP_4; - _glfw.ns.publicKeys[0x57] = GLFW_KEY_KP_5; - _glfw.ns.publicKeys[0x58] = GLFW_KEY_KP_6; - _glfw.ns.publicKeys[0x59] = GLFW_KEY_KP_7; - _glfw.ns.publicKeys[0x5B] = GLFW_KEY_KP_8; - _glfw.ns.publicKeys[0x5C] = GLFW_KEY_KP_9; - _glfw.ns.publicKeys[0x45] = GLFW_KEY_KP_ADD; - _glfw.ns.publicKeys[0x41] = GLFW_KEY_KP_DECIMAL; - _glfw.ns.publicKeys[0x4B] = GLFW_KEY_KP_DIVIDE; - _glfw.ns.publicKeys[0x4C] = GLFW_KEY_KP_ENTER; - _glfw.ns.publicKeys[0x51] = GLFW_KEY_KP_EQUAL; - _glfw.ns.publicKeys[0x43] = GLFW_KEY_KP_MULTIPLY; - _glfw.ns.publicKeys[0x4E] = GLFW_KEY_KP_SUBTRACT; -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW platform API ////// -////////////////////////////////////////////////////////////////////////// - -int _glfwPlatformInit(void) -{ - _glfw.ns.autoreleasePool = [[NSAutoreleasePool alloc] init]; - -#if defined(_GLFW_USE_CHDIR) - changeToResourcesDirectory(); -#endif - - createKeyTables(); - - _glfw.ns.eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState); - if (!_glfw.ns.eventSource) - return GL_FALSE; - - CGEventSourceSetLocalEventsSuppressionInterval(_glfw.ns.eventSource, 0.0); - - if (!_glfwInitContextAPI()) - return GL_FALSE; - - _glfwInitTimer(); - _glfwInitJoysticks(); - - return GL_TRUE; -} - -void _glfwPlatformTerminate(void) -{ - if (_glfw.ns.eventSource) - { - CFRelease(_glfw.ns.eventSource); - _glfw.ns.eventSource = NULL; - } - - if (_glfw.ns.delegate) - { - [NSApp setDelegate:nil]; - [_glfw.ns.delegate release]; - _glfw.ns.delegate = nil; - } - - [_glfw.ns.autoreleasePool release]; - _glfw.ns.autoreleasePool = nil; - - [_glfw.ns.cursor release]; - _glfw.ns.cursor = nil; - - free(_glfw.ns.clipboardString); - - _glfwTerminateJoysticks(); - _glfwTerminateContextAPI(); -} - -const char* _glfwPlatformGetVersionString(void) -{ - const char* version = _GLFW_VERSION_NUMBER " Cocoa" -#if defined(_GLFW_NSGL) - " NSGL" -#endif -#if defined(_GLFW_USE_CHDIR) - " chdir" -#endif -#if defined(_GLFW_USE_MENUBAR) - " menubar" -#endif -#if defined(_GLFW_USE_RETINA) - " retina" -#endif -#if defined(_GLFW_BUILD_DLL) - " dynamic" -#endif - ; - - return version; -} - diff --git a/examples/common/glfw/src/cocoa_monitor.m b/examples/common/glfw/src/cocoa_monitor.m deleted file mode 100644 index d518973a..00000000 --- a/examples/common/glfw/src/cocoa_monitor.m +++ /dev/null @@ -1,439 +0,0 @@ -//======================================================================== -// GLFW 3.1 OS X - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2002-2006 Marcus Geelnard -// Copyright (c) 2006-2010 Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#include "internal.h" - -#include -#include -#include - -#include -#include -#include -#include -#include - - -// Get the name of the specified display -// -static char* getDisplayName(CGDirectDisplayID displayID) -{ - char* name; - CFDictionaryRef info, names; - CFStringRef value; - CFIndex size; - - // NOTE: This uses a deprecated function because Apple has - // (as of January 2015) not provided any alternative - info = IODisplayCreateInfoDictionary(CGDisplayIOServicePort(displayID), - kIODisplayOnlyPreferredName); - names = CFDictionaryGetValue(info, CFSTR(kDisplayProductName)); - - if (!names || !CFDictionaryGetValueIfPresent(names, CFSTR("en_US"), - (const void**) &value)) - { - // This may happen if a desktop Mac is running headless - _glfwInputError(GLFW_PLATFORM_ERROR, "Failed to retrieve display name"); - - CFRelease(info); - return strdup("Unknown"); - } - - size = CFStringGetMaximumSizeForEncoding(CFStringGetLength(value), - kCFStringEncodingUTF8); - name = calloc(size + 1, sizeof(char)); - CFStringGetCString(value, name, size, kCFStringEncodingUTF8); - - CFRelease(info); - - return name; -} - -// Check whether the display mode should be included in enumeration -// -static GLboolean modeIsGood(CGDisplayModeRef mode) -{ - uint32_t flags = CGDisplayModeGetIOFlags(mode); - if (!(flags & kDisplayModeValidFlag) || !(flags & kDisplayModeSafeFlag)) - return GL_FALSE; - - if (flags & kDisplayModeInterlacedFlag) - return GL_FALSE; - - if (flags & kDisplayModeStretchedFlag) - return GL_FALSE; - - CFStringRef format = CGDisplayModeCopyPixelEncoding(mode); - if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) && - CFStringCompare(format, CFSTR(IO32BitDirectPixels), 0)) - { - CFRelease(format); - return GL_FALSE; - } - - CFRelease(format); - return GL_TRUE; -} - -// Convert Core Graphics display mode to GLFW video mode -// -static GLFWvidmode vidmodeFromCGDisplayMode(CGDisplayModeRef mode, - CVDisplayLinkRef link) -{ - GLFWvidmode result; - result.width = (int) CGDisplayModeGetWidth(mode); - result.height = (int) CGDisplayModeGetHeight(mode); - result.refreshRate = (int) CGDisplayModeGetRefreshRate(mode); - - if (result.refreshRate == 0) - { - const CVTime time = CVDisplayLinkGetNominalOutputVideoRefreshPeriod(link); - if (!(time.flags & kCVTimeIsIndefinite)) - result.refreshRate = (int) (time.timeScale / (double) time.timeValue); - } - - CFStringRef format = CGDisplayModeCopyPixelEncoding(mode); - - if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) == 0) - { - result.redBits = 5; - result.greenBits = 5; - result.blueBits = 5; - } - else - { - result.redBits = 8; - result.greenBits = 8; - result.blueBits = 8; - } - - CFRelease(format); - return result; -} - -// Starts reservation for display fading -// -static CGDisplayFadeReservationToken beginFadeReservation(void) -{ - CGDisplayFadeReservationToken token = kCGDisplayFadeReservationInvalidToken; - - if (CGAcquireDisplayFadeReservation(5, &token) == kCGErrorSuccess) - CGDisplayFade(token, 0.3, kCGDisplayBlendNormal, kCGDisplayBlendSolidColor, 0.0, 0.0, 0.0, TRUE); - - return token; -} - -// Ends reservation for display fading -// -static void endFadeReservation(CGDisplayFadeReservationToken token) -{ - if (token != kCGDisplayFadeReservationInvalidToken) - { - CGDisplayFade(token, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0, FALSE); - CGReleaseDisplayFadeReservation(token); - } -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW internal API ////// -////////////////////////////////////////////////////////////////////////// - -// Change the current video mode -// -GLboolean _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired) -{ - CFArrayRef modes; - CFIndex count, i; - CVDisplayLinkRef link; - CGDisplayModeRef native = NULL; - GLFWvidmode current; - const GLFWvidmode* best; - - best = _glfwChooseVideoMode(monitor, desired); - _glfwPlatformGetVideoMode(monitor, ¤t); - if (_glfwCompareVideoModes(¤t, best) == 0) - return GL_TRUE; - - CVDisplayLinkCreateWithCGDisplay(monitor->ns.displayID, &link); - - modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL); - count = CFArrayGetCount(modes); - - for (i = 0; i < count; i++) - { - CGDisplayModeRef dm = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i); - if (!modeIsGood(dm)) - continue; - - const GLFWvidmode mode = vidmodeFromCGDisplayMode(dm, link); - if (_glfwCompareVideoModes(best, &mode) == 0) - { - native = dm; - break; - } - } - - if (native) - { - if (monitor->ns.previousMode == NULL) - monitor->ns.previousMode = CGDisplayCopyDisplayMode(monitor->ns.displayID); - - CGDisplayFadeReservationToken token = beginFadeReservation(); - CGDisplaySetDisplayMode(monitor->ns.displayID, native, NULL); - endFadeReservation(token); - } - - CFRelease(modes); - CVDisplayLinkRelease(link); - - if (!native) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Cocoa: Monitor mode list changed"); - return GL_FALSE; - } - - return GL_TRUE; -} - -// Restore the previously saved (original) video mode -// -void _glfwRestoreVideoMode(_GLFWmonitor* monitor) -{ - if (monitor->ns.previousMode) - { - CGDisplayFadeReservationToken token = beginFadeReservation(); - CGDisplaySetDisplayMode(monitor->ns.displayID, - monitor->ns.previousMode, NULL); - endFadeReservation(token); - - CGDisplayModeRelease(monitor->ns.previousMode); - monitor->ns.previousMode = NULL; - } -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW platform API ////// -////////////////////////////////////////////////////////////////////////// - -_GLFWmonitor** _glfwPlatformGetMonitors(int* count) -{ - uint32_t i, found = 0, displayCount; - _GLFWmonitor** monitors; - CGDirectDisplayID* displays; - - *count = 0; - - CGGetOnlineDisplayList(0, NULL, &displayCount); - - displays = calloc(displayCount, sizeof(CGDirectDisplayID)); - monitors = calloc(displayCount, sizeof(_GLFWmonitor*)); - - CGGetOnlineDisplayList(displayCount, displays, &displayCount); - - NSArray* screens = [NSScreen screens]; - - for (i = 0; i < displayCount; i++) - { - int j; - - if (CGDisplayIsAsleep(displays[i])) - continue; - - CGDirectDisplayID screenDisplayID = CGDisplayMirrorsDisplay(displays[i]); - if (screenDisplayID == kCGNullDirectDisplay) - screenDisplayID = displays[i]; - - const CGSize size = CGDisplayScreenSize(displays[i]); - char* name = getDisplayName(displays[i]); - - monitors[found] = _glfwAllocMonitor(name, size.width, size.height); - monitors[found]->ns.displayID = displays[i]; - - free(name); - - for (j = 0; j < [screens count]; j++) - { - NSScreen* screen = [screens objectAtIndex:j]; - NSDictionary* dictionary = [screen deviceDescription]; - NSNumber* number = [dictionary objectForKey:@"NSScreenNumber"]; - - if ([number unsignedIntegerValue] == screenDisplayID) - { - monitors[found]->ns.screen = screen; - break; - } - } - - if (monitors[found]->ns.screen) - found++; - else - { - _glfwFreeMonitor(monitors[found]); - monitors[found] = NULL; - } - } - - free(displays); - - *count = found; - return monitors; -} - -GLboolean _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second) -{ - return first->ns.displayID == second->ns.displayID; -} - -void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos) -{ - const CGRect bounds = CGDisplayBounds(monitor->ns.displayID); - - if (xpos) - *xpos = (int) bounds.origin.x; - if (ypos) - *ypos = (int) bounds.origin.y; -} - -GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found) -{ - CFArrayRef modes; - CFIndex count, i, j; - GLFWvidmode* result; - CVDisplayLinkRef link; - - CVDisplayLinkCreateWithCGDisplay(monitor->ns.displayID, &link); - - modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL); - count = CFArrayGetCount(modes); - - result = calloc(count, sizeof(GLFWvidmode)); - *found = 0; - - for (i = 0; i < count; i++) - { - CGDisplayModeRef dm = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i); - if (!modeIsGood(dm)) - continue; - - const GLFWvidmode mode = vidmodeFromCGDisplayMode(dm, link); - - for (j = 0; j < *found; j++) - { - if (_glfwCompareVideoModes(result + j, &mode) == 0) - break; - } - - if (i < *found) - { - // This is a duplicate, so skip it - continue; - } - - result[*found] = mode; - (*found)++; - } - - CFRelease(modes); - - CVDisplayLinkRelease(link); - return result; -} - -void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode *mode) -{ - CGDisplayModeRef displayMode; - CVDisplayLinkRef link; - - CVDisplayLinkCreateWithCGDisplay(monitor->ns.displayID, &link); - - displayMode = CGDisplayCopyDisplayMode(monitor->ns.displayID); - *mode = vidmodeFromCGDisplayMode(displayMode, link); - CGDisplayModeRelease(displayMode); - - CVDisplayLinkRelease(link); -} - -void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) -{ - uint32_t i, size = CGDisplayGammaTableCapacity(monitor->ns.displayID); - CGGammaValue* values = calloc(size * 3, sizeof(CGGammaValue)); - - CGGetDisplayTransferByTable(monitor->ns.displayID, - size, - values, - values + size, - values + size * 2, - &size); - - _glfwAllocGammaArrays(ramp, size); - - for (i = 0; i < size; i++) - { - ramp->red[i] = (unsigned short) (values[i] * 65535); - ramp->green[i] = (unsigned short) (values[i + size] * 65535); - ramp->blue[i] = (unsigned short) (values[i + size * 2] * 65535); - } - - free(values); -} - -void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) -{ - int i; - CGGammaValue* values = calloc(ramp->size * 3, sizeof(CGGammaValue)); - - for (i = 0; i < ramp->size; i++) - { - values[i] = ramp->red[i] / 65535.f; - values[i + ramp->size] = ramp->green[i] / 65535.f; - values[i + ramp->size * 2] = ramp->blue[i] / 65535.f; - } - - CGSetDisplayTransferByTable(monitor->ns.displayID, - ramp->size, - values, - values + ramp->size, - values + ramp->size * 2); - - free(values); -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW native API ////// -////////////////////////////////////////////////////////////////////////// - -GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* handle) -{ - _GLFWmonitor* monitor = (_GLFWmonitor*) handle; - _GLFW_REQUIRE_INIT_OR_RETURN(kCGNullDirectDisplay); - return monitor->ns.displayID; -} - diff --git a/examples/common/glfw/src/cocoa_platform.h b/examples/common/glfw/src/cocoa_platform.h deleted file mode 100644 index 7e131be6..00000000 --- a/examples/common/glfw/src/cocoa_platform.h +++ /dev/null @@ -1,124 +0,0 @@ -//======================================================================== -// GLFW 3.1 OS X - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2009-2010 Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#ifndef _cocoa_platform_h_ -#define _cocoa_platform_h_ - - -#include - -#if defined(__OBJC__) -#import -#else -#include -typedef void* id; -#endif - -#include "posix_tls.h" - -#if defined(_GLFW_NSGL) - #include "nsgl_context.h" -#else - #error "No supported context creation API selected" -#endif - -#include "iokit_joystick.h" - -#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowNS ns -#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryNS ns -#define _GLFW_PLATFORM_LIBRARY_TIME_STATE _GLFWtimeNS ns_time -#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorNS ns -#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorNS ns - - -// Cocoa-specific per-window data -// -typedef struct _GLFWwindowNS -{ - id object; - id delegate; - id view; - unsigned int modifierFlags; - - // The total sum of the distances the cursor has been warped - // since the last cursor motion event was processed - // This is kept to counteract Cocoa doing the same internally - double warpDeltaX, warpDeltaY; - -} _GLFWwindowNS; - - -// Cocoa-specific global data -// -typedef struct _GLFWlibraryNS -{ - CGEventSourceRef eventSource; - id delegate; - id autoreleasePool; - id cursor; - - short int publicKeys[256]; - char* clipboardString; - -} _GLFWlibraryNS; - - -// Cocoa-specific per-monitor data -// -typedef struct _GLFWmonitorNS -{ - CGDirectDisplayID displayID; - CGDisplayModeRef previousMode; - id screen; - -} _GLFWmonitorNS; - - -// Cocoa-specific per-cursor data -// -typedef struct _GLFWcursorNS -{ - id object; - -} _GLFWcursorNS; - - -// Cocoa-specific global timer data -// -typedef struct _GLFWtimeNS -{ - double base; - double resolution; - -} _GLFWtimeNS; - - -void _glfwInitTimer(void); - -GLboolean _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired); -void _glfwRestoreVideoMode(_GLFWmonitor* monitor); - -#endif // _cocoa_platform_h_ diff --git a/examples/common/glfw/src/cocoa_window.m b/examples/common/glfw/src/cocoa_window.m deleted file mode 100644 index 9d182f42..00000000 --- a/examples/common/glfw/src/cocoa_window.m +++ /dev/null @@ -1,1284 +0,0 @@ -//======================================================================== -// GLFW 3.1 OS X - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2009-2010 Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#include "internal.h" - -#include - -// Needed for _NSGetProgname -#include - - -// Returns the specified standard cursor -// -static NSCursor* getStandardCursor(int shape) -{ - switch (shape) - { - case GLFW_ARROW_CURSOR: - return [NSCursor arrowCursor]; - case GLFW_IBEAM_CURSOR: - return [NSCursor IBeamCursor]; - case GLFW_CROSSHAIR_CURSOR: - return [NSCursor crosshairCursor]; - case GLFW_HAND_CURSOR: - return [NSCursor pointingHandCursor]; - case GLFW_HRESIZE_CURSOR: - return [NSCursor resizeLeftRightCursor]; - case GLFW_VRESIZE_CURSOR: - return [NSCursor resizeUpDownCursor]; - } - - return nil; -} - -// Center the cursor in the view of the window -// -static void centerCursor(_GLFWwindow *window) -{ - int width, height; - _glfwPlatformGetWindowSize(window, &width, &height); - _glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0); -} - -// Update the cursor to match the specified cursor mode -// -static void updateModeCursor(_GLFWwindow* window) -{ - if (window->cursorMode == GLFW_CURSOR_NORMAL) - { - if (window->cursor) - [(NSCursor*) window->cursor->ns.object set]; - else - [[NSCursor arrowCursor] set]; - } - else - [(NSCursor*) _glfw.ns.cursor set]; -} - -// Enter full screen mode -// -static GLboolean enterFullscreenMode(_GLFWwindow* window) -{ - GLboolean status; - - status = _glfwSetVideoMode(window->monitor, &window->videoMode); - - // NOTE: The window is resized despite mode setting failure to make - // glfwSetWindowSize more robust - [window->ns.object setFrame:[window->monitor->ns.screen frame] - display:YES]; - - return status; -} - -// Leave full screen mode -// -static void leaveFullscreenMode(_GLFWwindow* window) -{ - _glfwRestoreVideoMode(window->monitor); -} - -// Transforms the specified y-coordinate between the CG display and NS screen -// coordinate systems -// -static float transformY(float y) -{ - const float height = CGDisplayBounds(CGMainDisplayID()).size.height; - return height - y; -} - -// Returns the backing rect of the specified window -// -static NSRect convertRectToBacking(_GLFWwindow* window, NSRect contentRect) -{ -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 - if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) - return [window->ns.view convertRectToBacking:contentRect]; - else -#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ - return contentRect; -} - - -//------------------------------------------------------------------------ -// Delegate for window related notifications -//------------------------------------------------------------------------ - -@interface GLFWWindowDelegate : NSObject -{ - _GLFWwindow* window; -} - -- (id)initWithGlfwWindow:(_GLFWwindow *)initWindow; - -@end - -@implementation GLFWWindowDelegate - -- (id)initWithGlfwWindow:(_GLFWwindow *)initWindow -{ - self = [super init]; - if (self != nil) - window = initWindow; - - return self; -} - -- (BOOL)windowShouldClose:(id)sender -{ - _glfwInputWindowCloseRequest(window); - return NO; -} - -- (void)windowDidResize:(NSNotification *)notification -{ - if (_glfw.focusedWindow == window && - window->cursorMode == GLFW_CURSOR_DISABLED) - { - centerCursor(window); - } - - const NSRect contentRect = [window->ns.view frame]; - const NSRect fbRect = convertRectToBacking(window, contentRect); - - _glfwInputFramebufferSize(window, fbRect.size.width, fbRect.size.height); - _glfwInputWindowSize(window, contentRect.size.width, contentRect.size.height); - _glfwInputWindowDamage(window); -} - -- (void)windowDidMove:(NSNotification *)notification -{ - if (_glfw.focusedWindow == window && - window->cursorMode == GLFW_CURSOR_DISABLED) - { - centerCursor(window); - } - - int x, y; - _glfwPlatformGetWindowPos(window, &x, &y); - _glfwInputWindowPos(window, x, y); -} - -- (void)windowDidMiniaturize:(NSNotification *)notification -{ - _glfwInputWindowIconify(window, GL_TRUE); -} - -- (void)windowDidDeminiaturize:(NSNotification *)notification -{ - _glfwInputWindowIconify(window, GL_FALSE); -} - -- (void)windowDidBecomeKey:(NSNotification *)notification -{ - if (window->monitor) - enterFullscreenMode(window); - - if (_glfw.focusedWindow == window && - window->cursorMode == GLFW_CURSOR_DISABLED) - { - centerCursor(window); - } - - _glfwInputWindowFocus(window, GL_TRUE); - _glfwPlatformApplyCursorMode(window); -} - -- (void)windowDidResignKey:(NSNotification *)notification -{ - if (window->monitor) - leaveFullscreenMode(window); - - _glfwInputWindowFocus(window, GL_FALSE); -} - -@end - - -//------------------------------------------------------------------------ -// Delegate for application related notifications -//------------------------------------------------------------------------ - -@interface GLFWApplicationDelegate : NSObject -@end - -@implementation GLFWApplicationDelegate - -- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender -{ - _GLFWwindow* window; - - for (window = _glfw.windowListHead; window; window = window->next) - _glfwInputWindowCloseRequest(window); - - return NSTerminateCancel; -} - -- (void)applicationDidChangeScreenParameters:(NSNotification *) notification -{ - _glfwInputMonitorChange(); -} - -- (void)applicationDidFinishLaunching:(NSNotification *)notification -{ - [NSApp stop:nil]; - - _glfwPlatformPostEmptyEvent(); -} - -@end - -// Translates OS X key modifiers into GLFW ones -// -static int translateFlags(NSUInteger flags) -{ - int mods = 0; - - if (flags & NSShiftKeyMask) - mods |= GLFW_MOD_SHIFT; - if (flags & NSControlKeyMask) - mods |= GLFW_MOD_CONTROL; - if (flags & NSAlternateKeyMask) - mods |= GLFW_MOD_ALT; - if (flags & NSCommandKeyMask) - mods |= GLFW_MOD_SUPER; - - return mods; -} - -// Translates a OS X keycode to a GLFW keycode -// -static int translateKey(unsigned int key) -{ - if (key >= sizeof(_glfw.ns.publicKeys) / sizeof(_glfw.ns.publicKeys[0])) - return GLFW_KEY_UNKNOWN; - - return _glfw.ns.publicKeys[key]; -} - - -//------------------------------------------------------------------------ -// Content view class for the GLFW window -//------------------------------------------------------------------------ - -@interface GLFWContentView : NSOpenGLView -{ - _GLFWwindow* window; - NSTrackingArea* trackingArea; -} - -- (id)initWithGlfwWindow:(_GLFWwindow *)initWindow; - -@end - -@implementation GLFWContentView - -+ (void)initialize -{ - if (self == [GLFWContentView class]) - { - if (_glfw.ns.cursor == nil) - { - NSImage* data = [[NSImage alloc] initWithSize:NSMakeSize(16, 16)]; - _glfw.ns.cursor = [[NSCursor alloc] initWithImage:data - hotSpot:NSZeroPoint]; - [data release]; - } - } -} - -- (id)initWithGlfwWindow:(_GLFWwindow *)initWindow -{ - self = [super initWithFrame:NSMakeRect(0, 0, 1, 1) - pixelFormat:nil]; - if (self != nil) - { - window = initWindow; - trackingArea = nil; - - [self updateTrackingAreas]; - [self registerForDraggedTypes:[NSArray arrayWithObjects: - NSFilenamesPboardType, nil]]; - } - - return self; -} - --(void)dealloc -{ - [trackingArea release]; - [super dealloc]; -} - -- (BOOL)isOpaque -{ - return YES; -} - -- (BOOL)canBecomeKeyView -{ - return YES; -} - -- (BOOL)acceptsFirstResponder -{ - return YES; -} - -- (void)cursorUpdate:(NSEvent *)event -{ - updateModeCursor(window); -} - -- (void)mouseDown:(NSEvent *)event -{ - _glfwInputMouseClick(window, - GLFW_MOUSE_BUTTON_LEFT, - GLFW_PRESS, - translateFlags([event modifierFlags])); -} - -- (void)mouseDragged:(NSEvent *)event -{ - [self mouseMoved:event]; -} - -- (void)mouseUp:(NSEvent *)event -{ - _glfwInputMouseClick(window, - GLFW_MOUSE_BUTTON_LEFT, - GLFW_RELEASE, - translateFlags([event modifierFlags])); -} - -- (void)mouseMoved:(NSEvent *)event -{ - if (window->cursorMode == GLFW_CURSOR_DISABLED) - { - _glfwInputCursorMotion(window, - [event deltaX] - window->ns.warpDeltaX, - [event deltaY] - window->ns.warpDeltaY); - } - else - { - const NSRect contentRect = [window->ns.view frame]; - const NSPoint pos = [event locationInWindow]; - - _glfwInputCursorMotion(window, pos.x, contentRect.size.height - pos.y); - } - - window->ns.warpDeltaX = 0; - window->ns.warpDeltaY = 0; -} - -- (void)rightMouseDown:(NSEvent *)event -{ - _glfwInputMouseClick(window, - GLFW_MOUSE_BUTTON_RIGHT, - GLFW_PRESS, - translateFlags([event modifierFlags])); -} - -- (void)rightMouseDragged:(NSEvent *)event -{ - [self mouseMoved:event]; -} - -- (void)rightMouseUp:(NSEvent *)event -{ - _glfwInputMouseClick(window, - GLFW_MOUSE_BUTTON_RIGHT, - GLFW_RELEASE, - translateFlags([event modifierFlags])); -} - -- (void)otherMouseDown:(NSEvent *)event -{ - _glfwInputMouseClick(window, - (int) [event buttonNumber], - GLFW_PRESS, - translateFlags([event modifierFlags])); -} - -- (void)otherMouseDragged:(NSEvent *)event -{ - [self mouseMoved:event]; -} - -- (void)otherMouseUp:(NSEvent *)event -{ - _glfwInputMouseClick(window, - (int) [event buttonNumber], - GLFW_RELEASE, - translateFlags([event modifierFlags])); -} - -- (void)mouseExited:(NSEvent *)event -{ - _glfwInputCursorEnter(window, GL_FALSE); -} - -- (void)mouseEntered:(NSEvent *)event -{ - _glfwInputCursorEnter(window, GL_TRUE); -} - -- (void)viewDidChangeBackingProperties -{ - const NSRect contentRect = [window->ns.view frame]; - const NSRect fbRect = convertRectToBacking(window, contentRect); - - _glfwInputFramebufferSize(window, fbRect.size.width, fbRect.size.height); - _glfwInputWindowDamage(window); -} - -- (void)updateTrackingAreas -{ - if (trackingArea != nil) - { - [self removeTrackingArea:trackingArea]; - [trackingArea release]; - } - - const NSTrackingAreaOptions options = NSTrackingMouseEnteredAndExited | - NSTrackingActiveInKeyWindow | - NSTrackingEnabledDuringMouseDrag | - NSTrackingCursorUpdate | - NSTrackingInVisibleRect | - NSTrackingAssumeInside; - - trackingArea = [[NSTrackingArea alloc] initWithRect:[self bounds] - options:options - owner:self - userInfo:nil]; - - [self addTrackingArea:trackingArea]; - [super updateTrackingAreas]; -} - -- (void)keyDown:(NSEvent *)event -{ - const int key = translateKey([event keyCode]); - const int mods = translateFlags([event modifierFlags]); - - _glfwInputKey(window, key, [event keyCode], GLFW_PRESS, mods); - - NSString* characters = [event characters]; - NSUInteger i, length = [characters length]; - const int plain = !(mods & GLFW_MOD_SUPER); - - for (i = 0; i < length; i++) - { - const unichar codepoint = [characters characterAtIndex:i]; - if ((codepoint & 0xff00) == 0xf700) - continue; - - _glfwInputChar(window, codepoint, mods, plain); - } -} - -- (void)flagsChanged:(NSEvent *)event -{ - int action; - const unsigned int modifierFlags = - [event modifierFlags] & NSDeviceIndependentModifierFlagsMask; - const int key = translateKey([event keyCode]); - const int mods = translateFlags(modifierFlags); - - if (modifierFlags == window->ns.modifierFlags) - { - if (window->keys[key] == GLFW_PRESS) - action = GLFW_RELEASE; - else - action = GLFW_PRESS; - } - else if (modifierFlags > window->ns.modifierFlags) - action = GLFW_PRESS; - else - action = GLFW_RELEASE; - - window->ns.modifierFlags = modifierFlags; - - _glfwInputKey(window, key, [event keyCode], action, mods); -} - -- (void)keyUp:(NSEvent *)event -{ - const int key = translateKey([event keyCode]); - const int mods = translateFlags([event modifierFlags]); - _glfwInputKey(window, key, [event keyCode], GLFW_RELEASE, mods); -} - -- (void)scrollWheel:(NSEvent *)event -{ - double deltaX, deltaY; - -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 - if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) - { - deltaX = [event scrollingDeltaX]; - deltaY = [event scrollingDeltaY]; - - if ([event hasPreciseScrollingDeltas]) - { - deltaX *= 0.1; - deltaY *= 0.1; - } - } - else -#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ - { - deltaX = [event deltaX]; - deltaY = [event deltaY]; - } - - if (fabs(deltaX) > 0.0 || fabs(deltaY) > 0.0) - _glfwInputScroll(window, deltaX, deltaY); -} - -- (NSDragOperation)draggingEntered:(id )sender -{ - if ((NSDragOperationGeneric & [sender draggingSourceOperationMask]) - == NSDragOperationGeneric) - { - [self setNeedsDisplay:YES]; - return NSDragOperationGeneric; - } - - return NSDragOperationNone; -} - -- (BOOL)prepareForDragOperation:(id )sender -{ - [self setNeedsDisplay:YES]; - return YES; -} - -- (BOOL)performDragOperation:(id )sender -{ - NSPasteboard* pasteboard = [sender draggingPasteboard]; - NSArray* files = [pasteboard propertyListForType:NSFilenamesPboardType]; - - const NSRect contentRect = [window->ns.view frame]; - _glfwInputCursorMotion(window, - [sender draggingLocation].x, - contentRect.size.height - [sender draggingLocation].y); - - const int count = [files count]; - if (count) - { - NSEnumerator* e = [files objectEnumerator]; - char** names = calloc(count, sizeof(char*)); - int i; - - for (i = 0; i < count; i++) - names[i] = strdup([[e nextObject] UTF8String]); - - _glfwInputDrop(window, count, (const char**) names); - - for (i = 0; i < count; i++) - free(names[i]); - free(names); - } - - return YES; -} - -- (void)concludeDragOperation:(id )sender -{ - [self setNeedsDisplay:YES]; -} - -@end - - -//------------------------------------------------------------------------ -// GLFW window class -//------------------------------------------------------------------------ - -@interface GLFWWindow : NSWindow {} -@end - -@implementation GLFWWindow - -- (BOOL)canBecomeKeyWindow -{ - // Required for NSBorderlessWindowMask windows - return YES; -} - -@end - - -//------------------------------------------------------------------------ -// GLFW application class -//------------------------------------------------------------------------ - -@interface GLFWApplication : NSApplication -@end - -@implementation GLFWApplication - -// From http://cocoadev.com/index.pl?GameKeyboardHandlingAlmost -// This works around an AppKit bug, where key up events while holding -// down the command key don't get sent to the key window. -- (void)sendEvent:(NSEvent *)event -{ - if ([event type] == NSKeyUp && ([event modifierFlags] & NSCommandKeyMask)) - [[self keyWindow] sendEvent:event]; - else - [super sendEvent:event]; -} - -@end - -#if defined(_GLFW_USE_MENUBAR) - -// Try to figure out what the calling application is called -// -static NSString* findAppName(void) -{ - size_t i; - NSDictionary* infoDictionary = [[NSBundle mainBundle] infoDictionary]; - - // Keys to search for as potential application names - NSString* GLFWNameKeys[] = - { - @"CFBundleDisplayName", - @"CFBundleName", - @"CFBundleExecutable", - }; - - for (i = 0; i < sizeof(GLFWNameKeys) / sizeof(GLFWNameKeys[0]); i++) - { - id name = [infoDictionary objectForKey:GLFWNameKeys[i]]; - if (name && - [name isKindOfClass:[NSString class]] && - ![name isEqualToString:@""]) - { - return name; - } - } - - char** progname = _NSGetProgname(); - if (progname && *progname) - return [NSString stringWithUTF8String:*progname]; - - // Really shouldn't get here - return @"GLFW Application"; -} - -// Set up the menu bar (manually) -// This is nasty, nasty stuff -- calls to undocumented semi-private APIs that -// could go away at any moment, lots of stuff that really should be -// localize(d|able), etc. Loading a nib would save us this horror, but that -// doesn't seem like a good thing to require of GLFW users. -// -static void createMenuBar(void) -{ - NSString* appName = findAppName(); - - NSMenu* bar = [[NSMenu alloc] init]; - [NSApp setMainMenu:bar]; - - NSMenuItem* appMenuItem = - [bar addItemWithTitle:@"" action:NULL keyEquivalent:@""]; - NSMenu* appMenu = [[NSMenu alloc] init]; - [appMenuItem setSubmenu:appMenu]; - - [appMenu addItemWithTitle:[NSString stringWithFormat:@"About %@", appName] - action:@selector(orderFrontStandardAboutPanel:) - keyEquivalent:@""]; - [appMenu addItem:[NSMenuItem separatorItem]]; - NSMenu* servicesMenu = [[NSMenu alloc] init]; - [NSApp setServicesMenu:servicesMenu]; - [[appMenu addItemWithTitle:@"Services" - action:NULL - keyEquivalent:@""] setSubmenu:servicesMenu]; - [appMenu addItem:[NSMenuItem separatorItem]]; - [appMenu addItemWithTitle:[NSString stringWithFormat:@"Hide %@", appName] - action:@selector(hide:) - keyEquivalent:@"h"]; - [[appMenu addItemWithTitle:@"Hide Others" - action:@selector(hideOtherApplications:) - keyEquivalent:@"h"] - setKeyEquivalentModifierMask:NSAlternateKeyMask | NSCommandKeyMask]; - [appMenu addItemWithTitle:@"Show All" - action:@selector(unhideAllApplications:) - keyEquivalent:@""]; - [appMenu addItem:[NSMenuItem separatorItem]]; - [appMenu addItemWithTitle:[NSString stringWithFormat:@"Quit %@", appName] - action:@selector(terminate:) - keyEquivalent:@"q"]; - - NSMenuItem* windowMenuItem = - [bar addItemWithTitle:@"" action:NULL keyEquivalent:@""]; - NSMenu* windowMenu = [[NSMenu alloc] initWithTitle:@"Window"]; - [NSApp setWindowsMenu:windowMenu]; - [windowMenuItem setSubmenu:windowMenu]; - - [windowMenu addItemWithTitle:@"Minimize" - action:@selector(performMiniaturize:) - keyEquivalent:@"m"]; - [windowMenu addItemWithTitle:@"Zoom" - action:@selector(performZoom:) - keyEquivalent:@""]; - [windowMenu addItem:[NSMenuItem separatorItem]]; - [windowMenu addItemWithTitle:@"Bring All to Front" - action:@selector(arrangeInFront:) - keyEquivalent:@""]; - -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 - if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) - { - // TODO: Make this appear at the bottom of the menu (for consistency) - - [windowMenu addItem:[NSMenuItem separatorItem]]; - [[windowMenu addItemWithTitle:@"Enter Full Screen" - action:@selector(toggleFullScreen:) - keyEquivalent:@"f"] - setKeyEquivalentModifierMask:NSControlKeyMask | NSCommandKeyMask]; - } -#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ - - // Prior to Snow Leopard, we need to use this oddly-named semi-private API - // to get the application menu working properly. - SEL setAppleMenuSelector = NSSelectorFromString(@"setAppleMenu:"); - [NSApp performSelector:setAppleMenuSelector withObject:appMenu]; -} - -#endif /* _GLFW_USE_MENUBAR */ - -// Initialize the Cocoa Application Kit -// -static GLboolean initializeAppKit(void) -{ - if (NSApp) - return GL_TRUE; - - // Implicitly create shared NSApplication instance - [GLFWApplication sharedApplication]; - - // In case we are unbundled, make us a proper UI application - [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; - -#if defined(_GLFW_USE_MENUBAR) - // Menu bar setup must go between sharedApplication above and - // finishLaunching below, in order to properly emulate the behavior - // of NSApplicationMain - createMenuBar(); -#endif - - // There can only be one application delegate, but we allocate it the - // first time a window is created to keep all window code in this file - _glfw.ns.delegate = [[GLFWApplicationDelegate alloc] init]; - if (_glfw.ns.delegate == nil) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Cocoa: Failed to create application delegate"); - return GL_FALSE; - } - - [NSApp setDelegate:_glfw.ns.delegate]; - [NSApp run]; - - return GL_TRUE; -} - -// Create the Cocoa window -// -static GLboolean createWindow(_GLFWwindow* window, - const _GLFWwndconfig* wndconfig) -{ - window->ns.delegate = [[GLFWWindowDelegate alloc] initWithGlfwWindow:window]; - if (window->ns.delegate == nil) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Cocoa: Failed to create window delegate"); - return GL_FALSE; - } - - unsigned int styleMask = 0; - - if (wndconfig->monitor || !wndconfig->decorated) - styleMask = NSBorderlessWindowMask; - else - { - styleMask = NSTitledWindowMask | NSClosableWindowMask | - NSMiniaturizableWindowMask; - - if (wndconfig->resizable) - styleMask |= NSResizableWindowMask; - } - - NSRect contentRect; - - if (wndconfig->monitor) - contentRect = [wndconfig->monitor->ns.screen frame]; - else - contentRect = NSMakeRect(0, 0, wndconfig->width, wndconfig->height); - - window->ns.object = [[GLFWWindow alloc] - initWithContentRect:contentRect - styleMask:styleMask - backing:NSBackingStoreBuffered - defer:NO]; - - if (window->ns.object == nil) - { - _glfwInputError(GLFW_PLATFORM_ERROR, "Cocoa: Failed to create window"); - return GL_FALSE; - } - -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 - if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) - { - if (wndconfig->resizable) - [window->ns.object setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; - } -#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ - - if (wndconfig->monitor) - { - [window->ns.object setLevel:NSMainMenuWindowLevel + 1]; - [window->ns.object setHidesOnDeactivate:YES]; - } - else - { - [window->ns.object center]; - - if (wndconfig->floating) - [window->ns.object setLevel:NSFloatingWindowLevel]; - } - - [window->ns.object setTitle:[NSString stringWithUTF8String:wndconfig->title]]; - [window->ns.object setDelegate:window->ns.delegate]; - [window->ns.object setAcceptsMouseMovedEvents:YES]; - -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 - if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) - [window->ns.object setRestorable:NO]; -#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ - - return GL_TRUE; -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW platform API ////// -////////////////////////////////////////////////////////////////////////// - -int _glfwPlatformCreateWindow(_GLFWwindow* window, - const _GLFWwndconfig* wndconfig, - const _GLFWctxconfig* ctxconfig, - const _GLFWfbconfig* fbconfig) -{ - if (!initializeAppKit()) - return GL_FALSE; - - if (!createWindow(window, wndconfig)) - return GL_FALSE; - - if (!_glfwCreateContext(window, ctxconfig, fbconfig)) - return GL_FALSE; - - window->ns.view = [[GLFWContentView alloc] initWithGlfwWindow:window]; - -#if defined(_GLFW_USE_RETINA) -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 - if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) - [window->ns.view setWantsBestResolutionOpenGLSurface:YES]; -#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ -#endif /*_GLFW_USE_RETINA*/ - - [window->ns.object setContentView:window->ns.view]; - // NOTE: If you set the pixel format before the context it creates another - // context, only to have it destroyed by the next line - // We cannot use the view to create the context because that interface - // does not support context resource sharing - [window->ns.view setOpenGLContext:window->nsgl.context]; - [window->ns.view setPixelFormat:window->nsgl.pixelFormat]; - [window->nsgl.context setView:window->ns.view]; - - if (wndconfig->monitor) - { - _glfwPlatformShowWindow(window); - if (!enterFullscreenMode(window)) - return GL_FALSE; - } - - return GL_TRUE; -} - -void _glfwPlatformDestroyWindow(_GLFWwindow* window) -{ - [window->ns.object orderOut:nil]; - - if (window->monitor) - leaveFullscreenMode(window); - - _glfwDestroyContext(window); - - [window->ns.object setDelegate:nil]; - [window->ns.delegate release]; - window->ns.delegate = nil; - - [window->ns.view release]; - window->ns.view = nil; - - [window->ns.object close]; - window->ns.object = nil; -} - -void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char *title) -{ - [window->ns.object setTitle:[NSString stringWithUTF8String:title]]; -} - -void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos) -{ - const NSRect contentRect = - [window->ns.object contentRectForFrameRect:[window->ns.object frame]]; - - if (xpos) - *xpos = contentRect.origin.x; - if (ypos) - *ypos = transformY(contentRect.origin.y + contentRect.size.height); -} - -void _glfwPlatformSetWindowPos(_GLFWwindow* window, int x, int y) -{ - const NSRect contentRect = [window->ns.view frame]; - const NSRect dummyRect = NSMakeRect(x, transformY(y + contentRect.size.height), 0, 0); - const NSRect frameRect = [window->ns.object frameRectForContentRect:dummyRect]; - [window->ns.object setFrameOrigin:frameRect.origin]; -} - -void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height) -{ - const NSRect contentRect = [window->ns.view frame]; - - if (width) - *width = contentRect.size.width; - if (height) - *height = contentRect.size.height; -} - -void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) -{ - [window->ns.object setContentSize:NSMakeSize(width, height)]; -} - -void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height) -{ - const NSRect contentRect = [window->ns.view frame]; - const NSRect fbRect = convertRectToBacking(window, contentRect); - - if (width) - *width = (int) fbRect.size.width; - if (height) - *height = (int) fbRect.size.height; -} - -void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, - int* left, int* top, - int* right, int* bottom) -{ - const NSRect contentRect = [window->ns.view frame]; - const NSRect frameRect = [window->ns.object frameRectForContentRect:contentRect]; - - if (left) - *left = contentRect.origin.x - frameRect.origin.x; - if (top) - *top = frameRect.origin.y + frameRect.size.height - - contentRect.origin.y - contentRect.size.height; - if (right) - *right = frameRect.origin.x + frameRect.size.width - - contentRect.origin.x - contentRect.size.width; - if (bottom) - *bottom = contentRect.origin.y - frameRect.origin.y; -} - -void _glfwPlatformIconifyWindow(_GLFWwindow* window) -{ - [window->ns.object miniaturize:nil]; -} - -void _glfwPlatformRestoreWindow(_GLFWwindow* window) -{ - [window->ns.object deminiaturize:nil]; -} - -void _glfwPlatformShowWindow(_GLFWwindow* window) -{ - // Make us the active application - // HACK: This has been moved here from initializeAppKit to prevent - // applications using only hidden windows from being activated, but - // should probably not be done every time any window is shown - [NSApp activateIgnoringOtherApps:YES]; - - [window->ns.object makeKeyAndOrderFront:nil]; -} - -void _glfwPlatformUnhideWindow(_GLFWwindow* window) -{ - [window->ns.object orderFront:nil]; -} - -void _glfwPlatformHideWindow(_GLFWwindow* window) -{ - [window->ns.object orderOut:nil]; -} - -int _glfwPlatformWindowFocused(_GLFWwindow* window) -{ - return [window->ns.object isKeyWindow]; -} - -int _glfwPlatformWindowIconified(_GLFWwindow* window) -{ - return [window->ns.object isMiniaturized]; -} - -int _glfwPlatformWindowVisible(_GLFWwindow* window) -{ - return [window->ns.object isVisible]; -} - -void _glfwPlatformPollEvents(void) -{ - for (;;) - { - NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask - untilDate:[NSDate distantPast] - inMode:NSDefaultRunLoopMode - dequeue:YES]; - if (event == nil) - break; - - [NSApp sendEvent:event]; - } - - [_glfw.ns.autoreleasePool drain]; - _glfw.ns.autoreleasePool = [[NSAutoreleasePool alloc] init]; -} - -void _glfwPlatformWaitEvents(void) -{ - // I wanted to pass NO to dequeue:, and rely on PollEvents to - // dequeue and send. For reasons not at all clear to me, passing - // NO to dequeue: causes this method never to return. - NSEvent *event = [NSApp nextEventMatchingMask:NSAnyEventMask - untilDate:[NSDate distantFuture] - inMode:NSDefaultRunLoopMode - dequeue:YES]; - [NSApp sendEvent:event]; - - _glfwPlatformPollEvents(); -} - -void _glfwPlatformPostEmptyEvent(void) -{ - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - NSEvent* event = [NSEvent otherEventWithType:NSApplicationDefined - location:NSMakePoint(0, 0) - modifierFlags:0 - timestamp:0 - windowNumber:0 - context:nil - subtype:0 - data1:0 - data2:0]; - [NSApp postEvent:event atStart:YES]; - [pool drain]; -} - -void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos) -{ - const NSRect contentRect = [window->ns.view frame]; - const NSPoint pos = [window->ns.object mouseLocationOutsideOfEventStream]; - - if (xpos) - *xpos = pos.x; - if (ypos) - *ypos = contentRect.size.height - pos.y - 1; -} - -void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y) -{ - updateModeCursor(window); - - const NSRect contentRect = [window->ns.view frame]; - const NSPoint pos = [window->ns.object mouseLocationOutsideOfEventStream]; - - window->ns.warpDeltaX += x - pos.x; - window->ns.warpDeltaY += y - contentRect.size.height + pos.y; - - if (window->monitor) - { - CGDisplayMoveCursorToPoint(window->monitor->ns.displayID, - CGPointMake(x, y)); - } - else - { - const NSPoint localPoint = NSMakePoint(x, contentRect.size.height - y - 1); - const NSPoint globalPoint = [window->ns.object convertBaseToScreen:localPoint]; - - CGWarpMouseCursorPosition(CGPointMake(globalPoint.x, - transformY(globalPoint.y))); - } -} - -void _glfwPlatformApplyCursorMode(_GLFWwindow* window) -{ - updateModeCursor(window); - - if (window->cursorMode == GLFW_CURSOR_DISABLED) - CGAssociateMouseAndMouseCursorPosition(false); - else - CGAssociateMouseAndMouseCursorPosition(true); -} - -int _glfwPlatformCreateCursor(_GLFWcursor* cursor, - const GLFWimage* image, - int xhot, int yhot) -{ - NSImage* native; - NSBitmapImageRep* rep; - - rep = [[NSBitmapImageRep alloc] - initWithBitmapDataPlanes:NULL - pixelsWide:image->width - pixelsHigh:image->height - bitsPerSample:8 - samplesPerPixel:4 - hasAlpha:YES - isPlanar:NO - colorSpaceName:NSCalibratedRGBColorSpace - bitmapFormat:NSAlphaNonpremultipliedBitmapFormat - bytesPerRow:image->width * 4 - bitsPerPixel:32]; - - if (rep == nil) - return GL_FALSE; - - memcpy([rep bitmapData], image->pixels, image->width * image->height * 4); - - native = [[NSImage alloc] initWithSize:NSMakeSize(image->width, image->height)]; - [native addRepresentation: rep]; - - cursor->ns.object = [[NSCursor alloc] initWithImage:native - hotSpot:NSMakePoint(xhot, yhot)]; - - [native release]; - [rep release]; - - if (cursor->ns.object == nil) - return GL_FALSE; - - return GL_TRUE; -} - -int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape) -{ - cursor->ns.object = getStandardCursor(shape); - if (!cursor->ns.object) - { - _glfwInputError(GLFW_INVALID_ENUM, "Cocoa: Invalid standard cursor"); - return GL_FALSE; - } - - [cursor->ns.object retain]; - return GL_TRUE; -} - -void _glfwPlatformDestroyCursor(_GLFWcursor* cursor) -{ - if (cursor->ns.object) - [(NSCursor*) cursor->ns.object release]; -} - -void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) -{ - const NSPoint pos = [window->ns.object mouseLocationOutsideOfEventStream]; - - if (window->cursorMode == GLFW_CURSOR_NORMAL && - [window->ns.view mouse:pos inRect:[window->ns.view frame]]) - { - if (cursor) - [(NSCursor*) cursor->ns.object set]; - else - [[NSCursor arrowCursor] set]; - } -} - -void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string) -{ - NSArray* types = [NSArray arrayWithObjects:NSStringPboardType, nil]; - - NSPasteboard* pasteboard = [NSPasteboard generalPasteboard]; - [pasteboard declareTypes:types owner:nil]; - [pasteboard setString:[NSString stringWithUTF8String:string] - forType:NSStringPboardType]; -} - -const char* _glfwPlatformGetClipboardString(_GLFWwindow* window) -{ - NSPasteboard* pasteboard = [NSPasteboard generalPasteboard]; - - if (![[pasteboard types] containsObject:NSStringPboardType]) - { - _glfwInputError(GLFW_FORMAT_UNAVAILABLE, NULL); - return NULL; - } - - NSString* object = [pasteboard stringForType:NSStringPboardType]; - if (!object) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Cocoa: Failed to retrieve object from pasteboard"); - return NULL; - } - - free(_glfw.ns.clipboardString); - _glfw.ns.clipboardString = strdup([object UTF8String]); - - return _glfw.ns.clipboardString; -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW native API ////// -////////////////////////////////////////////////////////////////////////// - -GLFWAPI id glfwGetCocoaWindow(GLFWwindow* handle) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - _GLFW_REQUIRE_INIT_OR_RETURN(nil); - return window->ns.object; -} - diff --git a/examples/common/glfw/src/context.c b/examples/common/glfw/src/context.c deleted file mode 100644 index f8b80085..00000000 --- a/examples/common/glfw/src/context.c +++ /dev/null @@ -1,665 +0,0 @@ -//======================================================================== -// GLFW 3.1 - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2002-2006 Marcus Geelnard -// Copyright (c) 2006-2010 Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#include "internal.h" - -#include -#include -#include -#include - - -// Parses the client API version string and extracts the version number -// -static GLboolean parseVersionString(int* api, int* major, int* minor, int* rev) -{ - int i; - const char* version; - const char* prefixes[] = - { - "OpenGL ES-CM ", - "OpenGL ES-CL ", - "OpenGL ES ", - NULL - }; - - *api = GLFW_OPENGL_API; - - version = (const char*) glGetString(GL_VERSION); - if (!version) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Failed to retrieve context version string"); - return GL_FALSE; - } - - for (i = 0; prefixes[i]; i++) - { - const size_t length = strlen(prefixes[i]); - - if (strncmp(version, prefixes[i], length) == 0) - { - version += length; - *api = GLFW_OPENGL_ES_API; - break; - } - } - - if (!sscanf(version, "%d.%d.%d", major, minor, rev)) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "No version found in context version string"); - return GL_FALSE; - } - - return GL_TRUE; -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW internal API ////// -////////////////////////////////////////////////////////////////////////// - -GLboolean _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig) -{ - if (ctxconfig->api != GLFW_OPENGL_API && - ctxconfig->api != GLFW_OPENGL_ES_API) - { - _glfwInputError(GLFW_INVALID_ENUM, "Invalid client API requested"); - return GL_FALSE; - } - - if (ctxconfig->api == GLFW_OPENGL_API) - { - if ((ctxconfig->major < 1 || ctxconfig->minor < 0) || - (ctxconfig->major == 1 && ctxconfig->minor > 5) || - (ctxconfig->major == 2 && ctxconfig->minor > 1) || - (ctxconfig->major == 3 && ctxconfig->minor > 3)) - { - // OpenGL 1.0 is the smallest valid version - // OpenGL 1.x series ended with version 1.5 - // OpenGL 2.x series ended with version 2.1 - // OpenGL 3.x series ended with version 3.3 - - _glfwInputError(GLFW_INVALID_VALUE, - "Invalid OpenGL version %i.%i requested", - ctxconfig->major, ctxconfig->minor); - return GL_FALSE; - } - else - { - // For now, let everything else through - } - - if (ctxconfig->profile) - { - if (ctxconfig->profile != GLFW_OPENGL_CORE_PROFILE && - ctxconfig->profile != GLFW_OPENGL_COMPAT_PROFILE) - { - _glfwInputError(GLFW_INVALID_ENUM, - "Invalid OpenGL profile requested"); - return GL_FALSE; - } - - if (ctxconfig->major < 3 || - (ctxconfig->major == 3 && ctxconfig->minor < 2)) - { - // Desktop OpenGL context profiles are only defined for version 3.2 - // and above - - _glfwInputError(GLFW_INVALID_VALUE, - "Context profiles only exist for " - "OpenGL version 3.2 and above"); - return GL_FALSE; - } - } - - if (ctxconfig->forward && ctxconfig->major < 3) - { - // Forward-compatible contexts are only defined for OpenGL version 3.0 and above - _glfwInputError(GLFW_INVALID_VALUE, - "Forward compatibility only exist for OpenGL " - "version 3.0 and above"); - return GL_FALSE; - } - } - else if (ctxconfig->api == GLFW_OPENGL_ES_API) - { - if (ctxconfig->major < 1 || ctxconfig->minor < 0 || - (ctxconfig->major == 1 && ctxconfig->minor > 1) || - (ctxconfig->major == 2 && ctxconfig->minor > 0)) - { - // OpenGL ES 1.0 is the smallest valid version - // OpenGL ES 1.x series ended with version 1.1 - // OpenGL ES 2.x series ended with version 2.0 - - _glfwInputError(GLFW_INVALID_VALUE, - "Invalid OpenGL ES version %i.%i requested", - ctxconfig->major, ctxconfig->minor); - return GL_FALSE; - } - else - { - // For now, let everything else through - } - - if (ctxconfig->profile) - { - // OpenGL ES does not support profiles - _glfwInputError(GLFW_INVALID_VALUE, - "Context profiles are not supported by OpenGL ES"); - return GL_FALSE; - } - - if (ctxconfig->forward) - { - // OpenGL ES does not support forward-compatibility - _glfwInputError(GLFW_INVALID_VALUE, - "Forward compatibility is not supported by OpenGL ES"); - return GL_FALSE; - } - } - - if (ctxconfig->robustness) - { - if (ctxconfig->robustness != GLFW_NO_RESET_NOTIFICATION && - ctxconfig->robustness != GLFW_LOSE_CONTEXT_ON_RESET) - { - _glfwInputError(GLFW_INVALID_VALUE, - "Invalid context robustness mode requested"); - return GL_FALSE; - } - } - - if (ctxconfig->release) - { - if (ctxconfig->release != GLFW_RELEASE_BEHAVIOR_NONE && - ctxconfig->release != GLFW_RELEASE_BEHAVIOR_FLUSH) - { - _glfwInputError(GLFW_INVALID_VALUE, - "Invalid context release behavior requested"); - return GL_FALSE; - } - } - - return GL_TRUE; -} - -const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired, - const _GLFWfbconfig* alternatives, - unsigned int count) -{ - unsigned int i; - unsigned int missing, leastMissing = UINT_MAX; - unsigned int colorDiff, leastColorDiff = UINT_MAX; - unsigned int extraDiff, leastExtraDiff = UINT_MAX; - const _GLFWfbconfig* current; - const _GLFWfbconfig* closest = NULL; - - for (i = 0; i < count; i++) - { - current = alternatives + i; - - if (desired->stereo > 0 && current->stereo == 0) - { - // Stereo is a hard constraint - continue; - } - - if (desired->doublebuffer != current->doublebuffer) - { - // Double buffering is a hard constraint - continue; - } - - // Count number of missing buffers - { - missing = 0; - - if (desired->alphaBits > 0 && current->alphaBits == 0) - missing++; - - if (desired->depthBits > 0 && current->depthBits == 0) - missing++; - - if (desired->stencilBits > 0 && current->stencilBits == 0) - missing++; - - if (desired->auxBuffers > 0 && - current->auxBuffers < desired->auxBuffers) - { - missing += desired->auxBuffers - current->auxBuffers; - } - - if (desired->samples > 0 && current->samples == 0) - { - // Technically, several multisampling buffers could be - // involved, but that's a lower level implementation detail and - // not important to us here, so we count them as one - missing++; - } - } - - // These polynomials make many small channel size differences matter - // less than one large channel size difference - - // Calculate color channel size difference value - { - colorDiff = 0; - - if (desired->redBits != GLFW_DONT_CARE) - { - colorDiff += (desired->redBits - current->redBits) * - (desired->redBits - current->redBits); - } - - if (desired->greenBits != GLFW_DONT_CARE) - { - colorDiff += (desired->greenBits - current->greenBits) * - (desired->greenBits - current->greenBits); - } - - if (desired->blueBits != GLFW_DONT_CARE) - { - colorDiff += (desired->blueBits - current->blueBits) * - (desired->blueBits - current->blueBits); - } - } - - // Calculate non-color channel size difference value - { - extraDiff = 0; - - if (desired->alphaBits != GLFW_DONT_CARE) - { - extraDiff += (desired->alphaBits - current->alphaBits) * - (desired->alphaBits - current->alphaBits); - } - - if (desired->depthBits != GLFW_DONT_CARE) - { - extraDiff += (desired->depthBits - current->depthBits) * - (desired->depthBits - current->depthBits); - } - - if (desired->stencilBits != GLFW_DONT_CARE) - { - extraDiff += (desired->stencilBits - current->stencilBits) * - (desired->stencilBits - current->stencilBits); - } - - if (desired->accumRedBits != GLFW_DONT_CARE) - { - extraDiff += (desired->accumRedBits - current->accumRedBits) * - (desired->accumRedBits - current->accumRedBits); - } - - if (desired->accumGreenBits != GLFW_DONT_CARE) - { - extraDiff += (desired->accumGreenBits - current->accumGreenBits) * - (desired->accumGreenBits - current->accumGreenBits); - } - - if (desired->accumBlueBits != GLFW_DONT_CARE) - { - extraDiff += (desired->accumBlueBits - current->accumBlueBits) * - (desired->accumBlueBits - current->accumBlueBits); - } - - if (desired->accumAlphaBits != GLFW_DONT_CARE) - { - extraDiff += (desired->accumAlphaBits - current->accumAlphaBits) * - (desired->accumAlphaBits - current->accumAlphaBits); - } - - if (desired->samples != GLFW_DONT_CARE) - { - extraDiff += (desired->samples - current->samples) * - (desired->samples - current->samples); - } - - if (desired->sRGB && !current->sRGB) - extraDiff++; - } - - // Figure out if the current one is better than the best one found so far - // Least number of missing buffers is the most important heuristic, - // then color buffer size match and lastly size match for other buffers - - if (missing < leastMissing) - closest = current; - else if (missing == leastMissing) - { - if ((colorDiff < leastColorDiff) || - (colorDiff == leastColorDiff && extraDiff < leastExtraDiff)) - { - closest = current; - } - } - - if (current == closest) - { - leastMissing = missing; - leastColorDiff = colorDiff; - leastExtraDiff = extraDiff; - } - } - - return closest; -} - -GLboolean _glfwRefreshContextAttribs(const _GLFWctxconfig* ctxconfig) -{ - _GLFWwindow* window = _glfwPlatformGetCurrentContext(); - - if (!parseVersionString(&window->context.api, - &window->context.major, - &window->context.minor, - &window->context.revision)) - { - return GL_FALSE; - } - -#if defined(_GLFW_USE_OPENGL) - if (window->context.major > 2) - { - // OpenGL 3.0+ uses a different function for extension string retrieval - // We cache it here instead of in glfwExtensionSupported mostly to alert - // users as early as possible that their build may be broken - - window->GetStringi = (PFNGLGETSTRINGIPROC) glfwGetProcAddress("glGetStringi"); - if (!window->GetStringi) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Entry point retrieval is broken"); - return GL_FALSE; - } - } - - if (window->context.api == GLFW_OPENGL_API) - { - // Read back context flags (OpenGL 3.0 and above) - if (window->context.major >= 3) - { - GLint flags; - glGetIntegerv(GL_CONTEXT_FLAGS, &flags); - - if (flags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT) - window->context.forward = GL_TRUE; - - if (flags & GL_CONTEXT_FLAG_DEBUG_BIT) - window->context.debug = GL_TRUE; - else if (glfwExtensionSupported("GL_ARB_debug_output") && - ctxconfig->debug) - { - // HACK: This is a workaround for older drivers (pre KHR_debug) - // not setting the debug bit in the context flags for - // debug contexts - window->context.debug = GL_TRUE; - } - } - - // Read back OpenGL context profile (OpenGL 3.2 and above) - if (window->context.major > 3 || - (window->context.major == 3 && window->context.minor >= 2)) - { - GLint mask; - glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &mask); - - if (mask & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) - window->context.profile = GLFW_OPENGL_COMPAT_PROFILE; - else if (mask & GL_CONTEXT_CORE_PROFILE_BIT) - window->context.profile = GLFW_OPENGL_CORE_PROFILE; - else if (glfwExtensionSupported("GL_ARB_compatibility")) - { - // HACK: This is a workaround for the compatibility profile bit - // not being set in the context flags if an OpenGL 3.2+ - // context was created without having requested a specific - // version - window->context.profile = GLFW_OPENGL_COMPAT_PROFILE; - } - } - - // Read back robustness strategy - if (glfwExtensionSupported("GL_ARB_robustness")) - { - // NOTE: We avoid using the context flags for detection, as they are - // only present from 3.0 while the extension applies from 1.1 - - GLint strategy; - glGetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_ARB, &strategy); - - if (strategy == GL_LOSE_CONTEXT_ON_RESET_ARB) - window->context.robustness = GLFW_LOSE_CONTEXT_ON_RESET; - else if (strategy == GL_NO_RESET_NOTIFICATION_ARB) - window->context.robustness = GLFW_NO_RESET_NOTIFICATION; - } - } - else - { - // Read back robustness strategy - if (glfwExtensionSupported("GL_EXT_robustness")) - { - // NOTE: The values of these constants match those of the OpenGL ARB - // one, so we can reuse them here - - GLint strategy; - glGetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_ARB, &strategy); - - if (strategy == GL_LOSE_CONTEXT_ON_RESET_ARB) - window->context.robustness = GLFW_LOSE_CONTEXT_ON_RESET; - else if (strategy == GL_NO_RESET_NOTIFICATION_ARB) - window->context.robustness = GLFW_NO_RESET_NOTIFICATION; - } - } - - if (glfwExtensionSupported("GL_KHR_context_flush_control")) - { - GLint behavior; - glGetIntegerv(GL_CONTEXT_RELEASE_BEHAVIOR, &behavior); - - if (behavior == GL_NONE) - window->context.release = GLFW_RELEASE_BEHAVIOR_NONE; - else if (behavior == GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH) - window->context.release = GLFW_RELEASE_BEHAVIOR_FLUSH; - } -#endif // _GLFW_USE_OPENGL - - return GL_TRUE; -} - -GLboolean _glfwIsValidContext(const _GLFWctxconfig* ctxconfig) -{ - _GLFWwindow* window = _glfwPlatformGetCurrentContext(); - - if (window->context.major < ctxconfig->major || - (window->context.major == ctxconfig->major && - window->context.minor < ctxconfig->minor)) - { - // The desired OpenGL version is greater than the actual version - // This only happens if the machine lacks {GLX|WGL}_ARB_create_context - // /and/ the user has requested an OpenGL version greater than 1.0 - - // For API consistency, we emulate the behavior of the - // {GLX|WGL}_ARB_create_context extension and fail here - - _glfwInputError(GLFW_VERSION_UNAVAILABLE, NULL); - return GL_FALSE; - } - - return GL_TRUE; -} - -int _glfwStringInExtensionString(const char* string, const GLubyte* extensions) -{ - const GLubyte* start; - GLubyte* where; - GLubyte* terminator; - - // It takes a bit of care to be fool-proof about parsing the - // OpenGL extensions string. Don't be fooled by sub-strings, - // etc. - start = extensions; - for (;;) - { - where = (GLubyte*) strstr((const char*) start, string); - if (!where) - return GL_FALSE; - - terminator = where + strlen(string); - if (where == start || *(where - 1) == ' ') - { - if (*terminator == ' ' || *terminator == '\0') - break; - } - - start = terminator; - } - - return GL_TRUE; -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW public API ////// -////////////////////////////////////////////////////////////////////////// - -GLFWAPI void glfwMakeContextCurrent(GLFWwindow* handle) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - - _GLFW_REQUIRE_INIT(); - - if (_glfwPlatformGetCurrentContext() == window) - return; - - _glfwPlatformMakeContextCurrent(window); -} - -GLFWAPI GLFWwindow* glfwGetCurrentContext(void) -{ - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - return (GLFWwindow*) _glfwPlatformGetCurrentContext(); -} - -GLFWAPI void glfwSwapBuffers(GLFWwindow* handle) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - _GLFW_REQUIRE_INIT(); - _glfwPlatformSwapBuffers(window); -} - -GLFWAPI void glfwSwapInterval(int interval) -{ - _GLFW_REQUIRE_INIT(); - - if (!_glfwPlatformGetCurrentContext()) - { - _glfwInputError(GLFW_NO_CURRENT_CONTEXT, NULL); - return; - } - - _glfwPlatformSwapInterval(interval); -} - -GLFWAPI int glfwExtensionSupported(const char* extension) -{ - _GLFWwindow* window; - - _GLFW_REQUIRE_INIT_OR_RETURN(GL_FALSE); - - window = _glfwPlatformGetCurrentContext(); - if (!window) - { - _glfwInputError(GLFW_NO_CURRENT_CONTEXT, NULL); - return GL_FALSE; - } - - if (*extension == '\0') - { - _glfwInputError(GLFW_INVALID_VALUE, NULL); - return GL_FALSE; - } - -#if defined(_GLFW_USE_OPENGL) - if (window->context.major >= 3) - { - int i; - GLint count; - - // Check if extension is in the modern OpenGL extensions string list - - glGetIntegerv(GL_NUM_EXTENSIONS, &count); - - for (i = 0; i < count; i++) - { - const char* en = (const char*) window->GetStringi(GL_EXTENSIONS, i); - if (!en) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Failed to retrieve extension string %i", i); - return GL_FALSE; - } - - if (strcmp(en, extension) == 0) - return GL_TRUE; - } - } - else -#endif // _GLFW_USE_OPENGL - { - // Check if extension is in the old style OpenGL extensions string - - const GLubyte* extensions = glGetString(GL_EXTENSIONS); - if (!extensions) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Failed to retrieve extension string"); - return GL_FALSE; - } - - if (_glfwStringInExtensionString(extension, extensions)) - return GL_TRUE; - } - - // Check if extension is in the platform-specific string - return _glfwPlatformExtensionSupported(extension); -} - -GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname) -{ - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - - if (!_glfwPlatformGetCurrentContext()) - { - _glfwInputError(GLFW_NO_CURRENT_CONTEXT, NULL); - return NULL; - } - - return _glfwPlatformGetProcAddress(procname); -} - diff --git a/examples/common/glfw/src/egl_context.c b/examples/common/glfw/src/egl_context.c deleted file mode 100644 index e3335a53..00000000 --- a/examples/common/glfw/src/egl_context.c +++ /dev/null @@ -1,533 +0,0 @@ -//======================================================================== -// GLFW 3.1 EGL - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2002-2006 Marcus Geelnard -// Copyright (c) 2006-2010 Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#include "internal.h" - -#include -#include -#include - - -// Return a description of the specified EGL error -// -static const char* getErrorString(EGLint error) -{ - switch (error) - { - case EGL_SUCCESS: - return "Success"; - case EGL_NOT_INITIALIZED: - return "EGL is not or could not be initialized"; - case EGL_BAD_ACCESS: - return "EGL cannot access a requested resource"; - case EGL_BAD_ALLOC: - return "EGL failed to allocate resources for the requested operation"; - case EGL_BAD_ATTRIBUTE: - return "An unrecognized attribute or attribute value was passed " - "in the attribute list"; - case EGL_BAD_CONTEXT: - return "An EGLContext argument does not name a valid EGL " - "rendering context"; - case EGL_BAD_CONFIG: - return "An EGLConfig argument does not name a valid EGL frame " - "buffer configuration"; - case EGL_BAD_CURRENT_SURFACE: - return "The current surface of the calling thread is a window, pixel " - "buffer or pixmap that is no longer valid"; - case EGL_BAD_DISPLAY: - return "An EGLDisplay argument does not name a valid EGL display " - "connection"; - case EGL_BAD_SURFACE: - return "An EGLSurface argument does not name a valid surface " - "configured for GL rendering"; - case EGL_BAD_MATCH: - return "Arguments are inconsistent"; - case EGL_BAD_PARAMETER: - return "One or more argument values are invalid"; - case EGL_BAD_NATIVE_PIXMAP: - return "A NativePixmapType argument does not refer to a valid " - "native pixmap"; - case EGL_BAD_NATIVE_WINDOW: - return "A NativeWindowType argument does not refer to a valid " - "native window"; - case EGL_CONTEXT_LOST: - return "The application must destroy all contexts and reinitialise"; - } - - return "UNKNOWN EGL ERROR"; -} - -// Returns the specified attribute of the specified EGLConfig -// -static int getConfigAttrib(EGLConfig config, int attrib) -{ - int value; - eglGetConfigAttrib(_glfw.egl.display, config, attrib, &value); - return value; -} - -// Return a list of available and usable framebuffer configs -// -static GLboolean chooseFBConfigs(const _GLFWctxconfig* ctxconfig, - const _GLFWfbconfig* desired, - EGLConfig* result) -{ - EGLConfig* nativeConfigs; - _GLFWfbconfig* usableConfigs; - const _GLFWfbconfig* closest; - int i, nativeCount, usableCount; - - eglGetConfigs(_glfw.egl.display, NULL, 0, &nativeCount); - if (!nativeCount) - { - _glfwInputError(GLFW_API_UNAVAILABLE, "EGL: No EGLConfigs returned"); - return GL_FALSE; - } - - nativeConfigs = calloc(nativeCount, sizeof(EGLConfig)); - eglGetConfigs(_glfw.egl.display, nativeConfigs, nativeCount, &nativeCount); - - usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig)); - usableCount = 0; - - for (i = 0; i < nativeCount; i++) - { - const EGLConfig n = nativeConfigs[i]; - _GLFWfbconfig* u = usableConfigs + usableCount; - -#if defined(_GLFW_X11) - if (!getConfigAttrib(n, EGL_NATIVE_VISUAL_ID)) - { - // Only consider EGLConfigs with associated visuals - continue; - } -#endif // _GLFW_X11 - - if (!(getConfigAttrib(n, EGL_COLOR_BUFFER_TYPE) & EGL_RGB_BUFFER)) - { - // Only consider RGB(A) EGLConfigs - continue; - } - - if (!(getConfigAttrib(n, EGL_SURFACE_TYPE) & EGL_WINDOW_BIT)) - { - // Only consider window EGLConfigs - continue; - } - - if (ctxconfig->api == GLFW_OPENGL_ES_API) - { - if (ctxconfig->major == 1) - { - if (!(getConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES_BIT)) - continue; - } - else - { - if (!(getConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES2_BIT)) - continue; - } - } - else if (ctxconfig->api == GLFW_OPENGL_API) - { - if (!(getConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_BIT)) - continue; - } - - u->redBits = getConfigAttrib(n, EGL_RED_SIZE); - u->greenBits = getConfigAttrib(n, EGL_GREEN_SIZE); - u->blueBits = getConfigAttrib(n, EGL_BLUE_SIZE); - - u->alphaBits = getConfigAttrib(n, EGL_ALPHA_SIZE); - u->depthBits = getConfigAttrib(n, EGL_DEPTH_SIZE); - u->stencilBits = getConfigAttrib(n, EGL_STENCIL_SIZE); - - u->samples = getConfigAttrib(n, EGL_SAMPLES); - u->doublebuffer = GL_TRUE; - - u->egl = n; - usableCount++; - } - - closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount); - if (closest) - *result = closest->egl; - - free(nativeConfigs); - free(usableConfigs); - - return closest ? GL_TRUE : GL_FALSE; -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW internal API ////// -////////////////////////////////////////////////////////////////////////// - -// Initialize EGL -// -int _glfwInitContextAPI(void) -{ - if (!_glfwInitTLS()) - return GL_FALSE; - - _glfw.egl.display = eglGetDisplay((EGLNativeDisplayType)_GLFW_EGL_NATIVE_DISPLAY); - if (_glfw.egl.display == EGL_NO_DISPLAY) - { - _glfwInputError(GLFW_API_UNAVAILABLE, - "EGL: Failed to get EGL display: %s", - getErrorString(eglGetError())); - return GL_FALSE; - } - - if (!eglInitialize(_glfw.egl.display, - &_glfw.egl.versionMajor, - &_glfw.egl.versionMinor)) - { - _glfwInputError(GLFW_API_UNAVAILABLE, - "EGL: Failed to initialize EGL: %s", - getErrorString(eglGetError())); - return GL_FALSE; - } - - if (_glfwPlatformExtensionSupported("EGL_KHR_create_context")) - _glfw.egl.KHR_create_context = GL_TRUE; - - return GL_TRUE; -} - -// Terminate EGL -// -void _glfwTerminateContextAPI(void) -{ - eglTerminate(_glfw.egl.display); - - _glfwTerminateTLS(); -} - -#define setEGLattrib(attribName, attribValue) \ -{ \ - attribs[index++] = attribName; \ - attribs[index++] = attribValue; \ - assert((size_t) index < sizeof(attribs) / sizeof(attribs[0])); \ -} - -// Create the OpenGL or OpenGL ES context -// -int _glfwCreateContext(_GLFWwindow* window, - const _GLFWctxconfig* ctxconfig, - const _GLFWfbconfig* fbconfig) -{ - int attribs[40]; - EGLConfig config; - EGLContext share = NULL; - - if (ctxconfig->share) - share = ctxconfig->share->egl.context; - - if (!chooseFBConfigs(ctxconfig, fbconfig, &config)) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "EGL: Failed to find a suitable EGLConfig"); - return GL_FALSE; - } - -#if defined(_GLFW_X11) - // Retrieve the visual corresponding to the chosen EGL config - { - EGLint count = 0; - int mask; - EGLint redBits, greenBits, blueBits, alphaBits, visualID = 0; - XVisualInfo info; - - eglGetConfigAttrib(_glfw.egl.display, config, - EGL_NATIVE_VISUAL_ID, &visualID); - - info.screen = _glfw.x11.screen; - mask = VisualScreenMask; - - if (visualID) - { - // The X window visual must match the EGL config - info.visualid = visualID; - mask |= VisualIDMask; - } - else - { - // some EGL drivers don't implement the EGL_NATIVE_VISUAL_ID - // attribute, so attempt to find the closest match. - - eglGetConfigAttrib(_glfw.egl.display, config, - EGL_RED_SIZE, &redBits); - eglGetConfigAttrib(_glfw.egl.display, config, - EGL_GREEN_SIZE, &greenBits); - eglGetConfigAttrib(_glfw.egl.display, config, - EGL_BLUE_SIZE, &blueBits); - eglGetConfigAttrib(_glfw.egl.display, config, - EGL_ALPHA_SIZE, &alphaBits); - - info.depth = redBits + greenBits + blueBits + alphaBits; - mask |= VisualDepthMask; - } - - window->egl.visual = XGetVisualInfo(_glfw.x11.display, - mask, &info, &count); - if (!window->egl.visual) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "EGL: Failed to retrieve visual for EGLConfig"); - return GL_FALSE; - } - } -#endif // _GLFW_X11 - - if (ctxconfig->api == GLFW_OPENGL_ES_API) - { - if (!eglBindAPI(EGL_OPENGL_ES_API)) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "EGL: Failed to bind OpenGL ES: %s", - getErrorString(eglGetError())); - return GL_FALSE; - } - } - else - { - if (!eglBindAPI(EGL_OPENGL_API)) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "EGL: Failed to bind OpenGL: %s", - getErrorString(eglGetError())); - return GL_FALSE; - } - } - - if (_glfw.egl.KHR_create_context) - { - int index = 0, mask = 0, flags = 0, strategy = 0; - - if (ctxconfig->api == GLFW_OPENGL_API) - { - if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE) - mask |= EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR; - else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE) - mask |= EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR; - - if (ctxconfig->forward) - flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR; - - if (ctxconfig->debug) - flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR; - } - - if (ctxconfig->robustness) - { - if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION) - strategy = EGL_NO_RESET_NOTIFICATION_KHR; - else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET) - strategy = EGL_LOSE_CONTEXT_ON_RESET_KHR; - - flags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR; - } - - if (ctxconfig->major != 1 || ctxconfig->minor != 0) - { - setEGLattrib(EGL_CONTEXT_MAJOR_VERSION_KHR, ctxconfig->major); - setEGLattrib(EGL_CONTEXT_MINOR_VERSION_KHR, ctxconfig->minor); - } - - if (mask) - setEGLattrib(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, mask); - - if (flags) - setEGLattrib(EGL_CONTEXT_FLAGS_KHR, flags); - - if (strategy) - setEGLattrib(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR, strategy); - - setEGLattrib(EGL_NONE, EGL_NONE); - } - else - { - int index = 0; - - if (ctxconfig->api == GLFW_OPENGL_ES_API) - setEGLattrib(EGL_CONTEXT_CLIENT_VERSION, ctxconfig->major); - - setEGLattrib(EGL_NONE, EGL_NONE); - } - - // Context release behaviors (GL_KHR_context_flush_control) are not yet - // supported on EGL but are not a hard constraint, so ignore and continue - - window->egl.context = eglCreateContext(_glfw.egl.display, - config, share, attribs); - - if (window->egl.context == EGL_NO_CONTEXT) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "EGL: Failed to create context: %s", - getErrorString(eglGetError())); - return GL_FALSE; - } - - window->egl.config = config; - - return GL_TRUE; -} - -#undef setEGLattrib - -// Destroy the OpenGL context -// -void _glfwDestroyContext(_GLFWwindow* window) -{ -#if defined(_GLFW_X11) - if (window->egl.visual) - { - XFree(window->egl.visual); - window->egl.visual = NULL; - } -#endif // _GLFW_X11 - - if (window->egl.surface) - { - eglDestroySurface(_glfw.egl.display, window->egl.surface); - window->egl.surface = EGL_NO_SURFACE; - } - - if (window->egl.context) - { - eglDestroyContext(_glfw.egl.display, window->egl.context); - window->egl.context = EGL_NO_CONTEXT; - } -} - -// Analyzes the specified context for possible recreation -// -int _glfwAnalyzeContext(const _GLFWwindow* window, - const _GLFWctxconfig* ctxconfig, - const _GLFWfbconfig* fbconfig) -{ -#if defined(_GLFW_WIN32) - return _GLFW_RECREATION_NOT_NEEDED; -#else - return 0; -#endif -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW platform API ////// -////////////////////////////////////////////////////////////////////////// - -void _glfwPlatformMakeContextCurrent(_GLFWwindow* window) -{ - if (window) - { - if (window->egl.surface == EGL_NO_SURFACE) - { - window->egl.surface = eglCreateWindowSurface(_glfw.egl.display, - window->egl.config, - (EGLNativeWindowType)_GLFW_EGL_NATIVE_WINDOW, - NULL); - if (window->egl.surface == EGL_NO_SURFACE) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "EGL: Failed to create window surface: %s", - getErrorString(eglGetError())); - } - } - - eglMakeCurrent(_glfw.egl.display, - window->egl.surface, - window->egl.surface, - window->egl.context); - } - else - { - eglMakeCurrent(_glfw.egl.display, - EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - } - - _glfwSetCurrentContext(window); -} - -void _glfwPlatformSwapBuffers(_GLFWwindow* window) -{ - eglSwapBuffers(_glfw.egl.display, window->egl.surface); -} - -void _glfwPlatformSwapInterval(int interval) -{ - eglSwapInterval(_glfw.egl.display, interval); -} - -int _glfwPlatformExtensionSupported(const char* extension) -{ - const char* extensions; - - extensions = eglQueryString(_glfw.egl.display, EGL_EXTENSIONS); - if (extensions != NULL) - { - if (_glfwStringInExtensionString(extension, (unsigned char*) extensions)) - return GL_TRUE; - } - - return GL_FALSE; -} - -GLFWglproc _glfwPlatformGetProcAddress(const char* procname) -{ - return eglGetProcAddress(procname); -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW native API ////// -////////////////////////////////////////////////////////////////////////// - -GLFWAPI EGLDisplay glfwGetEGLDisplay(void) -{ - _GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_DISPLAY); - return _glfw.egl.display; -} - -GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* handle) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - _GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_CONTEXT); - return window->egl.context; -} - -GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* handle) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - _GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_SURFACE); - return window->egl.surface; -} - diff --git a/examples/common/glfw/src/egl_context.h b/examples/common/glfw/src/egl_context.h deleted file mode 100644 index 21d68527..00000000 --- a/examples/common/glfw/src/egl_context.h +++ /dev/null @@ -1,85 +0,0 @@ -//======================================================================== -// GLFW 3.1 EGL - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2002-2006 Marcus Geelnard -// Copyright (c) 2006-2010 Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#ifndef _egl_context_h_ -#define _egl_context_h_ - -#include - -// This path may need to be changed if you build GLFW using your own setup -// We ship and use our own copy of eglext.h since GLFW uses fairly new -// extensions and not all operating systems come with an up-to-date version -#include "../deps/EGL/eglext.h" - -// Do we have support for dlopen/dlsym? -#if defined(_GLFW_HAS_DLOPEN) - #include -#endif - -#define _GLFW_PLATFORM_FBCONFIG EGLConfig egl -#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextEGL egl -#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryEGL egl - - -// EGL-specific per-context data -// -typedef struct _GLFWcontextEGL -{ - EGLConfig config; - EGLContext context; - EGLSurface surface; - -#if defined(_GLFW_X11) - XVisualInfo* visual; -#endif - -} _GLFWcontextEGL; - - -// EGL-specific global data -// -typedef struct _GLFWlibraryEGL -{ - EGLDisplay display; - EGLint versionMajor, versionMinor; - - GLboolean KHR_create_context; - -} _GLFWlibraryEGL; - - -int _glfwInitContextAPI(void); -void _glfwTerminateContextAPI(void); -int _glfwCreateContext(_GLFWwindow* window, - const _GLFWctxconfig* ctxconfig, - const _GLFWfbconfig* fbconfig); -void _glfwDestroyContext(_GLFWwindow* window); -int _glfwAnalyzeContext(const _GLFWwindow* window, - const _GLFWctxconfig* ctxconfig, - const _GLFWfbconfig* fbconfig); - -#endif // _egl_context_h_ diff --git a/examples/common/glfw/src/glfw3.pc.in b/examples/common/glfw/src/glfw3.pc.in deleted file mode 100644 index f2e4d976..00000000 --- a/examples/common/glfw/src/glfw3.pc.in +++ /dev/null @@ -1,13 +0,0 @@ -prefix=@CMAKE_INSTALL_PREFIX@ -exec_prefix=${prefix} -includedir=${prefix}/include -libdir=${exec_prefix}/lib@LIB_SUFFIX@ - -Name: GLFW -Description: A multi-platform library for OpenGL, window and input -Version: @GLFW_VERSION_FULL@ -URL: http://www.glfw.org/ -Requires.private: @GLFW_PKG_DEPS@ -Libs: -L${libdir} -l@GLFW_LIB_NAME@ -Libs.private: @GLFW_PKG_LIBS@ -Cflags: -I${includedir} diff --git a/examples/common/glfw/src/glfw3Config.cmake.in b/examples/common/glfw/src/glfw3Config.cmake.in deleted file mode 100644 index d34df06f..00000000 --- a/examples/common/glfw/src/glfw3Config.cmake.in +++ /dev/null @@ -1,15 +0,0 @@ -# - Config file for the glfw3 package -# It defines the following variables -# GLFW3_INCLUDE_DIR, the path where GLFW headers are located -# GLFW3_LIBRARY_DIR, folder in which the GLFW library is located -# GLFW3_LIBRARY, library to link against to use GLFW - -set(GLFW3_VERSION "@GLFW_VERSION_FULL@") - -@PACKAGE_INIT@ - -set_and_check(GLFW3_INCLUDE_DIR "@PACKAGE_CMAKE_INSTALL_PREFIX@/include") -set_and_check(GLFW3_LIBRARY_DIR "@PACKAGE_CMAKE_INSTALL_PREFIX@/lib@LIB_SUFFIX@") - -find_library(GLFW3_LIBRARY "@GLFW_LIB_NAME@" HINTS ${GLFW3_LIBRARY_DIR}) - diff --git a/examples/common/glfw/src/glfw_config.h.in b/examples/common/glfw/src/glfw_config.h.in deleted file mode 100644 index 485cac58..00000000 --- a/examples/common/glfw/src/glfw_config.h.in +++ /dev/null @@ -1,87 +0,0 @@ -//======================================================================== -// GLFW 3.1 - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2010 Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== -// As glfw_config.h.in, this file is used by CMake to produce the -// glfw_config.h configuration header file. If you are adding a feature -// requiring conditional compilation, this is where to add the macro. -//======================================================================== -// As glfw_config.h, this file defines compile-time option macros for a -// specific platform and development environment. If you are using the -// GLFW CMake files, modify glfw_config.h.in instead of this file. If you -// are using your own build system, make this file define the appropriate -// macros in whatever way is suitable. -//======================================================================== - -// Define this to 1 if building GLFW for X11 -#cmakedefine _GLFW_X11 -// Define this to 1 if building GLFW for Win32 -#cmakedefine _GLFW_WIN32 -// Define this to 1 if building GLFW for Cocoa -#cmakedefine _GLFW_COCOA -// Define this to 1 if building GLFW for Wayland -#cmakedefine _GLFW_WAYLAND -// Define this to 1 if building GLFW for Mir -#cmakedefine _GLFW_MIR - -// Define this to 1 if building GLFW for EGL -#cmakedefine _GLFW_EGL -// Define this to 1 if building GLFW for GLX -#cmakedefine _GLFW_GLX -// Define this to 1 if building GLFW for WGL -#cmakedefine _GLFW_WGL -// Define this to 1 if building GLFW for NSGL -#cmakedefine _GLFW_NSGL - -// Define this to 1 if building as a shared library / dynamic library / DLL -#cmakedefine _GLFW_BUILD_DLL - -// Define this to 1 if glfwSwapInterval should ignore DWM compositing status -#cmakedefine _GLFW_USE_DWM_SWAP_INTERVAL -// Define this to 1 to force use of high-performance GPU on Optimus systems -#cmakedefine _GLFW_USE_OPTIMUS_HPG - -// Define this to 1 if glXGetProcAddress is available -#cmakedefine _GLFW_HAS_GLXGETPROCADDRESS -// Define this to 1 if glXGetProcAddressARB is available -#cmakedefine _GLFW_HAS_GLXGETPROCADDRESSARB -// Define this to 1 if glXGetProcAddressEXT is available -#cmakedefine _GLFW_HAS_GLXGETPROCADDRESSEXT -// Define this to 1 if dlopen is available -#cmakedefine _GLFW_HAS_DLOPEN - -// Define this to 1 if glfwInit should change the current directory -#cmakedefine _GLFW_USE_CHDIR -// Define this to 1 if glfwCreateWindow should populate the menu bar -#cmakedefine _GLFW_USE_MENUBAR -// Define this to 1 if windows should use full resolution on Retina displays -#cmakedefine _GLFW_USE_RETINA - -// Define this to 1 if using OpenGL as the client library -#cmakedefine _GLFW_USE_OPENGL -// Define this to 1 if using OpenGL ES 1.1 as the client library -#cmakedefine _GLFW_USE_GLESV1 -// Define this to 1 if using OpenGL ES 2.0 as the client library -#cmakedefine _GLFW_USE_GLESV2 - diff --git a/examples/common/glfw/src/glx_context.c b/examples/common/glfw/src/glx_context.c deleted file mode 100644 index 562abf7f..00000000 --- a/examples/common/glfw/src/glx_context.c +++ /dev/null @@ -1,558 +0,0 @@ -//======================================================================== -// GLFW 3.1 GLX - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2002-2006 Marcus Geelnard -// Copyright (c) 2006-2010 Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#include "internal.h" - -#include -#include -#include - - -// This is the only glXGetProcAddress variant not declared by glxext.h -void (*glXGetProcAddressEXT(const GLubyte* procName))(); - - -#ifndef GLXBadProfileARB - #define GLXBadProfileARB 13 -#endif - - -// Returns the specified attribute of the specified GLXFBConfig -// -static int getFBConfigAttrib(GLXFBConfig fbconfig, int attrib) -{ - int value; - glXGetFBConfigAttrib(_glfw.x11.display, fbconfig, attrib, &value); - return value; -} - -// Return a list of available and usable framebuffer configs -// -static GLboolean chooseFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* result) -{ - GLXFBConfig* nativeConfigs; - _GLFWfbconfig* usableConfigs; - const _GLFWfbconfig* closest; - int i, nativeCount, usableCount; - const char* vendor; - GLboolean trustWindowBit = GL_TRUE; - - vendor = glXGetClientString(_glfw.x11.display, GLX_VENDOR); - if (strcmp(vendor, "Chromium") == 0) - { - // HACK: This is a (hopefully temporary) workaround for Chromium - // (VirtualBox GL) not setting the window bit on any GLXFBConfigs - trustWindowBit = GL_FALSE; - } - - nativeConfigs = glXGetFBConfigs(_glfw.x11.display, _glfw.x11.screen, - &nativeCount); - if (!nativeCount) - { - _glfwInputError(GLFW_API_UNAVAILABLE, "GLX: No GLXFBConfigs returned"); - return GL_FALSE; - } - - usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig)); - usableCount = 0; - - for (i = 0; i < nativeCount; i++) - { - const GLXFBConfig n = nativeConfigs[i]; - _GLFWfbconfig* u = usableConfigs + usableCount; - - if (!getFBConfigAttrib(n, GLX_VISUAL_ID)) - { - // Only consider GLXFBConfigs with associated visuals - continue; - } - - if (!(getFBConfigAttrib(n, GLX_RENDER_TYPE) & GLX_RGBA_BIT)) - { - // Only consider RGBA GLXFBConfigs - continue; - } - - if (!(getFBConfigAttrib(n, GLX_DRAWABLE_TYPE) & GLX_WINDOW_BIT)) - { - if (trustWindowBit) - { - // Only consider window GLXFBConfigs - continue; - } - } - - u->redBits = getFBConfigAttrib(n, GLX_RED_SIZE); - u->greenBits = getFBConfigAttrib(n, GLX_GREEN_SIZE); - u->blueBits = getFBConfigAttrib(n, GLX_BLUE_SIZE); - - u->alphaBits = getFBConfigAttrib(n, GLX_ALPHA_SIZE); - u->depthBits = getFBConfigAttrib(n, GLX_DEPTH_SIZE); - u->stencilBits = getFBConfigAttrib(n, GLX_STENCIL_SIZE); - - u->accumRedBits = getFBConfigAttrib(n, GLX_ACCUM_RED_SIZE); - u->accumGreenBits = getFBConfigAttrib(n, GLX_ACCUM_GREEN_SIZE); - u->accumBlueBits = getFBConfigAttrib(n, GLX_ACCUM_BLUE_SIZE); - u->accumAlphaBits = getFBConfigAttrib(n, GLX_ACCUM_ALPHA_SIZE); - - u->auxBuffers = getFBConfigAttrib(n, GLX_AUX_BUFFERS); - - if (getFBConfigAttrib(n, GLX_STEREO)) - u->stereo = GL_TRUE; - if (getFBConfigAttrib(n, GLX_DOUBLEBUFFER)) - u->doublebuffer = GL_TRUE; - - if (_glfw.glx.ARB_multisample) - u->samples = getFBConfigAttrib(n, GLX_SAMPLES); - - if (_glfw.glx.ARB_framebuffer_sRGB) - u->sRGB = getFBConfigAttrib(n, GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB); - - u->glx = n; - usableCount++; - } - - closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount); - if (closest) - *result = closest->glx; - - XFree(nativeConfigs); - free(usableConfigs); - - return closest ? GL_TRUE : GL_FALSE; -} - -// Create the OpenGL context using legacy API -// -static GLXContext createLegacyContext(_GLFWwindow* window, - GLXFBConfig fbconfig, - GLXContext share) -{ - return glXCreateNewContext(_glfw.x11.display, - fbconfig, - GLX_RGBA_TYPE, - share, - True); -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW internal API ////// -////////////////////////////////////////////////////////////////////////// - -// Initialize GLX -// -int _glfwInitContextAPI(void) -{ - if (!_glfwInitTLS()) - return GL_FALSE; - -#ifdef _GLFW_DLOPEN_LIBGL - _glfw.glx.libGL = dlopen("libGL.so.1", RTLD_LAZY | RTLD_GLOBAL); - if (!_glfw.glx.libGL) - { - _glfwInputError(GLFW_PLATFORM_ERROR, "GLX: Failed to find libGL"); - return GL_FALSE; - } -#endif - - if (!glXQueryExtension(_glfw.x11.display, - &_glfw.glx.errorBase, - &_glfw.glx.eventBase)) - { - _glfwInputError(GLFW_API_UNAVAILABLE, "GLX: GLX extension not found"); - return GL_FALSE; - } - - if (!glXQueryVersion(_glfw.x11.display, - &_glfw.glx.versionMajor, - &_glfw.glx.versionMinor)) - { - _glfwInputError(GLFW_API_UNAVAILABLE, - "GLX: Failed to query GLX version"); - return GL_FALSE; - } - - if (_glfw.glx.versionMajor == 1 && _glfw.glx.versionMinor < 3) - { - _glfwInputError(GLFW_API_UNAVAILABLE, - "GLX: GLX version 1.3 is required"); - return GL_FALSE; - } - - if (_glfwPlatformExtensionSupported("GLX_EXT_swap_control")) - { - _glfw.glx.SwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC) - _glfwPlatformGetProcAddress("glXSwapIntervalEXT"); - - if (_glfw.glx.SwapIntervalEXT) - _glfw.glx.EXT_swap_control = GL_TRUE; - } - - if (_glfwPlatformExtensionSupported("GLX_SGI_swap_control")) - { - _glfw.glx.SwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC) - _glfwPlatformGetProcAddress("glXSwapIntervalSGI"); - - if (_glfw.glx.SwapIntervalSGI) - _glfw.glx.SGI_swap_control = GL_TRUE; - } - - if (_glfwPlatformExtensionSupported("GLX_MESA_swap_control")) - { - _glfw.glx.SwapIntervalMESA = (PFNGLXSWAPINTERVALMESAPROC) - _glfwPlatformGetProcAddress("glXSwapIntervalMESA"); - - if (_glfw.glx.SwapIntervalMESA) - _glfw.glx.MESA_swap_control = GL_TRUE; - } - - if (_glfwPlatformExtensionSupported("GLX_ARB_multisample")) - _glfw.glx.ARB_multisample = GL_TRUE; - - if (_glfwPlatformExtensionSupported("GLX_ARB_framebuffer_sRGB")) - _glfw.glx.ARB_framebuffer_sRGB = GL_TRUE; - - if (_glfwPlatformExtensionSupported("GLX_ARB_create_context")) - { - _glfw.glx.CreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC) - _glfwPlatformGetProcAddress("glXCreateContextAttribsARB"); - - if (_glfw.glx.CreateContextAttribsARB) - _glfw.glx.ARB_create_context = GL_TRUE; - } - - if (_glfwPlatformExtensionSupported("GLX_ARB_create_context_robustness")) - _glfw.glx.ARB_create_context_robustness = GL_TRUE; - - if (_glfwPlatformExtensionSupported("GLX_ARB_create_context_profile")) - _glfw.glx.ARB_create_context_profile = GL_TRUE; - - if (_glfwPlatformExtensionSupported("GLX_EXT_create_context_es2_profile")) - _glfw.glx.EXT_create_context_es2_profile = GL_TRUE; - - if (_glfwPlatformExtensionSupported("GLX_ARB_context_flush_control")) - _glfw.glx.ARB_context_flush_control = GL_TRUE; - - return GL_TRUE; -} - -// Terminate GLX -// -void _glfwTerminateContextAPI(void) -{ - // Unload libGL.so if necessary -#ifdef _GLFW_DLOPEN_LIBGL - if (_glfw.glx.libGL != NULL) - { - dlclose(_glfw.glx.libGL); - _glfw.glx.libGL = NULL; - } -#endif - - _glfwTerminateTLS(); -} - -#define setGLXattrib(attribName, attribValue) \ -{ \ - attribs[index++] = attribName; \ - attribs[index++] = attribValue; \ - assert((size_t) index < sizeof(attribs) / sizeof(attribs[0])); \ -} - -// Create the OpenGL or OpenGL ES context -// -int _glfwCreateContext(_GLFWwindow* window, - const _GLFWctxconfig* ctxconfig, - const _GLFWfbconfig* fbconfig) -{ - int attribs[40]; - GLXFBConfig native; - GLXContext share = NULL; - - if (ctxconfig->share) - share = ctxconfig->share->glx.context; - - if (!chooseFBConfig(fbconfig, &native)) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "GLX: Failed to find a suitable GLXFBConfig"); - return GL_FALSE; - } - - // Retrieve the corresponding visual - window->glx.visual = glXGetVisualFromFBConfig(_glfw.x11.display, native); - if (!window->glx.visual) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "GLX: Failed to retrieve visual for GLXFBConfig"); - return GL_FALSE; - } - - if (ctxconfig->api == GLFW_OPENGL_ES_API) - { - if (!_glfw.glx.ARB_create_context || - !_glfw.glx.ARB_create_context_profile || - !_glfw.glx.EXT_create_context_es2_profile) - { - _glfwInputError(GLFW_API_UNAVAILABLE, - "GLX: OpenGL ES requested but " - "GLX_EXT_create_context_es2_profile is unavailable"); - return GL_FALSE; - } - } - - if (ctxconfig->forward) - { - if (!_glfw.glx.ARB_create_context) - { - _glfwInputError(GLFW_VERSION_UNAVAILABLE, - "GLX: Forward compatibility requested but " - "GLX_ARB_create_context_profile is unavailable"); - return GL_FALSE; - } - } - - if (ctxconfig->profile) - { - if (!_glfw.glx.ARB_create_context || - !_glfw.glx.ARB_create_context_profile) - { - _glfwInputError(GLFW_VERSION_UNAVAILABLE, - "GLX: An OpenGL profile requested but " - "GLX_ARB_create_context_profile is unavailable"); - return GL_FALSE; - } - } - - _glfwGrabXErrorHandler(); - - if (_glfw.glx.ARB_create_context) - { - int index = 0, mask = 0, flags = 0, strategy = 0; - - if (ctxconfig->api == GLFW_OPENGL_API) - { - if (ctxconfig->forward) - flags |= GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; - - if (ctxconfig->debug) - flags |= GLX_CONTEXT_DEBUG_BIT_ARB; - - if (ctxconfig->profile) - { - if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE) - mask |= GLX_CONTEXT_CORE_PROFILE_BIT_ARB; - else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE) - mask |= GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; - } - } - else - mask |= GLX_CONTEXT_ES2_PROFILE_BIT_EXT; - - if (ctxconfig->robustness) - { - if (_glfw.glx.ARB_create_context_robustness) - { - if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION) - strategy = GLX_NO_RESET_NOTIFICATION_ARB; - else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET) - strategy = GLX_LOSE_CONTEXT_ON_RESET_ARB; - - flags |= GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB; - } - } - - if (ctxconfig->release) - { - if (_glfw.glx.ARB_context_flush_control) - { - if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE) - { - setGLXattrib(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB, - GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB); - } - else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH) - { - setGLXattrib(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB, - GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB); - } - } - } - - if (ctxconfig->major != 1 || ctxconfig->minor != 0) - { - // NOTE: Only request an explicitly versioned context when - // necessary, as explicitly requesting version 1.0 does not - // always return the highest available version - - setGLXattrib(GLX_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major); - setGLXattrib(GLX_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor); - } - - if (mask) - setGLXattrib(GLX_CONTEXT_PROFILE_MASK_ARB, mask); - - if (flags) - setGLXattrib(GLX_CONTEXT_FLAGS_ARB, flags); - - if (strategy) - setGLXattrib(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, strategy); - - setGLXattrib(None, None); - - window->glx.context = - _glfw.glx.CreateContextAttribsARB(_glfw.x11.display, - native, - share, - True, - attribs); - - if (!window->glx.context) - { - // HACK: This is a fallback for the broken Mesa implementation of - // GLX_ARB_create_context_profile, which fails default 1.0 - // context creation with a GLXBadProfileARB error in violation - // of the extension spec - if (_glfw.x11.errorCode == _glfw.glx.errorBase + GLXBadProfileARB && - ctxconfig->api == GLFW_OPENGL_API && - ctxconfig->profile == GLFW_OPENGL_ANY_PROFILE && - ctxconfig->forward == GL_FALSE) - { - window->glx.context = createLegacyContext(window, native, share); - } - } - } - else - window->glx.context = createLegacyContext(window, native, share); - - _glfwReleaseXErrorHandler(); - - if (!window->glx.context) - { - _glfwInputXError(GLFW_PLATFORM_ERROR, "GLX: Failed to create context"); - return GL_FALSE; - } - - return GL_TRUE; -} - -#undef setGLXattrib - -// Destroy the OpenGL context -// -void _glfwDestroyContext(_GLFWwindow* window) -{ - if (window->glx.visual) - { - XFree(window->glx.visual); - window->glx.visual = NULL; - } - - if (window->glx.context) - { - glXDestroyContext(_glfw.x11.display, window->glx.context); - window->glx.context = NULL; - } -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW platform API ////// -////////////////////////////////////////////////////////////////////////// - -void _glfwPlatformMakeContextCurrent(_GLFWwindow* window) -{ - if (window) - { - glXMakeCurrent(_glfw.x11.display, - window->x11.handle, - window->glx.context); - } - else - glXMakeCurrent(_glfw.x11.display, None, NULL); - - _glfwSetCurrentContext(window); -} - -void _glfwPlatformSwapBuffers(_GLFWwindow* window) -{ - glXSwapBuffers(_glfw.x11.display, window->x11.handle); -} - -void _glfwPlatformSwapInterval(int interval) -{ - _GLFWwindow* window = _glfwPlatformGetCurrentContext(); - - if (_glfw.glx.EXT_swap_control) - { - _glfw.glx.SwapIntervalEXT(_glfw.x11.display, - window->x11.handle, - interval); - } - else if (_glfw.glx.MESA_swap_control) - _glfw.glx.SwapIntervalMESA(interval); - else if (_glfw.glx.SGI_swap_control) - { - if (interval > 0) - _glfw.glx.SwapIntervalSGI(interval); - } -} - -int _glfwPlatformExtensionSupported(const char* extension) -{ - const GLubyte* extensions; - - // Get list of GLX extensions - extensions = (const GLubyte*) glXQueryExtensionsString(_glfw.x11.display, - _glfw.x11.screen); - if (extensions != NULL) - { - if (_glfwStringInExtensionString(extension, extensions)) - return GL_TRUE; - } - - return GL_FALSE; -} - -GLFWglproc _glfwPlatformGetProcAddress(const char* procname) -{ - return _glfw_glXGetProcAddress((const GLubyte*) procname); -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW native API ////// -////////////////////////////////////////////////////////////////////////// - -GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* handle) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - return window->glx.context; -} - diff --git a/examples/common/glfw/src/glx_context.h b/examples/common/glfw/src/glx_context.h deleted file mode 100644 index 918ab000..00000000 --- a/examples/common/glfw/src/glx_context.h +++ /dev/null @@ -1,120 +0,0 @@ -//======================================================================== -// GLFW 3.1 GLX - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2002-2006 Marcus Geelnard -// Copyright (c) 2006-2010 Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#ifndef _glx_context_h_ -#define _glx_context_h_ - -#define GLX_GLXEXT_LEGACY -#include - -// This path may need to be changed if you build GLFW using your own setup -// We ship and use our own copy of glxext.h since GLFW uses fairly new -// extensions and not all operating systems come with an up-to-date version -#include "../deps/GL/glxext.h" - -// Do we have support for dlopen/dlsym? -#if defined(_GLFW_HAS_DLOPEN) - #include -#endif - -// We support four different ways for getting addresses for GL/GLX -// extension functions: glXGetProcAddress, glXGetProcAddressARB, -// glXGetProcAddressEXT, and dlsym -#if defined(_GLFW_HAS_GLXGETPROCADDRESSARB) - #define _glfw_glXGetProcAddress(x) glXGetProcAddressARB(x) -#elif defined(_GLFW_HAS_GLXGETPROCADDRESS) - #define _glfw_glXGetProcAddress(x) glXGetProcAddress(x) -#elif defined(_GLFW_HAS_GLXGETPROCADDRESSEXT) - #define _glfw_glXGetProcAddress(x) glXGetProcAddressEXT(x) -#elif defined(_GLFW_HAS_DLOPEN) - #define _glfw_glXGetProcAddress(x) dlsym(_glfw.glx.libGL, x) - #define _GLFW_DLOPEN_LIBGL -#else - #error "No OpenGL entry point retrieval mechanism was enabled" -#endif - -#define _GLFW_PLATFORM_FBCONFIG GLXFBConfig glx -#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextGLX glx -#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryGLX glx - -#ifndef GLX_MESA_swap_control -typedef int (*PFNGLXSWAPINTERVALMESAPROC)(int); -#endif - - -// GLX-specific per-context data -// -typedef struct _GLFWcontextGLX -{ - // Rendering context - GLXContext context; - // Visual of selected GLXFBConfig - XVisualInfo* visual; - -} _GLFWcontextGLX; - - -// GLX-specific global data -// -typedef struct _GLFWlibraryGLX -{ - int versionMajor, versionMinor; - int eventBase; - int errorBase; - - // GLX extensions - PFNGLXSWAPINTERVALSGIPROC SwapIntervalSGI; - PFNGLXSWAPINTERVALEXTPROC SwapIntervalEXT; - PFNGLXSWAPINTERVALMESAPROC SwapIntervalMESA; - PFNGLXCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB; - GLboolean SGI_swap_control; - GLboolean EXT_swap_control; - GLboolean MESA_swap_control; - GLboolean ARB_multisample; - GLboolean ARB_framebuffer_sRGB; - GLboolean ARB_create_context; - GLboolean ARB_create_context_profile; - GLboolean ARB_create_context_robustness; - GLboolean EXT_create_context_es2_profile; - GLboolean ARB_context_flush_control; - -#if defined(_GLFW_DLOPEN_LIBGL) - // dlopen handle for libGL.so (for glfwGetProcAddress) - void* libGL; -#endif - -} _GLFWlibraryGLX; - - -int _glfwInitContextAPI(void); -void _glfwTerminateContextAPI(void); -int _glfwCreateContext(_GLFWwindow* window, - const _GLFWctxconfig* ctxconfig, - const _GLFWfbconfig* fbconfig); -void _glfwDestroyContext(_GLFWwindow* window); - -#endif // _glx_context_h_ diff --git a/examples/common/glfw/src/init.c b/examples/common/glfw/src/init.c deleted file mode 100644 index 4a044ed0..00000000 --- a/examples/common/glfw/src/init.c +++ /dev/null @@ -1,201 +0,0 @@ -//======================================================================== -// GLFW 3.1 - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2002-2006 Marcus Geelnard -// Copyright (c) 2006-2010 Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#include "internal.h" - -#include -#include -#include -#include - - -// The three global variables below comprise all global data in GLFW, except for -// various static const translation tables. Any other global variable is a bug. - -// Global state shared between compilation units of GLFW -// These are documented in internal.h -// -GLboolean _glfwInitialized = GL_FALSE; -_GLFWlibrary _glfw; - -// This is outside of _glfw so it can be initialized and usable before -// glfwInit is called, which lets that function report errors -// -static GLFWerrorfun _glfwErrorCallback = NULL; - - -// Returns a generic string representation of the specified error -// -static const char* getErrorString(int error) -{ - switch (error) - { - case GLFW_NOT_INITIALIZED: - return "The GLFW library is not initialized"; - case GLFW_NO_CURRENT_CONTEXT: - return "There is no current context"; - case GLFW_INVALID_ENUM: - return "Invalid argument for enum parameter"; - case GLFW_INVALID_VALUE: - return "Invalid value for parameter"; - case GLFW_OUT_OF_MEMORY: - return "Out of memory"; - case GLFW_API_UNAVAILABLE: - return "The requested client API is unavailable"; - case GLFW_VERSION_UNAVAILABLE: - return "The requested client API version is unavailable"; - case GLFW_PLATFORM_ERROR: - return "A platform-specific error occurred"; - case GLFW_FORMAT_UNAVAILABLE: - return "The requested format is unavailable"; - } - - return "ERROR: UNKNOWN ERROR TOKEN PASSED TO glfwErrorString"; -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW event API ////// -////////////////////////////////////////////////////////////////////////// - -void _glfwInputError(int error, const char* format, ...) -{ - if (_glfwErrorCallback) - { - char buffer[16384]; - const char* description; - - if (format) - { - int count; - va_list vl; - - va_start(vl, format); - count = vsnprintf(buffer, sizeof(buffer), format, vl); - va_end(vl); - - if (count < 0) - buffer[sizeof(buffer) - 1] = '\0'; - - description = buffer; - } - else - description = getErrorString(error); - - _glfwErrorCallback(error, description); - } -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW public API ////// -////////////////////////////////////////////////////////////////////////// - -GLFWAPI int glfwInit(void) -{ - if (_glfwInitialized) - return GL_TRUE; - - memset(&_glfw, 0, sizeof(_glfw)); - - if (!_glfwPlatformInit()) - { - _glfwPlatformTerminate(); - return GL_FALSE; - } - - _glfw.monitors = _glfwPlatformGetMonitors(&_glfw.monitorCount); - if (!_glfw.monitorCount) - { - _glfwInputError(GLFW_PLATFORM_ERROR, "No monitors found"); - _glfwPlatformTerminate(); - return GL_FALSE; - } - - _glfwInitialized = GL_TRUE; - - // Not all window hints have zero as their default value - glfwDefaultWindowHints(); - - return GL_TRUE; -} - -GLFWAPI void glfwTerminate(void) -{ - int i; - - if (!_glfwInitialized) - return; - - memset(&_glfw.callbacks, 0, sizeof(_glfw.callbacks)); - - while (_glfw.windowListHead) - glfwDestroyWindow((GLFWwindow*) _glfw.windowListHead); - - while (_glfw.cursorListHead) - glfwDestroyCursor((GLFWcursor*) _glfw.cursorListHead); - - for (i = 0; i < _glfw.monitorCount; i++) - { - _GLFWmonitor* monitor = _glfw.monitors[i]; - if (monitor->originalRamp.size) - _glfwPlatformSetGammaRamp(monitor, &monitor->originalRamp); - } - - _glfwFreeMonitors(_glfw.monitors, _glfw.monitorCount); - _glfw.monitors = NULL; - _glfw.monitorCount = 0; - - _glfwPlatformTerminate(); - - memset(&_glfw, 0, sizeof(_glfw)); - _glfwInitialized = GL_FALSE; -} - -GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev) -{ - if (major != NULL) - *major = GLFW_VERSION_MAJOR; - - if (minor != NULL) - *minor = GLFW_VERSION_MINOR; - - if (rev != NULL) - *rev = GLFW_VERSION_REVISION; -} - -GLFWAPI const char* glfwGetVersionString(void) -{ - return _glfwPlatformGetVersionString(); -} - -GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun) -{ - _GLFW_SWAP_POINTERS(_glfwErrorCallback, cbfun); - return cbfun; -} - diff --git a/examples/common/glfw/src/input.c b/examples/common/glfw/src/input.c deleted file mode 100644 index 74a715c9..00000000 --- a/examples/common/glfw/src/input.c +++ /dev/null @@ -1,596 +0,0 @@ -//======================================================================== -// GLFW 3.1 - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2002-2006 Marcus Geelnard -// Copyright (c) 2006-2010 Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#include "internal.h" - -#include -#if defined(_MSC_VER) - #include -#endif - -// Internal key state used for sticky keys -#define _GLFW_STICK 3 - - -// Sets the cursor mode for the specified window -// -static void setCursorMode(_GLFWwindow* window, int newMode) -{ - const int oldMode = window->cursorMode; - - if (newMode != GLFW_CURSOR_NORMAL && - newMode != GLFW_CURSOR_HIDDEN && - newMode != GLFW_CURSOR_DISABLED) - { - _glfwInputError(GLFW_INVALID_ENUM, NULL); - return; - } - - if (oldMode == newMode) - return; - - window->cursorMode = newMode; - - if (_glfw.focusedWindow == window) - { - if (oldMode == GLFW_CURSOR_DISABLED) - { - _glfwPlatformSetCursorPos(window, - _glfw.cursorPosX, - _glfw.cursorPosY); - } - else if (newMode == GLFW_CURSOR_DISABLED) - { - int width, height; - - _glfwPlatformGetCursorPos(window, - &_glfw.cursorPosX, - &_glfw.cursorPosY); - - window->cursorPosX = _glfw.cursorPosX; - window->cursorPosY = _glfw.cursorPosY; - - _glfwPlatformGetWindowSize(window, &width, &height); - _glfwPlatformSetCursorPos(window, width / 2, height / 2); - } - - _glfwPlatformApplyCursorMode(window); - } -} - -// Set sticky keys mode for the specified window -// -static void setStickyKeys(_GLFWwindow* window, int enabled) -{ - if (window->stickyKeys == enabled) - return; - - if (!enabled) - { - int i; - - // Release all sticky keys - for (i = 0; i <= GLFW_KEY_LAST; i++) - { - if (window->keys[i] == _GLFW_STICK) - window->keys[i] = GLFW_RELEASE; - } - } - - window->stickyKeys = enabled; -} - -// Set sticky mouse buttons mode for the specified window -// -static void setStickyMouseButtons(_GLFWwindow* window, int enabled) -{ - if (window->stickyMouseButtons == enabled) - return; - - if (!enabled) - { - int i; - - // Release all sticky mouse buttons - for (i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i++) - { - if (window->mouseButtons[i] == _GLFW_STICK) - window->mouseButtons[i] = GLFW_RELEASE; - } - } - - window->stickyMouseButtons = enabled; -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW event API ////// -////////////////////////////////////////////////////////////////////////// - -void _glfwInputKey(_GLFWwindow* window, int key, int scancode, int action, int mods) -{ - if (key >= 0 && key <= GLFW_KEY_LAST) - { - GLboolean repeated = GL_FALSE; - - if (action == GLFW_RELEASE && window->keys[key] == GLFW_RELEASE) - return; - - if (action == GLFW_PRESS && window->keys[key] == GLFW_PRESS) - repeated = GL_TRUE; - - if (action == GLFW_RELEASE && window->stickyKeys) - window->keys[key] = _GLFW_STICK; - else - window->keys[key] = (char) action; - - if (repeated) - action = GLFW_REPEAT; - } - - if (window->callbacks.key) - window->callbacks.key((GLFWwindow*) window, key, scancode, action, mods); -} - -void _glfwInputChar(_GLFWwindow* window, unsigned int codepoint, int mods, int plain) -{ - if (codepoint < 32 || (codepoint > 126 && codepoint < 160)) - return; - - if (window->callbacks.charmods) - window->callbacks.charmods((GLFWwindow*) window, codepoint, mods); - - if (plain) - { - if (window->callbacks.character) - window->callbacks.character((GLFWwindow*) window, codepoint); - } -} - -void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset) -{ - if (window->callbacks.scroll) - window->callbacks.scroll((GLFWwindow*) window, xoffset, yoffset); -} - -void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods) -{ - if (button < 0 || button > GLFW_MOUSE_BUTTON_LAST) - return; - - // Register mouse button action - if (action == GLFW_RELEASE && window->stickyMouseButtons) - window->mouseButtons[button] = _GLFW_STICK; - else - window->mouseButtons[button] = (char) action; - - if (window->callbacks.mouseButton) - window->callbacks.mouseButton((GLFWwindow*) window, button, action, mods); -} - -void _glfwInputCursorMotion(_GLFWwindow* window, double x, double y) -{ - if (window->cursorMode == GLFW_CURSOR_DISABLED) - { - if (x == 0.0 && y == 0.0) - return; - - window->cursorPosX += x; - window->cursorPosY += y; - - x = window->cursorPosX; - y = window->cursorPosY; - } - - if (window->callbacks.cursorPos) - window->callbacks.cursorPos((GLFWwindow*) window, x, y); -} - -void _glfwInputCursorEnter(_GLFWwindow* window, int entered) -{ - if (window->callbacks.cursorEnter) - window->callbacks.cursorEnter((GLFWwindow*) window, entered); -} - -void _glfwInputDrop(_GLFWwindow* window, int count, const char** names) -{ - if (window->callbacks.drop) - window->callbacks.drop((GLFWwindow*) window, count, names); -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW public API ////// -////////////////////////////////////////////////////////////////////////// - -GLFWAPI int glfwGetInputMode(GLFWwindow* handle, int mode) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - - _GLFW_REQUIRE_INIT_OR_RETURN(0); - - switch (mode) - { - case GLFW_CURSOR: - return window->cursorMode; - case GLFW_STICKY_KEYS: - return window->stickyKeys; - case GLFW_STICKY_MOUSE_BUTTONS: - return window->stickyMouseButtons; - default: - _glfwInputError(GLFW_INVALID_ENUM, NULL); - return 0; - } -} - -GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - - _GLFW_REQUIRE_INIT(); - - switch (mode) - { - case GLFW_CURSOR: - setCursorMode(window, value); - break; - case GLFW_STICKY_KEYS: - setStickyKeys(window, value ? GL_TRUE : GL_FALSE); - break; - case GLFW_STICKY_MOUSE_BUTTONS: - setStickyMouseButtons(window, value ? GL_TRUE : GL_FALSE); - break; - default: - _glfwInputError(GLFW_INVALID_ENUM, NULL); - break; - } -} - -GLFWAPI int glfwGetKey(GLFWwindow* handle, int key) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - - _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_RELEASE); - - if (key < 0 || key > GLFW_KEY_LAST) - { - _glfwInputError(GLFW_INVALID_ENUM, "The specified key is invalid"); - return GLFW_RELEASE; - } - - if (window->keys[key] == _GLFW_STICK) - { - // Sticky mode: release key now - window->keys[key] = GLFW_RELEASE; - return GLFW_PRESS; - } - - return (int) window->keys[key]; -} - -GLFWAPI int glfwGetMouseButton(GLFWwindow* handle, int button) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - - _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_RELEASE); - - if (button < 0 || button > GLFW_MOUSE_BUTTON_LAST) - { - _glfwInputError(GLFW_INVALID_ENUM, - "The specified mouse button is invalid"); - return GLFW_RELEASE; - } - - if (window->mouseButtons[button] == _GLFW_STICK) - { - // Sticky mode: release mouse button now - window->mouseButtons[button] = GLFW_RELEASE; - return GLFW_PRESS; - } - - return (int) window->mouseButtons[button]; -} - -GLFWAPI void glfwGetCursorPos(GLFWwindow* handle, double* xpos, double* ypos) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - - if (xpos) - *xpos = 0; - if (ypos) - *ypos = 0; - - _GLFW_REQUIRE_INIT(); - - if (window->cursorMode == GLFW_CURSOR_DISABLED) - { - if (xpos) - *xpos = window->cursorPosX; - if (ypos) - *ypos = window->cursorPosY; - } - else - _glfwPlatformGetCursorPos(window, xpos, ypos); -} - -GLFWAPI void glfwSetCursorPos(GLFWwindow* handle, double xpos, double ypos) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - - _GLFW_REQUIRE_INIT(); - - if (_glfw.focusedWindow != window) - return; - - if (window->cursorMode == GLFW_CURSOR_DISABLED) - { - // Only update the accumulated position if the cursor is disabled - window->cursorPosX = xpos; - window->cursorPosY = ypos; - } - else - { - // Update system cursor position - _glfwPlatformSetCursorPos(window, xpos, ypos); - } -} - -GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot) -{ - _GLFWcursor* cursor; - - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - - cursor = calloc(1, sizeof(_GLFWcursor)); - cursor->next = _glfw.cursorListHead; - _glfw.cursorListHead = cursor; - - if (!_glfwPlatformCreateCursor(cursor, image, xhot, yhot)) - { - glfwDestroyCursor((GLFWcursor*) cursor); - return NULL; - } - - return (GLFWcursor*) cursor; -} - -GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape) -{ - _GLFWcursor* cursor; - - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - - cursor = calloc(1, sizeof(_GLFWcursor)); - cursor->next = _glfw.cursorListHead; - _glfw.cursorListHead = cursor; - - if (!_glfwPlatformCreateStandardCursor(cursor, shape)) - { - glfwDestroyCursor((GLFWcursor*) cursor); - return NULL; - } - - return (GLFWcursor*) cursor; -} - -GLFWAPI void glfwDestroyCursor(GLFWcursor* handle) -{ - _GLFWcursor* cursor = (_GLFWcursor*) handle; - - _GLFW_REQUIRE_INIT(); - - if (cursor == NULL) - return; - - // Make sure the cursor is not being used by any window - { - _GLFWwindow* window; - - for (window = _glfw.windowListHead; window; window = window->next) - { - if (window->cursor == cursor) - glfwSetCursor((GLFWwindow*) window, NULL); - } - } - - _glfwPlatformDestroyCursor(cursor); - - // Unlink cursor from global linked list - { - _GLFWcursor** prev = &_glfw.cursorListHead; - - while (*prev != cursor) - prev = &((*prev)->next); - - *prev = cursor->next; - } - - free(cursor); -} - -GLFWAPI void glfwSetCursor(GLFWwindow* windowHandle, GLFWcursor* cursorHandle) -{ - _GLFWwindow* window = (_GLFWwindow*) windowHandle; - _GLFWcursor* cursor = (_GLFWcursor*) cursorHandle; - - _GLFW_REQUIRE_INIT(); - - _glfwPlatformSetCursor(window, cursor); - - window->cursor = cursor; -} - -GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* handle, GLFWkeyfun cbfun) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.key, cbfun); - return cbfun; -} - -GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* handle, GLFWcharfun cbfun) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.character, cbfun); - return cbfun; -} - -GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* handle, GLFWcharmodsfun cbfun) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.charmods, cbfun); - return cbfun; -} - -GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* handle, - GLFWmousebuttonfun cbfun) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.mouseButton, cbfun); - return cbfun; -} - -GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* handle, - GLFWcursorposfun cbfun) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.cursorPos, cbfun); - return cbfun; -} - -GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* handle, - GLFWcursorenterfun cbfun) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.cursorEnter, cbfun); - return cbfun; -} - -GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* handle, - GLFWscrollfun cbfun) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.scroll, cbfun); - return cbfun; -} - -GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* handle, GLFWdropfun cbfun) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.drop, cbfun); - return cbfun; -} - -GLFWAPI int glfwJoystickPresent(int joy) -{ - _GLFW_REQUIRE_INIT_OR_RETURN(0); - - if (joy < 0 || joy > GLFW_JOYSTICK_LAST) - { - _glfwInputError(GLFW_INVALID_ENUM, NULL); - return 0; - } - - return _glfwPlatformJoystickPresent(joy); -} - -GLFWAPI const float* glfwGetJoystickAxes(int joy, int* count) -{ - *count = 0; - - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - - if (joy < 0 || joy > GLFW_JOYSTICK_LAST) - { - _glfwInputError(GLFW_INVALID_ENUM, NULL); - return NULL; - } - - return _glfwPlatformGetJoystickAxes(joy, count); -} - -GLFWAPI const unsigned char* glfwGetJoystickButtons(int joy, int* count) -{ - *count = 0; - - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - - if (joy < 0 || joy > GLFW_JOYSTICK_LAST) - { - _glfwInputError(GLFW_INVALID_ENUM, NULL); - return NULL; - } - - return _glfwPlatformGetJoystickButtons(joy, count); -} - -GLFWAPI const char* glfwGetJoystickName(int joy) -{ - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - - if (joy < 0 || joy > GLFW_JOYSTICK_LAST) - { - _glfwInputError(GLFW_INVALID_ENUM, NULL); - return NULL; - } - - return _glfwPlatformGetJoystickName(joy); -} - -GLFWAPI void glfwSetClipboardString(GLFWwindow* handle, const char* string) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - _GLFW_REQUIRE_INIT(); - _glfwPlatformSetClipboardString(window, string); -} - -GLFWAPI const char* glfwGetClipboardString(GLFWwindow* handle) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - return _glfwPlatformGetClipboardString(window); -} - -GLFWAPI double glfwGetTime(void) -{ - _GLFW_REQUIRE_INIT_OR_RETURN(0.0); - return _glfwPlatformGetTime(); -} - -GLFWAPI void glfwSetTime(double time) -{ - _GLFW_REQUIRE_INIT(); - _glfwPlatformSetTime(time); -} - diff --git a/examples/common/glfw/src/internal.h b/examples/common/glfw/src/internal.h deleted file mode 100644 index 1e6977ff..00000000 --- a/examples/common/glfw/src/internal.h +++ /dev/null @@ -1,886 +0,0 @@ -//======================================================================== -// GLFW 3.1 - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2002-2006 Marcus Geelnard -// Copyright (c) 2006-2010 Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#ifndef _internal_h_ -#define _internal_h_ - - -#if defined(_GLFW_USE_CONFIG_H) - #include "glfw_config.h" -#endif - -#define _GLFW_VERSION_NUMBER "3.1.0" - -#if defined(_GLFW_USE_OPENGL) - // This is the default for glfw3.h -#elif defined(_GLFW_USE_GLESV1) - #define GLFW_INCLUDE_ES1 -#elif defined(_GLFW_USE_GLESV2) - #define GLFW_INCLUDE_ES2 -#else - #error "No supported client library selected" -#endif - -// Disable the inclusion of the platform glext.h by gl.h to allow proper -// inclusion of our own, newer glext.h below -#define GL_GLEXT_LEGACY - -#include "../include/GLFW/glfw3.h" - -#if defined(_GLFW_USE_OPENGL) - // This path may need to be changed if you build GLFW using your own setup - // GLFW comes with its own copy of glext.h since it uses fairly new extensions - // and not all development environments come with an up-to-date version - #include "../deps/GL/glext.h" -#endif - -typedef struct _GLFWwndconfig _GLFWwndconfig; -typedef struct _GLFWctxconfig _GLFWctxconfig; -typedef struct _GLFWfbconfig _GLFWfbconfig; -typedef struct _GLFWwindow _GLFWwindow; -typedef struct _GLFWlibrary _GLFWlibrary; -typedef struct _GLFWmonitor _GLFWmonitor; -typedef struct _GLFWcursor _GLFWcursor; - -#if defined(_GLFW_COCOA) - #include "cocoa_platform.h" -#elif defined(_GLFW_WIN32) - #include "win32_platform.h" -#elif defined(_GLFW_X11) - #include "x11_platform.h" -#elif defined(_GLFW_WAYLAND) - #include "wl_platform.h" -#elif defined(_GLFW_MIR) - #include "mir_platform.h" -#else - #error "No supported window creation API selected" -#endif - - -//======================================================================== -// Doxygen group definitions -//======================================================================== - -/*! @defgroup platform Platform interface - * @brief The interface implemented by the platform-specific code. - * - * The platform API is the interface exposed by the platform-specific code for - * each platform and is called by the shared code of the public API It mirrors - * the public API except it uses objects instead of handles. - */ -/*! @defgroup event Event interface - * @brief The interface used by the platform-specific code to report events. - * - * The event API is used by the platform-specific code to notify the shared - * code of events that can be translated into state changes and/or callback - * calls. - */ -/*! @defgroup utility Utility functions - * @brief Various utility functions for internal use. - * - * These functions are shared code and may be used by any part of GLFW - * Each platform may add its own utility functions, but those may only be - * called by the platform-specific code - */ - - -//======================================================================== -// Helper macros -//======================================================================== - -// Checks for whether the library has been initialized -#define _GLFW_REQUIRE_INIT() \ - if (!_glfwInitialized) \ - { \ - _glfwInputError(GLFW_NOT_INITIALIZED, NULL); \ - return; \ - } -#define _GLFW_REQUIRE_INIT_OR_RETURN(x) \ - if (!_glfwInitialized) \ - { \ - _glfwInputError(GLFW_NOT_INITIALIZED, NULL); \ - return x; \ - } - -// Swaps the provided pointers -#define _GLFW_SWAP_POINTERS(x, y) \ - { \ - void* t; \ - t = x; \ - x = y; \ - y = t; \ - } - - -//======================================================================== -// Platform-independent structures -//======================================================================== - -/*! @brief Window configuration. - * - * Parameters relating to the creation of the window but not directly related - * to the framebuffer. This is used to pass window creation parameters from - * shared code to the platform API. - */ -struct _GLFWwndconfig -{ - int width; - int height; - const char* title; - GLboolean resizable; - GLboolean visible; - GLboolean decorated; - GLboolean focused; - GLboolean autoIconify; - GLboolean floating; - _GLFWmonitor* monitor; -}; - - -/*! @brief Context configuration. - * - * Parameters relating to the creation of the context but not directly related - * to the framebuffer. This is used to pass context creation parameters from - * shared code to the platform API. - */ -struct _GLFWctxconfig -{ - int api; - int major; - int minor; - GLboolean forward; - GLboolean debug; - int profile; - int robustness; - int release; - _GLFWwindow* share; -}; - - -/*! @brief Framebuffer configuration. - * - * This describes buffers and their sizes. It also contains - * a platform-specific ID used to map back to the backend API object. - * - * It is used to pass framebuffer parameters from shared code to the platform - * API and also to enumerate and select available framebuffer configs. - */ -struct _GLFWfbconfig -{ - int redBits; - int greenBits; - int blueBits; - int alphaBits; - int depthBits; - int stencilBits; - int accumRedBits; - int accumGreenBits; - int accumBlueBits; - int accumAlphaBits; - int auxBuffers; - int stereo; - int samples; - int sRGB; - int doublebuffer; - - // This is defined in the context API's context.h - _GLFW_PLATFORM_FBCONFIG; -}; - - -/*! @brief Window and context structure. - */ -struct _GLFWwindow -{ - struct _GLFWwindow* next; - - // Window settings and state - GLboolean resizable; - GLboolean decorated; - GLboolean autoIconify; - GLboolean floating; - GLboolean closed; - void* userPointer; - GLFWvidmode videoMode; - _GLFWmonitor* monitor; - _GLFWcursor* cursor; - - // Window input state - GLboolean stickyKeys; - GLboolean stickyMouseButtons; - double cursorPosX, cursorPosY; - int cursorMode; - char mouseButtons[GLFW_MOUSE_BUTTON_LAST + 1]; - char keys[GLFW_KEY_LAST + 1]; - - // OpenGL extensions and context attributes - struct { - int api; - int major, minor, revision; - GLboolean forward, debug; - int profile; - int robustness; - int release; - } context; - -#if defined(_GLFW_USE_OPENGL) - PFNGLGETSTRINGIPROC GetStringi; -#endif - - struct { - GLFWwindowposfun pos; - GLFWwindowsizefun size; - GLFWwindowclosefun close; - GLFWwindowrefreshfun refresh; - GLFWwindowfocusfun focus; - GLFWwindowiconifyfun iconify; - GLFWframebuffersizefun fbsize; - GLFWmousebuttonfun mouseButton; - GLFWcursorposfun cursorPos; - GLFWcursorenterfun cursorEnter; - GLFWscrollfun scroll; - GLFWkeyfun key; - GLFWcharfun character; - GLFWcharmodsfun charmods; - GLFWdropfun drop; - } callbacks; - - // This is defined in the window API's platform.h - _GLFW_PLATFORM_WINDOW_STATE; - // This is defined in the context API's context.h - _GLFW_PLATFORM_CONTEXT_STATE; -}; - - -/*! @brief Monitor structure. - */ -struct _GLFWmonitor -{ - char* name; - - // Physical dimensions in millimeters. - int widthMM, heightMM; - - GLFWvidmode* modes; - int modeCount; - GLFWvidmode currentMode; - - GLFWgammaramp originalRamp; - GLFWgammaramp currentRamp; - - // This is defined in the window API's platform.h - _GLFW_PLATFORM_MONITOR_STATE; -}; - - -/*! @brief Cursor structure - */ -struct _GLFWcursor -{ - _GLFWcursor* next; - - // This is defined in the window API's platform.h - _GLFW_PLATFORM_CURSOR_STATE; -}; - -/*! @brief Library global data. - */ -struct _GLFWlibrary -{ - struct { - int redBits; - int greenBits; - int blueBits; - int alphaBits; - int depthBits; - int stencilBits; - int accumRedBits; - int accumGreenBits; - int accumBlueBits; - int accumAlphaBits; - int auxBuffers; - int stereo; - int resizable; - int visible; - int decorated; - int focused; - int autoIconify; - int floating; - int samples; - int sRGB; - int refreshRate; - int doublebuffer; - int api; - int major; - int minor; - int forward; - int debug; - int profile; - int robustness; - int release; - } hints; - - double cursorPosX, cursorPosY; - - _GLFWcursor* cursorListHead; - - _GLFWwindow* windowListHead; - _GLFWwindow* focusedWindow; - - _GLFWmonitor** monitors; - int monitorCount; - - struct { - GLFWmonitorfun monitor; - } callbacks; - - // This is defined in the window API's platform.h - _GLFW_PLATFORM_LIBRARY_WINDOW_STATE; - // This is defined in the context API's context.h - _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE; - // This is defined in the platform's time.h - _GLFW_PLATFORM_LIBRARY_TIME_STATE; - // This is defined in the platform's joystick.h - _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE; - // This is defined in the platform's tls.h - _GLFW_PLATFORM_LIBRARY_TLS_STATE; -}; - - -//======================================================================== -// Global state shared between compilation units of GLFW -//======================================================================== - -/*! @brief Flag indicating whether GLFW has been successfully initialized. - */ -extern GLboolean _glfwInitialized; - -/*! @brief All global data protected by @ref _glfwInitialized. - * This should only be touched after a call to @ref glfwInit that has not been - * followed by a call to @ref glfwTerminate. - */ -extern _GLFWlibrary _glfw; - - -//======================================================================== -// Platform API functions -//======================================================================== - -/*! @brief Initializes the platform-specific part of the library. - * @return `GL_TRUE` if successful, or `GL_FALSE` if an error occurred. - * @ingroup platform - */ -int _glfwPlatformInit(void); - -/*! @brief Terminates the platform-specific part of the library. - * @ingroup platform - */ -void _glfwPlatformTerminate(void); - -/*! @copydoc glfwGetVersionString - * @ingroup platform - * - * @note The returned string must be available for the duration of the program. - * - * @note The returned string must not change for the duration of the program. - */ -const char* _glfwPlatformGetVersionString(void); - -/*! @copydoc glfwGetCursorPos - * @ingroup platform - */ -void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos); - -/*! @copydoc glfwSetCursorPos - * @ingroup platform - */ -void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos); - -/*! @brief Applies the cursor mode of the specified window to the system. - * @param[in] window The window whose cursor mode to apply. - * @ingroup platform - */ -void _glfwPlatformApplyCursorMode(_GLFWwindow* window); - -/*! @copydoc glfwGetMonitors - * @ingroup platform - */ -_GLFWmonitor** _glfwPlatformGetMonitors(int* count); - -/*! @brief Checks whether two monitor objects represent the same monitor. - * - * @param[in] first The first monitor. - * @param[in] second The second monitor. - * @return @c GL_TRUE if the monitor objects represent the same monitor, or @c - * GL_FALSE otherwise. - * @ingroup platform - */ -GLboolean _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second); - -/*! @copydoc glfwGetMonitorPos - * @ingroup platform - */ -void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos); - -/*! @copydoc glfwGetVideoModes - * @ingroup platform - */ -GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count); - -/*! @ingroup platform - */ -void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode); - -/*! @copydoc glfwGetGammaRamp - * @ingroup platform - */ -void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp); - -/*! @copydoc glfwSetGammaRamp - * @ingroup platform - */ -void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp); - -/*! @copydoc glfwSetClipboardString - * @ingroup platform - */ -void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string); - -/*! @copydoc glfwGetClipboardString - * @ingroup platform - * - * @note The returned string must be valid until the next call to @ref - * _glfwPlatformGetClipboardString or @ref _glfwPlatformSetClipboardString. - */ -const char* _glfwPlatformGetClipboardString(_GLFWwindow* window); - -/*! @copydoc glfwJoystickPresent - * @ingroup platform - */ -int _glfwPlatformJoystickPresent(int joy); - -/*! @copydoc glfwGetJoystickAxes - * @ingroup platform - */ -const float* _glfwPlatformGetJoystickAxes(int joy, int* count); - -/*! @copydoc glfwGetJoystickButtons - * @ingroup platform - */ -const unsigned char* _glfwPlatformGetJoystickButtons(int joy, int* count); - -/*! @copydoc glfwGetJoystickName - * @ingroup platform - */ -const char* _glfwPlatformGetJoystickName(int joy); - -/*! @copydoc glfwGetTime - * @ingroup platform - */ -double _glfwPlatformGetTime(void); - -/*! @copydoc glfwSetTime - * @ingroup platform - */ -void _glfwPlatformSetTime(double time); - -/*! @ingroup platform - */ -int _glfwPlatformCreateWindow(_GLFWwindow* window, - const _GLFWwndconfig* wndconfig, - const _GLFWctxconfig* ctxconfig, - const _GLFWfbconfig* fbconfig); - -/*! @ingroup platform - */ -void _glfwPlatformDestroyWindow(_GLFWwindow* window); - -/*! @copydoc glfwSetWindowTitle - * @ingroup platform - */ -void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title); - -/*! @copydoc glfwGetWindowPos - * @ingroup platform - */ -void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos); - -/*! @copydoc glfwSetWindowPos - * @ingroup platform - */ -void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos); - -/*! @copydoc glfwGetWindowSize - * @ingroup platform - */ -void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height); - -/*! @copydoc glfwSetWindowSize - * @ingroup platform - */ -void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height); - -/*! @copydoc glfwGetFramebufferSize - * @ingroup platform - */ -void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height); - -/*! @copydoc glfwGetWindowFrameSize - * @ingroup platform - */ -void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, int* left, int* top, int* right, int* bottom); - -/*! @copydoc glfwIconifyWindow - * @ingroup platform - */ -void _glfwPlatformIconifyWindow(_GLFWwindow* window); - -/*! @copydoc glfwRestoreWindow - * @ingroup platform - */ -void _glfwPlatformRestoreWindow(_GLFWwindow* window); - -/*! @copydoc glfwShowWindow - * @ingroup platform - */ -void _glfwPlatformShowWindow(_GLFWwindow* window); - -/*! @ingroup platform - */ -void _glfwPlatformUnhideWindow(_GLFWwindow* window); - -/*! @copydoc glfwHideWindow - * @ingroup platform - */ -void _glfwPlatformHideWindow(_GLFWwindow* window); - -/*! @brief Returns whether the window is focused. - * @ingroup platform - */ -int _glfwPlatformWindowFocused(_GLFWwindow* window); - -/*! @brief Returns whether the window is iconified. - * @ingroup platform - */ -int _glfwPlatformWindowIconified(_GLFWwindow* window); - -/*! @brief Returns whether the window is visible. - * @ingroup platform - */ -int _glfwPlatformWindowVisible(_GLFWwindow* window); - -/*! @copydoc glfwPollEvents - * @ingroup platform - */ -void _glfwPlatformPollEvents(void); - -/*! @copydoc glfwWaitEvents - * @ingroup platform - */ -void _glfwPlatformWaitEvents(void); - -/*! @copydoc glfwPostEmptyEvent - * @ingroup platform - */ -void _glfwPlatformPostEmptyEvent(void); - -/*! @copydoc glfwMakeContextCurrent - * @ingroup platform - */ -void _glfwPlatformMakeContextCurrent(_GLFWwindow* window); - -/*! @copydoc glfwGetCurrentContext - * @ingroup platform - */ -_GLFWwindow* _glfwPlatformGetCurrentContext(void); - -/*! @copydoc glfwSwapBuffers - * @ingroup platform - */ -void _glfwPlatformSwapBuffers(_GLFWwindow* window); - -/*! @copydoc glfwSwapInterval - * @ingroup platform - */ -void _glfwPlatformSwapInterval(int interval); - -/*! @copydoc glfwExtensionSupported - * @ingroup platform - */ -int _glfwPlatformExtensionSupported(const char* extension); - -/*! @copydoc glfwGetProcAddress - * @ingroup platform - */ -GLFWglproc _glfwPlatformGetProcAddress(const char* procname); - -/*! @copydoc glfwCreateCursor - * @ingroup platform - */ -int _glfwPlatformCreateCursor(_GLFWcursor* cursor, const GLFWimage* image, int xhot, int yhot); - -/*! @copydoc glfwCreateStandardCursor - * @ingroup platform - */ -int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape); - -/*! @copydoc glfwDestroyCursor - * @ingroup platform - */ -void _glfwPlatformDestroyCursor(_GLFWcursor* cursor); - -/*! @copydoc glfwSetCursor - * @ingroup platform - */ -void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor); - - -//======================================================================== -// Event API functions -//======================================================================== - -/*! @brief Notifies shared code of a window focus event. - * @param[in] window The window that received the event. - * @param[in] focused `GL_TRUE` if the window received focus, or `GL_FALSE` - * if it lost focus. - * @ingroup event - */ -void _glfwInputWindowFocus(_GLFWwindow* window, GLboolean focused); - -/*! @brief Notifies shared code of a window movement event. - * @param[in] window The window that received the event. - * @param[in] xpos The new x-coordinate of the client area of the window. - * @param[in] ypos The new y-coordinate of the client area of the window. - * @ingroup event - */ -void _glfwInputWindowPos(_GLFWwindow* window, int xpos, int ypos); - -/*! @brief Notifies shared code of a window resize event. - * @param[in] window The window that received the event. - * @param[in] width The new width of the client area of the window. - * @param[in] height The new height of the client area of the window. - * @ingroup event - */ -void _glfwInputWindowSize(_GLFWwindow* window, int width, int height); - -/*! @brief Notifies shared code of a framebuffer resize event. - * @param[in] window The window that received the event. - * @param[in] width The new width, in pixels, of the framebuffer. - * @param[in] height The new height, in pixels, of the framebuffer. - * @ingroup event - */ -void _glfwInputFramebufferSize(_GLFWwindow* window, int width, int height); - -/*! @brief Notifies shared code of a window iconification event. - * @param[in] window The window that received the event. - * @param[in] iconified `GL_TRUE` if the window was iconified, or `GL_FALSE` - * if it was restored. - * @ingroup event - */ -void _glfwInputWindowIconify(_GLFWwindow* window, int iconified); - -/*! @brief Notifies shared code of a window damage event. - * @param[in] window The window that received the event. - */ -void _glfwInputWindowDamage(_GLFWwindow* window); - -/*! @brief Notifies shared code of a window close request event - * @param[in] window The window that received the event. - * @ingroup event - */ -void _glfwInputWindowCloseRequest(_GLFWwindow* window); - -/*! @brief Notifies shared code of a physical key event. - * @param[in] window The window that received the event. - * @param[in] key The key that was pressed or released. - * @param[in] scancode The system-specific scan code of the key. - * @param[in] action @ref GLFW_PRESS or @ref GLFW_RELEASE. - * @param[in] mods The modifiers pressed when the event was generated. - * @ingroup event - */ -void _glfwInputKey(_GLFWwindow* window, int key, int scancode, int action, int mods); - -/*! @brief Notifies shared code of a Unicode character input event. - * @param[in] window The window that received the event. - * @param[in] codepoint The Unicode code point of the input character. - * @param[in] mods Bit field describing which modifier keys were held down. - * @param[in] plain `GL_TRUE` if the character is regular text input, or - * `GL_FALSE` otherwise. - * @ingroup event - */ -void _glfwInputChar(_GLFWwindow* window, unsigned int codepoint, int mods, int plain); - -/*! @brief Notifies shared code of a scroll event. - * @param[in] window The window that received the event. - * @param[in] x The scroll offset along the x-axis. - * @param[in] y The scroll offset along the y-axis. - * @ingroup event - */ -void _glfwInputScroll(_GLFWwindow* window, double x, double y); - -/*! @brief Notifies shared code of a mouse button click event. - * @param[in] window The window that received the event. - * @param[in] button The button that was pressed or released. - * @param[in] action @ref GLFW_PRESS or @ref GLFW_RELEASE. - * @ingroup event - */ -void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods); - -/*! @brief Notifies shared code of a cursor motion event. - * @param[in] window The window that received the event. - * @param[in] x The new x-coordinate of the cursor, relative to the left edge - * of the client area of the window. - * @param[in] y The new y-coordinate of the cursor, relative to the top edge - * of the client area of the window. - * @ingroup event - */ -void _glfwInputCursorMotion(_GLFWwindow* window, double x, double y); - -/*! @brief Notifies shared code of a cursor enter/leave event. - * @param[in] window The window that received the event. - * @param[in] entered `GL_TRUE` if the cursor entered the client area of the - * window, or `GL_FALSE` if it left it. - * @ingroup event - */ -void _glfwInputCursorEnter(_GLFWwindow* window, int entered); - -/*! @ingroup event - */ -void _glfwInputMonitorChange(void); - -/*! @brief Notifies shared code of an error. - * @param[in] error The error code most suitable for the error. - * @param[in] format The `printf` style format string of the error - * description. - * @ingroup event - */ -void _glfwInputError(int error, const char* format, ...); - -/*! @brief Notifies dropped object over window. - * @param[in] window The window that received the event. - * @param[in] count The number of dropped objects. - * @param[in] names The names of the dropped objects. - * @ingroup event - */ -void _glfwInputDrop(_GLFWwindow* window, int count, const char** names); - - -//======================================================================== -// Utility functions -//======================================================================== - -/*! @ingroup utility - */ -const GLFWvidmode* _glfwChooseVideoMode(_GLFWmonitor* monitor, - const GLFWvidmode* desired); - -/*! @brief Performs lexical comparison between two @ref GLFWvidmode structures. - * @ingroup utility - */ -int _glfwCompareVideoModes(const GLFWvidmode* first, const GLFWvidmode* second); - -/*! @brief Splits a color depth into red, green and blue bit depths. - * @ingroup utility - */ -void _glfwSplitBPP(int bpp, int* red, int* green, int* blue); - -/*! @brief Searches an extension string for the specified extension. - * @param[in] string The extension string to search. - * @param[in] extensions The extension to search for. - * @return `GL_TRUE` if the extension was found, or `GL_FALSE` otherwise. - * @ingroup utility - */ -int _glfwStringInExtensionString(const char* string, const GLubyte* extensions); - -/*! @brief Chooses the framebuffer config that best matches the desired one. - * @param[in] desired The desired framebuffer config. - * @param[in] alternatives The framebuffer configs supported by the system. - * @param[in] count The number of entries in the alternatives array. - * @return The framebuffer config most closely matching the desired one, or @c - * NULL if none fulfilled the hard constraints of the desired values. - * @ingroup utility - */ -const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired, - const _GLFWfbconfig* alternatives, - unsigned int count); - -/*! @brief Retrieves the attributes of the current context. - * @param[in] ctxconfig The desired context attributes. - * @return `GL_TRUE` if successful, or `GL_FALSE` if the context is unusable. - * @ingroup utility - */ -GLboolean _glfwRefreshContextAttribs(const _GLFWctxconfig* ctxconfig); - -/*! @brief Checks whether the desired context attributes are valid. - * @param[in] ctxconfig The context attributes to check. - * @return `GL_TRUE` if the context attributes are valid, or `GL_FALSE` - * otherwise. - * @ingroup utility - * - * This function checks things like whether the specified client API version - * exists and whether all relevant options have supported and non-conflicting - * values. - */ -GLboolean _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig); - -/*! @brief Checks whether the current context fulfils the specified hard - * constraints. - * @param[in] ctxconfig The desired context attributes. - * @return `GL_TRUE` if the context fulfils the hard constraints, or `GL_FALSE` - * otherwise. - * @ingroup utility - */ -GLboolean _glfwIsValidContext(const _GLFWctxconfig* ctxconfig); - -/*! @ingroup utility - */ -void _glfwAllocGammaArrays(GLFWgammaramp* ramp, unsigned int size); - -/*! @ingroup utility - */ -void _glfwFreeGammaArrays(GLFWgammaramp* ramp); - -/*! @brief Allocates and returns a monitor object with the specified name - * and dimensions. - * @param[in] name The name of the monitor. - * @param[in] widthMM The width, in mm, of the monitor's display area. - * @param[in] heightMM The height, in mm, of the monitor's display area. - * @return The newly created object. - * @ingroup utility - */ -_GLFWmonitor* _glfwAllocMonitor(const char* name, int widthMM, int heightMM); - -/*! @brief Frees a monitor object and any data associated with it. - * @ingroup utility - */ -void _glfwFreeMonitor(_GLFWmonitor* monitor); - -/*! @ingroup utility - */ -void _glfwFreeMonitors(_GLFWmonitor** monitors, int count); - -#endif // _internal_h_ diff --git a/examples/common/glfw/src/iokit_joystick.h b/examples/common/glfw/src/iokit_joystick.h deleted file mode 100644 index c08809f2..00000000 --- a/examples/common/glfw/src/iokit_joystick.h +++ /dev/null @@ -1,61 +0,0 @@ -//======================================================================== -// GLFW 3.1 IOKit - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2006-2014 Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#ifndef _iokit_joystick_h_ -#define _iokit_joystick_h_ - -#include -#include -#include -#include - -#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE \ - _GLFWjoystickIOKit iokit_js[GLFW_JOYSTICK_LAST + 1] - - -// IOKit-specific per-joystick data -// -typedef struct _GLFWjoystickIOKit -{ - int present; - char name[256]; - - IOHIDDeviceInterface** interface; - - CFMutableArrayRef axisElements; - CFMutableArrayRef buttonElements; - CFMutableArrayRef hatElements; - - float* axes; - unsigned char* buttons; - -} _GLFWjoystickIOKit; - - -void _glfwInitJoysticks(void); -void _glfwTerminateJoysticks(void); - -#endif // _iokit_joystick_h_ diff --git a/examples/common/glfw/src/iokit_joystick.m b/examples/common/glfw/src/iokit_joystick.m deleted file mode 100644 index 5ff67dd8..00000000 --- a/examples/common/glfw/src/iokit_joystick.m +++ /dev/null @@ -1,506 +0,0 @@ -//======================================================================== -// GLFW 3.1 IOKit - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2009-2010 Camilla Berglund -// Copyright (c) 2012 Torsten Walluhn -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#include "internal.h" - -#include -#include - -#include -#include - -#include -#include - - -//------------------------------------------------------------------------ -// Joystick element information -//------------------------------------------------------------------------ -typedef struct -{ - IOHIDElementCookie cookie; - - long min; - long max; - - long minReport; - long maxReport; - -} _GLFWjoyelement; - - -static void getElementsCFArrayHandler(const void* value, void* parameter); - - -// Adds an element to the specified joystick -// -static void addJoystickElement(_GLFWjoystickIOKit* joystick, CFTypeRef elementRef) -{ - long elementType, usagePage, usage; - CFMutableArrayRef elementsArray = NULL; - - CFNumberGetValue(CFDictionaryGetValue(elementRef, CFSTR(kIOHIDElementTypeKey)), - kCFNumberLongType, &elementType); - CFNumberGetValue(CFDictionaryGetValue(elementRef, CFSTR(kIOHIDElementUsagePageKey)), - kCFNumberLongType, &usagePage); - CFNumberGetValue(CFDictionaryGetValue(elementRef, CFSTR(kIOHIDElementUsageKey)), - kCFNumberLongType, &usage); - - if ((elementType == kIOHIDElementTypeInput_Axis) || - (elementType == kIOHIDElementTypeInput_Button) || - (elementType == kIOHIDElementTypeInput_Misc)) - { - switch (usagePage) - { - case kHIDPage_GenericDesktop: - { - switch (usage) - { - case kHIDUsage_GD_X: - case kHIDUsage_GD_Y: - case kHIDUsage_GD_Z: - case kHIDUsage_GD_Rx: - case kHIDUsage_GD_Ry: - case kHIDUsage_GD_Rz: - case kHIDUsage_GD_Slider: - case kHIDUsage_GD_Dial: - case kHIDUsage_GD_Wheel: - elementsArray = joystick->axisElements; - break; - case kHIDUsage_GD_Hatswitch: - elementsArray = joystick->hatElements; - break; - } - - break; - } - - case kHIDPage_Button: - elementsArray = joystick->buttonElements; - break; - default: - break; - } - - if (elementsArray) - { - long number; - CFTypeRef numberRef; - _GLFWjoyelement* element = calloc(1, sizeof(_GLFWjoyelement)); - - CFArrayAppendValue(elementsArray, element); - - numberRef = CFDictionaryGetValue(elementRef, CFSTR(kIOHIDElementCookieKey)); - if (numberRef && CFNumberGetValue(numberRef, kCFNumberLongType, &number)) - element->cookie = (IOHIDElementCookie) number; - - numberRef = CFDictionaryGetValue(elementRef, CFSTR(kIOHIDElementMinKey)); - if (numberRef && CFNumberGetValue(numberRef, kCFNumberLongType, &number)) - element->minReport = element->min = number; - - numberRef = CFDictionaryGetValue(elementRef, CFSTR(kIOHIDElementMaxKey)); - if (numberRef && CFNumberGetValue(numberRef, kCFNumberLongType, &number)) - element->maxReport = element->max = number; - } - } - else - { - CFTypeRef array = CFDictionaryGetValue(elementRef, CFSTR(kIOHIDElementKey)); - if (array) - { - if (CFGetTypeID(array) == CFArrayGetTypeID()) - { - CFRange range = { 0, CFArrayGetCount(array) }; - CFArrayApplyFunction(array, range, getElementsCFArrayHandler, joystick); - } - } - } -} - -// Adds an element to the specified joystick -// -static void getElementsCFArrayHandler(const void* value, void* parameter) -{ - if (CFGetTypeID(value) == CFDictionaryGetTypeID()) - addJoystickElement((_GLFWjoystickIOKit*) parameter, (CFTypeRef) value); -} - -// Returns the value of the specified element of the specified joystick -// -static long getElementValue(_GLFWjoystickIOKit* joystick, _GLFWjoyelement* element) -{ - IOReturn result = kIOReturnSuccess; - IOHIDEventStruct hidEvent; - hidEvent.value = 0; - - if (joystick && element && joystick->interface) - { - result = (*(joystick->interface))->getElementValue(joystick->interface, - element->cookie, - &hidEvent); - if (kIOReturnSuccess == result) - { - // Record min and max for auto calibration - if (hidEvent.value < element->minReport) - element->minReport = hidEvent.value; - if (hidEvent.value > element->maxReport) - element->maxReport = hidEvent.value; - } - } - - // Auto user scale - return (long) hidEvent.value; -} - -// Removes the specified joystick -// -static void removeJoystick(_GLFWjoystickIOKit* joystick) -{ - int i; - - if (!joystick->present) - return; - - for (i = 0; i < CFArrayGetCount(joystick->axisElements); i++) - free((void*) CFArrayGetValueAtIndex(joystick->axisElements, i)); - CFArrayRemoveAllValues(joystick->axisElements); - - for (i = 0; i < CFArrayGetCount(joystick->buttonElements); i++) - free((void*) CFArrayGetValueAtIndex(joystick->buttonElements, i)); - CFArrayRemoveAllValues(joystick->buttonElements); - - for (i = 0; i < CFArrayGetCount(joystick->hatElements); i++) - free((void*) CFArrayGetValueAtIndex(joystick->hatElements, i)); - CFArrayRemoveAllValues(joystick->hatElements); - - free(joystick->axes); - free(joystick->buttons); - - (*(joystick->interface))->close(joystick->interface); - (*(joystick->interface))->Release(joystick->interface); - - memset(joystick, 0, sizeof(_GLFWjoystickIOKit)); -} - -// Callback for user-initiated joystick removal -// -static void removalCallback(void* target, IOReturn result, void* refcon, void* sender) -{ - removeJoystick((_GLFWjoystickIOKit*) refcon); -} - -// Polls for joystick events and updates GLFW state -// -static void pollJoystickEvents(void) -{ - int joy; - - for (joy = 0; joy <= GLFW_JOYSTICK_LAST; joy++) - { - CFIndex i; - int buttonIndex = 0; - _GLFWjoystickIOKit* joystick = _glfw.iokit_js + joy; - - if (!joystick->present) - continue; - - for (i = 0; i < CFArrayGetCount(joystick->buttonElements); i++) - { - _GLFWjoyelement* button = - (_GLFWjoyelement*) CFArrayGetValueAtIndex(joystick->buttonElements, i); - - if (getElementValue(joystick, button)) - joystick->buttons[buttonIndex++] = GLFW_PRESS; - else - joystick->buttons[buttonIndex++] = GLFW_RELEASE; - } - - for (i = 0; i < CFArrayGetCount(joystick->axisElements); i++) - { - _GLFWjoyelement* axis = - (_GLFWjoyelement*) CFArrayGetValueAtIndex(joystick->axisElements, i); - - long value = getElementValue(joystick, axis); - long readScale = axis->maxReport - axis->minReport; - - if (readScale == 0) - joystick->axes[i] = value; - else - joystick->axes[i] = (2.f * (value - axis->minReport) / readScale) - 1.f; - } - - for (i = 0; i < CFArrayGetCount(joystick->hatElements); i++) - { - _GLFWjoyelement* hat = - (_GLFWjoyelement*) CFArrayGetValueAtIndex(joystick->hatElements, i); - - // Bit fields of button presses for each direction, including nil - const int directions[9] = { 1, 3, 2, 6, 4, 12, 8, 9, 0 }; - - long j, value = getElementValue(joystick, hat); - if (value < 0 || value > 8) - value = 8; - - for (j = 0; j < 4; j++) - { - if (directions[value] & (1 << j)) - joystick->buttons[buttonIndex++] = GLFW_PRESS; - else - joystick->buttons[buttonIndex++] = GLFW_RELEASE; - } - } - } -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW internal API ////// -////////////////////////////////////////////////////////////////////////// - -// Initialize joystick interface -// -void _glfwInitJoysticks(void) -{ - int joy = 0; - IOReturn result = kIOReturnSuccess; - mach_port_t masterPort = 0; - io_iterator_t objectIterator = 0; - CFMutableDictionaryRef hidMatchDictionary = NULL; - io_object_t ioHIDDeviceObject = 0; - - result = IOMasterPort(bootstrap_port, &masterPort); - hidMatchDictionary = IOServiceMatching(kIOHIDDeviceKey); - if (kIOReturnSuccess != result || !hidMatchDictionary) - { - if (hidMatchDictionary) - CFRelease(hidMatchDictionary); - - return; - } - - result = IOServiceGetMatchingServices(masterPort, - hidMatchDictionary, - &objectIterator); - if (result != kIOReturnSuccess) - return; - - if (!objectIterator) - { - // There are no joysticks - return; - } - - while ((ioHIDDeviceObject = IOIteratorNext(objectIterator))) - { - CFMutableDictionaryRef propsRef = NULL; - CFTypeRef valueRef = NULL; - kern_return_t result; - - IOCFPlugInInterface** ppPlugInInterface = NULL; - HRESULT plugInResult = S_OK; - SInt32 score = 0; - - long usagePage = 0; - long usage = 0; - - valueRef = IORegistryEntryCreateCFProperty(ioHIDDeviceObject, - CFSTR(kIOHIDPrimaryUsagePageKey), - kCFAllocatorDefault, kNilOptions); - if (valueRef) - { - CFNumberGetValue(valueRef, kCFNumberLongType, &usagePage); - CFRelease(valueRef); - } - - valueRef = IORegistryEntryCreateCFProperty(ioHIDDeviceObject, - CFSTR(kIOHIDPrimaryUsageKey), - kCFAllocatorDefault, kNilOptions); - if (valueRef) - { - CFNumberGetValue(valueRef, kCFNumberLongType, &usage); - CFRelease(valueRef); - } - - if (usagePage != kHIDPage_GenericDesktop) - { - // This device is not relevant to GLFW - continue; - } - - if ((usage != kHIDUsage_GD_Joystick && - usage != kHIDUsage_GD_GamePad && - usage != kHIDUsage_GD_MultiAxisController)) - { - // This device is not relevant to GLFW - continue; - } - - result = IORegistryEntryCreateCFProperties(ioHIDDeviceObject, - &propsRef, - kCFAllocatorDefault, - kNilOptions); - - if (result != kIOReturnSuccess) - continue; - - _GLFWjoystickIOKit* joystick = _glfw.iokit_js + joy; - joystick->present = GL_TRUE; - - result = IOCreatePlugInInterfaceForService(ioHIDDeviceObject, - kIOHIDDeviceUserClientTypeID, - kIOCFPlugInInterfaceID, - &ppPlugInInterface, - &score); - - if (kIOReturnSuccess != result) - { - CFRelease(propsRef); - return; - } - - plugInResult = (*ppPlugInInterface)->QueryInterface( - ppPlugInInterface, - CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID), - (void *) &(joystick->interface)); - - if (plugInResult != S_OK) - { - CFRelease(propsRef); - return; - } - - (*ppPlugInInterface)->Release(ppPlugInInterface); - - (*(joystick->interface))->open(joystick->interface, 0); - (*(joystick->interface))->setRemovalCallback(joystick->interface, - removalCallback, - joystick, - joystick); - - // Get product string - valueRef = CFDictionaryGetValue(propsRef, CFSTR(kIOHIDProductKey)); - if (valueRef) - { - CFStringGetCString(valueRef, - joystick->name, - sizeof(joystick->name), - kCFStringEncodingUTF8); - } - - joystick->axisElements = CFArrayCreateMutable(NULL, 0, NULL); - joystick->buttonElements = CFArrayCreateMutable(NULL, 0, NULL); - joystick->hatElements = CFArrayCreateMutable(NULL, 0, NULL); - - valueRef = CFDictionaryGetValue(propsRef, CFSTR(kIOHIDElementKey)); - if (CFGetTypeID(valueRef) == CFArrayGetTypeID()) - { - CFRange range = { 0, CFArrayGetCount(valueRef) }; - CFArrayApplyFunction(valueRef, - range, - getElementsCFArrayHandler, - (void*) joystick); - } - - CFRelease(propsRef); - - joystick->axes = calloc(CFArrayGetCount(joystick->axisElements), - sizeof(float)); - joystick->buttons = calloc(CFArrayGetCount(joystick->buttonElements) + - CFArrayGetCount(joystick->hatElements) * 4, 1); - - joy++; - if (joy > GLFW_JOYSTICK_LAST) - break; - } -} - -// Close all opened joystick handles -// -void _glfwTerminateJoysticks(void) -{ - int i; - - for (i = 0; i < GLFW_JOYSTICK_LAST + 1; i++) - { - _GLFWjoystickIOKit* joystick = &_glfw.iokit_js[i]; - removeJoystick(joystick); - - if (joystick->axisElements) - CFRelease(joystick->axisElements); - if (joystick->buttonElements) - CFRelease(joystick->buttonElements); - if (joystick->hatElements) - CFRelease(joystick->hatElements); - } -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW platform API ////// -////////////////////////////////////////////////////////////////////////// - -int _glfwPlatformJoystickPresent(int joy) -{ - pollJoystickEvents(); - - return _glfw.iokit_js[joy].present; -} - -const float* _glfwPlatformGetJoystickAxes(int joy, int* count) -{ - _GLFWjoystickIOKit* joystick = _glfw.iokit_js + joy; - - pollJoystickEvents(); - - if (!joystick->present) - return NULL; - - *count = (int) CFArrayGetCount(joystick->axisElements); - return joystick->axes; -} - -const unsigned char* _glfwPlatformGetJoystickButtons(int joy, int* count) -{ - _GLFWjoystickIOKit* joystick = _glfw.iokit_js + joy; - - pollJoystickEvents(); - - if (!joystick->present) - return NULL; - - *count = (int) CFArrayGetCount(joystick->buttonElements) + - (int) CFArrayGetCount(joystick->hatElements) * 4; - return joystick->buttons; -} - -const char* _glfwPlatformGetJoystickName(int joy) -{ - pollJoystickEvents(); - - return _glfw.iokit_js[joy].name; -} - diff --git a/examples/common/glfw/src/linux_joystick.c b/examples/common/glfw/src/linux_joystick.c deleted file mode 100644 index 5f46519b..00000000 --- a/examples/common/glfw/src/linux_joystick.c +++ /dev/null @@ -1,322 +0,0 @@ -//======================================================================== -// GLFW 3.1 Linux - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2002-2006 Marcus Geelnard -// Copyright (c) 2006-2010 Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#include "internal.h" - -#if defined(__linux__) -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#endif // __linux__ - - -// Attempt to open the specified joystick device -// -static void openJoystickDevice(const char* path) -{ -#if defined(__linux__) - char axisCount, buttonCount; - char name[256]; - int joy, fd, version; - - for (joy = GLFW_JOYSTICK_1; joy <= GLFW_JOYSTICK_LAST; joy++) - { - if (!_glfw.linux_js.js[joy].present) - continue; - - if (strcmp(_glfw.linux_js.js[joy].path, path) == 0) - return; - } - - for (joy = GLFW_JOYSTICK_1; joy <= GLFW_JOYSTICK_LAST; joy++) - { - if (!_glfw.linux_js.js[joy].present) - break; - } - - if (joy > GLFW_JOYSTICK_LAST) - return; - - fd = open(path, O_RDONLY | O_NONBLOCK); - if (fd == -1) - return; - - _glfw.linux_js.js[joy].fd = fd; - - // Verify that the joystick driver version is at least 1.0 - ioctl(fd, JSIOCGVERSION, &version); - if (version < 0x010000) - { - // It's an old 0.x interface (we don't support it) - close(fd); - return; - } - - if (ioctl(fd, JSIOCGNAME(sizeof(name)), name) < 0) - strncpy(name, "Unknown", sizeof(name)); - - _glfw.linux_js.js[joy].name = strdup(name); - _glfw.linux_js.js[joy].path = strdup(path); - - ioctl(fd, JSIOCGAXES, &axisCount); - _glfw.linux_js.js[joy].axisCount = (int) axisCount; - - ioctl(fd, JSIOCGBUTTONS, &buttonCount); - _glfw.linux_js.js[joy].buttonCount = (int) buttonCount; - - _glfw.linux_js.js[joy].axes = calloc(axisCount, sizeof(float)); - _glfw.linux_js.js[joy].buttons = calloc(buttonCount, 1); - - _glfw.linux_js.js[joy].present = GL_TRUE; -#endif // __linux__ -} - -// Polls for and processes events for all present joysticks -// -static void pollJoystickEvents(void) -{ -#if defined(__linux__) - int i; - struct js_event e; - ssize_t offset = 0; - char buffer[16384]; - - const ssize_t size = read(_glfw.linux_js.inotify, buffer, sizeof(buffer)); - - while (size > offset) - { - regmatch_t match; - const struct inotify_event* e = (struct inotify_event*) (buffer + offset); - - if (regexec(&_glfw.linux_js.regex, e->name, 1, &match, 0) == 0) - { - char path[20]; - snprintf(path, sizeof(path), "/dev/input/%s", e->name); - openJoystickDevice(path); - } - - offset += sizeof(struct inotify_event) + e->len; - } - - for (i = 0; i <= GLFW_JOYSTICK_LAST; i++) - { - if (!_glfw.linux_js.js[i].present) - continue; - - // Read all queued events (non-blocking) - for (;;) - { - errno = 0; - if (read(_glfw.linux_js.js[i].fd, &e, sizeof(e)) < 0) - { - if (errno == ENODEV) - { - // The joystick was disconnected - - free(_glfw.linux_js.js[i].axes); - free(_glfw.linux_js.js[i].buttons); - free(_glfw.linux_js.js[i].name); - free(_glfw.linux_js.js[i].path); - - memset(&_glfw.linux_js.js[i], 0, sizeof(_glfw.linux_js.js[i])); - } - - break; - } - - // We don't care if it's an init event or not - e.type &= ~JS_EVENT_INIT; - - switch (e.type) - { - case JS_EVENT_AXIS: - _glfw.linux_js.js[i].axes[e.number] = - (float) e.value / 32767.0f; - break; - - case JS_EVENT_BUTTON: - _glfw.linux_js.js[i].buttons[e.number] = - e.value ? GLFW_PRESS : GLFW_RELEASE; - break; - - default: - break; - } - } - } -#endif // __linux__ -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW internal API ////// -////////////////////////////////////////////////////////////////////////// - -// Initialize joystick interface -// -int _glfwInitJoysticks(void) -{ -#if defined(__linux__) - const char* dirname = "/dev/input"; - DIR* dir; - - _glfw.linux_js.inotify = inotify_init1(IN_NONBLOCK | IN_CLOEXEC); - if (_glfw.linux_js.inotify == -1) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Linux: Failed to initialize inotify: %s", - strerror(errno)); - return GL_FALSE; - } - - // HACK: Register for IN_ATTRIB as well to get notified when udev is done - // This works well in practice but the true way is libudev - - _glfw.linux_js.watch = inotify_add_watch(_glfw.linux_js.inotify, - dirname, - IN_CREATE | IN_ATTRIB); - if (_glfw.linux_js.watch == -1) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Linux: Failed to watch for joystick connections in %s: %s", - dirname, - strerror(errno)); - // Continue without device connection notifications - } - - if (regcomp(&_glfw.linux_js.regex, "^js[0-9]\\+$", 0) != 0) - { - _glfwInputError(GLFW_PLATFORM_ERROR, "Linux: Failed to compile regex"); - return GL_FALSE; - } - - dir = opendir(dirname); - if (dir) - { - struct dirent* entry; - - while ((entry = readdir(dir))) - { - char path[20]; - regmatch_t match; - - if (regexec(&_glfw.linux_js.regex, entry->d_name, 1, &match, 0) != 0) - continue; - - snprintf(path, sizeof(path), "%s/%s", dirname, entry->d_name); - openJoystickDevice(path); - } - - closedir(dir); - } - else - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Linux: Failed to open joystick device directory %s: %s", - dirname, - strerror(errno)); - // Continue with no joysticks detected - } - -#endif // __linux__ - - return GL_TRUE; -} - -// Close all opened joystick handles -// -void _glfwTerminateJoysticks(void) -{ -#if defined(__linux__) - int i; - - for (i = 0; i <= GLFW_JOYSTICK_LAST; i++) - { - if (_glfw.linux_js.js[i].present) - { - close(_glfw.linux_js.js[i].fd); - free(_glfw.linux_js.js[i].axes); - free(_glfw.linux_js.js[i].buttons); - free(_glfw.linux_js.js[i].name); - free(_glfw.linux_js.js[i].path); - } - } - - regfree(&_glfw.linux_js.regex); - - if (_glfw.linux_js.watch > 0) - close(_glfw.linux_js.watch); - - if (_glfw.linux_js.inotify > 0) - close(_glfw.linux_js.inotify); -#endif // __linux__ -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW platform API ////// -////////////////////////////////////////////////////////////////////////// - -int _glfwPlatformJoystickPresent(int joy) -{ - pollJoystickEvents(); - - return _glfw.linux_js.js[joy].present; -} - -const float* _glfwPlatformGetJoystickAxes(int joy, int* count) -{ - pollJoystickEvents(); - - *count = _glfw.linux_js.js[joy].axisCount; - return _glfw.linux_js.js[joy].axes; -} - -const unsigned char* _glfwPlatformGetJoystickButtons(int joy, int* count) -{ - pollJoystickEvents(); - - *count = _glfw.linux_js.js[joy].buttonCount; - return _glfw.linux_js.js[joy].buttons; -} - -const char* _glfwPlatformGetJoystickName(int joy) -{ - pollJoystickEvents(); - - return _glfw.linux_js.js[joy].name; -} - diff --git a/examples/common/glfw/src/linux_joystick.h b/examples/common/glfw/src/linux_joystick.h deleted file mode 100644 index 163b07c5..00000000 --- a/examples/common/glfw/src/linux_joystick.h +++ /dev/null @@ -1,63 +0,0 @@ -//======================================================================== -// GLFW 3.1 Linux - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2014 Jonas Ådahl -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#ifndef _linux_joystick_h_ -#define _linux_joystick_h_ - -#include - -#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE \ - _GLFWjoystickLinux linux_js - - -// Linux-specific joystick API data -// -typedef struct _GLFWjoystickLinux -{ - struct - { - int present; - int fd; - float* axes; - int axisCount; - unsigned char* buttons; - int buttonCount; - char* name; - char* path; - } js[GLFW_JOYSTICK_LAST + 1]; - -#if defined(__linux__) - int inotify; - int watch; - regex_t regex; -#endif /*__linux__*/ -} _GLFWjoystickLinux; - - -int _glfwInitJoysticks(void); -void _glfwTerminateJoysticks(void); - -#endif // _linux_joystick_h_ diff --git a/examples/common/glfw/src/mach_time.c b/examples/common/glfw/src/mach_time.c deleted file mode 100644 index 59916bb4..00000000 --- a/examples/common/glfw/src/mach_time.c +++ /dev/null @@ -1,71 +0,0 @@ -//======================================================================== -// GLFW 3.1 OS X - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2009-2010 Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#include "internal.h" - -#include - - -// Return raw time -// -static uint64_t getRawTime(void) -{ - return mach_absolute_time(); -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW internal API ////// -////////////////////////////////////////////////////////////////////////// - -// Initialise timer -// -void _glfwInitTimer(void) -{ - mach_timebase_info_data_t info; - mach_timebase_info(&info); - - _glfw.ns_time.resolution = (double) info.numer / (info.denom * 1.0e9); - _glfw.ns_time.base = getRawTime(); -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW platform API ////// -////////////////////////////////////////////////////////////////////////// - -double _glfwPlatformGetTime(void) -{ - return (double) (getRawTime() - _glfw.ns_time.base) * - _glfw.ns_time.resolution; -} - -void _glfwPlatformSetTime(double time) -{ - _glfw.ns_time.base = getRawTime() - - (uint64_t) (time / _glfw.ns_time.resolution); -} - diff --git a/examples/common/glfw/src/mir_init.c b/examples/common/glfw/src/mir_init.c deleted file mode 100644 index a3c8de9f..00000000 --- a/examples/common/glfw/src/mir_init.c +++ /dev/null @@ -1,101 +0,0 @@ -//======================================================================== -// GLFW 3.1 Mir - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2014 Brandon Schaefer -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#include "internal.h" - -#include -#include - - -////////////////////////////////////////////////////////////////////////// -////// GLFW internal API ////// -////////////////////////////////////////////////////////////////////////// - -int _glfwPlatformInit(void) -{ - int error; - - _glfw.mir.connection = mir_connect_sync(NULL, __PRETTY_FUNCTION__); - - if (!mir_connection_is_valid(_glfw.mir.connection)) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Mir: Unable to connect to server: %s", - mir_connection_get_error_message(_glfw.mir.connection)); - - return GL_FALSE; - } - - _glfw.mir.display = - mir_connection_get_egl_native_display(_glfw.mir.connection); - - if (!_glfwInitContextAPI()) - return GL_FALSE; - - _glfwInitTimer(); - _glfwInitJoysticks(); - - _glfw.mir.event_queue = calloc(1, sizeof(EventQueue)); - _glfwInitEventQueue(_glfw.mir.event_queue); - - error = pthread_mutex_init(&_glfw.mir.event_mutex, NULL); - if (error) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Mir: Failed to create event mutex: %s\n", - strerror(error)); - return GL_FALSE; - } - - return GL_TRUE; -} - -void _glfwPlatformTerminate(void) -{ - _glfwTerminateContextAPI(); - _glfwTerminateJoysticks(); - - _glfwDeleteEventQueue(_glfw.mir.event_queue); - - pthread_mutex_destroy(&_glfw.mir.event_mutex); - - mir_connection_release(_glfw.mir.connection); -} - -const char* _glfwPlatformGetVersionString(void) -{ - const char* version = _GLFW_VERSION_NUMBER " Mir EGL" -#if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK) - " clock_gettime" -#endif -#if defined(_GLFW_BUILD_DLL) - " shared" -#endif - ; - - return version; -} - diff --git a/examples/common/glfw/src/mir_monitor.c b/examples/common/glfw/src/mir_monitor.c deleted file mode 100644 index 9776b10e..00000000 --- a/examples/common/glfw/src/mir_monitor.c +++ /dev/null @@ -1,138 +0,0 @@ -//======================================================================== -// GLFW 3.1 Mir - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2014 Brandon Schaefer -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#include "internal.h" - -#include - - -////////////////////////////////////////////////////////////////////////// -////// GLFW platform API ////// -////////////////////////////////////////////////////////////////////////// - -_GLFWmonitor** _glfwPlatformGetMonitors(int* count) -{ - int i, found = 0; - _GLFWmonitor** monitors = NULL; - MirDisplayConfiguration* displayConfig = - mir_connection_create_display_config(_glfw.mir.connection); - - *count = 0; - - for (i = 0; i < displayConfig->num_outputs; i++) - { - const MirDisplayOutput* out = displayConfig->outputs + i; - - if (out->used && - out->connected && - out->num_modes && - out->current_mode < out->num_modes) - { - found++; - monitors = realloc(monitors, sizeof(_GLFWmonitor*) * found); - monitors[i] = _glfwAllocMonitor("Unknown", - out->physical_width_mm, - out->physical_height_mm); - - monitors[i]->mir.x = out->position_x; - monitors[i]->mir.y = out->position_y; - monitors[i]->mir.output_id = out->output_id; - monitors[i]->mir.cur_mode = out->current_mode; - - monitors[i]->modes = _glfwPlatformGetVideoModes(monitors[i], - &monitors[i]->modeCount); - } - } - - mir_display_config_destroy(displayConfig); - - *count = found; - return monitors; -} - -GLboolean _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second) -{ - return first->mir.output_id == second->mir.output_id; -} - -void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos) -{ - if (xpos) - *xpos = monitor->mir.x; - if (ypos) - *ypos = monitor->mir.y; -} - -GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found) -{ - int i; - GLFWvidmode* modes = NULL; - MirDisplayConfiguration* displayConfig = - mir_connection_create_display_config(_glfw.mir.connection); - - for (i = 0; i < displayConfig->num_outputs; i++) - { - const MirDisplayOutput* out = displayConfig->outputs + i; - if (out->output_id != monitor->mir.output_id) - continue; - - modes = calloc(out->num_modes, sizeof(GLFWvidmode)); - - for (*found = 0; *found < out->num_modes; (*found)++) - { - modes[*found].width = out->modes[*found].horizontal_resolution; - modes[*found].height = out->modes[*found].vertical_resolution; - modes[*found].refreshRate = out->modes[*found].refresh_rate; - modes[*found].redBits = 8; - modes[*found].greenBits = 8; - modes[*found].blueBits = 8; - } - - break; - } - - mir_display_config_destroy(displayConfig); - - return modes; -} - -void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) -{ - *mode = monitor->modes[monitor->mir.cur_mode]; -} - -void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) -{ - _glfwInputError(GLFW_PLATFORM_ERROR, - "Mir: Unsupported function %s!", __PRETTY_FUNCTION__); -} - -void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) -{ - _glfwInputError(GLFW_PLATFORM_ERROR, - "Mir: Unsupported function %s!", __PRETTY_FUNCTION__); -} - diff --git a/examples/common/glfw/src/mir_platform.h b/examples/common/glfw/src/mir_platform.h deleted file mode 100644 index 76399c2a..00000000 --- a/examples/common/glfw/src/mir_platform.h +++ /dev/null @@ -1,110 +0,0 @@ -//======================================================================== -// GLFW 3.1 Mir - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2014 Brandon Schaefer -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#ifndef _mir_platform_h_ -#define _mir_platform_h_ - -#include - -#include "posix_tls.h" -#include "posix_time.h" -#include "linux_joystick.h" - -#include - -#include - -#if defined(_GLFW_EGL) - #include "egl_context.h" -#else - #error "The Mir backend depends on EGL platform support" -#endif - -#define _GLFW_EGL_NATIVE_WINDOW window->mir.window -#define _GLFW_EGL_NATIVE_DISPLAY _glfw.mir.display - -#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowMir mir -#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorMir mir -#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryMir mir -#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorMir mir - -// Mir-specific Event Queue -// -typedef struct EventQueue -{ - TAILQ_HEAD(, EventNode) head; -} EventQueue; - -// Mir-specific per-window data -// -typedef struct _GLFWwindowMir -{ - MirSurface* surface; - int width; - int height; - MirEGLNativeWindowType window; - -} _GLFWwindowMir; - - -// Mir-specific per-monitor data -// -typedef struct _GLFWmonitorMir -{ - int cur_mode; - int output_id; - int x; - int y; - -} _GLFWmonitorMir; - - -// Mir-specific global data -// -typedef struct _GLFWlibraryMir -{ - MirConnection* connection; - MirEGLNativeDisplayType display; - EventQueue* event_queue; - - pthread_mutex_t event_mutex; - pthread_cond_t event_cond; - -} _GLFWlibraryMir; - - -// Mir-specific per-cursor data -// TODO: Only system cursors are implemented in Mir atm. Need to wait for support. -// -typedef struct _GLFWcursorMir -{ -} _GLFWcursorMir; - - -extern void _glfwInitEventQueue(EventQueue* queue); -extern void _glfwDeleteEventQueue(EventQueue* queue); - -#endif // _mir_platform_h_ diff --git a/examples/common/glfw/src/mir_window.c b/examples/common/glfw/src/mir_window.c deleted file mode 100644 index f2890cbd..00000000 --- a/examples/common/glfw/src/mir_window.c +++ /dev/null @@ -1,687 +0,0 @@ -//======================================================================== -// GLFW 3.1 Mir - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2014 Brandon Schaefer -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#include "internal.h" -#include "xkb_unicode.h" - -#include -#include -#include - - -typedef struct EventNode -{ - TAILQ_ENTRY(EventNode) entries; - MirEvent* event; - _GLFWwindow* window; -} EventNode; - -static void deleteNode(EventQueue* queue, EventNode* node) -{ - free(node->event); - free(node); -} - -static int emptyEventQueue(EventQueue* queue) -{ - return queue->head.tqh_first == NULL ? GL_TRUE : GL_FALSE; -} - -static EventNode* newEventNode(MirEvent const* event, _GLFWwindow* context) -{ - EventNode* new_node = calloc(1, sizeof(EventNode)); - new_node->event = calloc(1, sizeof(MirEvent)); - new_node->window = context; - - memcpy(new_node->event, event, sizeof(MirEvent)); - return new_node; -} - -static void enqueueEvent(MirEvent const* event, _GLFWwindow* context) -{ - pthread_mutex_lock(&_glfw.mir.event_mutex); - - EventNode* new_node = newEventNode(event, context); - TAILQ_INSERT_TAIL(&_glfw.mir.event_queue->head, new_node, entries); - - pthread_cond_signal(&_glfw.mir.event_cond); - - pthread_mutex_unlock(&_glfw.mir.event_mutex); -} - -static EventNode* dequeueEvent(EventQueue* queue) -{ - EventNode* node = NULL; - - pthread_mutex_lock(&_glfw.mir.event_mutex); - - node = queue->head.tqh_first; - - if (node) - TAILQ_REMOVE(&queue->head, node, entries); - - pthread_mutex_unlock(&_glfw.mir.event_mutex); - - return node; -} - -static MirPixelFormat findValidPixelFormat(void) -{ - unsigned int i, validFormats, mirPixelFormats = 32; - MirPixelFormat formats[mir_pixel_formats]; - - mir_connection_get_available_surface_formats(_glfw.mir.connection, formats, - mirPixelFormats, &validFormats); - - for (i = 0; i < validFormats; i++) - { - if (formats[i] == mir_pixel_format_abgr_8888 || - formats[i] == mir_pixel_format_xbgr_8888 || - formats[i] == mir_pixel_format_argb_8888 || - formats[i] == mir_pixel_format_xrgb_8888) - { - return formats[i]; - } - } - - return mir_pixel_format_invalid; -} - -static int mirModToGLFWMod(uint32_t mods) -{ - int publicMods = 0x0; - - if (mods & mir_key_modifier_alt) - publicMods |= GLFW_MOD_ALT; - else if (mods & mir_key_modifier_shift) - publicMods |= GLFW_MOD_SHIFT; - else if (mods & mir_key_modifier_ctrl) - publicMods |= GLFW_MOD_CONTROL; - else if (mods & mir_key_modifier_meta) - publicMods |= GLFW_MOD_SUPER; - - return publicMods; -} - -// Taken from wl_init.c -static int toGLFWKeyCode(uint32_t key) -{ - switch (key) - { - case KEY_GRAVE: return GLFW_KEY_GRAVE_ACCENT; - case KEY_1: return GLFW_KEY_1; - case KEY_2: return GLFW_KEY_2; - case KEY_3: return GLFW_KEY_3; - case KEY_4: return GLFW_KEY_4; - case KEY_5: return GLFW_KEY_5; - case KEY_6: return GLFW_KEY_6; - case KEY_7: return GLFW_KEY_7; - case KEY_8: return GLFW_KEY_8; - case KEY_9: return GLFW_KEY_9; - case KEY_0: return GLFW_KEY_0; - case KEY_MINUS: return GLFW_KEY_MINUS; - case KEY_EQUAL: return GLFW_KEY_EQUAL; - case KEY_Q: return GLFW_KEY_Q; - case KEY_W: return GLFW_KEY_W; - case KEY_E: return GLFW_KEY_E; - case KEY_R: return GLFW_KEY_R; - case KEY_T: return GLFW_KEY_T; - case KEY_Y: return GLFW_KEY_Y; - case KEY_U: return GLFW_KEY_U; - case KEY_I: return GLFW_KEY_I; - case KEY_O: return GLFW_KEY_O; - case KEY_P: return GLFW_KEY_P; - case KEY_LEFTBRACE: return GLFW_KEY_LEFT_BRACKET; - case KEY_RIGHTBRACE: return GLFW_KEY_RIGHT_BRACKET; - case KEY_A: return GLFW_KEY_A; - case KEY_S: return GLFW_KEY_S; - case KEY_D: return GLFW_KEY_D; - case KEY_F: return GLFW_KEY_F; - case KEY_G: return GLFW_KEY_G; - case KEY_H: return GLFW_KEY_H; - case KEY_J: return GLFW_KEY_J; - case KEY_K: return GLFW_KEY_K; - case KEY_L: return GLFW_KEY_L; - case KEY_SEMICOLON: return GLFW_KEY_SEMICOLON; - case KEY_APOSTROPHE: return GLFW_KEY_APOSTROPHE; - case KEY_Z: return GLFW_KEY_Z; - case KEY_X: return GLFW_KEY_X; - case KEY_C: return GLFW_KEY_C; - case KEY_V: return GLFW_KEY_V; - case KEY_B: return GLFW_KEY_B; - case KEY_N: return GLFW_KEY_N; - case KEY_M: return GLFW_KEY_M; - case KEY_COMMA: return GLFW_KEY_COMMA; - case KEY_DOT: return GLFW_KEY_PERIOD; - case KEY_SLASH: return GLFW_KEY_SLASH; - case KEY_BACKSLASH: return GLFW_KEY_BACKSLASH; - case KEY_ESC: return GLFW_KEY_ESCAPE; - case KEY_TAB: return GLFW_KEY_TAB; - case KEY_LEFTSHIFT: return GLFW_KEY_LEFT_SHIFT; - case KEY_RIGHTSHIFT: return GLFW_KEY_RIGHT_SHIFT; - case KEY_LEFTCTRL: return GLFW_KEY_LEFT_CONTROL; - case KEY_RIGHTCTRL: return GLFW_KEY_RIGHT_CONTROL; - case KEY_LEFTALT: return GLFW_KEY_LEFT_ALT; - case KEY_RIGHTALT: return GLFW_KEY_RIGHT_ALT; - case KEY_LEFTMETA: return GLFW_KEY_LEFT_SUPER; - case KEY_RIGHTMETA: return GLFW_KEY_RIGHT_SUPER; - case KEY_MENU: return GLFW_KEY_MENU; - case KEY_NUMLOCK: return GLFW_KEY_NUM_LOCK; - case KEY_CAPSLOCK: return GLFW_KEY_CAPS_LOCK; - case KEY_PRINT: return GLFW_KEY_PRINT_SCREEN; - case KEY_SCROLLLOCK: return GLFW_KEY_SCROLL_LOCK; - case KEY_PAUSE: return GLFW_KEY_PAUSE; - case KEY_DELETE: return GLFW_KEY_DELETE; - case KEY_BACKSPACE: return GLFW_KEY_BACKSPACE; - case KEY_ENTER: return GLFW_KEY_ENTER; - case KEY_HOME: return GLFW_KEY_HOME; - case KEY_END: return GLFW_KEY_END; - case KEY_PAGEUP: return GLFW_KEY_PAGE_UP; - case KEY_PAGEDOWN: return GLFW_KEY_PAGE_DOWN; - case KEY_INSERT: return GLFW_KEY_INSERT; - case KEY_LEFT: return GLFW_KEY_LEFT; - case KEY_RIGHT: return GLFW_KEY_RIGHT; - case KEY_DOWN: return GLFW_KEY_DOWN; - case KEY_UP: return GLFW_KEY_UP; - case KEY_F1: return GLFW_KEY_F1; - case KEY_F2: return GLFW_KEY_F2; - case KEY_F3: return GLFW_KEY_F3; - case KEY_F4: return GLFW_KEY_F4; - case KEY_F5: return GLFW_KEY_F5; - case KEY_F6: return GLFW_KEY_F6; - case KEY_F7: return GLFW_KEY_F7; - case KEY_F8: return GLFW_KEY_F8; - case KEY_F9: return GLFW_KEY_F9; - case KEY_F10: return GLFW_KEY_F10; - case KEY_F11: return GLFW_KEY_F11; - case KEY_F12: return GLFW_KEY_F12; - case KEY_F13: return GLFW_KEY_F13; - case KEY_F14: return GLFW_KEY_F14; - case KEY_F15: return GLFW_KEY_F15; - case KEY_F16: return GLFW_KEY_F16; - case KEY_F17: return GLFW_KEY_F17; - case KEY_F18: return GLFW_KEY_F18; - case KEY_F19: return GLFW_KEY_F19; - case KEY_F20: return GLFW_KEY_F20; - case KEY_F21: return GLFW_KEY_F21; - case KEY_F22: return GLFW_KEY_F22; - case KEY_F23: return GLFW_KEY_F23; - case KEY_F24: return GLFW_KEY_F24; - case KEY_KPSLASH: return GLFW_KEY_KP_DIVIDE; - case KEY_KPDOT: return GLFW_KEY_KP_MULTIPLY; - case KEY_KPMINUS: return GLFW_KEY_KP_SUBTRACT; - case KEY_KPPLUS: return GLFW_KEY_KP_ADD; - case KEY_KP0: return GLFW_KEY_KP_0; - case KEY_KP1: return GLFW_KEY_KP_1; - case KEY_KP2: return GLFW_KEY_KP_2; - case KEY_KP3: return GLFW_KEY_KP_3; - case KEY_KP4: return GLFW_KEY_KP_4; - case KEY_KP5: return GLFW_KEY_KP_5; - case KEY_KP6: return GLFW_KEY_KP_6; - case KEY_KP7: return GLFW_KEY_KP_7; - case KEY_KP8: return GLFW_KEY_KP_8; - case KEY_KP9: return GLFW_KEY_KP_9; - case KEY_KPCOMMA: return GLFW_KEY_KP_DECIMAL; - case KEY_KPEQUAL: return GLFW_KEY_KP_EQUAL; - case KEY_KPENTER: return GLFW_KEY_KP_ENTER; - default: return GLFW_KEY_UNKNOWN; - } -} - -static void handleKeyEvent(const MirKeyEvent key, _GLFWwindow* window) -{ - const int pressed = key.action == mir_key_action_up ? GLFW_RELEASE : GLFW_PRESS; - const int mods = mirModToGLFWMod(key.modifiers); - const long text = _glfwKeySym2Unicode(key.key_code); - const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT)); - - _glfwInputKey(window, toGLFWKeyCode(key.scan_code), key.scan_code, pressed, mods); - - if (text != -1) - _glfwInputChar(window, text, mods, plain); -} - -static void handleMouseButton(_GLFWwindow* window, - int pressed, int mods, MirMotionButton button) -{ - static int lastButton; - int publicButton; - const int publicMods = mirModToGLFWMod(mods); - - switch (button) - { - case mir_motion_button_primary: - publicButton = GLFW_MOUSE_BUTTON_LEFT; - break; - case mir_motion_button_secondary: - publicButton = GLFW_MOUSE_BUTTON_RIGHT; - break; - case mir_motion_button_tertiary: - publicButton = GLFW_MOUSE_BUTTON_MIDDLE; - break; - case mir_motion_button_forward: - // FIXME What is the forward button? - publicButton = GLFW_MOUSE_BUTTON_4; - break; - case mir_motion_button_back: - // FIXME What is the back button? - publicButton = GLFW_MOUSE_BUTTON_5; - break; - default: - publicButton = lastButton; - break; - } - - lastButton = publicButton; - - _glfwInputMouseClick(window, publicButton, pressed, publicMods); -} - -static void handleMouseMotion(_GLFWwindow* window, int x, int y) -{ - _glfwInputCursorMotion(window, x, y); -} - -static void handleMouseScroll(_GLFWwindow* window, int dx, int dy) -{ - _glfwInputScroll(window, dx, dy); -} - -static void handleMouseEvent(const MirMotionEvent motion, - int cord_index, - _GLFWwindow* window) -{ - switch (motion.action) - { - case mir_motion_action_down: - case mir_motion_action_pointer_down: - handleMouseButton(window, GLFW_PRESS, - motion.modifiers, motion.button_state); - break; - case mir_motion_action_up: - case mir_motion_action_pointer_up: - handleMouseButton(window, GLFW_RELEASE, - motion.modifiers, motion.button_state); - break; - case mir_motion_action_hover_move: - case mir_motion_action_move: - handleMouseMotion(window, - motion.pointer_coordinates[cord_index].x, - motion.pointer_coordinates[cord_index].y); - break; - case mir_motion_action_outside: - break; - case mir_motion_action_scroll: - handleMouseScroll(window, - motion.pointer_coordinates[cord_index].hscroll, - motion.pointer_coordinates[cord_index].vscroll); - break; - case mir_motion_action_cancel: - case mir_motion_action_hover_enter: - case mir_motion_action_hover_exit: - break; - default: - break; - - } -} - -static void handleMotionEvent(const MirMotionEvent motion, _GLFWwindow* window) -{ - int i; - for (i = 0; i < motion.pointer_count; i++) - handleMouseEvent(motion, i, window); -} - -static void handleInput(MirEvent const* event, _GLFWwindow* window) -{ - switch (event->type) - { - case mir_event_type_key: - handleKeyEvent(event->key, window); - break; - case mir_event_type_motion: - handleMotionEvent(event->motion, window); - break; - default: - break; - } -} - -static void addNewEvent(MirSurface* surface, MirEvent const* event, void* context) -{ - enqueueEvent(event, context); -} - -static int createSurface(_GLFWwindow* window) -{ - MirSurfaceParameters params = - { - .name = "MirSurface", - .width = window->mir.width, - .height = window->mir.height, - .pixel_format = mir_pixel_format_invalid, - .buffer_usage = mir_buffer_usage_hardware, - .output_id = mir_display_output_id_invalid - }; - - MirEventDelegate delegate = - { - addNewEvent, - window - }; - - params.pixel_format = findValidPixelFormat(); - if (params.pixel_format == mir_pixel_format_invalid) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Mir: Unable to find a correct pixel format"); - return GL_FALSE; - } - - window->mir.surface = - mir_connection_create_surface_sync(_glfw.mir.connection, ¶ms); - if (!mir_surface_is_valid(window->mir.surface)) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Mir: Unable to create surface: %s", - mir_surface_get_error_message(window->mir.surface)); - - return GL_FALSE; - } - - mir_surface_set_event_handler(window->mir.surface, &delegate); - - return GL_TRUE; -} - -////////////////////////////////////////////////////////////////////////// -////// GLFW internal API ////// -////////////////////////////////////////////////////////////////////////// - -void _glfwInitEventQueue(EventQueue* queue) -{ - TAILQ_INIT(&queue->head); -} - -void _glfwDeleteEventQueue(EventQueue* queue) -{ - if (queue) - { - EventNode* node, *node_next; - node = queue->head.tqh_first; - - while (node != NULL) - { - node_next = node->entries.tqe_next; - - TAILQ_REMOVE(&queue->head, node, entries); - deleteNode(queue, node); - - node = node_next; - } - - free(queue); - } -} - -////////////////////////////////////////////////////////////////////////// -////// GLFW platform API ////// -////////////////////////////////////////////////////////////////////////// - -int _glfwPlatformCreateWindow(_GLFWwindow* window, - const _GLFWwndconfig* wndconfig, - const _GLFWctxconfig* ctxconfig, - const _GLFWfbconfig* fbconfig) -{ - if (!_glfwCreateContext(window, ctxconfig, fbconfig)) - return GL_FALSE; - - if (wndconfig->monitor) - { - GLFWvidmode mode; - _glfwPlatformGetVideoMode(wndconfig->monitor, &mode); - - mir_surface_set_state(window->mir.surface, mir_surface_state_fullscreen); - - if (wndconfig->width > mode.width || wndconfig->height > mode.height) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Mir: Requested surface size is to large (%i %i)", - wndconfig->width, wndconfig->height); - - return GL_FALSE; - } - } - - window->mir.width = wndconfig->width; - window->mir.height = wndconfig->height; - - if (!createSurface(window)) - return GL_FALSE; - - window->mir.window = mir_surface_get_egl_native_window(window->mir.surface); - - return GL_TRUE; -} - -void _glfwPlatformDestroyWindow(_GLFWwindow* window) -{ - if (mir_surface_is_valid(window->mir.surface)) - { - mir_surface_release_sync(window->mir.surface); - window->mir.surface = NULL; - } - - _glfwDestroyContext(window); -} - -void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title) -{ - _glfwInputError(GLFW_PLATFORM_ERROR, - "Mir: Unsupported function %s!", __PRETTY_FUNCTION__); -} - -void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos) -{ - _glfwInputError(GLFW_PLATFORM_ERROR, - "Mir: Unsupported function %s!", __PRETTY_FUNCTION__); -} - -void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, - int* left, int* top, - int* right, int* bottom) -{ - _glfwInputError(GLFW_PLATFORM_ERROR, - "Mir: Unsupported function %s!", __PRETTY_FUNCTION__); -} - -void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos) -{ - _glfwInputError(GLFW_PLATFORM_ERROR, - "Mir: Unsupported function %s!", __PRETTY_FUNCTION__); -} - -void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) -{ - _glfwInputError(GLFW_PLATFORM_ERROR, - "Mir: Unsupported function %s!", __PRETTY_FUNCTION__); -} - -void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height) -{ - if (width) - *width = window->mir.width; - if (height) - *height = window->mir.height; -} - -void _glfwPlatformIconifyWindow(_GLFWwindow* window) -{ - mir_surface_set_state(window->mir.surface, mir_surface_state_minimized); -} - -void _glfwPlatformRestoreWindow(_GLFWwindow* window) -{ - mir_surface_set_state(window->mir.surface, mir_surface_state_restored); -} - -void _glfwPlatformHideWindow(_GLFWwindow* window) -{ - _glfwInputError(GLFW_PLATFORM_ERROR, - "Mir: Unsupported function %s!", __PRETTY_FUNCTION__); -} - -void _glfwPlatformShowWindow(_GLFWwindow* window) -{ - _glfwInputError(GLFW_PLATFORM_ERROR, - "Mir: Unsupported function %s!", __PRETTY_FUNCTION__); -} - -void _glfwPlatformUnhideWindow(_GLFWwindow* window) -{ - _glfwInputError(GLFW_PLATFORM_ERROR, - "Mir: Unsupported function %s!", __PRETTY_FUNCTION__); -} - -int _glfwPlatformWindowFocused(_GLFWwindow* window) -{ - _glfwInputError(GLFW_PLATFORM_ERROR, - "Mir: Unsupported function %s!", __PRETTY_FUNCTION__); - return GL_FALSE; -} - -int _glfwPlatformWindowIconified(_GLFWwindow* window) -{ - _glfwInputError(GLFW_PLATFORM_ERROR, - "Mir: Unsupported function %s!", __PRETTY_FUNCTION__); - return GL_FALSE; -} - -int _glfwPlatformWindowVisible(_GLFWwindow* window) -{ - _glfwInputError(GLFW_PLATFORM_ERROR, - "Mir: Unsupported function %s!", __PRETTY_FUNCTION__); - return GL_FALSE; -} - -void _glfwPlatformPollEvents(void) -{ - EventNode* node = NULL; - - while ((node = dequeueEvent(_glfw.mir.event_queue))) - { - handleInput(node->event, node->window); - deleteNode(_glfw.mir.event_queue, node); - } -} - -void _glfwPlatformWaitEvents(void) -{ - pthread_mutex_lock(&_glfw.mir.event_mutex); - - if (emptyEventQueue(_glfw.mir.event_queue)) - pthread_cond_wait(&_glfw.mir.event_cond, &_glfw.mir.event_mutex); - - pthread_mutex_unlock(&_glfw.mir.event_mutex); - - _glfwPlatformPollEvents(); -} - -void _glfwPlatformPostEmptyEvent(void) -{ -} - -void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height) -{ - if (width) - *width = window->mir.width; - if (height) - *height = window->mir.height; -} - -int _glfwPlatformCreateCursor(_GLFWcursor* cursor, - const GLFWimage* image, - int xhot, int yhot) -{ - _glfwInputError(GLFW_PLATFORM_ERROR, - "Mir: Unsupported function %s!", __PRETTY_FUNCTION__); - - return GL_FALSE; -} - -int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape) -{ - _glfwInputError(GLFW_PLATFORM_ERROR, - "Mir: Unsupported function %s!", __PRETTY_FUNCTION__); - - return GL_FALSE; -} - -void _glfwPlatformDestroyCursor(_GLFWcursor* cursor) -{ - _glfwInputError(GLFW_PLATFORM_ERROR, - "Mir: Unsupported function %s!", __PRETTY_FUNCTION__); -} - -void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) -{ - _glfwInputError(GLFW_PLATFORM_ERROR, - "Mir: Unsupported function %s!", __PRETTY_FUNCTION__); -} - -void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos) -{ - _glfwInputError(GLFW_PLATFORM_ERROR, - "Mir: Unsupported function %s!", __PRETTY_FUNCTION__); -} - -void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos) -{ - _glfwInputError(GLFW_PLATFORM_ERROR, - "Mir: Unsupported function %s!", __PRETTY_FUNCTION__); -} - -void _glfwPlatformApplyCursorMode(_GLFWwindow* window) -{ - _glfwInputError(GLFW_PLATFORM_ERROR, - "Mir: Unsupported function %s!", __PRETTY_FUNCTION__); -} - -void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string) -{ - _glfwInputError(GLFW_PLATFORM_ERROR, - "Mir: Unsupported function %s!", __PRETTY_FUNCTION__); -} - -const char* _glfwPlatformGetClipboardString(_GLFWwindow* window) -{ - _glfwInputError(GLFW_PLATFORM_ERROR, - "Mir: Unsupported function %s!", __PRETTY_FUNCTION__); - - return NULL; -} - diff --git a/examples/common/glfw/src/monitor.c b/examples/common/glfw/src/monitor.c deleted file mode 100644 index 1ab57489..00000000 --- a/examples/common/glfw/src/monitor.c +++ /dev/null @@ -1,442 +0,0 @@ -//======================================================================== -// GLFW 3.1 - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2002-2006 Marcus Geelnard -// Copyright (c) 2006-2010 Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#include "internal.h" - -#include -#include -#include -#include - - -// Lexical comparison function for GLFW video modes, used by qsort -// -static int compareVideoModes(const void* firstPtr, const void* secondPtr) -{ - int firstBPP, secondBPP, firstSize, secondSize; - const GLFWvidmode* first = firstPtr; - const GLFWvidmode* second = secondPtr; - - // First sort on color bits per pixel - firstBPP = first->redBits + first->greenBits + first->blueBits; - secondBPP = second->redBits + second->greenBits + second->blueBits; - if (firstBPP != secondBPP) - return firstBPP - secondBPP; - - // Then sort on screen area, in pixels - firstSize = first->width * first->height; - secondSize = second->width * second->height; - if (firstSize != secondSize) - return firstSize - secondSize; - - // Lastly sort on refresh rate - return first->refreshRate - second->refreshRate; -} - -// Retrieves the available modes for the specified monitor -// -static int refreshVideoModes(_GLFWmonitor* monitor) -{ - int modeCount; - GLFWvidmode* modes; - - if (monitor->modes) - return GL_TRUE; - - modes = _glfwPlatformGetVideoModes(monitor, &modeCount); - if (!modes) - return GL_FALSE; - - qsort(modes, modeCount, sizeof(GLFWvidmode), compareVideoModes); - - free(monitor->modes); - monitor->modes = modes; - monitor->modeCount = modeCount; - - return GL_TRUE; -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW event API ////// -////////////////////////////////////////////////////////////////////////// - -void _glfwInputMonitorChange(void) -{ - int i, j, monitorCount = _glfw.monitorCount; - _GLFWmonitor** monitors = _glfw.monitors; - - _glfw.monitors = _glfwPlatformGetMonitors(&_glfw.monitorCount); - - // Re-use still connected monitor objects - - for (i = 0; i < _glfw.monitorCount; i++) - { - for (j = 0; j < monitorCount; j++) - { - if (_glfwPlatformIsSameMonitor(_glfw.monitors[i], monitors[j])) - { - _glfwFreeMonitor(_glfw.monitors[i]); - _glfw.monitors[i] = monitors[j]; - break; - } - } - } - - // Find and report disconnected monitors (not in the new list) - - for (i = 0; i < monitorCount; i++) - { - _GLFWwindow* window; - - for (j = 0; j < _glfw.monitorCount; j++) - { - if (monitors[i] == _glfw.monitors[j]) - break; - } - - if (j < _glfw.monitorCount) - continue; - - for (window = _glfw.windowListHead; window; window = window->next) - { - if (window->monitor == monitors[i]) - window->monitor = NULL; - } - - if (_glfw.callbacks.monitor) - _glfw.callbacks.monitor((GLFWmonitor*) monitors[i], GLFW_DISCONNECTED); - } - - // Find and report newly connected monitors (not in the old list) - // Re-used monitor objects are then removed from the old list to avoid - // having them destroyed at the end of this function - - for (i = 0; i < _glfw.monitorCount; i++) - { - for (j = 0; j < monitorCount; j++) - { - if (_glfw.monitors[i] == monitors[j]) - { - monitors[j] = NULL; - break; - } - } - - if (j < monitorCount) - continue; - - if (_glfw.callbacks.monitor) - _glfw.callbacks.monitor((GLFWmonitor*) _glfw.monitors[i], GLFW_CONNECTED); - } - - _glfwFreeMonitors(monitors, monitorCount); -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW internal API ////// -////////////////////////////////////////////////////////////////////////// - -_GLFWmonitor* _glfwAllocMonitor(const char* name, int widthMM, int heightMM) -{ - _GLFWmonitor* monitor = calloc(1, sizeof(_GLFWmonitor)); - monitor->name = strdup(name); - monitor->widthMM = widthMM; - monitor->heightMM = heightMM; - - return monitor; -} - -void _glfwFreeMonitor(_GLFWmonitor* monitor) -{ - if (monitor == NULL) - return; - - _glfwFreeGammaArrays(&monitor->originalRamp); - _glfwFreeGammaArrays(&monitor->currentRamp); - - free(monitor->modes); - free(monitor->name); - free(monitor); -} - -void _glfwAllocGammaArrays(GLFWgammaramp* ramp, unsigned int size) -{ - ramp->red = calloc(size, sizeof(unsigned short)); - ramp->green = calloc(size, sizeof(unsigned short)); - ramp->blue = calloc(size, sizeof(unsigned short)); - ramp->size = size; -} - -void _glfwFreeGammaArrays(GLFWgammaramp* ramp) -{ - free(ramp->red); - free(ramp->green); - free(ramp->blue); - - memset(ramp, 0, sizeof(GLFWgammaramp)); -} - -void _glfwFreeMonitors(_GLFWmonitor** monitors, int count) -{ - int i; - - for (i = 0; i < count; i++) - _glfwFreeMonitor(monitors[i]); - - free(monitors); -} - -const GLFWvidmode* _glfwChooseVideoMode(_GLFWmonitor* monitor, - const GLFWvidmode* desired) -{ - int i; - unsigned int sizeDiff, leastSizeDiff = UINT_MAX; - unsigned int rateDiff, leastRateDiff = UINT_MAX; - unsigned int colorDiff, leastColorDiff = UINT_MAX; - const GLFWvidmode* current; - const GLFWvidmode* closest = NULL; - - if (!refreshVideoModes(monitor)) - return NULL; - - for (i = 0; i < monitor->modeCount; i++) - { - current = monitor->modes + i; - - colorDiff = 0; - - if (desired->redBits != GLFW_DONT_CARE) - colorDiff += abs(current->redBits - desired->redBits); - if (desired->greenBits != GLFW_DONT_CARE) - colorDiff += abs(current->greenBits - desired->greenBits); - if (desired->blueBits != GLFW_DONT_CARE) - colorDiff += abs(current->blueBits - desired->blueBits); - - sizeDiff = abs((current->width - desired->width) * - (current->width - desired->width) + - (current->height - desired->height) * - (current->height - desired->height)); - - if (desired->refreshRate != GLFW_DONT_CARE) - rateDiff = abs(current->refreshRate - desired->refreshRate); - else - rateDiff = UINT_MAX - current->refreshRate; - - if ((colorDiff < leastColorDiff) || - (colorDiff == leastColorDiff && sizeDiff < leastSizeDiff) || - (colorDiff == leastColorDiff && sizeDiff == leastSizeDiff && rateDiff < leastRateDiff)) - { - closest = current; - leastSizeDiff = sizeDiff; - leastRateDiff = rateDiff; - leastColorDiff = colorDiff; - } - } - - return closest; -} - -int _glfwCompareVideoModes(const GLFWvidmode* first, const GLFWvidmode* second) -{ - return compareVideoModes(first, second); -} - -void _glfwSplitBPP(int bpp, int* red, int* green, int* blue) -{ - int delta; - - // We assume that by 32 the user really meant 24 - if (bpp == 32) - bpp = 24; - - // Convert "bits per pixel" to red, green & blue sizes - - *red = *green = *blue = bpp / 3; - delta = bpp - (*red * 3); - if (delta >= 1) - *green = *green + 1; - - if (delta == 2) - *red = *red + 1; -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW public API ////// -////////////////////////////////////////////////////////////////////////// - -GLFWAPI GLFWmonitor** glfwGetMonitors(int* count) -{ - *count = 0; - - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - - *count = _glfw.monitorCount; - return (GLFWmonitor**) _glfw.monitors; -} - -GLFWAPI GLFWmonitor* glfwGetPrimaryMonitor(void) -{ - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - return (GLFWmonitor*) _glfw.monitors[0]; -} - -GLFWAPI void glfwGetMonitorPos(GLFWmonitor* handle, int* xpos, int* ypos) -{ - _GLFWmonitor* monitor = (_GLFWmonitor*) handle; - - if (xpos) - *xpos = 0; - if (ypos) - *ypos = 0; - - _GLFW_REQUIRE_INIT(); - - _glfwPlatformGetMonitorPos(monitor, xpos, ypos); -} - -GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* handle, int* widthMM, int* heightMM) -{ - _GLFWmonitor* monitor = (_GLFWmonitor*) handle; - - if (widthMM) - *widthMM = 0; - if (heightMM) - *heightMM = 0; - - _GLFW_REQUIRE_INIT(); - - if (widthMM) - *widthMM = monitor->widthMM; - if (heightMM) - *heightMM = monitor->heightMM; -} - -GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* handle) -{ - _GLFWmonitor* monitor = (_GLFWmonitor*) handle; - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - return monitor->name; -} - -GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun cbfun) -{ - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(_glfw.callbacks.monitor, cbfun); - return cbfun; -} - -GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* handle, int* count) -{ - _GLFWmonitor* monitor = (_GLFWmonitor*) handle; - - *count = 0; - - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - - if (!refreshVideoModes(monitor)) - return NULL; - - *count = monitor->modeCount; - return monitor->modes; -} - -GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* handle) -{ - _GLFWmonitor* monitor = (_GLFWmonitor*) handle; - - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - - _glfwPlatformGetVideoMode(monitor, &monitor->currentMode); - return &monitor->currentMode; -} - -GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma) -{ - int i; - unsigned short values[256]; - GLFWgammaramp ramp; - - _GLFW_REQUIRE_INIT(); - - if (gamma <= 0.f) - { - _glfwInputError(GLFW_INVALID_VALUE, - "Gamma value must be greater than zero"); - return; - } - - for (i = 0; i < 256; i++) - { - double value; - - // Calculate intensity - value = i / 255.0; - // Apply gamma curve - value = pow(value, 1.0 / gamma) * 65535.0 + 0.5; - - // Clamp to value range - if (value > 65535.0) - value = 65535.0; - - values[i] = (unsigned short) value; - } - - ramp.red = values; - ramp.green = values; - ramp.blue = values; - ramp.size = 256; - - glfwSetGammaRamp(handle, &ramp); -} - -GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle) -{ - _GLFWmonitor* monitor = (_GLFWmonitor*) handle; - - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - - _glfwFreeGammaArrays(&monitor->currentRamp); - _glfwPlatformGetGammaRamp(monitor, &monitor->currentRamp); - - return &monitor->currentRamp; -} - -GLFWAPI void glfwSetGammaRamp(GLFWmonitor* handle, const GLFWgammaramp* ramp) -{ - _GLFWmonitor* monitor = (_GLFWmonitor*) handle; - - _GLFW_REQUIRE_INIT(); - - if (!monitor->originalRamp.size) - _glfwPlatformGetGammaRamp(monitor, &monitor->originalRamp); - - _glfwPlatformSetGammaRamp(monitor, ramp); -} - diff --git a/examples/common/glfw/src/nsgl_context.h b/examples/common/glfw/src/nsgl_context.h deleted file mode 100644 index fd045359..00000000 --- a/examples/common/glfw/src/nsgl_context.h +++ /dev/null @@ -1,62 +0,0 @@ -//======================================================================== -// GLFW 3.1 OS X - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2009-2010 Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#ifndef _nsgl_context_h_ -#define _nsgl_context_h_ - -#define _GLFW_PLATFORM_FBCONFIG -#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextNSGL nsgl -#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryNSGL nsgl - - -// NSGL-specific per-context data -// -typedef struct _GLFWcontextNSGL -{ - id pixelFormat; - id context; - -} _GLFWcontextNSGL; - - -// NSGL-specific global data -// -typedef struct _GLFWlibraryNSGL -{ - // dlopen handle for OpenGL.framework (for glfwGetProcAddress) - void* framework; - -} _GLFWlibraryNSGL; - - -int _glfwInitContextAPI(void); -void _glfwTerminateContextAPI(void); -int _glfwCreateContext(_GLFWwindow* window, - const _GLFWctxconfig* ctxconfig, - const _GLFWfbconfig* fbconfig); -void _glfwDestroyContext(_GLFWwindow* window); - -#endif // _nsgl_context_h_ diff --git a/examples/common/glfw/src/nsgl_context.m b/examples/common/glfw/src/nsgl_context.m deleted file mode 100644 index 0f0fb86e..00000000 --- a/examples/common/glfw/src/nsgl_context.m +++ /dev/null @@ -1,314 +0,0 @@ -//======================================================================== -// GLFW 3.1 OS X - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2009-2010 Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#include "internal.h" - - -////////////////////////////////////////////////////////////////////////// -////// GLFW internal API ////// -////////////////////////////////////////////////////////////////////////// - -// Initialize OpenGL support -// -int _glfwInitContextAPI(void) -{ - if (!_glfwInitTLS()) - return GL_FALSE; - - _glfw.nsgl.framework = - CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl")); - if (_glfw.nsgl.framework == NULL) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "NSGL: Failed to locate OpenGL framework"); - return GL_FALSE; - } - - return GL_TRUE; -} - -// Terminate OpenGL support -// -void _glfwTerminateContextAPI(void) -{ - _glfwTerminateTLS(); -} - -// Create the OpenGL context -// -int _glfwCreateContext(_GLFWwindow* window, - const _GLFWctxconfig* ctxconfig, - const _GLFWfbconfig* fbconfig) -{ - unsigned int attributeCount = 0; - - if (ctxconfig->api == GLFW_OPENGL_ES_API) - { - _glfwInputError(GLFW_VERSION_UNAVAILABLE, - "NSGL: This API does not support OpenGL ES"); - return GL_FALSE; - } - -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 - if (ctxconfig->major == 3 && ctxconfig->minor < 2) - { - _glfwInputError(GLFW_VERSION_UNAVAILABLE, - "NSGL: The targeted version of OS X does not " - "support OpenGL 3.0 or 3.1"); - return GL_FALSE; - } - - if (ctxconfig->major > 2) - { - if (!ctxconfig->forward) - { - _glfwInputError(GLFW_VERSION_UNAVAILABLE, - "NSGL: The targeted version of OS X only " - "supports OpenGL 3.2 and later versions if they " - "are forward-compatible"); - return GL_FALSE; - } - - if (ctxconfig->profile != GLFW_OPENGL_CORE_PROFILE) - { - _glfwInputError(GLFW_VERSION_UNAVAILABLE, - "NSGL: The targeted version of OS X only " - "supports OpenGL 3.2 and later versions if they " - "use the core profile"); - return GL_FALSE; - } - } -#else - // Fail if OpenGL 3.0 or above was requested - if (ctxconfig->major > 2) - { - _glfwInputError(GLFW_VERSION_UNAVAILABLE, - "NSGL: The targeted version of OS X does not " - "support OpenGL version 3.0 or above"); - return GL_FALSE; - } -#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ - - // Context robustness modes (GL_KHR_robustness) are not yet supported on - // OS X but are not a hard constraint, so ignore and continue - - // Context release behaviors (GL_KHR_context_flush_control) are not yet - // supported on OS X but are not a hard constraint, so ignore and continue - -#define ADD_ATTR(x) { attributes[attributeCount++] = x; } -#define ADD_ATTR2(x, y) { ADD_ATTR(x); ADD_ATTR(y); } - - // Arbitrary array size here - NSOpenGLPixelFormatAttribute attributes[40]; - - ADD_ATTR(NSOpenGLPFAAccelerated); - ADD_ATTR(NSOpenGLPFAClosestPolicy); - -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101000 - if (ctxconfig->major >= 4) - { - ADD_ATTR2(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion4_1Core); - } - else -#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ - if (ctxconfig->major >= 3) - { - ADD_ATTR2(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core); - } -#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ - - if (ctxconfig->major <= 2) - { - if (fbconfig->auxBuffers != GLFW_DONT_CARE) - ADD_ATTR2(NSOpenGLPFAAuxBuffers, fbconfig->auxBuffers); - - if (fbconfig->accumRedBits != GLFW_DONT_CARE && - fbconfig->accumGreenBits != GLFW_DONT_CARE && - fbconfig->accumBlueBits != GLFW_DONT_CARE && - fbconfig->accumAlphaBits != GLFW_DONT_CARE) - { - const int accumBits = fbconfig->accumRedBits + - fbconfig->accumGreenBits + - fbconfig->accumBlueBits + - fbconfig->accumAlphaBits; - - ADD_ATTR2(NSOpenGLPFAAccumSize, accumBits); - } - } - - if (fbconfig->redBits != GLFW_DONT_CARE && - fbconfig->greenBits != GLFW_DONT_CARE && - fbconfig->blueBits != GLFW_DONT_CARE) - { - int colorBits = fbconfig->redBits + - fbconfig->greenBits + - fbconfig->blueBits; - - // OS X needs non-zero color size, so set reasonable values - if (colorBits == 0) - colorBits = 24; - else if (colorBits < 15) - colorBits = 15; - - ADD_ATTR2(NSOpenGLPFAColorSize, colorBits); - } - - if (fbconfig->alphaBits != GLFW_DONT_CARE) - ADD_ATTR2(NSOpenGLPFAAlphaSize, fbconfig->alphaBits); - - if (fbconfig->depthBits != GLFW_DONT_CARE) - ADD_ATTR2(NSOpenGLPFADepthSize, fbconfig->depthBits); - - if (fbconfig->stencilBits != GLFW_DONT_CARE) - ADD_ATTR2(NSOpenGLPFAStencilSize, fbconfig->stencilBits); - - if (fbconfig->stereo) - ADD_ATTR(NSOpenGLPFAStereo); - - if (fbconfig->doublebuffer) - ADD_ATTR(NSOpenGLPFADoubleBuffer); - - if (fbconfig->samples != GLFW_DONT_CARE) - { - if (fbconfig->samples == 0) - { - ADD_ATTR2(NSOpenGLPFASampleBuffers, 0); - } - else - { - ADD_ATTR2(NSOpenGLPFASampleBuffers, 1); - ADD_ATTR2(NSOpenGLPFASamples, fbconfig->samples); - } - } - - // NOTE: All NSOpenGLPixelFormats on the relevant cards support sRGB - // framebuffer, so there's no need (and no way) to request it - - ADD_ATTR(0); - -#undef ADD_ATTR -#undef ADD_ATTR2 - - window->nsgl.pixelFormat = - [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes]; - if (window->nsgl.pixelFormat == nil) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "NSGL: Failed to create OpenGL pixel format"); - return GL_FALSE; - } - - NSOpenGLContext* share = NULL; - - if (ctxconfig->share) - share = ctxconfig->share->nsgl.context; - - window->nsgl.context = - [[NSOpenGLContext alloc] initWithFormat:window->nsgl.pixelFormat - shareContext:share]; - if (window->nsgl.context == nil) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "NSGL: Failed to create OpenGL context"); - return GL_FALSE; - } - - return GL_TRUE; -} - -// Destroy the OpenGL context -// -void _glfwDestroyContext(_GLFWwindow* window) -{ - [window->nsgl.pixelFormat release]; - window->nsgl.pixelFormat = nil; - - [window->nsgl.context release]; - window->nsgl.context = nil; -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW platform API ////// -////////////////////////////////////////////////////////////////////////// - -void _glfwPlatformMakeContextCurrent(_GLFWwindow* window) -{ - if (window) - [window->nsgl.context makeCurrentContext]; - else - [NSOpenGLContext clearCurrentContext]; - - _glfwSetCurrentContext(window); -} - -void _glfwPlatformSwapBuffers(_GLFWwindow* window) -{ - // ARP appears to be unnecessary, but this is future-proof - [window->nsgl.context flushBuffer]; -} - -void _glfwPlatformSwapInterval(int interval) -{ - _GLFWwindow* window = _glfwPlatformGetCurrentContext(); - - GLint sync = interval; - [window->nsgl.context setValues:&sync forParameter:NSOpenGLCPSwapInterval]; -} - -int _glfwPlatformExtensionSupported(const char* extension) -{ - // There are no NSGL extensions - return GL_FALSE; -} - -GLFWglproc _glfwPlatformGetProcAddress(const char* procname) -{ - CFStringRef symbolName = CFStringCreateWithCString(kCFAllocatorDefault, - procname, - kCFStringEncodingASCII); - - GLFWglproc symbol = CFBundleGetFunctionPointerForName(_glfw.nsgl.framework, - symbolName); - - CFRelease(symbolName); - - return symbol; -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW native API ////// -////////////////////////////////////////////////////////////////////////// - -GLFWAPI id glfwGetNSGLContext(GLFWwindow* handle) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - _GLFW_REQUIRE_INIT_OR_RETURN(nil); - return window->nsgl.context; -} - diff --git a/examples/common/glfw/src/posix_time.c b/examples/common/glfw/src/posix_time.c deleted file mode 100644 index 53ea7949..00000000 --- a/examples/common/glfw/src/posix_time.c +++ /dev/null @@ -1,97 +0,0 @@ -//======================================================================== -// GLFW 3.1 POSIX - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2002-2006 Marcus Geelnard -// Copyright (c) 2006-2010 Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#include "internal.h" - -#include -#include - -// Return raw time -// -static uint64_t getRawTime(void) -{ -#if defined(CLOCK_MONOTONIC) - if (_glfw.posix_time.monotonic) - { - struct timespec ts; - - clock_gettime(CLOCK_MONOTONIC, &ts); - return (uint64_t) ts.tv_sec * (uint64_t) 1000000000 + (uint64_t) ts.tv_nsec; - } - else -#endif - { - struct timeval tv; - - gettimeofday(&tv, NULL); - return (uint64_t) tv.tv_sec * (uint64_t) 1000000 + (uint64_t) tv.tv_usec; - } -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW internal API ////// -////////////////////////////////////////////////////////////////////////// - -// Initialise timer -// -void _glfwInitTimer(void) -{ -#if defined(CLOCK_MONOTONIC) - struct timespec ts; - - if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) - { - _glfw.posix_time.monotonic = GL_TRUE; - _glfw.posix_time.resolution = 1e-9; - } - else -#endif - { - _glfw.posix_time.resolution = 1e-6; - } - - _glfw.posix_time.base = getRawTime(); -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW platform API ////// -////////////////////////////////////////////////////////////////////////// - -double _glfwPlatformGetTime(void) -{ - return (double) (getRawTime() - _glfw.posix_time.base) * - _glfw.posix_time.resolution; -} - -void _glfwPlatformSetTime(double time) -{ - _glfw.posix_time.base = getRawTime() - - (uint64_t) (time / _glfw.posix_time.resolution); -} - diff --git a/examples/common/glfw/src/posix_time.h b/examples/common/glfw/src/posix_time.h deleted file mode 100644 index 3e0955a1..00000000 --- a/examples/common/glfw/src/posix_time.h +++ /dev/null @@ -1,49 +0,0 @@ -//======================================================================== -// GLFW 3.1 POSIX - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2002-2006 Marcus Geelnard -// Copyright (c) 2006-2010 Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#ifndef _posix_time_h_ -#define _posix_time_h_ - -#define _GLFW_PLATFORM_LIBRARY_TIME_STATE _GLFWtimePOSIX posix_time - -#include - - -// POSIX-specific global timer data -// -typedef struct _GLFWtimePOSIX -{ - GLboolean monotonic; - double resolution; - uint64_t base; - -} _GLFWtimePOSIX; - - -void _glfwInitTimer(void); - -#endif // _posix_time_h_ diff --git a/examples/common/glfw/src/posix_tls.c b/examples/common/glfw/src/posix_tls.c deleted file mode 100644 index 70fe19bb..00000000 --- a/examples/common/glfw/src/posix_tls.c +++ /dev/null @@ -1,66 +0,0 @@ -//======================================================================== -// GLFW 3.1 POSIX - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2002-2006 Marcus Geelnard -// Copyright (c) 2006-2010 Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#include "internal.h" - - -////////////////////////////////////////////////////////////////////////// -////// GLFW internal API ////// -////////////////////////////////////////////////////////////////////////// - -int _glfwInitTLS(void) -{ - if (pthread_key_create(&_glfw.posix_tls.context, NULL) != 0) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "POSIX: Failed to create context TLS"); - return GL_FALSE; - } - - return GL_TRUE; -} - -void _glfwTerminateTLS(void) -{ - pthread_key_delete(_glfw.posix_tls.context); -} - -void _glfwSetCurrentContext(_GLFWwindow* context) -{ - pthread_setspecific(_glfw.posix_tls.context, context); -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW platform API ////// -////////////////////////////////////////////////////////////////////////// - -_GLFWwindow* _glfwPlatformGetCurrentContext(void) -{ - return pthread_getspecific(_glfw.posix_tls.context); -} - diff --git a/examples/common/glfw/src/posix_tls.h b/examples/common/glfw/src/posix_tls.h deleted file mode 100644 index d6fa000d..00000000 --- a/examples/common/glfw/src/posix_tls.h +++ /dev/null @@ -1,49 +0,0 @@ -//======================================================================== -// GLFW 3.1 POSIX - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2002-2006 Marcus Geelnard -// Copyright (c) 2006-2010 Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#ifndef _posix_tls_h_ -#define _posix_tls_h_ - -#include - -#define _GLFW_PLATFORM_LIBRARY_TLS_STATE _GLFWtlsPOSIX posix_tls - - -// POSIX-specific global TLS data -// -typedef struct _GLFWtlsPOSIX -{ - pthread_key_t context; - -} _GLFWtlsPOSIX; - - -int _glfwInitTLS(void); -void _glfwTerminateTLS(void); -void _glfwSetCurrentContext(_GLFWwindow* context); - -#endif // _posix_tls_h_ diff --git a/examples/common/glfw/src/wgl_context.c b/examples/common/glfw/src/wgl_context.c deleted file mode 100644 index 7b3b9c90..00000000 --- a/examples/common/glfw/src/wgl_context.c +++ /dev/null @@ -1,709 +0,0 @@ -//======================================================================== -// GLFW 3.1 WGL - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2002-2006 Marcus Geelnard -// Copyright (c) 2006-2010 Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#include "internal.h" - -#include -#include -#include - - -// Initialize WGL-specific extensions -// This function is called once before initial context creation, i.e. before -// any WGL extensions could be present. This is done in order to have both -// extension variable clearing and loading in the same place, hopefully -// decreasing the possibility of forgetting to add one without the other. -// -static void initWGLExtensions(_GLFWwindow* window) -{ - // This needs to include every function pointer loaded below - window->wgl.SwapIntervalEXT = NULL; - window->wgl.GetPixelFormatAttribivARB = NULL; - window->wgl.GetExtensionsStringARB = NULL; - window->wgl.GetExtensionsStringEXT = NULL; - window->wgl.CreateContextAttribsARB = NULL; - - // This needs to include every extension used below except for - // WGL_ARB_extensions_string and WGL_EXT_extensions_string - window->wgl.ARB_multisample = GL_FALSE; - window->wgl.ARB_framebuffer_sRGB = GL_FALSE; - window->wgl.ARB_create_context = GL_FALSE; - window->wgl.ARB_create_context_profile = GL_FALSE; - window->wgl.EXT_create_context_es2_profile = GL_FALSE; - window->wgl.ARB_create_context_robustness = GL_FALSE; - window->wgl.EXT_swap_control = GL_FALSE; - window->wgl.ARB_pixel_format = GL_FALSE; - window->wgl.ARB_context_flush_control = GL_FALSE; - - window->wgl.GetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC) - wglGetProcAddress("wglGetExtensionsStringEXT"); - if (!window->wgl.GetExtensionsStringEXT) - { - window->wgl.GetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC) - wglGetProcAddress("wglGetExtensionsStringARB"); - if (!window->wgl.GetExtensionsStringARB) - return; - } - - if (_glfwPlatformExtensionSupported("WGL_ARB_multisample")) - window->wgl.ARB_multisample = GL_TRUE; - - if (_glfwPlatformExtensionSupported("WGL_ARB_framebuffer_sRGB")) - window->wgl.ARB_framebuffer_sRGB = GL_TRUE; - - if (_glfwPlatformExtensionSupported("WGL_ARB_create_context")) - { - window->wgl.CreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC) - wglGetProcAddress("wglCreateContextAttribsARB"); - - if (window->wgl.CreateContextAttribsARB) - window->wgl.ARB_create_context = GL_TRUE; - } - - if (window->wgl.ARB_create_context) - { - if (_glfwPlatformExtensionSupported("WGL_ARB_create_context_profile")) - window->wgl.ARB_create_context_profile = GL_TRUE; - } - - if (window->wgl.ARB_create_context && - window->wgl.ARB_create_context_profile) - { - if (_glfwPlatformExtensionSupported("WGL_EXT_create_context_es2_profile")) - window->wgl.EXT_create_context_es2_profile = GL_TRUE; - } - - if (window->wgl.ARB_create_context) - { - if (_glfwPlatformExtensionSupported("WGL_ARB_create_context_robustness")) - window->wgl.ARB_create_context_robustness = GL_TRUE; - } - - if (_glfwPlatformExtensionSupported("WGL_EXT_swap_control")) - { - window->wgl.SwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC) - wglGetProcAddress("wglSwapIntervalEXT"); - - if (window->wgl.SwapIntervalEXT) - window->wgl.EXT_swap_control = GL_TRUE; - } - - if (_glfwPlatformExtensionSupported("WGL_ARB_pixel_format")) - { - window->wgl.GetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC) - wglGetProcAddress("wglGetPixelFormatAttribivARB"); - - if (window->wgl.GetPixelFormatAttribivARB) - window->wgl.ARB_pixel_format = GL_TRUE; - } - - if (_glfwPlatformExtensionSupported("WGL_ARB_context_flush_control")) - window->wgl.ARB_context_flush_control = GL_TRUE; -} - -// Returns the specified attribute of the specified pixel format -// NOTE: Do not call this unless we have found WGL_ARB_pixel_format -// -static int getPixelFormatAttrib(_GLFWwindow* window, int pixelFormat, int attrib) -{ - int value = 0; - - if (!window->wgl.GetPixelFormatAttribivARB(window->wgl.dc, - pixelFormat, - 0, 1, &attrib, &value)) - { - // NOTE: We should probably handle this error somehow - return 0; - } - - return value; -} - -// Return a list of available and usable framebuffer configs -// -static GLboolean choosePixelFormat(_GLFWwindow* window, - const _GLFWfbconfig* desired, - int* result) -{ - _GLFWfbconfig* usableConfigs; - const _GLFWfbconfig* closest; - int i, nativeCount, usableCount; - - if (window->wgl.ARB_pixel_format) - { - nativeCount = getPixelFormatAttrib(window, - 1, - WGL_NUMBER_PIXEL_FORMATS_ARB); - } - else - { - nativeCount = DescribePixelFormat(window->wgl.dc, - 1, - sizeof(PIXELFORMATDESCRIPTOR), - NULL); - } - - if (!nativeCount) - { - _glfwInputError(GLFW_API_UNAVAILABLE, "WGL: No pixel formats found"); - return GL_FALSE; - } - - usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig)); - usableCount = 0; - - for (i = 0; i < nativeCount; i++) - { - const int n = i + 1; - _GLFWfbconfig* u = usableConfigs + usableCount; - - if (window->wgl.ARB_pixel_format) - { - // Get pixel format attributes through WGL_ARB_pixel_format - if (!getPixelFormatAttrib(window, n, WGL_SUPPORT_OPENGL_ARB) || - !getPixelFormatAttrib(window, n, WGL_DRAW_TO_WINDOW_ARB)) - { - continue; - } - - if (getPixelFormatAttrib(window, n, WGL_PIXEL_TYPE_ARB) != - WGL_TYPE_RGBA_ARB) - { - continue; - } - - if (getPixelFormatAttrib(window, n, WGL_ACCELERATION_ARB) == - WGL_NO_ACCELERATION_ARB) - { - continue; - } - - u->redBits = getPixelFormatAttrib(window, n, WGL_RED_BITS_ARB); - u->greenBits = getPixelFormatAttrib(window, n, WGL_GREEN_BITS_ARB); - u->blueBits = getPixelFormatAttrib(window, n, WGL_BLUE_BITS_ARB); - u->alphaBits = getPixelFormatAttrib(window, n, WGL_ALPHA_BITS_ARB); - - u->depthBits = getPixelFormatAttrib(window, n, WGL_DEPTH_BITS_ARB); - u->stencilBits = getPixelFormatAttrib(window, n, WGL_STENCIL_BITS_ARB); - - u->accumRedBits = getPixelFormatAttrib(window, n, WGL_ACCUM_RED_BITS_ARB); - u->accumGreenBits = getPixelFormatAttrib(window, n, WGL_ACCUM_GREEN_BITS_ARB); - u->accumBlueBits = getPixelFormatAttrib(window, n, WGL_ACCUM_BLUE_BITS_ARB); - u->accumAlphaBits = getPixelFormatAttrib(window, n, WGL_ACCUM_ALPHA_BITS_ARB); - - u->auxBuffers = getPixelFormatAttrib(window, n, WGL_AUX_BUFFERS_ARB); - - if (getPixelFormatAttrib(window, n, WGL_STEREO_ARB)) - u->stereo = GL_TRUE; - if (getPixelFormatAttrib(window, n, WGL_DOUBLE_BUFFER_ARB)) - u->doublebuffer = GL_TRUE; - - if (window->wgl.ARB_multisample) - u->samples = getPixelFormatAttrib(window, n, WGL_SAMPLES_ARB); - - if (window->wgl.ARB_framebuffer_sRGB) - { - if (getPixelFormatAttrib(window, n, WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB)) - u->sRGB = GL_TRUE; - } - } - else - { - PIXELFORMATDESCRIPTOR pfd; - - // Get pixel format attributes through old-fashioned PFDs - - if (!DescribePixelFormat(window->wgl.dc, - n, - sizeof(PIXELFORMATDESCRIPTOR), - &pfd)) - { - continue; - } - - if (!(pfd.dwFlags & PFD_DRAW_TO_WINDOW) || - !(pfd.dwFlags & PFD_SUPPORT_OPENGL)) - { - continue; - } - - if (!(pfd.dwFlags & PFD_GENERIC_ACCELERATED) && - (pfd.dwFlags & PFD_GENERIC_FORMAT)) - { - continue; - } - - if (pfd.iPixelType != PFD_TYPE_RGBA) - continue; - - u->redBits = pfd.cRedBits; - u->greenBits = pfd.cGreenBits; - u->blueBits = pfd.cBlueBits; - u->alphaBits = pfd.cAlphaBits; - - u->depthBits = pfd.cDepthBits; - u->stencilBits = pfd.cStencilBits; - - u->accumRedBits = pfd.cAccumRedBits; - u->accumGreenBits = pfd.cAccumGreenBits; - u->accumBlueBits = pfd.cAccumBlueBits; - u->accumAlphaBits = pfd.cAccumAlphaBits; - - u->auxBuffers = pfd.cAuxBuffers; - - if (pfd.dwFlags & PFD_STEREO) - u->stereo = GL_TRUE; - if (pfd.dwFlags & PFD_DOUBLEBUFFER) - u->doublebuffer = GL_TRUE; - } - - u->wgl = n; - usableCount++; - } - - if (!usableCount) - { - _glfwInputError(GLFW_API_UNAVAILABLE, - "WGL: The driver does not appear to support OpenGL"); - - free(usableConfigs); - return GL_FALSE; - } - - closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount); - if (!closest) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "WGL: Failed to find a suitable pixel format"); - - free(usableConfigs); - return GL_FALSE; - } - - *result = closest->wgl; - free(usableConfigs); - - return GL_TRUE; -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW internal API ////// -////////////////////////////////////////////////////////////////////////// - -// Initialize WGL -// -int _glfwInitContextAPI(void) -{ - if (!_glfwInitTLS()) - return GL_FALSE; - - _glfw.wgl.opengl32.instance = LoadLibraryW(L"opengl32.dll"); - if (!_glfw.wgl.opengl32.instance) - { - _glfwInputError(GLFW_PLATFORM_ERROR, "Failed to load opengl32.dll"); - return GL_FALSE; - } - - return GL_TRUE; -} - -// Terminate WGL -// -void _glfwTerminateContextAPI(void) -{ - if (_glfw.wgl.opengl32.instance) - FreeLibrary(_glfw.wgl.opengl32.instance); - - _glfwTerminateTLS(); -} - -#define setWGLattrib(attribName, attribValue) \ -{ \ - attribs[index++] = attribName; \ - attribs[index++] = attribValue; \ - assert((size_t) index < sizeof(attribs) / sizeof(attribs[0])); \ -} - -// Create the OpenGL or OpenGL ES context -// -int _glfwCreateContext(_GLFWwindow* window, - const _GLFWctxconfig* ctxconfig, - const _GLFWfbconfig* fbconfig) -{ - int attribs[40]; - int pixelFormat = 0; - PIXELFORMATDESCRIPTOR pfd; - HGLRC share = NULL; - - if (ctxconfig->share) - share = ctxconfig->share->wgl.context; - - window->wgl.dc = GetDC(window->win32.handle); - if (!window->wgl.dc) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Win32: Failed to retrieve DC for window"); - return GL_FALSE; - } - - if (!choosePixelFormat(window, fbconfig, &pixelFormat)) - return GL_FALSE; - - if (!DescribePixelFormat(window->wgl.dc, pixelFormat, sizeof(pfd), &pfd)) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Win32: Failed to retrieve PFD for selected pixel " - "format"); - return GL_FALSE; - } - - if (!SetPixelFormat(window->wgl.dc, pixelFormat, &pfd)) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Win32: Failed to set selected pixel format"); - return GL_FALSE; - } - - if (window->wgl.ARB_create_context) - { - int index = 0, mask = 0, flags = 0, strategy = 0; - - if (ctxconfig->api == GLFW_OPENGL_API) - { - if (ctxconfig->forward) - flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; - - if (ctxconfig->debug) - flags |= WGL_CONTEXT_DEBUG_BIT_ARB; - - if (ctxconfig->profile) - { - if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE) - mask |= WGL_CONTEXT_CORE_PROFILE_BIT_ARB; - else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE) - mask |= WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; - } - } - else - mask |= WGL_CONTEXT_ES2_PROFILE_BIT_EXT; - - if (ctxconfig->robustness) - { - if (window->wgl.ARB_create_context_robustness) - { - if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION) - strategy = WGL_NO_RESET_NOTIFICATION_ARB; - else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET) - strategy = WGL_LOSE_CONTEXT_ON_RESET_ARB; - - flags |= WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB; - } - } - - if (ctxconfig->release) - { - if (window->wgl.ARB_context_flush_control) - { - if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE) - { - setWGLattrib(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB, - WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB); - } - else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH) - { - setWGLattrib(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB, - WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB); - } - } - } - - if (ctxconfig->major != 1 || ctxconfig->minor != 0) - { - // NOTE: Only request an explicitly versioned context when - // necessary, as explicitly requesting version 1.0 does not - // always return the highest available version - - setWGLattrib(WGL_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major); - setWGLattrib(WGL_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor); - } - - if (flags) - setWGLattrib(WGL_CONTEXT_FLAGS_ARB, flags); - - if (mask) - setWGLattrib(WGL_CONTEXT_PROFILE_MASK_ARB, mask); - - if (strategy) - setWGLattrib(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, strategy); - - setWGLattrib(0, 0); - - window->wgl.context = window->wgl.CreateContextAttribsARB(window->wgl.dc, - share, - attribs); - if (!window->wgl.context) - { - _glfwInputError(GLFW_VERSION_UNAVAILABLE, - "WGL: Failed to create OpenGL context"); - return GL_FALSE; - } - } - else - { - window->wgl.context = wglCreateContext(window->wgl.dc); - if (!window->wgl.context) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "WGL: Failed to create OpenGL context"); - return GL_FALSE; - } - - if (share) - { - if (!wglShareLists(share, window->wgl.context)) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "WGL: Failed to enable sharing with specified " - "OpenGL context"); - return GL_FALSE; - } - } - } - - _glfwPlatformMakeContextCurrent(window); - initWGLExtensions(window); - - return GL_TRUE; -} - -#undef setWGLattrib - -// Destroy the OpenGL context -// -void _glfwDestroyContext(_GLFWwindow* window) -{ - if (window->wgl.context) - { - wglDeleteContext(window->wgl.context); - window->wgl.context = NULL; - } - - if (window->wgl.dc) - { - ReleaseDC(window->win32.handle, window->wgl.dc); - window->wgl.dc = NULL; - } -} - -// Analyzes the specified context for possible recreation -// -int _glfwAnalyzeContext(const _GLFWwindow* window, - const _GLFWctxconfig* ctxconfig, - const _GLFWfbconfig* fbconfig) -{ - GLboolean required = GL_FALSE; - - if (ctxconfig->api == GLFW_OPENGL_API) - { - if (ctxconfig->forward) - { - if (!window->wgl.ARB_create_context) - { - _glfwInputError(GLFW_VERSION_UNAVAILABLE, - "WGL: A forward compatible OpenGL context " - "requested but WGL_ARB_create_context is " - "unavailable"); - return _GLFW_RECREATION_IMPOSSIBLE; - } - - required = GL_TRUE; - } - - if (ctxconfig->profile) - { - if (!window->wgl.ARB_create_context_profile) - { - _glfwInputError(GLFW_VERSION_UNAVAILABLE, - "WGL: OpenGL profile requested but " - "WGL_ARB_create_context_profile is unavailable"); - return _GLFW_RECREATION_IMPOSSIBLE; - } - - required = GL_TRUE; - } - - if (ctxconfig->release) - { - if (window->wgl.ARB_context_flush_control) - required = GL_TRUE; - } - } - else - { - if (!window->wgl.ARB_create_context || - !window->wgl.ARB_create_context_profile || - !window->wgl.EXT_create_context_es2_profile) - { - _glfwInputError(GLFW_API_UNAVAILABLE, - "WGL: OpenGL ES requested but " - "WGL_ARB_create_context_es2_profile is unavailable"); - return _GLFW_RECREATION_IMPOSSIBLE; - } - - required = GL_TRUE; - } - - if (ctxconfig->major != 1 || ctxconfig->minor != 0) - { - if (window->wgl.ARB_create_context) - required = GL_TRUE; - } - - if (ctxconfig->debug) - { - if (window->wgl.ARB_create_context) - required = GL_TRUE; - } - - if (fbconfig->samples > 0) - { - // We want FSAA, but can we get it? - // FSAA is not a hard constraint, so otherwise we just don't care - - if (window->wgl.ARB_multisample && window->wgl.ARB_pixel_format) - { - // We appear to have both the extension and the means to ask for it - required = GL_TRUE; - } - } - - if (fbconfig->sRGB) - { - // We want sRGB, but can we get it? - // sRGB is not a hard constraint, so otherwise we just don't care - - if (window->wgl.ARB_framebuffer_sRGB && window->wgl.ARB_pixel_format) - { - // We appear to have both the extension and the means to ask for it - required = GL_TRUE; - } - } - - if (required) - return _GLFW_RECREATION_REQUIRED; - - return _GLFW_RECREATION_NOT_NEEDED; -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW platform API ////// -////////////////////////////////////////////////////////////////////////// - -void _glfwPlatformMakeContextCurrent(_GLFWwindow* window) -{ - if (window) - wglMakeCurrent(window->wgl.dc, window->wgl.context); - else - wglMakeCurrent(NULL, NULL); - - _glfwSetCurrentContext(window); -} - -void _glfwPlatformSwapBuffers(_GLFWwindow* window) -{ - SwapBuffers(window->wgl.dc); -} - -void _glfwPlatformSwapInterval(int interval) -{ - _GLFWwindow* window = _glfwPlatformGetCurrentContext(); - -#if !defined(_GLFW_USE_DWM_SWAP_INTERVAL) - if (_glfwIsCompositionEnabled() && interval) - { - // Don't enabled vsync when desktop compositing is enabled, as it leads - // to frame jitter - return; - } -#endif - - if (window->wgl.EXT_swap_control) - window->wgl.SwapIntervalEXT(interval); -} - -int _glfwPlatformExtensionSupported(const char* extension) -{ - const GLubyte* extensions; - - _GLFWwindow* window = _glfwPlatformGetCurrentContext(); - - if (window->wgl.GetExtensionsStringEXT != NULL) - { - extensions = (GLubyte*) window->wgl.GetExtensionsStringEXT(); - if (extensions != NULL) - { - if (_glfwStringInExtensionString(extension, extensions)) - return GL_TRUE; - } - } - - if (window->wgl.GetExtensionsStringARB != NULL) - { - extensions = (GLubyte*) window->wgl.GetExtensionsStringARB(window->wgl.dc); - if (extensions != NULL) - { - if (_glfwStringInExtensionString(extension, extensions)) - return GL_TRUE; - } - } - - return GL_FALSE; -} - -GLFWglproc _glfwPlatformGetProcAddress(const char* procname) -{ - const GLFWglproc proc = (GLFWglproc) wglGetProcAddress(procname); - if (proc) - return proc; - - return (GLFWglproc) GetProcAddress(_glfw.wgl.opengl32.instance, procname); -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW native API ////// -////////////////////////////////////////////////////////////////////////// - -GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* handle) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - return window->wgl.context; -} - diff --git a/examples/common/glfw/src/wgl_context.h b/examples/common/glfw/src/wgl_context.h deleted file mode 100644 index 3fc29e72..00000000 --- a/examples/common/glfw/src/wgl_context.h +++ /dev/null @@ -1,89 +0,0 @@ -//======================================================================== -// GLFW 3.1 WGL - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2002-2006 Marcus Geelnard -// Copyright (c) 2006-2010 Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#ifndef _wgl_context_h_ -#define _wgl_context_h_ - -// This path may need to be changed if you build GLFW using your own setup -// We ship and use our own copy of wglext.h since GLFW uses fairly new -// extensions and not all operating systems come with an up-to-date version -#include "../deps/GL/wglext.h" - -#define _GLFW_PLATFORM_FBCONFIG int wgl -#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextWGL wgl -#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryWGL wgl - - -// WGL-specific per-context data -// -typedef struct _GLFWcontextWGL -{ - HDC dc; // Private GDI device context - HGLRC context; // Permanent rendering context - - // WGL extensions (context specific) - PFNWGLSWAPINTERVALEXTPROC SwapIntervalEXT; - PFNWGLGETPIXELFORMATATTRIBIVARBPROC GetPixelFormatAttribivARB; - PFNWGLGETEXTENSIONSSTRINGEXTPROC GetExtensionsStringEXT; - PFNWGLGETEXTENSIONSSTRINGARBPROC GetExtensionsStringARB; - PFNWGLCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB; - GLboolean EXT_swap_control; - GLboolean ARB_multisample; - GLboolean ARB_framebuffer_sRGB; - GLboolean ARB_pixel_format; - GLboolean ARB_create_context; - GLboolean ARB_create_context_profile; - GLboolean EXT_create_context_es2_profile; - GLboolean ARB_create_context_robustness; - GLboolean ARB_context_flush_control; - -} _GLFWcontextWGL; - - -// WGL-specific global data -// -typedef struct _GLFWlibraryWGL -{ - // opengl32.dll (for glfwGetProcAddress) - struct { - HINSTANCE instance; - } opengl32; - -} _GLFWlibraryWGL; - - -int _glfwInitContextAPI(void); -void _glfwTerminateContextAPI(void); -int _glfwCreateContext(_GLFWwindow* window, - const _GLFWctxconfig* ctxconfig, - const _GLFWfbconfig* fbconfig); -void _glfwDestroyContext(_GLFWwindow* window); -int _glfwAnalyzeContext(const _GLFWwindow* window, - const _GLFWctxconfig* ctxconfig, - const _GLFWfbconfig* fbconfig); - -#endif // _wgl_context_h_ diff --git a/examples/common/glfw/src/win32_init.c b/examples/common/glfw/src/win32_init.c deleted file mode 100644 index 964b23aa..00000000 --- a/examples/common/glfw/src/win32_init.c +++ /dev/null @@ -1,394 +0,0 @@ -//======================================================================== -// GLFW 3.1 Win32 - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2002-2006 Marcus Geelnard -// Copyright (c) 2006-2010 Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#include "internal.h" - -#include -#include - -#ifdef __BORLANDC__ -// With the Borland C++ compiler, we want to disable FPU exceptions -#include -#endif // __BORLANDC__ - - -#if defined(_GLFW_USE_OPTIMUS_HPG) - -// Applications exporting this symbol with this value will be automatically -// directed to the high-performance GPU on Nvidia Optimus systems -// -__declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; - -#endif // _GLFW_USE_OPTIMUS_HPG - -#if defined(_GLFW_BUILD_DLL) - -// GLFW DLL entry point -// -BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) -{ - return TRUE; -} - -#endif // _GLFW_BUILD_DLL - -// Load necessary libraries (DLLs) -// -static GLboolean initLibraries(void) -{ - _glfw.win32.winmm.instance = LoadLibraryW(L"winmm.dll"); - if (!_glfw.win32.winmm.instance) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Win32: Failed to load winmm.dll"); - return GL_FALSE; - } - - _glfw.win32.winmm.joyGetDevCaps = (JOYGETDEVCAPS_T) - GetProcAddress(_glfw.win32.winmm.instance, "joyGetDevCapsW"); - _glfw.win32.winmm.joyGetPos = (JOYGETPOS_T) - GetProcAddress(_glfw.win32.winmm.instance, "joyGetPos"); - _glfw.win32.winmm.joyGetPosEx = (JOYGETPOSEX_T) - GetProcAddress(_glfw.win32.winmm.instance, "joyGetPosEx"); - _glfw.win32.winmm.timeGetTime = (TIMEGETTIME_T) - GetProcAddress(_glfw.win32.winmm.instance, "timeGetTime"); - - if (!_glfw.win32.winmm.joyGetDevCaps || - !_glfw.win32.winmm.joyGetPos || - !_glfw.win32.winmm.joyGetPosEx || - !_glfw.win32.winmm.timeGetTime) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Win32: Failed to load winmm functions"); - return GL_FALSE; - } - - _glfw.win32.user32.instance = LoadLibraryW(L"user32.dll"); - if (_glfw.win32.user32.instance) - { - _glfw.win32.user32.SetProcessDPIAware = (SETPROCESSDPIAWARE_T) - GetProcAddress(_glfw.win32.user32.instance, "SetProcessDPIAware"); - _glfw.win32.user32.ChangeWindowMessageFilterEx = (CHANGEWINDOWMESSAGEFILTEREX_T) - GetProcAddress(_glfw.win32.user32.instance, "ChangeWindowMessageFilterEx"); - } - - _glfw.win32.dwmapi.instance = LoadLibraryW(L"dwmapi.dll"); - if (_glfw.win32.dwmapi.instance) - { - _glfw.win32.dwmapi.DwmIsCompositionEnabled = (DWMISCOMPOSITIONENABLED_T) - GetProcAddress(_glfw.win32.dwmapi.instance, "DwmIsCompositionEnabled"); - } - - return GL_TRUE; -} - -// Unload used libraries (DLLs) -// -static void terminateLibraries(void) -{ - if (_glfw.win32.winmm.instance) - FreeLibrary(_glfw.win32.winmm.instance); - - if (_glfw.win32.user32.instance) - FreeLibrary(_glfw.win32.user32.instance); - - if (_glfw.win32.dwmapi.instance) - FreeLibrary(_glfw.win32.dwmapi.instance); -} - -// Create key code translation tables -// -static void createKeyTables(void) -{ - memset(_glfw.win32.publicKeys, -1, sizeof(_glfw.win32.publicKeys)); - - _glfw.win32.publicKeys[0x00B] = GLFW_KEY_0; - _glfw.win32.publicKeys[0x002] = GLFW_KEY_1; - _glfw.win32.publicKeys[0x003] = GLFW_KEY_2; - _glfw.win32.publicKeys[0x004] = GLFW_KEY_3; - _glfw.win32.publicKeys[0x005] = GLFW_KEY_4; - _glfw.win32.publicKeys[0x006] = GLFW_KEY_5; - _glfw.win32.publicKeys[0x007] = GLFW_KEY_6; - _glfw.win32.publicKeys[0x008] = GLFW_KEY_7; - _glfw.win32.publicKeys[0x009] = GLFW_KEY_8; - _glfw.win32.publicKeys[0x00A] = GLFW_KEY_9; - _glfw.win32.publicKeys[0x01E] = GLFW_KEY_A; - _glfw.win32.publicKeys[0x030] = GLFW_KEY_B; - _glfw.win32.publicKeys[0x02E] = GLFW_KEY_C; - _glfw.win32.publicKeys[0x020] = GLFW_KEY_D; - _glfw.win32.publicKeys[0x012] = GLFW_KEY_E; - _glfw.win32.publicKeys[0x021] = GLFW_KEY_F; - _glfw.win32.publicKeys[0x022] = GLFW_KEY_G; - _glfw.win32.publicKeys[0x023] = GLFW_KEY_H; - _glfw.win32.publicKeys[0x017] = GLFW_KEY_I; - _glfw.win32.publicKeys[0x024] = GLFW_KEY_J; - _glfw.win32.publicKeys[0x025] = GLFW_KEY_K; - _glfw.win32.publicKeys[0x026] = GLFW_KEY_L; - _glfw.win32.publicKeys[0x032] = GLFW_KEY_M; - _glfw.win32.publicKeys[0x031] = GLFW_KEY_N; - _glfw.win32.publicKeys[0x018] = GLFW_KEY_O; - _glfw.win32.publicKeys[0x019] = GLFW_KEY_P; - _glfw.win32.publicKeys[0x010] = GLFW_KEY_Q; - _glfw.win32.publicKeys[0x013] = GLFW_KEY_R; - _glfw.win32.publicKeys[0x01F] = GLFW_KEY_S; - _glfw.win32.publicKeys[0x014] = GLFW_KEY_T; - _glfw.win32.publicKeys[0x016] = GLFW_KEY_U; - _glfw.win32.publicKeys[0x02F] = GLFW_KEY_V; - _glfw.win32.publicKeys[0x011] = GLFW_KEY_W; - _glfw.win32.publicKeys[0x02D] = GLFW_KEY_X; - _glfw.win32.publicKeys[0x015] = GLFW_KEY_Y; - _glfw.win32.publicKeys[0x02C] = GLFW_KEY_Z; - - _glfw.win32.publicKeys[0x028] = GLFW_KEY_APOSTROPHE; - _glfw.win32.publicKeys[0x02B] = GLFW_KEY_BACKSLASH; - _glfw.win32.publicKeys[0x033] = GLFW_KEY_COMMA; - _glfw.win32.publicKeys[0x00D] = GLFW_KEY_EQUAL; - _glfw.win32.publicKeys[0x029] = GLFW_KEY_GRAVE_ACCENT; - _glfw.win32.publicKeys[0x01A] = GLFW_KEY_LEFT_BRACKET; - _glfw.win32.publicKeys[0x00C] = GLFW_KEY_MINUS; - _glfw.win32.publicKeys[0x034] = GLFW_KEY_PERIOD; - _glfw.win32.publicKeys[0x01B] = GLFW_KEY_RIGHT_BRACKET; - _glfw.win32.publicKeys[0x027] = GLFW_KEY_SEMICOLON; - _glfw.win32.publicKeys[0x035] = GLFW_KEY_SLASH; - _glfw.win32.publicKeys[0x056] = GLFW_KEY_WORLD_2; - - _glfw.win32.publicKeys[0x00E] = GLFW_KEY_BACKSPACE; - _glfw.win32.publicKeys[0x153] = GLFW_KEY_DELETE; - _glfw.win32.publicKeys[0x14F] = GLFW_KEY_END; - _glfw.win32.publicKeys[0x01C] = GLFW_KEY_ENTER; - _glfw.win32.publicKeys[0x001] = GLFW_KEY_ESCAPE; - _glfw.win32.publicKeys[0x147] = GLFW_KEY_HOME; - _glfw.win32.publicKeys[0x152] = GLFW_KEY_INSERT; - _glfw.win32.publicKeys[0x15D] = GLFW_KEY_MENU; - _glfw.win32.publicKeys[0x151] = GLFW_KEY_PAGE_DOWN; - _glfw.win32.publicKeys[0x149] = GLFW_KEY_PAGE_UP; - _glfw.win32.publicKeys[0x045] = GLFW_KEY_PAUSE; - _glfw.win32.publicKeys[0x039] = GLFW_KEY_SPACE; - _glfw.win32.publicKeys[0x00F] = GLFW_KEY_TAB; - _glfw.win32.publicKeys[0x03A] = GLFW_KEY_CAPS_LOCK; - _glfw.win32.publicKeys[0x145] = GLFW_KEY_NUM_LOCK; - _glfw.win32.publicKeys[0x046] = GLFW_KEY_SCROLL_LOCK; - _glfw.win32.publicKeys[0x03B] = GLFW_KEY_F1; - _glfw.win32.publicKeys[0x03C] = GLFW_KEY_F2; - _glfw.win32.publicKeys[0x03D] = GLFW_KEY_F3; - _glfw.win32.publicKeys[0x03E] = GLFW_KEY_F4; - _glfw.win32.publicKeys[0x03F] = GLFW_KEY_F5; - _glfw.win32.publicKeys[0x040] = GLFW_KEY_F6; - _glfw.win32.publicKeys[0x041] = GLFW_KEY_F7; - _glfw.win32.publicKeys[0x042] = GLFW_KEY_F8; - _glfw.win32.publicKeys[0x043] = GLFW_KEY_F9; - _glfw.win32.publicKeys[0x044] = GLFW_KEY_F10; - _glfw.win32.publicKeys[0x057] = GLFW_KEY_F11; - _glfw.win32.publicKeys[0x058] = GLFW_KEY_F12; - _glfw.win32.publicKeys[0x064] = GLFW_KEY_F13; - _glfw.win32.publicKeys[0x065] = GLFW_KEY_F14; - _glfw.win32.publicKeys[0x066] = GLFW_KEY_F15; - _glfw.win32.publicKeys[0x067] = GLFW_KEY_F16; - _glfw.win32.publicKeys[0x068] = GLFW_KEY_F17; - _glfw.win32.publicKeys[0x069] = GLFW_KEY_F18; - _glfw.win32.publicKeys[0x06A] = GLFW_KEY_F19; - _glfw.win32.publicKeys[0x06B] = GLFW_KEY_F20; - _glfw.win32.publicKeys[0x06C] = GLFW_KEY_F21; - _glfw.win32.publicKeys[0x06D] = GLFW_KEY_F22; - _glfw.win32.publicKeys[0x06E] = GLFW_KEY_F23; - _glfw.win32.publicKeys[0x076] = GLFW_KEY_F24; - _glfw.win32.publicKeys[0x038] = GLFW_KEY_LEFT_ALT; - _glfw.win32.publicKeys[0x01D] = GLFW_KEY_LEFT_CONTROL; - _glfw.win32.publicKeys[0x02A] = GLFW_KEY_LEFT_SHIFT; - _glfw.win32.publicKeys[0x15B] = GLFW_KEY_LEFT_SUPER; - _glfw.win32.publicKeys[0x137] = GLFW_KEY_PRINT_SCREEN; - _glfw.win32.publicKeys[0x138] = GLFW_KEY_RIGHT_ALT; - _glfw.win32.publicKeys[0x11D] = GLFW_KEY_RIGHT_CONTROL; - _glfw.win32.publicKeys[0x036] = GLFW_KEY_RIGHT_SHIFT; - _glfw.win32.publicKeys[0x15C] = GLFW_KEY_RIGHT_SUPER; - _glfw.win32.publicKeys[0x150] = GLFW_KEY_DOWN; - _glfw.win32.publicKeys[0x14B] = GLFW_KEY_LEFT; - _glfw.win32.publicKeys[0x14D] = GLFW_KEY_RIGHT; - _glfw.win32.publicKeys[0x148] = GLFW_KEY_UP; - - _glfw.win32.publicKeys[0x052] = GLFW_KEY_KP_0; - _glfw.win32.publicKeys[0x04F] = GLFW_KEY_KP_1; - _glfw.win32.publicKeys[0x050] = GLFW_KEY_KP_2; - _glfw.win32.publicKeys[0x051] = GLFW_KEY_KP_3; - _glfw.win32.publicKeys[0x04B] = GLFW_KEY_KP_4; - _glfw.win32.publicKeys[0x04C] = GLFW_KEY_KP_5; - _glfw.win32.publicKeys[0x04D] = GLFW_KEY_KP_6; - _glfw.win32.publicKeys[0x047] = GLFW_KEY_KP_7; - _glfw.win32.publicKeys[0x048] = GLFW_KEY_KP_8; - _glfw.win32.publicKeys[0x049] = GLFW_KEY_KP_9; - _glfw.win32.publicKeys[0x04E] = GLFW_KEY_KP_ADD; - _glfw.win32.publicKeys[0x053] = GLFW_KEY_KP_DECIMAL; - _glfw.win32.publicKeys[0x135] = GLFW_KEY_KP_DIVIDE; - _glfw.win32.publicKeys[0x11C] = GLFW_KEY_KP_ENTER; - _glfw.win32.publicKeys[0x037] = GLFW_KEY_KP_MULTIPLY; - _glfw.win32.publicKeys[0x04A] = GLFW_KEY_KP_SUBTRACT; -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW internal API ////// -////////////////////////////////////////////////////////////////////////// - -// Returns whether desktop compositing is enabled -// -BOOL _glfwIsCompositionEnabled(void) -{ - BOOL enabled; - - if (!_glfw_DwmIsCompositionEnabled) - return FALSE; - - if (_glfw_DwmIsCompositionEnabled(&enabled) != S_OK) - return FALSE; - - return enabled; -} - -// Returns a wide string version of the specified UTF-8 string -// -WCHAR* _glfwCreateWideStringFromUTF8(const char* source) -{ - WCHAR* target; - int length; - - length = MultiByteToWideChar(CP_UTF8, 0, source, -1, NULL, 0); - if (!length) - return NULL; - - target = calloc(length, sizeof(WCHAR)); - - if (!MultiByteToWideChar(CP_UTF8, 0, source, -1, target, length)) - { - free(target); - return NULL; - } - - return target; -} - -// Returns a UTF-8 string version of the specified wide string -// -char* _glfwCreateUTF8FromWideString(const WCHAR* source) -{ - char* target; - int length; - - length = WideCharToMultiByte(CP_UTF8, 0, source, -1, NULL, 0, NULL, NULL); - if (!length) - return NULL; - - target = calloc(length, sizeof(char)); - - if (!WideCharToMultiByte(CP_UTF8, 0, source, -1, target, length, NULL, NULL)) - { - free(target); - return NULL; - } - - return target; -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW platform API ////// -////////////////////////////////////////////////////////////////////////// - -int _glfwPlatformInit(void) -{ - // To make SetForegroundWindow work as we want, we need to fiddle - // with the FOREGROUNDLOCKTIMEOUT system setting (we do this as early - // as possible in the hope of still being the foreground process) - SystemParametersInfoW(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, - &_glfw.win32.foregroundLockTimeout, 0); - SystemParametersInfoW(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, UIntToPtr(0), - SPIF_SENDCHANGE); - - if (!initLibraries()) - return GL_FALSE; - - createKeyTables(); - - if (_glfw_SetProcessDPIAware) - _glfw_SetProcessDPIAware(); - -#ifdef __BORLANDC__ - // With the Borland C++ compiler, we want to disable FPU exceptions - // (this is recommended for OpenGL applications under Windows) - _control87(MCW_EM, MCW_EM); -#endif - - if (!_glfwRegisterWindowClass()) - return GL_FALSE; - - if (!_glfwInitContextAPI()) - return GL_FALSE; - - _glfwInitTimer(); - _glfwInitJoysticks(); - - return GL_TRUE; -} - -void _glfwPlatformTerminate(void) -{ - _glfwUnregisterWindowClass(); - - // Restore previous foreground lock timeout system setting - SystemParametersInfoW(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, - UIntToPtr(_glfw.win32.foregroundLockTimeout), - SPIF_SENDCHANGE); - - free(_glfw.win32.clipboardString); - - _glfwTerminateJoysticks(); - _glfwTerminateContextAPI(); - terminateLibraries(); -} - -const char* _glfwPlatformGetVersionString(void) -{ - const char* version = _GLFW_VERSION_NUMBER " Win32" -#if defined(_GLFW_WGL) - " WGL" -#elif defined(_GLFW_EGL) - " EGL" -#endif -#if defined(__MINGW32__) - " MinGW" -#elif defined(_MSC_VER) - " VisualC" -#elif defined(__BORLANDC__) - " BorlandC" -#endif -#if defined(_GLFW_BUILD_DLL) - " DLL" -#endif - ; - - return version; -} - diff --git a/examples/common/glfw/src/win32_monitor.c b/examples/common/glfw/src/win32_monitor.c deleted file mode 100644 index 0690dc1f..00000000 --- a/examples/common/glfw/src/win32_monitor.c +++ /dev/null @@ -1,348 +0,0 @@ -//======================================================================== -// GLFW 3.1 Win32 - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2002-2006 Marcus Geelnard -// Copyright (c) 2006-2010 Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#include "internal.h" - -#include -#include -#include -#include - -// These constants are missing on MinGW -#ifndef EDS_ROTATEDMODE - #define EDS_ROTATEDMODE 0x00000004 -#endif -#ifndef DISPLAY_DEVICE_ACTIVE - #define DISPLAY_DEVICE_ACTIVE 0x00000001 -#endif - - -////////////////////////////////////////////////////////////////////////// -////// GLFW internal API ////// -////////////////////////////////////////////////////////////////////////// - -// Change the current video mode -// -GLboolean _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired) -{ - GLFWvidmode current; - const GLFWvidmode* best; - DEVMODEW dm; - - best = _glfwChooseVideoMode(monitor, desired); - _glfwPlatformGetVideoMode(monitor, ¤t); - if (_glfwCompareVideoModes(¤t, best) == 0) - return GL_TRUE; - - ZeroMemory(&dm, sizeof(dm)); - dm.dmSize = sizeof(DEVMODEW); - dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | - DM_DISPLAYFREQUENCY; - dm.dmPelsWidth = best->width; - dm.dmPelsHeight = best->height; - dm.dmBitsPerPel = best->redBits + best->greenBits + best->blueBits; - dm.dmDisplayFrequency = best->refreshRate; - - if (dm.dmBitsPerPel < 15 || dm.dmBitsPerPel >= 24) - dm.dmBitsPerPel = 32; - - if (ChangeDisplaySettingsExW(monitor->win32.adapterName, - &dm, - NULL, - CDS_FULLSCREEN, - NULL) != DISP_CHANGE_SUCCESSFUL) - { - _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to set video mode"); - return GL_FALSE; - } - - monitor->win32.modeChanged = GL_TRUE; - return GL_TRUE; -} - -// Restore the previously saved (original) video mode -// -void _glfwRestoreVideoMode(_GLFWmonitor* monitor) -{ - if (monitor->win32.modeChanged) - { - ChangeDisplaySettingsExW(monitor->win32.adapterName, - NULL, NULL, CDS_FULLSCREEN, NULL); - monitor->win32.modeChanged = GL_FALSE; - } -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW platform API ////// -////////////////////////////////////////////////////////////////////////// - -_GLFWmonitor** _glfwPlatformGetMonitors(int* count) -{ - int size = 0, found = 0; - _GLFWmonitor** monitors = NULL; - DWORD adapterIndex, displayIndex; - - *count = 0; - - for (adapterIndex = 0; ; adapterIndex++) - { - DISPLAY_DEVICEW adapter; - - ZeroMemory(&adapter, sizeof(DISPLAY_DEVICEW)); - adapter.cb = sizeof(DISPLAY_DEVICEW); - - if (!EnumDisplayDevicesW(NULL, adapterIndex, &adapter, 0)) - break; - - if (!(adapter.StateFlags & DISPLAY_DEVICE_ACTIVE)) - continue; - - for (displayIndex = 0; ; displayIndex++) - { - DISPLAY_DEVICEW display; - char* name; - HDC dc; - - ZeroMemory(&display, sizeof(DISPLAY_DEVICEW)); - display.cb = sizeof(DISPLAY_DEVICEW); - - if (!EnumDisplayDevicesW(adapter.DeviceName, displayIndex, &display, 0)) - break; - - if (found == size) - { - size += 4; - monitors = realloc(monitors, sizeof(_GLFWmonitor*) * size); - } - - name = _glfwCreateUTF8FromWideString(display.DeviceString); - if (!name) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Failed to convert string to UTF-8"); - continue; - } - - dc = CreateDCW(L"DISPLAY", adapter.DeviceName, NULL, NULL); - - monitors[found] = _glfwAllocMonitor(name, - GetDeviceCaps(dc, HORZSIZE), - GetDeviceCaps(dc, VERTSIZE)); - - DeleteDC(dc); - free(name); - - wcscpy(monitors[found]->win32.adapterName, adapter.DeviceName); - wcscpy(monitors[found]->win32.displayName, display.DeviceName); - - WideCharToMultiByte(CP_UTF8, 0, - adapter.DeviceName, -1, - monitors[found]->win32.publicAdapterName, - sizeof(monitors[found]->win32.publicAdapterName), - NULL, NULL); - - WideCharToMultiByte(CP_UTF8, 0, - display.DeviceName, -1, - monitors[found]->win32.publicDisplayName, - sizeof(monitors[found]->win32.publicDisplayName), - NULL, NULL); - - if (adapter.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE && - displayIndex == 0) - { - _GLFW_SWAP_POINTERS(monitors[0], monitors[found]); - } - - found++; - } - } - - *count = found; - return monitors; -} - -GLboolean _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second) -{ - return wcscmp(first->win32.displayName, second->win32.displayName) == 0; -} - -void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos) -{ - DEVMODEW settings; - ZeroMemory(&settings, sizeof(DEVMODEW)); - settings.dmSize = sizeof(DEVMODEW); - - EnumDisplaySettingsExW(monitor->win32.adapterName, - ENUM_CURRENT_SETTINGS, - &settings, - EDS_ROTATEDMODE); - - if (xpos) - *xpos = settings.dmPosition.x; - if (ypos) - *ypos = settings.dmPosition.y; -} - -GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found) -{ - int modeIndex = 0, count = 0; - GLFWvidmode* result = NULL; - - *found = 0; - - for (;;) - { - int i; - GLFWvidmode mode; - DEVMODEW dm; - - ZeroMemory(&dm, sizeof(DEVMODEW)); - dm.dmSize = sizeof(DEVMODEW); - - if (!EnumDisplaySettingsW(monitor->win32.adapterName, modeIndex, &dm)) - break; - - modeIndex++; - - if (dm.dmBitsPerPel < 15) - { - // Skip modes with less than 15 BPP - continue; - } - - mode.width = dm.dmPelsWidth; - mode.height = dm.dmPelsHeight; - mode.refreshRate = dm.dmDisplayFrequency; - _glfwSplitBPP(dm.dmBitsPerPel, - &mode.redBits, - &mode.greenBits, - &mode.blueBits); - - for (i = 0; i < *found; i++) - { - if (_glfwCompareVideoModes(result + i, &mode) == 0) - break; - } - - if (i < *found) - { - // This is a duplicate, so skip it - continue; - } - - if (*found == count) - { - if (count) - count *= 2; - else - count = 128; - - result = (GLFWvidmode*) realloc(result, count * sizeof(GLFWvidmode)); - } - - result[*found] = mode; - (*found)++; - } - - return result; -} - -void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) -{ - DEVMODEW dm; - - ZeroMemory(&dm, sizeof(DEVMODEW)); - dm.dmSize = sizeof(DEVMODEW); - - EnumDisplaySettingsW(monitor->win32.adapterName, ENUM_CURRENT_SETTINGS, &dm); - - mode->width = dm.dmPelsWidth; - mode->height = dm.dmPelsHeight; - mode->refreshRate = dm.dmDisplayFrequency; - _glfwSplitBPP(dm.dmBitsPerPel, - &mode->redBits, - &mode->greenBits, - &mode->blueBits); -} - -void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) -{ - HDC dc; - WORD values[768]; - - dc = CreateDCW(L"DISPLAY", monitor->win32.adapterName, NULL, NULL); - GetDeviceGammaRamp(dc, values); - DeleteDC(dc); - - _glfwAllocGammaArrays(ramp, 256); - - memcpy(ramp->red, values + 0, 256 * sizeof(unsigned short)); - memcpy(ramp->green, values + 256, 256 * sizeof(unsigned short)); - memcpy(ramp->blue, values + 512, 256 * sizeof(unsigned short)); -} - -void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) -{ - HDC dc; - WORD values[768]; - - if (ramp->size != 256) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Win32: Gamma ramp size must be 256"); - return; - } - - memcpy(values + 0, ramp->red, 256 * sizeof(unsigned short)); - memcpy(values + 256, ramp->green, 256 * sizeof(unsigned short)); - memcpy(values + 512, ramp->blue, 256 * sizeof(unsigned short)); - - dc = CreateDCW(L"DISPLAY", monitor->win32.adapterName, NULL, NULL); - SetDeviceGammaRamp(dc, values); - DeleteDC(dc); -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW native API ////// -////////////////////////////////////////////////////////////////////////// - -GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* handle) -{ - _GLFWmonitor* monitor = (_GLFWmonitor*) handle; - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - return monitor->win32.publicAdapterName; -} - -GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* handle) -{ - _GLFWmonitor* monitor = (_GLFWmonitor*) handle; - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - return monitor->win32.publicDisplayName; -} - diff --git a/examples/common/glfw/src/win32_platform.h b/examples/common/glfw/src/win32_platform.h deleted file mode 100644 index 861d2bc3..00000000 --- a/examples/common/glfw/src/win32_platform.h +++ /dev/null @@ -1,250 +0,0 @@ -//======================================================================== -// GLFW 3.1 Win32 - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2002-2006 Marcus Geelnard -// Copyright (c) 2006-2010 Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#ifndef _win32_platform_h_ -#define _win32_platform_h_ - - -// We don't need all the fancy stuff -#ifndef NOMINMAX - #define NOMINMAX -#endif - -#ifndef VC_EXTRALEAN - #define VC_EXTRALEAN -#endif - -#ifndef WIN32_LEAN_AND_MEAN - #define WIN32_LEAN_AND_MEAN -#endif - -// This is a workaround for the fact that glfw3.h needs to export APIENTRY (for -// example to allow applications to correctly declare a GL_ARB_debug_output -// callback) but windows.h assumes no one will define APIENTRY before it does -#undef APIENTRY - -// GLFW on Windows is Unicode only and does not work in MBCS mode -#ifndef UNICODE - #define UNICODE -#endif - -// GLFW requires Windows XP or later -#if WINVER < 0x0501 - #undef WINVER - #define WINVER 0x0501 -#endif -#if _WIN32_WINNT < 0x0501 - #undef _WIN32_WINNT - #define _WIN32_WINNT 0x0501 -#endif - -#include -#include -#include - -#if defined(_MSC_VER) - #include - #define strdup _strdup -#endif - - -// HACK: Define macros that some older windows.h variants don't - -#ifndef WM_MOUSEHWHEEL - #define WM_MOUSEHWHEEL 0x020E -#endif -#ifndef WM_DWMCOMPOSITIONCHANGED - #define WM_DWMCOMPOSITIONCHANGED 0x031E -#endif -#ifndef WM_COPYGLOBALDATA - #define WM_COPYGLOBALDATA 0x0049 -#endif -#ifndef WM_UNICHAR - #define WM_UNICHAR 0x0109 -#endif -#ifndef UNICODE_NOCHAR - #define UNICODE_NOCHAR 0xFFFF -#endif - -#if WINVER < 0x0601 -typedef struct tagCHANGEFILTERSTRUCT -{ - DWORD cbSize; - DWORD ExtStatus; - -} CHANGEFILTERSTRUCT, *PCHANGEFILTERSTRUCT; -#ifndef MSGFLT_ALLOW - #define MSGFLT_ALLOW 1 -#endif -#endif /*Windows 7*/ - - -// winmm.dll function pointer typedefs -typedef MMRESULT (WINAPI * JOYGETDEVCAPS_T)(UINT,LPJOYCAPS,UINT); -typedef MMRESULT (WINAPI * JOYGETPOS_T)(UINT,LPJOYINFO); -typedef MMRESULT (WINAPI * JOYGETPOSEX_T)(UINT,LPJOYINFOEX); -typedef DWORD (WINAPI * TIMEGETTIME_T)(void); -#define _glfw_joyGetDevCaps _glfw.win32.winmm.joyGetDevCaps -#define _glfw_joyGetPos _glfw.win32.winmm.joyGetPos -#define _glfw_joyGetPosEx _glfw.win32.winmm.joyGetPosEx -#define _glfw_timeGetTime _glfw.win32.winmm.timeGetTime - -// user32.dll function pointer typedefs -typedef BOOL (WINAPI * SETPROCESSDPIAWARE_T)(void); -typedef BOOL (WINAPI * CHANGEWINDOWMESSAGEFILTEREX_T)(HWND,UINT,DWORD,PCHANGEFILTERSTRUCT); -#define _glfw_SetProcessDPIAware _glfw.win32.user32.SetProcessDPIAware -#define _glfw_ChangeWindowMessageFilterEx _glfw.win32.user32.ChangeWindowMessageFilterEx - -// dwmapi.dll function pointer typedefs -typedef HRESULT (WINAPI * DWMISCOMPOSITIONENABLED_T)(BOOL*); -#define _glfw_DwmIsCompositionEnabled _glfw.win32.dwmapi.DwmIsCompositionEnabled - - -#define _GLFW_RECREATION_NOT_NEEDED 0 -#define _GLFW_RECREATION_REQUIRED 1 -#define _GLFW_RECREATION_IMPOSSIBLE 2 - - -#include "win32_tls.h" - -#if defined(_GLFW_WGL) - #include "wgl_context.h" -#elif defined(_GLFW_EGL) - #define _GLFW_EGL_NATIVE_WINDOW window->win32.handle - #define _GLFW_EGL_NATIVE_DISPLAY EGL_DEFAULT_DISPLAY - #include "egl_context.h" -#else - #error "No supported context creation API selected" -#endif - -#include "winmm_joystick.h" - -#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowWin32 win32 -#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryWin32 win32 -#define _GLFW_PLATFORM_LIBRARY_TIME_STATE _GLFWtimeWin32 win32_time -#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorWin32 win32 -#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorWin32 win32 - - -// Win32-specific per-window data -// -typedef struct _GLFWwindowWin32 -{ - HWND handle; - DWORD dwStyle; - DWORD dwExStyle; - - GLboolean cursorInside; - GLboolean iconified; - - // The last received cursor position, regardless of source - int cursorPosX, cursorPosY; - -} _GLFWwindowWin32; - - -// Win32-specific global data -// -typedef struct _GLFWlibraryWin32 -{ - DWORD foregroundLockTimeout; - char* clipboardString; - short int publicKeys[512]; - - // winmm.dll - struct { - HINSTANCE instance; - JOYGETDEVCAPS_T joyGetDevCaps; - JOYGETPOS_T joyGetPos; - JOYGETPOSEX_T joyGetPosEx; - TIMEGETTIME_T timeGetTime; - } winmm; - - // user32.dll - struct { - HINSTANCE instance; - SETPROCESSDPIAWARE_T SetProcessDPIAware; - CHANGEWINDOWMESSAGEFILTEREX_T ChangeWindowMessageFilterEx; - } user32; - - // dwmapi.dll - struct { - HINSTANCE instance; - DWMISCOMPOSITIONENABLED_T DwmIsCompositionEnabled; - } dwmapi; - -} _GLFWlibraryWin32; - - -// Win32-specific per-monitor data -// -typedef struct _GLFWmonitorWin32 -{ - // This size matches the static size of DISPLAY_DEVICE.DeviceName - WCHAR adapterName[32]; - WCHAR displayName[32]; - char publicAdapterName[64]; - char publicDisplayName[64]; - GLboolean modeChanged; - -} _GLFWmonitorWin32; - - -// Win32-specific per-cursor data -// -typedef struct _GLFWcursorWin32 -{ - HCURSOR handle; - -} _GLFWcursorWin32; - - -// Win32-specific global timer data -// -typedef struct _GLFWtimeWin32 -{ - GLboolean hasPC; - double resolution; - unsigned __int64 base; - -} _GLFWtimeWin32; - - -GLboolean _glfwRegisterWindowClass(void); -void _glfwUnregisterWindowClass(void); - -BOOL _glfwIsCompositionEnabled(void); - -WCHAR* _glfwCreateWideStringFromUTF8(const char* source); -char* _glfwCreateUTF8FromWideString(const WCHAR* source); - -void _glfwInitTimer(void); - -GLboolean _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired); -void _glfwRestoreVideoMode(_GLFWmonitor* monitor); - -#endif // _win32_platform_h_ diff --git a/examples/common/glfw/src/win32_time.c b/examples/common/glfw/src/win32_time.c deleted file mode 100644 index 5f7adf8f..00000000 --- a/examples/common/glfw/src/win32_time.c +++ /dev/null @@ -1,86 +0,0 @@ -//======================================================================== -// GLFW 3.1 Win32 - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2002-2006 Marcus Geelnard -// Copyright (c) 2006-2010 Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#include "internal.h" - - -// Return raw time -// -static unsigned __int64 getRawTime(void) -{ - if (_glfw.win32_time.hasPC) - { - unsigned __int64 time; - QueryPerformanceCounter((LARGE_INTEGER*) &time); - return time; - } - else - return (unsigned __int64) _glfw_timeGetTime(); -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW internal API ////// -////////////////////////////////////////////////////////////////////////// - -// Initialise timer -// -void _glfwInitTimer(void) -{ - unsigned __int64 frequency; - - if (QueryPerformanceFrequency((LARGE_INTEGER*) &frequency)) - { - _glfw.win32_time.hasPC = GL_TRUE; - _glfw.win32_time.resolution = 1.0 / (double) frequency; - } - else - { - _glfw.win32_time.hasPC = GL_FALSE; - _glfw.win32_time.resolution = 0.001; // winmm resolution is 1 ms - } - - _glfw.win32_time.base = getRawTime(); -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW platform API ////// -////////////////////////////////////////////////////////////////////////// - -double _glfwPlatformGetTime(void) -{ - return (double) (getRawTime() - _glfw.win32_time.base) * - _glfw.win32_time.resolution; -} - -void _glfwPlatformSetTime(double time) -{ - _glfw.win32_time.base = getRawTime() - - (unsigned __int64) (time / _glfw.win32_time.resolution); -} - diff --git a/examples/common/glfw/src/win32_tls.c b/examples/common/glfw/src/win32_tls.c deleted file mode 100644 index 088e25df..00000000 --- a/examples/common/glfw/src/win32_tls.c +++ /dev/null @@ -1,69 +0,0 @@ -//======================================================================== -// GLFW 3.1 Win32 - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2002-2006 Marcus Geelnard -// Copyright (c) 2006-2010 Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#include "internal.h" - - -////////////////////////////////////////////////////////////////////////// -////// GLFW internal API ////// -////////////////////////////////////////////////////////////////////////// - -int _glfwInitTLS(void) -{ - _glfw.win32_tls.context = TlsAlloc(); - if (_glfw.win32_tls.context == TLS_OUT_OF_INDEXES) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Win32: Failed to allocate TLS index"); - return GL_FALSE; - } - - _glfw.win32_tls.allocated = GL_TRUE; - return GL_TRUE; -} - -void _glfwTerminateTLS(void) -{ - if (_glfw.win32_tls.allocated) - TlsFree(_glfw.win32_tls.context); -} - -void _glfwSetCurrentContext(_GLFWwindow* context) -{ - TlsSetValue(_glfw.win32_tls.context, context); -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW platform API ////// -////////////////////////////////////////////////////////////////////////// - -_GLFWwindow* _glfwPlatformGetCurrentContext(void) -{ - return TlsGetValue(_glfw.win32_tls.context); -} - diff --git a/examples/common/glfw/src/win32_tls.h b/examples/common/glfw/src/win32_tls.h deleted file mode 100644 index 3ffef725..00000000 --- a/examples/common/glfw/src/win32_tls.h +++ /dev/null @@ -1,48 +0,0 @@ -//======================================================================== -// GLFW 3.1 Win32 - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2002-2006 Marcus Geelnard -// Copyright (c) 2006-2010 Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#ifndef _win32_tls_h_ -#define _win32_tls_h_ - -#define _GLFW_PLATFORM_LIBRARY_TLS_STATE _GLFWtlsWin32 win32_tls - - -// Win32-specific global TLS data -// -typedef struct _GLFWtlsWin32 -{ - GLboolean allocated; - DWORD context; - -} _GLFWtlsWin32; - - -int _glfwInitTLS(void); -void _glfwTerminateTLS(void); -void _glfwSetCurrentContext(_GLFWwindow* context); - -#endif // _win32_tls_h_ diff --git a/examples/common/glfw/src/win32_window.c b/examples/common/glfw/src/win32_window.c deleted file mode 100644 index 176ed596..00000000 --- a/examples/common/glfw/src/win32_window.c +++ /dev/null @@ -1,1312 +0,0 @@ -//======================================================================== -// GLFW 3.1 Win32 - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2002-2006 Marcus Geelnard -// Copyright (c) 2006-2010 Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#include "internal.h" - -#include -#include -#include -#include -#include - -#define _GLFW_KEY_INVALID -2 - -#define _GLFW_WNDCLASSNAME L"GLFW30" - - -// Updates the cursor clip rect -// -static void updateClipRect(_GLFWwindow* window) -{ - RECT clipRect; - GetClientRect(window->win32.handle, &clipRect); - ClientToScreen(window->win32.handle, (POINT*) &clipRect.left); - ClientToScreen(window->win32.handle, (POINT*) &clipRect.right); - ClipCursor(&clipRect); -} - -// Hide the mouse cursor -// -static void hideCursor(_GLFWwindow* window) -{ - POINT pos; - - ClipCursor(NULL); - - if (GetCursorPos(&pos)) - { - if (WindowFromPoint(pos) == window->win32.handle) - SetCursor(NULL); - } -} - -// Disable the mouse cursor -// -static void disableCursor(_GLFWwindow* window) -{ - POINT pos; - - updateClipRect(window); - - if (GetCursorPos(&pos)) - { - if (WindowFromPoint(pos) == window->win32.handle) - SetCursor(NULL); - } -} - -// Restores the mouse cursor -// -static void restoreCursor(_GLFWwindow* window) -{ - POINT pos; - - ClipCursor(NULL); - - if (GetCursorPos(&pos)) - { - if (WindowFromPoint(pos) == window->win32.handle) - { - if (window->cursor) - SetCursor(window->cursor->win32.handle); - else - SetCursor(LoadCursorW(NULL, IDC_ARROW)); - } - } -} - -// Translates a GLFW standard cursor to a resource ID -// -static LPWSTR translateCursorShape(int shape) -{ - switch (shape) - { - case GLFW_ARROW_CURSOR: - return IDC_ARROW; - case GLFW_IBEAM_CURSOR: - return IDC_IBEAM; - case GLFW_CROSSHAIR_CURSOR: - return IDC_CROSS; - case GLFW_HAND_CURSOR: - return IDC_HAND; - case GLFW_HRESIZE_CURSOR: - return IDC_SIZEWE; - case GLFW_VRESIZE_CURSOR: - return IDC_SIZENS; - } - - return NULL; -} - -// Retrieves and translates modifier keys -// -static int getKeyMods(void) -{ - int mods = 0; - - if (GetKeyState(VK_SHIFT) & (1 << 31)) - mods |= GLFW_MOD_SHIFT; - if (GetKeyState(VK_CONTROL) & (1 << 31)) - mods |= GLFW_MOD_CONTROL; - if (GetKeyState(VK_MENU) & (1 << 31)) - mods |= GLFW_MOD_ALT; - if ((GetKeyState(VK_LWIN) | GetKeyState(VK_RWIN)) & (1 << 31)) - mods |= GLFW_MOD_SUPER; - - return mods; -} - -// Retrieves and translates modifier keys -// -static int getAsyncKeyMods(void) -{ - int mods = 0; - - if (GetAsyncKeyState(VK_SHIFT) & (1 << 31)) - mods |= GLFW_MOD_SHIFT; - if (GetAsyncKeyState(VK_CONTROL) & (1 << 31)) - mods |= GLFW_MOD_CONTROL; - if (GetAsyncKeyState(VK_MENU) & (1 << 31)) - mods |= GLFW_MOD_ALT; - if ((GetAsyncKeyState(VK_LWIN) | GetAsyncKeyState(VK_RWIN)) & (1 << 31)) - mods |= GLFW_MOD_SUPER; - - return mods; -} - -// Translates a Windows key to the corresponding GLFW key -// -static int translateKey(WPARAM wParam, LPARAM lParam) -{ - if (wParam == VK_CONTROL) - { - // The CTRL keys require special handling - - MSG next; - DWORD time; - - // Is this an extended key (i.e. right key)? - if (lParam & 0x01000000) - return GLFW_KEY_RIGHT_CONTROL; - - // Here is a trick: "Alt Gr" sends LCTRL, then RALT. We only - // want the RALT message, so we try to see if the next message - // is a RALT message. In that case, this is a false LCTRL! - time = GetMessageTime(); - - if (PeekMessageW(&next, NULL, 0, 0, PM_NOREMOVE)) - { - if (next.message == WM_KEYDOWN || - next.message == WM_SYSKEYDOWN || - next.message == WM_KEYUP || - next.message == WM_SYSKEYUP) - { - if (next.wParam == VK_MENU && - (next.lParam & 0x01000000) && - next.time == time) - { - // Next message is a RALT down message, which - // means that this is not a proper LCTRL message - return _GLFW_KEY_INVALID; - } - } - } - - return GLFW_KEY_LEFT_CONTROL; - } - - return _glfw.win32.publicKeys[HIWORD(lParam) & 0x1FF]; -} - -// Enter full screen mode -// -static GLboolean enterFullscreenMode(_GLFWwindow* window) -{ - GLFWvidmode mode; - GLboolean status; - int xpos, ypos; - - status = _glfwSetVideoMode(window->monitor, &window->videoMode); - - _glfwPlatformGetVideoMode(window->monitor, &mode); - _glfwPlatformGetMonitorPos(window->monitor, &xpos, &ypos); - - SetWindowPos(window->win32.handle, HWND_TOPMOST, - xpos, ypos, mode.width, mode.height, SWP_NOCOPYBITS); - - return status; -} - -// Leave full screen mode -// -static void leaveFullscreenMode(_GLFWwindow* window) -{ - _glfwRestoreVideoMode(window->monitor); -} - -// Window callback function (handles window events) -// -static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, - WPARAM wParam, LPARAM lParam) -{ - _GLFWwindow* window = (_GLFWwindow*) GetWindowLongPtrW(hWnd, 0); - - switch (uMsg) - { - case WM_NCCREATE: - { - CREATESTRUCTW* cs = (CREATESTRUCTW*) lParam; - SetWindowLongPtrW(hWnd, 0, (LONG_PTR) cs->lpCreateParams); - break; - } - - case WM_SETFOCUS: - { - if (window->cursorMode != GLFW_CURSOR_NORMAL) - _glfwPlatformApplyCursorMode(window); - - if (window->monitor && window->autoIconify) - enterFullscreenMode(window); - - _glfwInputWindowFocus(window, GL_TRUE); - return 0; - } - - case WM_KILLFOCUS: - { - if (window->cursorMode != GLFW_CURSOR_NORMAL) - restoreCursor(window); - - if (window->monitor && window->autoIconify) - { - _glfwPlatformIconifyWindow(window); - leaveFullscreenMode(window); - } - - _glfwInputWindowFocus(window, GL_FALSE); - return 0; - } - - case WM_SYSCOMMAND: - { - switch (wParam & 0xfff0) - { - case SC_SCREENSAVE: - case SC_MONITORPOWER: - { - if (window->monitor) - { - // We are running in full screen mode, so disallow - // screen saver and screen blanking - return 0; - } - else - break; - } - - // User trying to access application menu using ALT? - case SC_KEYMENU: - return 0; - } - break; - } - - case WM_CLOSE: - { - _glfwInputWindowCloseRequest(window); - return 0; - } - - case WM_KEYDOWN: - case WM_SYSKEYDOWN: - { - const int scancode = (lParam >> 16) & 0x1ff; - const int key = translateKey(wParam, lParam); - if (key == _GLFW_KEY_INVALID) - break; - - _glfwInputKey(window, key, scancode, GLFW_PRESS, getKeyMods()); - break; - } - - case WM_CHAR: - { - _glfwInputChar(window, (unsigned int) wParam, getKeyMods(), GL_TRUE); - return 0; - } - - case WM_SYSCHAR: - { - _glfwInputChar(window, (unsigned int) wParam, getKeyMods(), GL_FALSE); - return 0; - } - - case WM_UNICHAR: - { - // This message is not sent by Windows, but is sent by some - // third-party input method engines - - if (wParam == UNICODE_NOCHAR) - { - // Returning TRUE here announces support for this message - return TRUE; - } - - _glfwInputChar(window, (unsigned int) wParam, getKeyMods(), GL_TRUE); - return FALSE; - } - - case WM_KEYUP: - case WM_SYSKEYUP: - { - const int mods = getKeyMods(); - const int scancode = (lParam >> 16) & 0x1ff; - const int key = translateKey(wParam, lParam); - if (key == _GLFW_KEY_INVALID) - break; - - if (wParam == VK_SHIFT) - { - // Release both Shift keys on Shift up event, as only one event - // is sent even if both keys are released - _glfwInputKey(window, GLFW_KEY_LEFT_SHIFT, scancode, GLFW_RELEASE, mods); - _glfwInputKey(window, GLFW_KEY_RIGHT_SHIFT, scancode, GLFW_RELEASE, mods); - } - else if (wParam == VK_SNAPSHOT) - { - // Key down is not reported for the print screen key - _glfwInputKey(window, key, scancode, GLFW_PRESS, mods); - _glfwInputKey(window, key, scancode, GLFW_RELEASE, mods); - } - else - _glfwInputKey(window, key, scancode, GLFW_RELEASE, mods); - - break; - } - - case WM_LBUTTONDOWN: - case WM_RBUTTONDOWN: - case WM_MBUTTONDOWN: - case WM_XBUTTONDOWN: - { - const int mods = getKeyMods(); - - SetCapture(hWnd); - - if (uMsg == WM_LBUTTONDOWN) - _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS, mods); - else if (uMsg == WM_RBUTTONDOWN) - _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS, mods); - else if (uMsg == WM_MBUTTONDOWN) - _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_MIDDLE, GLFW_PRESS, mods); - else - { - if (HIWORD(wParam) == XBUTTON1) - _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_4, GLFW_PRESS, mods); - else if (HIWORD(wParam) == XBUTTON2) - _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_5, GLFW_PRESS, mods); - - return TRUE; - } - - return 0; - } - - case WM_LBUTTONUP: - case WM_RBUTTONUP: - case WM_MBUTTONUP: - case WM_XBUTTONUP: - { - const int mods = getKeyMods(); - - ReleaseCapture(); - - if (uMsg == WM_LBUTTONUP) - _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_RELEASE, mods); - else if (uMsg == WM_RBUTTONUP) - _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_RIGHT, GLFW_RELEASE, mods); - else if (uMsg == WM_MBUTTONUP) - _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_MIDDLE, GLFW_RELEASE, mods); - else - { - if (HIWORD(wParam) == XBUTTON1) - _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_4, GLFW_RELEASE, mods); - else if (HIWORD(wParam) == XBUTTON2) - _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_5, GLFW_RELEASE, mods); - - return TRUE; - } - - return 0; - } - - case WM_MOUSEMOVE: - { - const int x = GET_X_LPARAM(lParam); - const int y = GET_Y_LPARAM(lParam); - - if (window->cursorMode == GLFW_CURSOR_DISABLED) - { - if (_glfw.focusedWindow != window) - break; - - _glfwInputCursorMotion(window, - x - window->win32.cursorPosX, - y - window->win32.cursorPosY); - } - else - _glfwInputCursorMotion(window, x, y); - - window->win32.cursorPosX = x; - window->win32.cursorPosY = y; - - if (!window->win32.cursorInside) - { - TRACKMOUSEEVENT tme; - ZeroMemory(&tme, sizeof(tme)); - tme.cbSize = sizeof(tme); - tme.dwFlags = TME_LEAVE; - tme.hwndTrack = window->win32.handle; - TrackMouseEvent(&tme); - - window->win32.cursorInside = GL_TRUE; - _glfwInputCursorEnter(window, GL_TRUE); - } - - return 0; - } - - case WM_MOUSELEAVE: - { - window->win32.cursorInside = GL_FALSE; - _glfwInputCursorEnter(window, GL_FALSE); - return 0; - } - - case WM_MOUSEWHEEL: - { - _glfwInputScroll(window, 0.0, (SHORT) HIWORD(wParam) / (double) WHEEL_DELTA); - return 0; - } - - case WM_MOUSEHWHEEL: - { - // This message is only sent on Windows Vista and later - // NOTE: The X-axis is inverted for consistency with OS X and X11. - _glfwInputScroll(window, -((SHORT) HIWORD(wParam) / (double) WHEEL_DELTA), 0.0); - return 0; - } - - case WM_SIZE: - { - if (_glfw.focusedWindow == window) - { - if (window->cursorMode == GLFW_CURSOR_DISABLED) - updateClipRect(window); - } - - if (!window->win32.iconified && wParam == SIZE_MINIMIZED) - { - window->win32.iconified = GL_TRUE; - _glfwInputWindowIconify(window, GL_TRUE); - } - else if (window->win32.iconified && - (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED)) - { - window->win32.iconified = GL_FALSE; - _glfwInputWindowIconify(window, GL_FALSE); - } - - _glfwInputFramebufferSize(window, LOWORD(lParam), HIWORD(lParam)); - _glfwInputWindowSize(window, LOWORD(lParam), HIWORD(lParam)); - return 0; - } - - case WM_MOVE: - { - if (_glfw.focusedWindow == window) - { - if (window->cursorMode == GLFW_CURSOR_DISABLED) - updateClipRect(window); - } - - // NOTE: This cannot use LOWORD/HIWORD recommended by MSDN, as - // those macros do not handle negative window positions correctly - _glfwInputWindowPos(window, - GET_X_LPARAM(lParam), - GET_Y_LPARAM(lParam)); - return 0; - } - - case WM_PAINT: - { - _glfwInputWindowDamage(window); - break; - } - - case WM_ERASEBKGND: - { - return TRUE; - } - - case WM_SETCURSOR: - { - if (_glfw.focusedWindow == window && LOWORD(lParam) == HTCLIENT) - { - if (window->cursorMode == GLFW_CURSOR_HIDDEN || - window->cursorMode == GLFW_CURSOR_DISABLED) - { - SetCursor(NULL); - return TRUE; - } - else if (window->cursor) - { - SetCursor(window->cursor->win32.handle); - return TRUE; - } - } - - break; - } - - case WM_DEVICECHANGE: - { - if (DBT_DEVNODES_CHANGED == wParam) - { - _glfwInputMonitorChange(); - return TRUE; - } - break; - } - - case WM_DWMCOMPOSITIONCHANGED: - { - if (_glfwIsCompositionEnabled()) - { - _GLFWwindow* previous = _glfwPlatformGetCurrentContext(); - _glfwPlatformMakeContextCurrent(window); - _glfwPlatformSwapInterval(0); - _glfwPlatformMakeContextCurrent(previous); - } - - // TODO: Restore vsync if compositing was disabled - break; - } - - case WM_DROPFILES: - { - HDROP hDrop = (HDROP) wParam; - POINT pt; - int i; - - const int count = DragQueryFileW(hDrop, 0xffffffff, NULL, 0); - char** names = calloc(count, sizeof(char*)); - - // Move the mouse to the position of the drop - DragQueryPoint(hDrop, &pt); - _glfwInputCursorMotion(window, pt.x, pt.y); - - for (i = 0; i < count; i++) - { - const UINT length = DragQueryFileW(hDrop, i, NULL, 0); - WCHAR* buffer = calloc(length + 1, sizeof(WCHAR)); - - DragQueryFileW(hDrop, i, buffer, length + 1); - names[i] = _glfwCreateUTF8FromWideString(buffer); - - free(buffer); - } - - _glfwInputDrop(window, count, (const char**) names); - - for (i = 0; i < count; i++) - free(names[i]); - free(names); - - DragFinish(hDrop); - return 0; - } - } - - return DefWindowProc(hWnd, uMsg, wParam, lParam); -} - -// Translate client window size to full window size (including window borders) -// -static void getFullWindowSize(_GLFWwindow* window, - int clientWidth, int clientHeight, - int* fullWidth, int* fullHeight) -{ - RECT rect = { 0, 0, clientWidth, clientHeight }; - AdjustWindowRectEx(&rect, window->win32.dwStyle, - FALSE, window->win32.dwExStyle); - *fullWidth = rect.right - rect.left; - *fullHeight = rect.bottom - rect.top; -} - -// Creates the GLFW window and rendering context -// -static int createWindow(_GLFWwindow* window, - const _GLFWwndconfig* wndconfig, - const _GLFWctxconfig* ctxconfig, - const _GLFWfbconfig* fbconfig) -{ - int xpos, ypos, fullWidth, fullHeight; - WCHAR* wideTitle; - - window->win32.dwStyle = WS_CLIPSIBLINGS | WS_CLIPCHILDREN; - window->win32.dwExStyle = WS_EX_APPWINDOW; - - if (window->monitor) - { - window->win32.dwStyle |= WS_POPUP; - - // NOTE: This window placement is temporary and approximate, as the - // correct position and size cannot be known until the monitor - // video mode has been set - _glfwPlatformGetMonitorPos(wndconfig->monitor, &xpos, &ypos); - fullWidth = wndconfig->width; - fullHeight = wndconfig->height; - } - else - { - if (wndconfig->decorated) - { - window->win32.dwStyle |= WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX; - - if (wndconfig->resizable) - { - window->win32.dwStyle |= WS_MAXIMIZEBOX | WS_SIZEBOX; - window->win32.dwExStyle |= WS_EX_WINDOWEDGE; - } - } - else - window->win32.dwStyle |= WS_POPUP; - - xpos = CW_USEDEFAULT; - ypos = CW_USEDEFAULT; - - getFullWindowSize(window, - wndconfig->width, wndconfig->height, - &fullWidth, &fullHeight); - } - - wideTitle = _glfwCreateWideStringFromUTF8(wndconfig->title); - if (!wideTitle) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Win32: Failed to convert title to wide string"); - return GL_FALSE; - } - - window->win32.handle = CreateWindowExW(window->win32.dwExStyle, - _GLFW_WNDCLASSNAME, - wideTitle, - window->win32.dwStyle, - xpos, ypos, - fullWidth, fullHeight, - NULL, // No parent window - NULL, // No window menu - GetModuleHandleW(NULL), - window); // Pass object to WM_CREATE - - free(wideTitle); - - if (!window->win32.handle) - { - _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to create window"); - return GL_FALSE; - } - - if (_glfw_ChangeWindowMessageFilterEx) - { - _glfw_ChangeWindowMessageFilterEx(window->win32.handle, - WM_DROPFILES, MSGFLT_ALLOW, NULL); - _glfw_ChangeWindowMessageFilterEx(window->win32.handle, - WM_COPYDATA, MSGFLT_ALLOW, NULL); - _glfw_ChangeWindowMessageFilterEx(window->win32.handle, - WM_COPYGLOBALDATA, MSGFLT_ALLOW, NULL); - } - - if (wndconfig->floating && !wndconfig->monitor) - { - SetWindowPos(window->win32.handle, - HWND_TOPMOST, - 0, 0, 0, 0, - SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); - } - - DragAcceptFiles(window->win32.handle, TRUE); - - if (!_glfwCreateContext(window, ctxconfig, fbconfig)) - return GL_FALSE; - - return GL_TRUE; -} - -// Destroys the GLFW window and rendering context -// -static void destroyWindow(_GLFWwindow* window) -{ - _glfwDestroyContext(window); - - if (window->win32.handle) - { - DestroyWindow(window->win32.handle); - window->win32.handle = NULL; - } -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW internal API ////// -////////////////////////////////////////////////////////////////////////// - -// Registers the GLFW window class -// -GLboolean _glfwRegisterWindowClass(void) -{ - WNDCLASSW wc; - - wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; - wc.lpfnWndProc = (WNDPROC) windowProc; - wc.cbClsExtra = 0; // No extra class data - wc.cbWndExtra = sizeof(void*) + sizeof(int); // Make room for one pointer - wc.hInstance = GetModuleHandleW(NULL); - wc.hCursor = LoadCursorW(NULL, IDC_ARROW); - wc.hbrBackground = NULL; // No background - wc.lpszMenuName = NULL; // No menu - wc.lpszClassName = _GLFW_WNDCLASSNAME; - - // Load user-provided icon if available - wc.hIcon = LoadIconW(GetModuleHandleW(NULL), L"GLFW_ICON"); - if (!wc.hIcon) - { - // No user-provided icon found, load default icon - wc.hIcon = LoadIconW(NULL, IDI_WINLOGO); - } - - if (!RegisterClassW(&wc)) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Win32: Failed to register window class"); - return GL_FALSE; - } - - return GL_TRUE; -} - -// Unregisters the GLFW window class -// -void _glfwUnregisterWindowClass(void) -{ - UnregisterClassW(_GLFW_WNDCLASSNAME, GetModuleHandleW(NULL)); -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW platform API ////// -////////////////////////////////////////////////////////////////////////// - -int _glfwPlatformCreateWindow(_GLFWwindow* window, - const _GLFWwndconfig* wndconfig, - const _GLFWctxconfig* ctxconfig, - const _GLFWfbconfig* fbconfig) -{ - int status; - - if (!createWindow(window, wndconfig, ctxconfig, fbconfig)) - return GL_FALSE; - - status = _glfwAnalyzeContext(window, ctxconfig, fbconfig); - - if (status == _GLFW_RECREATION_IMPOSSIBLE) - return GL_FALSE; - - if (status == _GLFW_RECREATION_REQUIRED) - { - // Some window hints require us to re-create the context using WGL - // extensions retrieved through the current context, as we cannot check - // for WGL extensions or retrieve WGL entry points before we have a - // current context (actually until we have implicitly loaded the ICD) - - // Yes, this is strange, and yes, this is the proper way on Win32 - - // As Windows only allows you to set the pixel format once for a - // window, we need to destroy the current window and create a new one - // to be able to use the new pixel format - - // Technically, it may be possible to keep the old window around if - // we're just creating an OpenGL 3.0+ context with the same pixel - // format, but it's not worth the added code complexity - - // First we clear the current context (the one we just created) - // This is usually done by glfwDestroyWindow, but as we're not doing - // full GLFW window destruction, it's duplicated here - _glfwPlatformMakeContextCurrent(NULL); - - // Next destroy the Win32 window and WGL context (without resetting or - // destroying the GLFW window object) - destroyWindow(window); - - // ...and then create them again, this time with better APIs - if (!createWindow(window, wndconfig, ctxconfig, fbconfig)) - return GL_FALSE; - } - - if (window->monitor) - { - _glfwPlatformShowWindow(window); - if (!enterFullscreenMode(window)) - return GL_FALSE; - } - - return GL_TRUE; -} - -void _glfwPlatformDestroyWindow(_GLFWwindow* window) -{ - if (window->monitor) - leaveFullscreenMode(window); - - destroyWindow(window); -} - -void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title) -{ - WCHAR* wideTitle = _glfwCreateWideStringFromUTF8(title); - if (!wideTitle) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Win32: Failed to convert title to wide string"); - return; - } - - SetWindowTextW(window->win32.handle, wideTitle); - free(wideTitle); -} - -void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos) -{ - POINT pos = { 0, 0 }; - ClientToScreen(window->win32.handle, &pos); - - if (xpos) - *xpos = pos.x; - if (ypos) - *ypos = pos.y; -} - -void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos) -{ - RECT rect = { xpos, ypos, xpos, ypos }; - AdjustWindowRectEx(&rect, window->win32.dwStyle, - FALSE, window->win32.dwExStyle); - SetWindowPos(window->win32.handle, NULL, rect.left, rect.top, 0, 0, - SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE); -} - -void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height) -{ - RECT area; - GetClientRect(window->win32.handle, &area); - - if (width) - *width = area.right; - if (height) - *height = area.bottom; -} - -void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) -{ - if (window->monitor) - enterFullscreenMode(window); - else - { - int fullWidth, fullHeight; - getFullWindowSize(window, width, height, &fullWidth, &fullHeight); - - SetWindowPos(window->win32.handle, HWND_TOP, - 0, 0, fullWidth, fullHeight, - SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOZORDER); - } -} - -void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height) -{ - _glfwPlatformGetWindowSize(window, width, height); -} - -void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, - int* left, int* top, - int* right, int* bottom) -{ - RECT rect; - int width, height; - - _glfwPlatformGetWindowSize(window, &width, &height); - SetRect(&rect, 0, 0, width, height); - AdjustWindowRectEx(&rect, window->win32.dwStyle, - FALSE, window->win32.dwExStyle); - - if (left) - *left = -rect.left; - if (top) - *top = -rect.top; - if (right) - *right = rect.right - width; - if (bottom) - *bottom = rect.bottom - height; -} - -void _glfwPlatformIconifyWindow(_GLFWwindow* window) -{ - ShowWindow(window->win32.handle, SW_MINIMIZE); -} - -void _glfwPlatformRestoreWindow(_GLFWwindow* window) -{ - ShowWindow(window->win32.handle, SW_RESTORE); -} - -void _glfwPlatformShowWindow(_GLFWwindow* window) -{ - ShowWindow(window->win32.handle, SW_SHOW); - BringWindowToTop(window->win32.handle); - SetForegroundWindow(window->win32.handle); - SetFocus(window->win32.handle); -} - -void _glfwPlatformUnhideWindow(_GLFWwindow* window) -{ - ShowWindow(window->win32.handle, SW_SHOW); -} - -void _glfwPlatformHideWindow(_GLFWwindow* window) -{ - ShowWindow(window->win32.handle, SW_HIDE); -} - -int _glfwPlatformWindowFocused(_GLFWwindow* window) -{ - return window->win32.handle == GetActiveWindow(); -} - -int _glfwPlatformWindowIconified(_GLFWwindow* window) -{ - return IsIconic(window->win32.handle); -} - -int _glfwPlatformWindowVisible(_GLFWwindow* window) -{ - return IsWindowVisible(window->win32.handle); -} - -void _glfwPlatformPollEvents(void) -{ - MSG msg; - _GLFWwindow* window; - - while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) - { - if (msg.message == WM_QUIT) - { - // Treat WM_QUIT as a close on all windows - // While GLFW does not itself post WM_QUIT, other processes may post - // it to this one, for example Task Manager - - window = _glfw.windowListHead; - while (window) - { - _glfwInputWindowCloseRequest(window); - window = window->next; - } - } - else - { - TranslateMessage(&msg); - DispatchMessageW(&msg); - } - } - - window = _glfw.focusedWindow; - if (window) - { - // LSHIFT/RSHIFT fixup (keys tend to "stick" without this fix) - // This is the only async event handling in GLFW, but it solves some - // nasty problems - { - const int mods = getAsyncKeyMods(); - - // Get current state of left and right shift keys - const int lshiftDown = (GetAsyncKeyState(VK_LSHIFT) >> 15) & 1; - const int rshiftDown = (GetAsyncKeyState(VK_RSHIFT) >> 15) & 1; - - // See if this differs from our belief of what has happened - // (we only have to check for lost key up events) - if (!lshiftDown && window->keys[GLFW_KEY_LEFT_SHIFT] == 1) - _glfwInputKey(window, GLFW_KEY_LEFT_SHIFT, 0, GLFW_RELEASE, mods); - - if (!rshiftDown && window->keys[GLFW_KEY_RIGHT_SHIFT] == 1) - _glfwInputKey(window, GLFW_KEY_RIGHT_SHIFT, 0, GLFW_RELEASE, mods); - } - - // Did the cursor move in an focused window that has disabled the cursor - if (window->cursorMode == GLFW_CURSOR_DISABLED) - { - int width, height; - _glfwPlatformGetWindowSize(window, &width, &height); - _glfwPlatformSetCursorPos(window, width / 2, height / 2); - } - } -} - -void _glfwPlatformWaitEvents(void) -{ - WaitMessage(); - - _glfwPlatformPollEvents(); -} - -void _glfwPlatformPostEmptyEvent(void) -{ - _GLFWwindow* window = _glfw.windowListHead; - PostMessage(window->win32.handle, WM_NULL, 0, 0); -} - -void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos) -{ - POINT pos; - - if (GetCursorPos(&pos)) - { - ScreenToClient(window->win32.handle, &pos); - - if (xpos) - *xpos = pos.x; - if (ypos) - *ypos = pos.y; - } -} - -void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos) -{ - POINT pos = { (int) xpos, (int) ypos }; - - // Store the new position so it can be recognized later - window->win32.cursorPosX = pos.x; - window->win32.cursorPosY = pos.y; - - ClientToScreen(window->win32.handle, &pos); - SetCursorPos(pos.x, pos.y); -} - -void _glfwPlatformApplyCursorMode(_GLFWwindow* window) -{ - switch (window->cursorMode) - { - case GLFW_CURSOR_NORMAL: - restoreCursor(window); - break; - case GLFW_CURSOR_HIDDEN: - hideCursor(window); - break; - case GLFW_CURSOR_DISABLED: - disableCursor(window); - break; - } -} - -int _glfwPlatformCreateCursor(_GLFWcursor* cursor, - const GLFWimage* image, - int xhot, int yhot) -{ - HDC dc; - HBITMAP bitmap, mask; - BITMAPV5HEADER bi; - ICONINFO ii; - DWORD* target = 0; - BYTE* source = (BYTE*) image->pixels; - int i; - - ZeroMemory(&bi, sizeof(bi)); - bi.bV5Size = sizeof(BITMAPV5HEADER); - bi.bV5Width = image->width; - bi.bV5Height = -image->height; - bi.bV5Planes = 1; - bi.bV5BitCount = 32; - bi.bV5Compression = BI_BITFIELDS; - bi.bV5RedMask = 0x00ff0000; - bi.bV5GreenMask = 0x0000ff00; - bi.bV5BlueMask = 0x000000ff; - bi.bV5AlphaMask = 0xff000000; - - dc = GetDC(NULL); - bitmap = CreateDIBSection(dc, (BITMAPINFO*) &bi, DIB_RGB_COLORS, - (void**) &target, NULL, (DWORD) 0); - ReleaseDC(NULL, dc); - - if (!bitmap) - return GL_FALSE; - - mask = CreateBitmap(image->width, image->height, 1, 1, NULL); - if (!mask) - { - DeleteObject(bitmap); - return GL_FALSE; - } - - for (i = 0; i < image->width * image->height; i++, target++, source += 4) - { - *target = (source[3] << 24) | - (source[0] << 16) | - (source[1] << 8) | - source[2]; - } - - ZeroMemory(&ii, sizeof(ii)); - ii.fIcon = FALSE; - ii.xHotspot = xhot; - ii.yHotspot = yhot; - ii.hbmMask = mask; - ii.hbmColor = bitmap; - - cursor->win32.handle = (HCURSOR) CreateIconIndirect(&ii); - - DeleteObject(bitmap); - DeleteObject(mask); - - if (!cursor->win32.handle) - return GL_FALSE; - - return GL_TRUE; -} - -int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape) -{ - LPCWSTR native = translateCursorShape(shape); - if (!native) - { - _glfwInputError(GLFW_INVALID_ENUM, "Win32: Invalid standard cursor"); - return GL_FALSE; - } - - cursor->win32.handle = CopyCursor(LoadCursorW(NULL, native)); - if (!cursor->win32.handle) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Win32: Failed to retrieve shared cursor"); - return GL_FALSE; - } - - return GL_TRUE; -} - -void _glfwPlatformDestroyCursor(_GLFWcursor* cursor) -{ - if (cursor->win32.handle) - DestroyIcon((HICON) cursor->win32.handle); -} - -void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) -{ - // It should be guaranteed that the cursor is not being used by this window if - // the following condition is not met. That way it should be safe to destroy the - // cursor after calling glfwSetCursor(window, NULL) on all windows using the cursor. - - if (_glfw.focusedWindow == window && - window->cursorMode == GLFW_CURSOR_NORMAL && - window->win32.cursorInside) - { - if (cursor) - SetCursor(cursor->win32.handle); - else - SetCursor(LoadCursorW(NULL, IDC_ARROW)); - } -} - -void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string) -{ - WCHAR* wideString; - HANDLE stringHandle; - size_t wideSize; - - wideString = _glfwCreateWideStringFromUTF8(string); - if (!wideString) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Win32: Failed to convert clipboard string to " - "wide string"); - return; - } - - wideSize = (wcslen(wideString) + 1) * sizeof(WCHAR); - - stringHandle = GlobalAlloc(GMEM_MOVEABLE, wideSize); - if (!stringHandle) - { - free(wideString); - - _glfwInputError(GLFW_PLATFORM_ERROR, - "Win32: Failed to allocate global handle for clipboard"); - return; - } - - memcpy(GlobalLock(stringHandle), wideString, wideSize); - GlobalUnlock(stringHandle); - - if (!OpenClipboard(window->win32.handle)) - { - GlobalFree(stringHandle); - free(wideString); - - _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to open clipboard"); - return; - } - - EmptyClipboard(); - SetClipboardData(CF_UNICODETEXT, stringHandle); - CloseClipboard(); - - free(wideString); -} - -const char* _glfwPlatformGetClipboardString(_GLFWwindow* window) -{ - HANDLE stringHandle; - - if (!IsClipboardFormatAvailable(CF_UNICODETEXT)) - { - _glfwInputError(GLFW_FORMAT_UNAVAILABLE, NULL); - return NULL; - } - - if (!OpenClipboard(window->win32.handle)) - { - _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to open clipboard"); - return NULL; - } - - stringHandle = GetClipboardData(CF_UNICODETEXT); - if (!stringHandle) - { - CloseClipboard(); - - _glfwInputError(GLFW_PLATFORM_ERROR, - "Win32: Failed to retrieve clipboard data"); - return NULL; - } - - free(_glfw.win32.clipboardString); - _glfw.win32.clipboardString = - _glfwCreateUTF8FromWideString(GlobalLock(stringHandle)); - - GlobalUnlock(stringHandle); - CloseClipboard(); - - if (!_glfw.win32.clipboardString) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Win32: Failed to convert wide string to UTF-8"); - return NULL; - } - - return _glfw.win32.clipboardString; -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW native API ////// -////////////////////////////////////////////////////////////////////////// - -GLFWAPI HWND glfwGetWin32Window(GLFWwindow* handle) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - return window->win32.handle; -} - diff --git a/examples/common/glfw/src/window.c b/examples/common/glfw/src/window.c deleted file mode 100644 index 4a46a6e4..00000000 --- a/examples/common/glfw/src/window.c +++ /dev/null @@ -1,740 +0,0 @@ -//======================================================================== -// GLFW 3.1 - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2002-2006 Marcus Geelnard -// Copyright (c) 2006-2010 Camilla Berglund -// Copyright (c) 2012 Torsten Walluhn -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#include "internal.h" - -#include -#include - - -////////////////////////////////////////////////////////////////////////// -////// GLFW event API ////// -////////////////////////////////////////////////////////////////////////// - -void _glfwInputWindowFocus(_GLFWwindow* window, GLboolean focused) -{ - if (focused) - { - _glfw.focusedWindow = window; - - if (window->callbacks.focus) - window->callbacks.focus((GLFWwindow*) window, focused); - } - else - { - int i; - - _glfw.focusedWindow = NULL; - - if (window->callbacks.focus) - window->callbacks.focus((GLFWwindow*) window, focused); - - // Release all pressed keyboard keys - for (i = 0; i <= GLFW_KEY_LAST; i++) - { - if (window->keys[i] == GLFW_PRESS) - _glfwInputKey(window, i, 0, GLFW_RELEASE, 0); - } - - // Release all pressed mouse buttons - for (i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i++) - { - if (window->mouseButtons[i] == GLFW_PRESS) - _glfwInputMouseClick(window, i, GLFW_RELEASE, 0); - } - } -} - -void _glfwInputWindowPos(_GLFWwindow* window, int x, int y) -{ - if (window->callbacks.pos) - window->callbacks.pos((GLFWwindow*) window, x, y); -} - -void _glfwInputWindowSize(_GLFWwindow* window, int width, int height) -{ - if (window->callbacks.size) - window->callbacks.size((GLFWwindow*) window, width, height); -} - -void _glfwInputWindowIconify(_GLFWwindow* window, int iconified) -{ - if (window->callbacks.iconify) - window->callbacks.iconify((GLFWwindow*) window, iconified); -} - -void _glfwInputFramebufferSize(_GLFWwindow* window, int width, int height) -{ - if (window->callbacks.fbsize) - window->callbacks.fbsize((GLFWwindow*) window, width, height); -} - -void _glfwInputWindowDamage(_GLFWwindow* window) -{ - if (window->callbacks.refresh) - window->callbacks.refresh((GLFWwindow*) window); -} - -void _glfwInputWindowCloseRequest(_GLFWwindow* window) -{ - window->closed = GL_TRUE; - - if (window->callbacks.close) - window->callbacks.close((GLFWwindow*) window); -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW public API ////// -////////////////////////////////////////////////////////////////////////// - -GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, - const char* title, - GLFWmonitor* monitor, - GLFWwindow* share) -{ - _GLFWfbconfig fbconfig; - _GLFWctxconfig ctxconfig; - _GLFWwndconfig wndconfig; - _GLFWwindow* window; - _GLFWwindow* previous; - - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - - if (width <= 0 || height <= 0) - { - _glfwInputError(GLFW_INVALID_VALUE, "Invalid window size"); - return NULL; - } - - // Set up desired framebuffer config - fbconfig.redBits = _glfw.hints.redBits; - fbconfig.greenBits = _glfw.hints.greenBits; - fbconfig.blueBits = _glfw.hints.blueBits; - fbconfig.alphaBits = _glfw.hints.alphaBits; - fbconfig.depthBits = _glfw.hints.depthBits; - fbconfig.stencilBits = _glfw.hints.stencilBits; - fbconfig.accumRedBits = _glfw.hints.accumRedBits; - fbconfig.accumGreenBits = _glfw.hints.accumGreenBits; - fbconfig.accumBlueBits = _glfw.hints.accumBlueBits; - fbconfig.accumAlphaBits = _glfw.hints.accumAlphaBits; - fbconfig.auxBuffers = _glfw.hints.auxBuffers; - fbconfig.stereo = _glfw.hints.stereo ? GL_TRUE : GL_FALSE; - fbconfig.samples = _glfw.hints.samples; - fbconfig.sRGB = _glfw.hints.sRGB; - fbconfig.doublebuffer = _glfw.hints.doublebuffer ? GL_TRUE : GL_FALSE; - - // Set up desired window config - wndconfig.width = width; - wndconfig.height = height; - wndconfig.title = title; - wndconfig.resizable = _glfw.hints.resizable ? GL_TRUE : GL_FALSE; - wndconfig.visible = _glfw.hints.visible ? GL_TRUE : GL_FALSE; - wndconfig.decorated = _glfw.hints.decorated ? GL_TRUE : GL_FALSE; - wndconfig.focused = _glfw.hints.focused ? GL_TRUE : GL_FALSE; - wndconfig.autoIconify = _glfw.hints.autoIconify ? GL_TRUE : GL_FALSE; - wndconfig.floating = _glfw.hints.floating ? GL_TRUE : GL_FALSE; - wndconfig.monitor = (_GLFWmonitor*) monitor; - - // Set up desired context config - ctxconfig.api = _glfw.hints.api; - ctxconfig.major = _glfw.hints.major; - ctxconfig.minor = _glfw.hints.minor; - ctxconfig.forward = _glfw.hints.forward ? GL_TRUE : GL_FALSE; - ctxconfig.debug = _glfw.hints.debug ? GL_TRUE : GL_FALSE; - ctxconfig.profile = _glfw.hints.profile; - ctxconfig.robustness = _glfw.hints.robustness; - ctxconfig.release = _glfw.hints.release; - ctxconfig.share = (_GLFWwindow*) share; - - // Check the OpenGL bits of the window config - if (!_glfwIsValidContextConfig(&ctxconfig)) - return NULL; - - window = calloc(1, sizeof(_GLFWwindow)); - window->next = _glfw.windowListHead; - _glfw.windowListHead = window; - - if (wndconfig.monitor) - { - wndconfig.resizable = GL_TRUE; - wndconfig.visible = GL_TRUE; - wndconfig.focused = GL_TRUE; - - // Set up desired video mode - window->videoMode.width = width; - window->videoMode.height = height; - window->videoMode.redBits = _glfw.hints.redBits; - window->videoMode.greenBits = _glfw.hints.greenBits; - window->videoMode.blueBits = _glfw.hints.blueBits; - window->videoMode.refreshRate = _glfw.hints.refreshRate; - } - - // Transfer window hints that are persistent settings and not - // just initial states - window->monitor = wndconfig.monitor; - window->resizable = wndconfig.resizable; - window->decorated = wndconfig.decorated; - window->autoIconify = wndconfig.autoIconify; - window->floating = wndconfig.floating; - window->cursorMode = GLFW_CURSOR_NORMAL; - - // Save the currently current context so it can be restored later - previous = _glfwPlatformGetCurrentContext(); - - // Open the actual window and create its context - if (!_glfwPlatformCreateWindow(window, &wndconfig, &ctxconfig, &fbconfig)) - { - glfwDestroyWindow((GLFWwindow*) window); - _glfwPlatformMakeContextCurrent(previous); - return NULL; - } - - _glfwPlatformMakeContextCurrent(window); - - // Retrieve the actual (as opposed to requested) context attributes - if (!_glfwRefreshContextAttribs(&ctxconfig)) - { - glfwDestroyWindow((GLFWwindow*) window); - _glfwPlatformMakeContextCurrent(previous); - return NULL; - } - - // Verify the context against the requested parameters - if (!_glfwIsValidContext(&ctxconfig)) - { - glfwDestroyWindow((GLFWwindow*) window); - _glfwPlatformMakeContextCurrent(previous); - return NULL; - } - - // Clearing the front buffer to black to avoid garbage pixels left over - // from previous uses of our bit of VRAM - glClear(GL_COLOR_BUFFER_BIT); - _glfwPlatformSwapBuffers(window); - - // Restore the previously current context (or NULL) - _glfwPlatformMakeContextCurrent(previous); - - if (wndconfig.monitor) - { - int width, height; - _glfwPlatformGetWindowSize(window, &width, &height); - - window->cursorPosX = width / 2; - window->cursorPosY = height / 2; - - _glfwPlatformSetCursorPos(window, window->cursorPosX, window->cursorPosY); - } - else - { - if (wndconfig.visible) - { - if (wndconfig.focused) - _glfwPlatformShowWindow(window); - else - _glfwPlatformUnhideWindow(window); - } - } - - return (GLFWwindow*) window; -} - -void glfwDefaultWindowHints(void) -{ - _GLFW_REQUIRE_INIT(); - - memset(&_glfw.hints, 0, sizeof(_glfw.hints)); - - // The default is OpenGL with minimum version 1.0 - _glfw.hints.api = GLFW_OPENGL_API; - _glfw.hints.major = 1; - _glfw.hints.minor = 0; - - // The default is a focused, visible, resizable window with decorations - _glfw.hints.resizable = GL_TRUE; - _glfw.hints.visible = GL_TRUE; - _glfw.hints.decorated = GL_TRUE; - _glfw.hints.focused = GL_TRUE; - _glfw.hints.autoIconify = GL_TRUE; - - // The default is to select the highest available refresh rate - _glfw.hints.refreshRate = GLFW_DONT_CARE; - - // The default is 24 bits of color, 24 bits of depth and 8 bits of stencil, - // double buffered - _glfw.hints.redBits = 8; - _glfw.hints.greenBits = 8; - _glfw.hints.blueBits = 8; - _glfw.hints.alphaBits = 8; - _glfw.hints.depthBits = 24; - _glfw.hints.stencilBits = 8; - _glfw.hints.doublebuffer = GL_TRUE; -} - -GLFWAPI void glfwWindowHint(int target, int hint) -{ - _GLFW_REQUIRE_INIT(); - - switch (target) - { - case GLFW_RED_BITS: - _glfw.hints.redBits = hint; - break; - case GLFW_GREEN_BITS: - _glfw.hints.greenBits = hint; - break; - case GLFW_BLUE_BITS: - _glfw.hints.blueBits = hint; - break; - case GLFW_ALPHA_BITS: - _glfw.hints.alphaBits = hint; - break; - case GLFW_DEPTH_BITS: - _glfw.hints.depthBits = hint; - break; - case GLFW_STENCIL_BITS: - _glfw.hints.stencilBits = hint; - break; - case GLFW_ACCUM_RED_BITS: - _glfw.hints.accumRedBits = hint; - break; - case GLFW_ACCUM_GREEN_BITS: - _glfw.hints.accumGreenBits = hint; - break; - case GLFW_ACCUM_BLUE_BITS: - _glfw.hints.accumBlueBits = hint; - break; - case GLFW_ACCUM_ALPHA_BITS: - _glfw.hints.accumAlphaBits = hint; - break; - case GLFW_AUX_BUFFERS: - _glfw.hints.auxBuffers = hint; - break; - case GLFW_STEREO: - _glfw.hints.stereo = hint; - break; - case GLFW_REFRESH_RATE: - _glfw.hints.refreshRate = hint; - break; - case GLFW_DOUBLEBUFFER: - _glfw.hints.doublebuffer = hint; - break; - case GLFW_RESIZABLE: - _glfw.hints.resizable = hint; - break; - case GLFW_DECORATED: - _glfw.hints.decorated = hint; - break; - case GLFW_FOCUSED: - _glfw.hints.focused = hint; - break; - case GLFW_AUTO_ICONIFY: - _glfw.hints.autoIconify = hint; - break; - case GLFW_FLOATING: - _glfw.hints.floating = hint; - break; - case GLFW_VISIBLE: - _glfw.hints.visible = hint; - break; - case GLFW_SAMPLES: - _glfw.hints.samples = hint; - break; - case GLFW_SRGB_CAPABLE: - _glfw.hints.sRGB = hint; - break; - case GLFW_CLIENT_API: - _glfw.hints.api = hint; - break; - case GLFW_CONTEXT_VERSION_MAJOR: - _glfw.hints.major = hint; - break; - case GLFW_CONTEXT_VERSION_MINOR: - _glfw.hints.minor = hint; - break; - case GLFW_CONTEXT_ROBUSTNESS: - _glfw.hints.robustness = hint; - break; - case GLFW_OPENGL_FORWARD_COMPAT: - _glfw.hints.forward = hint; - break; - case GLFW_OPENGL_DEBUG_CONTEXT: - _glfw.hints.debug = hint; - break; - case GLFW_OPENGL_PROFILE: - _glfw.hints.profile = hint; - break; - case GLFW_CONTEXT_RELEASE_BEHAVIOR: - _glfw.hints.release = hint; - break; - default: - _glfwInputError(GLFW_INVALID_ENUM, NULL); - break; - } -} - -GLFWAPI void glfwDestroyWindow(GLFWwindow* handle) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - - _GLFW_REQUIRE_INIT(); - - // Allow closing of NULL (to match the behavior of free) - if (window == NULL) - return; - - // Clear all callbacks to avoid exposing a half torn-down window object - memset(&window->callbacks, 0, sizeof(window->callbacks)); - - // The window's context must not be current on another thread when the - // window is destroyed - if (window == _glfwPlatformGetCurrentContext()) - _glfwPlatformMakeContextCurrent(NULL); - - // Clear the focused window pointer if this is the focused window - if (_glfw.focusedWindow == window) - _glfw.focusedWindow = NULL; - - _glfwPlatformDestroyWindow(window); - - // Unlink window from global linked list - { - _GLFWwindow** prev = &_glfw.windowListHead; - - while (*prev != window) - prev = &((*prev)->next); - - *prev = window->next; - } - - free(window); -} - -GLFWAPI int glfwWindowShouldClose(GLFWwindow* handle) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - _GLFW_REQUIRE_INIT_OR_RETURN(0); - return window->closed; -} - -GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* handle, int value) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - _GLFW_REQUIRE_INIT(); - window->closed = value; -} - -GLFWAPI void glfwSetWindowTitle(GLFWwindow* handle, const char* title) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - _GLFW_REQUIRE_INIT(); - _glfwPlatformSetWindowTitle(window, title); -} - -GLFWAPI void glfwGetWindowPos(GLFWwindow* handle, int* xpos, int* ypos) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - - if (xpos) - *xpos = 0; - if (ypos) - *ypos = 0; - - _GLFW_REQUIRE_INIT(); - _glfwPlatformGetWindowPos(window, xpos, ypos); -} - -GLFWAPI void glfwSetWindowPos(GLFWwindow* handle, int xpos, int ypos) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - - _GLFW_REQUIRE_INIT(); - - if (window->monitor) - { - _glfwInputError(GLFW_INVALID_VALUE, - "Full screen windows cannot be positioned"); - return; - } - - _glfwPlatformSetWindowPos(window, xpos, ypos); -} - -GLFWAPI void glfwGetWindowSize(GLFWwindow* handle, int* width, int* height) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - - if (width) - *width = 0; - if (height) - *height = 0; - - _GLFW_REQUIRE_INIT(); - _glfwPlatformGetWindowSize(window, width, height); -} - -GLFWAPI void glfwSetWindowSize(GLFWwindow* handle, int width, int height) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - - _GLFW_REQUIRE_INIT(); - - if (window->monitor) - { - window->videoMode.width = width; - window->videoMode.height = height; - } - - _glfwPlatformSetWindowSize(window, width, height); -} - -GLFWAPI void glfwGetFramebufferSize(GLFWwindow* handle, int* width, int* height) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - - if (width) - *width = 0; - if (height) - *height = 0; - - _GLFW_REQUIRE_INIT(); - _glfwPlatformGetFramebufferSize(window, width, height); -} - -GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* handle, - int* left, int* top, - int* right, int* bottom) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - - if (left) - *left = 0; - if (top) - *top = 0; - if (right) - *right = 0; - if (bottom) - *bottom = 0; - - _GLFW_REQUIRE_INIT(); - _glfwPlatformGetWindowFrameSize(window, left, top, right, bottom); -} - -GLFWAPI void glfwIconifyWindow(GLFWwindow* handle) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - _GLFW_REQUIRE_INIT(); - _glfwPlatformIconifyWindow(window); -} - -GLFWAPI void glfwRestoreWindow(GLFWwindow* handle) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - _GLFW_REQUIRE_INIT(); - _glfwPlatformRestoreWindow(window); -} - -GLFWAPI void glfwShowWindow(GLFWwindow* handle) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - - _GLFW_REQUIRE_INIT(); - - if (window->monitor) - return; - - _glfwPlatformShowWindow(window); -} - -GLFWAPI void glfwHideWindow(GLFWwindow* handle) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - - _GLFW_REQUIRE_INIT(); - - if (window->monitor) - return; - - _glfwPlatformHideWindow(window); -} - -GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - - _GLFW_REQUIRE_INIT_OR_RETURN(0); - - switch (attrib) - { - case GLFW_FOCUSED: - return _glfwPlatformWindowFocused(window); - case GLFW_ICONIFIED: - return _glfwPlatformWindowIconified(window); - case GLFW_VISIBLE: - return _glfwPlatformWindowVisible(window); - case GLFW_RESIZABLE: - return window->resizable; - case GLFW_DECORATED: - return window->decorated; - case GLFW_FLOATING: - return window->floating; - case GLFW_CLIENT_API: - return window->context.api; - case GLFW_CONTEXT_VERSION_MAJOR: - return window->context.major; - case GLFW_CONTEXT_VERSION_MINOR: - return window->context.minor; - case GLFW_CONTEXT_REVISION: - return window->context.revision; - case GLFW_CONTEXT_ROBUSTNESS: - return window->context.robustness; - case GLFW_OPENGL_FORWARD_COMPAT: - return window->context.forward; - case GLFW_OPENGL_DEBUG_CONTEXT: - return window->context.debug; - case GLFW_OPENGL_PROFILE: - return window->context.profile; - case GLFW_CONTEXT_RELEASE_BEHAVIOR: - return window->context.release; - } - - _glfwInputError(GLFW_INVALID_ENUM, NULL); - return 0; -} - -GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* handle) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - return (GLFWmonitor*) window->monitor; -} - -GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* handle, void* pointer) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - _GLFW_REQUIRE_INIT(); - window->userPointer = pointer; -} - -GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* handle) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - return window->userPointer; -} - -GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* handle, - GLFWwindowposfun cbfun) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.pos, cbfun); - return cbfun; -} - -GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* handle, - GLFWwindowsizefun cbfun) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.size, cbfun); - return cbfun; -} - -GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* handle, - GLFWwindowclosefun cbfun) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.close, cbfun); - return cbfun; -} - -GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* handle, - GLFWwindowrefreshfun cbfun) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.refresh, cbfun); - return cbfun; -} - -GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* handle, - GLFWwindowfocusfun cbfun) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.focus, cbfun); - return cbfun; -} - -GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* handle, - GLFWwindowiconifyfun cbfun) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.iconify, cbfun); - return cbfun; -} - -GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* handle, - GLFWframebuffersizefun cbfun) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.fbsize, cbfun); - return cbfun; -} - -GLFWAPI void glfwPollEvents(void) -{ - _GLFW_REQUIRE_INIT(); - _glfwPlatformPollEvents(); -} - -GLFWAPI void glfwWaitEvents(void) -{ - _GLFW_REQUIRE_INIT(); - - if (!_glfw.windowListHead) - return; - - _glfwPlatformWaitEvents(); -} - -GLFWAPI void glfwPostEmptyEvent(void) -{ - _GLFW_REQUIRE_INIT(); - - if (!_glfw.windowListHead) - return; - - _glfwPlatformPostEmptyEvent(); -} - diff --git a/examples/common/glfw/src/winmm_joystick.c b/examples/common/glfw/src/winmm_joystick.c deleted file mode 100644 index fcf6d94e..00000000 --- a/examples/common/glfw/src/winmm_joystick.c +++ /dev/null @@ -1,177 +0,0 @@ -//======================================================================== -// GLFW 3.1 WinMM - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2002-2006 Marcus Geelnard -// Copyright (c) 2006-2010 Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#include "internal.h" - -#include - - -////////////////////////////////////////////////////////////////////////// -////// GLFW internal API ////// -////////////////////////////////////////////////////////////////////////// - -// Convert axis value to the [-1,1] range -// -static float normalizeAxis(DWORD pos, DWORD min, DWORD max) -{ - float fpos = (float) pos; - float fmin = (float) min; - float fmax = (float) max; - - return (2.f * (fpos - fmin) / (fmax - fmin)) - 1.f; -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW internal API ////// -////////////////////////////////////////////////////////////////////////// - -// Initialize joystick interface -// -void _glfwInitJoysticks(void) -{ -} - -// Close all opened joystick handles -// -void _glfwTerminateJoysticks(void) -{ - int i; - - for (i = 0; i < GLFW_JOYSTICK_LAST; i++) - free(_glfw.winmm_js[i].name); -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW platform API ////// -////////////////////////////////////////////////////////////////////////// - -int _glfwPlatformJoystickPresent(int joy) -{ - JOYINFO ji; - - if (_glfw_joyGetPos(joy, &ji) != JOYERR_NOERROR) - return GL_FALSE; - - return GL_TRUE; -} - -const float* _glfwPlatformGetJoystickAxes(int joy, int* count) -{ - JOYCAPS jc; - JOYINFOEX ji; - float* axes = _glfw.winmm_js[joy].axes; - - if (_glfw_joyGetDevCaps(joy, &jc, sizeof(JOYCAPS)) != JOYERR_NOERROR) - return NULL; - - ji.dwSize = sizeof(JOYINFOEX); - ji.dwFlags = JOY_RETURNX | JOY_RETURNY | JOY_RETURNZ | - JOY_RETURNR | JOY_RETURNU | JOY_RETURNV; - if (_glfw_joyGetPosEx(joy, &ji) != JOYERR_NOERROR) - return NULL; - - axes[(*count)++] = normalizeAxis(ji.dwXpos, jc.wXmin, jc.wXmax); - axes[(*count)++] = normalizeAxis(ji.dwYpos, jc.wYmin, jc.wYmax); - - if (jc.wCaps & JOYCAPS_HASZ) - axes[(*count)++] = normalizeAxis(ji.dwZpos, jc.wZmin, jc.wZmax); - - if (jc.wCaps & JOYCAPS_HASR) - axes[(*count)++] = normalizeAxis(ji.dwRpos, jc.wRmin, jc.wRmax); - - if (jc.wCaps & JOYCAPS_HASU) - axes[(*count)++] = normalizeAxis(ji.dwUpos, jc.wUmin, jc.wUmax); - - if (jc.wCaps & JOYCAPS_HASV) - axes[(*count)++] = normalizeAxis(ji.dwVpos, jc.wVmin, jc.wVmax); - - return axes; -} - -const unsigned char* _glfwPlatformGetJoystickButtons(int joy, int* count) -{ - JOYCAPS jc; - JOYINFOEX ji; - unsigned char* buttons = _glfw.winmm_js[joy].buttons; - - if (_glfw_joyGetDevCaps(joy, &jc, sizeof(JOYCAPS)) != JOYERR_NOERROR) - return NULL; - - ji.dwSize = sizeof(JOYINFOEX); - ji.dwFlags = JOY_RETURNBUTTONS | JOY_RETURNPOV; - if (_glfw_joyGetPosEx(joy, &ji) != JOYERR_NOERROR) - return NULL; - - while (*count < (int) jc.wNumButtons) - { - buttons[*count] = (unsigned char) - (ji.dwButtons & (1UL << *count) ? GLFW_PRESS : GLFW_RELEASE); - (*count)++; - } - - // Virtual buttons - Inject data from hats - // Each hat is exposed as 4 buttons which exposes 8 directions with - // concurrent button presses - // NOTE: this API exposes only one hat - - if ((jc.wCaps & JOYCAPS_HASPOV) && (jc.wCaps & JOYCAPS_POV4DIR)) - { - int i, value = ji.dwPOV / 100 / 45; - - // Bit fields of button presses for each direction, including nil - const int directions[9] = { 1, 3, 2, 6, 4, 12, 8, 9, 0 }; - - if (value < 0 || value > 8) - value = 8; - - for (i = 0; i < 4; i++) - { - if (directions[value] & (1 << i)) - buttons[(*count)++] = GLFW_PRESS; - else - buttons[(*count)++] = GLFW_RELEASE; - } - } - - return buttons; -} - -const char* _glfwPlatformGetJoystickName(int joy) -{ - JOYCAPS jc; - - if (_glfw_joyGetDevCaps(joy, &jc, sizeof(JOYCAPS)) != JOYERR_NOERROR) - return NULL; - - free(_glfw.winmm_js[joy].name); - _glfw.winmm_js[joy].name = _glfwCreateUTF8FromWideString(jc.szPname); - - return _glfw.winmm_js[joy].name; -} - diff --git a/examples/common/glfw/src/winmm_joystick.h b/examples/common/glfw/src/winmm_joystick.h deleted file mode 100644 index 608f1dc5..00000000 --- a/examples/common/glfw/src/winmm_joystick.h +++ /dev/null @@ -1,47 +0,0 @@ -//======================================================================== -// GLFW 3.1 WinMM - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2006-2014 Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#ifndef _winmm_joystick_h_ -#define _winmm_joystick_h_ - -#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE \ - _GLFWjoystickWinMM winmm_js[GLFW_JOYSTICK_LAST + 1] - - -// WinMM-specific per-joystick data -// -typedef struct _GLFWjoystickWinMM -{ - float axes[6]; - unsigned char buttons[36]; // 32 buttons plus one hat - char* name; -} _GLFWjoystickWinMM; - - -void _glfwInitJoysticks(void); -void _glfwTerminateJoysticks(void); - -#endif // _winmm_joystick_h_ diff --git a/examples/common/glfw/src/wl_init.c b/examples/common/glfw/src/wl_init.c deleted file mode 100644 index 0269ee34..00000000 --- a/examples/common/glfw/src/wl_init.c +++ /dev/null @@ -1,630 +0,0 @@ -//======================================================================== -// GLFW 3.1 Wayland - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2014 Jonas Ådahl -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#include "internal.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "xkb_unicode.h" - -static void pointerHandleEnter(void* data, - struct wl_pointer* pointer, - uint32_t serial, - struct wl_surface* surface, - wl_fixed_t sx, - wl_fixed_t sy) -{ - _GLFWwindow* window = wl_surface_get_user_data(surface); - - _glfw.wl.pointerSerial = serial; - _glfw.wl.pointerFocus = window; - - _glfwPlatformSetCursor(window, window->wl.currentCursor); - _glfwInputCursorEnter(window, GL_TRUE); -} - -static void pointerHandleLeave(void* data, - struct wl_pointer* pointer, - uint32_t serial, - struct wl_surface* surface) -{ - _GLFWwindow* window = _glfw.wl.pointerFocus; - - if (!window) - return; - - _glfw.wl.pointerSerial = serial; - _glfw.wl.pointerFocus = NULL; - _glfwInputCursorEnter(window, GL_FALSE); -} - -static void pointerHandleMotion(void* data, - struct wl_pointer* pointer, - uint32_t time, - wl_fixed_t sx, - wl_fixed_t sy) -{ - _GLFWwindow* window = _glfw.wl.pointerFocus; - - if (!window) - return; - - if (window->cursorMode == GLFW_CURSOR_DISABLED) - { - /* TODO */ - _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: GLFW_CURSOR_DISABLED not supported"); - return; - } - - _glfwInputCursorMotion(window, - wl_fixed_to_double(sx), - wl_fixed_to_double(sy)); -} - -static void pointerHandleButton(void* data, - struct wl_pointer* wl_pointer, - uint32_t serial, - uint32_t time, - uint32_t button, - uint32_t state) -{ - _GLFWwindow* window = _glfw.wl.pointerFocus; - int glfwButton; - - if (!window) - return; - - /* Makes left, right and middle 0, 1 and 2. Overall order follows evdev - * codes. */ - glfwButton = button - BTN_LEFT; - - _glfwInputMouseClick(window, - glfwButton, - state == WL_POINTER_BUTTON_STATE_PRESSED - ? GLFW_PRESS - : GLFW_RELEASE, - _glfw.wl.xkb.modifiers); -} - -static void pointerHandleAxis(void* data, - struct wl_pointer* wl_pointer, - uint32_t time, - uint32_t axis, - wl_fixed_t value) -{ - _GLFWwindow* window = _glfw.wl.pointerFocus; - double scroll_factor; - double x, y; - - if (!window) - return; - - /* Wayland scroll events are in pointer motion coordinate space (think - * two finger scroll). The factor 10 is commonly used to convert to - * "scroll step means 1.0. */ - scroll_factor = 1.0/10.0; - - switch (axis) - { - case WL_POINTER_AXIS_HORIZONTAL_SCROLL: - x = wl_fixed_to_double(value) * scroll_factor; - y = 0.0; - break; - case WL_POINTER_AXIS_VERTICAL_SCROLL: - x = 0.0; - y = wl_fixed_to_double(value) * scroll_factor; - break; - default: - break; - } - - _glfwInputScroll(window, x, y); -} - -static const struct wl_pointer_listener pointerListener = { - pointerHandleEnter, - pointerHandleLeave, - pointerHandleMotion, - pointerHandleButton, - pointerHandleAxis, -}; - -static void keyboardHandleKeymap(void* data, - struct wl_keyboard* keyboard, - uint32_t format, - int fd, - uint32_t size) -{ - struct xkb_keymap* keymap; - struct xkb_state* state; - char* mapStr; - - if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) - { - close(fd); - return; - } - - mapStr = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); - if (mapStr == MAP_FAILED) { - close(fd); - return; - } - - keymap = xkb_map_new_from_string(_glfw.wl.xkb.context, - mapStr, - XKB_KEYMAP_FORMAT_TEXT_V1, - 0); - munmap(mapStr, size); - close(fd); - - if (!keymap) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Failed to compile keymap"); - return; - } - - state = xkb_state_new(keymap); - if (!state) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Failed to create XKB state"); - xkb_map_unref(keymap); - return; - } - - xkb_keymap_unref(_glfw.wl.xkb.keymap); - xkb_state_unref(_glfw.wl.xkb.state); - _glfw.wl.xkb.keymap = keymap; - _glfw.wl.xkb.state = state; - - _glfw.wl.xkb.control_mask = - 1 << xkb_map_mod_get_index(_glfw.wl.xkb.keymap, "Control"); - _glfw.wl.xkb.alt_mask = - 1 << xkb_map_mod_get_index(_glfw.wl.xkb.keymap, "Mod1"); - _glfw.wl.xkb.shift_mask = - 1 << xkb_map_mod_get_index(_glfw.wl.xkb.keymap, "Shift"); - _glfw.wl.xkb.super_mask = - 1 << xkb_map_mod_get_index(_glfw.wl.xkb.keymap, "Mod4"); -} - -static void keyboardHandleEnter(void* data, - struct wl_keyboard* keyboard, - uint32_t serial, - struct wl_surface* surface, - struct wl_array* keys) -{ - _GLFWwindow* window = wl_surface_get_user_data(surface); - - _glfw.wl.keyboardFocus = window; - _glfwInputWindowFocus(window, GL_TRUE); -} - -static void keyboardHandleLeave(void* data, - struct wl_keyboard* keyboard, - uint32_t serial, - struct wl_surface* surface) -{ - _GLFWwindow* window = _glfw.wl.keyboardFocus; - - if (!window) - return; - - _glfw.wl.keyboardFocus = NULL; - _glfwInputWindowFocus(window, GL_FALSE); -} - -static int toGLFWKeyCode(uint32_t key) -{ - switch (key) - { - case KEY_GRAVE: return GLFW_KEY_GRAVE_ACCENT; - case KEY_1: return GLFW_KEY_1; - case KEY_2: return GLFW_KEY_2; - case KEY_3: return GLFW_KEY_3; - case KEY_4: return GLFW_KEY_4; - case KEY_5: return GLFW_KEY_5; - case KEY_6: return GLFW_KEY_6; - case KEY_7: return GLFW_KEY_7; - case KEY_8: return GLFW_KEY_8; - case KEY_9: return GLFW_KEY_9; - case KEY_0: return GLFW_KEY_0; - case KEY_MINUS: return GLFW_KEY_MINUS; - case KEY_EQUAL: return GLFW_KEY_EQUAL; - case KEY_Q: return GLFW_KEY_Q; - case KEY_W: return GLFW_KEY_W; - case KEY_E: return GLFW_KEY_E; - case KEY_R: return GLFW_KEY_R; - case KEY_T: return GLFW_KEY_T; - case KEY_Y: return GLFW_KEY_Y; - case KEY_U: return GLFW_KEY_U; - case KEY_I: return GLFW_KEY_I; - case KEY_O: return GLFW_KEY_O; - case KEY_P: return GLFW_KEY_P; - case KEY_LEFTBRACE: return GLFW_KEY_LEFT_BRACKET; - case KEY_RIGHTBRACE: return GLFW_KEY_RIGHT_BRACKET; - case KEY_A: return GLFW_KEY_A; - case KEY_S: return GLFW_KEY_S; - case KEY_D: return GLFW_KEY_D; - case KEY_F: return GLFW_KEY_F; - case KEY_G: return GLFW_KEY_G; - case KEY_H: return GLFW_KEY_H; - case KEY_J: return GLFW_KEY_J; - case KEY_K: return GLFW_KEY_K; - case KEY_L: return GLFW_KEY_L; - case KEY_SEMICOLON: return GLFW_KEY_SEMICOLON; - case KEY_APOSTROPHE: return GLFW_KEY_APOSTROPHE; - case KEY_Z: return GLFW_KEY_Z; - case KEY_X: return GLFW_KEY_X; - case KEY_C: return GLFW_KEY_C; - case KEY_V: return GLFW_KEY_V; - case KEY_B: return GLFW_KEY_B; - case KEY_N: return GLFW_KEY_N; - case KEY_M: return GLFW_KEY_M; - case KEY_COMMA: return GLFW_KEY_COMMA; - case KEY_DOT: return GLFW_KEY_PERIOD; - case KEY_SLASH: return GLFW_KEY_SLASH; - case KEY_BACKSLASH: return GLFW_KEY_BACKSLASH; - case KEY_ESC: return GLFW_KEY_ESCAPE; - case KEY_TAB: return GLFW_KEY_TAB; - case KEY_LEFTSHIFT: return GLFW_KEY_LEFT_SHIFT; - case KEY_RIGHTSHIFT: return GLFW_KEY_RIGHT_SHIFT; - case KEY_LEFTCTRL: return GLFW_KEY_LEFT_CONTROL; - case KEY_RIGHTCTRL: return GLFW_KEY_RIGHT_CONTROL; - case KEY_LEFTALT: return GLFW_KEY_LEFT_ALT; - case KEY_RIGHTALT: return GLFW_KEY_RIGHT_ALT; - case KEY_LEFTMETA: return GLFW_KEY_LEFT_SUPER; - case KEY_RIGHTMETA: return GLFW_KEY_RIGHT_SUPER; - case KEY_MENU: return GLFW_KEY_MENU; - case KEY_NUMLOCK: return GLFW_KEY_NUM_LOCK; - case KEY_CAPSLOCK: return GLFW_KEY_CAPS_LOCK; - case KEY_PRINT: return GLFW_KEY_PRINT_SCREEN; - case KEY_SCROLLLOCK: return GLFW_KEY_SCROLL_LOCK; - case KEY_PAUSE: return GLFW_KEY_PAUSE; - case KEY_DELETE: return GLFW_KEY_DELETE; - case KEY_BACKSPACE: return GLFW_KEY_BACKSPACE; - case KEY_ENTER: return GLFW_KEY_ENTER; - case KEY_HOME: return GLFW_KEY_HOME; - case KEY_END: return GLFW_KEY_END; - case KEY_PAGEUP: return GLFW_KEY_PAGE_UP; - case KEY_PAGEDOWN: return GLFW_KEY_PAGE_DOWN; - case KEY_INSERT: return GLFW_KEY_INSERT; - case KEY_LEFT: return GLFW_KEY_LEFT; - case KEY_RIGHT: return GLFW_KEY_RIGHT; - case KEY_DOWN: return GLFW_KEY_DOWN; - case KEY_UP: return GLFW_KEY_UP; - case KEY_F1: return GLFW_KEY_F1; - case KEY_F2: return GLFW_KEY_F2; - case KEY_F3: return GLFW_KEY_F3; - case KEY_F4: return GLFW_KEY_F4; - case KEY_F5: return GLFW_KEY_F5; - case KEY_F6: return GLFW_KEY_F6; - case KEY_F7: return GLFW_KEY_F7; - case KEY_F8: return GLFW_KEY_F8; - case KEY_F9: return GLFW_KEY_F9; - case KEY_F10: return GLFW_KEY_F10; - case KEY_F11: return GLFW_KEY_F11; - case KEY_F12: return GLFW_KEY_F12; - case KEY_F13: return GLFW_KEY_F13; - case KEY_F14: return GLFW_KEY_F14; - case KEY_F15: return GLFW_KEY_F15; - case KEY_F16: return GLFW_KEY_F16; - case KEY_F17: return GLFW_KEY_F17; - case KEY_F18: return GLFW_KEY_F18; - case KEY_F19: return GLFW_KEY_F19; - case KEY_F20: return GLFW_KEY_F20; - case KEY_F21: return GLFW_KEY_F21; - case KEY_F22: return GLFW_KEY_F22; - case KEY_F23: return GLFW_KEY_F23; - case KEY_F24: return GLFW_KEY_F24; - case KEY_KPSLASH: return GLFW_KEY_KP_DIVIDE; - case KEY_KPDOT: return GLFW_KEY_KP_MULTIPLY; - case KEY_KPMINUS: return GLFW_KEY_KP_SUBTRACT; - case KEY_KPPLUS: return GLFW_KEY_KP_ADD; - case KEY_KP0: return GLFW_KEY_KP_0; - case KEY_KP1: return GLFW_KEY_KP_1; - case KEY_KP2: return GLFW_KEY_KP_2; - case KEY_KP3: return GLFW_KEY_KP_3; - case KEY_KP4: return GLFW_KEY_KP_4; - case KEY_KP5: return GLFW_KEY_KP_5; - case KEY_KP6: return GLFW_KEY_KP_6; - case KEY_KP7: return GLFW_KEY_KP_7; - case KEY_KP8: return GLFW_KEY_KP_8; - case KEY_KP9: return GLFW_KEY_KP_9; - case KEY_KPCOMMA: return GLFW_KEY_KP_DECIMAL; - case KEY_KPEQUAL: return GLFW_KEY_KP_EQUAL; - case KEY_KPENTER: return GLFW_KEY_KP_ENTER; - default: return GLFW_KEY_UNKNOWN; - } -} - -static void keyboardHandleKey(void* data, - struct wl_keyboard* keyboard, - uint32_t serial, - uint32_t time, - uint32_t key, - uint32_t state) -{ - uint32_t code, num_syms; - long cp; - int keyCode; - int action; - const xkb_keysym_t *syms; - _GLFWwindow* window = _glfw.wl.keyboardFocus; - - if (!window) - return; - - keyCode = toGLFWKeyCode(key); - action = state == WL_KEYBOARD_KEY_STATE_PRESSED - ? GLFW_PRESS : GLFW_RELEASE; - - _glfwInputKey(window, keyCode, key, action, - _glfw.wl.xkb.modifiers); - - code = key + 8; - num_syms = xkb_key_get_syms(_glfw.wl.xkb.state, code, &syms); - - if (num_syms == 1) - { - cp = _glfwKeySym2Unicode(syms[0]); - if (cp != -1) - { - const int mods = _glfw.wl.xkb.modifiers; - const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT)); - _glfwInputChar(window, cp, mods, plain); - } - } -} - -static void keyboardHandleModifiers(void* data, - struct wl_keyboard* keyboard, - uint32_t serial, - uint32_t modsDepressed, - uint32_t modsLatched, - uint32_t modsLocked, - uint32_t group) -{ - xkb_mod_mask_t mask; - unsigned int modifiers = 0; - - if (!_glfw.wl.xkb.keymap) - return; - - xkb_state_update_mask(_glfw.wl.xkb.state, - modsDepressed, - modsLatched, - modsLocked, - 0, - 0, - group); - - mask = xkb_state_serialize_mods(_glfw.wl.xkb.state, - XKB_STATE_DEPRESSED | - XKB_STATE_LATCHED); - if (mask & _glfw.wl.xkb.control_mask) - modifiers |= GLFW_MOD_CONTROL; - if (mask & _glfw.wl.xkb.alt_mask) - modifiers |= GLFW_MOD_ALT; - if (mask & _glfw.wl.xkb.shift_mask) - modifiers |= GLFW_MOD_SHIFT; - if (mask & _glfw.wl.xkb.super_mask) - modifiers |= GLFW_MOD_SUPER; - _glfw.wl.xkb.modifiers = modifiers; -} - -static const struct wl_keyboard_listener keyboardListener = { - keyboardHandleKeymap, - keyboardHandleEnter, - keyboardHandleLeave, - keyboardHandleKey, - keyboardHandleModifiers, -}; - -static void seatHandleCapabilities(void* data, - struct wl_seat* seat, - enum wl_seat_capability caps) -{ - if ((caps & WL_SEAT_CAPABILITY_POINTER) && !_glfw.wl.pointer) - { - _glfw.wl.pointer = wl_seat_get_pointer(seat); - wl_pointer_add_listener(_glfw.wl.pointer, &pointerListener, NULL); - } - else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && _glfw.wl.pointer) - { - wl_pointer_destroy(_glfw.wl.pointer); - _glfw.wl.pointer = NULL; - } - - if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !_glfw.wl.keyboard) - { - _glfw.wl.keyboard = wl_seat_get_keyboard(seat); - wl_keyboard_add_listener(_glfw.wl.keyboard, &keyboardListener, NULL); - } - else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && _glfw.wl.keyboard) - { - wl_keyboard_destroy(_glfw.wl.keyboard); - _glfw.wl.keyboard = NULL; - } -} - -static const struct wl_seat_listener seatListener = { - seatHandleCapabilities -}; - -static void registryHandleGlobal(void* data, - struct wl_registry* registry, - uint32_t name, - const char* interface, - uint32_t version) -{ - if (strcmp(interface, "wl_compositor") == 0) - { - _glfw.wl.compositor = - wl_registry_bind(registry, name, &wl_compositor_interface, 1); - } - else if (strcmp(interface, "wl_shm") == 0) - { - _glfw.wl.shm = - wl_registry_bind(registry, name, &wl_shm_interface, 1); - } - else if (strcmp(interface, "wl_shell") == 0) - { - _glfw.wl.shell = - wl_registry_bind(registry, name, &wl_shell_interface, 1); - } - else if (strcmp(interface, "wl_output") == 0) - { - _glfwAddOutput(name, version); - } - else if (strcmp(interface, "wl_seat") == 0) - { - if (!_glfw.wl.seat) - { - _glfw.wl.seat = - wl_registry_bind(registry, name, &wl_seat_interface, 1); - wl_seat_add_listener(_glfw.wl.seat, &seatListener, NULL); - } - } -} - -static void registryHandleGlobalRemove(void *data, - struct wl_registry *registry, - uint32_t name) -{ -} - - -static const struct wl_registry_listener registryListener = { - registryHandleGlobal, - registryHandleGlobalRemove -}; - - -////////////////////////////////////////////////////////////////////////// -////// GLFW platform API ////// -////////////////////////////////////////////////////////////////////////// - -int _glfwPlatformInit(void) -{ - _glfw.wl.display = wl_display_connect(NULL); - if (!_glfw.wl.display) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Failed to connect to display"); - return GL_FALSE; - } - - _glfw.wl.registry = wl_display_get_registry(_glfw.wl.display); - wl_registry_add_listener(_glfw.wl.registry, ®istryListener, NULL); - - _glfw.wl.monitors = calloc(4, sizeof(_GLFWmonitor*)); - _glfw.wl.monitorsSize = 4; - - _glfw.wl.xkb.context = xkb_context_new(0); - if (!_glfw.wl.xkb.context) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Failed to initialize xkb context"); - return GL_FALSE; - } - - // Sync so we got all registry objects - wl_display_roundtrip(_glfw.wl.display); - - // Sync so we got all initial output events - wl_display_roundtrip(_glfw.wl.display); - - if (!_glfwInitContextAPI()) - return GL_FALSE; - - _glfwInitTimer(); - _glfwInitJoysticks(); - - if (_glfw.wl.pointer && _glfw.wl.shm) - { - _glfw.wl.cursorTheme = wl_cursor_theme_load(NULL, 32, _glfw.wl.shm); - if (!_glfw.wl.cursorTheme) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Unable to load default cursor theme\n"); - return GL_FALSE; - } - _glfw.wl.defaultCursor = - wl_cursor_theme_get_cursor(_glfw.wl.cursorTheme, "left_ptr"); - if (!_glfw.wl.defaultCursor) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Unable to load default left pointer\n"); - return GL_FALSE; - } - _glfw.wl.cursorSurface = - wl_compositor_create_surface(_glfw.wl.compositor); - } - - return GL_TRUE; -} - -void _glfwPlatformTerminate(void) -{ - _glfwTerminateContextAPI(); - _glfwTerminateJoysticks(); - - if (_glfw.wl.cursorTheme) - wl_cursor_theme_destroy(_glfw.wl.cursorTheme); - if (_glfw.wl.cursorSurface) - wl_surface_destroy(_glfw.wl.cursorSurface); - if (_glfw.wl.registry) - wl_registry_destroy(_glfw.wl.registry); - if (_glfw.wl.display) - wl_display_flush(_glfw.wl.display); - if (_glfw.wl.display) - wl_display_disconnect(_glfw.wl.display); -} - -const char* _glfwPlatformGetVersionString(void) -{ - const char* version = _GLFW_VERSION_NUMBER " Wayland EGL " -#if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK) - " clock_gettime" -#endif -#if defined(_GLFW_BUILD_DLL) - " shared" -#endif - ; - - return version; -} - diff --git a/examples/common/glfw/src/wl_monitor.c b/examples/common/glfw/src/wl_monitor.c deleted file mode 100644 index fbcefd38..00000000 --- a/examples/common/glfw/src/wl_monitor.c +++ /dev/null @@ -1,250 +0,0 @@ -//======================================================================== -// GLFW 3.1 Wayland - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2014 Jonas Ådahl -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#include "internal.h" - -#include -#include -#include -#include - - -struct _GLFWvidmodeWayland -{ - GLFWvidmode base; - uint32_t flags; -}; - -static void geometry(void* data, - struct wl_output* output, - int32_t x, - int32_t y, - int32_t physicalWidth, - int32_t physicalHeight, - int32_t subpixel, - const char* make, - const char* model, - int32_t transform) -{ - struct _GLFWmonitor *monitor = data; - - monitor->wl.x = x; - monitor->wl.y = y; - monitor->widthMM = physicalWidth; - monitor->heightMM = physicalHeight; -} - -static void mode(void* data, - struct wl_output* output, - uint32_t flags, - int32_t width, - int32_t height, - int32_t refresh) -{ - struct _GLFWmonitor *monitor = data; - _GLFWvidmodeWayland mode = { { 0 }, }; - - mode.base.width = width; - mode.base.height = height; - mode.base.refreshRate = refresh; - mode.flags = flags; - - if (monitor->wl.modesCount + 1 >= monitor->wl.modesSize) - { - int size = monitor->wl.modesSize * 2; - _GLFWvidmodeWayland* modes = - realloc(monitor->wl.modes, - size * sizeof(_GLFWvidmodeWayland)); - monitor->wl.modes = modes; - monitor->wl.modesSize = size; - } - - monitor->wl.modes[monitor->wl.modesCount++] = mode; -} - -static void done(void* data, - struct wl_output* output) -{ - struct _GLFWmonitor *monitor = data; - - monitor->wl.done = GL_TRUE; -} - -static void scale(void* data, - struct wl_output* output, - int32_t factor) -{ -} - -static const struct wl_output_listener output_listener = { - geometry, - mode, - done, - scale, -}; - - -////////////////////////////////////////////////////////////////////////// -////// GLFW internal API ////// -////////////////////////////////////////////////////////////////////////// - -void _glfwAddOutput(uint32_t name, uint32_t version) -{ - _GLFWmonitor *monitor; - struct wl_output *output; - char name_str[80]; - - memset(name_str, 0, 80 * sizeof(char)); - snprintf(name_str, 79, "wl_output@%u", name); - - if (version < 2) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Unsupported output interface version"); - return; - } - - monitor = _glfwAllocMonitor(name_str, 0, 0); - - output = wl_registry_bind(_glfw.wl.registry, - name, - &wl_output_interface, - 2); - if (!output) - { - _glfwFreeMonitor(monitor); - return; - } - - monitor->wl.modes = calloc(4, sizeof(_GLFWvidmodeWayland)); - monitor->wl.modesSize = 4; - - monitor->wl.output = output; - wl_output_add_listener(output, &output_listener, monitor); - - if (_glfw.wl.monitorsCount + 1 >= _glfw.wl.monitorsSize) - { - _GLFWmonitor** monitors = _glfw.wl.monitors; - int size = _glfw.wl.monitorsSize * 2; - - monitors = realloc(monitors, size * sizeof(_GLFWmonitor*)); - - _glfw.wl.monitors = monitors; - _glfw.wl.monitorsSize = size; - } - - _glfw.wl.monitors[_glfw.wl.monitorsCount++] = monitor; -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW platform API ////// -////////////////////////////////////////////////////////////////////////// - -_GLFWmonitor** _glfwPlatformGetMonitors(int* count) -{ - _GLFWmonitor** monitors; - _GLFWmonitor* monitor; - int i, monitorsCount = _glfw.wl.monitorsCount; - - if (_glfw.wl.monitorsCount == 0) - goto err; - - monitors = calloc(monitorsCount, sizeof(_GLFWmonitor*)); - - for (i = 0; i < monitorsCount; i++) - { - _GLFWmonitor* origMonitor = _glfw.wl.monitors[i]; - monitor = calloc(1, sizeof(_GLFWmonitor)); - - monitor->modes = - _glfwPlatformGetVideoModes(origMonitor, - &origMonitor->wl.modesCount); - *monitor = *_glfw.wl.monitors[i]; - monitors[i] = monitor; - } - - *count = monitorsCount; - return monitors; - -err: - *count = 0; - return NULL; -} - -GLboolean _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second) -{ - return first->wl.output == second->wl.output; -} - -void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos) -{ - if (xpos) - *xpos = monitor->wl.x; - if (ypos) - *ypos = monitor->wl.y; -} - -GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found) -{ - GLFWvidmode *modes; - int i, modesCount = monitor->wl.modesCount; - - modes = calloc(modesCount, sizeof(GLFWvidmode)); - - for (i = 0; i < modesCount; i++) - modes[i] = monitor->wl.modes[i].base; - - *found = modesCount; - return modes; -} - -void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) -{ - int i; - - for (i = 0; i < monitor->wl.modesCount; i++) - { - if (monitor->wl.modes[i].flags & WL_OUTPUT_MODE_CURRENT) - { - *mode = monitor->wl.modes[i].base; - return; - } - } -} - -void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) -{ - // TODO - fprintf(stderr, "_glfwPlatformGetGammaRamp not implemented yet\n"); -} - -void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) -{ - // TODO - fprintf(stderr, "_glfwPlatformSetGammaRamp not implemented yet\n"); -} - diff --git a/examples/common/glfw/src/wl_platform.h b/examples/common/glfw/src/wl_platform.h deleted file mode 100644 index 66736b56..00000000 --- a/examples/common/glfw/src/wl_platform.h +++ /dev/null @@ -1,140 +0,0 @@ -//======================================================================== -// GLFW 3.1 Wayland - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2014 Jonas Ådahl -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#ifndef _wayland_platform_h_ -#define _wayland_platform_h_ - - -#include -#include - -#if defined(_GLFW_EGL) - #include "egl_context.h" -#else - #error "The Wayland backend depends on EGL platform support" -#endif - -#include "posix_tls.h" -#include "posix_time.h" -#include "linux_joystick.h" - -#define _GLFW_EGL_NATIVE_WINDOW window->wl.native -#define _GLFW_EGL_NATIVE_DISPLAY _glfw.wl.display - -#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowWayland wl -#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryWayland wl -#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorWayland wl -#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorWayland wl - - -// Wayland-specific video mode data -// -typedef struct _GLFWvidmodeWayland _GLFWvidmodeWayland; - - -// Wayland-specific per-window data -// -typedef struct _GLFWwindowWayland -{ - int width, height; - GLboolean visible; - struct wl_surface* surface; - struct wl_egl_window* native; - struct wl_shell_surface* shell_surface; - struct wl_callback* callback; - _GLFWcursor* currentCursor; -} _GLFWwindowWayland; - - -// Wayland-specific global data -// -typedef struct _GLFWlibraryWayland -{ - struct wl_display* display; - struct wl_registry* registry; - struct wl_compositor* compositor; - struct wl_shell* shell; - struct wl_shm* shm; - struct wl_seat* seat; - struct wl_pointer* pointer; - struct wl_keyboard* keyboard; - - struct wl_cursor_theme* cursorTheme; - struct wl_cursor* defaultCursor; - struct wl_surface* cursorSurface; - uint32_t pointerSerial; - - _GLFWmonitor** monitors; - int monitorsCount; - int monitorsSize; - - struct { - struct xkb_context* context; - struct xkb_keymap* keymap; - struct xkb_state* state; - xkb_mod_mask_t control_mask; - xkb_mod_mask_t alt_mask; - xkb_mod_mask_t shift_mask; - xkb_mod_mask_t super_mask; - unsigned int modifiers; - } xkb; - - _GLFWwindow* pointerFocus; - _GLFWwindow* keyboardFocus; - -} _GLFWlibraryWayland; - - -// Wayland-specific per-monitor data -// -typedef struct _GLFWmonitorWayland -{ - struct wl_output* output; - - _GLFWvidmodeWayland* modes; - int modesCount; - int modesSize; - GLboolean done; - - int x; - int y; - -} _GLFWmonitorWayland; - - -// Wayland-specific per-cursor data -// -typedef struct _GLFWcursorWayland -{ - struct wl_buffer* buffer; - int width, height; - int xhot, yhot; -} _GLFWcursorWayland; - - -void _glfwAddOutput(uint32_t name, uint32_t version); - -#endif // _wayland_platform_h_ diff --git a/examples/common/glfw/src/wl_window.c b/examples/common/glfw/src/wl_window.c deleted file mode 100644 index bb2da473..00000000 --- a/examples/common/glfw/src/wl_window.c +++ /dev/null @@ -1,524 +0,0 @@ -//======================================================================== -// GLFW 3.1 Wayland - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2014 Jonas Ådahl -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#define _GNU_SOURCE - -#include "internal.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - - -static void handlePing(void* data, - struct wl_shell_surface* shellSurface, - uint32_t serial) -{ - wl_shell_surface_pong(shellSurface, serial); -} - -static void handleConfigure(void* data, - struct wl_shell_surface* shellSurface, - uint32_t edges, - int32_t width, - int32_t height) -{ - _GLFWwindow* window = data; - _glfwInputFramebufferSize(window, width, height); - _glfwInputWindowSize(window, width, height); - _glfwPlatformSetWindowSize(window, width, height); - _glfwInputWindowDamage(window); -} - -static void handlePopupDone(void* data, - struct wl_shell_surface* shellSurface) -{ -} - -static const struct wl_shell_surface_listener shellSurfaceListener = { - handlePing, - handleConfigure, - handlePopupDone -}; - -static GLboolean createSurface(_GLFWwindow* window, - const _GLFWwndconfig* wndconfig) -{ - window->wl.surface = wl_compositor_create_surface(_glfw.wl.compositor); - if (!window->wl.surface) - return GL_FALSE; - - wl_surface_set_user_data(window->wl.surface, window); - - window->wl.native = wl_egl_window_create(window->wl.surface, - wndconfig->width, - wndconfig->height); - if (!window->wl.native) - return GL_FALSE; - - window->wl.shell_surface = wl_shell_get_shell_surface(_glfw.wl.shell, - window->wl.surface); - if (!window->wl.shell_surface) - return GL_FALSE; - - wl_shell_surface_add_listener(window->wl.shell_surface, - &shellSurfaceListener, - window); - - window->wl.width = wndconfig->width; - window->wl.height = wndconfig->height; - - return GL_TRUE; -} - -static int -createTmpfileCloexec(char* tmpname) -{ - int fd; - - fd = mkostemp(tmpname, O_CLOEXEC); - if (fd >= 0) - unlink(tmpname); - - return fd; -} - -/* - * Create a new, unique, anonymous file of the given size, and - * return the file descriptor for it. The file descriptor is set - * CLOEXEC. The file is immediately suitable for mmap()'ing - * the given size at offset zero. - * - * The file should not have a permanent backing store like a disk, - * but may have if XDG_RUNTIME_DIR is not properly implemented in OS. - * - * The file name is deleted from the file system. - * - * The file is suitable for buffer sharing between processes by - * transmitting the file descriptor over Unix sockets using the - * SCM_RIGHTS methods. - * - * posix_fallocate() is used to guarantee that disk space is available - * for the file at the given size. If disk space is insufficent, errno - * is set to ENOSPC. If posix_fallocate() is not supported, program may - * receive SIGBUS on accessing mmap()'ed file contents instead. - */ -int -createAnonymousFile(off_t size) -{ - static const char template[] = "/glfw-shared-XXXXXX"; - const char* path; - char* name; - int fd; - int ret; - - path = getenv("XDG_RUNTIME_DIR"); - if (!path) - { - errno = ENOENT; - return -1; - } - - name = malloc(strlen(path) + sizeof(template)); - strcpy(name, path); - strcat(name, template); - - fd = createTmpfileCloexec(name); - - free(name); - - if (fd < 0) - return -1; - ret = posix_fallocate(fd, 0, size); - if (ret != 0) - { - close(fd); - errno = ret; - return -1; - } - return fd; -} - -////////////////////////////////////////////////////////////////////////// -////// GLFW platform API ////// -////////////////////////////////////////////////////////////////////////// - -int _glfwPlatformCreateWindow(_GLFWwindow* window, - const _GLFWwndconfig* wndconfig, - const _GLFWctxconfig* ctxconfig, - const _GLFWfbconfig* fbconfig) -{ - if (!_glfwCreateContext(window, ctxconfig, fbconfig)) - return GL_FALSE; - - if (!createSurface(window, wndconfig)) - return GL_FALSE; - - if (wndconfig->monitor) - { - wl_shell_surface_set_fullscreen( - window->wl.shell_surface, - WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, - 0, - wndconfig->monitor->wl.output); - } - else - { - wl_shell_surface_set_toplevel(window->wl.shell_surface); - } - - window->wl.currentCursor = NULL; - - return GL_TRUE; -} - -void _glfwPlatformDestroyWindow(_GLFWwindow* window) -{ - if (window == _glfw.wl.pointerFocus) - { - _glfw.wl.pointerFocus = NULL; - _glfwInputCursorEnter(window, GL_FALSE); - } - if (window == _glfw.wl.keyboardFocus) - { - _glfw.wl.keyboardFocus = NULL; - _glfwInputWindowFocus(window, GL_FALSE); - } - - _glfwDestroyContext(window); - - if (window->wl.native) - wl_egl_window_destroy(window->wl.native); - - if (window->wl.shell_surface) - wl_shell_surface_destroy(window->wl.shell_surface); - - if (window->wl.surface) - wl_surface_destroy(window->wl.surface); -} - -void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title) -{ - wl_shell_surface_set_title(window->wl.shell_surface, title); -} - -void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos) -{ - // A Wayland client is not aware of its position, so just warn and leave it - // as (0, 0) - - _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Window position retrieval not supported"); -} - -void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos) -{ - // A Wayland client can not set its position, so just warn - - _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Window position setting not supported"); -} - -void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height) -{ - if (width) - *width = window->wl.width; - if (height) - *height = window->wl.height; -} - -void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) -{ - wl_egl_window_resize(window->wl.native, width, height, 0, 0); - window->wl.width = width; - window->wl.height = height; -} - -void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height) -{ - _glfwPlatformGetWindowSize(window, width, height); -} - -void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, - int* left, int* top, - int* right, int* bottom) -{ - // TODO - fprintf(stderr, "_glfwPlatformGetWindowFrameSize not implemented yet\n"); -} - -void _glfwPlatformIconifyWindow(_GLFWwindow* window) -{ - // TODO - fprintf(stderr, "_glfwPlatformIconifyWindow not implemented yet\n"); -} - -void _glfwPlatformRestoreWindow(_GLFWwindow* window) -{ - // TODO - fprintf(stderr, "_glfwPlatformRestoreWindow not implemented yet\n"); -} - -void _glfwPlatformShowWindow(_GLFWwindow* window) -{ - wl_shell_surface_set_toplevel(window->wl.shell_surface); -} - -void _glfwPlatformUnhideWindow(_GLFWwindow* window) -{ - // TODO - fprintf(stderr, "_glfwPlatformUnhideWindow not implemented yet\n"); -} - -void _glfwPlatformHideWindow(_GLFWwindow* window) -{ - wl_surface_attach(window->wl.surface, NULL, 0, 0); - wl_surface_commit(window->wl.surface); -} - -int _glfwPlatformWindowFocused(_GLFWwindow* window) -{ - // TODO - return GL_FALSE; -} - -int _glfwPlatformWindowIconified(_GLFWwindow* window) -{ - // TODO - return GL_FALSE; -} - -int _glfwPlatformWindowVisible(_GLFWwindow* window) -{ - // TODO - return GL_FALSE; -} - -void _glfwPlatformPollEvents(void) -{ - struct wl_display* display = _glfw.wl.display; - struct pollfd fds[] = { - { wl_display_get_fd(display), POLLIN }, - }; - - while (wl_display_prepare_read(display) != 0) - wl_display_dispatch_pending(display); - wl_display_flush(display); - if (poll(fds, 1, 0) > 0) - { - wl_display_read_events(display); - wl_display_dispatch_pending(display); - } - else - { - wl_display_cancel_read(display); - } -} - -void _glfwPlatformWaitEvents(void) -{ - struct wl_display* display = _glfw.wl.display; - struct pollfd fds[] = { - { wl_display_get_fd(display), POLLIN }, - }; - - while (wl_display_prepare_read(display) != 0) - wl_display_dispatch_pending(display); - wl_display_flush(display); - if (poll(fds, 1, -1) > 0) - { - wl_display_read_events(display); - wl_display_dispatch_pending(display); - } - else - { - wl_display_cancel_read(display); - } -} - -void _glfwPlatformPostEmptyEvent(void) -{ - wl_display_sync(_glfw.wl.display); -} - -void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos) -{ - // TODO - fprintf(stderr, "_glfwPlatformGetCursorPos not implemented yet\n"); -} - -void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y) -{ - // A Wayland client can not set the cursor position - _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Cursor position setting not supported"); -} - -void _glfwPlatformApplyCursorMode(_GLFWwindow* window) -{ - _glfwPlatformSetCursor(window, window->wl.currentCursor); -} - -int _glfwPlatformCreateCursor(_GLFWcursor* cursor, - const GLFWimage* image, - int xhot, int yhot) -{ - struct wl_shm_pool* pool; - int stride = image->width * 4; - int length = image->width * image->height * 4; - void* data; - int fd, i; - - fd = createAnonymousFile(length); - if (fd < 0) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Creating a buffer file for %d B failed: %m\n", - length); - return GL_FALSE; - } - - data = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - if (data == MAP_FAILED) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Cursor mmap failed: %m\n"); - close(fd); - return GL_FALSE; - } - - pool = wl_shm_create_pool(_glfw.wl.shm, fd, length); - - close(fd); - unsigned char* source = (unsigned char*) image->pixels; - unsigned char* target = data; - for (i = 0; i < image->width * image->height; i++, source += 4) - { - *target++ = source[2]; - *target++ = source[1]; - *target++ = source[0]; - *target++ = source[3]; - } - - cursor->wl.buffer = - wl_shm_pool_create_buffer(pool, 0, - image->width, - image->height, - stride, WL_SHM_FORMAT_ARGB8888); - munmap(data, length); - wl_shm_pool_destroy(pool); - - cursor->wl.width = image->width; - cursor->wl.height = image->height; - cursor->wl.xhot = xhot; - cursor->wl.yhot = yhot; - return GL_TRUE; -} - -int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape) -{ - // TODO - fprintf(stderr, "_glfwPlatformCreateStandardCursor not implemented yet\n"); - return GL_FALSE; -} - -void _glfwPlatformDestroyCursor(_GLFWcursor* cursor) -{ - wl_buffer_destroy(cursor->wl.buffer); -} - -void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) -{ - struct wl_buffer* buffer; - struct wl_cursor_image* image; - struct wl_surface* surface = _glfw.wl.cursorSurface; - - if (!_glfw.wl.pointer) - return; - - window->wl.currentCursor = cursor; - - // If we're not in the correct window just save the cursor - // the next time the pointer enters the window the cursor will change - if (window != _glfw.wl.pointerFocus) - return; - - if (window->cursorMode == GLFW_CURSOR_NORMAL) - { - if (cursor == NULL) - { - image = _glfw.wl.defaultCursor->images[0]; - buffer = wl_cursor_image_get_buffer(image); - if (!buffer) - return; - wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerSerial, - surface, - image->hotspot_x, - image->hotspot_y); - wl_surface_attach(surface, buffer, 0, 0); - wl_surface_damage(surface, 0, 0, - image->width, image->height); - wl_surface_commit(surface); - } - else - { - wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerSerial, - surface, - cursor->wl.xhot, - cursor->wl.yhot); - wl_surface_attach(surface, cursor->wl.buffer, 0, 0); - wl_surface_damage(surface, 0, 0, - cursor->wl.width, cursor->wl.height); - wl_surface_commit(surface); - } - } - else /* Cursor is hidden set cursor surface to NULL */ - { - wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerSerial, NULL, 0, 0); - } -} - -void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string) -{ - // TODO - fprintf(stderr, "_glfwPlatformSetClipboardString not implemented yet\n"); -} - -const char* _glfwPlatformGetClipboardString(_GLFWwindow* window) -{ - // TODO - fprintf(stderr, "_glfwPlatformGetClipboardString not implemented yet\n"); - return NULL; -} - diff --git a/examples/common/glfw/src/x11_init.c b/examples/common/glfw/src/x11_init.c deleted file mode 100644 index 388105ef..00000000 --- a/examples/common/glfw/src/x11_init.c +++ /dev/null @@ -1,816 +0,0 @@ -//======================================================================== -// GLFW 3.1 X11 - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2002-2006 Marcus Geelnard -// Copyright (c) 2006-2010 Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#include "internal.h" - -#include - -#include -#include -#include -#include -#include - - -// Translate an X11 key code to a GLFW key code. -// -static int translateKey(int scancode) -{ - int keySym; - - // Valid key code range is [8,255], according to the Xlib manual - if (scancode < 8 || scancode > 255) - return GLFW_KEY_UNKNOWN; - - if (_glfw.x11.xkb.available) - { - // Try secondary keysym, for numeric keypad keys - // Note: This way we always force "NumLock = ON", which is intentional - // since the returned key code should correspond to a physical - // location. - keySym = XkbKeycodeToKeysym(_glfw.x11.display, scancode, 0, 1); - switch (keySym) - { - case XK_KP_0: return GLFW_KEY_KP_0; - case XK_KP_1: return GLFW_KEY_KP_1; - case XK_KP_2: return GLFW_KEY_KP_2; - case XK_KP_3: return GLFW_KEY_KP_3; - case XK_KP_4: return GLFW_KEY_KP_4; - case XK_KP_5: return GLFW_KEY_KP_5; - case XK_KP_6: return GLFW_KEY_KP_6; - case XK_KP_7: return GLFW_KEY_KP_7; - case XK_KP_8: return GLFW_KEY_KP_8; - case XK_KP_9: return GLFW_KEY_KP_9; - case XK_KP_Separator: - case XK_KP_Decimal: return GLFW_KEY_KP_DECIMAL; - case XK_KP_Equal: return GLFW_KEY_KP_EQUAL; - case XK_KP_Enter: return GLFW_KEY_KP_ENTER; - default: break; - } - - // Now try primary keysym for function keys (non-printable keys). These - // should not be layout dependent (i.e. US layout and international - // layouts should give the same result). - keySym = XkbKeycodeToKeysym(_glfw.x11.display, scancode, 0, 0); - } - else - { - int dummy; - KeySym* keySyms; - - keySyms = XGetKeyboardMapping(_glfw.x11.display, scancode, 1, &dummy); - keySym = keySyms[0]; - XFree(keySyms); - } - - switch (keySym) - { - case XK_Escape: return GLFW_KEY_ESCAPE; - case XK_Tab: return GLFW_KEY_TAB; - case XK_Shift_L: return GLFW_KEY_LEFT_SHIFT; - case XK_Shift_R: return GLFW_KEY_RIGHT_SHIFT; - case XK_Control_L: return GLFW_KEY_LEFT_CONTROL; - case XK_Control_R: return GLFW_KEY_RIGHT_CONTROL; - case XK_Meta_L: - case XK_Alt_L: return GLFW_KEY_LEFT_ALT; - case XK_Mode_switch: // Mapped to Alt_R on many keyboards - case XK_ISO_Level3_Shift: // AltGr on at least some machines - case XK_Meta_R: - case XK_Alt_R: return GLFW_KEY_RIGHT_ALT; - case XK_Super_L: return GLFW_KEY_LEFT_SUPER; - case XK_Super_R: return GLFW_KEY_RIGHT_SUPER; - case XK_Menu: return GLFW_KEY_MENU; - case XK_Num_Lock: return GLFW_KEY_NUM_LOCK; - case XK_Caps_Lock: return GLFW_KEY_CAPS_LOCK; - case XK_Print: return GLFW_KEY_PRINT_SCREEN; - case XK_Scroll_Lock: return GLFW_KEY_SCROLL_LOCK; - case XK_Pause: return GLFW_KEY_PAUSE; - case XK_Delete: return GLFW_KEY_DELETE; - case XK_BackSpace: return GLFW_KEY_BACKSPACE; - case XK_Return: return GLFW_KEY_ENTER; - case XK_Home: return GLFW_KEY_HOME; - case XK_End: return GLFW_KEY_END; - case XK_Page_Up: return GLFW_KEY_PAGE_UP; - case XK_Page_Down: return GLFW_KEY_PAGE_DOWN; - case XK_Insert: return GLFW_KEY_INSERT; - case XK_Left: return GLFW_KEY_LEFT; - case XK_Right: return GLFW_KEY_RIGHT; - case XK_Down: return GLFW_KEY_DOWN; - case XK_Up: return GLFW_KEY_UP; - case XK_F1: return GLFW_KEY_F1; - case XK_F2: return GLFW_KEY_F2; - case XK_F3: return GLFW_KEY_F3; - case XK_F4: return GLFW_KEY_F4; - case XK_F5: return GLFW_KEY_F5; - case XK_F6: return GLFW_KEY_F6; - case XK_F7: return GLFW_KEY_F7; - case XK_F8: return GLFW_KEY_F8; - case XK_F9: return GLFW_KEY_F9; - case XK_F10: return GLFW_KEY_F10; - case XK_F11: return GLFW_KEY_F11; - case XK_F12: return GLFW_KEY_F12; - case XK_F13: return GLFW_KEY_F13; - case XK_F14: return GLFW_KEY_F14; - case XK_F15: return GLFW_KEY_F15; - case XK_F16: return GLFW_KEY_F16; - case XK_F17: return GLFW_KEY_F17; - case XK_F18: return GLFW_KEY_F18; - case XK_F19: return GLFW_KEY_F19; - case XK_F20: return GLFW_KEY_F20; - case XK_F21: return GLFW_KEY_F21; - case XK_F22: return GLFW_KEY_F22; - case XK_F23: return GLFW_KEY_F23; - case XK_F24: return GLFW_KEY_F24; - case XK_F25: return GLFW_KEY_F25; - - // Numeric keypad - case XK_KP_Divide: return GLFW_KEY_KP_DIVIDE; - case XK_KP_Multiply: return GLFW_KEY_KP_MULTIPLY; - case XK_KP_Subtract: return GLFW_KEY_KP_SUBTRACT; - case XK_KP_Add: return GLFW_KEY_KP_ADD; - - // These should have been detected in secondary keysym test above! - case XK_KP_Insert: return GLFW_KEY_KP_0; - case XK_KP_End: return GLFW_KEY_KP_1; - case XK_KP_Down: return GLFW_KEY_KP_2; - case XK_KP_Page_Down: return GLFW_KEY_KP_3; - case XK_KP_Left: return GLFW_KEY_KP_4; - case XK_KP_Right: return GLFW_KEY_KP_6; - case XK_KP_Home: return GLFW_KEY_KP_7; - case XK_KP_Up: return GLFW_KEY_KP_8; - case XK_KP_Page_Up: return GLFW_KEY_KP_9; - case XK_KP_Delete: return GLFW_KEY_KP_DECIMAL; - case XK_KP_Equal: return GLFW_KEY_KP_EQUAL; - case XK_KP_Enter: return GLFW_KEY_KP_ENTER; - - // Last resort: Check for printable keys (should not happen if the XKB - // extension is available). This will give a layout dependent mapping - // (which is wrong, and we may miss some keys, especially on non-US - // keyboards), but it's better than nothing... - case XK_a: return GLFW_KEY_A; - case XK_b: return GLFW_KEY_B; - case XK_c: return GLFW_KEY_C; - case XK_d: return GLFW_KEY_D; - case XK_e: return GLFW_KEY_E; - case XK_f: return GLFW_KEY_F; - case XK_g: return GLFW_KEY_G; - case XK_h: return GLFW_KEY_H; - case XK_i: return GLFW_KEY_I; - case XK_j: return GLFW_KEY_J; - case XK_k: return GLFW_KEY_K; - case XK_l: return GLFW_KEY_L; - case XK_m: return GLFW_KEY_M; - case XK_n: return GLFW_KEY_N; - case XK_o: return GLFW_KEY_O; - case XK_p: return GLFW_KEY_P; - case XK_q: return GLFW_KEY_Q; - case XK_r: return GLFW_KEY_R; - case XK_s: return GLFW_KEY_S; - case XK_t: return GLFW_KEY_T; - case XK_u: return GLFW_KEY_U; - case XK_v: return GLFW_KEY_V; - case XK_w: return GLFW_KEY_W; - case XK_x: return GLFW_KEY_X; - case XK_y: return GLFW_KEY_Y; - case XK_z: return GLFW_KEY_Z; - case XK_1: return GLFW_KEY_1; - case XK_2: return GLFW_KEY_2; - case XK_3: return GLFW_KEY_3; - case XK_4: return GLFW_KEY_4; - case XK_5: return GLFW_KEY_5; - case XK_6: return GLFW_KEY_6; - case XK_7: return GLFW_KEY_7; - case XK_8: return GLFW_KEY_8; - case XK_9: return GLFW_KEY_9; - case XK_0: return GLFW_KEY_0; - case XK_space: return GLFW_KEY_SPACE; - case XK_minus: return GLFW_KEY_MINUS; - case XK_equal: return GLFW_KEY_EQUAL; - case XK_bracketleft: return GLFW_KEY_LEFT_BRACKET; - case XK_bracketright: return GLFW_KEY_RIGHT_BRACKET; - case XK_backslash: return GLFW_KEY_BACKSLASH; - case XK_semicolon: return GLFW_KEY_SEMICOLON; - case XK_apostrophe: return GLFW_KEY_APOSTROPHE; - case XK_grave: return GLFW_KEY_GRAVE_ACCENT; - case XK_comma: return GLFW_KEY_COMMA; - case XK_period: return GLFW_KEY_PERIOD; - case XK_slash: return GLFW_KEY_SLASH; - case XK_less: return GLFW_KEY_WORLD_1; // At least in some layouts... - default: break; - } - - // No matching translation was found - return GLFW_KEY_UNKNOWN; -} - -// Create key code translation tables -// -static void createKeyTables(void) -{ - int scancode, key; - - memset(_glfw.x11.publicKeys, -1, sizeof(_glfw.x11.publicKeys)); - - if (_glfw.x11.xkb.available) - { - // Use XKB to determine physical key locations independently of the current - // keyboard layout - - char name[XkbKeyNameLength + 1]; - XkbDescPtr descr = XkbGetKeyboard(_glfw.x11.display, - XkbAllComponentsMask, - XkbUseCoreKbd); - - // Find the X11 key code -> GLFW key code mapping - for (scancode = descr->min_key_code; scancode <= descr->max_key_code; scancode++) - { - memcpy(name, descr->names->keys[scancode].name, XkbKeyNameLength); - name[XkbKeyNameLength] = 0; - - // Map the key name to a GLFW key code. Note: We only map printable - // keys here, and we use the US keyboard layout. The rest of the - // keys (function keys) are mapped using traditional KeySym - // translations. - if (strcmp(name, "TLDE") == 0) key = GLFW_KEY_GRAVE_ACCENT; - else if (strcmp(name, "AE01") == 0) key = GLFW_KEY_1; - else if (strcmp(name, "AE02") == 0) key = GLFW_KEY_2; - else if (strcmp(name, "AE03") == 0) key = GLFW_KEY_3; - else if (strcmp(name, "AE04") == 0) key = GLFW_KEY_4; - else if (strcmp(name, "AE05") == 0) key = GLFW_KEY_5; - else if (strcmp(name, "AE06") == 0) key = GLFW_KEY_6; - else if (strcmp(name, "AE07") == 0) key = GLFW_KEY_7; - else if (strcmp(name, "AE08") == 0) key = GLFW_KEY_8; - else if (strcmp(name, "AE09") == 0) key = GLFW_KEY_9; - else if (strcmp(name, "AE10") == 0) key = GLFW_KEY_0; - else if (strcmp(name, "AE11") == 0) key = GLFW_KEY_MINUS; - else if (strcmp(name, "AE12") == 0) key = GLFW_KEY_EQUAL; - else if (strcmp(name, "AD01") == 0) key = GLFW_KEY_Q; - else if (strcmp(name, "AD02") == 0) key = GLFW_KEY_W; - else if (strcmp(name, "AD03") == 0) key = GLFW_KEY_E; - else if (strcmp(name, "AD04") == 0) key = GLFW_KEY_R; - else if (strcmp(name, "AD05") == 0) key = GLFW_KEY_T; - else if (strcmp(name, "AD06") == 0) key = GLFW_KEY_Y; - else if (strcmp(name, "AD07") == 0) key = GLFW_KEY_U; - else if (strcmp(name, "AD08") == 0) key = GLFW_KEY_I; - else if (strcmp(name, "AD09") == 0) key = GLFW_KEY_O; - else if (strcmp(name, "AD10") == 0) key = GLFW_KEY_P; - else if (strcmp(name, "AD11") == 0) key = GLFW_KEY_LEFT_BRACKET; - else if (strcmp(name, "AD12") == 0) key = GLFW_KEY_RIGHT_BRACKET; - else if (strcmp(name, "AC01") == 0) key = GLFW_KEY_A; - else if (strcmp(name, "AC02") == 0) key = GLFW_KEY_S; - else if (strcmp(name, "AC03") == 0) key = GLFW_KEY_D; - else if (strcmp(name, "AC04") == 0) key = GLFW_KEY_F; - else if (strcmp(name, "AC05") == 0) key = GLFW_KEY_G; - else if (strcmp(name, "AC06") == 0) key = GLFW_KEY_H; - else if (strcmp(name, "AC07") == 0) key = GLFW_KEY_J; - else if (strcmp(name, "AC08") == 0) key = GLFW_KEY_K; - else if (strcmp(name, "AC09") == 0) key = GLFW_KEY_L; - else if (strcmp(name, "AC10") == 0) key = GLFW_KEY_SEMICOLON; - else if (strcmp(name, "AC11") == 0) key = GLFW_KEY_APOSTROPHE; - else if (strcmp(name, "AB01") == 0) key = GLFW_KEY_Z; - else if (strcmp(name, "AB02") == 0) key = GLFW_KEY_X; - else if (strcmp(name, "AB03") == 0) key = GLFW_KEY_C; - else if (strcmp(name, "AB04") == 0) key = GLFW_KEY_V; - else if (strcmp(name, "AB05") == 0) key = GLFW_KEY_B; - else if (strcmp(name, "AB06") == 0) key = GLFW_KEY_N; - else if (strcmp(name, "AB07") == 0) key = GLFW_KEY_M; - else if (strcmp(name, "AB08") == 0) key = GLFW_KEY_COMMA; - else if (strcmp(name, "AB09") == 0) key = GLFW_KEY_PERIOD; - else if (strcmp(name, "AB10") == 0) key = GLFW_KEY_SLASH; - else if (strcmp(name, "BKSL") == 0) key = GLFW_KEY_BACKSLASH; - else if (strcmp(name, "LSGT") == 0) key = GLFW_KEY_WORLD_1; - else key = GLFW_KEY_UNKNOWN; - - if ((scancode >= 0) && (scancode < 256)) - _glfw.x11.publicKeys[scancode] = key; - } - - XkbFreeKeyboard(descr, 0, True); - } - - // Translate the un-translated key codes using traditional X11 KeySym - // lookups - for (scancode = 0; scancode < 256; scancode++) - { - if (_glfw.x11.publicKeys[scancode] < 0) - _glfw.x11.publicKeys[scancode] = translateKey(scancode); - } -} - -// Check whether the IM has a usable style -// -static GLboolean hasUsableInputMethodStyle(void) -{ - unsigned int i; - GLboolean found = GL_FALSE; - XIMStyles* styles = NULL; - - if (XGetIMValues(_glfw.x11.im, XNQueryInputStyle, &styles, NULL) != NULL) - return GL_FALSE; - - for (i = 0; i < styles->count_styles; i++) - { - if (styles->supported_styles[i] == (XIMPreeditNothing | XIMStatusNothing)) - { - found = GL_TRUE; - break; - } - } - - XFree(styles); - return found; -} - -// Check whether the specified atom is supported -// -static Atom getSupportedAtom(Atom* supportedAtoms, - unsigned long atomCount, - const char* atomName) -{ - Atom atom = XInternAtom(_glfw.x11.display, atomName, True); - if (atom != None) - { - unsigned long i; - - for (i = 0; i < atomCount; i++) - { - if (supportedAtoms[i] == atom) - return atom; - } - } - - return None; -} - -// Check whether the running window manager is EWMH-compliant -// -static void detectEWMH(void) -{ - Window* windowFromRoot = NULL; - Window* windowFromChild = NULL; - - // First we need a couple of atoms, which should already be there - Atom supportingWmCheck = - XInternAtom(_glfw.x11.display, "_NET_SUPPORTING_WM_CHECK", True); - Atom wmSupported = - XInternAtom(_glfw.x11.display, "_NET_SUPPORTED", True); - if (supportingWmCheck == None || wmSupported == None) - return; - - // Then we look for the _NET_SUPPORTING_WM_CHECK property of the root window - if (_glfwGetWindowProperty(_glfw.x11.root, - supportingWmCheck, - XA_WINDOW, - (unsigned char**) &windowFromRoot) != 1) - { - if (windowFromRoot) - XFree(windowFromRoot); - return; - } - - _glfwGrabXErrorHandler(); - - // It should be the ID of a child window (of the root) - // Then we look for the same property on the child window - if (_glfwGetWindowProperty(*windowFromRoot, - supportingWmCheck, - XA_WINDOW, - (unsigned char**) &windowFromChild) != 1) - { - XFree(windowFromRoot); - if (windowFromChild) - XFree(windowFromChild); - return; - } - - _glfwReleaseXErrorHandler(); - - // It should be the ID of that same child window - if (*windowFromRoot != *windowFromChild) - { - XFree(windowFromRoot); - XFree(windowFromChild); - return; - } - - XFree(windowFromRoot); - XFree(windowFromChild); - - // We are now fairly sure that an EWMH-compliant window manager is running - - Atom* supportedAtoms; - unsigned long atomCount; - - // Now we need to check the _NET_SUPPORTED property of the root window - // It should be a list of supported WM protocol and state atoms - atomCount = _glfwGetWindowProperty(_glfw.x11.root, - wmSupported, - XA_ATOM, - (unsigned char**) &supportedAtoms); - - // See which of the atoms we support that are supported by the WM - _glfw.x11.NET_WM_STATE = - getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE"); - _glfw.x11.NET_WM_STATE_ABOVE = - getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_ABOVE"); - _glfw.x11.NET_WM_STATE_FULLSCREEN = - getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_FULLSCREEN"); - _glfw.x11.NET_WM_FULLSCREEN_MONITORS = - getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_FULLSCREEN_MONITORS"); - _glfw.x11.NET_WM_NAME = - getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_NAME"); - _glfw.x11.NET_WM_ICON_NAME = - getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_ICON_NAME"); - _glfw.x11.NET_WM_PID = - getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_PID"); - _glfw.x11.NET_WM_PING = - getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_PING"); - _glfw.x11.NET_ACTIVE_WINDOW = - getSupportedAtom(supportedAtoms, atomCount, "_NET_ACTIVE_WINDOW"); - _glfw.x11.NET_FRAME_EXTENTS = - getSupportedAtom(supportedAtoms, atomCount, "_NET_FRAME_EXTENTS"); - _glfw.x11.NET_REQUEST_FRAME_EXTENTS = - getSupportedAtom(supportedAtoms, atomCount, "_NET_REQUEST_FRAME_EXTENTS"); - _glfw.x11.NET_WM_BYPASS_COMPOSITOR = - getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_BYPASS_COMPOSITOR"); - - XFree(supportedAtoms); - - _glfw.x11.hasEWMH = GL_TRUE; -} - -// Initialize X11 display and look for supported X11 extensions -// -static GLboolean initExtensions(void) -{ - // Find or create window manager atoms - _glfw.x11.WM_PROTOCOLS = XInternAtom(_glfw.x11.display, - "WM_PROTOCOLS", - False); - _glfw.x11.WM_STATE = XInternAtom(_glfw.x11.display, "WM_STATE", False); - _glfw.x11.WM_DELETE_WINDOW = XInternAtom(_glfw.x11.display, - "WM_DELETE_WINDOW", - False); - _glfw.x11.MOTIF_WM_HINTS = XInternAtom(_glfw.x11.display, - "_MOTIF_WM_HINTS", - False); - - // Check for XF86VidMode extension - _glfw.x11.vidmode.available = - XF86VidModeQueryExtension(_glfw.x11.display, - &_glfw.x11.vidmode.eventBase, - &_glfw.x11.vidmode.errorBase); - - // Check for RandR extension - _glfw.x11.randr.available = - XRRQueryExtension(_glfw.x11.display, - &_glfw.x11.randr.eventBase, - &_glfw.x11.randr.errorBase); - - if (_glfw.x11.randr.available) - { - XRRScreenResources* sr; - - if (!XRRQueryVersion(_glfw.x11.display, - &_glfw.x11.randr.versionMajor, - &_glfw.x11.randr.versionMinor)) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "X11: Failed to query RandR version"); - return GL_FALSE; - } - - // The GLFW RandR path requires at least version 1.3 - if (_glfw.x11.randr.versionMajor == 1 && - _glfw.x11.randr.versionMinor < 3) - { - _glfw.x11.randr.available = GL_FALSE; - } - - sr = XRRGetScreenResources(_glfw.x11.display, _glfw.x11.root); - - if (!sr->ncrtc || !XRRGetCrtcGammaSize(_glfw.x11.display, sr->crtcs[0])) - { - // This is either a headless system or an older Nvidia binary driver - // with broken gamma support - // Flag it as useless and fall back to Xf86VidMode gamma, if - // available - _glfwInputError(GLFW_PLATFORM_ERROR, - "X11: RandR gamma ramp support seems broken"); - _glfw.x11.randr.gammaBroken = GL_TRUE; - } - - XRRFreeScreenResources(sr); - } - - if (XineramaQueryExtension(_glfw.x11.display, - &_glfw.x11.xinerama.versionMajor, - &_glfw.x11.xinerama.versionMinor)) - { - if (XineramaIsActive(_glfw.x11.display)) - _glfw.x11.xinerama.available = GL_TRUE; - } - - if (XQueryExtension(_glfw.x11.display, - "XInputExtension", - &_glfw.x11.xi.majorOpcode, - &_glfw.x11.xi.eventBase, - &_glfw.x11.xi.errorBase)) - { - _glfw.x11.xi.versionMajor = 2; - _glfw.x11.xi.versionMinor = 0; - - if (XIQueryVersion(_glfw.x11.display, - &_glfw.x11.xi.versionMajor, - &_glfw.x11.xi.versionMinor) != BadRequest) - { - _glfw.x11.xi.available = GL_TRUE; - } - } - - // Check if Xkb is supported on this display - _glfw.x11.xkb.versionMajor = 1; - _glfw.x11.xkb.versionMinor = 0; - _glfw.x11.xkb.available = - XkbQueryExtension(_glfw.x11.display, - &_glfw.x11.xkb.majorOpcode, - &_glfw.x11.xkb.eventBase, - &_glfw.x11.xkb.errorBase, - &_glfw.x11.xkb.versionMajor, - &_glfw.x11.xkb.versionMinor); - - if (_glfw.x11.xkb.available) - { - Bool supported; - - if (XkbSetDetectableAutoRepeat(_glfw.x11.display, True, &supported)) - { - if (supported) - _glfw.x11.xkb.detectable = GL_TRUE; - } - } - - // Update the key code LUT - // FIXME: We should listen to XkbMapNotify events to track changes to - // the keyboard mapping. - createKeyTables(); - - // Detect whether an EWMH-conformant window manager is running - detectEWMH(); - - // Find or create string format atoms - _glfw.x11._NULL = XInternAtom(_glfw.x11.display, "NULL", False); - _glfw.x11.UTF8_STRING = - XInternAtom(_glfw.x11.display, "UTF8_STRING", False); - _glfw.x11.COMPOUND_STRING = - XInternAtom(_glfw.x11.display, "COMPOUND_STRING", False); - _glfw.x11.ATOM_PAIR = XInternAtom(_glfw.x11.display, "ATOM_PAIR", False); - - // Find or create selection property atom - _glfw.x11.GLFW_SELECTION = - XInternAtom(_glfw.x11.display, "GLFW_SELECTION", False); - - // Find or create standard clipboard atoms - _glfw.x11.TARGETS = XInternAtom(_glfw.x11.display, "TARGETS", False); - _glfw.x11.MULTIPLE = XInternAtom(_glfw.x11.display, "MULTIPLE", False); - _glfw.x11.CLIPBOARD = XInternAtom(_glfw.x11.display, "CLIPBOARD", False); - - // Find or create clipboard manager atoms - _glfw.x11.CLIPBOARD_MANAGER = - XInternAtom(_glfw.x11.display, "CLIPBOARD_MANAGER", False); - _glfw.x11.SAVE_TARGETS = - XInternAtom(_glfw.x11.display, "SAVE_TARGETS", False); - - // Find Xdnd (drag and drop) atoms, if available - _glfw.x11.XdndAware = XInternAtom(_glfw.x11.display, "XdndAware", True); - _glfw.x11.XdndEnter = XInternAtom(_glfw.x11.display, "XdndEnter", True); - _glfw.x11.XdndPosition = XInternAtom(_glfw.x11.display, "XdndPosition", True); - _glfw.x11.XdndStatus = XInternAtom(_glfw.x11.display, "XdndStatus", True); - _glfw.x11.XdndActionCopy = XInternAtom(_glfw.x11.display, "XdndActionCopy", True); - _glfw.x11.XdndDrop = XInternAtom(_glfw.x11.display, "XdndDrop", True); - _glfw.x11.XdndLeave = XInternAtom(_glfw.x11.display, "XdndLeave", True); - _glfw.x11.XdndFinished = XInternAtom(_glfw.x11.display, "XdndFinished", True); - _glfw.x11.XdndSelection = XInternAtom(_glfw.x11.display, "XdndSelection", True); - - return GL_TRUE; -} - -// Create a blank cursor for hidden and disabled cursor modes -// -static Cursor createNULLCursor(void) -{ - unsigned char pixels[16 * 16 * 4]; - GLFWimage image = { 16, 16, pixels }; - - memset(pixels, 0, sizeof(pixels)); - - return _glfwCreateCursor(&image, 0, 0); -} - -// X error handler -// -static int errorHandler(Display *display, XErrorEvent* event) -{ - _glfw.x11.errorCode = event->error_code; - return 0; -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW internal API ////// -////////////////////////////////////////////////////////////////////////// - -// Sets the X error handler callback -// -void _glfwGrabXErrorHandler(void) -{ - _glfw.x11.errorCode = Success; - XSetErrorHandler(errorHandler); -} - -// Clears the X error handler callback -// -void _glfwReleaseXErrorHandler(void) -{ - // Synchronize to make sure all commands are processed - XSync(_glfw.x11.display, False); - XSetErrorHandler(NULL); -} - -// Reports the specified error, appending information about the last X error -// -void _glfwInputXError(int error, const char* message) -{ - char buffer[8192]; - XGetErrorText(_glfw.x11.display, _glfw.x11.errorCode, - buffer, sizeof(buffer)); - - _glfwInputError(error, "%s: %s", message, buffer); -} - -// Creates a native cursor object from the specified image and hotspot -// -Cursor _glfwCreateCursor(const GLFWimage* image, int xhot, int yhot) -{ - int i; - Cursor cursor; - - XcursorImage* native = XcursorImageCreate(image->width, image->height); - if (native == NULL) - return None; - - native->xhot = xhot; - native->yhot = yhot; - - unsigned char* source = (unsigned char*) image->pixels; - XcursorPixel* target = native->pixels; - - for (i = 0; i < image->width * image->height; i++, target++, source += 4) - { - *target = (source[3] << 24) | - (source[0] << 16) | - (source[1] << 8) | - source[2]; - } - - cursor = XcursorImageLoadCursor(_glfw.x11.display, native); - XcursorImageDestroy(native); - - return cursor; -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW platform API ////// -////////////////////////////////////////////////////////////////////////// - -int _glfwPlatformInit(void) -{ - if (strcmp(setlocale(LC_CTYPE, NULL), "C") == 0) - setlocale(LC_CTYPE, ""); - - XInitThreads(); - - _glfw.x11.display = XOpenDisplay(NULL); - if (!_glfw.x11.display) - { - _glfwInputError(GLFW_API_UNAVAILABLE, "X11: Failed to open X display"); - return GL_FALSE; - } - - _glfw.x11.screen = DefaultScreen(_glfw.x11.display); - _glfw.x11.root = RootWindow(_glfw.x11.display, _glfw.x11.screen); - _glfw.x11.context = XUniqueContext(); - - if (!initExtensions()) - return GL_FALSE; - - _glfw.x11.cursor = createNULLCursor(); - - if (XSupportsLocale()) - { - XSetLocaleModifiers(""); - - _glfw.x11.im = XOpenIM(_glfw.x11.display, 0, 0, 0); - if (_glfw.x11.im) - { - if (!hasUsableInputMethodStyle()) - { - XCloseIM(_glfw.x11.im); - _glfw.x11.im = NULL; - } - } - } - - if (!_glfwInitContextAPI()) - return GL_FALSE; - - if (!_glfwInitJoysticks()) - return GL_FALSE; - - _glfwInitTimer(); - - return GL_TRUE; -} - -void _glfwPlatformTerminate(void) -{ - if (_glfw.x11.cursor) - { - XFreeCursor(_glfw.x11.display, _glfw.x11.cursor); - _glfw.x11.cursor = (Cursor) 0; - } - - free(_glfw.x11.clipboardString); - - if (_glfw.x11.im) - { - XCloseIM(_glfw.x11.im); - _glfw.x11.im = NULL; - } - - _glfwTerminateJoysticks(); - _glfwTerminateContextAPI(); - - if (_glfw.x11.display) - { - XCloseDisplay(_glfw.x11.display); - _glfw.x11.display = NULL; - } -} - -const char* _glfwPlatformGetVersionString(void) -{ - const char* version = _GLFW_VERSION_NUMBER " X11" -#if defined(_GLFW_GLX) - " GLX" -#elif defined(_GLFW_EGL) - " EGL" -#endif -#if defined(_GLFW_HAS_GLXGETPROCADDRESS) - " glXGetProcAddress" -#elif defined(_GLFW_HAS_GLXGETPROCADDRESSARB) - " glXGetProcAddressARB" -#elif defined(_GLFW_HAS_GLXGETPROCADDRESSEXT) - " glXGetProcAddressEXT" -#elif defined(_GLFW_DLOPEN_LIBGL) - " dlsym(libGL)" -#endif -#if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK) - " clock_gettime" -#endif -#if defined(__linux__) - " /dev/js" -#endif -#if defined(_GLFW_BUILD_DLL) - " shared" -#endif - ; - - return version; -} - diff --git a/examples/common/glfw/src/x11_monitor.c b/examples/common/glfw/src/x11_monitor.c deleted file mode 100644 index 6265070f..00000000 --- a/examples/common/glfw/src/x11_monitor.c +++ /dev/null @@ -1,490 +0,0 @@ -//======================================================================== -// GLFW 3.1 X11 - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2002-2006 Marcus Geelnard -// Copyright (c) 2006-2010 Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#include "internal.h" - -#include -#include -#include - - -// Check whether the display mode should be included in enumeration -// -static GLboolean modeIsGood(const XRRModeInfo* mi) -{ - return (mi->modeFlags & RR_Interlace) == 0; -} - -// Calculates the refresh rate, in Hz, from the specified RandR mode info -// -static int calculateRefreshRate(const XRRModeInfo* mi) -{ - if (mi->hTotal && mi->vTotal) - return (int) ((double) mi->dotClock / ((double) mi->hTotal * (double) mi->vTotal)); - else - return 0; -} - -// Returns the mode info for a RandR mode XID -// -static const XRRModeInfo* getModeInfo(const XRRScreenResources* sr, RRMode id) -{ - int i; - - for (i = 0; i < sr->nmode; i++) - { - if (sr->modes[i].id == id) - return sr->modes + i; - } - - return NULL; -} - -// Convert RandR mode info to GLFW video mode -// -static GLFWvidmode vidmodeFromModeInfo(const XRRModeInfo* mi, - const XRRCrtcInfo* ci) -{ - GLFWvidmode mode; - - if (ci->rotation == RR_Rotate_90 || ci->rotation == RR_Rotate_270) - { - mode.width = mi->height; - mode.height = mi->width; - } - else - { - mode.width = mi->width; - mode.height = mi->height; - } - - mode.refreshRate = calculateRefreshRate(mi); - - _glfwSplitBPP(DefaultDepth(_glfw.x11.display, _glfw.x11.screen), - &mode.redBits, &mode.greenBits, &mode.blueBits); - - return mode; -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW internal API ////// -////////////////////////////////////////////////////////////////////////// - -// Set the current video mode for the specified monitor -// -GLboolean _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired) -{ - if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken) - { - XRRScreenResources* sr; - XRRCrtcInfo* ci; - XRROutputInfo* oi; - GLFWvidmode current; - const GLFWvidmode* best; - RRMode native = None; - int i; - - best = _glfwChooseVideoMode(monitor, desired); - _glfwPlatformGetVideoMode(monitor, ¤t); - if (_glfwCompareVideoModes(¤t, best) == 0) - return GL_TRUE; - - sr = XRRGetScreenResources(_glfw.x11.display, _glfw.x11.root); - ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc); - oi = XRRGetOutputInfo(_glfw.x11.display, sr, monitor->x11.output); - - for (i = 0; i < oi->nmode; i++) - { - const XRRModeInfo* mi = getModeInfo(sr, oi->modes[i]); - if (!modeIsGood(mi)) - continue; - - const GLFWvidmode mode = vidmodeFromModeInfo(mi, ci); - if (_glfwCompareVideoModes(best, &mode) == 0) - { - native = mi->id; - break; - } - } - - if (native) - { - if (monitor->x11.oldMode == None) - monitor->x11.oldMode = ci->mode; - - XRRSetCrtcConfig(_glfw.x11.display, - sr, monitor->x11.crtc, - CurrentTime, - ci->x, ci->y, - native, - ci->rotation, - ci->outputs, - ci->noutput); - } - - XRRFreeOutputInfo(oi); - XRRFreeCrtcInfo(ci); - XRRFreeScreenResources(sr); - - if (!native) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "X11: Monitor mode list changed"); - return GL_FALSE; - } - } - - return GL_TRUE; -} - -// Restore the saved (original) video mode for the specified monitor -// -void _glfwRestoreVideoMode(_GLFWmonitor* monitor) -{ - if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken) - { - XRRScreenResources* sr; - XRRCrtcInfo* ci; - - if (monitor->x11.oldMode == None) - return; - - sr = XRRGetScreenResources(_glfw.x11.display, _glfw.x11.root); - ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc); - - XRRSetCrtcConfig(_glfw.x11.display, - sr, monitor->x11.crtc, - CurrentTime, - ci->x, ci->y, - monitor->x11.oldMode, - ci->rotation, - ci->outputs, - ci->noutput); - - XRRFreeCrtcInfo(ci); - XRRFreeScreenResources(sr); - - monitor->x11.oldMode = None; - } -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW platform API ////// -////////////////////////////////////////////////////////////////////////// - -_GLFWmonitor** _glfwPlatformGetMonitors(int* count) -{ - int i, j, k, size = 0, found = 0; - _GLFWmonitor** monitors = NULL; - - *count = 0; - - if (_glfw.x11.randr.available) - { - int screenCount = 0; - XineramaScreenInfo* screens = NULL; - XRRScreenResources* sr = XRRGetScreenResources(_glfw.x11.display, - _glfw.x11.root); - RROutput primary = XRRGetOutputPrimary(_glfw.x11.display, - _glfw.x11.root); - - if (_glfw.x11.xinerama.available) - screens = XineramaQueryScreens(_glfw.x11.display, &screenCount); - - for (i = 0; i < sr->ncrtc; i++) - { - XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, - sr, sr->crtcs[i]); - - for (j = 0; j < ci->noutput; j++) - { - int widthMM, heightMM; - XRROutputInfo* oi = XRRGetOutputInfo(_glfw.x11.display, - sr, ci->outputs[j]); - if (oi->connection != RR_Connected) - { - XRRFreeOutputInfo(oi); - continue; - } - - if (found == size) - { - size += 4; - monitors = realloc(monitors, sizeof(_GLFWmonitor*) * size); - } - - if (ci->rotation == RR_Rotate_90 || ci->rotation == RR_Rotate_270) - { - widthMM = oi->mm_height; - heightMM = oi->mm_width; - } - else - { - widthMM = oi->mm_width; - heightMM = oi->mm_height; - } - - monitors[found] = _glfwAllocMonitor(oi->name, widthMM, heightMM); - monitors[found]->x11.output = ci->outputs[j]; - monitors[found]->x11.crtc = oi->crtc; - - for (k = 0; k < screenCount; k++) - { - if (screens[k].x_org == ci->x && - screens[k].y_org == ci->y && - screens[k].width == ci->width && - screens[k].height == ci->height) - { - monitors[found]->x11.index = k; - break; - } - } - - XRRFreeOutputInfo(oi); - - if (ci->outputs[j] == primary) - _GLFW_SWAP_POINTERS(monitors[0], monitors[found]); - - found++; - } - - XRRFreeCrtcInfo(ci); - } - - XRRFreeScreenResources(sr); - - if (screens) - XFree(screens); - - if (found == 0) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "X11: RandR monitor support seems broken"); - _glfw.x11.randr.monitorBroken = GL_TRUE; - } - } - - if (!monitors) - { - monitors = calloc(1, sizeof(_GLFWmonitor*)); - monitors[0] = _glfwAllocMonitor("Display", - DisplayWidthMM(_glfw.x11.display, - _glfw.x11.screen), - DisplayHeightMM(_glfw.x11.display, - _glfw.x11.screen)); - found = 1; - } - - *count = found; - return monitors; -} - -GLboolean _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second) -{ - return first->x11.crtc == second->x11.crtc; -} - -void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos) -{ - if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken) - { - XRRScreenResources* sr; - XRRCrtcInfo* ci; - - sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root); - ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc); - - if (xpos) - *xpos = ci->x; - if (ypos) - *ypos = ci->y; - - XRRFreeCrtcInfo(ci); - XRRFreeScreenResources(sr); - } -} - -GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found) -{ - GLFWvidmode* result; - - *found = 0; - - // Build array of available resolutions - - if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken) - { - int i, j; - XRRScreenResources* sr; - XRRCrtcInfo* ci; - XRROutputInfo* oi; - - sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root); - ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc); - oi = XRRGetOutputInfo(_glfw.x11.display, sr, monitor->x11.output); - - result = calloc(oi->nmode, sizeof(GLFWvidmode)); - - for (i = 0; i < oi->nmode; i++) - { - const XRRModeInfo* mi = getModeInfo(sr, oi->modes[i]); - if (!modeIsGood(mi)) - continue; - - const GLFWvidmode mode = vidmodeFromModeInfo(mi, ci); - - for (j = 0; j < *found; j++) - { - if (_glfwCompareVideoModes(result + j, &mode) == 0) - break; - } - - if (j < *found) - { - // This is a duplicate, so skip it - continue; - } - - result[*found] = mode; - (*found)++; - } - - XRRFreeOutputInfo(oi); - XRRFreeCrtcInfo(ci); - XRRFreeScreenResources(sr); - } - else - { - *found = 1; - result = calloc(1, sizeof(GLFWvidmode)); - _glfwPlatformGetVideoMode(monitor, result); - } - - return result; -} - -void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) -{ - if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken) - { - XRRScreenResources* sr; - XRRCrtcInfo* ci; - - sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root); - ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc); - - *mode = vidmodeFromModeInfo(getModeInfo(sr, ci->mode), ci); - - XRRFreeCrtcInfo(ci); - XRRFreeScreenResources(sr); - } - else - { - mode->width = DisplayWidth(_glfw.x11.display, _glfw.x11.screen); - mode->height = DisplayHeight(_glfw.x11.display, _glfw.x11.screen); - mode->refreshRate = 0; - - _glfwSplitBPP(DefaultDepth(_glfw.x11.display, _glfw.x11.screen), - &mode->redBits, &mode->greenBits, &mode->blueBits); - } -} - -void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) -{ - if (_glfw.x11.randr.available && !_glfw.x11.randr.gammaBroken) - { - const size_t size = XRRGetCrtcGammaSize(_glfw.x11.display, - monitor->x11.crtc); - XRRCrtcGamma* gamma = XRRGetCrtcGamma(_glfw.x11.display, - monitor->x11.crtc); - - _glfwAllocGammaArrays(ramp, size); - - memcpy(ramp->red, gamma->red, size * sizeof(unsigned short)); - memcpy(ramp->green, gamma->green, size * sizeof(unsigned short)); - memcpy(ramp->blue, gamma->blue, size * sizeof(unsigned short)); - - XRRFreeGamma(gamma); - } - else if (_glfw.x11.vidmode.available) - { - int size; - XF86VidModeGetGammaRampSize(_glfw.x11.display, _glfw.x11.screen, &size); - - _glfwAllocGammaArrays(ramp, size); - - XF86VidModeGetGammaRamp(_glfw.x11.display, - _glfw.x11.screen, - ramp->size, ramp->red, ramp->green, ramp->blue); - } -} - -void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) -{ - if (_glfw.x11.randr.available && !_glfw.x11.randr.gammaBroken) - { - XRRCrtcGamma* gamma = XRRAllocGamma(ramp->size); - - memcpy(gamma->red, ramp->red, ramp->size * sizeof(unsigned short)); - memcpy(gamma->green, ramp->green, ramp->size * sizeof(unsigned short)); - memcpy(gamma->blue, ramp->blue, ramp->size * sizeof(unsigned short)); - - XRRSetCrtcGamma(_glfw.x11.display, monitor->x11.crtc, gamma); - XRRFreeGamma(gamma); - } - else if (_glfw.x11.vidmode.available) - { - XF86VidModeSetGammaRamp(_glfw.x11.display, - _glfw.x11.screen, - ramp->size, - (unsigned short*) ramp->red, - (unsigned short*) ramp->green, - (unsigned short*) ramp->blue); - } -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW native API ////// -////////////////////////////////////////////////////////////////////////// - -GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* handle) -{ - _GLFWmonitor* monitor = (_GLFWmonitor*) handle; - _GLFW_REQUIRE_INIT_OR_RETURN(None); - return monitor->x11.crtc; -} - -GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* handle) -{ - _GLFWmonitor* monitor = (_GLFWmonitor*) handle; - _GLFW_REQUIRE_INIT_OR_RETURN(None); - return monitor->x11.output; -} - diff --git a/examples/common/glfw/src/x11_platform.h b/examples/common/glfw/src/x11_platform.h deleted file mode 100644 index 81d1bef1..00000000 --- a/examples/common/glfw/src/x11_platform.h +++ /dev/null @@ -1,259 +0,0 @@ -//======================================================================== -// GLFW 3.1 X11 - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2002-2006 Marcus Geelnard -// Copyright (c) 2006-2010 Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#ifndef _x11_platform_h_ -#define _x11_platform_h_ - -#include -#include -#include - -#include -#include -#include -#include - -// The Xf86VidMode extension provides fallback gamma control -#include - -// The XRandR extension provides mode setting and gamma control -#include - -// The XInput2 extension provides improved input events -#include - -// The Xkb extension provides improved keyboard support -#include - -// The Xinerama extension provides legacy monitor indices -#include - -#include "posix_tls.h" - -#if defined(_GLFW_GLX) - #define _GLFW_X11_CONTEXT_VISUAL window->glx.visual - #include "glx_context.h" -#elif defined(_GLFW_EGL) - #define _GLFW_X11_CONTEXT_VISUAL window->egl.visual - #define _GLFW_EGL_NATIVE_WINDOW window->x11.handle - #define _GLFW_EGL_NATIVE_DISPLAY _glfw.x11.display - #include "egl_context.h" -#else - #error "No supported context creation API selected" -#endif - -#include "posix_time.h" -#include "linux_joystick.h" -#include "xkb_unicode.h" - -#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowX11 x11 -#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryX11 x11 -#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorX11 x11 -#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorX11 x11 - - -// X11-specific per-window data -// -typedef struct _GLFWwindowX11 -{ - Colormap colormap; - Window handle; - XIC ic; - - GLboolean overrideRedirect; - - // Cached position and size used to filter out duplicate events - int width, height; - int xpos, ypos; - - // The last received cursor position, regardless of source - double cursorPosX, cursorPosY; - // The last position the cursor was warped to by GLFW - int warpPosX, warpPosY; - -} _GLFWwindowX11; - - -// X11-specific global data -// -typedef struct _GLFWlibraryX11 -{ - Display* display; - int screen; - Window root; - - // Invisible cursor for hidden cursor mode - Cursor cursor; - // Context for mapping window XIDs to _GLFWwindow pointers - XContext context; - // XIM input method - XIM im; - // True if window manager supports EWMH - GLboolean hasEWMH; - // Most recent error code received by X error handler - int errorCode; - // Clipboard string (while the selection is owned) - char* clipboardString; - // X11 keycode to GLFW key LUT - short int publicKeys[256]; - - // Window manager atoms - Atom WM_PROTOCOLS; - Atom WM_STATE; - Atom WM_DELETE_WINDOW; - Atom NET_WM_NAME; - Atom NET_WM_ICON_NAME; - Atom NET_WM_PID; - Atom NET_WM_PING; - Atom NET_WM_STATE; - Atom NET_WM_STATE_ABOVE; - Atom NET_WM_STATE_FULLSCREEN; - Atom NET_WM_BYPASS_COMPOSITOR; - Atom NET_WM_FULLSCREEN_MONITORS; - Atom NET_ACTIVE_WINDOW; - Atom NET_FRAME_EXTENTS; - Atom NET_REQUEST_FRAME_EXTENTS; - Atom MOTIF_WM_HINTS; - - // Xdnd (drag and drop) atoms - Atom XdndAware; - Atom XdndEnter; - Atom XdndPosition; - Atom XdndStatus; - Atom XdndActionCopy; - Atom XdndDrop; - Atom XdndLeave; - Atom XdndFinished; - Atom XdndSelection; - - // Selection (clipboard) atoms - Atom TARGETS; - Atom MULTIPLE; - Atom CLIPBOARD; - Atom CLIPBOARD_MANAGER; - Atom SAVE_TARGETS; - Atom _NULL; - Atom UTF8_STRING; - Atom COMPOUND_STRING; - Atom ATOM_PAIR; - Atom GLFW_SELECTION; - - struct { - GLboolean available; - int eventBase; - int errorBase; - } vidmode; - - struct { - GLboolean available; - int eventBase; - int errorBase; - int versionMajor; - int versionMinor; - GLboolean gammaBroken; - GLboolean monitorBroken; - } randr; - - struct { - GLboolean available; - GLboolean detectable; - int majorOpcode; - int eventBase; - int errorBase; - int versionMajor; - int versionMinor; - } xkb; - - struct { - GLboolean available; - int majorOpcode; - int eventBase; - int errorBase; - int versionMajor; - int versionMinor; - } xi; - - struct { - int count; - int timeout; - int interval; - int blanking; - int exposure; - } saver; - - struct { - Window source; - } xdnd; - - struct { - GLboolean available; - int versionMajor; - int versionMinor; - } xinerama; - -} _GLFWlibraryX11; - - -// X11-specific per-monitor data -// -typedef struct _GLFWmonitorX11 -{ - RROutput output; - RRCrtc crtc; - RRMode oldMode; - - // Index of corresponding Xinerama screen, - // for EWMH full screen window placement - int index; - -} _GLFWmonitorX11; - - -// X11-specific per-cursor data -// -typedef struct _GLFWcursorX11 -{ - Cursor handle; - -} _GLFWcursorX11; - - -GLboolean _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired); -void _glfwRestoreVideoMode(_GLFWmonitor* monitor); - -Cursor _glfwCreateCursor(const GLFWimage* image, int xhot, int yhot); - -unsigned long _glfwGetWindowProperty(Window window, - Atom property, - Atom type, - unsigned char** value); - -void _glfwGrabXErrorHandler(void); -void _glfwReleaseXErrorHandler(void); -void _glfwInputXError(int error, const char* message); - -#endif // _x11_platform_h_ diff --git a/examples/common/glfw/src/x11_window.c b/examples/common/glfw/src/x11_window.c deleted file mode 100644 index 0380b581..00000000 --- a/examples/common/glfw/src/x11_window.c +++ /dev/null @@ -1,1935 +0,0 @@ -//======================================================================== -// GLFW 3.1 X11 - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2002-2006 Marcus Geelnard -// Copyright (c) 2006-2010 Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#include "internal.h" - -#include - -#include - -#include -#include -#include -#include - -// Action for EWMH client messages -#define _NET_WM_STATE_REMOVE 0 -#define _NET_WM_STATE_ADD 1 -#define _NET_WM_STATE_TOGGLE 2 - -// Additional mouse button names for XButtonEvent -#define Button6 6 -#define Button7 7 - -typedef struct -{ - unsigned long flags; - unsigned long functions; - unsigned long decorations; - long input_mode; - unsigned long status; -} MotifWmHints; - -#define MWM_HINTS_DECORATIONS (1L << 1) - - -// Returns whether the window is iconified -// -static int getWindowState(_GLFWwindow* window) -{ - int result = WithdrawnState; - struct { - CARD32 state; - Window icon; - } *state = NULL; - - if (_glfwGetWindowProperty(window->x11.handle, - _glfw.x11.WM_STATE, - _glfw.x11.WM_STATE, - (unsigned char**) &state) >= 2) - { - result = state->state; - } - - XFree(state); - return result; -} - -// Returns whether the event is a selection event -// -static Bool isFrameExtentsEvent(Display* display, XEvent* event, XPointer pointer) -{ - _GLFWwindow* window = (_GLFWwindow*) pointer; - return event->type == PropertyNotify && - event->xproperty.state == PropertyNewValue && - event->xproperty.window == window->x11.handle && - event->xproperty.atom == _glfw.x11.NET_FRAME_EXTENTS; -} - -// Translates a GLFW standard cursor to a font cursor shape -// -static int translateCursorShape(int shape) -{ - switch (shape) - { - case GLFW_ARROW_CURSOR: - return XC_arrow; - case GLFW_IBEAM_CURSOR: - return XC_xterm; - case GLFW_CROSSHAIR_CURSOR: - return XC_crosshair; - case GLFW_HAND_CURSOR: - return XC_hand1; - case GLFW_HRESIZE_CURSOR: - return XC_sb_h_double_arrow; - case GLFW_VRESIZE_CURSOR: - return XC_sb_v_double_arrow; - } - - return 0; -} - -// Translates an X event modifier state mask -// -static int translateState(int state) -{ - int mods = 0; - - if (state & ShiftMask) - mods |= GLFW_MOD_SHIFT; - if (state & ControlMask) - mods |= GLFW_MOD_CONTROL; - if (state & Mod1Mask) - mods |= GLFW_MOD_ALT; - if (state & Mod4Mask) - mods |= GLFW_MOD_SUPER; - - return mods; -} - -// Translates an X Window key to internal coding -// -static int translateKey(int scancode) -{ - // Use the pre-filled LUT (see createKeyTables() in x11_init.c) - if (scancode < 0 || scancode > 255) - return GLFW_KEY_UNKNOWN; - - return _glfw.x11.publicKeys[scancode]; -} - -// Return the GLFW window corresponding to the specified X11 window -// -static _GLFWwindow* findWindowByHandle(Window handle) -{ - _GLFWwindow* window; - - if (XFindContext(_glfw.x11.display, - handle, - _glfw.x11.context, - (XPointer*) &window) != 0) - { - return NULL; - } - - return window; -} - -// Adds or removes an EWMH state to a window -// -static void changeWindowState(_GLFWwindow* window, Atom state, int action) -{ - XEvent event; - memset(&event, 0, sizeof(event)); - - event.type = ClientMessage; - event.xclient.window = window->x11.handle; - event.xclient.format = 32; // Data is 32-bit longs - event.xclient.message_type = _glfw.x11.NET_WM_STATE; - event.xclient.data.l[0] = action; - event.xclient.data.l[1] = state; - event.xclient.data.l[2] = 0; // No secondary property - event.xclient.data.l[3] = 1; // Sender is a normal application - - XSendEvent(_glfw.x11.display, - _glfw.x11.root, - False, - SubstructureNotifyMask | SubstructureRedirectMask, - &event); -} - -// Splits and translates a text/uri-list into separate file paths -// -static char** parseUriList(char* text, int* count) -{ - const char* prefix = "file://"; - char** names = NULL; - char* line; - - *count = 0; - - while ((line = strtok(text, "\r\n"))) - { - text = NULL; - - if (*line == '#') - continue; - - if (strncmp(line, prefix, strlen(prefix)) == 0) - line += strlen(prefix); - - (*count)++; - - char* name = calloc(strlen(line) + 1, 1); - names = realloc(names, *count * sizeof(char*)); - names[*count - 1] = name; - - while (*line) - { - if (line[0] == '%' && line[1] && line[2]) - { - const char digits[3] = { line[1], line[2], '\0' }; - *name = strtol(digits, NULL, 16); - line += 2; - } - else - *name = *line; - - name++; - line++; - } - } - - return names; -} - -// Create the X11 window (and its colormap) -// -static GLboolean createWindow(_GLFWwindow* window, - const _GLFWwndconfig* wndconfig) -{ - unsigned long wamask; - XSetWindowAttributes wa; - XVisualInfo* visual = _GLFW_X11_CONTEXT_VISUAL; - - // Every window needs a colormap - // Create one based on the visual used by the current context - // TODO: Decouple this from context creation - - window->x11.colormap = XCreateColormap(_glfw.x11.display, - _glfw.x11.root, - visual->visual, - AllocNone); - - // Create the actual window - { - wamask = CWBorderPixel | CWColormap | CWEventMask; - - wa.colormap = window->x11.colormap; - wa.border_pixel = 0; - wa.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask | - PointerMotionMask | ButtonPressMask | ButtonReleaseMask | - ExposureMask | FocusChangeMask | VisibilityChangeMask | - EnterWindowMask | LeaveWindowMask | PropertyChangeMask; - - _glfwGrabXErrorHandler(); - - window->x11.handle = XCreateWindow(_glfw.x11.display, - _glfw.x11.root, - 0, 0, - wndconfig->width, wndconfig->height, - 0, // Border width - visual->depth, // Color depth - InputOutput, - visual->visual, - wamask, - &wa); - - _glfwReleaseXErrorHandler(); - - if (!window->x11.handle) - { - _glfwInputXError(GLFW_PLATFORM_ERROR, - "X11: Failed to create window"); - return GL_FALSE; - } - - if (!wndconfig->decorated) - { - MotifWmHints hints; - hints.flags = MWM_HINTS_DECORATIONS; - hints.decorations = 0; - - XChangeProperty(_glfw.x11.display, window->x11.handle, - _glfw.x11.MOTIF_WM_HINTS, - _glfw.x11.MOTIF_WM_HINTS, 32, - PropModeReplace, - (unsigned char*) &hints, - sizeof(MotifWmHints) / sizeof(long)); - } - - XSaveContext(_glfw.x11.display, - window->x11.handle, - _glfw.x11.context, - (XPointer) window); - } - - if (window->monitor && !_glfw.x11.hasEWMH) - { - // This is the butcher's way of removing window decorations - // Setting the override-redirect attribute on a window makes the window - // manager ignore the window completely (ICCCM, section 4) - // The good thing is that this makes undecorated full screen windows - // easy to do; the bad thing is that we have to do everything manually - // and some things (like iconify/restore) won't work at all, as those - // are tasks usually performed by the window manager - - XSetWindowAttributes attributes; - attributes.override_redirect = True; - XChangeWindowAttributes(_glfw.x11.display, - window->x11.handle, - CWOverrideRedirect, - &attributes); - - window->x11.overrideRedirect = GL_TRUE; - } - - // Declare the WM protocols supported by GLFW - { - int count = 0; - Atom protocols[2]; - - // The WM_DELETE_WINDOW ICCCM protocol - // Basic window close notification protocol - if (_glfw.x11.WM_DELETE_WINDOW) - protocols[count++] = _glfw.x11.WM_DELETE_WINDOW; - - // The _NET_WM_PING EWMH protocol - // Tells the WM to ping the GLFW window and flag the application as - // unresponsive if the WM doesn't get a reply within a few seconds - if (_glfw.x11.NET_WM_PING) - protocols[count++] = _glfw.x11.NET_WM_PING; - - if (count > 0) - { - XSetWMProtocols(_glfw.x11.display, window->x11.handle, - protocols, count); - } - } - - if (_glfw.x11.NET_WM_PID) - { - const pid_t pid = getpid(); - - XChangeProperty(_glfw.x11.display, window->x11.handle, - _glfw.x11.NET_WM_PID, XA_CARDINAL, 32, - PropModeReplace, - (unsigned char*) &pid, 1); - } - - // Set ICCCM WM_HINTS property - { - XWMHints* hints = XAllocWMHints(); - if (!hints) - { - _glfwInputError(GLFW_OUT_OF_MEMORY, - "X11: Failed to allocate WM hints"); - return GL_FALSE; - } - - hints->flags = StateHint; - hints->initial_state = NormalState; - - XSetWMHints(_glfw.x11.display, window->x11.handle, hints); - XFree(hints); - } - - // Set ICCCM WM_NORMAL_HINTS property (even if no parts are set) - { - XSizeHints* hints = XAllocSizeHints(); - hints->flags = 0; - - if (wndconfig->monitor) - { - hints->flags |= PPosition; - _glfwPlatformGetMonitorPos(wndconfig->monitor, &hints->x, &hints->y); - } - else - { - // HACK: Explicitly setting PPosition to any value causes some WMs, - // notably Compiz and Metacity, to honor the position of - // unmapped windows set by XMoveWindow - hints->flags |= PPosition; - hints->x = hints->y = 0; - } - - if (!wndconfig->resizable) - { - hints->flags |= (PMinSize | PMaxSize); - hints->min_width = hints->max_width = wndconfig->width; - hints->min_height = hints->max_height = wndconfig->height; - } - - XSetWMNormalHints(_glfw.x11.display, window->x11.handle, hints); - XFree(hints); - } - - // Set ICCCM WM_CLASS property - // HACK: Until a mechanism for specifying the application name is added, the - // initial window title is used as the window class name - if (strlen(wndconfig->title)) - { - XClassHint* hint = XAllocClassHint(); - hint->res_name = (char*) wndconfig->title; - hint->res_class = (char*) wndconfig->title; - - XSetClassHint(_glfw.x11.display, window->x11.handle, hint); - XFree(hint); - } - - if (_glfw.x11.xi.available) - { - // Select for XInput2 events - - XIEventMask eventmask; - unsigned char mask[] = { 0 }; - - eventmask.deviceid = 2; - eventmask.mask_len = sizeof(mask); - eventmask.mask = mask; - XISetMask(mask, XI_Motion); - - XISelectEvents(_glfw.x11.display, window->x11.handle, &eventmask, 1); - } - - if (_glfw.x11.XdndAware) - { - // Announce support for Xdnd (drag and drop) - const Atom version = 5; - XChangeProperty(_glfw.x11.display, window->x11.handle, - _glfw.x11.XdndAware, XA_ATOM, 32, - PropModeReplace, (unsigned char*) &version, 1); - } - - if (_glfw.x11.NET_REQUEST_FRAME_EXTENTS) - { - // Ensure _NET_FRAME_EXTENTS is set, allowing glfwGetWindowFrameSize to - // function before the window is mapped - - XEvent event; - memset(&event, 0, sizeof(event)); - - event.type = ClientMessage; - event.xclient.window = window->x11.handle; - event.xclient.format = 32; // Data is 32-bit longs - event.xclient.message_type = _glfw.x11.NET_REQUEST_FRAME_EXTENTS; - - XSendEvent(_glfw.x11.display, - _glfw.x11.root, - False, - SubstructureNotifyMask | SubstructureRedirectMask, - &event); - XIfEvent(_glfw.x11.display, &event, isFrameExtentsEvent, (XPointer) window); - } - - if (wndconfig->floating && !wndconfig->monitor) - { - if (_glfw.x11.NET_WM_STATE && _glfw.x11.NET_WM_STATE_ABOVE) - { - changeWindowState(window, - _glfw.x11.NET_WM_STATE_ABOVE, - _NET_WM_STATE_ADD); - } - } - - _glfwPlatformSetWindowTitle(window, wndconfig->title); - - XRRSelectInput(_glfw.x11.display, window->x11.handle, - RRScreenChangeNotifyMask); - - if (_glfw.x11.im) - { - window->x11.ic = XCreateIC(_glfw.x11.im, - XNInputStyle, - XIMPreeditNothing | XIMStatusNothing, - XNClientWindow, - window->x11.handle, - XNFocusWindow, - window->x11.handle, - NULL); - } - - _glfwPlatformGetWindowPos(window, &window->x11.xpos, &window->x11.ypos); - _glfwPlatformGetWindowSize(window, &window->x11.width, &window->x11.height); - - return GL_TRUE; -} - -// Hide the mouse cursor -// -static void hideCursor(_GLFWwindow* window) -{ - XUngrabPointer(_glfw.x11.display, CurrentTime); - XDefineCursor(_glfw.x11.display, window->x11.handle, _glfw.x11.cursor); -} - -// Disable the mouse cursor -// -static void disableCursor(_GLFWwindow* window) -{ - XGrabPointer(_glfw.x11.display, window->x11.handle, True, - ButtonPressMask | ButtonReleaseMask | PointerMotionMask, - GrabModeAsync, GrabModeAsync, - window->x11.handle, _glfw.x11.cursor, CurrentTime); -} - -// Restores the mouse cursor -// -static void restoreCursor(_GLFWwindow* window) -{ - XUngrabPointer(_glfw.x11.display, CurrentTime); - - if (window->cursor) - { - XDefineCursor(_glfw.x11.display, window->x11.handle, - window->cursor->x11.handle); - } - else - XUndefineCursor(_glfw.x11.display, window->x11.handle); -} - -// Returns whether the event is a selection event -// -static Bool isSelectionEvent(Display* display, XEvent* event, XPointer pointer) -{ - return event->type == SelectionRequest || - event->type == SelectionNotify || - event->type == SelectionClear; -} - -// Set the specified property to the selection converted to the requested target -// -static Atom writeTargetToProperty(const XSelectionRequestEvent* request) -{ - int i; - const Atom formats[] = { _glfw.x11.UTF8_STRING, - _glfw.x11.COMPOUND_STRING, - XA_STRING }; - const int formatCount = sizeof(formats) / sizeof(formats[0]); - - if (request->property == None) - { - // The requester is a legacy client (ICCCM section 2.2) - // We don't support legacy clients, so fail here - return None; - } - - if (request->target == _glfw.x11.TARGETS) - { - // The list of supported targets was requested - - const Atom targets[] = { _glfw.x11.TARGETS, - _glfw.x11.MULTIPLE, - _glfw.x11.UTF8_STRING, - _glfw.x11.COMPOUND_STRING, - XA_STRING }; - - XChangeProperty(_glfw.x11.display, - request->requestor, - request->property, - XA_ATOM, - 32, - PropModeReplace, - (unsigned char*) targets, - sizeof(targets) / sizeof(targets[0])); - - return request->property; - } - - if (request->target == _glfw.x11.MULTIPLE) - { - // Multiple conversions were requested - - Atom* targets; - unsigned long i, count; - - count = _glfwGetWindowProperty(request->requestor, - request->property, - _glfw.x11.ATOM_PAIR, - (unsigned char**) &targets); - - for (i = 0; i < count; i += 2) - { - int j; - - for (j = 0; j < formatCount; j++) - { - if (targets[i] == formats[j]) - break; - } - - if (j < formatCount) - { - XChangeProperty(_glfw.x11.display, - request->requestor, - targets[i + 1], - targets[i], - 8, - PropModeReplace, - (unsigned char*) _glfw.x11.clipboardString, - strlen(_glfw.x11.clipboardString)); - } - else - targets[i + 1] = None; - } - - XChangeProperty(_glfw.x11.display, - request->requestor, - request->property, - _glfw.x11.ATOM_PAIR, - 32, - PropModeReplace, - (unsigned char*) targets, - count); - - XFree(targets); - - return request->property; - } - - if (request->target == _glfw.x11.SAVE_TARGETS) - { - // The request is a check whether we support SAVE_TARGETS - // It should be handled as a no-op side effect target - - XChangeProperty(_glfw.x11.display, - request->requestor, - request->property, - _glfw.x11._NULL, - 32, - PropModeReplace, - NULL, - 0); - - return request->property; - } - - // Conversion to a data target was requested - - for (i = 0; i < formatCount; i++) - { - if (request->target == formats[i]) - { - // The requested target is one we support - - XChangeProperty(_glfw.x11.display, - request->requestor, - request->property, - request->target, - 8, - PropModeReplace, - (unsigned char*) _glfw.x11.clipboardString, - strlen(_glfw.x11.clipboardString)); - - return request->property; - } - } - - // The requested target is not supported - - return None; -} - -static void handleSelectionClear(XEvent* event) -{ - free(_glfw.x11.clipboardString); - _glfw.x11.clipboardString = NULL; -} - -static void handleSelectionRequest(XEvent* event) -{ - const XSelectionRequestEvent* request = &event->xselectionrequest; - - XEvent response; - memset(&response, 0, sizeof(response)); - - response.xselection.property = writeTargetToProperty(request); - response.xselection.type = SelectionNotify; - response.xselection.display = request->display; - response.xselection.requestor = request->requestor; - response.xselection.selection = request->selection; - response.xselection.target = request->target; - response.xselection.time = request->time; - - XSendEvent(_glfw.x11.display, request->requestor, False, 0, &response); -} - -static void pushSelectionToManager(_GLFWwindow* window) -{ - XConvertSelection(_glfw.x11.display, - _glfw.x11.CLIPBOARD_MANAGER, - _glfw.x11.SAVE_TARGETS, - None, - window->x11.handle, - CurrentTime); - - for (;;) - { - XEvent event; - - if (!XCheckIfEvent(_glfw.x11.display, &event, isSelectionEvent, NULL)) - continue; - - switch (event.type) - { - case SelectionRequest: - handleSelectionRequest(&event); - break; - - case SelectionClear: - handleSelectionClear(&event); - break; - - case SelectionNotify: - { - if (event.xselection.target == _glfw.x11.SAVE_TARGETS) - { - // This means one of two things; either the selection was - // not owned, which means there is no clipboard manager, or - // the transfer to the clipboard manager has completed - // In either case, it means we are done here - return; - } - - break; - } - } - } -} - -// Enter full screen mode -// -static void enterFullscreenMode(_GLFWwindow* window) -{ - if (_glfw.x11.saver.count == 0) - { - // Remember old screen saver settings - XGetScreenSaver(_glfw.x11.display, - &_glfw.x11.saver.timeout, - &_glfw.x11.saver.interval, - &_glfw.x11.saver.blanking, - &_glfw.x11.saver.exposure); - - // Disable screen saver - XSetScreenSaver(_glfw.x11.display, 0, 0, DontPreferBlanking, - DefaultExposures); - } - - _glfw.x11.saver.count++; - - _glfwSetVideoMode(window->monitor, &window->videoMode); - - if (_glfw.x11.NET_WM_BYPASS_COMPOSITOR) - { - const unsigned long value = 1; - - XChangeProperty(_glfw.x11.display, window->x11.handle, - _glfw.x11.NET_WM_BYPASS_COMPOSITOR, XA_CARDINAL, 32, - PropModeReplace, (unsigned char*) &value, 1); - } - - if (_glfw.x11.xinerama.available && _glfw.x11.NET_WM_FULLSCREEN_MONITORS) - { - XEvent event; - memset(&event, 0, sizeof(event)); - - event.type = ClientMessage; - event.xclient.window = window->x11.handle; - event.xclient.format = 32; // Data is 32-bit longs - event.xclient.message_type = _glfw.x11.NET_WM_FULLSCREEN_MONITORS; - event.xclient.data.l[0] = window->monitor->x11.index; - event.xclient.data.l[1] = window->monitor->x11.index; - event.xclient.data.l[2] = window->monitor->x11.index; - event.xclient.data.l[3] = window->monitor->x11.index; - - XSendEvent(_glfw.x11.display, - _glfw.x11.root, - False, - SubstructureNotifyMask | SubstructureRedirectMask, - &event); - } - - if (_glfw.x11.NET_WM_STATE && _glfw.x11.NET_WM_STATE_FULLSCREEN) - { - int x, y; - _glfwPlatformGetMonitorPos(window->monitor, &x, &y); - _glfwPlatformSetWindowPos(window, x, y); - - if (_glfw.x11.NET_ACTIVE_WINDOW) - { - // Ask the window manager to raise and focus the GLFW window - // Only focused windows with the _NET_WM_STATE_FULLSCREEN state end - // up on top of all other windows ("Stacking order" in EWMH spec) - - XEvent event; - memset(&event, 0, sizeof(event)); - - event.type = ClientMessage; - event.xclient.window = window->x11.handle; - event.xclient.format = 32; // Data is 32-bit longs - event.xclient.message_type = _glfw.x11.NET_ACTIVE_WINDOW; - event.xclient.data.l[0] = 1; // Sender is a normal application - event.xclient.data.l[1] = 0; // We don't really know the timestamp - - XSendEvent(_glfw.x11.display, - _glfw.x11.root, - False, - SubstructureNotifyMask | SubstructureRedirectMask, - &event); - } - - // Ask the window manager to make the GLFW window a full screen window - // Full screen windows are undecorated and, when focused, are kept - // on top of all other windows - - changeWindowState(window, - _glfw.x11.NET_WM_STATE_FULLSCREEN, - _NET_WM_STATE_ADD); - } - else if (window->x11.overrideRedirect) - { - // In override-redirect mode we have divorced ourselves from the - // window manager, so we need to do everything manually - int xpos, ypos; - GLFWvidmode mode; - - _glfwPlatformGetMonitorPos(window->monitor, &xpos, &ypos); - _glfwPlatformGetVideoMode(window->monitor, &mode); - - XRaiseWindow(_glfw.x11.display, window->x11.handle); - XSetInputFocus(_glfw.x11.display, window->x11.handle, - RevertToParent, CurrentTime); - XMoveWindow(_glfw.x11.display, window->x11.handle, xpos, ypos); - XResizeWindow(_glfw.x11.display, window->x11.handle, - mode.width, mode.height); - } -} - -// Leave full screen mode -// -static void leaveFullscreenMode(_GLFWwindow* window) -{ - _glfwRestoreVideoMode(window->monitor); - - _glfw.x11.saver.count--; - - if (_glfw.x11.saver.count == 0) - { - // Restore old screen saver settings - XSetScreenSaver(_glfw.x11.display, - _glfw.x11.saver.timeout, - _glfw.x11.saver.interval, - _glfw.x11.saver.blanking, - _glfw.x11.saver.exposure); - } - - if (_glfw.x11.NET_WM_BYPASS_COMPOSITOR) - { - const unsigned long value = 0; - - XChangeProperty(_glfw.x11.display, window->x11.handle, - _glfw.x11.NET_WM_BYPASS_COMPOSITOR, XA_CARDINAL, 32, - PropModeReplace, (unsigned char*) &value, 1); - } - - if (_glfw.x11.NET_WM_STATE && _glfw.x11.NET_WM_STATE_FULLSCREEN) - { - // Ask the window manager to make the GLFW window a normal window - // Normal windows usually have frames and other decorations - - changeWindowState(window, - _glfw.x11.NET_WM_STATE_FULLSCREEN, - _NET_WM_STATE_REMOVE); - } -} - -// Process the specified X event -// -static void processEvent(XEvent *event) -{ - _GLFWwindow* window = NULL; - - if (event->type != GenericEvent) - { - window = findWindowByHandle(event->xany.window); - if (window == NULL) - { - // This is an event for a window that has already been destroyed - return; - } - } - - switch (event->type) - { - case KeyPress: - { - const int key = translateKey(event->xkey.keycode); - const int mods = translateState(event->xkey.state); - const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT)); - - if (event->xkey.keycode) - _glfwInputKey(window, key, event->xkey.keycode, GLFW_PRESS, mods); - - if (window->x11.ic) - { - // Translate keys to characters with XIM input context - - int i; - Status status; - wchar_t buffer[16]; - - if (XFilterEvent(event, None)) - { - // Discard intermediary (dead key) events for character input - break; - } - - const int count = XwcLookupString(window->x11.ic, - &event->xkey, - buffer, sizeof(buffer), - NULL, &status); - - for (i = 0; i < count; i++) - _glfwInputChar(window, buffer[i], mods, plain); - } - else - { - // Translate keys to characters with fallback lookup table - - KeySym keysym; - XLookupString(&event->xkey, NULL, 0, &keysym, NULL); - - const long character = _glfwKeySym2Unicode(keysym); - if (character != -1) - _glfwInputChar(window, character, mods, plain); - } - - break; - } - - case KeyRelease: - { - const int key = translateKey(event->xkey.keycode); - const int mods = translateState(event->xkey.state); - - if (!_glfw.x11.xkb.detectable) - { - // HACK: Key repeat events will arrive as KeyRelease/KeyPress - // pairs with similar or identical time stamps - // The key repeat logic in _glfwInputKey expects only key - // presses to repeat, so detect and discard release events - if (XEventsQueued(_glfw.x11.display, QueuedAfterReading)) - { - XEvent nextEvent; - XPeekEvent(_glfw.x11.display, &nextEvent); - - if (nextEvent.type == KeyPress && - nextEvent.xkey.window == event->xkey.window && - nextEvent.xkey.keycode == event->xkey.keycode) - { - // HACK: Repeat events sometimes leak through due to - // some sort of time drift, so add an epsilon - // Toshiyuki Takahashi can press a button 16 times - // per second so it's fairly safe to assume that - // no human is pressing the key 50 times per - // second (value is ms) - if ((nextEvent.xkey.time - event->xkey.time) < 20) - { - // This is very likely a server-generated key repeat - // event, so ignore it - break; - } - } - } - } - - _glfwInputKey(window, key, event->xkey.keycode, GLFW_RELEASE, mods); - break; - } - - case ButtonPress: - { - const int mods = translateState(event->xbutton.state); - - if (event->xbutton.button == Button1) - _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS, mods); - else if (event->xbutton.button == Button2) - _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_MIDDLE, GLFW_PRESS, mods); - else if (event->xbutton.button == Button3) - _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS, mods); - - // Modern X provides scroll events as mouse button presses - else if (event->xbutton.button == Button4) - _glfwInputScroll(window, 0.0, 1.0); - else if (event->xbutton.button == Button5) - _glfwInputScroll(window, 0.0, -1.0); - else if (event->xbutton.button == Button6) - _glfwInputScroll(window, 1.0, 0.0); - else if (event->xbutton.button == Button7) - _glfwInputScroll(window, -1.0, 0.0); - - else - { - // Additional buttons after 7 are treated as regular buttons - // We subtract 4 to fill the gap left by scroll input above - _glfwInputMouseClick(window, - event->xbutton.button - 4, - GLFW_PRESS, - mods); - } - - break; - } - - case ButtonRelease: - { - const int mods = translateState(event->xbutton.state); - - if (event->xbutton.button == Button1) - { - _glfwInputMouseClick(window, - GLFW_MOUSE_BUTTON_LEFT, - GLFW_RELEASE, - mods); - } - else if (event->xbutton.button == Button2) - { - _glfwInputMouseClick(window, - GLFW_MOUSE_BUTTON_MIDDLE, - GLFW_RELEASE, - mods); - } - else if (event->xbutton.button == Button3) - { - _glfwInputMouseClick(window, - GLFW_MOUSE_BUTTON_RIGHT, - GLFW_RELEASE, - mods); - } - else if (event->xbutton.button > Button7) - { - // Additional buttons after 7 are treated as regular buttons - // We subtract 4 to fill the gap left by scroll input above - _glfwInputMouseClick(window, - event->xbutton.button - 4, - GLFW_RELEASE, - mods); - } - break; - } - - case EnterNotify: - { - _glfwInputCursorEnter(window, GL_TRUE); - break; - } - - case LeaveNotify: - { - _glfwInputCursorEnter(window, GL_FALSE); - break; - } - - case MotionNotify: - { - const int x = event->xmotion.x; - const int y = event->xmotion.y; - - if (x != window->x11.warpPosX || y != window->x11.warpPosY) - { - // The cursor was moved by something other than GLFW - - if (window->cursorMode == GLFW_CURSOR_DISABLED) - { - if (_glfw.focusedWindow != window) - break; - - _glfwInputCursorMotion(window, - x - window->x11.cursorPosX, - y - window->x11.cursorPosY); - } - else - _glfwInputCursorMotion(window, x, y); - } - - window->x11.cursorPosX = x; - window->x11.cursorPosY = y; - break; - } - - case ConfigureNotify: - { - if (event->xconfigure.width != window->x11.width || - event->xconfigure.height != window->x11.height) - { - _glfwInputFramebufferSize(window, - event->xconfigure.width, - event->xconfigure.height); - - _glfwInputWindowSize(window, - event->xconfigure.width, - event->xconfigure.height); - - window->x11.width = event->xconfigure.width; - window->x11.height = event->xconfigure.height; - } - - if (event->xconfigure.x != window->x11.xpos || - event->xconfigure.y != window->x11.ypos) - { - _glfwInputWindowPos(window, - event->xconfigure.x, - event->xconfigure.y); - - window->x11.xpos = event->xconfigure.x; - window->x11.ypos = event->xconfigure.y; - } - - break; - } - - case ClientMessage: - { - // Custom client message, probably from the window manager - - if (event->xclient.message_type == None) - break; - - if (event->xclient.message_type == _glfw.x11.WM_PROTOCOLS) - { - if (_glfw.x11.WM_DELETE_WINDOW && - (Atom) event->xclient.data.l[0] == _glfw.x11.WM_DELETE_WINDOW) - { - // The window manager was asked to close the window, for example by - // the user pressing a 'close' window decoration button - - _glfwInputWindowCloseRequest(window); - } - else if (_glfw.x11.NET_WM_PING && - (Atom) event->xclient.data.l[0] == _glfw.x11.NET_WM_PING) - { - // The window manager is pinging the application to ensure it's - // still responding to events - - event->xclient.window = _glfw.x11.root; - XSendEvent(_glfw.x11.display, - event->xclient.window, - False, - SubstructureNotifyMask | SubstructureRedirectMask, - event); - } - } - else if (event->xclient.message_type == _glfw.x11.XdndEnter) - { - // A drag operation has entered the window - // TODO: Check if UTF-8 string is supported by the source - } - else if (event->xclient.message_type == _glfw.x11.XdndDrop) - { - // The drag operation has finished dropping on - // the window, ask to convert it to a UTF-8 string - _glfw.x11.xdnd.source = event->xclient.data.l[0]; - XConvertSelection(_glfw.x11.display, - _glfw.x11.XdndSelection, - _glfw.x11.UTF8_STRING, - _glfw.x11.XdndSelection, - window->x11.handle, CurrentTime); - } - else if (event->xclient.message_type == _glfw.x11.XdndPosition) - { - // The drag operation has moved over the window - const int absX = (event->xclient.data.l[2] >> 16) & 0xFFFF; - const int absY = (event->xclient.data.l[2]) & 0xFFFF; - int x, y; - - _glfwPlatformGetWindowPos(window, &x, &y); - _glfwInputCursorMotion(window, absX - x, absY - y); - - // Reply that we are ready to copy the dragged data - XEvent reply; - memset(&reply, 0, sizeof(reply)); - - reply.type = ClientMessage; - reply.xclient.window = event->xclient.data.l[0]; - reply.xclient.message_type = _glfw.x11.XdndStatus; - reply.xclient.format = 32; - reply.xclient.data.l[0] = window->x11.handle; - reply.xclient.data.l[1] = 1; // Always accept the dnd with no rectangle - reply.xclient.data.l[2] = 0; // Specify an empty rectangle - reply.xclient.data.l[3] = 0; - reply.xclient.data.l[4] = _glfw.x11.XdndActionCopy; - - XSendEvent(_glfw.x11.display, event->xclient.data.l[0], - False, NoEventMask, &reply); - XFlush(_glfw.x11.display); - } - - break; - } - - case SelectionNotify: - { - if (event->xselection.property) - { - // The converted data from the drag operation has arrived - char* data; - const int result = - _glfwGetWindowProperty(event->xselection.requestor, - event->xselection.property, - event->xselection.target, - (unsigned char**) &data); - - if (result) - { - int i, count; - char** names = parseUriList(data, &count); - - _glfwInputDrop(window, count, (const char**) names); - - for (i = 0; i < count; i++) - free(names[i]); - free(names); - } - - XFree(data); - - XEvent reply; - memset(&reply, 0, sizeof(reply)); - - reply.type = ClientMessage; - reply.xclient.window = _glfw.x11.xdnd.source; - reply.xclient.message_type = _glfw.x11.XdndFinished; - reply.xclient.format = 32; - reply.xclient.data.l[0] = window->x11.handle; - reply.xclient.data.l[1] = result; - reply.xclient.data.l[2] = _glfw.x11.XdndActionCopy; - - // Reply that all is well - XSendEvent(_glfw.x11.display, _glfw.x11.xdnd.source, - False, NoEventMask, &reply); - XFlush(_glfw.x11.display); - } - - break; - } - - case FocusIn: - { - if (event->xfocus.mode == NotifyNormal) - { - _glfwInputWindowFocus(window, GL_TRUE); - - if (window->cursorMode == GLFW_CURSOR_DISABLED) - disableCursor(window); - } - - break; - } - - case FocusOut: - { - if (event->xfocus.mode == NotifyNormal) - { - _glfwInputWindowFocus(window, GL_FALSE); - - if (window->cursorMode == GLFW_CURSOR_DISABLED) - restoreCursor(window); - } - - break; - } - - case Expose: - { - _glfwInputWindowDamage(window); - break; - } - - case PropertyNotify: - { - if (event->xproperty.atom == _glfw.x11.WM_STATE && - event->xproperty.state == PropertyNewValue) - { - const int state = getWindowState(window); - if (state == IconicState) - _glfwInputWindowIconify(window, GL_TRUE); - else if (state == NormalState) - _glfwInputWindowIconify(window, GL_FALSE); - } - - break; - } - - case SelectionClear: - { - handleSelectionClear(event); - break; - } - - case SelectionRequest: - { - handleSelectionRequest(event); - break; - } - - case DestroyNotify: - return; - - case GenericEvent: - { - if (event->xcookie.extension == _glfw.x11.xi.majorOpcode && - XGetEventData(_glfw.x11.display, &event->xcookie)) - { - if (event->xcookie.evtype == XI_Motion) - { - XIDeviceEvent* data = (XIDeviceEvent*) event->xcookie.data; - - window = findWindowByHandle(data->event); - if (window) - { - if (data->event_x != window->x11.warpPosX || - data->event_y != window->x11.warpPosY) - { - // The cursor was moved by something other than GLFW - - double x, y; - - if (window->cursorMode == GLFW_CURSOR_DISABLED) - { - if (_glfw.focusedWindow != window) - break; - - x = data->event_x - window->x11.cursorPosX; - y = data->event_y - window->x11.cursorPosY; - } - else - { - x = data->event_x; - y = data->event_y; - } - - _glfwInputCursorMotion(window, x, y); - } - - window->x11.cursorPosX = data->event_x; - window->x11.cursorPosY = data->event_y; - } - } - } - - XFreeEventData(_glfw.x11.display, &event->xcookie); - break; - } - - default: - { - switch (event->type - _glfw.x11.randr.eventBase) - { - case RRScreenChangeNotify: - { - XRRUpdateConfiguration(event); - break; - } - } - - break; - } - } -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW internal API ////// -////////////////////////////////////////////////////////////////////////// - -// Retrieve a single window property of the specified type -// Inspired by fghGetWindowProperty from freeglut -// -unsigned long _glfwGetWindowProperty(Window window, - Atom property, - Atom type, - unsigned char** value) -{ - Atom actualType; - int actualFormat; - unsigned long itemCount, bytesAfter; - - XGetWindowProperty(_glfw.x11.display, - window, - property, - 0, - LONG_MAX, - False, - type, - &actualType, - &actualFormat, - &itemCount, - &bytesAfter, - value); - - if (type != AnyPropertyType && actualType != type) - return 0; - - return itemCount; -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW platform API ////// -////////////////////////////////////////////////////////////////////////// - -int _glfwPlatformCreateWindow(_GLFWwindow* window, - const _GLFWwndconfig* wndconfig, - const _GLFWctxconfig* ctxconfig, - const _GLFWfbconfig* fbconfig) -{ - if (!_glfwCreateContext(window, ctxconfig, fbconfig)) - return GL_FALSE; - - if (!createWindow(window, wndconfig)) - return GL_FALSE; - - if (wndconfig->monitor) - { - _glfwPlatformShowWindow(window); - enterFullscreenMode(window); - } - - return GL_TRUE; -} - -void _glfwPlatformDestroyWindow(_GLFWwindow* window) -{ - if (window->monitor) - leaveFullscreenMode(window); - - if (window->x11.ic) - { - XDestroyIC(window->x11.ic); - window->x11.ic = NULL; - } - - _glfwDestroyContext(window); - - if (window->x11.handle) - { - if (window->x11.handle == - XGetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD)) - { - pushSelectionToManager(window); - } - - XDeleteContext(_glfw.x11.display, window->x11.handle, _glfw.x11.context); - XUnmapWindow(_glfw.x11.display, window->x11.handle); - XDestroyWindow(_glfw.x11.display, window->x11.handle); - window->x11.handle = (Window) 0; - } - - if (window->x11.colormap) - { - XFreeColormap(_glfw.x11.display, window->x11.colormap); - window->x11.colormap = (Colormap) 0; - } - - XFlush(_glfw.x11.display); -} - -void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title) -{ -#if defined(X_HAVE_UTF8_STRING) - Xutf8SetWMProperties(_glfw.x11.display, - window->x11.handle, - title, title, - NULL, 0, - NULL, NULL, NULL); -#else - // This may be a slightly better fallback than using XStoreName and - // XSetIconName, which always store their arguments using STRING - XmbSetWMProperties(_glfw.x11.display, - window->x11.handle, - title, title, - NULL, 0, - NULL, NULL, NULL); -#endif - - if (_glfw.x11.NET_WM_NAME) - { - XChangeProperty(_glfw.x11.display, window->x11.handle, - _glfw.x11.NET_WM_NAME, _glfw.x11.UTF8_STRING, 8, - PropModeReplace, - (unsigned char*) title, strlen(title)); - } - - if (_glfw.x11.NET_WM_ICON_NAME) - { - XChangeProperty(_glfw.x11.display, window->x11.handle, - _glfw.x11.NET_WM_ICON_NAME, _glfw.x11.UTF8_STRING, 8, - PropModeReplace, - (unsigned char*) title, strlen(title)); - } - - XFlush(_glfw.x11.display); -} - -void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos) -{ - Window child; - int x, y; - - XTranslateCoordinates(_glfw.x11.display, window->x11.handle, _glfw.x11.root, - 0, 0, &x, &y, &child); - - if (child) - { - int left, top; - XTranslateCoordinates(_glfw.x11.display, window->x11.handle, child, - 0, 0, &left, &top, &child); - - x -= left; - y -= top; - } - - if (xpos) - *xpos = x; - if (ypos) - *ypos = y; -} - -void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos) -{ - XMoveWindow(_glfw.x11.display, window->x11.handle, xpos, ypos); - XFlush(_glfw.x11.display); -} - -void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height) -{ - XWindowAttributes attribs; - XGetWindowAttributes(_glfw.x11.display, window->x11.handle, &attribs); - - if (width) - *width = attribs.width; - if (height) - *height = attribs.height; -} - -void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) -{ - if (window->monitor) - { - _glfwSetVideoMode(window->monitor, &window->videoMode); - - if (window->x11.overrideRedirect) - { - GLFWvidmode mode; - _glfwPlatformGetVideoMode(window->monitor, &mode); - XResizeWindow(_glfw.x11.display, window->x11.handle, - mode.width, mode.height); - } - } - else - { - if (!window->resizable) - { - // Update window size restrictions to match new window size - - XSizeHints* hints = XAllocSizeHints(); - - hints->flags |= (PMinSize | PMaxSize); - hints->min_width = hints->max_width = width; - hints->min_height = hints->max_height = height; - - XSetWMNormalHints(_glfw.x11.display, window->x11.handle, hints); - XFree(hints); - } - - XResizeWindow(_glfw.x11.display, window->x11.handle, width, height); - } - - XFlush(_glfw.x11.display); -} - -void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height) -{ - _glfwPlatformGetWindowSize(window, width, height); -} - -void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, - int* left, int* top, - int* right, int* bottom) -{ - long* extents = NULL; - - if (_glfw.x11.NET_FRAME_EXTENTS == None) - return; - - if (_glfwGetWindowProperty(window->x11.handle, - _glfw.x11.NET_FRAME_EXTENTS, - XA_CARDINAL, - (unsigned char**) &extents) == 4) - { - if (left) - *left = extents[0]; - if (top) - *top = extents[2]; - if (right) - *right = extents[1]; - if (bottom) - *bottom = extents[3]; - } - - if (extents) - XFree(extents); -} - -void _glfwPlatformIconifyWindow(_GLFWwindow* window) -{ - if (window->x11.overrideRedirect) - { - // Override-redirect windows cannot be iconified or restored, as those - // tasks are performed by the window manager - _glfwInputError(GLFW_API_UNAVAILABLE, - "X11: Iconification of full screen windows requires " - "a WM that supports EWMH"); - return; - } - - XIconifyWindow(_glfw.x11.display, window->x11.handle, _glfw.x11.screen); - XFlush(_glfw.x11.display); -} - -void _glfwPlatformRestoreWindow(_GLFWwindow* window) -{ - if (window->x11.overrideRedirect) - { - // Override-redirect windows cannot be iconified or restored, as those - // tasks are performed by the window manager - _glfwInputError(GLFW_API_UNAVAILABLE, - "X11: Iconification of full screen windows requires " - "a WM that supports EWMH"); - return; - } - - XMapWindow(_glfw.x11.display, window->x11.handle); - XFlush(_glfw.x11.display); -} - -void _glfwPlatformShowWindow(_GLFWwindow* window) -{ - XMapRaised(_glfw.x11.display, window->x11.handle); - XFlush(_glfw.x11.display); -} - -void _glfwPlatformUnhideWindow(_GLFWwindow* window) -{ - XMapWindow(_glfw.x11.display, window->x11.handle); - XFlush(_glfw.x11.display); -} - -void _glfwPlatformHideWindow(_GLFWwindow* window) -{ - XUnmapWindow(_glfw.x11.display, window->x11.handle); - XFlush(_glfw.x11.display); -} - -int _glfwPlatformWindowFocused(_GLFWwindow* window) -{ - Window focused; - int state; - - XGetInputFocus(_glfw.x11.display, &focused, &state); - return window->x11.handle == focused; -} - -int _glfwPlatformWindowIconified(_GLFWwindow* window) -{ - return getWindowState(window) == IconicState; -} - -int _glfwPlatformWindowVisible(_GLFWwindow* window) -{ - XWindowAttributes wa; - XGetWindowAttributes(_glfw.x11.display, window->x11.handle, &wa); - return wa.map_state == IsViewable; -} - -void _glfwPlatformPollEvents(void) -{ - int count = XPending(_glfw.x11.display); - while (count--) - { - XEvent event; - XNextEvent(_glfw.x11.display, &event); - processEvent(&event); - } - - _GLFWwindow* window = _glfw.focusedWindow; - if (window && window->cursorMode == GLFW_CURSOR_DISABLED) - { - int width, height; - _glfwPlatformGetWindowSize(window, &width, &height); - _glfwPlatformSetCursorPos(window, width / 2, height / 2); - } -} - -void _glfwPlatformWaitEvents(void) -{ - if (!XPending(_glfw.x11.display)) - { - fd_set fds; - const int fd = ConnectionNumber(_glfw.x11.display); - - FD_ZERO(&fds); - FD_SET(fd, &fds); - - // select(1) is used instead of an X function like XNextEvent, as the - // wait inside those are guarded by the mutex protecting the display - // struct, locking out other threads from using X (including GLX) - if (select(fd + 1, &fds, NULL, NULL, NULL) < 0) - return; - } - - _glfwPlatformPollEvents(); -} - -void _glfwPlatformPostEmptyEvent(void) -{ - XEvent event; - _GLFWwindow* window = _glfw.windowListHead; - - memset(&event, 0, sizeof(event)); - event.type = ClientMessage; - event.xclient.window = window->x11.handle; - event.xclient.format = 32; // Data is 32-bit longs - event.xclient.message_type = _glfw.x11._NULL; - - XSendEvent(_glfw.x11.display, window->x11.handle, False, 0, &event); - XFlush(_glfw.x11.display); -} - -void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos) -{ - Window root, child; - int rootX, rootY, childX, childY; - unsigned int mask; - - XQueryPointer(_glfw.x11.display, window->x11.handle, - &root, &child, - &rootX, &rootY, &childX, &childY, - &mask); - - if (xpos) - *xpos = childX; - if (ypos) - *ypos = childY; -} - -void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y) -{ - // Store the new position so it can be recognized later - window->x11.warpPosX = (int) x; - window->x11.warpPosY = (int) y; - - XWarpPointer(_glfw.x11.display, None, window->x11.handle, - 0,0,0,0, (int) x, (int) y); -} - -void _glfwPlatformApplyCursorMode(_GLFWwindow* window) -{ - switch (window->cursorMode) - { - case GLFW_CURSOR_NORMAL: - restoreCursor(window); - break; - case GLFW_CURSOR_HIDDEN: - hideCursor(window); - break; - case GLFW_CURSOR_DISABLED: - disableCursor(window); - break; - } -} - -int _glfwPlatformCreateCursor(_GLFWcursor* cursor, - const GLFWimage* image, - int xhot, int yhot) -{ - cursor->x11.handle = _glfwCreateCursor(image, xhot, yhot); - if (!cursor->x11.handle) - return GL_FALSE; - - return GL_TRUE; -} - -int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape) -{ - const unsigned int native = translateCursorShape(shape); - if (!native) - { - _glfwInputError(GLFW_INVALID_ENUM, "X11: Invalid standard cursor"); - return GL_FALSE; - } - - cursor->x11.handle = XCreateFontCursor(_glfw.x11.display, native); - if (!cursor->x11.handle) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "X11: Failed to create standard cursor"); - return GL_FALSE; - } - - return GL_TRUE; -} - -void _glfwPlatformDestroyCursor(_GLFWcursor* cursor) -{ - if (cursor->x11.handle) - XFreeCursor(_glfw.x11.display, cursor->x11.handle); -} - -void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) -{ - if (window->cursorMode == GLFW_CURSOR_NORMAL) - { - if (cursor) - XDefineCursor(_glfw.x11.display, window->x11.handle, cursor->x11.handle); - else - XUndefineCursor(_glfw.x11.display, window->x11.handle); - - XFlush(_glfw.x11.display); - } -} - -void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string) -{ - free(_glfw.x11.clipboardString); - _glfw.x11.clipboardString = strdup(string); - - XSetSelectionOwner(_glfw.x11.display, - _glfw.x11.CLIPBOARD, - window->x11.handle, CurrentTime); - - if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD) != - window->x11.handle) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "X11: Failed to become owner of the clipboard selection"); - } -} - -const char* _glfwPlatformGetClipboardString(_GLFWwindow* window) -{ - size_t i; - const Atom formats[] = { _glfw.x11.UTF8_STRING, - _glfw.x11.COMPOUND_STRING, - XA_STRING }; - const size_t formatCount = sizeof(formats) / sizeof(formats[0]); - - if (findWindowByHandle(XGetSelectionOwner(_glfw.x11.display, - _glfw.x11.CLIPBOARD))) - { - // Instead of doing a large number of X round-trips just to put this - // string into a window property and then read it back, just return it - return _glfw.x11.clipboardString; - } - - free(_glfw.x11.clipboardString); - _glfw.x11.clipboardString = NULL; - - for (i = 0; i < formatCount; i++) - { - char* data; - XEvent event; - - XConvertSelection(_glfw.x11.display, - _glfw.x11.CLIPBOARD, - formats[i], - _glfw.x11.GLFW_SELECTION, - window->x11.handle, CurrentTime); - - // XCheckTypedEvent is used instead of XIfEvent in order not to lock - // other threads out from the display during the entire wait period - while (!XCheckTypedEvent(_glfw.x11.display, SelectionNotify, &event)) - ; - - if (event.xselection.property == None) - continue; - - if (_glfwGetWindowProperty(event.xselection.requestor, - event.xselection.property, - event.xselection.target, - (unsigned char**) &data)) - { - _glfw.x11.clipboardString = strdup(data); - } - - XFree(data); - - XDeleteProperty(_glfw.x11.display, - event.xselection.requestor, - event.xselection.property); - - if (_glfw.x11.clipboardString) - break; - } - - if (_glfw.x11.clipboardString == NULL) - { - _glfwInputError(GLFW_FORMAT_UNAVAILABLE, - "X11: Failed to convert selection to string"); - } - - return _glfw.x11.clipboardString; -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW native API ////// -////////////////////////////////////////////////////////////////////////// - -GLFWAPI Display* glfwGetX11Display(void) -{ - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - return _glfw.x11.display; -} - -GLFWAPI Window glfwGetX11Window(GLFWwindow* handle) -{ - _GLFWwindow* window = (_GLFWwindow*) handle; - _GLFW_REQUIRE_INIT_OR_RETURN(None); - return window->x11.handle; -} - diff --git a/examples/common/glfw/src/xkb_unicode.c b/examples/common/glfw/src/xkb_unicode.c deleted file mode 100644 index fbc25a27..00000000 --- a/examples/common/glfw/src/xkb_unicode.c +++ /dev/null @@ -1,889 +0,0 @@ -//======================================================================== -// GLFW 3.1 X11 - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2002-2006 Marcus Geelnard -// Copyright (c) 2006-2010 Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#include "internal.h" - - -/* - * Marcus: This code was originally written by Markus G. Kuhn. - * I have made some slight changes (trimmed it down a bit from >60 KB to - * 20 KB), but the functionality is the same. - */ - -/* - * This module converts keysym values into the corresponding ISO 10646 - * (UCS, Unicode) values. - * - * The array keysymtab[] contains pairs of X11 keysym values for graphical - * characters and the corresponding Unicode value. The function - * _glfwKeySym2Unicode() maps a keysym onto a Unicode value using a binary - * search, therefore keysymtab[] must remain SORTED by keysym value. - * - * We allow to represent any UCS character in the range U-00000000 to - * U-00FFFFFF by a keysym value in the range 0x01000000 to 0x01ffffff. - * This admittedly does not cover the entire 31-bit space of UCS, but - * it does cover all of the characters up to U-10FFFF, which can be - * represented by UTF-16, and more, and it is very unlikely that higher - * UCS codes will ever be assigned by ISO. So to get Unicode character - * U+ABCD you can directly use keysym 0x0100abcd. - * - * Original author: Markus G. Kuhn , University of - * Cambridge, April 2001 - * - * Special thanks to Richard Verhoeven for preparing - * an initial draft of the mapping table. - * - */ - - -//************************************************************************ -//**** KeySym to Unicode mapping table **** -//************************************************************************ - -static const struct codepair { - unsigned short keysym; - unsigned short ucs; -} keysymtab[] = { - { 0x01a1, 0x0104 }, - { 0x01a2, 0x02d8 }, - { 0x01a3, 0x0141 }, - { 0x01a5, 0x013d }, - { 0x01a6, 0x015a }, - { 0x01a9, 0x0160 }, - { 0x01aa, 0x015e }, - { 0x01ab, 0x0164 }, - { 0x01ac, 0x0179 }, - { 0x01ae, 0x017d }, - { 0x01af, 0x017b }, - { 0x01b1, 0x0105 }, - { 0x01b2, 0x02db }, - { 0x01b3, 0x0142 }, - { 0x01b5, 0x013e }, - { 0x01b6, 0x015b }, - { 0x01b7, 0x02c7 }, - { 0x01b9, 0x0161 }, - { 0x01ba, 0x015f }, - { 0x01bb, 0x0165 }, - { 0x01bc, 0x017a }, - { 0x01bd, 0x02dd }, - { 0x01be, 0x017e }, - { 0x01bf, 0x017c }, - { 0x01c0, 0x0154 }, - { 0x01c3, 0x0102 }, - { 0x01c5, 0x0139 }, - { 0x01c6, 0x0106 }, - { 0x01c8, 0x010c }, - { 0x01ca, 0x0118 }, - { 0x01cc, 0x011a }, - { 0x01cf, 0x010e }, - { 0x01d0, 0x0110 }, - { 0x01d1, 0x0143 }, - { 0x01d2, 0x0147 }, - { 0x01d5, 0x0150 }, - { 0x01d8, 0x0158 }, - { 0x01d9, 0x016e }, - { 0x01db, 0x0170 }, - { 0x01de, 0x0162 }, - { 0x01e0, 0x0155 }, - { 0x01e3, 0x0103 }, - { 0x01e5, 0x013a }, - { 0x01e6, 0x0107 }, - { 0x01e8, 0x010d }, - { 0x01ea, 0x0119 }, - { 0x01ec, 0x011b }, - { 0x01ef, 0x010f }, - { 0x01f0, 0x0111 }, - { 0x01f1, 0x0144 }, - { 0x01f2, 0x0148 }, - { 0x01f5, 0x0151 }, - { 0x01f8, 0x0159 }, - { 0x01f9, 0x016f }, - { 0x01fb, 0x0171 }, - { 0x01fe, 0x0163 }, - { 0x01ff, 0x02d9 }, - { 0x02a1, 0x0126 }, - { 0x02a6, 0x0124 }, - { 0x02a9, 0x0130 }, - { 0x02ab, 0x011e }, - { 0x02ac, 0x0134 }, - { 0x02b1, 0x0127 }, - { 0x02b6, 0x0125 }, - { 0x02b9, 0x0131 }, - { 0x02bb, 0x011f }, - { 0x02bc, 0x0135 }, - { 0x02c5, 0x010a }, - { 0x02c6, 0x0108 }, - { 0x02d5, 0x0120 }, - { 0x02d8, 0x011c }, - { 0x02dd, 0x016c }, - { 0x02de, 0x015c }, - { 0x02e5, 0x010b }, - { 0x02e6, 0x0109 }, - { 0x02f5, 0x0121 }, - { 0x02f8, 0x011d }, - { 0x02fd, 0x016d }, - { 0x02fe, 0x015d }, - { 0x03a2, 0x0138 }, - { 0x03a3, 0x0156 }, - { 0x03a5, 0x0128 }, - { 0x03a6, 0x013b }, - { 0x03aa, 0x0112 }, - { 0x03ab, 0x0122 }, - { 0x03ac, 0x0166 }, - { 0x03b3, 0x0157 }, - { 0x03b5, 0x0129 }, - { 0x03b6, 0x013c }, - { 0x03ba, 0x0113 }, - { 0x03bb, 0x0123 }, - { 0x03bc, 0x0167 }, - { 0x03bd, 0x014a }, - { 0x03bf, 0x014b }, - { 0x03c0, 0x0100 }, - { 0x03c7, 0x012e }, - { 0x03cc, 0x0116 }, - { 0x03cf, 0x012a }, - { 0x03d1, 0x0145 }, - { 0x03d2, 0x014c }, - { 0x03d3, 0x0136 }, - { 0x03d9, 0x0172 }, - { 0x03dd, 0x0168 }, - { 0x03de, 0x016a }, - { 0x03e0, 0x0101 }, - { 0x03e7, 0x012f }, - { 0x03ec, 0x0117 }, - { 0x03ef, 0x012b }, - { 0x03f1, 0x0146 }, - { 0x03f2, 0x014d }, - { 0x03f3, 0x0137 }, - { 0x03f9, 0x0173 }, - { 0x03fd, 0x0169 }, - { 0x03fe, 0x016b }, - { 0x047e, 0x203e }, - { 0x04a1, 0x3002 }, - { 0x04a2, 0x300c }, - { 0x04a3, 0x300d }, - { 0x04a4, 0x3001 }, - { 0x04a5, 0x30fb }, - { 0x04a6, 0x30f2 }, - { 0x04a7, 0x30a1 }, - { 0x04a8, 0x30a3 }, - { 0x04a9, 0x30a5 }, - { 0x04aa, 0x30a7 }, - { 0x04ab, 0x30a9 }, - { 0x04ac, 0x30e3 }, - { 0x04ad, 0x30e5 }, - { 0x04ae, 0x30e7 }, - { 0x04af, 0x30c3 }, - { 0x04b0, 0x30fc }, - { 0x04b1, 0x30a2 }, - { 0x04b2, 0x30a4 }, - { 0x04b3, 0x30a6 }, - { 0x04b4, 0x30a8 }, - { 0x04b5, 0x30aa }, - { 0x04b6, 0x30ab }, - { 0x04b7, 0x30ad }, - { 0x04b8, 0x30af }, - { 0x04b9, 0x30b1 }, - { 0x04ba, 0x30b3 }, - { 0x04bb, 0x30b5 }, - { 0x04bc, 0x30b7 }, - { 0x04bd, 0x30b9 }, - { 0x04be, 0x30bb }, - { 0x04bf, 0x30bd }, - { 0x04c0, 0x30bf }, - { 0x04c1, 0x30c1 }, - { 0x04c2, 0x30c4 }, - { 0x04c3, 0x30c6 }, - { 0x04c4, 0x30c8 }, - { 0x04c5, 0x30ca }, - { 0x04c6, 0x30cb }, - { 0x04c7, 0x30cc }, - { 0x04c8, 0x30cd }, - { 0x04c9, 0x30ce }, - { 0x04ca, 0x30cf }, - { 0x04cb, 0x30d2 }, - { 0x04cc, 0x30d5 }, - { 0x04cd, 0x30d8 }, - { 0x04ce, 0x30db }, - { 0x04cf, 0x30de }, - { 0x04d0, 0x30df }, - { 0x04d1, 0x30e0 }, - { 0x04d2, 0x30e1 }, - { 0x04d3, 0x30e2 }, - { 0x04d4, 0x30e4 }, - { 0x04d5, 0x30e6 }, - { 0x04d6, 0x30e8 }, - { 0x04d7, 0x30e9 }, - { 0x04d8, 0x30ea }, - { 0x04d9, 0x30eb }, - { 0x04da, 0x30ec }, - { 0x04db, 0x30ed }, - { 0x04dc, 0x30ef }, - { 0x04dd, 0x30f3 }, - { 0x04de, 0x309b }, - { 0x04df, 0x309c }, - { 0x05ac, 0x060c }, - { 0x05bb, 0x061b }, - { 0x05bf, 0x061f }, - { 0x05c1, 0x0621 }, - { 0x05c2, 0x0622 }, - { 0x05c3, 0x0623 }, - { 0x05c4, 0x0624 }, - { 0x05c5, 0x0625 }, - { 0x05c6, 0x0626 }, - { 0x05c7, 0x0627 }, - { 0x05c8, 0x0628 }, - { 0x05c9, 0x0629 }, - { 0x05ca, 0x062a }, - { 0x05cb, 0x062b }, - { 0x05cc, 0x062c }, - { 0x05cd, 0x062d }, - { 0x05ce, 0x062e }, - { 0x05cf, 0x062f }, - { 0x05d0, 0x0630 }, - { 0x05d1, 0x0631 }, - { 0x05d2, 0x0632 }, - { 0x05d3, 0x0633 }, - { 0x05d4, 0x0634 }, - { 0x05d5, 0x0635 }, - { 0x05d6, 0x0636 }, - { 0x05d7, 0x0637 }, - { 0x05d8, 0x0638 }, - { 0x05d9, 0x0639 }, - { 0x05da, 0x063a }, - { 0x05e0, 0x0640 }, - { 0x05e1, 0x0641 }, - { 0x05e2, 0x0642 }, - { 0x05e3, 0x0643 }, - { 0x05e4, 0x0644 }, - { 0x05e5, 0x0645 }, - { 0x05e6, 0x0646 }, - { 0x05e7, 0x0647 }, - { 0x05e8, 0x0648 }, - { 0x05e9, 0x0649 }, - { 0x05ea, 0x064a }, - { 0x05eb, 0x064b }, - { 0x05ec, 0x064c }, - { 0x05ed, 0x064d }, - { 0x05ee, 0x064e }, - { 0x05ef, 0x064f }, - { 0x05f0, 0x0650 }, - { 0x05f1, 0x0651 }, - { 0x05f2, 0x0652 }, - { 0x06a1, 0x0452 }, - { 0x06a2, 0x0453 }, - { 0x06a3, 0x0451 }, - { 0x06a4, 0x0454 }, - { 0x06a5, 0x0455 }, - { 0x06a6, 0x0456 }, - { 0x06a7, 0x0457 }, - { 0x06a8, 0x0458 }, - { 0x06a9, 0x0459 }, - { 0x06aa, 0x045a }, - { 0x06ab, 0x045b }, - { 0x06ac, 0x045c }, - { 0x06ae, 0x045e }, - { 0x06af, 0x045f }, - { 0x06b0, 0x2116 }, - { 0x06b1, 0x0402 }, - { 0x06b2, 0x0403 }, - { 0x06b3, 0x0401 }, - { 0x06b4, 0x0404 }, - { 0x06b5, 0x0405 }, - { 0x06b6, 0x0406 }, - { 0x06b7, 0x0407 }, - { 0x06b8, 0x0408 }, - { 0x06b9, 0x0409 }, - { 0x06ba, 0x040a }, - { 0x06bb, 0x040b }, - { 0x06bc, 0x040c }, - { 0x06be, 0x040e }, - { 0x06bf, 0x040f }, - { 0x06c0, 0x044e }, - { 0x06c1, 0x0430 }, - { 0x06c2, 0x0431 }, - { 0x06c3, 0x0446 }, - { 0x06c4, 0x0434 }, - { 0x06c5, 0x0435 }, - { 0x06c6, 0x0444 }, - { 0x06c7, 0x0433 }, - { 0x06c8, 0x0445 }, - { 0x06c9, 0x0438 }, - { 0x06ca, 0x0439 }, - { 0x06cb, 0x043a }, - { 0x06cc, 0x043b }, - { 0x06cd, 0x043c }, - { 0x06ce, 0x043d }, - { 0x06cf, 0x043e }, - { 0x06d0, 0x043f }, - { 0x06d1, 0x044f }, - { 0x06d2, 0x0440 }, - { 0x06d3, 0x0441 }, - { 0x06d4, 0x0442 }, - { 0x06d5, 0x0443 }, - { 0x06d6, 0x0436 }, - { 0x06d7, 0x0432 }, - { 0x06d8, 0x044c }, - { 0x06d9, 0x044b }, - { 0x06da, 0x0437 }, - { 0x06db, 0x0448 }, - { 0x06dc, 0x044d }, - { 0x06dd, 0x0449 }, - { 0x06de, 0x0447 }, - { 0x06df, 0x044a }, - { 0x06e0, 0x042e }, - { 0x06e1, 0x0410 }, - { 0x06e2, 0x0411 }, - { 0x06e3, 0x0426 }, - { 0x06e4, 0x0414 }, - { 0x06e5, 0x0415 }, - { 0x06e6, 0x0424 }, - { 0x06e7, 0x0413 }, - { 0x06e8, 0x0425 }, - { 0x06e9, 0x0418 }, - { 0x06ea, 0x0419 }, - { 0x06eb, 0x041a }, - { 0x06ec, 0x041b }, - { 0x06ed, 0x041c }, - { 0x06ee, 0x041d }, - { 0x06ef, 0x041e }, - { 0x06f0, 0x041f }, - { 0x06f1, 0x042f }, - { 0x06f2, 0x0420 }, - { 0x06f3, 0x0421 }, - { 0x06f4, 0x0422 }, - { 0x06f5, 0x0423 }, - { 0x06f6, 0x0416 }, - { 0x06f7, 0x0412 }, - { 0x06f8, 0x042c }, - { 0x06f9, 0x042b }, - { 0x06fa, 0x0417 }, - { 0x06fb, 0x0428 }, - { 0x06fc, 0x042d }, - { 0x06fd, 0x0429 }, - { 0x06fe, 0x0427 }, - { 0x06ff, 0x042a }, - { 0x07a1, 0x0386 }, - { 0x07a2, 0x0388 }, - { 0x07a3, 0x0389 }, - { 0x07a4, 0x038a }, - { 0x07a5, 0x03aa }, - { 0x07a7, 0x038c }, - { 0x07a8, 0x038e }, - { 0x07a9, 0x03ab }, - { 0x07ab, 0x038f }, - { 0x07ae, 0x0385 }, - { 0x07af, 0x2015 }, - { 0x07b1, 0x03ac }, - { 0x07b2, 0x03ad }, - { 0x07b3, 0x03ae }, - { 0x07b4, 0x03af }, - { 0x07b5, 0x03ca }, - { 0x07b6, 0x0390 }, - { 0x07b7, 0x03cc }, - { 0x07b8, 0x03cd }, - { 0x07b9, 0x03cb }, - { 0x07ba, 0x03b0 }, - { 0x07bb, 0x03ce }, - { 0x07c1, 0x0391 }, - { 0x07c2, 0x0392 }, - { 0x07c3, 0x0393 }, - { 0x07c4, 0x0394 }, - { 0x07c5, 0x0395 }, - { 0x07c6, 0x0396 }, - { 0x07c7, 0x0397 }, - { 0x07c8, 0x0398 }, - { 0x07c9, 0x0399 }, - { 0x07ca, 0x039a }, - { 0x07cb, 0x039b }, - { 0x07cc, 0x039c }, - { 0x07cd, 0x039d }, - { 0x07ce, 0x039e }, - { 0x07cf, 0x039f }, - { 0x07d0, 0x03a0 }, - { 0x07d1, 0x03a1 }, - { 0x07d2, 0x03a3 }, - { 0x07d4, 0x03a4 }, - { 0x07d5, 0x03a5 }, - { 0x07d6, 0x03a6 }, - { 0x07d7, 0x03a7 }, - { 0x07d8, 0x03a8 }, - { 0x07d9, 0x03a9 }, - { 0x07e1, 0x03b1 }, - { 0x07e2, 0x03b2 }, - { 0x07e3, 0x03b3 }, - { 0x07e4, 0x03b4 }, - { 0x07e5, 0x03b5 }, - { 0x07e6, 0x03b6 }, - { 0x07e7, 0x03b7 }, - { 0x07e8, 0x03b8 }, - { 0x07e9, 0x03b9 }, - { 0x07ea, 0x03ba }, - { 0x07eb, 0x03bb }, - { 0x07ec, 0x03bc }, - { 0x07ed, 0x03bd }, - { 0x07ee, 0x03be }, - { 0x07ef, 0x03bf }, - { 0x07f0, 0x03c0 }, - { 0x07f1, 0x03c1 }, - { 0x07f2, 0x03c3 }, - { 0x07f3, 0x03c2 }, - { 0x07f4, 0x03c4 }, - { 0x07f5, 0x03c5 }, - { 0x07f6, 0x03c6 }, - { 0x07f7, 0x03c7 }, - { 0x07f8, 0x03c8 }, - { 0x07f9, 0x03c9 }, - { 0x08a1, 0x23b7 }, - { 0x08a2, 0x250c }, - { 0x08a3, 0x2500 }, - { 0x08a4, 0x2320 }, - { 0x08a5, 0x2321 }, - { 0x08a6, 0x2502 }, - { 0x08a7, 0x23a1 }, - { 0x08a8, 0x23a3 }, - { 0x08a9, 0x23a4 }, - { 0x08aa, 0x23a6 }, - { 0x08ab, 0x239b }, - { 0x08ac, 0x239d }, - { 0x08ad, 0x239e }, - { 0x08ae, 0x23a0 }, - { 0x08af, 0x23a8 }, - { 0x08b0, 0x23ac }, - { 0x08bc, 0x2264 }, - { 0x08bd, 0x2260 }, - { 0x08be, 0x2265 }, - { 0x08bf, 0x222b }, - { 0x08c0, 0x2234 }, - { 0x08c1, 0x221d }, - { 0x08c2, 0x221e }, - { 0x08c5, 0x2207 }, - { 0x08c8, 0x223c }, - { 0x08c9, 0x2243 }, - { 0x08cd, 0x21d4 }, - { 0x08ce, 0x21d2 }, - { 0x08cf, 0x2261 }, - { 0x08d6, 0x221a }, - { 0x08da, 0x2282 }, - { 0x08db, 0x2283 }, - { 0x08dc, 0x2229 }, - { 0x08dd, 0x222a }, - { 0x08de, 0x2227 }, - { 0x08df, 0x2228 }, - { 0x08ef, 0x2202 }, - { 0x08f6, 0x0192 }, - { 0x08fb, 0x2190 }, - { 0x08fc, 0x2191 }, - { 0x08fd, 0x2192 }, - { 0x08fe, 0x2193 }, - { 0x09e0, 0x25c6 }, - { 0x09e1, 0x2592 }, - { 0x09e2, 0x2409 }, - { 0x09e3, 0x240c }, - { 0x09e4, 0x240d }, - { 0x09e5, 0x240a }, - { 0x09e8, 0x2424 }, - { 0x09e9, 0x240b }, - { 0x09ea, 0x2518 }, - { 0x09eb, 0x2510 }, - { 0x09ec, 0x250c }, - { 0x09ed, 0x2514 }, - { 0x09ee, 0x253c }, - { 0x09ef, 0x23ba }, - { 0x09f0, 0x23bb }, - { 0x09f1, 0x2500 }, - { 0x09f2, 0x23bc }, - { 0x09f3, 0x23bd }, - { 0x09f4, 0x251c }, - { 0x09f5, 0x2524 }, - { 0x09f6, 0x2534 }, - { 0x09f7, 0x252c }, - { 0x09f8, 0x2502 }, - { 0x0aa1, 0x2003 }, - { 0x0aa2, 0x2002 }, - { 0x0aa3, 0x2004 }, - { 0x0aa4, 0x2005 }, - { 0x0aa5, 0x2007 }, - { 0x0aa6, 0x2008 }, - { 0x0aa7, 0x2009 }, - { 0x0aa8, 0x200a }, - { 0x0aa9, 0x2014 }, - { 0x0aaa, 0x2013 }, - { 0x0aae, 0x2026 }, - { 0x0aaf, 0x2025 }, - { 0x0ab0, 0x2153 }, - { 0x0ab1, 0x2154 }, - { 0x0ab2, 0x2155 }, - { 0x0ab3, 0x2156 }, - { 0x0ab4, 0x2157 }, - { 0x0ab5, 0x2158 }, - { 0x0ab6, 0x2159 }, - { 0x0ab7, 0x215a }, - { 0x0ab8, 0x2105 }, - { 0x0abb, 0x2012 }, - { 0x0abc, 0x2329 }, - { 0x0abe, 0x232a }, - { 0x0ac3, 0x215b }, - { 0x0ac4, 0x215c }, - { 0x0ac5, 0x215d }, - { 0x0ac6, 0x215e }, - { 0x0ac9, 0x2122 }, - { 0x0aca, 0x2613 }, - { 0x0acc, 0x25c1 }, - { 0x0acd, 0x25b7 }, - { 0x0ace, 0x25cb }, - { 0x0acf, 0x25af }, - { 0x0ad0, 0x2018 }, - { 0x0ad1, 0x2019 }, - { 0x0ad2, 0x201c }, - { 0x0ad3, 0x201d }, - { 0x0ad4, 0x211e }, - { 0x0ad6, 0x2032 }, - { 0x0ad7, 0x2033 }, - { 0x0ad9, 0x271d }, - { 0x0adb, 0x25ac }, - { 0x0adc, 0x25c0 }, - { 0x0add, 0x25b6 }, - { 0x0ade, 0x25cf }, - { 0x0adf, 0x25ae }, - { 0x0ae0, 0x25e6 }, - { 0x0ae1, 0x25ab }, - { 0x0ae2, 0x25ad }, - { 0x0ae3, 0x25b3 }, - { 0x0ae4, 0x25bd }, - { 0x0ae5, 0x2606 }, - { 0x0ae6, 0x2022 }, - { 0x0ae7, 0x25aa }, - { 0x0ae8, 0x25b2 }, - { 0x0ae9, 0x25bc }, - { 0x0aea, 0x261c }, - { 0x0aeb, 0x261e }, - { 0x0aec, 0x2663 }, - { 0x0aed, 0x2666 }, - { 0x0aee, 0x2665 }, - { 0x0af0, 0x2720 }, - { 0x0af1, 0x2020 }, - { 0x0af2, 0x2021 }, - { 0x0af3, 0x2713 }, - { 0x0af4, 0x2717 }, - { 0x0af5, 0x266f }, - { 0x0af6, 0x266d }, - { 0x0af7, 0x2642 }, - { 0x0af8, 0x2640 }, - { 0x0af9, 0x260e }, - { 0x0afa, 0x2315 }, - { 0x0afb, 0x2117 }, - { 0x0afc, 0x2038 }, - { 0x0afd, 0x201a }, - { 0x0afe, 0x201e }, - { 0x0ba3, 0x003c }, - { 0x0ba6, 0x003e }, - { 0x0ba8, 0x2228 }, - { 0x0ba9, 0x2227 }, - { 0x0bc0, 0x00af }, - { 0x0bc2, 0x22a5 }, - { 0x0bc3, 0x2229 }, - { 0x0bc4, 0x230a }, - { 0x0bc6, 0x005f }, - { 0x0bca, 0x2218 }, - { 0x0bcc, 0x2395 }, - { 0x0bce, 0x22a4 }, - { 0x0bcf, 0x25cb }, - { 0x0bd3, 0x2308 }, - { 0x0bd6, 0x222a }, - { 0x0bd8, 0x2283 }, - { 0x0bda, 0x2282 }, - { 0x0bdc, 0x22a2 }, - { 0x0bfc, 0x22a3 }, - { 0x0cdf, 0x2017 }, - { 0x0ce0, 0x05d0 }, - { 0x0ce1, 0x05d1 }, - { 0x0ce2, 0x05d2 }, - { 0x0ce3, 0x05d3 }, - { 0x0ce4, 0x05d4 }, - { 0x0ce5, 0x05d5 }, - { 0x0ce6, 0x05d6 }, - { 0x0ce7, 0x05d7 }, - { 0x0ce8, 0x05d8 }, - { 0x0ce9, 0x05d9 }, - { 0x0cea, 0x05da }, - { 0x0ceb, 0x05db }, - { 0x0cec, 0x05dc }, - { 0x0ced, 0x05dd }, - { 0x0cee, 0x05de }, - { 0x0cef, 0x05df }, - { 0x0cf0, 0x05e0 }, - { 0x0cf1, 0x05e1 }, - { 0x0cf2, 0x05e2 }, - { 0x0cf3, 0x05e3 }, - { 0x0cf4, 0x05e4 }, - { 0x0cf5, 0x05e5 }, - { 0x0cf6, 0x05e6 }, - { 0x0cf7, 0x05e7 }, - { 0x0cf8, 0x05e8 }, - { 0x0cf9, 0x05e9 }, - { 0x0cfa, 0x05ea }, - { 0x0da1, 0x0e01 }, - { 0x0da2, 0x0e02 }, - { 0x0da3, 0x0e03 }, - { 0x0da4, 0x0e04 }, - { 0x0da5, 0x0e05 }, - { 0x0da6, 0x0e06 }, - { 0x0da7, 0x0e07 }, - { 0x0da8, 0x0e08 }, - { 0x0da9, 0x0e09 }, - { 0x0daa, 0x0e0a }, - { 0x0dab, 0x0e0b }, - { 0x0dac, 0x0e0c }, - { 0x0dad, 0x0e0d }, - { 0x0dae, 0x0e0e }, - { 0x0daf, 0x0e0f }, - { 0x0db0, 0x0e10 }, - { 0x0db1, 0x0e11 }, - { 0x0db2, 0x0e12 }, - { 0x0db3, 0x0e13 }, - { 0x0db4, 0x0e14 }, - { 0x0db5, 0x0e15 }, - { 0x0db6, 0x0e16 }, - { 0x0db7, 0x0e17 }, - { 0x0db8, 0x0e18 }, - { 0x0db9, 0x0e19 }, - { 0x0dba, 0x0e1a }, - { 0x0dbb, 0x0e1b }, - { 0x0dbc, 0x0e1c }, - { 0x0dbd, 0x0e1d }, - { 0x0dbe, 0x0e1e }, - { 0x0dbf, 0x0e1f }, - { 0x0dc0, 0x0e20 }, - { 0x0dc1, 0x0e21 }, - { 0x0dc2, 0x0e22 }, - { 0x0dc3, 0x0e23 }, - { 0x0dc4, 0x0e24 }, - { 0x0dc5, 0x0e25 }, - { 0x0dc6, 0x0e26 }, - { 0x0dc7, 0x0e27 }, - { 0x0dc8, 0x0e28 }, - { 0x0dc9, 0x0e29 }, - { 0x0dca, 0x0e2a }, - { 0x0dcb, 0x0e2b }, - { 0x0dcc, 0x0e2c }, - { 0x0dcd, 0x0e2d }, - { 0x0dce, 0x0e2e }, - { 0x0dcf, 0x0e2f }, - { 0x0dd0, 0x0e30 }, - { 0x0dd1, 0x0e31 }, - { 0x0dd2, 0x0e32 }, - { 0x0dd3, 0x0e33 }, - { 0x0dd4, 0x0e34 }, - { 0x0dd5, 0x0e35 }, - { 0x0dd6, 0x0e36 }, - { 0x0dd7, 0x0e37 }, - { 0x0dd8, 0x0e38 }, - { 0x0dd9, 0x0e39 }, - { 0x0dda, 0x0e3a }, - { 0x0ddf, 0x0e3f }, - { 0x0de0, 0x0e40 }, - { 0x0de1, 0x0e41 }, - { 0x0de2, 0x0e42 }, - { 0x0de3, 0x0e43 }, - { 0x0de4, 0x0e44 }, - { 0x0de5, 0x0e45 }, - { 0x0de6, 0x0e46 }, - { 0x0de7, 0x0e47 }, - { 0x0de8, 0x0e48 }, - { 0x0de9, 0x0e49 }, - { 0x0dea, 0x0e4a }, - { 0x0deb, 0x0e4b }, - { 0x0dec, 0x0e4c }, - { 0x0ded, 0x0e4d }, - { 0x0df0, 0x0e50 }, - { 0x0df1, 0x0e51 }, - { 0x0df2, 0x0e52 }, - { 0x0df3, 0x0e53 }, - { 0x0df4, 0x0e54 }, - { 0x0df5, 0x0e55 }, - { 0x0df6, 0x0e56 }, - { 0x0df7, 0x0e57 }, - { 0x0df8, 0x0e58 }, - { 0x0df9, 0x0e59 }, - { 0x0ea1, 0x3131 }, - { 0x0ea2, 0x3132 }, - { 0x0ea3, 0x3133 }, - { 0x0ea4, 0x3134 }, - { 0x0ea5, 0x3135 }, - { 0x0ea6, 0x3136 }, - { 0x0ea7, 0x3137 }, - { 0x0ea8, 0x3138 }, - { 0x0ea9, 0x3139 }, - { 0x0eaa, 0x313a }, - { 0x0eab, 0x313b }, - { 0x0eac, 0x313c }, - { 0x0ead, 0x313d }, - { 0x0eae, 0x313e }, - { 0x0eaf, 0x313f }, - { 0x0eb0, 0x3140 }, - { 0x0eb1, 0x3141 }, - { 0x0eb2, 0x3142 }, - { 0x0eb3, 0x3143 }, - { 0x0eb4, 0x3144 }, - { 0x0eb5, 0x3145 }, - { 0x0eb6, 0x3146 }, - { 0x0eb7, 0x3147 }, - { 0x0eb8, 0x3148 }, - { 0x0eb9, 0x3149 }, - { 0x0eba, 0x314a }, - { 0x0ebb, 0x314b }, - { 0x0ebc, 0x314c }, - { 0x0ebd, 0x314d }, - { 0x0ebe, 0x314e }, - { 0x0ebf, 0x314f }, - { 0x0ec0, 0x3150 }, - { 0x0ec1, 0x3151 }, - { 0x0ec2, 0x3152 }, - { 0x0ec3, 0x3153 }, - { 0x0ec4, 0x3154 }, - { 0x0ec5, 0x3155 }, - { 0x0ec6, 0x3156 }, - { 0x0ec7, 0x3157 }, - { 0x0ec8, 0x3158 }, - { 0x0ec9, 0x3159 }, - { 0x0eca, 0x315a }, - { 0x0ecb, 0x315b }, - { 0x0ecc, 0x315c }, - { 0x0ecd, 0x315d }, - { 0x0ece, 0x315e }, - { 0x0ecf, 0x315f }, - { 0x0ed0, 0x3160 }, - { 0x0ed1, 0x3161 }, - { 0x0ed2, 0x3162 }, - { 0x0ed3, 0x3163 }, - { 0x0ed4, 0x11a8 }, - { 0x0ed5, 0x11a9 }, - { 0x0ed6, 0x11aa }, - { 0x0ed7, 0x11ab }, - { 0x0ed8, 0x11ac }, - { 0x0ed9, 0x11ad }, - { 0x0eda, 0x11ae }, - { 0x0edb, 0x11af }, - { 0x0edc, 0x11b0 }, - { 0x0edd, 0x11b1 }, - { 0x0ede, 0x11b2 }, - { 0x0edf, 0x11b3 }, - { 0x0ee0, 0x11b4 }, - { 0x0ee1, 0x11b5 }, - { 0x0ee2, 0x11b6 }, - { 0x0ee3, 0x11b7 }, - { 0x0ee4, 0x11b8 }, - { 0x0ee5, 0x11b9 }, - { 0x0ee6, 0x11ba }, - { 0x0ee7, 0x11bb }, - { 0x0ee8, 0x11bc }, - { 0x0ee9, 0x11bd }, - { 0x0eea, 0x11be }, - { 0x0eeb, 0x11bf }, - { 0x0eec, 0x11c0 }, - { 0x0eed, 0x11c1 }, - { 0x0eee, 0x11c2 }, - { 0x0eef, 0x316d }, - { 0x0ef0, 0x3171 }, - { 0x0ef1, 0x3178 }, - { 0x0ef2, 0x317f }, - { 0x0ef3, 0x3181 }, - { 0x0ef4, 0x3184 }, - { 0x0ef5, 0x3186 }, - { 0x0ef6, 0x318d }, - { 0x0ef7, 0x318e }, - { 0x0ef8, 0x11eb }, - { 0x0ef9, 0x11f0 }, - { 0x0efa, 0x11f9 }, - { 0x0eff, 0x20a9 }, - { 0x13a4, 0x20ac }, - { 0x13bc, 0x0152 }, - { 0x13bd, 0x0153 }, - { 0x13be, 0x0178 }, - { 0x20ac, 0x20ac }, - // Numeric keypad with numlock on - { XK_KP_Space, ' ' }, - { XK_KP_Equal, '=' }, - { XK_KP_Multiply, '*' }, - { XK_KP_Add, '+' }, - { XK_KP_Separator, ',' }, - { XK_KP_Subtract, '-' }, - { XK_KP_Decimal, '.' }, - { XK_KP_Divide, '/' }, - { XK_KP_0, 0x0030 }, - { XK_KP_1, 0x0031 }, - { XK_KP_2, 0x0032 }, - { XK_KP_3, 0x0033 }, - { XK_KP_4, 0x0034 }, - { XK_KP_5, 0x0035 }, - { XK_KP_6, 0x0036 }, - { XK_KP_7, 0x0037 }, - { XK_KP_8, 0x0038 }, - { XK_KP_9, 0x0039 } -}; - - -////////////////////////////////////////////////////////////////////////// -////// GLFW internal API ////// -////////////////////////////////////////////////////////////////////////// - -// Convert XKB KeySym to Unicode -// -long _glfwKeySym2Unicode(unsigned int keysym) -{ - int min = 0; - int max = sizeof(keysymtab) / sizeof(struct codepair) - 1; - int mid; - - // First check for Latin-1 characters (1:1 mapping) - if ((keysym >= 0x0020 && keysym <= 0x007e) || - (keysym >= 0x00a0 && keysym <= 0x00ff)) - { - return keysym; - } - - // Also check for directly encoded 24-bit UCS characters - if ((keysym & 0xff000000) == 0x01000000) - return keysym & 0x00ffffff; - - // Binary search in table - while (max >= min) - { - mid = (min + max) / 2; - if (keysymtab[mid].keysym < keysym) - min = mid + 1; - else if (keysymtab[mid].keysym > keysym) - max = mid - 1; - else - return keysymtab[mid].ucs; - } - - // No matching Unicode value found - return -1; -} - diff --git a/examples/common/glfw/src/xkb_unicode.h b/examples/common/glfw/src/xkb_unicode.h deleted file mode 100644 index 9772901d..00000000 --- a/examples/common/glfw/src/xkb_unicode.h +++ /dev/null @@ -1,33 +0,0 @@ -//======================================================================== -// GLFW 3.1 Linux - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2014 Jonas Ådahl -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#ifndef _xkb_unicode_h_ -#define _xkb_unicode_h_ - - -long _glfwKeySym2Unicode(unsigned int keysym); - -#endif // _xkb_unicode_h_ diff --git a/examples/common/glfw/tests/CMakeLists.txt b/examples/common/glfw/tests/CMakeLists.txt deleted file mode 100644 index a5f52474..00000000 --- a/examples/common/glfw/tests/CMakeLists.txt +++ /dev/null @@ -1,81 +0,0 @@ - -link_libraries(glfw "${OPENGL_glu_LIBRARY}") - -if (BUILD_SHARED_LIBS) - add_definitions(-DGLFW_DLL) - link_libraries("${OPENGL_gl_LIBRARY}" "${MATH_LIBRARY}") -else() - link_libraries(${glfw_LIBRARIES}) -endif() - -include_directories("${GLFW_SOURCE_DIR}/include" - "${GLFW_SOURCE_DIR}/deps") - -if ("${OPENGL_INCLUDE_DIR}") - include_directories("${OPENGL_INCLUDE_DIR}") -endif() - -set(GETOPT "${GLFW_SOURCE_DIR}/deps/getopt.h" - "${GLFW_SOURCE_DIR}/deps/getopt.c") -set(TINYCTHREAD "${GLFW_SOURCE_DIR}/deps/tinycthread.h" - "${GLFW_SOURCE_DIR}/deps/tinycthread.c") - -add_executable(clipboard clipboard.c ${GETOPT}) -add_executable(defaults defaults.c) -add_executable(events events.c ${GETOPT}) -add_executable(fsaa fsaa.c ${GETOPT}) -add_executable(gamma gamma.c ${GETOPT}) -add_executable(glfwinfo glfwinfo.c ${GETOPT}) -add_executable(iconify iconify.c ${GETOPT}) -add_executable(joysticks joysticks.c) -add_executable(modes modes.c ${GETOPT}) -add_executable(peter peter.c) -add_executable(reopen reopen.c) -add_executable(cursor cursor.c) - -add_executable(cursoranim WIN32 MACOSX_BUNDLE cursoranim.c) -set_target_properties(cursoranim PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Cursor animation") - -add_executable(accuracy WIN32 MACOSX_BUNDLE accuracy.c) -set_target_properties(accuracy PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Accuracy") - -add_executable(empty WIN32 MACOSX_BUNDLE empty.c ${TINYCTHREAD}) -set_target_properties(empty PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Empty Event") - -add_executable(sharing WIN32 MACOSX_BUNDLE sharing.c) -set_target_properties(sharing PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Sharing") - -add_executable(tearing WIN32 MACOSX_BUNDLE tearing.c) -set_target_properties(tearing PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Tearing") - -add_executable(threads WIN32 MACOSX_BUNDLE threads.c ${TINYCTHREAD}) -set_target_properties(threads PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Threads") - -add_executable(title WIN32 MACOSX_BUNDLE title.c) -set_target_properties(title PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Title") - -add_executable(windows WIN32 MACOSX_BUNDLE windows.c) -set_target_properties(windows PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Windows") - -target_link_libraries(empty "${CMAKE_THREAD_LIBS_INIT}" "${RT_LIBRARY}") -target_link_libraries(threads "${CMAKE_THREAD_LIBS_INIT}" "${RT_LIBRARY}") - -set(WINDOWS_BINARIES accuracy empty sharing tearing threads title windows cursoranim) -set(CONSOLE_BINARIES clipboard defaults events fsaa gamma glfwinfo - iconify joysticks modes peter reopen cursor) - -set_target_properties(${WINDOWS_BINARIES} ${CONSOLE_BINARIES} PROPERTIES - FOLDER "GLFW3/Tests") - -if (MSVC) - # Tell MSVC to use main instead of WinMain for Windows subsystem executables - set_target_properties(${WINDOWS_BINARIES} ${CONSOLE_BINARIES} PROPERTIES - LINK_FLAGS "/ENTRY:mainCRTStartup") -endif() - -if (APPLE) - set_target_properties(${WINDOWS_BINARIES} ${CONSOLE_BINARIES} PROPERTIES - MACOSX_BUNDLE_SHORT_VERSION_STRING ${GLFW_VERSION} - MACOSX_BUNDLE_LONG_VERSION_STRING ${GLFW_VERSION_FULL}) -endif() - diff --git a/examples/common/glfw/tests/accuracy.c b/examples/common/glfw/tests/accuracy.c deleted file mode 100644 index 6a63c889..00000000 --- a/examples/common/glfw/tests/accuracy.c +++ /dev/null @@ -1,128 +0,0 @@ -//======================================================================== -// Mouse cursor accuracy test -// Copyright (c) Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== -// -// This test came about as the result of bug #1867804 -// -// No sign of said bug has so far been detected -// -//======================================================================== - -#include - -#include -#include - -static double cursor_x = 0.0, cursor_y = 0.0; -static int window_width = 640, window_height = 480; -static int swap_interval = 1; - -static void set_swap_interval(GLFWwindow* window, int interval) -{ - char title[256]; - - swap_interval = interval; - glfwSwapInterval(swap_interval); - - sprintf(title, "Cursor Inaccuracy Detector (interval %i)", swap_interval); - - glfwSetWindowTitle(window, title); -} - -static void error_callback(int error, const char* description) -{ - fprintf(stderr, "Error: %s\n", description); -} - -static void framebuffer_size_callback(GLFWwindow* window, int width, int height) -{ - window_width = width; - window_height = height; - - glViewport(0, 0, window_width, window_height); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0.f, window_width, 0.f, window_height, 0.f, 1.f); -} - -static void cursor_position_callback(GLFWwindow* window, double x, double y) -{ - cursor_x = x; - cursor_y = y; -} - -static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) -{ - if (key == GLFW_KEY_SPACE && action == GLFW_PRESS) - set_swap_interval(window, 1 - swap_interval); -} - -int main(void) -{ - GLFWwindow* window; - int width, height; - - glfwSetErrorCallback(error_callback); - - if (!glfwInit()) - exit(EXIT_FAILURE); - - window = glfwCreateWindow(window_width, window_height, "", NULL, NULL); - if (!window) - { - glfwTerminate(); - exit(EXIT_FAILURE); - } - - glfwSetCursorPosCallback(window, cursor_position_callback); - glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); - glfwSetKeyCallback(window, key_callback); - - glfwMakeContextCurrent(window); - - glfwGetFramebufferSize(window, &width, &height); - framebuffer_size_callback(window, width, height); - - set_swap_interval(window, swap_interval); - - while (!glfwWindowShouldClose(window)) - { - glClear(GL_COLOR_BUFFER_BIT); - - glBegin(GL_LINES); - glVertex2f(0.f, (GLfloat) (window_height - cursor_y)); - glVertex2f((GLfloat) window_width, (GLfloat) (window_height - cursor_y)); - glVertex2f((GLfloat) cursor_x, 0.f); - glVertex2f((GLfloat) cursor_x, (GLfloat) window_height); - glEnd(); - - glfwSwapBuffers(window); - glfwPollEvents(); - } - - glfwTerminate(); - exit(EXIT_SUCCESS); -} - diff --git a/examples/common/glfw/tests/clipboard.c b/examples/common/glfw/tests/clipboard.c deleted file mode 100644 index 43422845..00000000 --- a/examples/common/glfw/tests/clipboard.c +++ /dev/null @@ -1,149 +0,0 @@ -//======================================================================== -// Clipboard test program -// Copyright (c) Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== -// -// This program is used to test the clipboard functionality. -// -//======================================================================== - -#include - -#include -#include - -#include "getopt.h" - -static void usage(void) -{ - printf("Usage: clipboard [-h]\n"); -} - -static void error_callback(int error, const char* description) -{ - fprintf(stderr, "Error: %s\n", description); -} - -static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) -{ - if (action != GLFW_PRESS) - return; - - switch (key) - { - case GLFW_KEY_ESCAPE: - glfwSetWindowShouldClose(window, GL_TRUE); - break; - - case GLFW_KEY_V: - if (mods == GLFW_MOD_CONTROL) - { - const char* string; - - string = glfwGetClipboardString(window); - if (string) - printf("Clipboard contains \"%s\"\n", string); - else - printf("Clipboard does not contain a string\n"); - } - break; - - case GLFW_KEY_C: - if (mods == GLFW_MOD_CONTROL) - { - const char* string = "Hello GLFW World!"; - glfwSetClipboardString(window, string); - printf("Setting clipboard to \"%s\"\n", string); - } - break; - } -} - -static void framebuffer_size_callback(GLFWwindow* window, int width, int height) -{ - glViewport(0, 0, width, height); -} - -int main(int argc, char** argv) -{ - int ch; - GLFWwindow* window; - - while ((ch = getopt(argc, argv, "h")) != -1) - { - switch (ch) - { - case 'h': - usage(); - exit(EXIT_SUCCESS); - - default: - usage(); - exit(EXIT_FAILURE); - } - } - - glfwSetErrorCallback(error_callback); - - if (!glfwInit()) - { - fprintf(stderr, "Failed to initialize GLFW\n"); - exit(EXIT_FAILURE); - } - - window = glfwCreateWindow(200, 200, "Clipboard Test", NULL, NULL); - if (!window) - { - glfwTerminate(); - - fprintf(stderr, "Failed to open GLFW window\n"); - exit(EXIT_FAILURE); - } - - glfwMakeContextCurrent(window); - glfwSwapInterval(1); - - glfwSetKeyCallback(window, key_callback); - glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); - - glMatrixMode(GL_PROJECTION); - glOrtho(-1.f, 1.f, -1.f, 1.f, -1.f, 1.f); - glMatrixMode(GL_MODELVIEW); - - glClearColor(0.5f, 0.5f, 0.5f, 0); - - while (!glfwWindowShouldClose(window)) - { - glClear(GL_COLOR_BUFFER_BIT); - - glColor3f(0.8f, 0.2f, 0.4f); - glRectf(-0.5f, -0.5f, 0.5f, 0.5f); - - glfwSwapBuffers(window); - glfwWaitEvents(); - } - - glfwTerminate(); - exit(EXIT_SUCCESS); -} - diff --git a/examples/common/glfw/tests/cursor.c b/examples/common/glfw/tests/cursor.c deleted file mode 100644 index 9b899266..00000000 --- a/examples/common/glfw/tests/cursor.c +++ /dev/null @@ -1,289 +0,0 @@ -//======================================================================== -// Cursor & input mode tests -// Copyright (c) Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== -// -// System cursors and input modes tests. -// -//======================================================================== - -#define GLFW_INCLUDE_GLU -#include - -#include -#include - -static int W = 640; -static int H = 480; -static int delay = 0; - -static GLFWwindow* windows[2] = { NULL, NULL }; -static GLFWwindow* activeWindow = NULL; -static GLFWcursor* cursor = NULL; - -static struct -{ - int key; - double time; -} commands[] = { - {GLFW_KEY_H, 0}, - {GLFW_KEY_C, 0}, - {GLFW_KEY_D, 0}, - {GLFW_KEY_S, 0}, - {GLFW_KEY_N, 0}, - {GLFW_KEY_1, 0}, - {GLFW_KEY_2, 0}, - {GLFW_KEY_3, 0} -}; - -static int CommandCount = sizeof(commands) / sizeof(commands[0]); - -static struct -{ - int w, h; -} cursorSize[] = { - { 24, 24 }, { 13, 37 }, { 5, 53 }, { 43, 64 }, { 300, 300 } -}; - -static int SizeCount = sizeof(cursorSize) / sizeof(cursorSize[0]); -static int currentSize = 0; - -static void command_callback(int key) -{ - switch (key) - { - case GLFW_KEY_H: - { - printf("H: show this help\n"); - printf("C: call glfwCreateCursor()\n"); - printf("D: call glfwDestroyCursor()\n"); - printf("S: call glfwSetCursor()\n"); - printf("N: call glfwSetCursor() with NULL\n"); - printf("1: set GLFW_CURSOR_NORMAL\n"); - printf("2: set GLFW_CURSOR_HIDDEN\n"); - printf("3: set GLFW_CURSOR_DISABLED\n"); - printf("T: enable 3s delay for all previous commands\n"); - } - break; - - case GLFW_KEY_C: - { - int x, y; - GLFWimage image; - unsigned char* pixels; - - if (cursor) - break; - - image.width = cursorSize[currentSize].w; - image.height = cursorSize[currentSize].h; - - pixels = malloc(4 * image.width * image.height); - image.pixels = pixels; - - for (y = 0; y < image.height; y++) - { - for (x = 0; x < image.width; x++) - { - *pixels++ = 0xff; - *pixels++ = 0; - *pixels++ = 255 * y / image.height; - *pixels++ = 255 * x / image.width; - } - } - - cursor = glfwCreateCursor(&image, image.width / 2, image.height / 2); - currentSize = (currentSize + 1) % SizeCount; - free(image.pixels); - break; - } - - case GLFW_KEY_D: - { - if (cursor != NULL) - { - glfwDestroyCursor(cursor); - cursor = NULL; - } - - break; - } - - case GLFW_KEY_S: - { - if (cursor != NULL) - glfwSetCursor(activeWindow, cursor); - else - printf("The cursor is not created\n"); - - break; - } - - case GLFW_KEY_N: - glfwSetCursor(activeWindow, NULL); - break; - - case GLFW_KEY_1: - glfwSetInputMode(activeWindow, GLFW_CURSOR, GLFW_CURSOR_NORMAL); - break; - - case GLFW_KEY_2: - glfwSetInputMode(activeWindow, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); - break; - - case GLFW_KEY_3: - glfwSetInputMode(activeWindow, GLFW_CURSOR, GLFW_CURSOR_DISABLED); - break; - } -} - -static void error_callback(int error, const char* description) -{ - fprintf(stderr, "Error: %s\n", description); -} - -static void framebuffer_size_callback(GLFWwindow* window, int width, int height) -{ - W = width; - H = height; - - glViewport(0, 0, W, H); -} - -static void refresh_callback(GLFWwindow* window) -{ - glfwMakeContextCurrent(window); - glClearColor(0.0f, window == activeWindow ? 0.8f : 0.0f, 0.0f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT); - glfwSwapBuffers(window); -} - -static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) -{ - if (action != GLFW_PRESS) - return; - - switch (key) - { - case GLFW_KEY_ESCAPE: - glfwSetWindowShouldClose(window, GL_TRUE); - break; - - case GLFW_KEY_T: - delay = !delay; - printf("Delay %s.\n", delay ? "enabled" : "disabled"); - break; - - default: - { - if (delay) - { - int i = 0; - - while (i < CommandCount && commands[i].key != key) - i++; - - if (i < CommandCount) - commands[i].time = glfwGetTime(); - } - else - { - command_callback(key); - } - } - break; - } -} - -static void focus_callback(GLFWwindow* window, int focused) -{ - if (focused) - { - activeWindow = window; - refresh_callback(windows[0]); - refresh_callback(windows[1]); - } -} - -int main(void) -{ - int i; - GLboolean running = GL_TRUE; - - glfwSetErrorCallback(error_callback); - - if (!glfwInit()) - exit(EXIT_FAILURE); - - for (i = 0; i < 2; i++) - { - windows[i] = glfwCreateWindow(W, H, "Cursor testing", NULL, NULL); - - if (!windows[i]) - { - glfwTerminate(); - exit(EXIT_FAILURE); - } - - glfwSetWindowPos(windows[i], 100 + (i & 1) * (W + 50), 100); - - glfwSetWindowRefreshCallback(windows[i], refresh_callback); - glfwSetFramebufferSizeCallback(windows[i], framebuffer_size_callback); - glfwSetKeyCallback(windows[i], key_callback); - glfwSetWindowFocusCallback(windows[i], focus_callback); - - glfwMakeContextCurrent(windows[i]); - glClear(GL_COLOR_BUFFER_BIT); - glfwSwapBuffers(windows[i]); - } - - activeWindow = windows[0]; - - key_callback(NULL, GLFW_KEY_H, 0, GLFW_PRESS, 0); - - while (running) - { - if (delay) - { - int i; - double t = glfwGetTime(); - - for (i = 0; i < CommandCount; i++) - { - if (commands[i].time != 0 && t - commands[i].time >= 3.0) - { - command_callback(commands[i].key); - commands[i].time = 0; - } - } - } - - running = !(glfwWindowShouldClose(windows[0]) || glfwWindowShouldClose(windows[1])); - - glfwPollEvents(); - } - - glfwTerminate(); - exit(EXIT_SUCCESS); -} - diff --git a/examples/common/glfw/tests/cursoranim.c b/examples/common/glfw/tests/cursoranim.c deleted file mode 100644 index 39a229c8..00000000 --- a/examples/common/glfw/tests/cursoranim.c +++ /dev/null @@ -1,135 +0,0 @@ -//======================================================================== -// Cursor animation -// Copyright (c) Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== -// -// Cursor animation test. -// -//======================================================================== - -#include - -#include -#include - -#ifdef min - #undef min -#endif -#ifdef max - #undef max -#endif - -#define SIZE 64 // cursor size (width & height) -#define N 60 // number of frames - -unsigned char buffer[4 * SIZE * SIZE]; - -static float max(float a, float b) { return a > b ? a : b; } -static float min(float a, float b) { return a < b ? a : b; } - -static float star(int x, int y, float t) -{ - float c = SIZE / 2.0f; - - float i = (0.25f * (float)sin(2.0f * 3.1415926f * t) + 0.75f); - float k = SIZE * 0.046875f * i; - - float dist = (float)sqrt((x - c) * (x - c) + (y - c) * (y - c)); - - float salpha = 1.0f - dist / c; - float xalpha = (float)x == c ? c : k / (float)fabs(x - c); - float yalpha = (float)y == c ? c : k / (float)fabs(y - c); - - return max(0.0f, min(1.0f, i * salpha * 0.2f + salpha * xalpha * yalpha)); -} - -static GLFWcursor* load_frame(float t) -{ - int i = 0, x, y; - const GLFWimage image = { SIZE, SIZE, buffer }; - - for (y = 0; y < image.width; y++) - { - for (x = 0; x < image.height; x++) - { - buffer[i++] = 255; - buffer[i++] = 255; - buffer[i++] = 255; - buffer[i++] = (unsigned char)(255 * star(x, y, t)); - } - } - - return glfwCreateCursor(&image, image.width / 2, image.height / 2); -} - -int main(void) -{ - int i; - double t0, t1, frameTime = 0.0; - - GLFWwindow* window; - GLFWcursor* frames[N]; - - if (!glfwInit()) - exit(EXIT_FAILURE); - - window = glfwCreateWindow(640, 480, "Cursor animation", NULL, NULL); - - if (!window) - { - glfwTerminate(); - exit(EXIT_FAILURE); - } - - glfwMakeContextCurrent(window); - glfwSwapInterval(1); - - for (i = 0; i < N; i++) - frames[i] = load_frame(i / (float)N); - - i = 0; - - t0 = glfwGetTime(); - - while (!glfwWindowShouldClose(window)) - { - glClear(GL_COLOR_BUFFER_BIT); - glfwSetCursor(window, frames[i]); - glfwSwapBuffers(window); - glfwPollEvents(); - - t1 = glfwGetTime(); - frameTime += t1 - t0; - t0 = t1; - - while (frameTime > 1.0 / (double)N) - { - i = (i + 1) % N; - frameTime -= 1.0 / (double)N; - } - } - - glfwTerminate(); - exit(EXIT_SUCCESS); -} - diff --git a/examples/common/glfw/tests/defaults.c b/examples/common/glfw/tests/defaults.c deleted file mode 100644 index 07ba5a45..00000000 --- a/examples/common/glfw/tests/defaults.c +++ /dev/null @@ -1,131 +0,0 @@ -//======================================================================== -// Default window/context test -// Copyright (c) Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== -// -// This test creates a windowed mode window with all window hints set to -// default values and then reports the actual attributes of the created -// window and context -// -//======================================================================== - -#define GLFW_INCLUDE_GLEXT -#include - -#include -#include - -typedef struct -{ - int attrib; - const char* ext; - const char* name; -} AttribGL; - -typedef struct -{ - int attrib; - const char* name; -} AttribGLFW; - -static AttribGL gl_attribs[] = -{ - { GL_RED_BITS, NULL, "red bits" }, - { GL_GREEN_BITS, NULL, "green bits" }, - { GL_BLUE_BITS, NULL, "blue bits" }, - { GL_ALPHA_BITS, NULL, "alpha bits" }, - { GL_DEPTH_BITS, NULL, "depth bits" }, - { GL_STENCIL_BITS, NULL, "stencil bits" }, - { GL_STEREO, NULL, "stereo" }, - { GL_SAMPLES_ARB, "GL_ARB_multisample", "FSAA samples" }, - { 0, NULL, NULL } -}; - -static AttribGLFW glfw_attribs[] = -{ - { GLFW_CONTEXT_VERSION_MAJOR, "Context version major" }, - { GLFW_CONTEXT_VERSION_MINOR, "Context version minor" }, - { GLFW_OPENGL_FORWARD_COMPAT, "OpenGL forward compatible" }, - { GLFW_OPENGL_DEBUG_CONTEXT, "OpenGL debug context" }, - { GLFW_OPENGL_PROFILE, "OpenGL profile" }, - { 0, NULL } -}; - -static void error_callback(int error, const char* description) -{ - fprintf(stderr, "Error: %s\n", description); -} - -int main(void) -{ - int i, width, height; - GLFWwindow* window; - - glfwSetErrorCallback(error_callback); - - if (!glfwInit()) - exit(EXIT_FAILURE); - - glfwWindowHint(GLFW_VISIBLE, GL_FALSE); - - window = glfwCreateWindow(640, 480, "Defaults", NULL, NULL); - if (!window) - { - glfwTerminate(); - exit(EXIT_FAILURE); - } - - glfwMakeContextCurrent(window); - glfwGetFramebufferSize(window, &width, &height); - - printf("framebuffer size: %ix%i\n", width, height); - - for (i = 0; glfw_attribs[i].name; i++) - { - printf("%s: %i\n", - glfw_attribs[i].name, - glfwGetWindowAttrib(window, glfw_attribs[i].attrib)); - } - - for (i = 0; gl_attribs[i].name; i++) - { - GLint value = 0; - - if (gl_attribs[i].ext) - { - if (!glfwExtensionSupported(gl_attribs[i].ext)) - continue; - } - - glGetIntegerv(gl_attribs[i].attrib, &value); - - printf("%s: %i\n", gl_attribs[i].name, value); - } - - glfwDestroyWindow(window); - window = NULL; - - glfwTerminate(); - exit(EXIT_SUCCESS); -} - diff --git a/examples/common/glfw/tests/empty.c b/examples/common/glfw/tests/empty.c deleted file mode 100644 index a4534ae5..00000000 --- a/examples/common/glfw/tests/empty.c +++ /dev/null @@ -1,129 +0,0 @@ -//======================================================================== -// Empty event test -// Copyright (c) Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== -// -// This test is intended to verify that posting of empty events works -// -//======================================================================== - -#include "tinycthread.h" - -#include - -#include -#include -#include - -static volatile GLboolean running = GL_TRUE; - -static void error_callback(int error, const char* description) -{ - fprintf(stderr, "Error: %s\n", description); -} - -static int thread_main(void* data) -{ - struct timespec time; - - while (running) - { - clock_gettime(CLOCK_REALTIME, &time); - time.tv_sec += 1; - thrd_sleep(&time, NULL); - - glfwPostEmptyEvent(); - } - - return 0; -} - -static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) -{ - if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) - glfwSetWindowShouldClose(window, GL_TRUE); -} - -static float nrand(void) -{ - return (float) rand() / (float) RAND_MAX; -} - -int main(void) -{ - int result; - thrd_t thread; - GLFWwindow* window; - - srand((unsigned int) time(NULL)); - - glfwSetErrorCallback(error_callback); - - if (!glfwInit()) - exit(EXIT_FAILURE); - - window = glfwCreateWindow(640, 480, "Empty Event Test", NULL, NULL); - if (!window) - { - glfwTerminate(); - exit(EXIT_FAILURE); - } - - glfwMakeContextCurrent(window); - glfwSetKeyCallback(window, key_callback); - - if (thrd_create(&thread, thread_main, NULL) != thrd_success) - { - fprintf(stderr, "Failed to create secondary thread\n"); - - glfwTerminate(); - exit(EXIT_FAILURE); - } - - while (running) - { - int width, height; - float r = nrand(), g = nrand(), b = nrand(); - float l = (float) sqrt(r * r + g * g + b * b); - - glfwGetFramebufferSize(window, &width, &height); - - glViewport(0, 0, width, height); - glClearColor(r / l, g / l, b / l, 1.f); - glClear(GL_COLOR_BUFFER_BIT); - glfwSwapBuffers(window); - - glfwWaitEvents(); - - if (glfwWindowShouldClose(window)) - running = GL_FALSE; - } - - glfwHideWindow(window); - thrd_join(thread, &result); - glfwDestroyWindow(window); - - glfwTerminate(); - exit(EXIT_SUCCESS); -} - diff --git a/examples/common/glfw/tests/events.c b/examples/common/glfw/tests/events.c deleted file mode 100644 index fda68164..00000000 --- a/examples/common/glfw/tests/events.c +++ /dev/null @@ -1,581 +0,0 @@ -//======================================================================== -// Event linter (event spewer) -// Copyright (c) Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== -// -// This test hooks every available callback and outputs their arguments -// -// Log messages go to stdout, error messages to stderr -// -// Every event also gets a (sequential) number to aid discussion of logs -// -//======================================================================== - -#include - -#include -#include -#include -#include -#include - -#include "getopt.h" - -// Event index -static unsigned int counter = 0; - -typedef struct -{ - GLFWwindow* window; - int number; - int closeable; -} Slot; - -static void usage(void) -{ - printf("Usage: events [-f] [-h] [-n WINDOWS]\n"); - printf("Options:\n"); - printf(" -f use full screen\n"); - printf(" -h show this help\n"); - printf(" -n the number of windows to create\n"); -} - -static const char* get_key_name(int key) -{ - switch (key) - { - // Printable keys - case GLFW_KEY_A: return "A"; - case GLFW_KEY_B: return "B"; - case GLFW_KEY_C: return "C"; - case GLFW_KEY_D: return "D"; - case GLFW_KEY_E: return "E"; - case GLFW_KEY_F: return "F"; - case GLFW_KEY_G: return "G"; - case GLFW_KEY_H: return "H"; - case GLFW_KEY_I: return "I"; - case GLFW_KEY_J: return "J"; - case GLFW_KEY_K: return "K"; - case GLFW_KEY_L: return "L"; - case GLFW_KEY_M: return "M"; - case GLFW_KEY_N: return "N"; - case GLFW_KEY_O: return "O"; - case GLFW_KEY_P: return "P"; - case GLFW_KEY_Q: return "Q"; - case GLFW_KEY_R: return "R"; - case GLFW_KEY_S: return "S"; - case GLFW_KEY_T: return "T"; - case GLFW_KEY_U: return "U"; - case GLFW_KEY_V: return "V"; - case GLFW_KEY_W: return "W"; - case GLFW_KEY_X: return "X"; - case GLFW_KEY_Y: return "Y"; - case GLFW_KEY_Z: return "Z"; - case GLFW_KEY_1: return "1"; - case GLFW_KEY_2: return "2"; - case GLFW_KEY_3: return "3"; - case GLFW_KEY_4: return "4"; - case GLFW_KEY_5: return "5"; - case GLFW_KEY_6: return "6"; - case GLFW_KEY_7: return "7"; - case GLFW_KEY_8: return "8"; - case GLFW_KEY_9: return "9"; - case GLFW_KEY_0: return "0"; - case GLFW_KEY_SPACE: return "SPACE"; - case GLFW_KEY_MINUS: return "MINUS"; - case GLFW_KEY_EQUAL: return "EQUAL"; - case GLFW_KEY_LEFT_BRACKET: return "LEFT BRACKET"; - case GLFW_KEY_RIGHT_BRACKET: return "RIGHT BRACKET"; - case GLFW_KEY_BACKSLASH: return "BACKSLASH"; - case GLFW_KEY_SEMICOLON: return "SEMICOLON"; - case GLFW_KEY_APOSTROPHE: return "APOSTROPHE"; - case GLFW_KEY_GRAVE_ACCENT: return "GRAVE ACCENT"; - case GLFW_KEY_COMMA: return "COMMA"; - case GLFW_KEY_PERIOD: return "PERIOD"; - case GLFW_KEY_SLASH: return "SLASH"; - case GLFW_KEY_WORLD_1: return "WORLD 1"; - case GLFW_KEY_WORLD_2: return "WORLD 2"; - - // Function keys - case GLFW_KEY_ESCAPE: return "ESCAPE"; - case GLFW_KEY_F1: return "F1"; - case GLFW_KEY_F2: return "F2"; - case GLFW_KEY_F3: return "F3"; - case GLFW_KEY_F4: return "F4"; - case GLFW_KEY_F5: return "F5"; - case GLFW_KEY_F6: return "F6"; - case GLFW_KEY_F7: return "F7"; - case GLFW_KEY_F8: return "F8"; - case GLFW_KEY_F9: return "F9"; - case GLFW_KEY_F10: return "F10"; - case GLFW_KEY_F11: return "F11"; - case GLFW_KEY_F12: return "F12"; - case GLFW_KEY_F13: return "F13"; - case GLFW_KEY_F14: return "F14"; - case GLFW_KEY_F15: return "F15"; - case GLFW_KEY_F16: return "F16"; - case GLFW_KEY_F17: return "F17"; - case GLFW_KEY_F18: return "F18"; - case GLFW_KEY_F19: return "F19"; - case GLFW_KEY_F20: return "F20"; - case GLFW_KEY_F21: return "F21"; - case GLFW_KEY_F22: return "F22"; - case GLFW_KEY_F23: return "F23"; - case GLFW_KEY_F24: return "F24"; - case GLFW_KEY_F25: return "F25"; - case GLFW_KEY_UP: return "UP"; - case GLFW_KEY_DOWN: return "DOWN"; - case GLFW_KEY_LEFT: return "LEFT"; - case GLFW_KEY_RIGHT: return "RIGHT"; - case GLFW_KEY_LEFT_SHIFT: return "LEFT SHIFT"; - case GLFW_KEY_RIGHT_SHIFT: return "RIGHT SHIFT"; - case GLFW_KEY_LEFT_CONTROL: return "LEFT CONTROL"; - case GLFW_KEY_RIGHT_CONTROL: return "RIGHT CONTROL"; - case GLFW_KEY_LEFT_ALT: return "LEFT ALT"; - case GLFW_KEY_RIGHT_ALT: return "RIGHT ALT"; - case GLFW_KEY_TAB: return "TAB"; - case GLFW_KEY_ENTER: return "ENTER"; - case GLFW_KEY_BACKSPACE: return "BACKSPACE"; - case GLFW_KEY_INSERT: return "INSERT"; - case GLFW_KEY_DELETE: return "DELETE"; - case GLFW_KEY_PAGE_UP: return "PAGE UP"; - case GLFW_KEY_PAGE_DOWN: return "PAGE DOWN"; - case GLFW_KEY_HOME: return "HOME"; - case GLFW_KEY_END: return "END"; - case GLFW_KEY_KP_0: return "KEYPAD 0"; - case GLFW_KEY_KP_1: return "KEYPAD 1"; - case GLFW_KEY_KP_2: return "KEYPAD 2"; - case GLFW_KEY_KP_3: return "KEYPAD 3"; - case GLFW_KEY_KP_4: return "KEYPAD 4"; - case GLFW_KEY_KP_5: return "KEYPAD 5"; - case GLFW_KEY_KP_6: return "KEYPAD 6"; - case GLFW_KEY_KP_7: return "KEYPAD 7"; - case GLFW_KEY_KP_8: return "KEYPAD 8"; - case GLFW_KEY_KP_9: return "KEYPAD 9"; - case GLFW_KEY_KP_DIVIDE: return "KEYPAD DIVIDE"; - case GLFW_KEY_KP_MULTIPLY: return "KEYPAD MULTPLY"; - case GLFW_KEY_KP_SUBTRACT: return "KEYPAD SUBTRACT"; - case GLFW_KEY_KP_ADD: return "KEYPAD ADD"; - case GLFW_KEY_KP_DECIMAL: return "KEYPAD DECIMAL"; - case GLFW_KEY_KP_EQUAL: return "KEYPAD EQUAL"; - case GLFW_KEY_KP_ENTER: return "KEYPAD ENTER"; - case GLFW_KEY_PRINT_SCREEN: return "PRINT SCREEN"; - case GLFW_KEY_NUM_LOCK: return "NUM LOCK"; - case GLFW_KEY_CAPS_LOCK: return "CAPS LOCK"; - case GLFW_KEY_SCROLL_LOCK: return "SCROLL LOCK"; - case GLFW_KEY_PAUSE: return "PAUSE"; - case GLFW_KEY_LEFT_SUPER: return "LEFT SUPER"; - case GLFW_KEY_RIGHT_SUPER: return "RIGHT SUPER"; - case GLFW_KEY_MENU: return "MENU"; - - default: return "UNKNOWN"; - } -} - -static const char* get_action_name(int action) -{ - switch (action) - { - case GLFW_PRESS: - return "pressed"; - case GLFW_RELEASE: - return "released"; - case GLFW_REPEAT: - return "repeated"; - } - - return "caused unknown action"; -} - -static const char* get_button_name(int button) -{ - switch (button) - { - case GLFW_MOUSE_BUTTON_LEFT: - return "left"; - case GLFW_MOUSE_BUTTON_RIGHT: - return "right"; - case GLFW_MOUSE_BUTTON_MIDDLE: - return "middle"; - default: - { - static char name[16]; - sprintf(name, "%i", button); - return name; - } - } -} - -static const char* get_mods_name(int mods) -{ - static char name[512]; - - if (mods == 0) - return " no mods"; - - name[0] = '\0'; - - if (mods & GLFW_MOD_SHIFT) - strcat(name, " shift"); - if (mods & GLFW_MOD_CONTROL) - strcat(name, " control"); - if (mods & GLFW_MOD_ALT) - strcat(name, " alt"); - if (mods & GLFW_MOD_SUPER) - strcat(name, " super"); - - return name; -} - -static const char* get_character_string(int codepoint) -{ - // This assumes UTF-8, which is stupid - static char result[6 + 1]; - - int length = wctomb(result, codepoint); - if (length == -1) - length = 0; - - result[length] = '\0'; - return result; -} - -static void error_callback(int error, const char* description) -{ - fprintf(stderr, "Error: %s\n", description); -} - -static void window_pos_callback(GLFWwindow* window, int x, int y) -{ - Slot* slot = glfwGetWindowUserPointer(window); - printf("%08x to %i at %0.3f: Window position: %i %i\n", - counter++, slot->number, glfwGetTime(), x, y); -} - -static void window_size_callback(GLFWwindow* window, int width, int height) -{ - Slot* slot = glfwGetWindowUserPointer(window); - printf("%08x to %i at %0.3f: Window size: %i %i\n", - counter++, slot->number, glfwGetTime(), width, height); -} - -static void framebuffer_size_callback(GLFWwindow* window, int width, int height) -{ - Slot* slot = glfwGetWindowUserPointer(window); - printf("%08x to %i at %0.3f: Framebuffer size: %i %i\n", - counter++, slot->number, glfwGetTime(), width, height); - - glViewport(0, 0, width, height); -} - -static void window_close_callback(GLFWwindow* window) -{ - Slot* slot = glfwGetWindowUserPointer(window); - printf("%08x to %i at %0.3f: Window close\n", - counter++, slot->number, glfwGetTime()); - - glfwSetWindowShouldClose(window, slot->closeable); -} - -static void window_refresh_callback(GLFWwindow* window) -{ - Slot* slot = glfwGetWindowUserPointer(window); - printf("%08x to %i at %0.3f: Window refresh\n", - counter++, slot->number, glfwGetTime()); - - glfwMakeContextCurrent(window); - glClear(GL_COLOR_BUFFER_BIT); - glfwSwapBuffers(window); -} - -static void window_focus_callback(GLFWwindow* window, int focused) -{ - Slot* slot = glfwGetWindowUserPointer(window); - printf("%08x to %i at %0.3f: Window %s\n", - counter++, slot->number, glfwGetTime(), - focused ? "focused" : "defocused"); -} - -static void window_iconify_callback(GLFWwindow* window, int iconified) -{ - Slot* slot = glfwGetWindowUserPointer(window); - printf("%08x to %i at %0.3f: Window was %s\n", - counter++, slot->number, glfwGetTime(), - iconified ? "iconified" : "restored"); -} - -static void mouse_button_callback(GLFWwindow* window, int button, int action, int mods) -{ - Slot* slot = glfwGetWindowUserPointer(window); - printf("%08x to %i at %0.3f: Mouse button %i (%s) (with%s) was %s\n", - counter++, slot->number, glfwGetTime(), button, - get_button_name(button), - get_mods_name(mods), - get_action_name(action)); -} - -static void cursor_position_callback(GLFWwindow* window, double x, double y) -{ - Slot* slot = glfwGetWindowUserPointer(window); - printf("%08x to %i at %0.3f: Cursor position: %f %f\n", - counter++, slot->number, glfwGetTime(), x, y); -} - -static void cursor_enter_callback(GLFWwindow* window, int entered) -{ - Slot* slot = glfwGetWindowUserPointer(window); - printf("%08x to %i at %0.3f: Cursor %s window\n", - counter++, slot->number, glfwGetTime(), - entered ? "entered" : "left"); -} - -static void scroll_callback(GLFWwindow* window, double x, double y) -{ - Slot* slot = glfwGetWindowUserPointer(window); - printf("%08x to %i at %0.3f: Scroll: %0.3f %0.3f\n", - counter++, slot->number, glfwGetTime(), x, y); -} - -static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) -{ - Slot* slot = glfwGetWindowUserPointer(window); - - printf("%08x to %i at %0.3f: Key 0x%04x Scancode 0x%04x (%s) (with%s) was %s\n", - counter++, slot->number, glfwGetTime(), key, scancode, - get_key_name(key), - get_mods_name(mods), - get_action_name(action)); - - if (action != GLFW_PRESS) - return; - - switch (key) - { - case GLFW_KEY_C: - { - slot->closeable = !slot->closeable; - - printf("(( closing %s ))\n", slot->closeable ? "enabled" : "disabled"); - break; - } - } -} - -static void char_callback(GLFWwindow* window, unsigned int codepoint) -{ - Slot* slot = glfwGetWindowUserPointer(window); - printf("%08x to %i at %0.3f: Character 0x%08x (%s) input\n", - counter++, slot->number, glfwGetTime(), codepoint, - get_character_string(codepoint)); -} - -static void char_mods_callback(GLFWwindow* window, unsigned int codepoint, int mods) -{ - Slot* slot = glfwGetWindowUserPointer(window); - printf("%08x to %i at %0.3f: Character 0x%08x (%s) with modifiers (with%s) input\n", - counter++, slot->number, glfwGetTime(), codepoint, - get_character_string(codepoint), - get_mods_name(mods)); -} - -static void drop_callback(GLFWwindow* window, int count, const char** names) -{ - int i; - Slot* slot = glfwGetWindowUserPointer(window); - - printf("%08x to %i at %0.3f: Drop input\n", - counter++, slot->number, glfwGetTime()); - - for (i = 0; i < count; i++) - printf(" %i: \"%s\"\n", i, names[i]); -} - -static void monitor_callback(GLFWmonitor* monitor, int event) -{ - if (event == GLFW_CONNECTED) - { - int x, y, widthMM, heightMM; - const GLFWvidmode* mode = glfwGetVideoMode(monitor); - - glfwGetMonitorPos(monitor, &x, &y); - glfwGetMonitorPhysicalSize(monitor, &widthMM, &heightMM); - - printf("%08x at %0.3f: Monitor %s (%ix%i at %ix%i, %ix%i mm) was connected\n", - counter++, - glfwGetTime(), - glfwGetMonitorName(monitor), - mode->width, mode->height, - x, y, - widthMM, heightMM); - } - else - { - printf("%08x at %0.3f: Monitor %s was disconnected\n", - counter++, - glfwGetTime(), - glfwGetMonitorName(monitor)); - } -} - -int main(int argc, char** argv) -{ - Slot* slots; - GLFWmonitor* monitor = NULL; - int ch, i, width, height, count = 1; - - setlocale(LC_ALL, ""); - - glfwSetErrorCallback(error_callback); - - if (!glfwInit()) - exit(EXIT_FAILURE); - - printf("Library initialized\n"); - - glfwSetMonitorCallback(monitor_callback); - - while ((ch = getopt(argc, argv, "hfn:")) != -1) - { - switch (ch) - { - case 'h': - usage(); - exit(EXIT_SUCCESS); - - case 'f': - monitor = glfwGetPrimaryMonitor(); - break; - - case 'n': - count = (int) strtol(optarg, NULL, 10); - break; - - default: - usage(); - exit(EXIT_FAILURE); - } - } - - if (monitor) - { - const GLFWvidmode* mode = glfwGetVideoMode(monitor); - - glfwWindowHint(GLFW_REFRESH_RATE, mode->refreshRate); - glfwWindowHint(GLFW_RED_BITS, mode->redBits); - glfwWindowHint(GLFW_GREEN_BITS, mode->greenBits); - glfwWindowHint(GLFW_BLUE_BITS, mode->blueBits); - - width = mode->width; - height = mode->height; - } - else - { - width = 640; - height = 480; - } - - if (!count) - { - fprintf(stderr, "Invalid user\n"); - exit(EXIT_FAILURE); - } - - slots = calloc(count, sizeof(Slot)); - - for (i = 0; i < count; i++) - { - char title[128]; - - slots[i].closeable = GL_TRUE; - slots[i].number = i + 1; - - sprintf(title, "Event Linter (Window %i)", slots[i].number); - - if (monitor) - { - printf("Creating full screen window %i (%ix%i on %s)\n", - slots[i].number, - width, height, - glfwGetMonitorName(monitor)); - } - else - { - printf("Creating windowed mode window %i (%ix%i)\n", - slots[i].number, - width, height); - } - - slots[i].window = glfwCreateWindow(width, height, title, monitor, NULL); - if (!slots[i].window) - { - free(slots); - glfwTerminate(); - exit(EXIT_FAILURE); - } - - glfwSetWindowUserPointer(slots[i].window, slots + i); - - glfwSetWindowPosCallback(slots[i].window, window_pos_callback); - glfwSetWindowSizeCallback(slots[i].window, window_size_callback); - glfwSetFramebufferSizeCallback(slots[i].window, framebuffer_size_callback); - glfwSetWindowCloseCallback(slots[i].window, window_close_callback); - glfwSetWindowRefreshCallback(slots[i].window, window_refresh_callback); - glfwSetWindowFocusCallback(slots[i].window, window_focus_callback); - glfwSetWindowIconifyCallback(slots[i].window, window_iconify_callback); - glfwSetMouseButtonCallback(slots[i].window, mouse_button_callback); - glfwSetCursorPosCallback(slots[i].window, cursor_position_callback); - glfwSetCursorEnterCallback(slots[i].window, cursor_enter_callback); - glfwSetScrollCallback(slots[i].window, scroll_callback); - glfwSetKeyCallback(slots[i].window, key_callback); - glfwSetCharCallback(slots[i].window, char_callback); - glfwSetCharModsCallback(slots[i].window, char_mods_callback); - glfwSetDropCallback(slots[i].window, drop_callback); - - glfwMakeContextCurrent(slots[i].window); - glfwSwapInterval(1); - } - - printf("Main loop starting\n"); - - for (;;) - { - for (i = 0; i < count; i++) - { - if (glfwWindowShouldClose(slots[i].window)) - break; - } - - if (i < count) - break; - - glfwWaitEvents(); - - // Workaround for an issue with msvcrt and mintty - fflush(stdout); - } - - free(slots); - glfwTerminate(); - exit(EXIT_SUCCESS); -} - diff --git a/examples/common/glfw/tests/fsaa.c b/examples/common/glfw/tests/fsaa.c deleted file mode 100644 index b368745a..00000000 --- a/examples/common/glfw/tests/fsaa.c +++ /dev/null @@ -1,162 +0,0 @@ -//======================================================================== -// Full screen anti-aliasing test -// Copyright (c) Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== -// -// This test renders two high contrast, slowly rotating quads, one aliased -// and one (hopefully) anti-aliased, thus allowing for visual verification -// of whether FSAA is indeed enabled -// -//======================================================================== - -#define GLFW_INCLUDE_GLEXT -#include - -#include -#include - -#include "getopt.h" - -static void error_callback(int error, const char* description) -{ - fprintf(stderr, "Error: %s\n", description); -} - -static void framebuffer_size_callback(GLFWwindow* window, int width, int height) -{ - glViewport(0, 0, width, height); -} - -static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) -{ - if (action != GLFW_PRESS) - return; - - switch (key) - { - case GLFW_KEY_SPACE: - glfwSetTime(0.0); - break; - } -} - -static void usage(void) -{ - printf("Usage: fsaa [-h] [-s SAMPLES]\n"); -} - -int main(int argc, char** argv) -{ - int ch, samples = 4; - GLFWwindow* window; - - while ((ch = getopt(argc, argv, "hs:")) != -1) - { - switch (ch) - { - case 'h': - usage(); - exit(EXIT_SUCCESS); - case 's': - samples = atoi(optarg); - break; - default: - usage(); - exit(EXIT_FAILURE); - } - } - - glfwSetErrorCallback(error_callback); - - if (!glfwInit()) - exit(EXIT_FAILURE); - - if (samples) - printf("Requesting FSAA with %i samples\n", samples); - else - printf("Requesting that FSAA not be available\n"); - - glfwWindowHint(GLFW_SAMPLES, samples); - glfwWindowHint(GLFW_VISIBLE, GL_FALSE); - - window = glfwCreateWindow(800, 400, "Aliasing Detector", NULL, NULL); - if (!window) - { - glfwTerminate(); - exit(EXIT_FAILURE); - } - - glfwSetKeyCallback(window, key_callback); - glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); - - glfwMakeContextCurrent(window); - glfwSwapInterval(1); - - if (!glfwExtensionSupported("GL_ARB_multisample")) - { - printf("GL_ARB_multisample extension not supported\n"); - - glfwTerminate(); - exit(EXIT_FAILURE); - } - - glfwShowWindow(window); - - glGetIntegerv(GL_SAMPLES_ARB, &samples); - if (samples) - printf("Context reports FSAA is available with %i samples\n", samples); - else - printf("Context reports FSAA is unavailable\n"); - - glMatrixMode(GL_PROJECTION); - glOrtho(0.f, 1.f, 0.f, 0.5f, 0.f, 1.f); - glMatrixMode(GL_MODELVIEW); - - while (!glfwWindowShouldClose(window)) - { - GLfloat time = (GLfloat) glfwGetTime(); - - glClear(GL_COLOR_BUFFER_BIT); - - glLoadIdentity(); - glTranslatef(0.25f, 0.25f, 0.f); - glRotatef(time, 0.f, 0.f, 1.f); - - glDisable(GL_MULTISAMPLE_ARB); - glRectf(-0.15f, -0.15f, 0.15f, 0.15f); - - glLoadIdentity(); - glTranslatef(0.75f, 0.25f, 0.f); - glRotatef(time, 0.f, 0.f, 1.f); - - glEnable(GL_MULTISAMPLE_ARB); - glRectf(-0.15f, -0.15f, 0.15f, 0.15f); - - glfwSwapBuffers(window); - glfwPollEvents(); - } - - glfwTerminate(); - exit(EXIT_SUCCESS); -} - diff --git a/examples/common/glfw/tests/gamma.c b/examples/common/glfw/tests/gamma.c deleted file mode 100644 index 93a24e6f..00000000 --- a/examples/common/glfw/tests/gamma.c +++ /dev/null @@ -1,181 +0,0 @@ -//======================================================================== -// Gamma correction test program -// Copyright (c) Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== -// -// This program is used to test the gamma correction functionality for -// both full screen and windowed mode windows -// -//======================================================================== - -#include - -#include -#include - -#include "getopt.h" - -#define STEP_SIZE 0.1f - -static GLfloat gamma_value = 1.0f; - -static void usage(void) -{ - printf("Usage: gamma [-h] [-f]\n"); -} - -static void set_gamma(GLFWwindow* window, float value) -{ - GLFWmonitor* monitor = glfwGetWindowMonitor(window); - if (!monitor) - monitor = glfwGetPrimaryMonitor(); - - gamma_value = value; - printf("Gamma: %f\n", gamma_value); - glfwSetGamma(monitor, gamma_value); -} - -static void error_callback(int error, const char* description) -{ - fprintf(stderr, "Error: %s\n", description); -} - -static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) -{ - if (action != GLFW_PRESS) - return; - - switch (key) - { - case GLFW_KEY_ESCAPE: - { - glfwSetWindowShouldClose(window, GL_TRUE); - break; - } - - case GLFW_KEY_KP_ADD: - case GLFW_KEY_Q: - { - set_gamma(window, gamma_value + STEP_SIZE); - break; - } - - case GLFW_KEY_KP_SUBTRACT: - case GLFW_KEY_W: - { - if (gamma_value - STEP_SIZE > 0.f) - set_gamma(window, gamma_value - STEP_SIZE); - - break; - } - } -} - -static void framebuffer_size_callback(GLFWwindow* window, int width, int height) -{ - glViewport(0, 0, width, height); -} - -int main(int argc, char** argv) -{ - int width, height, ch; - GLFWmonitor* monitor = NULL; - GLFWwindow* window; - - glfwSetErrorCallback(error_callback); - - if (!glfwInit()) - exit(EXIT_FAILURE); - - while ((ch = getopt(argc, argv, "fh")) != -1) - { - switch (ch) - { - case 'h': - usage(); - exit(EXIT_SUCCESS); - - case 'f': - monitor = glfwGetPrimaryMonitor(); - break; - - default: - usage(); - exit(EXIT_FAILURE); - } - } - - if (monitor) - { - const GLFWvidmode* mode = glfwGetVideoMode(monitor); - - glfwWindowHint(GLFW_REFRESH_RATE, mode->refreshRate); - glfwWindowHint(GLFW_RED_BITS, mode->redBits); - glfwWindowHint(GLFW_GREEN_BITS, mode->greenBits); - glfwWindowHint(GLFW_BLUE_BITS, mode->blueBits); - - width = mode->width; - height = mode->height; - } - else - { - width = 200; - height = 200; - } - - window = glfwCreateWindow(width, height, "Gamma Test", monitor, NULL); - if (!window) - { - glfwTerminate(); - exit(EXIT_FAILURE); - } - - set_gamma(window, 1.f); - - glfwMakeContextCurrent(window); - glfwSwapInterval(1); - - glfwSetKeyCallback(window, key_callback); - glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); - - glMatrixMode(GL_PROJECTION); - glOrtho(-1.f, 1.f, -1.f, 1.f, -1.f, 1.f); - glMatrixMode(GL_MODELVIEW); - - glClearColor(0.5f, 0.5f, 0.5f, 0); - - while (!glfwWindowShouldClose(window)) - { - glClear(GL_COLOR_BUFFER_BIT); - - glColor3f(0.8f, 0.2f, 0.4f); - glRectf(-0.5f, -0.5f, 0.5f, 0.5f); - - glfwSwapBuffers(window); - glfwWaitEvents(); - } - - glfwTerminate(); - exit(EXIT_SUCCESS); -} - diff --git a/examples/common/glfw/tests/glfwinfo.c b/examples/common/glfw/tests/glfwinfo.c deleted file mode 100644 index f07d7006..00000000 --- a/examples/common/glfw/tests/glfwinfo.c +++ /dev/null @@ -1,429 +0,0 @@ -//======================================================================== -// Version information dumper -// Copyright (c) Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== -// -// This test is a pale imitation of glxinfo(1), except not really -// -// It dumps GLFW and OpenGL version information -// -//======================================================================== - -#include -#include - -#include -#include -#include - -#include "getopt.h" - -#ifdef _MSC_VER -#define strcasecmp(x, y) _stricmp(x, y) -#endif - -#define API_OPENGL "gl" -#define API_OPENGL_ES "es" - -#define PROFILE_NAME_CORE "core" -#define PROFILE_NAME_COMPAT "compat" - -#define STRATEGY_NAME_NONE "none" -#define STRATEGY_NAME_LOSE "lose" - -#define BEHAVIOR_NAME_NONE "none" -#define BEHAVIOR_NAME_FLUSH "flush" - -static void usage(void) -{ - printf("Usage: glfwinfo [-h] [-a API] [-m MAJOR] [-n MINOR] [-d] [-l] [-f] [-p PROFILE] [-s STRATEGY] [-b BEHAVIOR]\n"); - printf("Options:\n"); - printf(" -a the client API to use (" API_OPENGL " or " API_OPENGL_ES ")\n"); - printf(" -b the release behavior to use (" BEHAVIOR_NAME_NONE " or " BEHAVIOR_NAME_FLUSH ")\n"); - printf(" -d request a debug context\n"); - printf(" -f require a forward-compatible context\n"); - printf(" -h show this help\n"); - printf(" -l list all client API extensions after context creation\n"); - printf(" -m the major number of the required client API version\n"); - printf(" -n the minor number of the required client API version\n"); - printf(" -p the OpenGL profile to use (" PROFILE_NAME_CORE " or " PROFILE_NAME_COMPAT ")\n"); - printf(" -s the robustness strategy to use (" STRATEGY_NAME_NONE " or " STRATEGY_NAME_LOSE ")\n"); -} - -static void error_callback(int error, const char* description) -{ - fprintf(stderr, "Error: %s\n", description); -} - -static const char* get_client_api_name(int api) -{ - if (api == GLFW_OPENGL_API) - return "OpenGL"; - else if (api == GLFW_OPENGL_ES_API) - return "OpenGL ES"; - - return "Unknown API"; -} - -static const char* get_profile_name_gl(GLint mask) -{ - if (mask & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) - return PROFILE_NAME_COMPAT; - if (mask & GL_CONTEXT_CORE_PROFILE_BIT) - return PROFILE_NAME_CORE; - - return "unknown"; -} - -static const char* get_profile_name_glfw(int profile) -{ - if (profile == GLFW_OPENGL_COMPAT_PROFILE) - return PROFILE_NAME_COMPAT; - if (profile == GLFW_OPENGL_CORE_PROFILE) - return PROFILE_NAME_CORE; - - return "unknown"; -} - -static const char* get_strategy_name_gl(GLint strategy) -{ - if (strategy == GL_LOSE_CONTEXT_ON_RESET_ARB) - return STRATEGY_NAME_LOSE; - if (strategy == GL_NO_RESET_NOTIFICATION_ARB) - return STRATEGY_NAME_NONE; - - return "unknown"; -} - -static const char* get_strategy_name_glfw(int strategy) -{ - if (strategy == GLFW_LOSE_CONTEXT_ON_RESET) - return STRATEGY_NAME_LOSE; - if (strategy == GLFW_NO_RESET_NOTIFICATION) - return STRATEGY_NAME_NONE; - - return "unknown"; -} - -static void list_extensions(int api, int major, int minor) -{ - int i; - GLint count; - const GLubyte* extensions; - - printf("%s context supported extensions:\n", get_client_api_name(api)); - - if (api == GLFW_OPENGL_API && major > 2) - { - PFNGLGETSTRINGIPROC glGetStringi = (PFNGLGETSTRINGIPROC) glfwGetProcAddress("glGetStringi"); - if (!glGetStringi) - { - glfwTerminate(); - exit(EXIT_FAILURE); - } - - glGetIntegerv(GL_NUM_EXTENSIONS, &count); - - for (i = 0; i < count; i++) - puts((const char*) glGetStringi(GL_EXTENSIONS, i)); - } - else - { - extensions = glGetString(GL_EXTENSIONS); - while (*extensions != '\0') - { - if (*extensions == ' ') - putchar('\n'); - else - putchar(*extensions); - - extensions++; - } - } - - putchar('\n'); -} - -static GLboolean valid_version(void) -{ - int major, minor, revision; - - glfwGetVersion(&major, &minor, &revision); - - printf("GLFW header version: %u.%u.%u\n", - GLFW_VERSION_MAJOR, - GLFW_VERSION_MINOR, - GLFW_VERSION_REVISION); - - printf("GLFW library version: %u.%u.%u\n", major, minor, revision); - - if (major != GLFW_VERSION_MAJOR) - { - printf("*** ERROR: GLFW major version mismatch! ***\n"); - return GL_FALSE; - } - - if (minor != GLFW_VERSION_MINOR || revision != GLFW_VERSION_REVISION) - printf("*** WARNING: GLFW version mismatch! ***\n"); - - printf("GLFW library version string: \"%s\"\n", glfwGetVersionString()); - return GL_TRUE; -} - -int main(int argc, char** argv) -{ - int ch, api = 0, profile = 0, strategy = 0, behavior = 0, major = 1, minor = 0, revision; - GLboolean debug = GL_FALSE, forward = GL_FALSE, list = GL_FALSE; - GLint flags, mask; - GLFWwindow* window; - - while ((ch = getopt(argc, argv, "a:b:dfhlm:n:p:s:")) != -1) - { - switch (ch) - { - case 'a': - if (strcasecmp(optarg, API_OPENGL) == 0) - api = GLFW_OPENGL_API; - else if (strcasecmp(optarg, API_OPENGL_ES) == 0) - api = GLFW_OPENGL_ES_API; - else - { - usage(); - exit(EXIT_FAILURE); - } - break; - case 'b': - if (strcasecmp(optarg, BEHAVIOR_NAME_NONE) == 0) - behavior = GLFW_RELEASE_BEHAVIOR_NONE; - else if (strcasecmp(optarg, BEHAVIOR_NAME_FLUSH) == 0) - behavior = GLFW_RELEASE_BEHAVIOR_FLUSH; - else - { - usage(); - exit(EXIT_FAILURE); - } - break; - case 'd': - debug = GL_TRUE; - break; - case 'f': - forward = GL_TRUE; - break; - case 'h': - usage(); - exit(EXIT_SUCCESS); - case 'l': - list = GL_TRUE; - break; - case 'm': - major = atoi(optarg); - break; - case 'n': - minor = atoi(optarg); - break; - case 'p': - if (strcasecmp(optarg, PROFILE_NAME_CORE) == 0) - profile = GLFW_OPENGL_CORE_PROFILE; - else if (strcasecmp(optarg, PROFILE_NAME_COMPAT) == 0) - profile = GLFW_OPENGL_COMPAT_PROFILE; - else - { - usage(); - exit(EXIT_FAILURE); - } - break; - case 's': - if (strcasecmp(optarg, STRATEGY_NAME_NONE) == 0) - strategy = GLFW_NO_RESET_NOTIFICATION; - else if (strcasecmp(optarg, STRATEGY_NAME_LOSE) == 0) - strategy = GLFW_LOSE_CONTEXT_ON_RESET; - else - { - usage(); - exit(EXIT_FAILURE); - } - break; - default: - usage(); - exit(EXIT_FAILURE); - } - } - - // Initialize GLFW and create window - - if (!valid_version()) - exit(EXIT_FAILURE); - - glfwSetErrorCallback(error_callback); - - if (!glfwInit()) - exit(EXIT_FAILURE); - - if (major != 1 || minor != 0) - { - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, major); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, minor); - } - - if (api != 0) - glfwWindowHint(GLFW_CLIENT_API, api); - - if (debug) - glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE); - - if (forward) - glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); - - if (profile != 0) - glfwWindowHint(GLFW_OPENGL_PROFILE, profile); - - if (strategy) - glfwWindowHint(GLFW_CONTEXT_ROBUSTNESS, strategy); - - if (behavior) - glfwWindowHint(GLFW_CONTEXT_RELEASE_BEHAVIOR, behavior); - - glfwWindowHint(GLFW_RED_BITS, GLFW_DONT_CARE); - glfwWindowHint(GLFW_GREEN_BITS, GLFW_DONT_CARE); - glfwWindowHint(GLFW_BLUE_BITS, GLFW_DONT_CARE); - glfwWindowHint(GLFW_ALPHA_BITS, GLFW_DONT_CARE); - glfwWindowHint(GLFW_DEPTH_BITS, GLFW_DONT_CARE); - glfwWindowHint(GLFW_STENCIL_BITS, GLFW_DONT_CARE); - glfwWindowHint(GLFW_ACCUM_RED_BITS, GLFW_DONT_CARE); - glfwWindowHint(GLFW_ACCUM_GREEN_BITS, GLFW_DONT_CARE); - glfwWindowHint(GLFW_ACCUM_BLUE_BITS, GLFW_DONT_CARE); - glfwWindowHint(GLFW_ACCUM_ALPHA_BITS, GLFW_DONT_CARE); - glfwWindowHint(GLFW_AUX_BUFFERS, GLFW_DONT_CARE); - glfwWindowHint(GLFW_SAMPLES, GLFW_DONT_CARE); - glfwWindowHint(GLFW_SRGB_CAPABLE, GLFW_DONT_CARE); - - glfwWindowHint(GLFW_VISIBLE, GL_FALSE); - - window = glfwCreateWindow(200, 200, "Version", NULL, NULL); - if (!window) - { - glfwTerminate(); - exit(EXIT_FAILURE); - } - - glfwMakeContextCurrent(window); - - // Report client API version - - api = glfwGetWindowAttrib(window, GLFW_CLIENT_API); - major = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MAJOR); - minor = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MINOR); - revision = glfwGetWindowAttrib(window, GLFW_CONTEXT_REVISION); - - printf("%s context version string: \"%s\"\n", - get_client_api_name(api), - glGetString(GL_VERSION)); - - printf("%s context version parsed by GLFW: %u.%u.%u\n", - get_client_api_name(api), - major, minor, revision); - - // Report client API context properties - - if (api == GLFW_OPENGL_API) - { - if (major >= 3) - { - glGetIntegerv(GL_CONTEXT_FLAGS, &flags); - printf("%s context flags (0x%08x):", get_client_api_name(api), flags); - - if (flags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT) - printf(" forward-compatible"); - if (flags & GL_CONTEXT_FLAG_DEBUG_BIT) - printf(" debug"); - if (flags & GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB) - printf(" robustness"); - putchar('\n'); - - printf("%s context flags parsed by GLFW:", get_client_api_name(api)); - - if (glfwGetWindowAttrib(window, GLFW_OPENGL_FORWARD_COMPAT)) - printf(" forward-compatible"); - if (glfwGetWindowAttrib(window, GLFW_OPENGL_DEBUG_CONTEXT)) - printf(" debug"); - if (glfwGetWindowAttrib(window, GLFW_CONTEXT_ROBUSTNESS) != GLFW_NO_ROBUSTNESS) - printf(" robustness"); - putchar('\n'); - } - - if (major > 3 || (major == 3 && minor >= 2)) - { - int profile = glfwGetWindowAttrib(window, GLFW_OPENGL_PROFILE); - - glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &mask); - printf("%s profile mask (0x%08x): %s\n", - get_client_api_name(api), - mask, - get_profile_name_gl(mask)); - - printf("%s profile mask parsed by GLFW: %s\n", - get_client_api_name(api), - get_profile_name_glfw(profile)); - } - - if (glfwExtensionSupported("GL_ARB_robustness")) - { - int robustness; - GLint strategy; - glGetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_ARB, &strategy); - - printf("%s robustness strategy (0x%08x): %s\n", - get_client_api_name(api), - strategy, - get_strategy_name_gl(strategy)); - - robustness = glfwGetWindowAttrib(window, GLFW_CONTEXT_ROBUSTNESS); - - printf("%s robustness strategy parsed by GLFW: %s\n", - get_client_api_name(api), - get_strategy_name_glfw(robustness)); - } - } - - printf("%s context renderer string: \"%s\"\n", - get_client_api_name(api), - glGetString(GL_RENDERER)); - printf("%s context vendor string: \"%s\"\n", - get_client_api_name(api), - glGetString(GL_VENDOR)); - - if (major > 1) - { - printf("%s context shading language version: \"%s\"\n", - get_client_api_name(api), - glGetString(GL_SHADING_LANGUAGE_VERSION)); - } - - // Report client API extensions - if (list) - list_extensions(api, major, minor); - - glfwTerminate(); - exit(EXIT_SUCCESS); -} - diff --git a/examples/common/glfw/tests/iconify.c b/examples/common/glfw/tests/iconify.c deleted file mode 100644 index 037b85ac..00000000 --- a/examples/common/glfw/tests/iconify.c +++ /dev/null @@ -1,254 +0,0 @@ -//======================================================================== -// Iconify/restore test program -// Copyright (c) Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== -// -// This program is used to test the iconify/restore functionality for -// both full screen and windowed mode windows -// -//======================================================================== - -#include - -#include -#include - -#include "getopt.h" - -static void usage(void) -{ - printf("Usage: iconify [-h] [-f [-a] [-n]]\n"); - printf("Options:\n"); - printf(" -a create windows for all monitors\n"); - printf(" -f create full screen window(s)\n"); - printf(" -h show this help\n"); - printf(" -n no automatic iconification of full screen windows\n"); -} - -static void error_callback(int error, const char* description) -{ - fprintf(stderr, "Error: %s\n", description); -} - -static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) -{ - printf("%0.2f Key %s\n", - glfwGetTime(), - action == GLFW_PRESS ? "pressed" : "released"); - - if (action != GLFW_PRESS) - return; - - switch (key) - { - case GLFW_KEY_SPACE: - glfwIconifyWindow(window); - break; - case GLFW_KEY_ESCAPE: - glfwSetWindowShouldClose(window, GL_TRUE); - break; - } -} - -static void window_size_callback(GLFWwindow* window, int width, int height) -{ - printf("%0.2f Window resized to %ix%i\n", glfwGetTime(), width, height); -} - -static void framebuffer_size_callback(GLFWwindow* window, int width, int height) -{ - printf("%0.2f Framebuffer resized to %ix%i\n", glfwGetTime(), width, height); - - glViewport(0, 0, width, height); -} - -static void window_focus_callback(GLFWwindow* window, int focused) -{ - printf("%0.2f Window %s\n", - glfwGetTime(), - focused ? "focused" : "defocused"); -} - -static void window_iconify_callback(GLFWwindow* window, int iconified) -{ - printf("%0.2f Window %s\n", - glfwGetTime(), - iconified ? "iconified" : "restored"); -} - -static void window_refresh_callback(GLFWwindow* window) -{ - int width, height; - glfwGetFramebufferSize(window, &width, &height); - - glfwMakeContextCurrent(window); - - glEnable(GL_SCISSOR_TEST); - - glScissor(0, 0, width, height); - glClearColor(0, 0, 0, 0); - glClear(GL_COLOR_BUFFER_BIT); - - glScissor(0, 0, 640, 480); - glClearColor(1, 1, 1, 0); - glClear(GL_COLOR_BUFFER_BIT); - - glfwSwapBuffers(window); -} - -static GLFWwindow* create_window(GLFWmonitor* monitor) -{ - int width, height; - GLFWwindow* window; - - if (monitor) - { - const GLFWvidmode* mode = glfwGetVideoMode(monitor); - - glfwWindowHint(GLFW_REFRESH_RATE, mode->refreshRate); - glfwWindowHint(GLFW_RED_BITS, mode->redBits); - glfwWindowHint(GLFW_GREEN_BITS, mode->greenBits); - glfwWindowHint(GLFW_BLUE_BITS, mode->blueBits); - - width = mode->width; - height = mode->height; - } - else - { - width = 640; - height = 480; - } - - window = glfwCreateWindow(width, height, "Iconify", monitor, NULL); - if (!window) - { - glfwTerminate(); - exit(EXIT_FAILURE); - } - - return window; -} - -int main(int argc, char** argv) -{ - int ch, i, window_count; - GLboolean auto_iconify = GL_TRUE, fullscreen = GL_FALSE, all_monitors = GL_FALSE; - GLFWwindow** windows; - - while ((ch = getopt(argc, argv, "afhn")) != -1) - { - switch (ch) - { - case 'a': - all_monitors = GL_TRUE; - break; - - case 'h': - usage(); - exit(EXIT_SUCCESS); - - case 'f': - fullscreen = GL_TRUE; - break; - - case 'n': - auto_iconify = GL_FALSE; - break; - - default: - usage(); - exit(EXIT_FAILURE); - } - } - - glfwSetErrorCallback(error_callback); - - if (!glfwInit()) - exit(EXIT_FAILURE); - - glfwWindowHint(GLFW_AUTO_ICONIFY, auto_iconify); - - if (fullscreen && all_monitors) - { - int monitor_count; - GLFWmonitor** monitors = glfwGetMonitors(&monitor_count); - - window_count = monitor_count; - windows = calloc(window_count, sizeof(GLFWwindow*)); - - for (i = 0; i < monitor_count; i++) - { - windows[i] = create_window(monitors[i]); - if (!windows[i]) - break; - } - } - else - { - GLFWmonitor* monitor = NULL; - - if (fullscreen) - monitor = glfwGetPrimaryMonitor(); - - window_count = 1; - windows = calloc(window_count, sizeof(GLFWwindow*)); - windows[0] = create_window(monitor); - } - - for (i = 0; i < window_count; i++) - { - glfwSetKeyCallback(windows[i], key_callback); - glfwSetFramebufferSizeCallback(windows[i], framebuffer_size_callback); - glfwSetWindowSizeCallback(windows[i], window_size_callback); - glfwSetWindowFocusCallback(windows[i], window_focus_callback); - glfwSetWindowIconifyCallback(windows[i], window_iconify_callback); - glfwSetWindowRefreshCallback(windows[i], window_refresh_callback); - - window_refresh_callback(windows[i]); - - printf("Window is %s and %s\n", - glfwGetWindowAttrib(windows[i], GLFW_ICONIFIED) ? "iconified" : "restored", - glfwGetWindowAttrib(windows[i], GLFW_FOCUSED) ? "focused" : "defocused"); - } - - for (;;) - { - glfwPollEvents(); - - for (i = 0; i < window_count; i++) - { - if (glfwWindowShouldClose(windows[i])) - break; - } - - if (i < window_count) - break; - - // Workaround for an issue with msvcrt and mintty - fflush(stdout); - } - - glfwTerminate(); - exit(EXIT_SUCCESS); -} - diff --git a/examples/common/glfw/tests/joysticks.c b/examples/common/glfw/tests/joysticks.c deleted file mode 100644 index a3a5cd7e..00000000 --- a/examples/common/glfw/tests/joysticks.c +++ /dev/null @@ -1,234 +0,0 @@ -//======================================================================== -// Joystick input test -// Copyright (c) Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== -// -// This test displays the state of every button and axis of every connected -// joystick and/or gamepad -// -//======================================================================== - -#include - -#include -#include -#include - -#ifdef _MSC_VER -#define strdup(x) _strdup(x) -#endif - -typedef struct Joystick -{ - GLboolean present; - char* name; - float* axes; - unsigned char* buttons; - int axis_count; - int button_count; -} Joystick; - -static Joystick joysticks[GLFW_JOYSTICK_LAST - GLFW_JOYSTICK_1 + 1]; -static int joystick_count = 0; - -static void error_callback(int error, const char* description) -{ - fprintf(stderr, "Error: %s\n", description); -} - -static void framebuffer_size_callback(GLFWwindow* window, int width, int height) -{ - glViewport(0, 0, width, height); -} - -static void draw_joystick(Joystick* j, int x, int y, int width, int height) -{ - int i; - const int axis_height = 3 * height / 4; - const int button_height = height / 4; - - if (j->axis_count) - { - const int axis_width = width / j->axis_count; - - for (i = 0; i < j->axis_count; i++) - { - float value = j->axes[i] / 2.f + 0.5f; - - glColor3f(0.3f, 0.3f, 0.3f); - glRecti(x + i * axis_width, - y, - x + (i + 1) * axis_width, - y + axis_height); - - glColor3f(1.f, 1.f, 1.f); - glRecti(x + i * axis_width, - y + (int) (value * (axis_height - 5)), - x + (i + 1) * axis_width, - y + 5 + (int) (value * (axis_height - 5))); - } - } - - if (j->button_count) - { - const int button_width = width / j->button_count; - - for (i = 0; i < j->button_count; i++) - { - if (j->buttons[i]) - glColor3f(1.f, 1.f, 1.f); - else - glColor3f(0.3f, 0.3f, 0.3f); - - glRecti(x + i * button_width, - y + axis_height, - x + (i + 1) * button_width, - y + axis_height + button_height); - } - } -} - -static void draw_joysticks(GLFWwindow* window) -{ - int i, width, height; - - glfwGetFramebufferSize(window, &width, &height); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0.f, width, height, 0.f, 1.f, -1.f); - glMatrixMode(GL_MODELVIEW); - - for (i = 0; i < sizeof(joysticks) / sizeof(Joystick); i++) - { - Joystick* j = joysticks + i; - - if (j->present) - { - draw_joystick(j, - 0, i * height / joystick_count, - width, height / joystick_count); - } - } -} - -static void refresh_joysticks(void) -{ - int i; - - for (i = 0; i < sizeof(joysticks) / sizeof(Joystick); i++) - { - Joystick* j = joysticks + i; - - if (glfwJoystickPresent(GLFW_JOYSTICK_1 + i)) - { - const float* axes; - const unsigned char* buttons; - int axis_count, button_count; - - free(j->name); - j->name = strdup(glfwGetJoystickName(GLFW_JOYSTICK_1 + i)); - - axes = glfwGetJoystickAxes(GLFW_JOYSTICK_1 + i, &axis_count); - if (axis_count != j->axis_count) - { - j->axis_count = axis_count; - j->axes = realloc(j->axes, j->axis_count * sizeof(float)); - } - - memcpy(j->axes, axes, axis_count * sizeof(float)); - - buttons = glfwGetJoystickButtons(GLFW_JOYSTICK_1 + i, &button_count); - if (button_count != j->button_count) - { - j->button_count = button_count; - j->buttons = realloc(j->buttons, j->button_count); - } - - memcpy(j->buttons, buttons, button_count * sizeof(unsigned char)); - - if (!j->present) - { - printf("Found joystick %i named \'%s\' with %i axes, %i buttons\n", - i + 1, j->name, j->axis_count, j->button_count); - - joystick_count++; - } - - j->present = GL_TRUE; - } - else - { - if (j->present) - { - printf("Lost joystick %i named \'%s\'\n", i + 1, j->name); - - free(j->name); - free(j->axes); - free(j->buttons); - memset(j, 0, sizeof(Joystick)); - - joystick_count--; - } - } - } -} - -int main(void) -{ - GLFWwindow* window; - - memset(joysticks, 0, sizeof(joysticks)); - - glfwSetErrorCallback(error_callback); - - if (!glfwInit()) - exit(EXIT_FAILURE); - - window = glfwCreateWindow(640, 480, "Joystick Test", NULL, NULL); - if (!window) - { - glfwTerminate(); - exit(EXIT_FAILURE); - } - - glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); - - glfwMakeContextCurrent(window); - glfwSwapInterval(1); - - while (!glfwWindowShouldClose(window)) - { - glClear(GL_COLOR_BUFFER_BIT); - - refresh_joysticks(); - draw_joysticks(window); - - glfwSwapBuffers(window); - glfwPollEvents(); - } - - glfwTerminate(); - exit(EXIT_SUCCESS); -} - diff --git a/examples/common/glfw/tests/modes.c b/examples/common/glfw/tests/modes.c deleted file mode 100644 index 58067e3e..00000000 --- a/examples/common/glfw/tests/modes.c +++ /dev/null @@ -1,240 +0,0 @@ -//======================================================================== -// Video mode test -// Copyright (c) Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== -// -// This test enumerates or verifies video modes -// -//======================================================================== - -#include - -#include -#include -#include - -#include "getopt.h" - -enum Mode -{ - LIST_MODE, - TEST_MODE -}; - -static void usage(void) -{ - printf("Usage: modes [-t]\n"); - printf(" modes -h\n"); -} - -static const char* format_mode(const GLFWvidmode* mode) -{ - static char buffer[512]; - - sprintf(buffer, - "%i x %i x %i (%i %i %i) %i Hz", - mode->width, mode->height, - mode->redBits + mode->greenBits + mode->blueBits, - mode->redBits, mode->greenBits, mode->blueBits, - mode->refreshRate); - - buffer[sizeof(buffer) - 1] = '\0'; - return buffer; -} - -static void error_callback(int error, const char* description) -{ - fprintf(stderr, "Error: %s\n", description); -} - -static void framebuffer_size_callback(GLFWwindow* window, int width, int height) -{ - printf("Framebuffer resized to %ix%i\n", width, height); - - glViewport(0, 0, width, height); -} - -static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) -{ - if (key == GLFW_KEY_ESCAPE) - glfwSetWindowShouldClose(window, GL_TRUE); -} - -static void list_modes(GLFWmonitor* monitor) -{ - int count, x, y, widthMM, heightMM, dpi, i; - const GLFWvidmode* mode = glfwGetVideoMode(monitor); - const GLFWvidmode* modes = glfwGetVideoModes(monitor, &count); - - glfwGetMonitorPos(monitor, &x, &y); - glfwGetMonitorPhysicalSize(monitor, &widthMM, &heightMM); - - printf("Name: %s (%s)\n", - glfwGetMonitorName(monitor), - glfwGetPrimaryMonitor() == monitor ? "primary" : "secondary"); - printf("Current mode: %s\n", format_mode(mode)); - printf("Virtual position: %i %i\n", x, y); - - dpi = (int) ((float) mode->width * 25.4f / (float) widthMM); - printf("Physical size: %i x %i mm (%i dpi)\n", widthMM, heightMM, dpi); - - printf("Modes:\n"); - - for (i = 0; i < count; i++) - { - printf("%3u: %s", (unsigned int) i, format_mode(modes + i)); - - if (memcmp(mode, modes + i, sizeof(GLFWvidmode)) == 0) - printf(" (current mode)"); - - putchar('\n'); - } -} - -static void test_modes(GLFWmonitor* monitor) -{ - int i, count; - GLFWwindow* window; - const GLFWvidmode* modes = glfwGetVideoModes(monitor, &count); - - for (i = 0; i < count; i++) - { - const GLFWvidmode* mode = modes + i; - GLFWvidmode current; - - glfwWindowHint(GLFW_RED_BITS, mode->redBits); - glfwWindowHint(GLFW_GREEN_BITS, mode->greenBits); - glfwWindowHint(GLFW_BLUE_BITS, mode->blueBits); - glfwWindowHint(GLFW_REFRESH_RATE, mode->refreshRate); - - printf("Testing mode %u on monitor %s: %s\n", - (unsigned int) i, - glfwGetMonitorName(monitor), - format_mode(mode)); - - window = glfwCreateWindow(mode->width, mode->height, - "Video Mode Test", - glfwGetPrimaryMonitor(), - NULL); - if (!window) - { - printf("Failed to enter mode %u: %s\n", - (unsigned int) i, - format_mode(mode)); - continue; - } - - glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); - glfwSetKeyCallback(window, key_callback); - - glfwMakeContextCurrent(window); - glfwSwapInterval(1); - - glfwSetTime(0.0); - - while (glfwGetTime() < 5.0) - { - glClear(GL_COLOR_BUFFER_BIT); - glfwSwapBuffers(window); - glfwPollEvents(); - - if (glfwWindowShouldClose(window)) - { - printf("User terminated program\n"); - - glfwTerminate(); - exit(EXIT_SUCCESS); - } - } - - glGetIntegerv(GL_RED_BITS, ¤t.redBits); - glGetIntegerv(GL_GREEN_BITS, ¤t.greenBits); - glGetIntegerv(GL_BLUE_BITS, ¤t.blueBits); - - glfwGetWindowSize(window, ¤t.width, ¤t.height); - - if (current.redBits != mode->redBits || - current.greenBits != mode->greenBits || - current.blueBits != mode->blueBits) - { - printf("*** Color bit mismatch: (%i %i %i) instead of (%i %i %i)\n", - current.redBits, current.greenBits, current.blueBits, - mode->redBits, mode->greenBits, mode->blueBits); - } - - if (current.width != mode->width || current.height != mode->height) - { - printf("*** Size mismatch: %ix%i instead of %ix%i\n", - current.width, current.height, - mode->width, mode->height); - } - - printf("Closing window\n"); - - glfwDestroyWindow(window); - window = NULL; - - glfwPollEvents(); - } -} - -int main(int argc, char** argv) -{ - int ch, i, count, mode = LIST_MODE; - GLFWmonitor** monitors; - - while ((ch = getopt(argc, argv, "th")) != -1) - { - switch (ch) - { - case 'h': - usage(); - exit(EXIT_SUCCESS); - case 't': - mode = TEST_MODE; - break; - default: - usage(); - exit(EXIT_FAILURE); - } - } - - glfwSetErrorCallback(error_callback); - - if (!glfwInit()) - exit(EXIT_FAILURE); - - monitors = glfwGetMonitors(&count); - - for (i = 0; i < count; i++) - { - if (mode == LIST_MODE) - list_modes(monitors[i]); - else if (mode == TEST_MODE) - test_modes(monitors[i]); - } - - glfwTerminate(); - exit(EXIT_SUCCESS); -} - diff --git a/examples/common/glfw/tests/peter.c b/examples/common/glfw/tests/peter.c deleted file mode 100644 index 723167ad..00000000 --- a/examples/common/glfw/tests/peter.c +++ /dev/null @@ -1,151 +0,0 @@ -//======================================================================== -// Cursor mode test -// Copyright (c) Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== -// -// This test allows you to switch between the various cursor modes -// -//======================================================================== - -#include - -#include -#include - -static GLboolean reopen = GL_FALSE; -static double cursor_x; -static double cursor_y; - -static void error_callback(int error, const char* description) -{ - fprintf(stderr, "Error: %s\n", description); -} - -static void cursor_position_callback(GLFWwindow* window, double x, double y) -{ - printf("%0.3f: Cursor position: %f %f (%f %f)\n", - glfwGetTime(), - x, y, x - cursor_x, y - cursor_y); - - cursor_x = x; - cursor_y = y; -} - -static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) -{ - if (action != GLFW_PRESS) - return; - - switch (key) - { - case GLFW_KEY_D: - glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); - printf("(( cursor is disabled ))\n"); - break; - - case GLFW_KEY_H: - glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); - printf("(( cursor is hidden ))\n"); - break; - - case GLFW_KEY_N: - glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); - printf("(( cursor is normal ))\n"); - break; - - case GLFW_KEY_R: - reopen = GL_TRUE; - break; - } -} - -static void framebuffer_size_callback(GLFWwindow* window, int width, int height) -{ - glViewport(0, 0, width, height); -} - -static GLFWwindow* open_window(void) -{ - GLFWwindow* window = glfwCreateWindow(640, 480, "Peter Detector", NULL, NULL); - if (!window) - return NULL; - - glfwMakeContextCurrent(window); - glfwSwapInterval(1); - - glfwGetCursorPos(window, &cursor_x, &cursor_y); - printf("Cursor position: %f %f\n", cursor_x, cursor_y); - - glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); - glfwSetCursorPosCallback(window, cursor_position_callback); - glfwSetKeyCallback(window, key_callback); - - return window; -} - -int main(void) -{ - GLFWwindow* window; - - glfwSetErrorCallback(error_callback); - - if (!glfwInit()) - exit(EXIT_FAILURE); - - window = open_window(); - if (!window) - { - glfwTerminate(); - exit(EXIT_FAILURE); - } - - glClearColor(0.f, 0.f, 0.f, 0.f); - - while (!glfwWindowShouldClose(window)) - { - glClear(GL_COLOR_BUFFER_BIT); - - glfwSwapBuffers(window); - glfwWaitEvents(); - - if (reopen) - { - glfwDestroyWindow(window); - window = open_window(); - if (!window) - { - glfwTerminate(); - exit(EXIT_FAILURE); - } - - reopen = GL_FALSE; - } - - // Workaround for an issue with msvcrt and mintty - fflush(stdout); - } - - glfwTerminate(); - exit(EXIT_SUCCESS); -} - diff --git a/examples/common/glfw/tests/reopen.c b/examples/common/glfw/tests/reopen.c deleted file mode 100644 index 7af8e8a9..00000000 --- a/examples/common/glfw/tests/reopen.c +++ /dev/null @@ -1,177 +0,0 @@ -//======================================================================== -// Window re-opener (open/close stress test) -// Copyright (c) Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== -// -// This test came about as the result of bug #1262773 -// -// It closes and re-opens the GLFW window every five seconds, alternating -// between windowed and full screen mode -// -// It also times and logs opening and closing actions and attempts to separate -// user initiated window closing from its own -// -//======================================================================== - -#include - -#include -#include -#include - -static void error_callback(int error, const char* description) -{ - fprintf(stderr, "Error: %s\n", description); -} - -static void framebuffer_size_callback(GLFWwindow* window, int width, int height) -{ - glViewport(0, 0, width, height); -} - -static void window_close_callback(GLFWwindow* window) -{ - printf("Close callback triggered\n"); -} - -static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) -{ - if (action != GLFW_PRESS) - return; - - switch (key) - { - case GLFW_KEY_Q: - case GLFW_KEY_ESCAPE: - glfwSetWindowShouldClose(window, GL_TRUE); - break; - } -} - -static GLFWwindow* open_window(int width, int height, GLFWmonitor* monitor) -{ - double base; - GLFWwindow* window; - - base = glfwGetTime(); - - window = glfwCreateWindow(width, height, "Window Re-opener", monitor, NULL); - if (!window) - return NULL; - - glfwMakeContextCurrent(window); - glfwSwapInterval(1); - - glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); - glfwSetWindowCloseCallback(window, window_close_callback); - glfwSetKeyCallback(window, key_callback); - - if (monitor) - { - printf("Opening full screen window on monitor %s took %0.3f seconds\n", - glfwGetMonitorName(monitor), - glfwGetTime() - base); - } - else - { - printf("Opening regular window took %0.3f seconds\n", - glfwGetTime() - base); - } - - return window; -} - -static void close_window(GLFWwindow* window) -{ - double base = glfwGetTime(); - glfwDestroyWindow(window); - printf("Closing window took %0.3f seconds\n", glfwGetTime() - base); -} - -int main(int argc, char** argv) -{ - int count = 0; - GLFWwindow* window; - - srand((unsigned int) time(NULL)); - - glfwSetErrorCallback(error_callback); - - if (!glfwInit()) - exit(EXIT_FAILURE); - - for (;;) - { - GLFWmonitor* monitor = NULL; - - if (count % 2 == 0) - { - int monitorCount; - GLFWmonitor** monitors = glfwGetMonitors(&monitorCount); - monitor = monitors[rand() % monitorCount]; - } - - window = open_window(640, 480, monitor); - if (!window) - { - glfwTerminate(); - exit(EXIT_FAILURE); - } - - glMatrixMode(GL_PROJECTION); - glOrtho(-1.f, 1.f, -1.f, 1.f, 1.f, -1.f); - glMatrixMode(GL_MODELVIEW); - - glfwSetTime(0.0); - - while (glfwGetTime() < 5.0) - { - glClear(GL_COLOR_BUFFER_BIT); - - glPushMatrix(); - glRotatef((GLfloat) glfwGetTime() * 100.f, 0.f, 0.f, 1.f); - glRectf(-0.5f, -0.5f, 1.f, 1.f); - glPopMatrix(); - - glfwSwapBuffers(window); - glfwPollEvents(); - - if (glfwWindowShouldClose(window)) - { - close_window(window); - printf("User closed window\n"); - - glfwTerminate(); - exit(EXIT_SUCCESS); - } - } - - printf("Closing window\n"); - close_window(window); - - count++; - } - - glfwTerminate(); -} - diff --git a/examples/common/glfw/tests/sharing.c b/examples/common/glfw/tests/sharing.c deleted file mode 100644 index 54b15c81..00000000 --- a/examples/common/glfw/tests/sharing.c +++ /dev/null @@ -1,184 +0,0 @@ -//======================================================================== -// Context sharing test program -// Copyright (c) Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== -// -// This program is used to test sharing of objects between contexts -// -//======================================================================== - -#include - -#include -#include - -#define WIDTH 400 -#define HEIGHT 400 -#define OFFSET 50 - -static GLFWwindow* windows[2]; - -static void error_callback(int error, const char* description) -{ - fprintf(stderr, "Error: %s\n", description); -} - -static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) -{ - if (action == GLFW_PRESS && key == GLFW_KEY_ESCAPE) - glfwSetWindowShouldClose(window, GL_TRUE); -} - -static GLFWwindow* open_window(const char* title, GLFWwindow* share, int posX, int posY) -{ - GLFWwindow* window; - - glfwWindowHint(GLFW_VISIBLE, GL_FALSE); - window = glfwCreateWindow(WIDTH, HEIGHT, title, NULL, share); - if (!window) - return NULL; - - glfwMakeContextCurrent(window); - glfwSwapInterval(1); - glfwSetWindowPos(window, posX, posY); - glfwShowWindow(window); - - glfwSetKeyCallback(window, key_callback); - - return window; -} - -static GLuint create_texture(void) -{ - int x, y; - char pixels[256 * 256]; - GLuint texture; - - glGenTextures(1, &texture); - glBindTexture(GL_TEXTURE_2D, texture); - - for (y = 0; y < 256; y++) - { - for (x = 0; x < 256; x++) - pixels[y * 256 + x] = rand() % 256; - } - - glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 256, 256, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, pixels); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - return texture; -} - -static void draw_quad(GLuint texture) -{ - int width, height; - glfwGetFramebufferSize(glfwGetCurrentContext(), &width, &height); - - glViewport(0, 0, width, height); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0.f, 1.f, 0.f, 1.f, 0.f, 1.f); - - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, texture); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - - glBegin(GL_QUADS); - - glTexCoord2f(0.f, 0.f); - glVertex2f(0.f, 0.f); - - glTexCoord2f(1.f, 0.f); - glVertex2f(1.f, 0.f); - - glTexCoord2f(1.f, 1.f); - glVertex2f(1.f, 1.f); - - glTexCoord2f(0.f, 1.f); - glVertex2f(0.f, 1.f); - - glEnd(); -} - -int main(int argc, char** argv) -{ - int x, y, width; - GLuint texture; - - glfwSetErrorCallback(error_callback); - - if (!glfwInit()) - exit(EXIT_FAILURE); - - windows[0] = open_window("First", NULL, OFFSET, OFFSET); - if (!windows[0]) - { - glfwTerminate(); - exit(EXIT_FAILURE); - } - - // This is the one and only time we create a texture - // It is created inside the first context, created above - // It will then be shared with the second context, created below - texture = create_texture(); - - glfwGetWindowPos(windows[0], &x, &y); - glfwGetWindowSize(windows[0], &width, NULL); - - // Put the second window to the right of the first one - windows[1] = open_window("Second", windows[0], x + width + OFFSET, y); - if (!windows[1]) - { - glfwTerminate(); - exit(EXIT_FAILURE); - } - - // Set drawing color for both contexts - glfwMakeContextCurrent(windows[0]); - glColor3f(0.6f, 0.f, 0.6f); - glfwMakeContextCurrent(windows[1]); - glColor3f(0.6f, 0.6f, 0.f); - - glfwMakeContextCurrent(windows[0]); - - while (!glfwWindowShouldClose(windows[0]) && - !glfwWindowShouldClose(windows[1])) - { - glfwMakeContextCurrent(windows[0]); - draw_quad(texture); - - glfwMakeContextCurrent(windows[1]); - draw_quad(texture); - - glfwSwapBuffers(windows[0]); - glfwSwapBuffers(windows[1]); - - glfwWaitEvents(); - } - - glfwTerminate(); - exit(EXIT_SUCCESS); -} - diff --git a/examples/common/glfw/tests/tearing.c b/examples/common/glfw/tests/tearing.c deleted file mode 100644 index 94865fab..00000000 --- a/examples/common/glfw/tests/tearing.c +++ /dev/null @@ -1,130 +0,0 @@ -//======================================================================== -// Vsync enabling test -// Copyright (c) Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== -// -// This test renders a high contrast, horizontally moving bar, allowing for -// visual verification of whether the set swap interval is indeed obeyed -// -//======================================================================== - -#include - -#include -#include -#include - -static int swap_interval; -static double frame_rate; - -static void update_window_title(GLFWwindow* window) -{ - char title[256]; - - sprintf(title, "Tearing detector (interval %i, %0.1f Hz)", - swap_interval, frame_rate); - - glfwSetWindowTitle(window, title); -} - -static void set_swap_interval(GLFWwindow* window, int interval) -{ - swap_interval = interval; - glfwSwapInterval(swap_interval); - update_window_title(window); -} - -static void error_callback(int error, const char* description) -{ - fprintf(stderr, "Error: %s\n", description); -} - -static void framebuffer_size_callback(GLFWwindow* window, int width, int height) -{ - glViewport(0, 0, width, height); -} - -static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) -{ - if (key == GLFW_KEY_SPACE && action == GLFW_PRESS) - set_swap_interval(window, 1 - swap_interval); -} - -int main(void) -{ - float position; - unsigned long frame_count = 0; - double last_time, current_time; - GLFWwindow* window; - - glfwSetErrorCallback(error_callback); - - if (!glfwInit()) - exit(EXIT_FAILURE); - - window = glfwCreateWindow(640, 480, "", NULL, NULL); - if (!window) - { - glfwTerminate(); - exit(EXIT_FAILURE); - } - - glfwMakeContextCurrent(window); - set_swap_interval(window, 0); - - last_time = glfwGetTime(); - frame_rate = 0.0; - - glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); - glfwSetKeyCallback(window, key_callback); - - glMatrixMode(GL_PROJECTION); - glOrtho(-1.f, 1.f, -1.f, 1.f, 1.f, -1.f); - glMatrixMode(GL_MODELVIEW); - - while (!glfwWindowShouldClose(window)) - { - glClear(GL_COLOR_BUFFER_BIT); - - position = cosf((float) glfwGetTime() * 4.f) * 0.75f; - glRectf(position - 0.25f, -1.f, position + 0.25f, 1.f); - - glfwSwapBuffers(window); - glfwPollEvents(); - - frame_count++; - - current_time = glfwGetTime(); - if (current_time - last_time > 1.0) - { - frame_rate = frame_count / (current_time - last_time); - frame_count = 0; - last_time = current_time; - update_window_title(window); - } - } - - glfwTerminate(); - exit(EXIT_SUCCESS); -} - diff --git a/examples/common/glfw/tests/threads.c b/examples/common/glfw/tests/threads.c deleted file mode 100644 index 0a385787..00000000 --- a/examples/common/glfw/tests/threads.c +++ /dev/null @@ -1,135 +0,0 @@ -//======================================================================== -// Multi-threading test -// Copyright (c) Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== -// -// This test is intended to verify whether the OpenGL context part of -// the GLFW API is able to be used from multiple threads -// -//======================================================================== - -#include "tinycthread.h" - -#include - -#include -#include -#include - -typedef struct -{ - GLFWwindow* window; - const char* title; - float r, g, b; - thrd_t id; -} Thread; - -static volatile GLboolean running = GL_TRUE; - -static void error_callback(int error, const char* description) -{ - fprintf(stderr, "Error: %s\n", description); -} - -static int thread_main(void* data) -{ - const Thread* thread = data; - - glfwMakeContextCurrent(thread->window); - glfwSwapInterval(1); - - while (running) - { - const float v = (float) fabs(sin(glfwGetTime() * 2.f)); - glClearColor(thread->r * v, thread->g * v, thread->b * v, 0.f); - - glClear(GL_COLOR_BUFFER_BIT); - glfwSwapBuffers(thread->window); - } - - glfwMakeContextCurrent(NULL); - return 0; -} - -int main(void) -{ - int i, result; - Thread threads[] = - { - { NULL, "Red", 1.f, 0.f, 0.f, 0 }, - { NULL, "Green", 0.f, 1.f, 0.f, 0 }, - { NULL, "Blue", 0.f, 0.f, 1.f, 0 } - }; - const int count = sizeof(threads) / sizeof(Thread); - - glfwSetErrorCallback(error_callback); - - if (!glfwInit()) - exit(EXIT_FAILURE); - - glfwWindowHint(GLFW_VISIBLE, GL_FALSE); - - for (i = 0; i < count; i++) - { - threads[i].window = glfwCreateWindow(200, 200, - threads[i].title, - NULL, NULL); - if (!threads[i].window) - { - glfwTerminate(); - exit(EXIT_FAILURE); - } - - glfwSetWindowPos(threads[i].window, 200 + 250 * i, 200); - glfwShowWindow(threads[i].window); - - if (thrd_create(&threads[i].id, thread_main, threads + i) != - thrd_success) - { - fprintf(stderr, "Failed to create secondary thread\n"); - - glfwTerminate(); - exit(EXIT_FAILURE); - } - } - - while (running) - { - glfwWaitEvents(); - - for (i = 0; i < count; i++) - { - if (glfwWindowShouldClose(threads[i].window)) - running = GL_FALSE; - } - } - - for (i = 0; i < count; i++) - glfwHideWindow(threads[i].window); - - for (i = 0; i < count; i++) - thrd_join(threads[i].id, &result); - - exit(EXIT_SUCCESS); -} - diff --git a/examples/common/glfw/tests/title.c b/examples/common/glfw/tests/title.c deleted file mode 100644 index 15ddb83f..00000000 --- a/examples/common/glfw/tests/title.c +++ /dev/null @@ -1,76 +0,0 @@ -//======================================================================== -// UTF-8 window title test -// Copyright (c) Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== -// -// This test sets a UTF-8 window title -// -//======================================================================== - -#include - -#include -#include - -static void error_callback(int error, const char* description) -{ - fprintf(stderr, "Error: %s\n", description); -} - -static void framebuffer_size_callback(GLFWwindow* window, int width, int height) -{ - glViewport(0, 0, width, height); -} - -int main(void) -{ - GLFWwindow* window; - - glfwSetErrorCallback(error_callback); - - if (!glfwInit()) - exit(EXIT_FAILURE); - - window = glfwCreateWindow(400, 400, "English 日本語 русский язык 官話", NULL, NULL); - if (!window) - { - glfwTerminate(); - exit(EXIT_FAILURE); - } - - glfwMakeContextCurrent(window); - glfwSwapInterval(1); - - glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); - - while (!glfwWindowShouldClose(window)) - { - glClear(GL_COLOR_BUFFER_BIT); - glfwSwapBuffers(window); - glfwWaitEvents(); - } - - glfwTerminate(); - exit(EXIT_SUCCESS); -} - diff --git a/examples/common/glfw/tests/windows.c b/examples/common/glfw/tests/windows.c deleted file mode 100644 index 164a298f..00000000 --- a/examples/common/glfw/tests/windows.c +++ /dev/null @@ -1,117 +0,0 @@ -//======================================================================== -// Simple multi-window test -// Copyright (c) Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== -// -// This test creates four windows and clears each in a different color -// -//======================================================================== - -#include - -#include -#include - -static const char* titles[4] = -{ - "Foo", - "Bar", - "Baz", - "Quux" -}; - -static void error_callback(int error, const char* description) -{ - fprintf(stderr, "Error: %s\n", description); -} - -static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) -{ - if (key == GLFW_KEY_SPACE && action == GLFW_PRESS) - { - int xpos, ypos; - glfwGetWindowPos(window, &xpos, &ypos); - glfwSetWindowPos(window, xpos, ypos); - } -} - -int main(void) -{ - int i; - GLboolean running = GL_TRUE; - GLFWwindow* windows[4]; - - glfwSetErrorCallback(error_callback); - - if (!glfwInit()) - exit(EXIT_FAILURE); - - glfwWindowHint(GLFW_VISIBLE, GL_FALSE); - - for (i = 0; i < 4; i++) - { - int left, top, right, bottom; - - windows[i] = glfwCreateWindow(200, 200, titles[i], NULL, NULL); - if (!windows[i]) - { - glfwTerminate(); - exit(EXIT_FAILURE); - } - - glfwSetKeyCallback(windows[i], key_callback); - - glfwMakeContextCurrent(windows[i]); - glClearColor((GLclampf) (i & 1), - (GLclampf) (i >> 1), - i ? 0.f : 1.f, - 0.f); - - glfwGetWindowFrameSize(windows[i], &left, &top, &right, &bottom); - glfwSetWindowPos(windows[i], - 100 + (i & 1) * (200 + left + right), - 100 + (i >> 1) * (200 + top + bottom)); - } - - for (i = 0; i < 4; i++) - glfwShowWindow(windows[i]); - - while (running) - { - for (i = 0; i < 4; i++) - { - glfwMakeContextCurrent(windows[i]); - glClear(GL_COLOR_BUFFER_BIT); - glfwSwapBuffers(windows[i]); - - if (glfwWindowShouldClose(windows[i])) - running = GL_FALSE; - } - - glfwPollEvents(); - } - - glfwTerminate(); - exit(EXIT_SUCCESS); -} - diff --git a/examples/common/meshes/capsule.obj b/examples/common/meshes/capsule.obj deleted file mode 100644 index 8479fb35..00000000 --- a/examples/common/meshes/capsule.obj +++ /dev/null @@ -1,1060 +0,0 @@ -# Blender v2.66 (sub 0) OBJ File: '' -v -0.195090 1.481026 0.000000 -v -0.382683 1.424120 0.000000 -v -0.555570 1.331710 0.000000 -v -0.707107 1.207348 0.000000 -v -0.831470 1.055811 0.000000 -v -0.923880 0.882924 0.000000 -v -0.980785 0.695331 0.000000 -v -1.000000 0.500241 0.000000 -v -0.191342 1.481026 -0.038060 -v -0.375330 1.424120 -0.074658 -v -0.544895 1.331710 -0.108386 -v -0.693520 1.207348 -0.137950 -v -0.815493 1.055811 -0.162212 -v -0.906127 0.882924 -0.180240 -v -0.961940 0.695331 -0.191342 -v -0.980785 0.500241 -0.195090 -v -0.180240 1.481026 -0.074658 -v -0.353553 1.424120 -0.146447 -v -0.513280 1.331710 -0.212608 -v -0.653281 1.207348 -0.270598 -v -0.768178 1.055811 -0.318190 -v -0.853553 0.882924 -0.353553 -v -0.906127 0.695331 -0.375330 -v -0.923880 0.500241 -0.382684 -v -0.162212 1.481026 -0.108387 -v -0.318190 1.424120 -0.212608 -v -0.461940 1.331710 -0.308658 -v -0.587938 1.207348 -0.392848 -v -0.691342 1.055811 -0.461940 -v -0.768178 0.882924 -0.513280 -v -0.815493 0.695331 -0.544895 -v -0.831470 0.500241 -0.555570 -v -0.137950 1.481026 -0.137950 -v -0.270598 1.424120 -0.270598 -v -0.392847 1.331710 -0.392848 -v -0.500000 1.207348 -0.500000 -v -0.587938 1.055811 -0.587938 -v -0.653281 0.882924 -0.653282 -v -0.693520 0.695331 -0.693520 -v -0.707107 0.500241 -0.707107 -v -0.108386 1.481026 -0.162212 -v -0.212607 1.424120 -0.318190 -v -0.308658 1.331710 -0.461940 -v -0.392847 1.207348 -0.587938 -v -0.461939 1.055811 -0.691342 -v -0.513280 0.882924 -0.768178 -v -0.544895 0.695331 -0.815493 -v -0.555570 0.500241 -0.831470 -v -0.074658 1.481026 -0.180240 -v -0.146446 1.424120 -0.353554 -v -0.212607 1.331710 -0.513280 -v -0.270598 1.207348 -0.653282 -v -0.318189 1.055811 -0.768178 -v -0.353553 0.882924 -0.853554 -v -0.375330 0.695331 -0.906128 -v -0.382683 0.500241 -0.923880 -v -0.038060 1.481026 -0.191342 -v -0.074658 1.424120 -0.375331 -v -0.108386 1.331710 -0.544895 -v -0.137949 1.207348 -0.693520 -v -0.162211 1.055811 -0.815493 -v -0.180240 0.882924 -0.906128 -v -0.191341 0.695331 -0.961940 -v -0.195090 0.500241 -0.980785 -v 0.000000 1.481026 -0.195091 -v 0.000000 1.424120 -0.382684 -v 0.000000 1.331710 -0.555570 -v 0.000000 1.207348 -0.707107 -v 0.000000 1.055811 -0.831470 -v 0.000000 0.882924 -0.923880 -v 0.000000 0.695331 -0.980785 -v 0.000000 0.500241 -1.000000 -v 0.038061 1.481026 -0.191342 -v 0.074658 1.424120 -0.375330 -v 0.108387 1.331710 -0.544895 -v 0.137950 1.207348 -0.693520 -v 0.162212 1.055811 -0.815493 -v 0.180240 0.882924 -0.906128 -v 0.191342 0.695331 -0.961940 -v 0.195091 0.500241 -0.980785 -v 0.074658 1.481026 -0.180240 -v 0.146447 1.424120 -0.353554 -v 0.212608 1.331710 -0.513280 -v 0.270599 1.207348 -0.653282 -v 0.318190 1.055811 -0.768178 -v 0.353554 0.882924 -0.853553 -v 0.375331 0.695331 -0.906127 -v 0.382684 0.500241 -0.923880 -v 0.108387 1.481026 -0.162212 -v 0.212608 1.424120 -0.318190 -v 0.308659 1.331710 -0.461940 -v 0.392848 1.207348 -0.587938 -v 0.461940 1.055811 -0.691342 -v 0.513280 0.882924 -0.768178 -v 0.544895 0.695331 -0.815493 -v 0.555571 0.500241 -0.831470 -v 0.137950 1.481026 -0.137950 -v 0.270599 1.424120 -0.270598 -v 0.392848 1.331710 -0.392848 -v 0.500000 1.207348 -0.500000 -v 0.587938 1.055811 -0.587938 -v 0.653282 0.882924 -0.653281 -v 0.693520 0.695331 -0.693520 -v 0.707107 0.500241 -0.707107 -v 0.162212 1.481026 -0.108386 -v 0.318190 1.424120 -0.212608 -v 0.461940 1.331710 -0.308658 -v 0.587938 1.207348 -0.392847 -v 0.691342 1.055811 -0.461940 -v 0.768178 0.882924 -0.513280 -v 0.815493 0.695331 -0.544895 -v 0.831470 0.500241 -0.555570 -v 0.180240 1.481026 -0.074658 -v 0.353554 1.424120 -0.146447 -v 0.513280 1.331710 -0.212608 -v 0.653282 1.207348 -0.270598 -v 0.768178 1.055811 -0.318190 -v 0.853554 0.882924 -0.353553 -v 0.906128 0.695331 -0.375330 -v 0.923880 0.500241 -0.382683 -v 0.191342 1.481026 -0.038060 -v 0.375331 1.424120 -0.074658 -v 0.544896 1.331710 -0.108386 -v 0.693520 1.207348 -0.137950 -v 0.815493 1.055811 -0.162212 -v 0.906128 0.882924 -0.180240 -v 0.961940 0.695331 -0.191342 -v 0.980785 0.500241 -0.195090 -v 0.195091 1.481026 0.000000 -v 0.382684 1.424120 0.000000 -v 0.555571 1.331710 0.000000 -v 0.707107 1.207348 0.000000 -v 0.831470 1.055811 0.000000 -v 0.923880 0.882924 0.000000 -v 0.980785 0.695331 0.000000 -v 1.000000 0.500241 0.000000 -v 0.191342 1.481026 0.038060 -v 0.375331 1.424120 0.074658 -v 0.544896 1.331710 0.108386 -v 0.693520 1.207348 0.137950 -v 0.815493 1.055811 0.162212 -v 0.906128 0.882924 0.180240 -v 0.961940 0.695331 0.191342 -v 0.980785 0.500241 0.195090 -v 0.180240 1.481026 0.074658 -v 0.353554 1.424120 0.146447 -v 0.513280 1.331710 0.212608 -v 0.653282 1.207348 0.270598 -v 0.768178 1.055811 0.318190 -v 0.853554 0.882924 0.353554 -v 0.906128 0.695331 0.375330 -v 0.923880 0.500241 0.382683 -v 0.162212 1.481026 0.108387 -v 0.318190 1.424120 0.212608 -v 0.461940 1.331710 0.308658 -v 0.587938 1.207348 0.392848 -v 0.691342 1.055811 0.461940 -v 0.768178 0.882924 0.513280 -v 0.815493 0.695331 0.544895 -v 0.831470 0.500241 0.555570 -v 0.137950 1.481026 0.137950 -v 0.270598 1.424120 0.270598 -v 0.392848 1.331710 0.392848 -v 0.500000 1.207348 0.500000 -v 0.587938 1.055811 0.587938 -v 0.653282 0.882924 0.653282 -v 0.693520 0.695331 0.693520 -v 0.707107 0.500241 0.707107 -v 0.108387 1.481026 0.162212 -v 0.212608 1.424120 0.318190 -v 0.308659 1.331710 0.461940 -v 0.392848 1.207348 0.587938 -v 0.461940 1.055811 0.691342 -v 0.513280 0.882924 0.768178 -v 0.544895 0.695331 0.815493 -v 0.555570 0.500241 0.831469 -v 0.074658 1.481026 0.180240 -v 0.146447 1.424120 0.353554 -v 0.212608 1.331710 0.513280 -v 0.270598 1.207348 0.653281 -v 0.318190 1.055811 0.768178 -v 0.353554 0.882924 0.853553 -v 0.375330 0.695331 0.906127 -v 0.382683 0.500241 0.923879 -v 0.038061 1.481026 0.191342 -v 0.074658 1.424120 0.375330 -v 0.108387 1.331710 0.544895 -v 0.137950 1.207348 0.693520 -v 0.162212 1.055811 0.815493 -v 0.180240 0.882924 0.906127 -v 0.191342 0.695331 0.961940 -v 0.195090 0.500241 0.980785 -v 0.000000 1.481026 0.195090 -v 0.000000 1.424120 0.382684 -v 0.000000 1.331710 0.555570 -v 0.000000 1.207348 0.707107 -v 0.000000 1.055811 0.831469 -v 0.000000 0.882924 0.923879 -v 0.000000 0.695331 0.980785 -v 0.000000 0.500241 1.000000 -v -0.038060 1.481026 0.191342 -v -0.074658 1.424120 0.375330 -v -0.108386 1.331710 0.544895 -v -0.137949 1.207348 0.693520 -v -0.162211 1.055811 0.815493 -v -0.180240 0.882924 0.906127 -v -0.191342 0.695331 0.961939 -v -0.195090 0.500241 0.980785 -v -0.074658 1.481026 0.180240 -v -0.146446 1.424120 0.353553 -v -0.212607 1.331710 0.513280 -v -0.270598 1.207348 0.653281 -v -0.318189 1.055811 0.768177 -v -0.353553 0.882924 0.853553 -v -0.375330 0.695331 0.906127 -v -0.382683 0.500241 0.923879 -v -0.108386 1.481026 0.162212 -v -0.212607 1.424120 0.318190 -v -0.308658 1.331710 0.461940 -v -0.392847 1.207348 0.587938 -v -0.461939 1.055811 0.691341 -v -0.513280 0.882924 0.768178 -v -0.544895 0.695331 0.815493 -v -0.555570 0.500241 0.831469 -v -0.137949 1.481026 0.137950 -v -0.270598 1.424120 0.270598 -v -0.392847 1.331710 0.392847 -v -0.500000 1.207348 0.500000 -v -0.587937 1.055811 0.587937 -v -0.653281 0.882924 0.653281 -v -0.693519 0.695331 0.693519 -v -0.707106 0.500241 0.707106 -v 0.000000 1.500241 0.000000 -v -0.162211 1.481026 0.108386 -v -0.318189 1.424120 0.212608 -v -0.461939 1.331710 0.308658 -v -0.587937 1.207348 0.392847 -v -0.691341 1.055811 0.461939 -v -0.768177 0.882924 0.513280 -v -0.815493 0.695331 0.544895 -v -0.831469 0.500241 0.555570 -v -0.180240 1.481026 0.074658 -v -0.353553 1.424120 0.146447 -v -0.513280 1.331710 0.212607 -v -0.653281 1.207348 0.270598 -v -0.768177 1.055811 0.318189 -v -0.853553 0.882924 0.353553 -v -0.906127 0.695331 0.375330 -v -0.923879 0.500241 0.382683 -v -0.191341 1.481026 0.038060 -v -0.375330 1.424120 0.074658 -v -0.544895 1.331710 0.108386 -v -0.693520 1.207348 0.137950 -v -0.815492 1.055811 0.162211 -v -0.906127 0.882924 0.180240 -v -0.961939 0.695331 0.191341 -v -0.980784 0.500241 0.195090 -v -1.000000 -0.503485 0.000000 -v -0.980785 -0.698576 0.000000 -v -0.923880 -0.886169 0.000000 -v -0.831470 -1.059056 0.000000 -v -0.707107 -1.210592 0.000000 -v -0.555570 -1.334955 0.000000 -v -0.382683 -1.427365 0.000000 -v -0.195090 -1.484271 0.000000 -v -0.980785 -0.503485 -0.195090 -v -0.961940 -0.698576 -0.191342 -v -0.906127 -0.886169 -0.180240 -v -0.815493 -1.059056 -0.162212 -v -0.693520 -1.210592 -0.137950 -v -0.544895 -1.334955 -0.108386 -v -0.375330 -1.427365 -0.074658 -v -0.191341 -1.484271 -0.038060 -v -0.923880 -0.503485 -0.382684 -v -0.906127 -0.698576 -0.375330 -v -0.853553 -0.886169 -0.353554 -v -0.768178 -1.059056 -0.318190 -v -0.653281 -1.210592 -0.270598 -v -0.513280 -1.334955 -0.212608 -v -0.353553 -1.427365 -0.146447 -v -0.180240 -1.484271 -0.074658 -v -0.831470 -0.503485 -0.555570 -v -0.815493 -0.698576 -0.544895 -v -0.768178 -0.886169 -0.513280 -v -0.691342 -1.059056 -0.461940 -v -0.587938 -1.210592 -0.392848 -v -0.461940 -1.334955 -0.308658 -v -0.318189 -1.427365 -0.212608 -v -0.162211 -1.484271 -0.108386 -v -0.707107 -0.503485 -0.707107 -v -0.693520 -0.698576 -0.693520 -v -0.653281 -0.886169 -0.653282 -v -0.587938 -1.059056 -0.587938 -v -0.500000 -1.210592 -0.500000 -v -0.392847 -1.334955 -0.392848 -v -0.270598 -1.427365 -0.270598 -v -0.137949 -1.484271 -0.137950 -v -0.555570 -0.503485 -0.831470 -v -0.544895 -0.698576 -0.815493 -v -0.513280 -0.886169 -0.768178 -v -0.461939 -1.059056 -0.691342 -v -0.392847 -1.210592 -0.587938 -v -0.308658 -1.334955 -0.461940 -v -0.212607 -1.427365 -0.318190 -v -0.108386 -1.484271 -0.162212 -v -0.382683 -0.503485 -0.923880 -v -0.375330 -0.698576 -0.906128 -v -0.353553 -0.886169 -0.853554 -v -0.318189 -1.059056 -0.768178 -v -0.270598 -1.210592 -0.653282 -v -0.212607 -1.334955 -0.513280 -v -0.146446 -1.427365 -0.353554 -v -0.074658 -1.484271 -0.180240 -v -0.195090 -0.503485 -0.980785 -v -0.191341 -0.698576 -0.961940 -v -0.180240 -0.886169 -0.906128 -v -0.162211 -1.059056 -0.815493 -v -0.137949 -1.210592 -0.693520 -v -0.108386 -1.334955 -0.544895 -v -0.074658 -1.427365 -0.375330 -v -0.038060 -1.484271 -0.191342 -v 0.000000 -0.503485 -1.000000 -v 0.000000 -0.698576 -0.980785 -v 0.000000 -0.886169 -0.923880 -v 0.000000 -1.059056 -0.831470 -v 0.000000 -1.210592 -0.707107 -v 0.000000 -1.334955 -0.555570 -v 0.000000 -1.427365 -0.382684 -v 0.000000 -1.484271 -0.195090 -v 0.195091 -0.503485 -0.980785 -v 0.191342 -0.698576 -0.961940 -v 0.180240 -0.886169 -0.906128 -v 0.162212 -1.059056 -0.815493 -v 0.137950 -1.210592 -0.693520 -v 0.108387 -1.334955 -0.544895 -v 0.074658 -1.427365 -0.375330 -v 0.038061 -1.484271 -0.191342 -v 0.382684 -0.503485 -0.923880 -v 0.375331 -0.698576 -0.906127 -v 0.353554 -0.886169 -0.853554 -v 0.318190 -1.059056 -0.768178 -v 0.270599 -1.210592 -0.653282 -v 0.212608 -1.334955 -0.513280 -v 0.146447 -1.427365 -0.353553 -v 0.074658 -1.484271 -0.180240 -v 0.555571 -0.503485 -0.831470 -v 0.544895 -0.698576 -0.815493 -v 0.513280 -0.886169 -0.768178 -v 0.461940 -1.059056 -0.691342 -v 0.392848 -1.210592 -0.587938 -v 0.308659 -1.334955 -0.461940 -v 0.212608 -1.427365 -0.318190 -v 0.108387 -1.484271 -0.162212 -v 0.707107 -0.503485 -0.707107 -v 0.693520 -0.698576 -0.693520 -v 0.653282 -0.886169 -0.653282 -v 0.587938 -1.059056 -0.587938 -v 0.500000 -1.210592 -0.500000 -v 0.392848 -1.334955 -0.392847 -v 0.270598 -1.427365 -0.270598 -v 0.137950 -1.484271 -0.137950 -v 0.831470 -0.503485 -0.555570 -v 0.815493 -0.698576 -0.544895 -v 0.768178 -0.886169 -0.513280 -v 0.691342 -1.059056 -0.461940 -v 0.587938 -1.210592 -0.392847 -v 0.461940 -1.334955 -0.308658 -v 0.318190 -1.427365 -0.212608 -v 0.162212 -1.484271 -0.108386 -v 0.923880 -0.503485 -0.382683 -v 0.906128 -0.698576 -0.375330 -v 0.853554 -0.886169 -0.353553 -v 0.768178 -1.059056 -0.318190 -v 0.653282 -1.210592 -0.270598 -v 0.513280 -1.334955 -0.212607 -v 0.353554 -1.427365 -0.146447 -v 0.180240 -1.484271 -0.074658 -v 0.980785 -0.503485 -0.195090 -v 0.961940 -0.698576 -0.191342 -v 0.906128 -0.886169 -0.180240 -v 0.815493 -1.059056 -0.162212 -v 0.693520 -1.210592 -0.137950 -v 0.544895 -1.334955 -0.108386 -v 0.375331 -1.427365 -0.074658 -v 0.191342 -1.484271 -0.038060 -v 1.000000 -0.503485 0.000000 -v 0.980785 -0.698576 0.000000 -v 0.923880 -0.886169 0.000000 -v 0.831470 -1.059056 0.000000 -v 0.707107 -1.210592 0.000000 -v 0.555571 -1.334955 0.000000 -v 0.382684 -1.427365 0.000000 -v 0.195091 -1.484271 0.000000 -v 0.980785 -0.503485 0.195090 -v 0.961940 -0.698576 0.191342 -v 0.906128 -0.886169 0.180240 -v 0.815493 -1.059056 0.162212 -v 0.693520 -1.210592 0.137950 -v 0.544895 -1.334955 0.108386 -v 0.375331 -1.427365 0.074658 -v 0.191342 -1.484271 0.038060 -v 0.923880 -0.503485 0.382683 -v 0.906128 -0.698576 0.375330 -v 0.853554 -0.886169 0.353553 -v 0.768178 -1.059056 0.318190 -v 0.653282 -1.210592 0.270598 -v 0.513280 -1.334955 0.212608 -v 0.353554 -1.427365 0.146447 -v 0.180240 -1.484271 0.074658 -v 0.831470 -0.503485 0.555570 -v 0.815493 -0.698576 0.544895 -v 0.768178 -0.886169 0.513280 -v 0.691342 -1.059056 0.461940 -v 0.587938 -1.210592 0.392848 -v 0.461940 -1.334955 0.308658 -v 0.318190 -1.427365 0.212608 -v 0.162212 -1.484271 0.108386 -v 0.707107 -0.503485 0.707107 -v 0.693520 -0.698576 0.693520 -v 0.653282 -0.886169 0.653282 -v 0.587938 -1.059056 0.587938 -v 0.500000 -1.210592 0.500000 -v 0.392848 -1.334955 0.392848 -v 0.270598 -1.427365 0.270598 -v 0.137950 -1.484271 0.137950 -v 0.555570 -0.503485 0.831469 -v 0.544895 -0.698576 0.815493 -v 0.513280 -0.886169 0.768178 -v 0.461940 -1.059056 0.691342 -v 0.392848 -1.210592 0.587938 -v 0.308659 -1.334955 0.461940 -v 0.212608 -1.427365 0.318190 -v 0.108387 -1.484271 0.162212 -v 0.000000 -1.503485 0.000000 -v 0.382683 -0.503485 0.923879 -v 0.375330 -0.698576 0.906127 -v 0.353554 -0.886169 0.853553 -v 0.318190 -1.059056 0.768178 -v 0.270598 -1.210592 0.653281 -v 0.212608 -1.334955 0.513280 -v 0.146447 -1.427365 0.353553 -v 0.074658 -1.484271 0.180240 -v 0.195090 -0.503485 0.980785 -v 0.191342 -0.698576 0.961940 -v 0.180240 -0.886169 0.906128 -v 0.162212 -1.059056 0.815493 -v 0.137950 -1.210592 0.693520 -v 0.108387 -1.334955 0.544895 -v 0.074658 -1.427365 0.375330 -v 0.038061 -1.484271 0.191342 -v 0.000000 -0.503485 1.000000 -v 0.000000 -0.698576 0.980785 -v 0.000000 -0.886169 0.923880 -v 0.000000 -1.059056 0.831469 -v 0.000000 -1.210592 0.707107 -v 0.000000 -1.334955 0.555570 -v 0.000000 -1.427365 0.382683 -v 0.000000 -1.484271 0.195090 -v -0.195090 -0.503485 0.980785 -v -0.191342 -0.698576 0.961939 -v -0.180240 -0.886169 0.906127 -v -0.162211 -1.059056 0.815493 -v -0.137949 -1.210592 0.693520 -v -0.108386 -1.334955 0.544895 -v -0.074658 -1.427365 0.375330 -v -0.038060 -1.484271 0.191342 -v -0.382683 -0.503485 0.923879 -v -0.375330 -0.698576 0.906127 -v -0.353553 -0.886169 0.853553 -v -0.318189 -1.059056 0.768177 -v -0.270598 -1.210592 0.653281 -v -0.212607 -1.334955 0.513280 -v -0.146446 -1.427365 0.353553 -v -0.074657 -1.484271 0.180240 -v -0.555570 -0.503485 0.831469 -v -0.544895 -0.698576 0.815493 -v -0.513280 -0.886169 0.768178 -v -0.461939 -1.059056 0.691341 -v -0.392847 -1.210592 0.587938 -v -0.308658 -1.334955 0.461940 -v -0.212607 -1.427365 0.318190 -v -0.108386 -1.484271 0.162212 -v -0.707106 -0.503485 0.707106 -v -0.693519 -0.698576 0.693519 -v -0.653281 -0.886169 0.653281 -v -0.587937 -1.059056 0.587937 -v -0.500000 -1.210592 0.500000 -v -0.392847 -1.334955 0.392847 -v -0.270598 -1.427365 0.270598 -v -0.137949 -1.484271 0.137950 -v -0.831469 -0.503485 0.555570 -v -0.815493 -0.698576 0.544895 -v -0.768178 -0.886169 0.513280 -v -0.691341 -1.059056 0.461939 -v -0.587937 -1.210592 0.392847 -v -0.461939 -1.334955 0.308658 -v -0.318189 -1.427365 0.212608 -v -0.162211 -1.484271 0.108386 -v -0.923879 -0.503485 0.382683 -v -0.906127 -0.698576 0.375330 -v -0.853553 -0.886169 0.353553 -v -0.768177 -1.059056 0.318189 -v -0.653281 -1.210592 0.270598 -v -0.513280 -1.334955 0.212607 -v -0.353553 -1.427365 0.146447 -v -0.180240 -1.484271 0.074658 -v -0.980784 -0.503485 0.195090 -v -0.961939 -0.698576 0.191341 -v -0.906127 -0.886169 0.180240 -v -0.815492 -1.059056 0.162211 -v -0.693520 -1.210592 0.137950 -v -0.544895 -1.334955 0.108386 -v -0.375330 -1.427365 0.074658 -v -0.191341 -1.484271 0.038060 -s off -f 7 6 14 15 -f 8 7 15 16 -f 2 1 9 10 -f 3 2 10 11 -f 4 3 11 12 -f 5 4 12 13 -f 6 5 13 14 -f 11 10 18 19 -f 12 11 19 20 -f 13 12 20 21 -f 14 13 21 22 -f 15 14 22 23 -f 16 15 23 24 -f 10 9 17 18 -f 23 22 30 31 -f 24 23 31 32 -f 18 17 25 26 -f 19 18 26 27 -f 20 19 27 28 -f 21 20 28 29 -f 22 21 29 30 -f 29 28 36 37 -f 30 29 37 38 -f 31 30 38 39 -f 32 31 39 40 -f 26 25 33 34 -f 27 26 34 35 -f 28 27 35 36 -f 35 34 42 43 -f 36 35 43 44 -f 37 36 44 45 -f 38 37 45 46 -f 39 38 46 47 -f 40 39 47 48 -f 34 33 41 42 -f 47 46 54 55 -f 48 47 55 56 -f 42 41 49 50 -f 43 42 50 51 -f 44 43 51 52 -f 45 44 52 53 -f 46 45 53 54 -f 53 52 60 61 -f 54 53 61 62 -f 55 54 62 63 -f 56 55 63 64 -f 50 49 57 58 -f 51 50 58 59 -f 52 51 59 60 -f 58 57 65 66 -f 59 58 66 67 -f 60 59 67 68 -f 61 60 68 69 -f 62 61 69 70 -f 63 62 70 71 -f 64 63 71 72 -f 70 69 77 78 -f 71 70 78 79 -f 72 71 79 80 -f 66 65 73 74 -f 67 66 74 75 -f 68 67 75 76 -f 69 68 76 77 -f 76 75 83 84 -f 77 76 84 85 -f 78 77 85 86 -f 79 78 86 87 -f 80 79 87 88 -f 74 73 81 82 -f 75 74 82 83 -f 88 87 95 96 -f 82 81 89 90 -f 83 82 90 91 -f 84 83 91 92 -f 85 84 92 93 -f 86 85 93 94 -f 87 86 94 95 -f 94 93 101 102 -f 95 94 102 103 -f 96 95 103 104 -f 90 89 97 98 -f 91 90 98 99 -f 92 91 99 100 -f 93 92 100 101 -f 100 99 107 108 -f 101 100 108 109 -f 102 101 109 110 -f 103 102 110 111 -f 104 103 111 112 -f 98 97 105 106 -f 99 98 106 107 -f 112 111 119 120 -f 106 105 113 114 -f 107 106 114 115 -f 108 107 115 116 -f 109 108 116 117 -f 110 109 117 118 -f 111 110 118 119 -f 118 117 125 126 -f 119 118 126 127 -f 120 119 127 128 -f 114 113 121 122 -f 115 114 122 123 -f 116 115 123 124 -f 117 116 124 125 -f 124 123 131 132 -f 125 124 132 133 -f 126 125 133 134 -f 127 126 134 135 -f 128 127 135 136 -f 122 121 129 130 -f 123 122 130 131 -f 136 135 143 144 -f 130 129 137 138 -f 131 130 138 139 -f 132 131 139 140 -f 133 132 140 141 -f 134 133 141 142 -f 135 134 142 143 -f 141 140 148 149 -f 142 141 149 150 -f 143 142 150 151 -f 144 143 151 152 -f 138 137 145 146 -f 139 138 146 147 -f 140 139 147 148 -f 147 146 154 155 -f 148 147 155 156 -f 149 148 156 157 -f 150 149 157 158 -f 151 150 158 159 -f 152 151 159 160 -f 146 145 153 154 -f 159 158 166 167 -f 160 159 167 168 -f 154 153 161 162 -f 155 154 162 163 -f 156 155 163 164 -f 157 156 164 165 -f 158 157 165 166 -f 165 164 172 173 -f 166 165 173 174 -f 167 166 174 175 -f 168 167 175 176 -f 162 161 169 170 -f 163 162 170 171 -f 164 163 171 172 -f 171 170 178 179 -f 172 171 179 180 -f 173 172 180 181 -f 174 173 181 182 -f 175 174 182 183 -f 176 175 183 184 -f 170 169 177 178 -f 183 182 190 191 -f 184 183 191 192 -f 178 177 185 186 -f 179 178 186 187 -f 180 179 187 188 -f 181 180 188 189 -f 182 181 189 190 -f 189 188 196 197 -f 190 189 197 198 -f 191 190 198 199 -f 192 191 199 200 -f 186 185 193 194 -f 187 186 194 195 -f 188 187 195 196 -f 195 194 202 203 -f 196 195 203 204 -f 197 196 204 205 -f 198 197 205 206 -f 199 198 206 207 -f 200 199 207 208 -f 194 193 201 202 -f 207 206 214 215 -f 208 207 215 216 -f 202 201 209 210 -f 203 202 210 211 -f 204 203 211 212 -f 205 204 212 213 -f 206 205 213 214 -f 212 211 219 220 -f 213 212 220 221 -f 214 213 221 222 -f 215 214 222 223 -f 216 215 223 224 -f 210 209 217 218 -f 211 210 218 219 -f 224 223 231 232 -f 218 217 225 226 -f 219 218 226 227 -f 220 219 227 228 -f 221 220 228 229 -f 222 221 229 230 -f 223 222 230 231 -f 230 229 238 239 -f 231 230 239 240 -f 232 231 240 241 -f 226 225 234 235 -f 227 226 235 236 -f 228 227 236 237 -f 229 228 237 238 -f 237 236 244 245 -f 238 237 245 246 -f 239 238 246 247 -f 240 239 247 248 -f 241 240 248 249 -f 235 234 242 243 -f 236 235 243 244 -f 249 248 256 257 -f 243 242 250 251 -f 244 243 251 252 -f 245 244 252 253 -f 246 245 253 254 -f 247 246 254 255 -f 248 247 255 256 -f 1 233 9 -f 9 233 17 -f 17 233 25 -f 25 233 33 -f 33 233 41 -f 41 233 49 -f 49 233 57 -f 57 233 65 -f 65 233 73 -f 73 233 81 -f 81 233 89 -f 89 233 97 -f 97 233 105 -f 105 233 113 -f 113 233 121 -f 121 233 129 -f 129 233 137 -f 137 233 145 -f 145 233 153 -f 153 233 161 -f 161 233 169 -f 169 233 177 -f 177 233 185 -f 185 233 193 -f 193 233 201 -f 201 233 209 -f 209 233 217 -f 217 233 225 -f 225 233 234 -f 234 233 242 -f 242 233 250 -f 255 254 5 6 -f 256 255 6 7 -f 250 233 1 -f 257 256 7 8 -f 251 250 1 2 -f 252 251 2 3 -f 253 252 3 4 -f 254 253 4 5 -f 263 262 270 271 -f 264 263 271 272 -f 265 264 272 273 -f 259 258 266 267 -f 260 259 267 268 -f 261 260 268 269 -f 262 261 269 270 -f 273 272 280 281 -f 267 266 274 275 -f 268 267 275 276 -f 269 268 276 277 -f 270 269 277 278 -f 271 270 278 279 -f 272 271 279 280 -f 279 278 286 287 -f 280 279 287 288 -f 281 280 288 289 -f 275 274 282 283 -f 276 275 283 284 -f 277 276 284 285 -f 278 277 285 286 -f 285 284 292 293 -f 286 285 293 294 -f 287 286 294 295 -f 288 287 295 296 -f 289 288 296 297 -f 283 282 290 291 -f 284 283 291 292 -f 297 296 304 305 -f 291 290 298 299 -f 292 291 299 300 -f 293 292 300 301 -f 294 293 301 302 -f 295 294 302 303 -f 296 295 303 304 -f 303 302 310 311 -f 304 303 311 312 -f 305 304 312 313 -f 299 298 306 307 -f 300 299 307 308 -f 301 300 308 309 -f 302 301 309 310 -f 309 308 316 317 -f 310 309 317 318 -f 311 310 318 319 -f 312 311 319 320 -f 313 312 320 321 -f 307 306 314 315 -f 308 307 315 316 -f 321 320 328 329 -f 315 314 322 323 -f 316 315 323 324 -f 317 316 324 325 -f 318 317 325 326 -f 319 318 326 327 -f 320 319 327 328 -f 327 326 334 335 -f 328 327 335 336 -f 329 328 336 337 -f 323 322 330 331 -f 324 323 331 332 -f 325 324 332 333 -f 326 325 333 334 -f 332 331 339 340 -f 333 332 340 341 -f 334 333 341 342 -f 335 334 342 343 -f 336 335 343 344 -f 337 336 344 345 -f 331 330 338 339 -f 344 343 351 352 -f 345 344 352 353 -f 339 338 346 347 -f 340 339 347 348 -f 341 340 348 349 -f 342 341 349 350 -f 343 342 350 351 -f 350 349 357 358 -f 351 350 358 359 -f 352 351 359 360 -f 353 352 360 361 -f 347 346 354 355 -f 348 347 355 356 -f 349 348 356 357 -f 356 355 363 364 -f 357 356 364 365 -f 358 357 365 366 -f 359 358 366 367 -f 360 359 367 368 -f 361 360 368 369 -f 355 354 362 363 -f 368 367 375 376 -f 369 368 376 377 -f 363 362 370 371 -f 364 363 371 372 -f 365 364 372 373 -f 366 365 373 374 -f 367 366 374 375 -f 374 373 381 382 -f 375 374 382 383 -f 376 375 383 384 -f 377 376 384 385 -f 371 370 378 379 -f 372 371 379 380 -f 373 372 380 381 -f 380 379 387 388 -f 381 380 388 389 -f 382 381 389 390 -f 383 382 390 391 -f 384 383 391 392 -f 385 384 392 393 -f 379 378 386 387 -f 392 391 399 400 -f 393 392 400 401 -f 387 386 394 395 -f 388 387 395 396 -f 389 388 396 397 -f 390 389 397 398 -f 391 390 398 399 -f 398 397 405 406 -f 399 398 406 407 -f 400 399 407 408 -f 401 400 408 409 -f 395 394 402 403 -f 396 395 403 404 -f 397 396 404 405 -f 403 402 410 411 -f 404 403 411 412 -f 405 404 412 413 -f 406 405 413 414 -f 407 406 414 415 -f 408 407 415 416 -f 409 408 416 417 -f 415 414 422 423 -f 416 415 423 424 -f 417 416 424 425 -f 411 410 418 419 -f 412 411 419 420 -f 413 412 420 421 -f 414 413 421 422 -f 421 420 428 429 -f 422 421 429 430 -f 423 422 430 431 -f 424 423 431 432 -f 425 424 432 433 -f 419 418 426 427 -f 420 419 427 428 -f 433 432 441 442 -f 427 426 435 436 -f 428 427 436 437 -f 429 428 437 438 -f 430 429 438 439 -f 431 430 439 440 -f 432 431 440 441 -f 440 439 447 448 -f 441 440 448 449 -f 442 441 449 450 -f 436 435 443 444 -f 437 436 444 445 -f 438 437 445 446 -f 439 438 446 447 -f 446 445 453 454 -f 447 446 454 455 -f 448 447 455 456 -f 449 448 456 457 -f 450 449 457 458 -f 444 443 451 452 -f 445 444 452 453 -f 458 457 465 466 -f 452 451 459 460 -f 453 452 460 461 -f 454 453 461 462 -f 455 454 462 463 -f 456 455 463 464 -f 457 456 464 465 -f 464 463 471 472 -f 465 464 472 473 -f 466 465 473 474 -f 460 459 467 468 -f 461 460 468 469 -f 462 461 469 470 -f 463 462 470 471 -f 470 469 477 478 -f 471 470 478 479 -f 472 471 479 480 -f 473 472 480 481 -f 474 473 481 482 -f 468 467 475 476 -f 469 468 476 477 -f 482 481 489 490 -f 476 475 483 484 -f 477 476 484 485 -f 478 477 485 486 -f 479 478 486 487 -f 480 479 487 488 -f 481 480 488 489 -f 487 486 494 495 -f 488 487 495 496 -f 489 488 496 497 -f 490 489 497 498 -f 484 483 491 492 -f 485 484 492 493 -f 486 485 493 494 -f 493 492 500 501 -f 494 493 501 502 -f 495 494 502 503 -f 496 495 503 504 -f 497 496 504 505 -f 498 497 505 506 -f 492 491 499 500 -f 505 504 512 513 -f 506 505 513 514 -f 500 499 507 508 -f 501 500 508 509 -f 502 501 509 510 -f 503 502 510 511 -f 504 503 511 512 -f 434 265 273 -f 434 273 281 -f 434 281 289 -f 434 289 297 -f 434 297 305 -f 434 305 313 -f 434 313 321 -f 434 321 329 -f 434 329 337 -f 434 337 345 -f 434 345 353 -f 434 353 361 -f 434 361 369 -f 434 369 377 -f 434 377 385 -f 434 385 393 -f 434 393 401 -f 434 401 409 -f 434 409 417 -f 434 417 425 -f 434 425 433 -f 434 433 442 -f 434 442 450 -f 434 450 458 -f 434 458 466 -f 434 466 474 -f 434 474 482 -f 434 482 490 -f 434 490 498 -f 434 498 506 -f 434 506 514 -f 511 510 261 262 -f 512 511 262 263 -f 513 512 263 264 -f 514 513 264 265 -f 508 507 258 259 -f 434 514 265 -f 509 508 259 260 -f 510 509 260 261 -f 128 378 370 120 -f 120 370 362 112 -f 136 386 378 128 -f 144 394 386 136 -f 152 402 394 144 -f 402 152 160 410 -f 168 418 410 160 -f 176 426 418 168 -f 426 176 184 435 -f 192 443 435 184 -f 200 451 443 192 -f 451 200 208 459 -f 216 467 459 208 -f 224 475 467 216 -f 232 483 475 224 -f 241 491 483 232 -f 249 499 491 241 -f 257 507 499 249 -f 8 258 507 257 -f 16 266 258 8 -f 266 16 24 274 -f 32 282 274 24 -f 40 290 282 32 -f 290 40 48 298 -f 56 306 298 48 -f 64 314 306 56 -f 314 64 72 322 -f 80 330 322 72 -f 88 338 330 80 -f 96 346 338 88 -f 104 354 346 96 -f 112 362 354 104 diff --git a/examples/common/meshes/cone.obj b/examples/common/meshes/cone.obj deleted file mode 100644 index da12486a..00000000 --- a/examples/common/meshes/cone.obj +++ /dev/null @@ -1,101 +0,0 @@ -# Blender v2.66 (sub 0) OBJ File: '' -# www.blender.org -v 0.000000 -0.500000 0.000000 -v 0.000000 -0.500000 -1.000000 -v 0.195090 -0.500000 -0.980785 -v 0.382683 -0.500000 -0.923880 -v 0.555570 -0.500000 -0.831470 -v 0.707107 -0.500000 -0.707107 -v 0.831470 -0.500000 -0.555570 -v 0.923880 -0.500000 -0.382683 -v 0.980785 -0.500000 -0.195090 -v 1.000000 -0.500000 -0.000000 -v 0.000000 0.500000 0.000000 -v 0.980785 -0.500000 0.195090 -v 0.923880 -0.500000 0.382683 -v 0.831470 -0.500000 0.555570 -v 0.707107 -0.500000 0.707107 -v 0.555570 -0.500000 0.831470 -v 0.382683 -0.500000 0.923880 -v 0.195090 -0.500000 0.980785 -v -0.000000 -0.500000 1.000000 -v -0.195091 -0.500000 0.980785 -v -0.382684 -0.500000 0.923879 -v -0.555571 -0.500000 0.831469 -v -0.707107 -0.500000 0.707106 -v -0.831470 -0.500000 0.555570 -v -0.923880 -0.500000 0.382683 -v -0.980785 -0.500000 0.195089 -v -1.000000 -0.500000 -0.000001 -v -0.980785 -0.500000 -0.195091 -v -0.923879 -0.500000 -0.382684 -v -0.831469 -0.500000 -0.555571 -v -0.707106 -0.500000 -0.707108 -v -0.555569 -0.500000 -0.831470 -v -0.382682 -0.500000 -0.923880 -v -0.195089 -0.500000 -0.980786 -s off -f 1 2 3 -f 1 3 4 -f 1 4 5 -f 1 5 6 -f 1 6 7 -f 1 7 8 -f 1 8 9 -f 1 9 10 -f 1 10 12 -f 1 12 13 -f 1 13 14 -f 1 14 15 -f 1 15 16 -f 1 16 17 -f 1 17 18 -f 1 18 19 -f 1 19 20 -f 1 20 21 -f 1 21 22 -f 1 22 23 -f 1 23 24 -f 1 24 25 -f 1 25 26 -f 1 26 27 -f 1 27 28 -f 1 28 29 -f 1 29 30 -f 1 30 31 -f 1 31 32 -f 1 32 33 -f 1 33 34 -f 1 34 2 -f 2 11 3 -f 3 11 4 -f 4 11 5 -f 5 11 6 -f 6 11 7 -f 7 11 8 -f 8 11 9 -f 9 11 10 -f 10 11 12 -f 12 11 13 -f 13 11 14 -f 14 11 15 -f 15 11 16 -f 16 11 17 -f 17 11 18 -f 18 11 19 -f 19 11 20 -f 20 11 21 -f 21 11 22 -f 22 11 23 -f 23 11 24 -f 24 11 25 -f 25 11 26 -f 26 11 27 -f 27 11 28 -f 28 11 29 -f 29 11 30 -f 30 11 31 -f 31 11 32 -f 32 11 33 -f 33 11 34 -f 34 11 2 diff --git a/examples/common/meshes/convexmesh.obj b/examples/common/meshes/convexmesh.obj deleted file mode 100644 index 7a194f13..00000000 --- a/examples/common/meshes/convexmesh.obj +++ /dev/null @@ -1,125 +0,0 @@ -# Blender v2.66 (sub 0) OBJ File: '' -# www.blender.org -v 0.000000 -1.000000 0.000000 -v 0.723607 -0.447220 0.525725 -v -0.276388 -0.447220 0.850649 -v -0.894426 -0.447216 0.000000 -v -0.276388 -0.447220 -0.850649 -v 0.723607 -0.447220 -0.525725 -v 0.276388 0.447220 0.850649 -v -0.723607 0.447220 0.525725 -v -0.723607 0.447220 -0.525725 -v 0.276388 0.447220 -0.850649 -v 0.894426 0.447216 0.000000 -v 0.000000 1.000000 0.000000 -v 0.425323 -0.850654 0.309011 -v 0.262869 -0.525738 0.809012 -v -0.162456 -0.850654 0.499995 -v 0.425323 -0.850654 -0.309011 -v 0.850648 -0.525736 0.000000 -v -0.688189 -0.525736 0.499997 -v -0.525730 -0.850652 0.000000 -v -0.688189 -0.525736 -0.499997 -v -0.162456 -0.850654 -0.499995 -v 0.262869 -0.525738 -0.809012 -v 0.951058 0.000000 -0.309013 -v 0.951058 0.000000 0.309013 -v 0.587786 0.000000 0.809017 -v 0.000000 0.000000 1.000000 -v -0.587786 0.000000 0.809017 -v -0.951058 0.000000 0.309013 -v -0.951058 0.000000 -0.309013 -v -0.587786 0.000000 -0.809017 -v 0.000000 0.000000 -1.000000 -v 0.587786 0.000000 -0.809017 -v 0.688189 0.525736 0.499997 -v -0.262869 0.525738 0.809012 -v -0.850648 0.525736 0.000000 -v -0.262869 0.525738 -0.809012 -v 0.688189 0.525736 -0.499997 -v 0.525730 0.850652 0.000000 -v 0.162456 0.850654 0.499995 -v -0.425323 0.850654 0.309011 -v -0.425323 0.850654 -0.309011 -v 0.162456 0.850654 -0.499995 -s off -f 1 13 15 -f 2 13 17 -f 1 15 19 -f 1 19 21 -f 1 21 16 -f 2 17 24 -f 3 14 26 -f 4 18 28 -f 5 20 30 -f 6 22 32 -f 2 24 25 -f 3 26 27 -f 4 28 29 -f 5 30 31 -f 6 32 23 -f 7 33 39 -f 8 34 40 -f 9 35 41 -f 10 36 42 -f 11 37 38 -f 15 14 3 -f 15 13 14 -f 13 2 14 -f 17 16 6 -f 17 13 16 -f 13 1 16 -f 19 18 4 -f 19 15 18 -f 15 3 18 -f 21 20 5 -f 21 19 20 -f 19 4 20 -f 16 22 6 -f 16 21 22 -f 21 5 22 -f 24 23 11 -f 24 17 23 -f 17 6 23 -f 26 25 7 -f 26 14 25 -f 14 2 25 -f 28 27 8 -f 28 18 27 -f 18 3 27 -f 30 29 9 -f 30 20 29 -f 20 4 29 -f 32 31 10 -f 32 22 31 -f 22 5 31 -f 25 33 7 -f 25 24 33 -f 24 11 33 -f 27 34 8 -f 27 26 34 -f 26 7 34 -f 29 35 9 -f 29 28 35 -f 28 8 35 -f 31 36 10 -f 31 30 36 -f 30 9 36 -f 23 37 11 -f 23 32 37 -f 32 10 37 -f 39 38 12 -f 39 33 38 -f 33 11 38 -f 40 39 12 -f 40 34 39 -f 34 7 39 -f 41 40 12 -f 41 35 40 -f 35 8 40 -f 42 41 12 -f 42 36 41 -f 36 9 41 -f 38 42 12 -f 38 37 42 -f 37 10 42 diff --git a/examples/common/meshes/cylinder.obj b/examples/common/meshes/cylinder.obj deleted file mode 100644 index 4fb9c374..00000000 --- a/examples/common/meshes/cylinder.obj +++ /dev/null @@ -1,293 +0,0 @@ -# Blender v2.66 (sub 0) OBJ File: '' -# www.blender.org -v 0.000000 -0.500000 0.000000 -v 0.000000 0.500000 0.000000 -v 0.000000 -0.500000 -1.000000 -v 0.000000 0.500000 -1.000000 -v 0.195090 -0.500000 -0.980785 -v 0.195090 0.500000 -0.980785 -v 0.382683 -0.500000 -0.923880 -v 0.382683 0.500000 -0.923880 -v 0.555570 -0.500000 -0.831470 -v 0.555570 0.500000 -0.831470 -v 0.707107 -0.500000 -0.707107 -v 0.707107 0.500000 -0.707107 -v 0.831470 -0.500000 -0.555570 -v 0.831470 0.500000 -0.555570 -v 0.923880 -0.500000 -0.382683 -v 0.923880 0.500000 -0.382683 -v 0.980785 -0.500000 -0.195090 -v 0.980785 0.500000 -0.195090 -v 1.000000 -0.500000 -0.000000 -v 1.000000 0.500000 -0.000000 -v 0.980785 -0.500000 0.195090 -v 0.980785 0.500000 0.195090 -v 0.923880 -0.500000 0.382683 -v 0.923880 0.500000 0.382683 -v 0.831470 -0.500000 0.555570 -v 0.831470 0.500000 0.555570 -v 0.707107 -0.500000 0.707107 -v 0.707107 0.500000 0.707107 -v 0.555570 -0.500000 0.831470 -v 0.555570 0.500000 0.831470 -v 0.382683 -0.500000 0.923880 -v 0.382683 0.500000 0.923880 -v 0.195090 -0.500000 0.980785 -v 0.195090 0.500000 0.980785 -v -0.000000 -0.500000 1.000000 -v -0.000000 0.500000 1.000000 -v -0.195091 -0.500000 0.980785 -v -0.195091 0.500000 0.980785 -v -0.382684 -0.500000 0.923879 -v -0.382684 0.500000 0.923879 -v -0.555571 -0.500000 0.831469 -v -0.555571 0.500000 0.831469 -v -0.707107 -0.500000 0.707106 -v -0.707107 0.500000 0.707106 -v -0.831470 -0.500000 0.555570 -v -0.831470 0.500000 0.555570 -v -0.923880 -0.500000 0.382683 -v -0.923880 0.500000 0.382683 -v -0.980785 -0.500000 0.195089 -v -0.980785 0.500000 0.195089 -v -1.000000 -0.500000 -0.000001 -v -1.000000 0.500000 -0.000001 -v -0.980785 -0.500000 -0.195091 -v -0.980785 0.500000 -0.195091 -v -0.923879 -0.500000 -0.382684 -v -0.923879 0.500000 -0.382684 -v -0.831469 -0.500000 -0.555571 -v -0.831469 0.500000 -0.555571 -v -0.707106 -0.500000 -0.707108 -v -0.707106 0.500000 -0.707108 -v -0.555569 -0.500000 -0.831470 -v -0.555569 0.500000 -0.831470 -v -0.382682 -0.500000 -0.923880 -v -0.382682 0.500000 -0.923880 -v -0.195089 -0.500000 -0.980786 -v -0.195089 0.500000 -0.980786 -v 0.000000 0.000000 -1.000000 -v 0.195090 0.000000 -0.980785 -v 0.382683 0.000000 -0.923880 -v 0.555570 0.000000 -0.831470 -v 0.707107 0.000000 -0.707107 -v 0.831470 0.000000 -0.555570 -v 0.923880 0.000000 -0.382683 -v 0.980785 0.000000 -0.195090 -v 1.000000 0.000000 -0.000000 -v 0.980785 0.000000 0.195090 -v 0.923880 0.000000 0.382683 -v 0.831470 0.000000 0.555570 -v 0.707107 0.000000 0.707107 -v 0.555570 0.000000 0.831470 -v 0.382683 0.000000 0.923880 -v 0.195090 0.000000 0.980785 -v -0.000000 0.000000 1.000000 -v -0.195091 0.000000 0.980785 -v -0.382684 0.000000 0.923879 -v -0.555571 0.000000 0.831469 -v -0.707107 0.000000 0.707106 -v -0.831470 0.000000 0.555570 -v -0.923880 0.000000 0.382683 -v -0.980785 0.000000 0.195089 -v -1.000000 0.000000 -0.000001 -v -0.980785 0.000000 -0.195091 -v -0.923879 0.000000 -0.382684 -v -0.831469 0.000000 -0.555571 -v -0.707106 0.000000 -0.707108 -v -0.555569 0.000000 -0.831470 -v -0.382682 0.000000 -0.923880 -v -0.195089 0.000000 -0.980786 -s off -f 1 3 5 -f 2 6 4 -f 67 4 6 -f 1 5 7 -f 2 8 6 -f 68 6 8 -f 1 7 9 -f 2 10 8 -f 69 8 10 -f 1 9 11 -f 2 12 10 -f 70 10 12 -f 1 11 13 -f 2 14 12 -f 71 12 14 -f 1 13 15 -f 2 16 14 -f 72 14 16 -f 1 15 17 -f 2 18 16 -f 73 16 18 -f 1 17 19 -f 2 20 18 -f 74 18 20 -f 1 19 21 -f 2 22 20 -f 75 20 22 -f 1 21 23 -f 2 24 22 -f 76 22 24 -f 1 23 25 -f 2 26 24 -f 77 24 26 -f 1 25 27 -f 2 28 26 -f 78 26 28 -f 1 27 29 -f 2 30 28 -f 79 28 30 -f 1 29 31 -f 2 32 30 -f 80 30 32 -f 1 31 33 -f 2 34 32 -f 81 32 34 -f 1 33 35 -f 2 36 34 -f 82 34 36 -f 1 35 37 -f 2 38 36 -f 83 36 38 -f 1 37 39 -f 2 40 38 -f 84 38 40 -f 1 39 41 -f 2 42 40 -f 85 40 42 -f 1 41 43 -f 2 44 42 -f 86 42 44 -f 1 43 45 -f 2 46 44 -f 87 44 46 -f 1 45 47 -f 2 48 46 -f 88 46 48 -f 1 47 49 -f 2 50 48 -f 89 48 50 -f 1 49 51 -f 2 52 50 -f 90 50 52 -f 1 51 53 -f 2 54 52 -f 91 52 54 -f 1 53 55 -f 2 56 54 -f 92 54 56 -f 1 55 57 -f 2 58 56 -f 93 56 58 -f 1 57 59 -f 2 60 58 -f 94 58 60 -f 1 59 61 -f 2 62 60 -f 95 60 62 -f 1 61 63 -f 2 64 62 -f 96 62 64 -f 1 63 65 -f 2 66 64 -f 97 64 66 -f 1 65 3 -f 2 4 66 -f 98 66 4 -f 3 67 68 -f 5 68 69 -f 7 69 70 -f 9 70 71 -f 11 71 72 -f 13 72 73 -f 15 73 74 -f 17 74 75 -f 19 75 76 -f 21 76 77 -f 23 77 78 -f 25 78 79 -f 27 79 80 -f 29 80 81 -f 31 81 82 -f 33 82 83 -f 35 83 84 -f 37 84 85 -f 39 85 86 -f 41 86 87 -f 43 87 88 -f 45 88 89 -f 47 89 90 -f 49 90 91 -f 51 91 92 -f 53 92 93 -f 55 93 94 -f 57 94 95 -f 59 95 96 -f 61 96 97 -f 63 97 98 -f 65 98 67 -f 86 85 42 -f 87 86 44 -f 88 87 46 -f 43 41 87 -f 45 43 88 -f 80 79 30 -f 81 80 32 -f 82 81 34 -f 83 82 36 -f 84 83 38 -f 85 84 40 -f 29 27 80 -f 31 29 81 -f 33 31 82 -f 35 33 83 -f 37 35 84 -f 39 37 85 -f 41 39 86 -f 68 67 6 -f 69 68 8 -f 70 69 10 -f 71 70 12 -f 72 71 14 -f 73 72 16 -f 74 73 18 -f 75 74 20 -f 76 75 22 -f 77 76 24 -f 78 77 26 -f 79 78 28 -f 89 88 48 -f 90 89 50 -f 91 90 52 -f 92 91 54 -f 93 92 56 -f 94 93 58 -f 95 94 60 -f 96 95 62 -f 97 96 64 -f 98 97 66 -f 67 98 4 -f 5 3 68 -f 7 5 69 -f 9 7 70 -f 11 9 71 -f 13 11 72 -f 15 13 73 -f 17 15 74 -f 19 17 75 -f 21 19 76 -f 23 21 77 -f 25 23 78 -f 27 25 79 -f 47 45 89 -f 49 47 90 -f 51 49 91 -f 53 51 92 -f 55 53 93 -f 57 55 94 -f 59 57 95 -f 61 59 96 -f 63 61 97 -f 65 63 98 -f 3 65 67 diff --git a/examples/common/meshes/dumbbell.obj b/examples/common/meshes/dumbbell.obj deleted file mode 100644 index 43099a93..00000000 --- a/examples/common/meshes/dumbbell.obj +++ /dev/null @@ -1,1396 +0,0 @@ -#### -# -# OBJ File Generated by Meshlab -# -#### -# Object dumbbell.obj -# -# Vertices: 464 -# Faces: 916 -# -#### -v -0.429342 4.000000 1.439240 -v -0.823902 4.000000 1.261880 -v -1.151714 4.000000 0.982291 -v -1.386221 4.000000 0.623122 -v -1.508424 4.000000 0.213472 -v -1.508424 4.000000 -0.213472 -v -1.386221 4.000000 -0.623123 -v -1.151714 4.000000 -0.982291 -v -0.823902 4.000000 -1.261880 -v -0.429342 4.000000 -1.439240 -v -0.410268 4.126197 1.439240 -v -0.787298 4.242170 1.261880 -v -1.100546 4.338524 0.982291 -v -1.324635 4.407454 0.623122 -v -1.441409 4.443373 0.213472 -v -1.441409 4.443373 -0.213472 -v -1.324635 4.407454 -0.623123 -v -1.100546 4.338524 -0.982291 -v -0.787298 4.242170 -1.261880 -v -0.410268 4.126197 -1.439240 -v -0.354739 4.241181 1.439240 -v -0.680740 4.462823 1.261880 -v -0.951591 4.646970 0.982291 -v -1.145349 4.778703 0.623122 -v -1.246319 4.847349 0.213472 -v -1.246319 4.847349 -0.213472 -v -1.145349 4.778703 -0.623123 -v -0.951590 4.646970 -0.982291 -v -0.680740 4.462823 -1.261880 -v -0.354739 4.241181 -1.439240 -v -0.267691 4.334735 1.439240 -v -0.513694 4.642351 1.261880 -v -0.718082 4.897928 0.982291 -v -0.864294 5.080761 0.623122 -v -0.940487 5.176036 0.213472 -v -0.940487 5.176036 -0.213472 -v -0.864295 5.080761 -0.623123 -v -0.718082 4.897928 -0.982291 -v -0.513694 4.642351 -1.261880 -v -0.267691 4.334735 -1.439240 -v -0.156856 4.398545 1.439240 -v -0.301005 4.764804 1.261880 -v -0.420768 5.069102 0.982291 -v -0.506443 5.286788 0.623122 -v -0.551089 5.400227 0.213472 -v -0.551089 5.400227 -0.213472 -v -0.506443 5.286788 -0.623123 -v -0.420768 5.069102 -0.982291 -v -0.301005 4.764804 -1.261880 -v -0.156856 4.398545 -1.439240 -v -0.032085 4.426945 1.439240 -v -0.061570 4.819301 1.261880 -v -0.086068 5.145282 0.982291 -v -0.103592 5.378479 0.623122 -v -0.112725 5.500000 0.213472 -v -0.112725 5.500000 -0.213472 -v -0.103593 5.378479 -0.623123 -v -0.086068 5.145282 -0.982291 -v -0.061570 4.819301 -1.261880 -v -0.032085 4.426945 -1.439240 -v 0.095537 4.417407 1.439240 -v 0.183335 4.800999 1.261880 -v 0.256280 5.119698 0.982291 -v 0.308463 5.347686 0.623122 -v 0.335656 5.466493 0.213472 -v 0.335656 5.466493 -0.213472 -v 0.308463 5.347686 -0.623123 -v 0.256280 5.119698 -0.982291 -v 0.183335 4.800999 -1.261880 -v 0.095537 4.417407 -1.439240 -v 0.214671 4.370781 1.439240 -v 0.411951 4.711524 1.261880 -v 0.575857 4.994623 0.982291 -v 0.693110 5.197145 0.623122 -v 0.754212 5.302681 0.213472 -v 0.754212 5.302681 -0.213472 -v 0.693110 5.197145 -0.623123 -v 0.575857 4.994623 -0.982291 -v 0.411951 4.711524 -1.261880 -v 0.214671 4.370781 -1.439240 -v 0.000000 4.000000 1.500000 -v 0.314730 4.291210 1.439240 -v 0.603963 4.558828 1.261880 -v 0.844266 4.781174 0.982291 -v 1.016171 4.940232 0.623122 -v 1.105753 5.023119 0.213472 -v 1.105753 5.023119 -0.213472 -v 1.016171 4.940232 -0.623123 -v 0.844265 4.781174 -0.982291 -v 0.603963 4.558828 -1.261880 -v 0.314730 4.291210 -1.439240 -v 0.000000 4.000000 -1.500000 -v 0.386824 4.185763 1.439240 -v 0.742310 4.356478 1.261880 -v 1.037658 4.498313 0.982291 -v 1.248941 4.599776 0.623122 -v 1.359043 4.652650 0.213472 -v 1.359043 4.652650 -0.213472 -v 1.248941 4.599776 -0.623123 -v 1.037657 4.498311 -0.982291 -v 0.742310 4.356478 -1.261880 -v 0.386824 4.185763 -1.439240 -v 0.424547 4.063811 1.439240 -v 0.814699 4.122453 1.261880 -v 1.138849 4.171173 0.982291 -v 1.370737 4.206027 0.623122 -v 1.491576 4.224190 0.213472 -v 1.491576 4.224190 -0.213472 -v 1.370737 4.206027 -0.623123 -v 1.138849 4.171173 -0.982291 -v 0.814699 4.122453 -1.261880 -v 0.424547 4.063811 -1.439240 -v 0.424546 3.936189 1.439240 -v 0.814699 3.877547 1.261880 -v 1.138849 3.828825 0.982291 -v 1.370737 3.793972 0.623122 -v 1.491575 3.775809 0.213472 -v 1.491575 3.775809 -0.213472 -v 1.370737 3.793972 -0.623123 -v 1.138849 3.828825 -0.982291 -v 0.814699 3.877547 -1.261880 -v 0.424547 3.936189 -1.439240 -v 0.386824 3.814236 1.439240 -v 0.742309 3.643522 1.261880 -v 1.037657 3.501688 0.982291 -v 1.248941 3.400223 0.623122 -v 1.359042 3.347349 0.213472 -v 1.359042 3.347349 -0.213472 -v 1.248941 3.400223 -0.623123 -v 1.037657 3.501688 -0.982291 -v 0.742309 3.643522 -1.261880 -v 0.386824 3.814236 -1.439240 -v 0.314730 3.708790 1.439240 -v 0.603962 3.441171 1.261880 -v 0.844265 3.218826 0.982291 -v 1.016171 3.059767 0.623122 -v 1.105752 2.976880 0.213472 -v 1.105752 2.976880 -0.213472 -v 1.016171 3.059767 -0.623123 -v 0.844265 3.218826 -0.982291 -v 0.603962 3.441171 -1.261880 -v 0.314730 3.708790 -1.439240 -v 0.214671 3.629218 1.439240 -v 0.411950 3.288475 1.261880 -v 0.575856 3.005375 0.982291 -v 0.693109 2.802855 0.623122 -v 0.754211 2.697319 0.213472 -v 0.754211 2.697319 -0.213472 -v 0.693109 2.802855 -0.623123 -v 0.575856 3.005376 -0.982291 -v 0.411950 3.288475 -1.261880 -v 0.214671 3.629218 -1.439240 -v 0.095537 3.582592 1.439240 -v 0.183335 3.199001 1.261880 -v 0.256280 2.880302 0.982291 -v 0.308462 2.652314 0.623122 -v 0.335655 2.533507 0.213472 -v 0.335655 2.533507 -0.213472 -v 0.308462 2.652314 -0.623123 -v 0.256280 2.880302 -0.982291 -v 0.183335 3.199001 -1.261880 -v 0.095537 3.582592 -1.439240 -v -0.032085 3.573055 1.439240 -v -0.061571 3.180699 1.261880 -v -0.086068 2.854718 0.982291 -v -0.103593 2.621521 0.623122 -v -0.112726 2.500000 0.213472 -v -0.112726 2.500000 -0.213472 -v -0.103593 2.621521 -0.623123 -v -0.086068 2.854718 -0.982291 -v -0.061571 3.180699 -1.261880 -v -0.032085 3.573055 -1.439240 -v -0.156857 3.601454 1.439240 -v -0.301005 3.235196 1.261880 -v -0.420769 2.930898 0.982291 -v -0.506444 2.713212 0.623122 -v -0.551090 2.599774 0.213472 -v -0.551090 2.599774 -0.213472 -v -0.506444 2.713212 -0.623123 -v -0.420769 2.930898 -0.982291 -v -0.301005 3.235196 -1.261880 -v -0.156857 3.601454 -1.439240 -v -0.267691 3.665266 1.439240 -v -0.513695 3.357649 1.261880 -v -0.718082 3.102072 0.982291 -v -0.864295 2.919240 0.623122 -v -0.940488 2.823965 0.213472 -v -0.940488 2.823965 -0.213472 -v -0.864295 2.919240 -0.623123 -v -0.718082 3.102072 -0.982291 -v -0.513695 3.357649 -1.261880 -v -0.267691 3.665266 -1.439240 -v -0.354739 3.758819 1.439240 -v -0.680740 3.537178 1.261880 -v -0.951591 3.353031 0.982291 -v -1.145349 3.221298 0.623122 -v -1.246319 3.152651 0.213472 -v -1.246319 3.152651 -0.213472 -v -1.145349 3.221298 -0.623123 -v -0.951591 3.353031 -0.982291 -v -0.680740 3.537178 -1.261880 -v -0.354739 3.758819 -1.439240 -v -0.410268 3.873803 1.439240 -v -0.787298 3.757830 1.261880 -v -1.100546 3.661476 0.982291 -v -1.324635 3.592547 0.623122 -v -1.441409 3.556628 0.213472 -v -1.441409 3.556628 -0.213472 -v -1.324635 3.592547 -0.623123 -v -1.100546 3.661476 -0.982291 -v -0.787298 3.757830 -1.261880 -v -0.410268 3.873803 -1.439240 -v -0.039595 2.492897 0.497466 -v -0.039595 -2.507103 0.497462 -v 0.114914 2.492897 0.472994 -v 0.114914 -2.507103 0.472991 -v 0.254298 2.492897 0.401974 -v 0.254298 -2.507103 0.401971 -v 0.364914 2.492897 0.291358 -v 0.364914 -2.507103 0.291355 -v 0.435934 2.492897 0.151974 -v 0.435934 -2.507103 0.151971 -v 0.460405 2.492897 -0.002534 -v 0.460405 -2.507103 -0.002538 -v 0.435934 2.492897 -0.157043 -v 0.435934 -2.507103 -0.157046 -v 0.364914 2.492897 -0.296427 -v 0.364914 -2.507103 -0.296430 -v 0.254298 2.492897 -0.407043 -v 0.254298 -2.507103 -0.407046 -v 0.114914 2.492897 -0.478063 -v 0.114914 -2.507103 -0.478066 -v -0.039595 2.492897 -0.502534 -v -0.039595 -2.507103 -0.502538 -v -0.194103 2.492897 -0.478063 -v -0.194103 -2.507103 -0.478066 -v -0.333487 2.492897 -0.407043 -v -0.333487 -2.507103 -0.407046 -v -0.444103 2.492897 -0.296427 -v -0.444103 -2.507103 -0.296430 -v -0.515123 2.492897 -0.157042 -v -0.515123 -2.507103 -0.157046 -v -0.539595 2.492897 -0.002534 -v -0.539595 -2.507103 -0.002537 -v -0.515123 2.492897 0.151975 -v -0.515123 -2.507103 0.151971 -v -0.444103 2.492897 0.291359 -v -0.444103 -2.507103 0.291356 -v -0.333487 2.492897 0.401975 -v -0.333487 -2.507103 0.401971 -v -0.194102 2.492897 0.472994 -v -0.194102 -2.507103 0.472991 -v -0.429342 -4.000000 1.439240 -v -0.823902 -4.000000 1.261880 -v -1.151714 -4.000000 0.982291 -v -1.386221 -4.000000 0.623122 -v -1.508424 -4.000000 0.213472 -v -1.508424 -4.000000 -0.213472 -v -1.386221 -4.000000 -0.623123 -v -1.151714 -4.000000 -0.982291 -v -0.823902 -4.000000 -1.261880 -v -0.429342 -4.000000 -1.439240 -v -0.410268 -3.873803 1.439240 -v -0.787298 -3.757830 1.261880 -v -1.100546 -3.661476 0.982291 -v -1.324635 -3.592547 0.623122 -v -1.441409 -3.556627 0.213472 -v -1.441409 -3.556627 -0.213472 -v -1.324635 -3.592547 -0.623123 -v -1.100546 -3.661476 -0.982291 -v -0.787298 -3.757830 -1.261880 -v -0.410268 -3.873803 -1.439240 -v -0.354739 -3.758819 1.439240 -v -0.680740 -3.537177 1.261880 -v -0.951591 -3.353031 0.982291 -v -1.145349 -3.221298 0.623122 -v -1.246319 -3.152650 0.213472 -v -1.246319 -3.152650 -0.213472 -v -1.145349 -3.221298 -0.623123 -v -0.951590 -3.353031 -0.982291 -v -0.680740 -3.537177 -1.261880 -v -0.354739 -3.758819 -1.439240 -v -0.267691 -3.665265 1.439240 -v -0.513694 -3.357649 1.261880 -v -0.718082 -3.102072 0.982291 -v -0.864294 -2.919240 0.623122 -v -0.940487 -2.823964 0.213472 -v -0.940487 -2.823964 -0.213472 -v -0.864295 -2.919240 -0.623123 -v -0.718082 -3.102072 -0.982291 -v -0.513694 -3.357649 -1.261880 -v -0.267691 -3.665265 -1.439240 -v -0.156856 -3.601454 1.439240 -v -0.301005 -3.235196 1.261880 -v -0.420768 -2.930898 0.982291 -v -0.506443 -2.713212 0.623122 -v -0.551089 -2.599774 0.213472 -v -0.551089 -2.599774 -0.213472 -v -0.506443 -2.713212 -0.623123 -v -0.420768 -2.930898 -0.982291 -v -0.301005 -3.235196 -1.261880 -v -0.156856 -3.601454 -1.439240 -v -0.032085 -3.573056 1.439240 -v -0.061570 -3.180699 1.261880 -v -0.086068 -2.854718 0.982291 -v -0.103592 -2.621521 0.623122 -v -0.112725 -2.500000 0.213472 -v -0.112725 -2.500000 -0.213472 -v -0.103593 -2.621521 -0.623123 -v -0.086068 -2.854718 -0.982291 -v -0.061570 -3.180699 -1.261880 -v -0.032085 -3.573056 -1.439240 -v 0.095537 -3.582593 1.439240 -v 0.183335 -3.199001 1.261880 -v 0.256280 -2.880302 0.982291 -v 0.308463 -2.652314 0.623122 -v 0.335656 -2.533507 0.213472 -v 0.335656 -2.533507 -0.213472 -v 0.308463 -2.652314 -0.623123 -v 0.256280 -2.880302 -0.982291 -v 0.183335 -3.199001 -1.261880 -v 0.095537 -3.582593 -1.439240 -v 0.214671 -3.629219 1.439240 -v 0.411951 -3.288476 1.261880 -v 0.575857 -3.005376 0.982291 -v 0.693110 -2.802855 0.623122 -v 0.754212 -2.697320 0.213472 -v 0.754212 -2.697320 -0.213472 -v 0.693110 -2.802855 -0.623123 -v 0.575857 -3.005376 -0.982291 -v 0.411951 -3.288476 -1.261880 -v 0.214671 -3.629218 -1.439240 -v 0.000000 -4.000000 1.500000 -v 0.314730 -3.708790 1.439240 -v 0.603963 -3.441172 1.261880 -v 0.844266 -3.218827 0.982291 -v 1.016171 -3.059767 0.623122 -v 1.105753 -2.976881 0.213472 -v 1.105753 -2.976881 -0.213472 -v 1.016171 -3.059767 -0.623123 -v 0.844265 -3.218827 -0.982291 -v 0.603963 -3.441172 -1.261880 -v 0.314730 -3.708790 -1.439240 -v 0.000000 -4.000000 -1.500000 -v 0.386824 -3.814236 1.439240 -v 0.742310 -3.643522 1.261880 -v 1.037658 -3.501688 0.982291 -v 1.248941 -3.400224 0.623122 -v 1.359043 -3.347350 0.213472 -v 1.359043 -3.347350 -0.213472 -v 1.248941 -3.400223 -0.623123 -v 1.037657 -3.501688 -0.982291 -v 0.742310 -3.643522 -1.261880 -v 0.386824 -3.814236 -1.439240 -v 0.424547 -3.936189 1.439240 -v 0.814699 -3.877548 1.261880 -v 1.138849 -3.828826 0.982291 -v 1.370737 -3.793973 0.623122 -v 1.491576 -3.775810 0.213472 -v 1.491576 -3.775810 -0.213472 -v 1.370737 -3.793972 -0.623123 -v 1.138849 -3.828826 -0.982291 -v 0.814699 -3.877548 -1.261880 -v 0.424547 -3.936189 -1.439240 -v 0.424546 -4.063811 1.439240 -v 0.814699 -4.122453 1.261880 -v 1.138849 -4.171175 0.982291 -v 1.370737 -4.206028 0.623122 -v 1.491575 -4.224191 0.213472 -v 1.491575 -4.224191 -0.213472 -v 1.370737 -4.206028 -0.623123 -v 1.138849 -4.171175 -0.982291 -v 0.814699 -4.122453 -1.261880 -v 0.424547 -4.063811 -1.439240 -v 0.386824 -4.185764 1.439240 -v 0.742309 -4.356478 1.261880 -v 1.037657 -4.498313 0.982291 -v 1.248941 -4.599777 0.623122 -v 1.359042 -4.652651 0.213472 -v 1.359042 -4.652651 -0.213472 -v 1.248941 -4.599777 -0.623123 -v 1.037657 -4.498313 -0.982291 -v 0.742309 -4.356478 -1.261880 -v 0.386824 -4.185764 -1.439240 -v 0.314730 -4.291210 1.439240 -v 0.603962 -4.558829 1.261880 -v 0.844265 -4.781174 0.982291 -v 1.016171 -4.940233 0.623122 -v 1.105752 -5.023120 0.213472 -v 1.105752 -5.023120 -0.213472 -v 1.016171 -4.940233 -0.623123 -v 0.844265 -4.781174 -0.982291 -v 0.603962 -4.558829 -1.261880 -v 0.314730 -4.291210 -1.439240 -v 0.214671 -4.370781 1.439240 -v 0.411950 -4.711525 1.261880 -v 0.575856 -4.994625 0.982291 -v 0.693109 -5.197145 0.623122 -v 0.754211 -5.302681 0.213472 -v 0.754211 -5.302681 -0.213472 -v 0.693109 -5.197145 -0.623123 -v 0.575856 -4.994624 -0.982291 -v 0.411950 -4.711525 -1.261880 -v 0.214671 -4.370781 -1.439240 -v 0.095537 -4.417407 1.439240 -v 0.183335 -4.800999 1.261880 -v 0.256280 -5.119698 0.982291 -v 0.308462 -5.347686 0.623122 -v 0.335655 -5.466493 0.213472 -v 0.335655 -5.466493 -0.213472 -v 0.308462 -5.347686 -0.623123 -v 0.256280 -5.119698 -0.982291 -v 0.183335 -4.800999 -1.261880 -v 0.095537 -4.417408 -1.439240 -v -0.032085 -4.426944 1.439240 -v -0.061571 -4.819301 1.261880 -v -0.086068 -5.145282 0.982291 -v -0.103593 -5.378479 0.623122 -v -0.112726 -5.500000 0.213472 -v -0.112726 -5.500000 -0.213472 -v -0.103593 -5.378479 -0.623123 -v -0.086068 -5.145282 -0.982291 -v -0.061571 -4.819301 -1.261880 -v -0.032085 -4.426945 -1.439240 -v -0.156857 -4.398546 1.439240 -v -0.301005 -4.764804 1.261880 -v -0.420769 -5.069102 0.982291 -v -0.506444 -5.286788 0.623122 -v -0.551090 -5.400226 0.213472 -v -0.551090 -5.400226 -0.213472 -v -0.506444 -5.286788 -0.623123 -v -0.420769 -5.069102 -0.982291 -v -0.301005 -4.764804 -1.261880 -v -0.156857 -4.398546 -1.439240 -v -0.267691 -4.334734 1.439240 -v -0.513695 -4.642351 1.261880 -v -0.718082 -4.897928 0.982291 -v -0.864295 -5.080760 0.623122 -v -0.940488 -5.176035 0.213472 -v -0.940488 -5.176035 -0.213472 -v -0.864295 -5.080760 -0.623123 -v -0.718082 -4.897928 -0.982291 -v -0.513695 -4.642351 -1.261880 -v -0.267691 -4.334734 -1.439240 -v -0.354739 -4.241180 1.439240 -v -0.680740 -4.462822 1.261880 -v -0.951591 -4.646969 0.982291 -v -1.145349 -4.778702 0.623122 -v -1.246319 -4.847349 0.213472 -v -1.246319 -4.847349 -0.213472 -v -1.145349 -4.778702 -0.623123 -v -0.951591 -4.646969 -0.982291 -v -0.680740 -4.462822 -1.261880 -v -0.354739 -4.241180 -1.439240 -v -0.410268 -4.126197 1.439240 -v -0.787298 -4.242170 1.261880 -v -1.100546 -4.338524 0.982291 -v -1.324635 -4.407453 0.623122 -v -1.441409 -4.443372 0.213472 -v -1.441409 -4.443372 -0.213472 -v -1.324635 -4.407453 -0.623123 -v -1.100546 -4.338524 -0.982291 -v -0.787298 -4.242170 -1.261880 -v -0.410268 -4.126197 -1.439240 -# 464 vertices, 0 vertices normals - -f 10 9 19 -f 10 19 20 -f 9 8 18 -f 9 18 19 -f 8 7 17 -f 8 17 18 -f 7 6 16 -f 7 16 17 -f 6 5 15 -f 6 15 16 -f 5 4 14 -f 5 14 15 -f 4 3 13 -f 4 13 14 -f 3 2 12 -f 3 12 13 -f 2 1 11 -f 2 11 12 -f 20 19 29 -f 20 29 30 -f 19 18 28 -f 19 28 29 -f 18 17 27 -f 18 27 28 -f 17 16 26 -f 17 26 27 -f 16 15 25 -f 16 25 26 -f 15 14 24 -f 15 24 25 -f 14 13 23 -f 14 23 24 -f 13 12 22 -f 13 22 23 -f 12 11 21 -f 12 21 22 -f 30 29 39 -f 30 39 40 -f 29 28 38 -f 29 38 39 -f 28 27 37 -f 28 37 38 -f 27 26 36 -f 27 36 37 -f 26 25 35 -f 26 35 36 -f 25 24 34 -f 25 34 35 -f 24 23 33 -f 24 33 34 -f 23 22 32 -f 23 32 33 -f 22 21 31 -f 22 31 32 -f 40 39 49 -f 40 49 50 -f 39 38 48 -f 39 48 49 -f 38 37 47 -f 38 47 48 -f 37 36 46 -f 37 46 47 -f 36 35 45 -f 36 45 46 -f 35 34 44 -f 35 44 45 -f 34 33 43 -f 34 43 44 -f 33 32 42 -f 33 42 43 -f 32 31 41 -f 32 41 42 -f 50 49 59 -f 50 59 60 -f 49 48 58 -f 49 58 59 -f 48 47 57 -f 48 57 58 -f 47 46 56 -f 47 56 57 -f 46 45 55 -f 46 55 56 -f 45 44 54 -f 45 54 55 -f 44 43 53 -f 44 53 54 -f 43 42 52 -f 43 52 53 -f 42 41 51 -f 42 51 52 -f 60 59 69 -f 60 69 70 -f 59 58 68 -f 59 68 69 -f 58 57 67 -f 58 67 68 -f 57 56 66 -f 57 66 67 -f 56 55 65 -f 56 65 66 -f 55 54 64 -f 55 64 65 -f 54 53 63 -f 54 63 64 -f 53 52 62 -f 53 62 63 -f 52 51 61 -f 52 61 62 -f 70 69 79 -f 70 79 80 -f 69 68 78 -f 69 78 79 -f 68 67 77 -f 68 77 78 -f 67 66 76 -f 67 76 77 -f 66 65 75 -f 66 75 76 -f 65 64 74 -f 65 74 75 -f 64 63 73 -f 64 73 74 -f 63 62 72 -f 63 72 73 -f 62 61 71 -f 62 71 72 -f 80 79 90 -f 80 90 91 -f 79 78 89 -f 79 89 90 -f 78 77 88 -f 78 88 89 -f 77 76 87 -f 77 87 88 -f 76 75 86 -f 76 86 87 -f 75 74 85 -f 75 85 86 -f 74 73 84 -f 74 84 85 -f 73 72 83 -f 73 83 84 -f 72 71 82 -f 72 82 83 -f 91 90 101 -f 91 101 102 -f 90 89 100 -f 90 100 101 -f 89 88 99 -f 89 99 100 -f 88 87 98 -f 88 98 99 -f 87 86 97 -f 87 97 98 -f 86 85 96 -f 86 96 97 -f 85 84 95 -f 85 95 96 -f 84 83 94 -f 84 94 95 -f 83 82 93 -f 83 93 94 -f 102 101 111 -f 102 111 112 -f 101 100 110 -f 101 110 111 -f 100 99 109 -f 100 109 110 -f 99 98 108 -f 99 108 109 -f 98 97 107 -f 98 107 108 -f 97 96 106 -f 97 106 107 -f 96 95 105 -f 96 105 106 -f 95 94 104 -f 95 104 105 -f 94 93 103 -f 94 103 104 -f 112 111 121 -f 112 121 122 -f 111 110 120 -f 111 120 121 -f 110 109 119 -f 110 119 120 -f 109 108 118 -f 109 118 119 -f 108 107 117 -f 108 117 118 -f 107 106 116 -f 107 116 117 -f 106 105 115 -f 106 115 116 -f 105 104 114 -f 105 114 115 -f 104 103 113 -f 104 113 114 -f 122 121 131 -f 122 131 132 -f 121 120 130 -f 121 130 131 -f 120 119 129 -f 120 129 130 -f 119 118 128 -f 119 128 129 -f 118 117 127 -f 118 127 128 -f 117 116 126 -f 117 126 127 -f 116 115 125 -f 116 125 126 -f 115 114 124 -f 115 124 125 -f 114 113 123 -f 114 123 124 -f 132 131 141 -f 132 141 142 -f 131 130 140 -f 131 140 141 -f 130 129 139 -f 130 139 140 -f 129 128 138 -f 129 138 139 -f 128 127 137 -f 128 137 138 -f 127 126 136 -f 127 136 137 -f 126 125 135 -f 126 135 136 -f 125 124 134 -f 125 134 135 -f 124 123 133 -f 124 133 134 -f 142 141 151 -f 142 151 152 -f 141 140 150 -f 141 150 151 -f 140 139 149 -f 140 149 150 -f 139 138 148 -f 139 148 149 -f 138 137 147 -f 138 147 148 -f 137 136 146 -f 137 146 147 -f 136 135 145 -f 136 145 146 -f 135 134 144 -f 135 144 145 -f 134 133 143 -f 134 143 144 -f 152 151 161 -f 152 161 162 -f 151 150 160 -f 151 160 161 -f 150 149 159 -f 150 159 160 -f 149 148 158 -f 149 158 159 -f 148 147 157 -f 148 157 158 -f 147 146 156 -f 147 156 157 -f 146 145 155 -f 146 155 156 -f 145 144 154 -f 145 154 155 -f 144 143 153 -f 144 153 154 -f 162 161 171 -f 162 171 172 -f 161 160 170 -f 161 170 171 -f 160 159 169 -f 160 169 170 -f 159 158 168 -f 159 168 169 -f 158 157 167 -f 158 167 168 -f 157 156 166 -f 157 166 167 -f 156 155 165 -f 156 165 166 -f 155 154 164 -f 155 164 165 -f 154 153 163 -f 154 163 164 -f 172 171 181 -f 172 181 182 -f 171 170 180 -f 171 180 181 -f 170 169 179 -f 170 179 180 -f 169 168 178 -f 169 178 179 -f 168 167 177 -f 168 177 178 -f 167 166 176 -f 167 176 177 -f 166 165 175 -f 166 175 176 -f 165 164 174 -f 165 174 175 -f 164 163 173 -f 164 173 174 -f 182 181 191 -f 182 191 192 -f 181 180 190 -f 181 190 191 -f 180 179 189 -f 180 189 190 -f 179 178 188 -f 179 188 189 -f 178 177 187 -f 178 187 188 -f 177 176 186 -f 177 186 187 -f 176 175 185 -f 176 185 186 -f 175 174 184 -f 175 184 185 -f 174 173 183 -f 174 183 184 -f 192 191 201 -f 192 201 202 -f 191 190 200 -f 191 200 201 -f 190 189 199 -f 190 199 200 -f 189 188 198 -f 189 198 199 -f 188 187 197 -f 188 197 198 -f 187 186 196 -f 187 196 197 -f 186 185 195 -f 186 195 196 -f 185 184 194 -f 185 194 195 -f 184 183 193 -f 184 193 194 -f 202 201 211 -f 202 211 212 -f 201 200 210 -f 201 210 211 -f 200 199 209 -f 200 209 210 -f 199 198 208 -f 199 208 209 -f 198 197 207 -f 198 207 208 -f 197 196 206 -f 197 206 207 -f 196 195 205 -f 196 205 206 -f 195 194 204 -f 195 204 205 -f 194 193 203 -f 194 203 204 -f 92 10 20 -f 1 81 11 -f 92 20 30 -f 11 81 21 -f 92 30 40 -f 21 81 31 -f 92 40 50 -f 31 81 41 -f 92 50 60 -f 41 81 51 -f 92 60 70 -f 51 81 61 -f 92 70 80 -f 61 81 71 -f 92 80 91 -f 71 81 82 -f 92 91 102 -f 82 81 93 -f 92 102 112 -f 93 81 103 -f 92 112 122 -f 103 81 113 -f 92 122 132 -f 113 81 123 -f 92 132 142 -f 123 81 133 -f 92 142 152 -f 133 81 143 -f 92 152 162 -f 143 81 153 -f 92 162 172 -f 153 81 163 -f 92 172 182 -f 163 81 173 -f 92 182 192 -f 173 81 183 -f 92 192 202 -f 183 81 193 -f 92 202 212 -f 193 81 203 -f 92 212 10 -f 212 211 9 -f 212 9 10 -f 211 210 8 -f 211 8 9 -f 210 209 7 -f 210 7 8 -f 209 208 6 -f 209 6 7 -f 208 207 5 -f 208 5 6 -f 207 206 4 -f 207 4 5 -f 206 205 3 -f 206 3 4 -f 205 204 2 -f 205 2 3 -f 204 203 1 -f 204 1 2 -f 203 81 1 -f 213 214 216 -f 213 216 215 -f 215 216 218 -f 215 218 217 -f 217 218 220 -f 217 220 219 -f 219 220 222 -f 219 222 221 -f 221 222 224 -f 221 224 223 -f 223 224 226 -f 223 226 225 -f 225 226 228 -f 225 228 227 -f 227 228 230 -f 227 230 229 -f 229 230 232 -f 229 232 231 -f 231 232 234 -f 231 234 233 -f 233 234 236 -f 233 236 235 -f 235 236 238 -f 235 238 237 -f 237 238 240 -f 237 240 239 -f 239 240 242 -f 239 242 241 -f 241 242 244 -f 241 244 243 -f 243 244 246 -f 243 246 245 -f 245 246 248 -f 245 248 247 -f 247 248 250 -f 247 250 249 -f 216 214 252 -f 216 252 250 -f 216 250 248 -f 216 248 246 -f 216 246 244 -f 216 244 242 -f 216 242 240 -f 216 240 238 -f 216 238 236 -f 216 236 234 -f 216 234 232 -f 216 232 230 -f 216 230 228 -f 216 228 226 -f 216 226 224 -f 216 224 222 -f 216 222 220 -f 216 220 218 -f 251 252 214 -f 251 214 213 -f 249 250 252 -f 249 252 251 -f 213 215 217 -f 213 217 219 -f 213 219 221 -f 213 221 223 -f 213 223 225 -f 213 225 227 -f 213 227 229 -f 213 229 231 -f 213 231 233 -f 213 233 235 -f 213 235 237 -f 213 237 239 -f 213 239 241 -f 213 241 243 -f 213 243 245 -f 213 245 247 -f 213 247 249 -f 213 249 251 -f 262 261 271 -f 262 271 272 -f 261 260 270 -f 261 270 271 -f 260 259 269 -f 260 269 270 -f 259 258 268 -f 259 268 269 -f 258 257 267 -f 258 267 268 -f 257 256 266 -f 257 266 267 -f 256 255 265 -f 256 265 266 -f 255 254 264 -f 255 264 265 -f 254 253 263 -f 254 263 264 -f 272 271 281 -f 272 281 282 -f 271 270 280 -f 271 280 281 -f 270 269 279 -f 270 279 280 -f 269 268 278 -f 269 278 279 -f 268 267 277 -f 268 277 278 -f 267 266 276 -f 267 276 277 -f 266 265 275 -f 266 275 276 -f 265 264 274 -f 265 274 275 -f 264 263 273 -f 264 273 274 -f 282 281 291 -f 282 291 292 -f 281 280 290 -f 281 290 291 -f 280 279 289 -f 280 289 290 -f 279 278 288 -f 279 288 289 -f 278 277 287 -f 278 287 288 -f 277 276 286 -f 277 286 287 -f 276 275 285 -f 276 285 286 -f 275 274 284 -f 275 284 285 -f 274 273 283 -f 274 283 284 -f 292 291 301 -f 292 301 302 -f 291 290 300 -f 291 300 301 -f 290 289 299 -f 290 299 300 -f 289 288 298 -f 289 298 299 -f 288 287 297 -f 288 297 298 -f 287 286 296 -f 287 296 297 -f 286 285 295 -f 286 295 296 -f 285 284 294 -f 285 294 295 -f 284 283 293 -f 284 293 294 -f 302 301 311 -f 302 311 312 -f 301 300 310 -f 301 310 311 -f 300 299 309 -f 300 309 310 -f 299 298 308 -f 299 308 309 -f 298 297 307 -f 298 307 308 -f 297 296 306 -f 297 306 307 -f 296 295 305 -f 296 305 306 -f 295 294 304 -f 295 304 305 -f 294 293 303 -f 294 303 304 -f 312 311 321 -f 312 321 322 -f 311 310 320 -f 311 320 321 -f 310 309 319 -f 310 319 320 -f 309 308 318 -f 309 318 319 -f 308 307 317 -f 308 317 318 -f 307 306 316 -f 307 316 317 -f 306 305 315 -f 306 315 316 -f 305 304 314 -f 305 314 315 -f 304 303 313 -f 304 313 314 -f 322 321 331 -f 322 331 332 -f 321 320 330 -f 321 330 331 -f 320 319 329 -f 320 329 330 -f 319 318 328 -f 319 328 329 -f 318 317 327 -f 318 327 328 -f 317 316 326 -f 317 326 327 -f 316 315 325 -f 316 325 326 -f 315 314 324 -f 315 324 325 -f 314 313 323 -f 314 323 324 -f 332 331 342 -f 332 342 343 -f 331 330 341 -f 331 341 342 -f 330 329 340 -f 330 340 341 -f 329 328 339 -f 329 339 340 -f 328 327 338 -f 328 338 339 -f 327 326 337 -f 327 337 338 -f 326 325 336 -f 326 336 337 -f 325 324 335 -f 325 335 336 -f 324 323 334 -f 324 334 335 -f 343 342 353 -f 343 353 354 -f 342 341 352 -f 342 352 353 -f 341 340 351 -f 341 351 352 -f 340 339 350 -f 340 350 351 -f 339 338 349 -f 339 349 350 -f 338 337 348 -f 338 348 349 -f 337 336 347 -f 337 347 348 -f 336 335 346 -f 336 346 347 -f 335 334 345 -f 335 345 346 -f 354 353 363 -f 354 363 364 -f 353 352 362 -f 353 362 363 -f 352 351 361 -f 352 361 362 -f 351 350 360 -f 351 360 361 -f 350 349 359 -f 350 359 360 -f 349 348 358 -f 349 358 359 -f 348 347 357 -f 348 357 358 -f 347 346 356 -f 347 356 357 -f 346 345 355 -f 346 355 356 -f 364 363 373 -f 364 373 374 -f 363 362 372 -f 363 372 373 -f 362 361 371 -f 362 371 372 -f 361 360 370 -f 361 370 371 -f 360 359 369 -f 360 369 370 -f 359 358 368 -f 359 368 369 -f 358 357 367 -f 358 367 368 -f 357 356 366 -f 357 366 367 -f 356 355 365 -f 356 365 366 -f 374 373 383 -f 374 383 384 -f 373 372 382 -f 373 382 383 -f 372 371 381 -f 372 381 382 -f 371 370 380 -f 371 380 381 -f 370 369 379 -f 370 379 380 -f 369 368 378 -f 369 378 379 -f 368 367 377 -f 368 377 378 -f 367 366 376 -f 367 376 377 -f 366 365 375 -f 366 375 376 -f 384 383 393 -f 384 393 394 -f 383 382 392 -f 383 392 393 -f 382 381 391 -f 382 391 392 -f 381 380 390 -f 381 390 391 -f 380 379 389 -f 380 389 390 -f 379 378 388 -f 379 388 389 -f 378 377 387 -f 378 387 388 -f 377 376 386 -f 377 386 387 -f 376 375 385 -f 376 385 386 -f 394 393 403 -f 394 403 404 -f 393 392 402 -f 393 402 403 -f 392 391 401 -f 392 401 402 -f 391 390 400 -f 391 400 401 -f 390 389 399 -f 390 399 400 -f 389 388 398 -f 389 398 399 -f 388 387 397 -f 388 397 398 -f 387 386 396 -f 387 396 397 -f 386 385 395 -f 386 395 396 -f 404 403 413 -f 404 413 414 -f 403 402 412 -f 403 412 413 -f 402 401 411 -f 402 411 412 -f 401 400 410 -f 401 410 411 -f 400 399 409 -f 400 409 410 -f 399 398 408 -f 399 408 409 -f 398 397 407 -f 398 407 408 -f 397 396 406 -f 397 406 407 -f 396 395 405 -f 396 405 406 -f 414 413 423 -f 414 423 424 -f 413 412 422 -f 413 422 423 -f 412 411 421 -f 412 421 422 -f 411 410 420 -f 411 420 421 -f 410 409 419 -f 410 419 420 -f 409 408 418 -f 409 418 419 -f 408 407 417 -f 408 417 418 -f 407 406 416 -f 407 416 417 -f 406 405 415 -f 406 415 416 -f 424 423 433 -f 424 433 434 -f 423 422 432 -f 423 432 433 -f 422 421 431 -f 422 431 432 -f 421 420 430 -f 421 430 431 -f 420 419 429 -f 420 429 430 -f 419 418 428 -f 419 428 429 -f 418 417 427 -f 418 427 428 -f 417 416 426 -f 417 426 427 -f 416 415 425 -f 416 425 426 -f 434 433 443 -f 434 443 444 -f 433 432 442 -f 433 442 443 -f 432 431 441 -f 432 441 442 -f 431 430 440 -f 431 440 441 -f 430 429 439 -f 430 439 440 -f 429 428 438 -f 429 438 439 -f 428 427 437 -f 428 437 438 -f 427 426 436 -f 427 436 437 -f 426 425 435 -f 426 435 436 -f 444 443 453 -f 444 453 454 -f 443 442 452 -f 443 452 453 -f 442 441 451 -f 442 451 452 -f 441 440 450 -f 441 450 451 -f 440 439 449 -f 440 449 450 -f 439 438 448 -f 439 448 449 -f 438 437 447 -f 438 447 448 -f 437 436 446 -f 437 446 447 -f 436 435 445 -f 436 445 446 -f 454 453 463 -f 454 463 464 -f 453 452 462 -f 453 462 463 -f 452 451 461 -f 452 461 462 -f 451 450 460 -f 451 460 461 -f 450 449 459 -f 450 459 460 -f 449 448 458 -f 449 458 459 -f 448 447 457 -f 448 457 458 -f 447 446 456 -f 447 456 457 -f 446 445 455 -f 446 455 456 -f 344 262 272 -f 253 333 263 -f 344 272 282 -f 263 333 273 -f 344 282 292 -f 273 333 283 -f 344 292 302 -f 283 333 293 -f 344 302 312 -f 293 333 303 -f 344 312 322 -f 303 333 313 -f 344 322 332 -f 313 333 323 -f 344 332 343 -f 323 333 334 -f 344 343 354 -f 334 333 345 -f 344 354 364 -f 345 333 355 -f 344 364 374 -f 355 333 365 -f 344 374 384 -f 365 333 375 -f 344 384 394 -f 375 333 385 -f 344 394 404 -f 385 333 395 -f 344 404 414 -f 395 333 405 -f 344 414 424 -f 405 333 415 -f 344 424 434 -f 415 333 425 -f 344 434 444 -f 425 333 435 -f 344 444 454 -f 435 333 445 -f 344 454 464 -f 445 333 455 -f 344 464 262 -f 464 463 261 -f 464 261 262 -f 463 462 260 -f 463 260 261 -f 462 461 259 -f 462 259 260 -f 461 460 258 -f 461 258 259 -f 460 459 257 -f 460 257 258 -f 459 458 256 -f 459 256 257 -f 458 457 255 -f 458 255 256 -f 457 456 254 -f 457 254 255 -f 456 455 253 -f 456 253 254 -f 455 333 253 -# 916 faces, 0 coords texture - -# End of File diff --git a/examples/common/meshes/sphere.obj b/examples/common/meshes/sphere.obj deleted file mode 100644 index def1c1b5..00000000 --- a/examples/common/meshes/sphere.obj +++ /dev/null @@ -1,997 +0,0 @@ -# Blender v2.66 (sub 0) OBJ File: '' -# www.blender.org -v -0.195090 0.980785 0.000000 -v -0.382683 0.923880 0.000000 -v -0.555570 0.831470 0.000000 -v -0.707107 0.707107 0.000000 -v -0.831470 0.555570 0.000000 -v -0.923880 0.382683 0.000000 -v -0.980785 0.195090 0.000000 -v -1.000000 0.000000 0.000000 -v -0.980785 -0.195090 0.000000 -v -0.923880 -0.382683 0.000000 -v -0.831470 -0.555570 0.000000 -v -0.707107 -0.707107 0.000000 -v -0.555570 -0.831470 0.000000 -v -0.382683 -0.923880 0.000000 -v -0.195090 -0.980785 0.000000 -v -0.191342 0.980785 -0.038060 -v -0.375330 0.923880 -0.074658 -v -0.544895 0.831470 -0.108386 -v -0.693520 0.707107 -0.137950 -v -0.815493 0.555570 -0.162212 -v -0.906127 0.382683 -0.180240 -v -0.961940 0.195090 -0.191342 -v -0.980785 0.000000 -0.195090 -v -0.961940 -0.195090 -0.191342 -v -0.906127 -0.382683 -0.180240 -v -0.815493 -0.555570 -0.162212 -v -0.693520 -0.707107 -0.137950 -v -0.544895 -0.831470 -0.108386 -v -0.375330 -0.923880 -0.074658 -v -0.191341 -0.980785 -0.038060 -v -0.180240 0.980785 -0.074658 -v -0.353553 0.923880 -0.146447 -v -0.513280 0.831470 -0.212608 -v -0.653281 0.707107 -0.270598 -v -0.768178 0.555570 -0.318190 -v -0.853553 0.382683 -0.353553 -v -0.906127 0.195090 -0.375330 -v -0.923880 0.000000 -0.382684 -v -0.906127 -0.195090 -0.375330 -v -0.853553 -0.382683 -0.353554 -v -0.768178 -0.555570 -0.318190 -v -0.653281 -0.707107 -0.270598 -v -0.513280 -0.831470 -0.212608 -v -0.353553 -0.923880 -0.146447 -v -0.180240 -0.980785 -0.074658 -v -0.162212 0.980785 -0.108387 -v -0.318190 0.923880 -0.212608 -v -0.461940 0.831470 -0.308658 -v -0.587938 0.707107 -0.392848 -v -0.691342 0.555570 -0.461940 -v -0.768178 0.382683 -0.513280 -v -0.815493 0.195090 -0.544895 -v -0.831470 0.000000 -0.555570 -v -0.815493 -0.195090 -0.544895 -v -0.768178 -0.382683 -0.513280 -v -0.691342 -0.555570 -0.461940 -v -0.587938 -0.707107 -0.392848 -v -0.461940 -0.831470 -0.308658 -v -0.318189 -0.923880 -0.212608 -v -0.162211 -0.980785 -0.108386 -v -0.137950 0.980785 -0.137950 -v -0.270598 0.923880 -0.270598 -v -0.392847 0.831470 -0.392848 -v -0.500000 0.707107 -0.500000 -v -0.587938 0.555570 -0.587938 -v -0.653281 0.382683 -0.653282 -v -0.693520 0.195090 -0.693520 -v -0.707107 0.000000 -0.707107 -v -0.693520 -0.195090 -0.693520 -v -0.653281 -0.382683 -0.653282 -v -0.587938 -0.555570 -0.587938 -v -0.500000 -0.707107 -0.500000 -v -0.392847 -0.831470 -0.392848 -v -0.270598 -0.923880 -0.270598 -v -0.137949 -0.980785 -0.137950 -v -0.108386 0.980785 -0.162212 -v -0.212607 0.923880 -0.318190 -v -0.308658 0.831470 -0.461940 -v -0.392847 0.707107 -0.587938 -v -0.461939 0.555570 -0.691342 -v -0.513280 0.382683 -0.768178 -v -0.544895 0.195090 -0.815493 -v -0.555570 0.000000 -0.831470 -v -0.544895 -0.195090 -0.815493 -v -0.513280 -0.382683 -0.768178 -v -0.461939 -0.555570 -0.691342 -v -0.392847 -0.707107 -0.587938 -v -0.308658 -0.831470 -0.461940 -v -0.212607 -0.923880 -0.318190 -v -0.108386 -0.980785 -0.162212 -v -0.074658 0.980785 -0.180240 -v -0.146446 0.923880 -0.353554 -v -0.212607 0.831470 -0.513280 -v -0.270598 0.707107 -0.653282 -v -0.318189 0.555570 -0.768178 -v -0.353553 0.382683 -0.853554 -v -0.375330 0.195090 -0.906128 -v -0.382683 0.000000 -0.923880 -v -0.375330 -0.195090 -0.906128 -v -0.353553 -0.382683 -0.853554 -v -0.318189 -0.555570 -0.768178 -v -0.270598 -0.707107 -0.653282 -v -0.212607 -0.831470 -0.513280 -v -0.146446 -0.923880 -0.353554 -v -0.074658 -0.980785 -0.180240 -v -0.038060 0.980785 -0.191342 -v -0.074658 0.923880 -0.375331 -v -0.108386 0.831470 -0.544895 -v -0.137949 0.707107 -0.693520 -v -0.162211 0.555570 -0.815493 -v -0.180240 0.382683 -0.906128 -v -0.191341 0.195090 -0.961940 -v -0.195090 0.000000 -0.980785 -v -0.191341 -0.195090 -0.961940 -v -0.180240 -0.382683 -0.906128 -v -0.162211 -0.555570 -0.815493 -v -0.137949 -0.707107 -0.693520 -v -0.108386 -0.831470 -0.544895 -v -0.074658 -0.923880 -0.375330 -v -0.038060 -0.980785 -0.191342 -v 0.000000 0.980785 -0.195091 -v 0.000000 0.923880 -0.382684 -v 0.000000 0.831470 -0.555570 -v 0.000000 0.707107 -0.707107 -v 0.000000 0.555570 -0.831470 -v 0.000000 0.382683 -0.923880 -v 0.000000 0.195090 -0.980785 -v 0.000000 0.000000 -1.000000 -v 0.000000 -0.195090 -0.980785 -v 0.000000 -0.382683 -0.923880 -v 0.000000 -0.555570 -0.831470 -v 0.000000 -0.707107 -0.707107 -v 0.000000 -0.831470 -0.555570 -v 0.000000 -0.923880 -0.382684 -v 0.000000 -0.980785 -0.195090 -v 0.038061 0.980785 -0.191342 -v 0.074658 0.923880 -0.375330 -v 0.108387 0.831470 -0.544895 -v 0.137950 0.707107 -0.693520 -v 0.162212 0.555570 -0.815493 -v 0.180240 0.382683 -0.906128 -v 0.191342 0.195090 -0.961940 -v 0.195091 0.000000 -0.980785 -v 0.191342 -0.195090 -0.961940 -v 0.180240 -0.382683 -0.906128 -v 0.162212 -0.555570 -0.815493 -v 0.137950 -0.707107 -0.693520 -v 0.108387 -0.831470 -0.544895 -v 0.074658 -0.923880 -0.375330 -v 0.038061 -0.980785 -0.191342 -v 0.074658 0.980785 -0.180240 -v 0.146447 0.923880 -0.353554 -v 0.212608 0.831470 -0.513280 -v 0.270599 0.707107 -0.653282 -v 0.318190 0.555570 -0.768178 -v 0.353554 0.382683 -0.853553 -v 0.375331 0.195090 -0.906127 -v 0.382684 0.000000 -0.923880 -v 0.375331 -0.195090 -0.906127 -v 0.353554 -0.382683 -0.853554 -v 0.318190 -0.555570 -0.768178 -v 0.270599 -0.707107 -0.653282 -v 0.212608 -0.831470 -0.513280 -v 0.146447 -0.923880 -0.353553 -v 0.074658 -0.980785 -0.180240 -v 0.108387 0.980785 -0.162212 -v 0.212608 0.923880 -0.318190 -v 0.308659 0.831470 -0.461940 -v 0.392848 0.707107 -0.587938 -v 0.461940 0.555570 -0.691342 -v 0.513280 0.382683 -0.768178 -v 0.544895 0.195090 -0.815493 -v 0.555571 0.000000 -0.831470 -v 0.544895 -0.195090 -0.815493 -v 0.513280 -0.382683 -0.768178 -v 0.461940 -0.555570 -0.691342 -v 0.392848 -0.707107 -0.587938 -v 0.308659 -0.831470 -0.461940 -v 0.212608 -0.923880 -0.318190 -v 0.108387 -0.980785 -0.162212 -v 0.137950 0.980785 -0.137950 -v 0.270599 0.923880 -0.270598 -v 0.392848 0.831470 -0.392848 -v 0.500000 0.707107 -0.500000 -v 0.587938 0.555570 -0.587938 -v 0.653282 0.382683 -0.653281 -v 0.693520 0.195090 -0.693520 -v 0.707107 0.000000 -0.707107 -v 0.693520 -0.195090 -0.693520 -v 0.653282 -0.382683 -0.653282 -v 0.587938 -0.555570 -0.587938 -v 0.500000 -0.707107 -0.500000 -v 0.392848 -0.831470 -0.392847 -v 0.270598 -0.923880 -0.270598 -v 0.137950 -0.980785 -0.137950 -v 0.162212 0.980785 -0.108386 -v 0.318190 0.923880 -0.212608 -v 0.461940 0.831470 -0.308658 -v 0.587938 0.707107 -0.392847 -v 0.691342 0.555570 -0.461940 -v 0.768178 0.382683 -0.513280 -v 0.815493 0.195090 -0.544895 -v 0.831470 0.000000 -0.555570 -v 0.815493 -0.195090 -0.544895 -v 0.768178 -0.382683 -0.513280 -v 0.691342 -0.555570 -0.461940 -v 0.587938 -0.707107 -0.392847 -v 0.461940 -0.831470 -0.308658 -v 0.318190 -0.923880 -0.212608 -v 0.162212 -0.980785 -0.108386 -v 0.180240 0.980785 -0.074658 -v 0.353554 0.923880 -0.146447 -v 0.513280 0.831470 -0.212608 -v 0.653282 0.707107 -0.270598 -v 0.768178 0.555570 -0.318190 -v 0.853554 0.382683 -0.353553 -v 0.906128 0.195090 -0.375330 -v 0.923880 0.000000 -0.382683 -v 0.906128 -0.195090 -0.375330 -v 0.853554 -0.382683 -0.353553 -v 0.768178 -0.555570 -0.318190 -v 0.653282 -0.707107 -0.270598 -v 0.513280 -0.831470 -0.212607 -v 0.353554 -0.923880 -0.146447 -v 0.180240 -0.980785 -0.074658 -v 0.191342 0.980785 -0.038060 -v 0.375331 0.923880 -0.074658 -v 0.544896 0.831470 -0.108386 -v 0.693520 0.707107 -0.137950 -v 0.815493 0.555570 -0.162212 -v 0.906128 0.382683 -0.180240 -v 0.961940 0.195090 -0.191342 -v 0.980785 0.000000 -0.195090 -v 0.961940 -0.195090 -0.191342 -v 0.906128 -0.382683 -0.180240 -v 0.815493 -0.555570 -0.162212 -v 0.693520 -0.707107 -0.137950 -v 0.544895 -0.831470 -0.108386 -v 0.375331 -0.923880 -0.074658 -v 0.191342 -0.980785 -0.038060 -v 0.195091 0.980785 0.000000 -v 0.382684 0.923880 0.000000 -v 0.555571 0.831470 0.000000 -v 0.707107 0.707107 0.000000 -v 0.831470 0.555570 0.000000 -v 0.923880 0.382683 0.000000 -v 0.980785 0.195090 0.000000 -v 1.000000 0.000000 0.000000 -v 0.980785 -0.195090 0.000000 -v 0.923880 -0.382683 0.000000 -v 0.831470 -0.555570 0.000000 -v 0.707107 -0.707107 0.000000 -v 0.555571 -0.831470 0.000000 -v 0.382684 -0.923880 0.000000 -v 0.195091 -0.980785 0.000000 -v 0.191342 0.980785 0.038060 -v 0.375331 0.923880 0.074658 -v 0.544896 0.831470 0.108386 -v 0.693520 0.707107 0.137950 -v 0.815493 0.555570 0.162212 -v 0.906128 0.382683 0.180240 -v 0.961940 0.195090 0.191342 -v 0.980785 0.000000 0.195090 -v 0.961940 -0.195090 0.191342 -v 0.906128 -0.382683 0.180240 -v 0.815493 -0.555570 0.162212 -v 0.693520 -0.707107 0.137950 -v 0.544895 -0.831470 0.108386 -v 0.375331 -0.923880 0.074658 -v 0.191342 -0.980785 0.038060 -v 0.180240 0.980785 0.074658 -v 0.353554 0.923880 0.146447 -v 0.513280 0.831470 0.212608 -v 0.653282 0.707107 0.270598 -v 0.768178 0.555570 0.318190 -v 0.853554 0.382683 0.353554 -v 0.906128 0.195090 0.375330 -v 0.923880 0.000000 0.382683 -v 0.906128 -0.195090 0.375330 -v 0.853554 -0.382683 0.353553 -v 0.768178 -0.555570 0.318190 -v 0.653282 -0.707107 0.270598 -v 0.513280 -0.831470 0.212608 -v 0.353554 -0.923880 0.146447 -v 0.180240 -0.980785 0.074658 -v 0.162212 0.980785 0.108387 -v 0.318190 0.923880 0.212608 -v 0.461940 0.831470 0.308658 -v 0.587938 0.707107 0.392848 -v 0.691342 0.555570 0.461940 -v 0.768178 0.382683 0.513280 -v 0.815493 0.195090 0.544895 -v 0.831470 0.000000 0.555570 -v 0.815493 -0.195090 0.544895 -v 0.768178 -0.382683 0.513280 -v 0.691342 -0.555570 0.461940 -v 0.587938 -0.707107 0.392848 -v 0.461940 -0.831470 0.308658 -v 0.318190 -0.923880 0.212608 -v 0.162212 -0.980785 0.108386 -v 0.137950 0.980785 0.137950 -v 0.270598 0.923880 0.270598 -v 0.392848 0.831470 0.392848 -v 0.500000 0.707107 0.500000 -v 0.587938 0.555570 0.587938 -v 0.653282 0.382683 0.653282 -v 0.693520 0.195090 0.693520 -v 0.707107 0.000000 0.707107 -v 0.693520 -0.195090 0.693520 -v 0.653282 -0.382683 0.653282 -v 0.587938 -0.555570 0.587938 -v 0.500000 -0.707107 0.500000 -v 0.392848 -0.831470 0.392848 -v 0.270598 -0.923880 0.270598 -v 0.137950 -0.980785 0.137950 -v 0.108387 0.980785 0.162212 -v 0.212608 0.923880 0.318190 -v 0.308659 0.831470 0.461940 -v 0.392848 0.707107 0.587938 -v 0.461940 0.555570 0.691342 -v 0.513280 0.382683 0.768178 -v 0.544895 0.195090 0.815493 -v 0.555570 0.000000 0.831469 -v 0.544895 -0.195090 0.815493 -v 0.513280 -0.382683 0.768178 -v 0.461940 -0.555570 0.691342 -v 0.392848 -0.707107 0.587938 -v 0.308659 -0.831470 0.461940 -v 0.212608 -0.923880 0.318190 -v 0.108387 -0.980785 0.162212 -v 0.000000 -1.000000 0.000000 -v 0.074658 0.980785 0.180240 -v 0.146447 0.923880 0.353554 -v 0.212608 0.831470 0.513280 -v 0.270598 0.707107 0.653281 -v 0.318190 0.555570 0.768178 -v 0.353554 0.382683 0.853553 -v 0.375330 0.195090 0.906127 -v 0.382683 0.000000 0.923879 -v 0.375330 -0.195090 0.906127 -v 0.353554 -0.382683 0.853553 -v 0.318190 -0.555570 0.768178 -v 0.270598 -0.707107 0.653281 -v 0.212608 -0.831470 0.513280 -v 0.146447 -0.923880 0.353553 -v 0.074658 -0.980785 0.180240 -v 0.038061 0.980785 0.191342 -v 0.074658 0.923880 0.375330 -v 0.108387 0.831470 0.544895 -v 0.137950 0.707107 0.693520 -v 0.162212 0.555570 0.815493 -v 0.180240 0.382683 0.906127 -v 0.191342 0.195090 0.961940 -v 0.195090 0.000000 0.980785 -v 0.191342 -0.195090 0.961940 -v 0.180240 -0.382683 0.906128 -v 0.162212 -0.555570 0.815493 -v 0.137950 -0.707107 0.693520 -v 0.108387 -0.831470 0.544895 -v 0.074658 -0.923880 0.375330 -v 0.038061 -0.980785 0.191342 -v 0.000000 0.980785 0.195090 -v 0.000000 0.923880 0.382684 -v 0.000000 0.831470 0.555570 -v 0.000000 0.707107 0.707107 -v 0.000000 0.555570 0.831469 -v 0.000000 0.382683 0.923879 -v 0.000000 0.195090 0.980785 -v 0.000000 0.000000 1.000000 -v 0.000000 -0.195090 0.980785 -v 0.000000 -0.382683 0.923880 -v 0.000000 -0.555570 0.831469 -v 0.000000 -0.707107 0.707107 -v 0.000000 -0.831470 0.555570 -v 0.000000 -0.923880 0.382683 -v 0.000000 -0.980785 0.195090 -v -0.038060 0.980785 0.191342 -v -0.074658 0.923880 0.375330 -v -0.108386 0.831470 0.544895 -v -0.137949 0.707107 0.693520 -v -0.162211 0.555570 0.815493 -v -0.180240 0.382683 0.906127 -v -0.191342 0.195090 0.961939 -v -0.195090 0.000000 0.980785 -v -0.191342 -0.195090 0.961939 -v -0.180240 -0.382683 0.906127 -v -0.162211 -0.555570 0.815493 -v -0.137949 -0.707107 0.693520 -v -0.108386 -0.831470 0.544895 -v -0.074658 -0.923880 0.375330 -v -0.038060 -0.980785 0.191342 -v -0.074658 0.980785 0.180240 -v -0.146446 0.923880 0.353553 -v -0.212607 0.831470 0.513280 -v -0.270598 0.707107 0.653281 -v -0.318189 0.555570 0.768177 -v -0.353553 0.382683 0.853553 -v -0.375330 0.195090 0.906127 -v -0.382683 0.000000 0.923879 -v -0.375330 -0.195090 0.906127 -v -0.353553 -0.382683 0.853553 -v -0.318189 -0.555570 0.768177 -v -0.270598 -0.707107 0.653281 -v -0.212607 -0.831470 0.513280 -v -0.146446 -0.923880 0.353553 -v -0.074657 -0.980785 0.180240 -v -0.108386 0.980785 0.162212 -v -0.212607 0.923880 0.318190 -v -0.308658 0.831470 0.461940 -v -0.392847 0.707107 0.587938 -v -0.461939 0.555570 0.691341 -v -0.513280 0.382683 0.768178 -v -0.544895 0.195090 0.815493 -v -0.555570 0.000000 0.831469 -v -0.544895 -0.195090 0.815493 -v -0.513280 -0.382683 0.768178 -v -0.461939 -0.555570 0.691341 -v -0.392847 -0.707107 0.587938 -v -0.308658 -0.831470 0.461940 -v -0.212607 -0.923880 0.318190 -v -0.108386 -0.980785 0.162212 -v -0.137949 0.980785 0.137950 -v -0.270598 0.923880 0.270598 -v -0.392847 0.831470 0.392847 -v -0.500000 0.707107 0.500000 -v -0.587937 0.555570 0.587937 -v -0.653281 0.382683 0.653281 -v -0.693519 0.195090 0.693519 -v -0.707106 0.000000 0.707106 -v -0.693519 -0.195090 0.693519 -v -0.653281 -0.382683 0.653281 -v -0.587937 -0.555570 0.587937 -v -0.500000 -0.707107 0.500000 -v -0.392847 -0.831470 0.392847 -v -0.270598 -0.923880 0.270598 -v -0.137949 -0.980785 0.137950 -v 0.000000 1.000000 0.000000 -v -0.162211 0.980785 0.108386 -v -0.318189 0.923880 0.212608 -v -0.461939 0.831470 0.308658 -v -0.587937 0.707107 0.392847 -v -0.691341 0.555570 0.461939 -v -0.768177 0.382683 0.513280 -v -0.815493 0.195090 0.544895 -v -0.831469 0.000000 0.555570 -v -0.815493 -0.195090 0.544895 -v -0.768178 -0.382683 0.513280 -v -0.691341 -0.555570 0.461939 -v -0.587937 -0.707107 0.392847 -v -0.461939 -0.831470 0.308658 -v -0.318189 -0.923880 0.212608 -v -0.162211 -0.980785 0.108386 -v -0.180240 0.980785 0.074658 -v -0.353553 0.923880 0.146447 -v -0.513280 0.831470 0.212607 -v -0.653281 0.707107 0.270598 -v -0.768177 0.555570 0.318189 -v -0.853553 0.382683 0.353553 -v -0.906127 0.195090 0.375330 -v -0.923879 0.000000 0.382683 -v -0.906127 -0.195090 0.375330 -v -0.853553 -0.382683 0.353553 -v -0.768177 -0.555570 0.318189 -v -0.653281 -0.707107 0.270598 -v -0.513280 -0.831470 0.212607 -v -0.353553 -0.923880 0.146447 -v -0.180240 -0.980785 0.074658 -v -0.191341 0.980785 0.038060 -v -0.375330 0.923880 0.074658 -v -0.544895 0.831470 0.108386 -v -0.693520 0.707107 0.137950 -v -0.815492 0.555570 0.162211 -v -0.906127 0.382683 0.180240 -v -0.961939 0.195090 0.191341 -v -0.980784 0.000000 0.195090 -v -0.961939 -0.195090 0.191341 -v -0.906127 -0.382683 0.180240 -v -0.815492 -0.555570 0.162211 -v -0.693520 -0.707107 0.137950 -v -0.544895 -0.831470 0.108386 -v -0.375330 -0.923880 0.074658 -v -0.191341 -0.980785 0.038060 -s off -f 13 12 27 28 -f 7 6 21 22 -f 14 13 28 29 -f 8 7 22 23 -f 2 1 16 17 -f 15 14 29 30 -f 9 8 23 24 -f 3 2 17 18 -f 10 9 24 25 -f 4 3 18 19 -f 11 10 25 26 -f 5 4 19 20 -f 12 11 26 27 -f 6 5 20 21 -f 30 29 44 45 -f 24 23 38 39 -f 18 17 32 33 -f 25 24 39 40 -f 19 18 33 34 -f 26 25 40 41 -f 20 19 34 35 -f 27 26 41 42 -f 21 20 35 36 -f 28 27 42 43 -f 22 21 36 37 -f 29 28 43 44 -f 23 22 37 38 -f 17 16 31 32 -f 43 42 57 58 -f 37 36 51 52 -f 44 43 58 59 -f 38 37 52 53 -f 32 31 46 47 -f 45 44 59 60 -f 39 38 53 54 -f 33 32 47 48 -f 40 39 54 55 -f 34 33 48 49 -f 41 40 55 56 -f 35 34 49 50 -f 42 41 56 57 -f 36 35 50 51 -f 56 55 70 71 -f 50 49 64 65 -f 57 56 71 72 -f 51 50 65 66 -f 58 57 72 73 -f 52 51 66 67 -f 59 58 73 74 -f 53 52 67 68 -f 47 46 61 62 -f 60 59 74 75 -f 54 53 68 69 -f 48 47 62 63 -f 55 54 69 70 -f 49 48 63 64 -f 75 74 89 90 -f 69 68 83 84 -f 63 62 77 78 -f 70 69 84 85 -f 64 63 78 79 -f 71 70 85 86 -f 65 64 79 80 -f 72 71 86 87 -f 66 65 80 81 -f 73 72 87 88 -f 67 66 81 82 -f 74 73 88 89 -f 68 67 82 83 -f 62 61 76 77 -f 88 87 102 103 -f 82 81 96 97 -f 89 88 103 104 -f 83 82 97 98 -f 77 76 91 92 -f 90 89 104 105 -f 84 83 98 99 -f 78 77 92 93 -f 85 84 99 100 -f 79 78 93 94 -f 86 85 100 101 -f 80 79 94 95 -f 87 86 101 102 -f 81 80 95 96 -f 94 93 108 109 -f 101 100 115 116 -f 95 94 109 110 -f 102 101 116 117 -f 96 95 110 111 -f 103 102 117 118 -f 97 96 111 112 -f 104 103 118 119 -f 98 97 112 113 -f 92 91 106 107 -f 105 104 119 120 -f 99 98 113 114 -f 93 92 107 108 -f 100 99 114 115 -f 113 112 127 128 -f 107 106 121 122 -f 120 119 134 135 -f 114 113 128 129 -f 108 107 122 123 -f 115 114 129 130 -f 109 108 123 124 -f 116 115 130 131 -f 110 109 124 125 -f 117 116 131 132 -f 111 110 125 126 -f 118 117 132 133 -f 112 111 126 127 -f 119 118 133 134 -f 132 131 146 147 -f 126 125 140 141 -f 133 132 147 148 -f 127 126 141 142 -f 134 133 148 149 -f 128 127 142 143 -f 122 121 136 137 -f 135 134 149 150 -f 129 128 143 144 -f 123 122 137 138 -f 130 129 144 145 -f 124 123 138 139 -f 131 130 145 146 -f 125 124 139 140 -f 145 144 159 160 -f 139 138 153 154 -f 146 145 160 161 -f 140 139 154 155 -f 147 146 161 162 -f 141 140 155 156 -f 148 147 162 163 -f 142 141 156 157 -f 149 148 163 164 -f 143 142 157 158 -f 137 136 151 152 -f 150 149 164 165 -f 144 143 158 159 -f 138 137 152 153 -f 164 163 178 179 -f 158 157 172 173 -f 152 151 166 167 -f 165 164 179 180 -f 159 158 173 174 -f 153 152 167 168 -f 160 159 174 175 -f 154 153 168 169 -f 161 160 175 176 -f 155 154 169 170 -f 162 161 176 177 -f 156 155 170 171 -f 163 162 177 178 -f 157 156 171 172 -f 177 176 191 192 -f 171 170 185 186 -f 178 177 192 193 -f 172 171 186 187 -f 179 178 193 194 -f 173 172 187 188 -f 167 166 181 182 -f 180 179 194 195 -f 174 173 188 189 -f 168 167 182 183 -f 175 174 189 190 -f 169 168 183 184 -f 176 175 190 191 -f 170 169 184 185 -f 190 189 204 205 -f 184 183 198 199 -f 191 190 205 206 -f 185 184 199 200 -f 192 191 206 207 -f 186 185 200 201 -f 193 192 207 208 -f 187 186 201 202 -f 194 193 208 209 -f 188 187 202 203 -f 182 181 196 197 -f 195 194 209 210 -f 189 188 203 204 -f 183 182 197 198 -f 209 208 223 224 -f 203 202 217 218 -f 197 196 211 212 -f 210 209 224 225 -f 204 203 218 219 -f 198 197 212 213 -f 205 204 219 220 -f 199 198 213 214 -f 206 205 220 221 -f 200 199 214 215 -f 207 206 221 222 -f 201 200 215 216 -f 208 207 222 223 -f 202 201 216 217 -f 222 221 236 237 -f 216 215 230 231 -f 223 222 237 238 -f 217 216 231 232 -f 224 223 238 239 -f 218 217 232 233 -f 212 211 226 227 -f 225 224 239 240 -f 219 218 233 234 -f 213 212 227 228 -f 220 219 234 235 -f 214 213 228 229 -f 221 220 235 236 -f 215 214 229 230 -f 228 227 242 243 -f 235 234 249 250 -f 229 228 243 244 -f 236 235 250 251 -f 230 229 244 245 -f 237 236 251 252 -f 231 230 245 246 -f 238 237 252 253 -f 232 231 246 247 -f 239 238 253 254 -f 233 232 247 248 -f 227 226 241 242 -f 240 239 254 255 -f 234 233 248 249 -f 247 246 261 262 -f 254 253 268 269 -f 248 247 262 263 -f 242 241 256 257 -f 255 254 269 270 -f 249 248 263 264 -f 243 242 257 258 -f 250 249 264 265 -f 244 243 258 259 -f 251 250 265 266 -f 245 244 259 260 -f 252 251 266 267 -f 246 245 260 261 -f 253 252 267 268 -f 266 265 280 281 -f 260 259 274 275 -f 267 266 281 282 -f 261 260 275 276 -f 268 267 282 283 -f 262 261 276 277 -f 269 268 283 284 -f 263 262 277 278 -f 257 256 271 272 -f 270 269 284 285 -f 264 263 278 279 -f 258 257 272 273 -f 265 264 279 280 -f 259 258 273 274 -f 285 284 299 300 -f 279 278 293 294 -f 273 272 287 288 -f 280 279 294 295 -f 274 273 288 289 -f 281 280 295 296 -f 275 274 289 290 -f 282 281 296 297 -f 276 275 290 291 -f 283 282 297 298 -f 277 276 291 292 -f 284 283 298 299 -f 278 277 292 293 -f 272 271 286 287 -f 298 297 312 313 -f 292 291 306 307 -f 299 298 313 314 -f 293 292 307 308 -f 287 286 301 302 -f 300 299 314 315 -f 294 293 308 309 -f 288 287 302 303 -f 295 294 309 310 -f 289 288 303 304 -f 296 295 310 311 -f 290 289 304 305 -f 297 296 311 312 -f 291 290 305 306 -f 311 310 325 326 -f 305 304 319 320 -f 312 311 326 327 -f 306 305 320 321 -f 313 312 327 328 -f 307 306 321 322 -f 314 313 328 329 -f 308 307 322 323 -f 302 301 316 317 -f 315 314 329 330 -f 309 308 323 324 -f 303 302 317 318 -f 310 309 324 325 -f 304 303 318 319 -f 330 329 345 346 -f 324 323 339 340 -f 318 317 333 334 -f 325 324 340 341 -f 319 318 334 335 -f 326 325 341 342 -f 320 319 335 336 -f 327 326 342 343 -f 321 320 336 337 -f 328 327 343 344 -f 322 321 337 338 -f 329 328 344 345 -f 323 322 338 339 -f 317 316 332 333 -f 344 343 358 359 -f 338 337 352 353 -f 345 344 359 360 -f 339 338 353 354 -f 333 332 347 348 -f 346 345 360 361 -f 340 339 354 355 -f 334 333 348 349 -f 341 340 355 356 -f 335 334 349 350 -f 342 341 356 357 -f 336 335 350 351 -f 343 342 357 358 -f 337 336 351 352 -f 357 356 371 372 -f 351 350 365 366 -f 358 357 372 373 -f 352 351 366 367 -f 359 358 373 374 -f 353 352 367 368 -f 360 359 374 375 -f 354 353 368 369 -f 348 347 362 363 -f 361 360 375 376 -f 355 354 369 370 -f 349 348 363 364 -f 356 355 370 371 -f 350 349 364 365 -f 363 362 377 378 -f 376 375 390 391 -f 370 369 384 385 -f 364 363 378 379 -f 371 370 385 386 -f 365 364 379 380 -f 372 371 386 387 -f 366 365 380 381 -f 373 372 387 388 -f 367 366 381 382 -f 374 373 388 389 -f 368 367 382 383 -f 375 374 389 390 -f 369 368 383 384 -f 382 381 396 397 -f 389 388 403 404 -f 383 382 397 398 -f 390 389 404 405 -f 384 383 398 399 -f 378 377 392 393 -f 391 390 405 406 -f 385 384 399 400 -f 379 378 393 394 -f 386 385 400 401 -f 380 379 394 395 -f 387 386 401 402 -f 381 380 395 396 -f 388 387 402 403 -f 401 400 415 416 -f 395 394 409 410 -f 402 401 416 417 -f 396 395 410 411 -f 403 402 417 418 -f 397 396 411 412 -f 404 403 418 419 -f 398 397 412 413 -f 405 404 419 420 -f 399 398 413 414 -f 393 392 407 408 -f 406 405 420 421 -f 400 399 414 415 -f 394 393 408 409 -f 420 419 434 435 -f 414 413 428 429 -f 408 407 422 423 -f 421 420 435 436 -f 415 414 429 430 -f 409 408 423 424 -f 416 415 430 431 -f 410 409 424 425 -f 417 416 431 432 -f 411 410 425 426 -f 418 417 432 433 -f 412 411 426 427 -f 419 418 433 434 -f 413 412 427 428 -f 433 432 448 449 -f 427 426 442 443 -f 434 433 449 450 -f 428 427 443 444 -f 435 434 450 451 -f 429 428 444 445 -f 423 422 438 439 -f 436 435 451 452 -f 430 429 445 446 -f 424 423 439 440 -f 431 430 446 447 -f 425 424 440 441 -f 432 431 447 448 -f 426 425 441 442 -f 447 446 461 462 -f 441 440 455 456 -f 448 447 462 463 -f 442 441 456 457 -f 449 448 463 464 -f 443 442 457 458 -f 450 449 464 465 -f 444 443 458 459 -f 451 450 465 466 -f 445 444 459 460 -f 439 438 453 454 -f 452 451 466 467 -f 446 445 460 461 -f 440 439 454 455 -f 466 465 480 481 -f 460 459 474 475 -f 454 453 468 469 -f 467 466 481 482 -f 461 460 475 476 -f 455 454 469 470 -f 462 461 476 477 -f 456 455 470 471 -f 463 462 477 478 -f 457 456 471 472 -f 464 463 478 479 -f 458 457 472 473 -f 465 464 479 480 -f 459 458 473 474 -f 1 437 16 -f 331 15 30 -f 331 30 45 -f 16 437 31 -f 31 437 46 -f 331 45 60 -f 46 437 61 -f 331 60 75 -f 331 75 90 -f 61 437 76 -f 76 437 91 -f 331 90 105 -f 91 437 106 -f 331 105 120 -f 331 120 135 -f 106 437 121 -f 121 437 136 -f 331 135 150 -f 331 150 165 -f 136 437 151 -f 331 165 180 -f 151 437 166 -f 166 437 181 -f 331 180 195 -f 331 195 210 -f 181 437 196 -f 331 210 225 -f 196 437 211 -f 211 437 226 -f 331 225 240 -f 331 240 255 -f 226 437 241 -f 241 437 256 -f 331 255 270 -f 256 437 271 -f 331 270 285 -f 331 285 300 -f 271 437 286 -f 286 437 301 -f 331 300 315 -f 301 437 316 -f 331 315 330 -f 331 330 346 -f 316 437 332 -f 332 437 347 -f 331 346 361 -f 347 437 362 -f 331 361 376 -f 331 376 391 -f 362 437 377 -f 377 437 392 -f 331 391 406 -f 392 437 407 -f 331 406 421 -f 331 421 436 -f 407 437 422 -f 422 437 438 -f 331 436 452 -f 331 452 467 -f 438 437 453 -f 331 467 482 -f 453 437 468 -f 479 478 11 12 -f 473 472 5 6 -f 480 479 12 13 -f 474 473 6 7 -f 468 437 1 -f 481 480 13 14 -f 475 474 7 8 -f 469 468 1 2 -f 482 481 14 15 -f 476 475 8 9 -f 470 469 2 3 -f 331 482 15 -f 477 476 9 10 -f 471 470 3 4 -f 478 477 10 11 -f 472 471 4 5 diff --git a/examples/common/opengl-framework/CMakeLists.txt b/examples/common/opengl-framework/CMakeLists.txt deleted file mode 100644 index e10ae781..00000000 --- a/examples/common/opengl-framework/CMakeLists.txt +++ /dev/null @@ -1,84 +0,0 @@ -# Minimum cmake version required -CMAKE_MINIMUM_REQUIRED(VERSION 2.6) - -# Project configuration -PROJECT(OPENGLFRAMEWORK) - -# Options -OPTION(USE_JPEG_TEXTURES "Select this if you want to use jpeg textures (libjpeg required)" OFF) - -# Where to find the module to find special packages/libraries -SET(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/") - -# Find OpenGL -FIND_PACKAGE(OpenGL REQUIRED) -IF(OPENGL_FOUND) - MESSAGE("OpenGL found") -ELSE() - MESSAGE("OpenGL not found") -ENDIF() - -# Find the GLEW library -FIND_PACKAGE(GLEW REQUIRED) -IF(GLEW_FOUND) - MESSAGE("GLEW found") -ELSE() - MESSAGE("GLEW not found") -ENDIF() - -# If the user wants to use JPEG textures -IF(USE_JPEG_TEXTURES) - - # Find the LIBJPEG library - FIND_PACKAGE(JPEG REQUIRED) - IF(JPEG_FOUND) - MESSAGE("LIBJPEG found") - ELSE() - MESSAGE("LIBJPEG not found") - ENDIF() -ENDIF() - -# Headers -INCLUDE_DIRECTORIES(src ${OPENGL_INCLUDE_DIR} ${GLEW_INCLUDE_PATH} ${JPEG_INCLUDE_DIR}) - -# Source files -SET(OPENGL_FRAMEWORK_SOURCES - "src/maths/Color.h" - "src/maths/Matrix3.h" - "src/maths/Matrix4.h" - "src/maths/Vector2.h" - "src/maths/Vector3.h" - "src/maths/Vector4.h" - "src/Camera.cpp" - "src/Camera.h" - "src/definitions.h" - "src/FrameBufferObject.cpp" - "src/FrameBufferObject.h" - "src/Light.h" - "src/Light.cpp" - "src/Mesh.h" - "src/Mesh.cpp" - "src/MeshReaderWriter.h" - "src/MeshReaderWriter.cpp" - "src/Object3D.h" - "src/Object3D.cpp" - "src/openglframework.h" - "src/Shader.h" - "src/Shader.cpp" - "src/Texture2D.h" - "src/Texture2D.cpp" - "src/TextureReaderWriter.h" - "src/TextureReaderWriter.cpp" - "src/VertexBufferObject.h" - "src/VertexBufferObject.cpp" -) - -IF(USE_JPEG_TEXTURES) - ADD_DEFINITIONS(-DUSE_JPEG_TEXTURE) -ENDIF() - -# Create the library -ADD_LIBRARY (openglframework STATIC ${OPENGL_FRAMEWORK_SOURCES}) - -# Link with others libraries -TARGET_LINK_LIBRARIES(openglframework ${GLEW_LIBRARIES} ${OPENGL_LIBRARY}) diff --git a/examples/common/opengl-framework/cmake/FindFREEGLUT.cmake b/examples/common/opengl-framework/cmake/FindFREEGLUT.cmake deleted file mode 100644 index 0ca4821e..00000000 --- a/examples/common/opengl-framework/cmake/FindFREEGLUT.cmake +++ /dev/null @@ -1,32 +0,0 @@ -# This module is used to try to find the Freeglut library and include files - -IF(WIN32) - FIND_PATH(FREEGLUT_INCLUDE_DIR NAMES GL/freeglut.h) - FIND_LIBRARY(FREEGLUT_LIBRARY NAMES freeglut freeglut_static - PATHS ${OPENGL_LIBRARY_DIR}) -ELSE(WIN32) - - IF(APPLE) - # Do nothing, we do not want to use freeglut on Mac OS X - ELSE(APPLE) - FIND_PATH(FREEGLUT_INCLUDE_DIR GL/freeglut.h /usr/include/GL - /usr/openwin/share/include - /usr/openwin/include - /opt/graphics/OpenGL/include - /opt/graphics/OpenGL/contrib/libglut) - - FIND_LIBRARY(FREEGLUT_LIBRARY NAMES glut freeglut freeglut_static PATHS /usr/openwin/lib) - FIND_LIBRARY(Xi_LIBRARY Xi /usr/openwin/lib) - FIND_LIBRARY(Xmu_LIBRARY Xmu /usr/openwin/lib) - ENDIF(APPLE) -ENDIF(WIN32) - -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(FREEGLUT REQUIRED_VARS FREEGLUT_LIBRARY FREEGLUT_INCLUDE_DIR) - -IF(FREEGLUT_FOUND) - SET(FREEGLUT_LIBRARIES ${FREEGLUT_LIBRARY} ${Xi_LIBRARY} ${Xmu_LIBRARY}) - SET(FREEGLUT_LIBRARY ${FREEGLUT_LIBRARIES}) -ENDIF(FREEGLUT_FOUND) - -MARK_AS_ADVANCED(FREEGLUT_INCLUDE_DIR FREEGLUT_LIBRARY Xi_LIBRARY Xmu_LIBRARY) diff --git a/examples/common/opengl-framework/cmake/FindGLEW.cmake b/examples/common/opengl-framework/cmake/FindGLEW.cmake deleted file mode 100644 index c29c4eb2..00000000 --- a/examples/common/opengl-framework/cmake/FindGLEW.cmake +++ /dev/null @@ -1,65 +0,0 @@ -# -# Try to find GLEW library and include path. -# Once done this will define -# -# GLEW_FOUND -# GLEW_INCLUDE_PATH -# GLEW_LIBRARY -# - -IF (WIN32) -FIND_PATH( GLEW_INCLUDE_PATH GL/glew.h -$ENV{PROGRAMFILES}/GLEW/include -${GLEW_ROOT_DIR}/include -DOC "The directory where GL/glew.h resides") - -IF (NV_SYSTEM_PROCESSOR STREQUAL "AMD64") -FIND_LIBRARY( GLEW_LIBRARY -NAMES glew64 glew64s -PATHS -$ENV{PROGRAMFILES}/GLEW/lib -${PROJECT_SOURCE_DIR}/src/nvgl/glew/bin -${PROJECT_SOURCE_DIR}/src/nvgl/glew/lib -DOC "The GLEW library (64-bit)" -) -ELSE(NV_SYSTEM_PROCESSOR STREQUAL "AMD64") -FIND_LIBRARY( GLEW_LIBRARY -NAMES glew GLEW glew32 glew32s -PATHS -$ENV{PROGRAMFILES}/GLEW/lib -${PROJECT_SOURCE_DIR}/src/nvgl/glew/bin -${PROJECT_SOURCE_DIR}/src/nvgl/glew/lib -DOC "The GLEW library" -) -ENDIF(NV_SYSTEM_PROCESSOR STREQUAL "AMD64") -ELSE (WIN32) -FIND_PATH( GLEW_INCLUDE_PATH GL/glew.h -/usr/include -/usr/local/include -/sw/include -/opt/local/include -${GLEW_ROOT_DIR}/include -DOC "The directory where GL/glew.h resides") - -FIND_LIBRARY( GLEW_LIBRARY -NAMES GLEW glew -PATHS -/usr/lib64 -/usr/lib -/usr/local/lib64 -/usr/local/lib -/sw/lib -/opt/local/lib -${GLEW_ROOT_DIR}/lib -DOC "The GLEW library") -ENDIF (WIN32) - -SET(GLEW_FOUND "NO") -IF (GLEW_INCLUDE_PATH AND GLEW_LIBRARY) -SET(GLEW_LIBRARIES ${GLEW_LIBRARY}) -SET(GLEW_FOUND "YES") -ENDIF (GLEW_INCLUDE_PATH AND GLEW_LIBRARY) - - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(GLEW DEFAULT_MSG GLEW_LIBRARY GLEW_INCLUDE_PATH) \ No newline at end of file diff --git a/examples/common/opengl-framework/src/Camera.cpp b/examples/common/opengl-framework/src/Camera.cpp deleted file mode 100644 index a032a046..00000000 --- a/examples/common/opengl-framework/src/Camera.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/******************************************************************************** -* OpenGL-Framework * -* Copyright (c) 2013 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - - -// Libraries -#include "Camera.h" -#include "definitions.h" -#include - -// Namespaces -using namespace openglframework; - -// Constructor -Camera::Camera() : Object3D() { - - // Set default values - mFieldOfView = 45.0f; - mSceneRadius = 1.0f; - mNearPlane = 0.1f; - mFarPlane = 10.0f; - mWidth = 1; - mHeight = 1; - - // Update the projection matrix - updateProjectionMatrix(); -} - -// Destructor -Camera::~Camera() { - -} - -// Update the projection matrix -void Camera::updateProjectionMatrix() { - - // Compute the aspect ratio - float aspect = float(mWidth) / float(mHeight); - - float top = mNearPlane * tan((mFieldOfView / 2.0f) * (float(PI) / 180.0f)); - float bottom = -top; - float left = bottom * aspect; - float right = top * aspect; - - float fx = 2.0f * mNearPlane / (right - left); - float fy = 2.0f * mNearPlane / (top - bottom); - float fz = -(mFarPlane + mNearPlane) / (mFarPlane - mNearPlane); - float fw = -2.0f * mFarPlane * mNearPlane / (mFarPlane - mNearPlane); - - // Recompute the projection matrix - mProjectionMatrix = Matrix4(fx, 0, 0, 0, - 0, fy, 0, 0, - 0, 0, fz, fw, - 0, 0, -1, 0); -} - -// Translate the camera go a given point using the dx, dy fraction -void Camera::translateCamera(float dx, float dy, const Vector3& worldPoint) { - - // Transform the world point into camera coordinates - Vector3 pointCamera = mTransformMatrix.getInverse() * worldPoint; - - // Get the depth - float z = -pointCamera.z; - - // Find the scaling of dx and dy from windows coordinates to near plane coordinates - // and from there to camera coordinates at the object's depth - float aspect = float(mWidth) / float(mHeight); - float top = mNearPlane * tan(mFieldOfView * PI / 360.0f); - float right = top * aspect; - - // Translate the camera - translateLocal(Vector3(2.0f * dx * right / mNearPlane * z, - -2.0f * dy * top / mNearPlane * z, - 0.0f)); -} diff --git a/examples/common/opengl-framework/src/Camera.h b/examples/common/opengl-framework/src/Camera.h deleted file mode 100644 index 108c363f..00000000 --- a/examples/common/opengl-framework/src/Camera.h +++ /dev/null @@ -1,181 +0,0 @@ -/******************************************************************************** -* OpenGL-Framework * -* Copyright (c) 2013 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -#ifndef CAMERA_H -#define CAMERA_H - -// Libraries -#include "Object3D.h" -#include "definitions.h" - -namespace openglframework { - -// Class Camera -class Camera : public Object3D { - - protected : - - // ------------------- Attributes ------------------- // - - // Field of view - float mFieldOfView; - - // Radius of the scene - float mSceneRadius; - - // Near plane - float mNearPlane; - - // Far plane - float mFarPlane; - - // Width of the camera - uint mWidth; - - // Height of the camera - uint mHeight; - - // Projection matrix - Matrix4 mProjectionMatrix; - - // ------------------- Methods ------------------- // - - // Update the projection matrix - void updateProjectionMatrix(); - - public: - - // ------------------- Methods ------------------- // - - // Constructor - Camera(); - - // Destructor - ~Camera(); - - // Get the projection matrix - const Matrix4& getProjectionMatrix() const; - - // Set the dimensions of the camera - void setDimensions(uint width, uint height); - - // Get the radius of the scene the camera should capture - float getSceneRadius() const; - - // Set the radius of the scene the camera should capture - // This will update the clipping planes accordingly - void setSceneRadius(float radius); - - // Set the clipping planes - void setClippingPlanes(float near, float far); - - // Set the field of view - void setFieldOfView(float fov); - - // Set the zoom of the camera (a fraction between 0 and 1) - void setZoom(float fraction); - - // Translate the camera go a given point using the dx, dy fraction - void translateCamera(float dx, float dy, const Vector3& worldPoint); - - // Get the near clipping plane - float getNearClippingPlane() const; - - // Get the far clipping plane - float getFarClippingPlane() const; - - // Get the width - uint getWidth() const; - - // Get the height - uint getHeight() const; -}; - -// Get the projection matrix -inline const Matrix4& Camera::getProjectionMatrix() const { - return mProjectionMatrix; -} - -// Set the dimensions of the camera -inline void Camera::setDimensions(uint width, uint height) { - mWidth = width; - mHeight = height; - updateProjectionMatrix(); -} - -// Get the radius of the scene the camera should capture -inline float Camera::getSceneRadius() const { - return mSceneRadius; -} - -// Set the radius of the scene the camera should capture -// This will update the clipping planes accordingly -inline void Camera::setSceneRadius(float radius) { - mSceneRadius = radius; - setClippingPlanes(0.01f * radius, 10.0f * radius); -} - -// Set the clipping planes -inline void Camera::setClippingPlanes(float near, float far) { - mNearPlane = near; - mFarPlane = far; - updateProjectionMatrix(); -} - -// Set the field of view -inline void Camera::setFieldOfView(float fov) { - mFieldOfView = fov; - updateProjectionMatrix(); -} - -// Set the zoom of the camera (a fraction between 0 and 1) -inline void Camera::setZoom(float fraction) { - Vector3 zoomVector(0, 0, mSceneRadius * fraction); - translateLocal(zoomVector); -} - -// Get the near clipping plane -inline float Camera::getNearClippingPlane() const { - return mNearPlane; -} - -// Get the far clipping plane -inline float Camera::getFarClippingPlane() const { - return mFarPlane; -} - -// Get the width -inline uint Camera::getWidth() const { - return mWidth; -} - -// Get the height -inline uint Camera::getHeight() const { - return mHeight; -} - -} - -#endif diff --git a/examples/common/opengl-framework/src/FrameBufferObject.cpp b/examples/common/opengl-framework/src/FrameBufferObject.cpp deleted file mode 100644 index 5f67be23..00000000 --- a/examples/common/opengl-framework/src/FrameBufferObject.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/******************************************************************************** -* OpenGL-Framework * -* Copyright (c) 2013 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -// Libraries -#include "FrameBufferObject.h" -#include - -using namespace openglframework; -using namespace std; - -// Constructor -FrameBufferObject::FrameBufferObject() : mFrameBufferID(0), mRenderBufferID (0) { - -} - -// Destructor -FrameBufferObject::~FrameBufferObject() { - -} - -// Create the frame buffer object -bool FrameBufferObject::create(uint width, uint height, bool needRenderBuffer) { - - // Destroy the current FBO - destroy(); - - // Check that the needed OpenGL extensions are available - bool isExtensionOK = checkOpenGLExtensions(); - if (!isExtensionOK) { - std::cerr << "Error : Impossible to use Framebuffer Object on this platform" << std::endl; - assert(false); - return false; - } - - // Generate a new FBO - glGenFramebuffersEXT(1, &mFrameBufferID); - assert(mFrameBufferID != 0); - - // If we also need to create a render buffer - if (needRenderBuffer) { - - // Generate the render buffer - glGenRenderbuffers(1, &mRenderBufferID); - assert(mRenderBufferID != 0); - - glBindRenderbuffer(GL_RENDERBUFFER, mRenderBufferID); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT32, width, height); - glBindFramebuffer(GL_FRAMEBUFFER, mFrameBufferID); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, - mRenderBufferID); - glBindRenderbuffer(GL_RENDERBUFFER, 0); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - } - - // Check the FBO status - GLenum statusFBO = glCheckFramebufferStatus(GL_FRAMEBUFFER); - if(statusFBO != GL_FRAMEBUFFER_COMPLETE) { - std::cerr << "Error : An error occured while creating the Frame Buffer Object !" << endl; - assert(false); - return false; - } - - return true; -} - -// Destroy the FBO -void FrameBufferObject::destroy() { - - // Delete the frame buffer object - if (mFrameBufferID) { - glDeleteFramebuffers(1, &mFrameBufferID); - mFrameBufferID = 0; - } - - // Delete the render buffer - if (mRenderBufferID) { - glDeleteRenderbuffers(1, &mRenderBufferID); - } -} - -// Attach a texture to the frame buffer object -void FrameBufferObject::attachTexture(uint position, uint textureID) { - assert(mFrameBufferID); - - // Bind the current FBO - glBindFramebuffer(GL_FRAMEBUFFER, mFrameBufferID); - - // Bind the texture - glFramebufferTexture2D(GL_FRAMEBUFFER, position, GL_TEXTURE_2D, textureID, 0); - - // Unbind the current FBO - glBindFramebuffer(GL_FRAMEBUFFER, 0); -} diff --git a/examples/common/opengl-framework/src/FrameBufferObject.h b/examples/common/opengl-framework/src/FrameBufferObject.h deleted file mode 100644 index a76951c7..00000000 --- a/examples/common/opengl-framework/src/FrameBufferObject.h +++ /dev/null @@ -1,105 +0,0 @@ -/******************************************************************************** -* OpenGL-Framework * -* Copyright (c) 2013 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -#ifndef FRAME_BUFFER_OBJECT_H -#define FRAME_BUFFER_OBJECT_H - -// Libraries -#include "definitions.h" -#include -#include -#include - -namespace openglframework { - - -// Class FrameBufferObject -class FrameBufferObject { - - private: - - // -------------------- Attributes -------------------- // - - // Frame buffer ID - uint mFrameBufferID; - - // Render buffer ID - uint mRenderBufferID; - - public: - - // -------------------- Methods -------------------- // - - // Constructor - FrameBufferObject(); - - // Destructor - ~FrameBufferObject(); - - // Create the frame buffer object - bool create(uint width, uint height, bool needRenderBuffer = true); - - // Attach a texture to the frame buffer object - void attachTexture(uint position, uint textureID); - - // Bind the FBO - void bind(uint position) const; - - // Unbind the FBO - void unbind() const; - - // Return true if the needed OpenGL extensions are available for FBO - static bool checkOpenGLExtensions(); - - // Destroy the FBO - void destroy(); -}; - -// Bind the FBO -inline void FrameBufferObject::bind(uint position) const { - assert(mFrameBufferID != 0); - glBindFramebuffer(GL_FRAMEBUFFER, mFrameBufferID); - glDrawBuffer(position); - glReadBuffer(position); -} - -// Unbind the FBO -inline void FrameBufferObject::unbind() const { - assert(mFrameBufferID != 0); - glDrawBuffer(GL_NONE); - glReadBuffer(GL_NONE); - glBindFramebuffer(GL_FRAMEBUFFER, 0); -} - -// Return true if the needed OpenGL extensions are available for FBO -inline bool FrameBufferObject::checkOpenGLExtensions() { - - // Check that OpenGL version is at least 3.0 or there the framebuffer object extension exists - return (GLEW_VERSION_3_0 || GLEW_ARB_framebuffer_object); -} - -} - -#endif diff --git a/examples/common/opengl-framework/src/Light.cpp b/examples/common/opengl-framework/src/Light.cpp deleted file mode 100644 index cd1831eb..00000000 --- a/examples/common/opengl-framework/src/Light.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/******************************************************************************** -* OpenGL-Framework * -* Copyright (c) 2013 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -// Libraries -#include "Light.h" - -// Namespaces -using namespace openglframework; - -// Constructor -Light::Light(GLuint id) - : mLightID(id), mDiffuseColor(Color::white()), - mSpecularColor(Color::white()), mIsActive(false) { - -} - -// Constructor -Light::Light(GLuint id, Color diffuseColor, Color specularColor) - : mLightID(id), mDiffuseColor(diffuseColor), - mSpecularColor(specularColor), mIsActive(false) { - -} - -// Destructor -Light::~Light() { - -} - -// Initialize the light -void Light::init() { - - // Enable the light - enable(); - - // Set the diffuse and specular color - GLfloat diffuseColor[] = {mDiffuseColor.r, mDiffuseColor.g, mDiffuseColor.b, mDiffuseColor.a}; - GLfloat specularColor[] = {mSpecularColor.r,mSpecularColor.g,mSpecularColor.b,mSpecularColor.a}; - glLightfv(mLightID, GL_DIFFUSE, diffuseColor); - glLightfv(mLightID, GL_SPECULAR, specularColor); -} - -// Create a shadow map associated with this light -bool Light::createShadowMap(uint width, uint height) { - - // Destroy the current shadow map - destroyShadowMap(); - - // Create the Framebuffer object to render the shadow map - bool isFBOCreated = mFBOShadowMap.create(width, height, false); - if (!isFBOCreated) { - std::cerr << "Error : Cannot create the Shadow Map !" << std::endl; - destroyShadowMap(); - return false; - } - - // Bind the Framebuffer object - mFBOShadowMap.bind(GL_NONE); - - // Create the shadow map depth texture - mShadowMap.create(width, height, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE); - - // Attache the shadow map texture to the Framebuffer object - mFBOShadowMap.attachTexture(GL_DEPTH_ATTACHMENT_EXT, mShadowMap.getID()); - - // Unbind the Framebuffer object - mFBOShadowMap.unbind(); - - // TODO : Change the path of the shader here so that it does not depend on the build folder - bool isShaderCreated = mDepthShader.create("../../opengl-framework/src/shaders/depth.vert", - "../../opengl-framework/src/shaders/depth.vert"); - if (!isShaderCreated) { - std::cerr << "Error : Cannot create the Shadow Map !" << std::endl; - destroyShadowMap(); - return false; - } - - return true; -} diff --git a/examples/common/opengl-framework/src/Light.h b/examples/common/opengl-framework/src/Light.h deleted file mode 100644 index 8f8323d9..00000000 --- a/examples/common/opengl-framework/src/Light.h +++ /dev/null @@ -1,181 +0,0 @@ -/******************************************************************************** -* OpenGL-Framework * -* Copyright (c) 2013 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -#ifndef LIGHT_H -#define LIGHT_H - -// Libraries -#include "maths/Color.h" -#include "maths/Vector3.h" -#include "Object3D.h" -#include "Texture2D.h" -#include "FrameBufferObject.h" -#include "Shader.h" -#include - -namespace openglframework { - -// Class Light -class Light : public Object3D { - - private: - - // -------------------- Attributes -------------------- // - - // OpenGL light ID - GLuint mLightID; - - // Diffuse color of the light - Color mDiffuseColor; - - // Specular color of the light - Color mSpecularColor; - - // True if the light is active - bool mIsActive; - - // Shadow map associated with this light - Texture2D mShadowMap; - - // Framebuffer object to render the shadow map - FrameBufferObject mFBOShadowMap; - - // Shader to render the depth of the scene into a texture - Shader mDepthShader; - - public: - - // -------------------- Methods -------------------- // - - // Constructor - Light(GLuint id); - - // Constructor - Light(GLuint id, Color diffuseColor, Color specularColor); - - // Destructor - virtual ~Light(); - - // Return the diffuse color - Color getDiffuseColor() const; - - // Set the diffuse color - void setDiffuseColor(const Color& color); - - // Return the specular color - Color getSpecularColor() const; - - // Set the specular color - void setSpecularColor(const Color& color); - - // Return true if the light is active - bool getIsActive() const; - - // Initialize the light - void init(); - - // Enable the light - void enable(); - - // Disable the light - void disable(); - - // Create a shadow map associated with this light - bool createShadowMap(uint width, uint height); - - // Call this method before rendering the scene for the shadow map computation - void startRenderingShadowMap(); - - // Call this method after having rendered the scene for the shadow map computation - void stopRenderingShadowMap(); - - // Destroy the shadow map associated with this light - void destroyShadowMap(); -}; - -// Return the diffuse color -inline Color Light::getDiffuseColor() const { - return mDiffuseColor; -} - -// Set the diffuse color -inline void Light::setDiffuseColor(const Color& color) { - mDiffuseColor = color; -} - -// Return the specular color -inline Color Light::getSpecularColor() const { - return mSpecularColor; -} - -// Set the specular color -inline void Light::setSpecularColor(const Color& color) { - mSpecularColor = color; -} - -// Return true if the light is active -inline bool Light::getIsActive() const { - return mIsActive; -} - -// Enable the light -inline void Light::enable() { - - mIsActive = true; - - // Enable the light - glEnable(GL_LIGHTING); - glEnable(GL_LIGHT0 + mLightID); -} - -// Disable the light -inline void Light::disable() { - - mIsActive = false; - - // Disable the light - glDisable(GL_LIGHT0 + mLightID); -} - -// Destroy the shadow map associated with this light -inline void Light::destroyShadowMap() { - mShadowMap.destroy(); - mFBOShadowMap.destroy(); - mDepthShader.destroy(); -} - -// Call this method before rendering the scene for the shadow map computation -inline void Light::startRenderingShadowMap() { - assert(mShadowMap.getID()); -} - -// Call this method after having rendered the scene for the shadow map computation -inline void Light::stopRenderingShadowMap() { - assert(mShadowMap.getID()); -} - -} - -#endif diff --git a/examples/common/opengl-framework/src/Mesh.cpp b/examples/common/opengl-framework/src/Mesh.cpp deleted file mode 100644 index 070c1d07..00000000 --- a/examples/common/opengl-framework/src/Mesh.cpp +++ /dev/null @@ -1,176 +0,0 @@ -/******************************************************************************** -* OpenGL-Framework * -* Copyright (c) 2013 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -// Libraries -#include "Mesh.h" - -// Namespaces -using namespace openglframework; -using namespace std; - -// Constructor -Mesh::Mesh() { - -} - -// Destructor -Mesh::~Mesh() { - -} - -// Destroy the mesh -void Mesh::destroy() { - - mVertices.clear(); - mNormals.clear(); - mTangents.clear(); - mIndices.clear(); - mColors.clear(); - mUVs.clear(); - mTextures.clear(); -} - -// Compute the normals of the mesh -void Mesh::calculateNormals() { - - mNormals = vector(getNbVertices(), Vector3(0, 0, 0)); - - // For each triangular face - for (uint i=0; i(getNbVertices(), Vector3(0, 0, 0)); - - // For each face - for (uint i=0; i::const_iterator it(mVertices.begin()); - - // For each vertex of the mesh - for (; it != mVertices.end(); ++it) { - - if( (*it).x < min.x ) min.x = (*it).x; - else if ( (*it).x > max.x ) max.x = (*it).x; - - if( (*it).y < min.y ) min.y = (*it).y; - else if ( (*it).y > max.y ) max.y = (*it).y; - - if( (*it).z < min.z ) min.z = (*it).z; - else if ( (*it).z > max.z ) max.z = (*it).z; - } - } - else { - std::cerr << "Error : Impossible to calculate the bounding box of the mesh because there" << - "are no vertices !" << std::endl; - assert(false); - } -} - -// Scale of vertices of the mesh using a given factor -void Mesh::scaleVertices(float factor) { - - // For each vertex - for (uint i=0; i -#include -#include -#include "definitions.h" -#include "maths/Vector2.h" -#include "maths/Vector3.h" -#include "maths/Color.h" -#include "Texture2D.h" -#include "Object3D.h" - -namespace openglframework { - -// Class Mesh -// This class represents a 3D triangular mesh -// object that can be loaded from an OBJ file for instance. -class Mesh : public Object3D { - - protected: - - // -------------------- Attributes -------------------- // - - // A triplet of vertex indices for each triangle - std::vector > mIndices; - - // Vertices coordinates (local space) - std::vector mVertices; - - // Normals coordinates - std::vector mNormals; - - // Tangents coordinates - std::vector mTangents; - - // Color for each vertex - std::vector mColors; - - // UV texture coordinates - std::vector mUVs; - - // Textures of the mesh (one for each part of the mesh) - std::map mTextures; - - public: - - // -------------------- Methods -------------------- // - - // Constructor - Mesh(); - - // Destructor - virtual ~Mesh(); - - // Destroy the mesh - void destroy(); - - // Compute the normals of the mesh - void calculateNormals(); - - // Compute the tangents of the mesh - void calculateTangents(); - - // Calculate the bounding box of the mesh - void calculateBoundingBox(Vector3& min, Vector3& max) const; - - // Scale of vertices of the mesh using a given factor - void scaleVertices(float factor); - - // Return the number of triangles - uint getNbFaces(uint part = 0) const; - - // Return the number of vertices - uint getNbVertices() const; - - // Return the number of parts in the mesh - uint getNbParts() const; - - // Return a reference to the vertices - const std::vector& getVertices() const; - - // Set the vertices of the mesh - void setVertices(std::vector& vertices); - - // Return a reference to the normals - const std::vector& getNormals() const; - - // set the normals of the mesh - void setNormals(std::vector& normals); - - // Return a reference to the UVs - const std::vector& getUVs() const; - - // Set the UV texture coordinates of the mesh - void setUVs(std::vector& uvs); - - // Return a reference to the vertex indices - const std::vector& getIndices(uint part = 0) const; - - // Set the vertices indices of the mesh - void setIndices(std::vector >& indices); - - // Return the coordinates of a given vertex - const Vector3& getVertex(uint i) const; - - // Set the coordinates of a given vertex - void setVertex(uint i, const Vector3& vertex); - - // Return the coordinates of a given normal - const Vector3& getNormal(uint i) const; - - // Set the coordinates of a given normal - void setNormal(uint i, const Vector3& normal); - - // Return the color of a given vertex - const Color& getColor(uint i) const; - - // Set the color of a given vertex - void setColor(uint i, const Color& color); - - // Set a color to all the vertices - void setColorToAllVertices(const Color& color); - - // Return the UV of a given vertex - const Vector2& getUV(uint i) const; - - // Set the UV of a given vertex - void setUV(uint i, const Vector2& uv); - - // Return the vertex index of the ith (i=0,1,2) vertex of a given face - uint getVertexIndexInFace(uint faceIndex, uint i, uint part = 0) const; - - // Return true if the mesh has normals - bool hasNormals() const; - - // Return true if the mesh has tangents - bool hasTangents() const; - - // Return true if the mesh has vertex colors - bool hasColors() const; - - // Return true if the mesh has UV texture coordinates - bool hasUVTextureCoordinates() const; - - // Return true if the mesh has a texture for a given part of the mesh and if it - // also have texture coordinates - bool hasTextureForPart(uint part = 0) const; - - // Return true if the mesh has a texture (and texture coordinates) for at least one - // part of the mesh - bool hasTexture() const; - - // Return a pointer to the vertices data - void* getVerticesPointer(); - - // Return a pointer to the normals data - void* getNormalsPointer(); - - // Return a pointer to the colors data - void* getColorsPointer(); - - // Return a pointer to the tangents data - void* getTangentsPointer(); - - // Return a pointer to the UV texture coordinates data - void* getUVTextureCoordinatesPointer(); - - // Return a pointer to the vertex indicies data - void* getIndicesPointer(uint part = 0); - - // Return a reference to a texture of the mesh - Texture2D &getTexture(uint part = 0); - - // Set a texture to a part of the mesh - void setTexture(Texture2D &texture, uint part = 0); -}; - -// Return the number of triangles -inline uint Mesh::getNbFaces(uint part) const { - return mIndices[part].size() / 3; -} - -// Return the number of vertices -inline uint Mesh::getNbVertices() const { - return mVertices.size(); -} - -// Return the number of parts in the mesh -inline uint Mesh::getNbParts() const { - return mIndices.size(); -} - -// Return a reference to the vertices -inline const std::vector& Mesh::getVertices() const { - return mVertices; -} - -// Set the vertices of the mesh -inline void Mesh::setVertices(std::vector& vertices) { - mVertices = vertices; -} - -// Return a reference to the normals -inline const std::vector& Mesh::getNormals() const { - return mNormals; -} - -// set the normals of the mesh -inline void Mesh::setNormals(std::vector& normals) { - mNormals = normals; -} - -// Return a reference to the UVs -inline const std::vector& Mesh::getUVs() const { - return mUVs; -} - -// Set the UV texture coordinates of the mesh -inline void Mesh::setUVs(std::vector& uvs) { - mUVs = uvs; -} - -// Return a reference to the vertex indices -inline const std::vector& Mesh::getIndices(uint part) const { - return mIndices[part]; -} - -// Set the vertices indices of the mesh -inline void Mesh::setIndices(std::vector >& indices) { - mIndices = indices; -} - -// Return the coordinates of a given vertex -inline const Vector3& Mesh::getVertex(uint i) const { - assert(i < getNbVertices()); - return mVertices[i]; -} - -// Set the coordinates of a given vertex -inline void Mesh::setVertex(uint i, const Vector3& vertex) { - assert(i < getNbVertices()); - mVertices[i] = vertex; -} - -// Return the coordinates of a given normal -inline const Vector3& Mesh::getNormal(uint i) const { - assert(i < getNbVertices()); - return mNormals[i]; -} - -// Set the coordinates of a given normal -inline void Mesh::setNormal(uint i, const Vector3& normal) { - assert(i < getNbVertices()); - mNormals[i] = normal; -} - -// Return the color of a given vertex -inline const Color& Mesh::getColor(uint i) const { - assert(i < getNbVertices()); - return mColors[i]; -} - -// Set the color of a given vertex -inline void Mesh::setColor(uint i, const Color& color) { - - // If the color array does not have the same size as - // the vertices array - if (mColors.size() != mVertices.size()) { - - // Create the color array with the same size - mColors = std::vector(mVertices.size()); - } - - mColors[i] = color; -} - -// Set a color to all the vertices -inline void Mesh::setColorToAllVertices(const Color& color) { - - // If the color array does not have the same size as - // the vertices array - if (mColors.size() != mVertices.size()) { - - // Create the color array with the same size - mColors = std::vector(mVertices.size()); - } - - for (size_t v=0; v 0); -} - -// Return a pointer to the vertices data -inline void* Mesh::getVerticesPointer() { - return &(mVertices[0]); -} - -// Return a pointer to the normals data -inline void* Mesh::getNormalsPointer() { - return &(mNormals[0]); -} - -// Return a pointer to the colors data -inline void* Mesh::getColorsPointer() { - return &(mColors[0]); -} - -// Return a pointer to the tangents data -inline void* Mesh::getTangentsPointer() { - return &(mTangents[0]); -} - -// Return a pointer to the UV texture coordinates data -inline void* Mesh::getUVTextureCoordinatesPointer() { - return &(mUVs[0]); -} - -// Return a pointer to the vertex indicies data -inline void* Mesh::getIndicesPointer(uint part) { - return &(mIndices[part])[0]; -} - -// Return a reference to a texture of the mesh -inline Texture2D& Mesh::getTexture(uint part) { - return mTextures[part]; -} - -// Set a texture to a part of the mesh -inline void Mesh::setTexture(Texture2D& texture, uint part) { - mTextures[part] = texture; -} - -} - -#endif diff --git a/examples/common/opengl-framework/src/MeshReaderWriter.cpp b/examples/common/opengl-framework/src/MeshReaderWriter.cpp deleted file mode 100644 index 275226ae..00000000 --- a/examples/common/opengl-framework/src/MeshReaderWriter.cpp +++ /dev/null @@ -1,393 +0,0 @@ -/******************************************************************************** -* OpenGL-Framework * -* Copyright (c) 2013 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -// Libraries -#include "MeshReaderWriter.h" -#include -#include -#include -#include -#include -#include - -using namespace openglframework; -using namespace std; - -// Constructor -MeshReaderWriter::MeshReaderWriter() { - -} - -// Load a mesh from a file and returns true if the mesh has been sucessfully loaded -void MeshReaderWriter::loadMeshFromFile(const std::string& filename, Mesh& meshToCreate) { - - // Get the extension of the file - uint startPosExtension = filename.find_last_of("."); - string extension = filename.substr(startPosExtension+1); - - // Load the file using the correct method - if (extension == "obj") { - loadOBJFile(filename, meshToCreate); - } - else { - - // Display an error message and throw an exception - string errorMessage("Error : the MeshReaderWriter class cannot load a file with the extension ."); - errorMessage += extension; - std::cerr << errorMessage << std::endl; - throw std::invalid_argument(errorMessage.c_str()); - } -} - -// Write a mesh to a file -void MeshReaderWriter::writeMeshToFile(const std::string& filename, const Mesh& meshToWrite) { - - // Get the extension of the file - uint startPosExtension = filename.find_last_of("."); - string extension = filename.substr(startPosExtension+1); - - // Load the file using the correct method - if (extension == "obj") { - writeOBJFile(filename, meshToWrite); - } - else { - - // Display an error message and throw an exception - string errorMessage("Error : the MeshReaderWriter class cannot store a mesh file with the extension ."); - errorMessage += extension; - std::cerr << errorMessage << std::endl; - throw std::invalid_argument(errorMessage.c_str()); - } -} - -// Load an OBJ file with a triangular or quad mesh -void MeshReaderWriter::loadOBJFile(const string &filename, Mesh& meshToCreate) { - - // Open the file - std::ifstream meshFile(filename.c_str()); - - // If we cannot open the file - if(!meshFile.is_open()) { - - // Throw an exception and display an error message - string errorMessage("Error : Cannot open the file " + filename); - std::cerr << errorMessage << std::endl; - throw runtime_error(errorMessage); - } - - std::string buffer; - string line, tmp; - int id1, id2, id3, id4; - int nId1, nId2, nId3, nId4; - int tId1, tId2, tId3, tId4; - float v1, v2, v3; - size_t found1, found2; - std::vector isQuad; - std::vector vertices; - std::vector normals; - std::vector uvs; - std::vector verticesIndices; - std::vector normalsIndices; - std::vector uvsIndices; - - // ---------- Collect the data from the file ---------- // - - // For each line of the file - while(std::getline(meshFile, buffer)) { - - std::istringstream lineStream(buffer); - std::string word; - lineStream >> word; - std::transform(word.begin(), word.end(), word.begin(), ::tolower); - if(word == "usemtl") { // Material definition - - // Loading of MTL file is not implemented - - } - else if(word == "v") { // Vertex position - sscanf(buffer.c_str(), "%*s %f %f %f", &v1, &v2, &v3); - vertices.push_back(Vector3(v1, v2, v3)); - } - else if(word == "vt") { // Vertex texture coordinate - sscanf(buffer.c_str(), "%*s %f %f", &v1, &v2); - uvs.push_back(Vector2(v1,v2)); - } - else if(word == "vn") { // Vertex normal - sscanf(buffer.c_str(), "%*s %f %f %f", &v1, &v2, &v3); - normals.push_back(Vector3(v1 ,v2, v3)); - } - else if (word == "f") { // Face - line = buffer; - found1 = (int)line.find("/"); - bool isFaceQuad = false; - int foundNext = (int)line.substr(found1+1).find("/"); - - // If the face definition is of the form "f v1 v2 v3 v4" - if(found1 == string::npos) { - int nbVertices = sscanf(buffer.c_str(), "%*s %d %d %d %d", &id1, &id2, &id3, &id4); - if (nbVertices == 4) isFaceQuad = true; - } - // If the face definition is of the form "f v1// v2// v3// v4//" - else if (foundNext == 0) { - int nbVertices = sscanf(buffer.c_str(), "%*s %d// %d// %d// %d//", &id1, &id2, &id3, &id4); - if (nbVertices == 4) isFaceQuad = true; - } - else { // If the face definition contains vertices and texture coordinates - - //get the part of the string until the second index - tmp = line.substr(found1+1); - found2 = (int)tmp.find(" "); - tmp = tmp.substr(0,found2); - found2 = (int)tmp.find("/"); - - // If the face definition is of the form "f vert1/textcoord1 vert2/textcoord2 ..." - if(found2 == string::npos) { - int n = sscanf(buffer.c_str(), "%*s %d/%d %d/%d %d/%d %d/%d", &id1, &tId1, &id2, &tId2, &id3, &tId3, &id4, &tId4); - if (n == 8) isFaceQuad = true; - uvsIndices.push_back(tId1-1); - uvsIndices.push_back(tId2-1); - uvsIndices.push_back(tId3-1); - if (isFaceQuad) uvsIndices.push_back(tId4-1); - } - else { - tmp = line.substr(found1+1); - found2 = (int)tmp.find("/"); - - // If the face definition is of the form "f vert1/normal1 vert2/normal2 ..." - if(found2 == 0) { - int n = sscanf(buffer.c_str(), "%*s %d//%d %d//%d %d//%d %d//%d", &id1, &nId1, &id2, &nId2, &id3, &nId3, &id4, &nId4); - if (n == 8) isFaceQuad = true; - } - // If the face definition is of the form "f vert1/textcoord1/normal1 ..." - else { - int n = sscanf(buffer.c_str(), "%*s %d/%d/%d %d/%d/%d %d/%d/%d %d/%d/%d", &id1, &tId1, &nId1, &id2, &tId2, &nId2, &id3, &tId3, &nId3, &id4, &tId4, &nId4); - if (n == 12) isFaceQuad = true; - uvsIndices.push_back(tId1-1); - uvsIndices.push_back(tId2-1); - uvsIndices.push_back(tId3-1); - if (isFaceQuad) uvsIndices.push_back(tId4-1); - } - normalsIndices.push_back(nId1-1); - normalsIndices.push_back(nId2-1); - normalsIndices.push_back(nId3-1); - if (isFaceQuad) normalsIndices.push_back(nId4-1); - } - } - verticesIndices.push_back(id1-1); - verticesIndices.push_back(id2-1); - verticesIndices.push_back(id3-1); - if (isFaceQuad) verticesIndices.push_back((id4-1)); - isQuad.push_back(isFaceQuad); - } - } - - assert(!verticesIndices.empty()); - assert(normalsIndices.empty() || normalsIndices.size() == verticesIndices.size()); - assert(uvsIndices.empty() || uvsIndices.size() == verticesIndices.size()); - meshFile.close(); - - // ---------- Merge the data that we have collected from the file ---------- // - - // Destroy the current mesh - meshToCreate.destroy(); - - // Mesh data - vector > meshIndices; - vector meshNormals; - if (!normals.empty()) meshNormals = vector(vertices.size(), Vector3(0, 0, 0)); - vector meshUVs; - if (!uvs.empty()) meshUVs = vector(vertices.size(), Vector2(0, 0)); - - // We cannot load mesh with several parts for the moment - uint meshPart = 0; - - // Fill in the vertex indices - // We also triangulate each quad face - meshIndices.push_back(std::vector()); - for(size_t i = 0, j = 0; i < verticesIndices.size(); j++) { - - // Get the current vertex IDs - uint i1 = verticesIndices[i]; - uint i2 = verticesIndices[i+1]; - uint i3 = verticesIndices[i+2]; - - // Add the vertex normal - if (!normalsIndices.empty() && !normals.empty()) { - meshNormals[i1] = normals[normalsIndices[i]]; - meshNormals[i2] = normals[normalsIndices[i+1]]; - meshNormals[i3] = normals[normalsIndices[i+2]]; - } - - // Add the vertex UV texture coordinates - if (!uvsIndices.empty() && !uvs.empty()) { - meshUVs[i1] = uvs[uvsIndices[i]]; - meshUVs[i2] = uvs[uvsIndices[i+1]]; - meshUVs[i3] = uvs[uvsIndices[i+2]]; - } - - // If the current vertex not in a quad (it is part of a triangle) - if (!isQuad[j]) { - - // Add the vertex indices - meshIndices[meshPart].push_back(i1); - meshIndices[meshPart].push_back(i2); - meshIndices[meshPart].push_back(i3); - - i+=3; - } - else { // If the current vertex is in a quad - - Vector3 v1 = vertices[i1]; - Vector3 v2 = vertices[i2]; - Vector3 v3 = vertices[i3]; - uint i4 = verticesIndices[i+3]; - Vector3 v4 = vertices[i4]; - - Vector3 v13 = v3-v1; - Vector3 v12 = v2-v1; - Vector3 v14 = v4-v1; - - float a1 = v13.dot(v12); - float a2 = v13.dot(v14); - if((a1 >= 0 && a2 <= 0) || (a1 <= 0 && a2 >= 0)) { - meshIndices[meshPart].push_back(i1); - meshIndices[meshPart].push_back(i2); - meshIndices[meshPart].push_back(i3); - meshIndices[meshPart].push_back(i1); - meshIndices[meshPart].push_back(i3); - meshIndices[meshPart].push_back(i4); - } - else { - meshIndices[meshPart].push_back(i1); - meshIndices[meshPart].push_back(i2); - meshIndices[meshPart].push_back(i4); - meshIndices[meshPart].push_back(i2); - meshIndices[meshPart].push_back(i3); - meshIndices[meshPart].push_back(i4); - } - - // Add the vertex normal - if (!normalsIndices.empty() && !normals.empty()) { - meshNormals[i4] = normals[normalsIndices[i]]; - } - - // Add the vertex UV texture coordinates - if (!uvsIndices.empty() && !uvs.empty()) { - meshUVs[i4] = uvs[uvsIndices[i]]; - } - - i+=4; - } - } - - assert(meshNormals.empty() || meshNormals.size() == vertices.size()); - assert(meshUVs.empty() || meshUVs.size() == vertices.size()); - - // Set the data to the mesh - meshToCreate.setIndices(meshIndices); - meshToCreate.setVertices(vertices); - meshToCreate.setNormals(meshNormals); - meshToCreate.setUVs(meshUVs); -} - -// Store a mesh into a OBJ file -void MeshReaderWriter::writeOBJFile(const std::string& filename, const Mesh& meshToWrite) { - std::ofstream file(filename.c_str()); - - // Geth the mesh data - const std::vector& vertices = meshToWrite.getVertices(); - const std::vector& normals = meshToWrite.getNormals(); - const std::vector& uvs = meshToWrite.getUVs(); - - // If we can open the file - if (file.is_open()) { - - assert(meshToWrite.getNbVertices() == vertices.size()); - - // Write the vertices - for (uint v=0; v& indices = meshToWrite.getIndices(p); - - // For each index of the part - for (uint i=0; i -#include -#include "Mesh.h" - -namespace openglframework { - -// Class MeshReaderWriter -// This class is used to read or write any mesh file in order to -// create the corresponding Mesh object. Currently, this class -// is able to read meshes of the current formats : .obj -class MeshReaderWriter { - - private : - - // -------------------- Methods -------------------- // - - // Constructor (private because we do not want instances of this class) - MeshReaderWriter(); - - // Load an OBJ file with a triangular or quad mesh - static void loadOBJFile(const std::string& filename, Mesh& meshToCreate); - - // Store a mesh into a OBJ file - static void writeOBJFile(const std::string& filename, const Mesh &meshToWrite); - - public : - - // -------------------- Methods -------------------- // - - // Read a mesh from a file - static void loadMeshFromFile(const std::string& filename, Mesh& meshToCreate); - - // Write a mesh to a file - static void writeMeshToFile(const std::string& filename, const Mesh& meshToWrite); -}; - -// Class VertexMergingData -// This class is used in the method to read a mesh -class VertexMergingData { - - public: - VertexMergingData() : indexPosition(0), indexNormal(0), indexUV(0) {} - unsigned int indexPosition; - unsigned int indexNormal; - unsigned int indexUV; -}; - -// Class VertexMergingDataComparison -// This class is used in the method to read a mesh -class VertexMergingDataComparison { - - public: - bool operator()(const VertexMergingData& x, const VertexMergingData& y) const { - if(x.indexPosition < y.indexPosition) - return true; - if(x.indexPosition == y.indexPosition && x.indexNormal < y.indexNormal) - return true; - if(x.indexPosition == y.indexPosition && x.indexNormal == - y.indexNormal && x.indexUV < y.indexUV) - return true; - return false; - } -}; - -} - -#endif diff --git a/examples/common/opengl-framework/src/Object3D.cpp b/examples/common/opengl-framework/src/Object3D.cpp deleted file mode 100644 index 6beb8d28..00000000 --- a/examples/common/opengl-framework/src/Object3D.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/******************************************************************************** -* OpenGL-Framework * -* Copyright (c) 2013 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -// Libraries -#include "Object3D.h" - -// Namespaces -using namespace openglframework; - -// Constructor -Object3D::Object3D() { - // Set the transformation matrix to the identity - setToIdentity(); -} - -// Destructor -Object3D::~Object3D() { - -} diff --git a/examples/common/opengl-framework/src/Object3D.h b/examples/common/opengl-framework/src/Object3D.h deleted file mode 100644 index 24c28fa1..00000000 --- a/examples/common/opengl-framework/src/Object3D.h +++ /dev/null @@ -1,149 +0,0 @@ -/******************************************************************************** -* OpenGL-Framework * -* Copyright (c) 2013 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -#ifndef OBJECT3D_H -#define OBJECT3D_H - -// Libraries -#include "maths/Vector3.h" -#include "maths/Matrix4.h" - -namespace openglframework { - -// Class Object3D -// This class represent a generic 3D object on the scene. -class Object3D { - - protected: - - // -------------------- Attributes -------------------- // - - // Transformation matrix that convert local-space - // coordinates to world-space coordinates - Matrix4 mTransformMatrix; - - public: - - // -------------------- Methods -------------------- // - - // Constructor - Object3D(); - - // Destructor - virtual ~Object3D(); - - // Return the transform matrix - const Matrix4& getTransformMatrix() const; - - // Set the transform matrix - void setTransformMatrix(const Matrix4& matrix); - - // Set to the identity transform - void setToIdentity(); - - // Return the origin of object in world-space - Vector3 getOrigin() const; - - // Translate the object in world-space - void translateWorld(const Vector3& v); - - // Translate the object in local-space - void translateLocal(const Vector3& v); - - // Rotate the object in world-space - void rotateWorld(const Vector3& axis, float angle); - - // Rotate the object in local-space - void rotateLocal(const Vector3& axis, float angle); - - // Rotate around a world-space point - void rotateAroundWorldPoint(const Vector3& axis, float angle, const Vector3& point); - - // Rotate around a local-space point - void rotateAroundLocalPoint(const Vector3& axis, float angle, const Vector3& worldPoint); -}; - -// Return the transform matrix -inline const Matrix4& Object3D::getTransformMatrix() const { - return mTransformMatrix; -} - -// Set the transform matrix -inline void Object3D::setTransformMatrix(const Matrix4& matrix) { - mTransformMatrix = matrix; -} - -// Set to the identity transform -inline void Object3D::setToIdentity() { - mTransformMatrix.setToIdentity(); -} - - // Return the origin of object in world-space -inline Vector3 Object3D::getOrigin() const { - return mTransformMatrix * Vector3(0.0, 0.0, 0.0); -} - -// Translate the object in world-space -inline void Object3D::translateWorld(const Vector3& v) { - mTransformMatrix = Matrix4::translationMatrix(v) * mTransformMatrix; -} - -// Translate the object in local-space -inline void Object3D::translateLocal(const Vector3& v) { - mTransformMatrix = mTransformMatrix * Matrix4::translationMatrix(v); -} - -// Rotate the object in world-space -inline void Object3D::rotateWorld(const Vector3& axis, float angle) { - mTransformMatrix = Matrix4::rotationMatrix(axis, angle) * mTransformMatrix; -} - -// Rotate the object in local-space -inline void Object3D::rotateLocal(const Vector3& axis, float angle) { - mTransformMatrix = mTransformMatrix * Matrix4::rotationMatrix(axis, angle); -} - -// Rotate the object around a world-space point -inline void Object3D::rotateAroundWorldPoint(const Vector3& axis, float angle, - const Vector3& worldPoint) { - mTransformMatrix = Matrix4::translationMatrix(worldPoint) * Matrix4::rotationMatrix(axis, angle) - * Matrix4::translationMatrix(-worldPoint) * mTransformMatrix; -} - -// Rotate the object around a local-space point -inline void Object3D::rotateAroundLocalPoint(const Vector3& axis, float angle, - const Vector3& worldPoint) { - - // Convert the world point into the local coordinate system - Vector3 localPoint = mTransformMatrix.getInverse() * worldPoint; - - mTransformMatrix = mTransformMatrix * Matrix4::translationMatrix(localPoint) - * Matrix4::rotationMatrix(axis, angle) - * Matrix4::translationMatrix(-localPoint); -} - -} - -#endif diff --git a/examples/common/opengl-framework/src/Shader.cpp b/examples/common/opengl-framework/src/Shader.cpp deleted file mode 100644 index 137669f7..00000000 --- a/examples/common/opengl-framework/src/Shader.cpp +++ /dev/null @@ -1,206 +0,0 @@ -/******************************************************************************** -* OpenGL-Framework * -* Copyright (c) 2013 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -// Libraries -#include "Shader.h" -#include -#include -#include - -// Namespaces -using namespace openglframework; -using namespace std; - -// Constructor -Shader::Shader() : mProgramObjectID(0) { - -} - -// Constructor with arguments -Shader::Shader(const std::string vertexShaderFilename, const std::string fragmentShaderFilename) - : mProgramObjectID(0) { - - // Create the shader - create(vertexShaderFilename, fragmentShaderFilename); -} - -// Destructor -Shader::~Shader() { - -} - -// Create the shader -bool Shader::create(const std::string vertexShaderFilename, - const std::string fragmentShaderFilename) { - - // Set the shader filenames - mFilenameVertexShader = vertexShaderFilename; - mFilenameFragmentShader = fragmentShaderFilename; - - // Check that the needed OpenGL extensions are available - bool isExtensionOK = checkOpenGLExtensions(); - if (!isExtensionOK) { - cerr << "Error : Impossible to use GLSL vertex or fragment shaders on this platform" << endl; - assert(false); - return false; - } - - // Delete the current shader - destroy(); - - assert(!vertexShaderFilename.empty() && !fragmentShaderFilename.empty()); - - // ------------------- Load the vertex shader ------------------- // - GLuint vertexShaderID; - std::ifstream fileVertexShader; - fileVertexShader.open(vertexShaderFilename.c_str(), std::ios::binary); - - if (fileVertexShader.is_open()) { - - // Get the size of the file - fileVertexShader.seekg(0, std::ios::end); - uint fileSize = (uint) (fileVertexShader.tellg()); - assert(fileSize != 0); - - // Read the file - fileVertexShader.seekg(std::ios::beg); - char* bufferVertexShader = new char[fileSize + 1]; - fileVertexShader.read(bufferVertexShader, fileSize); - fileVertexShader.close(); - bufferVertexShader[fileSize] = '\0'; - - // Create the OpenGL vertex shader and compile it - vertexShaderID = glCreateShader(GL_VERTEX_SHADER); - assert(vertexShaderID != 0); - glShaderSource(vertexShaderID, 1, (const char **) (&bufferVertexShader), NULL); - glCompileShader(vertexShaderID); - delete[] bufferVertexShader; - - // Get the compilation information - int compiled; - glGetShaderiv(vertexShaderID, GL_COMPILE_STATUS, &compiled); - - // If the compilation failed - if (compiled == 0) { - - // Get the log of the compilation - int lengthLog; - glGetShaderiv(vertexShaderID, GL_INFO_LOG_LENGTH, &lengthLog); - char* str = new char[lengthLog]; - glGetShaderInfoLog(vertexShaderID, lengthLog, NULL, str); - - // Display the log of the compilation - std::cerr << "Vertex Shader Error : " << str << std::endl; - delete[] str; - assert(false); - return false; - } - } - else { - std::cerr << "Error : Impossible to open the vertex shader file " << - vertexShaderFilename << std::endl; - assert(false); - return false; - } - - // ------------------- Load the fragment shader ------------------- // - GLuint fragmentShaderID; - std::ifstream fileFragmentShader; - fileFragmentShader.open(fragmentShaderFilename.c_str(), std::ios::binary); - - if (fileFragmentShader.is_open()) { - - // Get the size of the file - fileFragmentShader.seekg(0, std::ios::end); - uint fileSize = (uint) (fileFragmentShader.tellg()); - assert(fileSize != 0); - - // Read the file - fileFragmentShader.seekg(std::ios::beg); - char* bufferFragmentShader = new char[fileSize + 1]; - fileFragmentShader.read(bufferFragmentShader, fileSize); - fileFragmentShader.close(); - bufferFragmentShader[fileSize] = '\0'; - - // Create the OpenGL fragment shader and compile it - fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); - assert(fragmentShaderID != 0); - glShaderSource(fragmentShaderID, 1, (const char **) (&bufferFragmentShader), NULL); - glCompileShader(fragmentShaderID); - delete[] bufferFragmentShader; - - // Get the compilation information - int compiled; - glGetShaderiv(fragmentShaderID, GL_COMPILE_STATUS, &compiled); - - // If the compilation failed - if (compiled == 0) { - - // Get the log of the compilation - int lengthLog; - glGetShaderiv(fragmentShaderID, GL_INFO_LOG_LENGTH, &lengthLog); - char* str = new char[lengthLog]; - glGetShaderInfoLog(fragmentShaderID, lengthLog, NULL, str); - - // Display the log of the compilation - std::cerr << "Fragment Shader Error : " << str << std::endl; - delete[] str; - assert(false); - return false; - } - } - else { - std::cerr << "Error : Impossible to open the fragment shader file " << - fragmentShaderFilename << std::endl; - assert(false); - return false; - } - - // Create the shader program and attach the shaders - mProgramObjectID = glCreateProgram(); - assert(mProgramObjectID); - glAttachShader(mProgramObjectID, vertexShaderID); - glAttachShader(mProgramObjectID, fragmentShaderID); - glDeleteShader(vertexShaderID); - glDeleteShader(fragmentShaderID); - - // Try to link the program - glLinkProgram(mProgramObjectID); - int linked; - glGetProgramiv(mProgramObjectID, GL_LINK_STATUS, &linked); - if (!linked) { - int logLength; - glGetProgramiv(mProgramObjectID, GL_INFO_LOG_LENGTH, &logLength); - char* strLog = new char[logLength]; - glGetProgramInfoLog(mProgramObjectID, logLength, NULL, strLog); - cerr << "Linker Error in vertex shader " << vertexShaderFilename << - " or in fragment shader " << fragmentShaderFilename << " : " << strLog << endl; - delete[] strLog; - destroy(); - assert(false); - } - - return true; -} diff --git a/examples/common/opengl-framework/src/Shader.h b/examples/common/opengl-framework/src/Shader.h deleted file mode 100644 index 52a206bc..00000000 --- a/examples/common/opengl-framework/src/Shader.h +++ /dev/null @@ -1,260 +0,0 @@ -/******************************************************************************** -* OpenGL-Framework * -* Copyright (c) 2013 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -#ifndef SHADER_H -#define SHADER_H - -// Libraries -#include "definitions.h" -#include "maths/Matrix4.h" -#include "maths/Vector2.h" -#include "maths/Vector3.h" -#include "maths/Vector4.h" -#include -#include -#include - -namespace openglframework { - -// Class Shader -class Shader { - - private : - - // -------------------- Attributes -------------------- // - - // Shader object program ID - GLuint mProgramObjectID; - - // Filenames of the vertex and fragment shaders - std::string mFilenameVertexShader, mFilenameFragmentShader; - - public : - - // -------------------- Methods -------------------- // - - // Constructor - Shader(); - - // Constructor with arguments - Shader(const std::string vertexShaderFilename, const std::string fragmentShaderFilename); - - // Destructor - ~Shader(); - - // Create the shader - bool create(const std::string vertexShaderFilename, - const std::string fragmentShaderFilename); - - // Clear the shader - void destroy(); - - // Bind the shader - void bind() const; - - // Unbind the shader - void unbind() const; - - // Return the location of a uniform variable inside a shader program - int getUniformLocation(const std::string& variableName) const; - - // Set a float uniform value to this shader (be careful if the uniform is not - // used in the shader, the compiler will remove it, then when you will try - // to set it, an assert will occur) - void setFloatUniform(const std::string& variableName, float value) const; - - // Set an int uniform value to this shader (be careful if the uniform is not - // used in the shader, the compiler will remove it, then when you will try - // to set it, an assert will occur) - void setIntUniform(const std::string& variableName, int value) const; - - // Set a vector 2 uniform value to this shader (be careful if the uniform is not - // used in the shader, the compiler will remove it, then when you will try - // to set it, an assert will occur) - void setVector2Uniform(const std::string& variableName, const Vector2& v) const; - - // Set a vector 3 uniform value to this shader (be careful if the uniform is not - // used in the shader, the compiler will remove it, then when you will try - // to set it, an assert will occur) - void setVector3Uniform(const std::string& variableName, const Vector3& v) const; - - // Set a vector 4 uniform value to this shader (be careful if the uniform is not - // used in the shader, the compiler will remove it, then when you will try - // to set it, an assert will occur) - void setVector4Uniform(const std::string& variableName, const Vector4 &v) const; - - // Set a 3x3 matrix uniform value to this shader (be careful if the uniform is not - // used in the shader, the compiler will remove it, then when you will try - // to set it, an assert will occur) - void setMatrix3x3Uniform(const std::string& variableName, const float* matrix, - bool transpose = false) const; - - // Set a 3x3 matrix uniform value to this shader (be careful if the uniform is not - // used in the shader, the compiler will remove it, then when you will try - // to set it, an assert will occur) - void setMatrix3x3Uniform(const std::string& variableName, const Matrix3& matrix) const; - - // Set a 4x4 matrix uniform value to this shader (be careful if the uniform is not - // used in the shader, the compiler will remove it, then when you will try - // to set it, an assert will occur) - void setMatrix4x4Uniform(const std::string& variableName, const float* matrix, - bool transpose = false) const; - - // Set a 4x4 matrix uniform value to this shader (be careful if the uniform is not - // used in the shader, the compiler will remove it, then when you will try - // to set it, an assert will occur) - void setMatrix4x4Uniform(const std::string& variableName, const Matrix4& matrix) const; - - // Return true if the needed OpenGL extensions are available - static bool checkOpenGLExtensions(); -}; - -// Bind the shader -inline void Shader::bind() const { - assert(mProgramObjectID != 0); - glUseProgram(mProgramObjectID); -} - -// Unbind the shader -inline void Shader::unbind() const { - assert(mProgramObjectID != 0); - glUseProgram(0); -} - -// Return the location of a uniform variable inside a shader program -inline int Shader::getUniformLocation(const std::string& variableName) const { - assert(mProgramObjectID != 0); - int location = glGetUniformLocation(mProgramObjectID, variableName.c_str()); - if (location == -1) { - std::cerr << "Error in vertex shader " << mFilenameVertexShader << " or in fragment shader" - << mFilenameFragmentShader << " : No Uniform variable : " << variableName - << std::endl; - } - assert(location != -1); - return location; -} - -// Clear the shader -inline void Shader::destroy() { - glDeleteProgram(mProgramObjectID); - mProgramObjectID = 0; -} - -// Set a float uniform value to this shader (be careful if the uniform is not -// used in the shader, the compiler will remove it, then when you will try -// to set it, an assert will occur) -inline void Shader::setFloatUniform(const std::string& variableName, float value) const { - assert(mProgramObjectID != 0); - glUniform1f(getUniformLocation(variableName), value); -} - -// Set an int uniform value to this shader (be careful if the uniform is not -// used in the shader, the compiler will remove it, then when you will try -// to set it, an assert will occur) -inline void Shader::setIntUniform(const std::string& variableName, int value) const { - assert(mProgramObjectID != 0); - glUniform1i(getUniformLocation(variableName), value); -} - -// Set a vector 2 uniform value to this shader (be careful if the uniform is not -// used in the shader, the compiler will remove it, then when you will try -// to set it, an assert will occur) -inline void Shader::setVector2Uniform(const std::string& variableName, const Vector2& v) const { - assert(mProgramObjectID != 0); - glUniform2f(getUniformLocation(variableName), v.x, v.y); -} - -// Set a vector 3 uniform value to this shader (be careful if the uniform is not -// used in the shader, the compiler will remove it, then when you will try -// to set it, an assert will occur) -inline void Shader::setVector3Uniform(const std::string& variableName, const Vector3 &v) const { - assert(mProgramObjectID != 0); - glUniform3f(getUniformLocation(variableName), v.x, v.y, v.z); -} - -// Set a vector 4 uniform value to this shader (be careful if the uniform is not -// used in the shader, the compiler will remove it, then when you will try -// to set it, an assert will occur) -inline void Shader::setVector4Uniform(const std::string& variableName, const Vector4& v) const { - assert(mProgramObjectID != 0); - glUniform4f(getUniformLocation(variableName), v.x, v.y, v.z, v.w); -} - -// Set a 4x4 matrix uniform value to this shader (be careful if the uniform is not -// used in the shader, the compiler will remove it, then when you will try -// to set it, an assert will occur) -inline void Shader::setMatrix3x3Uniform(const std::string& variableName, const float* matrix, - bool transpose) const { - assert(mProgramObjectID != 0); - glUniformMatrix3fv(getUniformLocation(variableName), 1, transpose, matrix); -} - -// Set a 3x3 matrix uniform value to this shader (be careful if the uniform is not -// used in the shader, the compiler will remove it, then when you will try -// to set it, an assert will occur) -inline void Shader::setMatrix3x3Uniform(const std::string& variableName, const Matrix3& matrix) const { - assert(mProgramObjectID != 0); - GLfloat mat[9]; - for (int i=0; i<3; i++) { - for (int j=0; j<3; j++) { - mat[i*3 + j] = matrix.getValue(i, j); - } - } - glUniformMatrix3fv(getUniformLocation(variableName), 1, true, mat); -} - -// Set a 4x4 matrix uniform value to this shader (be careful if the uniform is not -// used in the shader, the compiler will remove it, then when you will try -// to set it, an assert will occur) -inline void Shader::setMatrix4x4Uniform(const std::string& variableName, const float* matrix, - bool transpose) const { - assert(mProgramObjectID != 0); - glUniformMatrix4fv(getUniformLocation(variableName), 1, transpose, matrix); -} - -// Set a 4x4 matrix uniform value to this shader (be careful if the uniform is not -// used in the shader, the compiler will remove it, then when you will try -// to set it, an assert will occur) -inline void Shader::setMatrix4x4Uniform(const std::string& variableName, const Matrix4& matrix) const { - assert(mProgramObjectID != 0); - GLfloat mat[16]; - for (int i=0; i<4; i++) { - for (int j=0; j<4; j++) { - mat[i*4 + j] = matrix.m[i][j]; - } - } - glUniformMatrix4fv(getUniformLocation(variableName), 1, true, mat); -} - -// Return true if the needed OpenGL extensions are available for shaders -inline bool Shader::checkOpenGLExtensions() { - - // Check that GLSL vertex and fragment shaders are available on the platform - return (GLEW_VERSION_2_0 || (GLEW_ARB_vertex_shader && GLEW_ARB_fragment_shader)); -} - -} - -#endif diff --git a/examples/common/opengl-framework/src/Texture2D.cpp b/examples/common/opengl-framework/src/Texture2D.cpp deleted file mode 100644 index 1b316b73..00000000 --- a/examples/common/opengl-framework/src/Texture2D.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/******************************************************************************** -* OpenGL-Framework * -* Copyright (c) 2013 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -// Libraries -#include "Texture2D.h" -#include -#include -#include - -// Namespaces -using namespace openglframework; - -// Constructor -Texture2D::Texture2D() : mID(0), mLayer(0), mWidth(0), mHeight(0) { - -} - -// Constructor -Texture2D::Texture2D(uint width, uint height, uint internalFormat, uint format, uint type) - : mID(0), mLayer(0), mWidth(0), mHeight(0){ - - // Create the texture - create(width, height, internalFormat, format, type); -} - -// Destructor -Texture2D::~Texture2D() { - -} - -// Create the texture -void Texture2D::create(uint width, uint height, uint internalFormat, uint format, uint type, - void* data) { - - // Destroy the current texture - destroy(); - - mWidth = width; - mHeight = height; - - // Create the OpenGL texture - glGenTextures(1, &mID); - assert(mID != 0); - glBindTexture(GL_TEXTURE_2D, mID); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, mWidth, mHeight, 0, format, type, data); - glBindTexture(GL_TEXTURE_2D, 0); -} - -// Destroy the texture -void Texture2D::destroy() { - if (mID != 0) { - glDeleteTextures(1, &mID); - mID = 0; - mLayer = 0; - mWidth = 0; - mHeight = 0; - } -} diff --git a/examples/common/opengl-framework/src/Texture2D.h b/examples/common/opengl-framework/src/Texture2D.h deleted file mode 100644 index 9c6fa1c0..00000000 --- a/examples/common/opengl-framework/src/Texture2D.h +++ /dev/null @@ -1,142 +0,0 @@ -/******************************************************************************** -* OpenGL-Framework * -* Copyright (c) 2013 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -#ifndef TEXTURE2D_H -#define TEXTURE2D_H - -// Libraries -#include -#include -#include "definitions.h" -#include - -namespace openglframework { - -// Class Texture2D -// This class represents a 2D texture -class Texture2D { - - private: - - // -------------------- Attributes -------------------- // - - // OpenGL texture ID - GLuint mID; - - // Layer of the texture - GLuint mLayer; - - // Width - uint mWidth; - - // Height - uint mHeight; - - public: - - // -------------------- Methods -------------------- // - - // Constructor - Texture2D(); - - // Constructor - Texture2D(uint width, uint height, uint internalFormat, uint format, uint type); - - // Destructor - ~Texture2D(); - - // Create the texture - void create(uint width, uint height, uint internalFormat, uint format, uint type, - void* data = NULL); - - // Destroy the texture - void destroy(); - - // Bind the texture - void bind() const; - - // Unbind the texture - void unbind() const; - - // Get the OpenGL texture ID - uint getID() const; - - // Get the layer of the texture - uint getLayer() const; - - // Set the layer of the texture - void setLayer(uint layer); - - // Get the width - uint getWidth() const; - - // Get the height - uint getHeight() const; -}; - -// Bind the texture -inline void Texture2D::bind() const { - assert(mID != 0); - glEnable(GL_TEXTURE_2D); - glActiveTexture(GL_TEXTURE0 + mLayer); - glBindTexture(GL_TEXTURE_2D, mID); -} - -// Unbind the texture -inline void Texture2D::unbind() const { - assert(mID != 0); - glActiveTexture(GL_TEXTURE0 + mLayer); - glBindTexture(GL_TEXTURE_2D, 0); - glDisable(GL_TEXTURE_2D); -} - -// Get the OpenGL texture ID -inline uint Texture2D::getID() const { - return mID; -} - -// Get the layer of the texture -inline uint Texture2D::getLayer() const { - return mLayer; -} - -// Set the layer of the texture -inline void Texture2D::setLayer(uint layer) { - mLayer = layer; -} - -// Get the width -inline uint Texture2D::getWidth() const { - return mWidth; -} - -// Get the height -inline uint Texture2D::getHeight() const { - return mHeight; -} - -} - -#endif diff --git a/examples/common/opengl-framework/src/TextureReaderWriter.cpp b/examples/common/opengl-framework/src/TextureReaderWriter.cpp deleted file mode 100644 index 2e09ad0c..00000000 --- a/examples/common/opengl-framework/src/TextureReaderWriter.cpp +++ /dev/null @@ -1,332 +0,0 @@ -/******************************************************************************** -* OpenGL-Framework * -* Copyright (c) 2013 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -// Librairies -#include "TextureReaderWriter.h" -#include -#ifdef USE_JPEG_TEXTURE - #include - #include -#endif - -using namespace openglframework; -using namespace std; - -// Constants -const uint TextureReaderWriter::JPEG_COMPRESSION_QUALITY = 98; - -// TGA file Header -#pragma pack(push, 1) -typedef struct { - unsigned char identsize; // size of ID field that follows 18 byte header (0 usually) - unsigned char colourmaptype; // type of colour map 0=none, 1=has palette - unsigned char imagetype; // type of image 0=none,1=indexed,2=rgb,3=grey,+8=rle packed - - short colourmapstart; // first colour map entry in palette - short colourmaplength; // number of colours in palette - unsigned char colourmapbits; // number of bits per palette entry 15,16,24,32 - - short xstart; // image x origin - short ystart; // image y origin - short width; // image width in pixels - short height; // image height in pixels - unsigned char bits; // image bits per pixel 8,16,24,32 - unsigned char descriptor; // image descriptor bits (vh flip bits) - - // pixel data follows header -} TGA_HEADER; -#pragma pack(pop) - -// Load a texture from a file -void TextureReaderWriter::loadTextureFromFile(const std::string& filename, - Texture2D& textureToCreate) { - - // Get the extension of the file - uint startPosExtension = filename.find_last_of("."); - string extension = filename.substr(startPosExtension+1); - - // Load the file using the correct method - if (extension == "tga") { - readTGAPicture(filename, textureToCreate); - } -#ifdef USE_JPEG_TEXTURE - else if (extension == "jpg" || extension == "jpeg"){ - readJPEGPicture(filename, textureToCreate); - } -#endif - else { - - // Display an error message and throw an exception - string errorMessage("Error : the TextureLoader class cannot load a file with the extension ."); - errorMessage += extension; - std::cerr << errorMessage << std::endl; - throw std::invalid_argument(errorMessage.c_str()); - } -} - -// Write a texture to a file -void TextureReaderWriter::writeTextureToFile(const std::string& filename,const Texture2D& texture) { - - // Get the extension of the file - uint startPosExtension = filename.find_last_of("."); - string extension = filename.substr(startPosExtension+1); - - // Write the file using the correct method - if (extension == "tga") { - writeTGAPicture(filename, texture); - } -#ifdef USE_JPEG_TEXTURE - else if (extension == "jpg" || extension == "jpeg"){ - writeJPEGPicture(filename, texture); - } -#endif - else { - - // Display an error message and throw an exception - string errorMessage("Error : the TextureReaderWriter class cannot write a file with the extension ."); - errorMessage += extension; - std::cerr << errorMessage << std::endl; - throw std::invalid_argument(errorMessage.c_str()); - } -} - -// Load a TGA picture -void TextureReaderWriter::readTGAPicture(const std::string &filename, Texture2D& textureToCreate) { - - // Open the file - std::ifstream stream(filename.c_str(), std::ios::binary); - - // If we cannot open the file - if(!stream.is_open()) { - - // Throw an exception and display an error message - string errorMessage("Error : Cannot open the file " + filename); - std::cerr << errorMessage << std::endl; - throw std::runtime_error(errorMessage); - } - - TGA_HEADER header; - stream.read((char *)(&header), sizeof(TGA_HEADER)); - assert(header.width <= 4096 && header.width <= 4096 && - header.imagetype == 2 && header.bits == 24); - - // Read the file - uint width = header.width; - uint height = header.width; - uint sizeImg = width*height; - char* data = new char[sizeImg*3]; - assert(data); - stream.read(data, sizeImg*3); - for(uint i = 0; i < sizeImg; i++) { - unsigned pos = i*3; - unsigned char red = data[pos]; - data[pos] = data[pos + 2]; - data[pos + 2] = red; - } - - // Close the stream - stream.close(); - - // Create the OpenGL texture using the picture data from the file - textureToCreate.create(width, height, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, data); - - // Free the data memory - delete[] data; -} - - -// Write a TGA picture -void TextureReaderWriter::writeTGAPicture(const std::string& filename, const Texture2D& texture) { - assert(texture.getID() != 0); - - // Bind the corresponding texture - glBindTexture(GL_TEXTURE_2D, texture.getID()); - - uint sizeImg = texture.getWidth() * texture.getHeight(); - - // Get the bytes form the OpenGL texture - char* data = new char[sizeImg * 3]; - glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, data); - - // Open the file - std::ofstream stream(filename.c_str(), std::ios::binary); - - // If the file cannot be opened - if(!stream.is_open()) { - - // Throw an exception and display an error message - string errorMessage("Error : Cannot create/access the file " + filename); - std::cerr << errorMessage << std::endl; - delete[] data; - throw std::runtime_error(errorMessage); - } - - // Fill in the TGA header - TGA_HEADER header; - header.identsize = 0; // size of ID field that follows 18 byte header (0 usually) - header.colourmaptype = 0; // type of colour map 0=none, 1=has palette - header.imagetype = 2; // type of image 0=none,1=indexed,2=rgb,3=grey,+8=rle packed - header.colourmapstart = 0; // first colour map entry in palette - header.colourmaplength = 0; // number of colours in palette - header.colourmapbits=0; // number of bits per palette entry 15,16,24,32 - header.xstart = 0; // image x origin - header.ystart = 0; // image y origin - header.width = (short)texture.getWidth(); // image width in pixels - header.height = (short)texture.getHeight(); // image height in pixels - header.bits = 24; // image bits per pixel 8,16,24,32 - header.descriptor = 0; // image descriptor bits (vh flip bits) - - // Write the header to the file - stream.write((char*)(&header), sizeof(TGA_HEADER)); - - // Write the bytes to the file - for(uint i = 0; i < sizeImg; i++) { - unsigned pos = i*3; - unsigned char red = data[pos]; - data[pos] = data[pos + 2]; - data[pos + 2] = red; - } - stream.write(data, sizeImg*3); - - // Close the file - stream.close(); - - // Delete the data - delete[] data; - - // Unbind the corresponding texture - glBindTexture(GL_TEXTURE_2D, 0); -} - -#ifdef USE_JPEG_TEXTURE - -// Read a JPEG picture -void TextureReaderWriter::readJPEGPicture(const std::string& filename, Texture2D& textureToCreate) { - - struct jpeg_decompress_struct info; - struct jpeg_error_mgr error; - - info.err = jpeg_std_error(&error); - jpeg_create_decompress(&info); - - // Open the file - FILE* file = fopen(filename.c_str(), "rb"); - - // If we cannot open the file - if (!file) { - - // Throw an exception and display an error message - string errorMessage("Error : Cannot open the file " + filename); - std::cerr << errorMessage << std::endl; - throw std::runtime_error(errorMessage); - } - - jpeg_stdio_src(&info, file); - jpeg_read_header(&info, true); - jpeg_start_decompress(&info); - - unsigned long x = info.output_width; - unsigned long y = info.output_height; - int channels = info.num_components; - assert(channels == 3); - - unsigned long size = x * y * 3; - - BYTE* data = new BYTE[size]; - - BYTE* p1 = data; - BYTE** p2 = &p1; - int numlines = 0; - - while(info.output_scanline < info.output_height) { - numlines = jpeg_read_scanlines(&info, p2, 1); - *p2 += numlines * 3 * info.output_width; - } - - jpeg_finish_decompress(&info); //finish decompressing this file - - // Close the file - fclose(file); - - // Create the OpenGL texture - textureToCreate.create(x, y, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, data); - - // Free allocated memory - delete[] data; -} - -// Write a JPEG picture -void TextureReaderWriter::writeJPEGPicture(const std::string& filename, const Texture2D& texture) { - - struct jpeg_compress_struct info; - struct jpeg_error_mgr error; - - info.err = jpeg_std_error(&error); - jpeg_create_compress(&info); - - // Open the file - FILE* file = fopen(filename.c_str(), "wb"); - - if (!file) { - // Throw an exception and display an error message - string errorMessage("Error : Cannot write JPEG picture into the file " + filename); - std::cerr << errorMessage << std::endl; - throw std::runtime_error(errorMessage); - } - - // Get the bytes form the OpenGL texture - char* data = new char[texture.getWidth() * texture.getHeight() * 3]; - glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, data); - - jpeg_stdio_dest(&info, file); - - info.image_width = texture.getWidth(); - info.image_height = texture.getHeight(); - info.input_components = 3; - info.in_color_space = JCS_RGB; - jpeg_set_defaults(&info); - jpeg_set_quality(&info, JPEG_COMPRESSION_QUALITY, true); - - jpeg_start_compress(&info, true); - - // Write the data into the file - JSAMPROW rowPointer; - int rowStride = texture.getWidth() * 3; - while (info.next_scanline < info.image_height) { - rowPointer = (JSAMPROW) &data[info.next_scanline * rowStride]; - jpeg_write_scanlines(&info, &rowPointer, 1); - } - - jpeg_finish_compress(&info); - jpeg_destroy_compress(&info); - - // Close the file - fclose(file); - - // Free allocated memory - delete[] data; -} - -#endif diff --git a/examples/common/opengl-framework/src/TextureReaderWriter.h b/examples/common/opengl-framework/src/TextureReaderWriter.h deleted file mode 100644 index a83b9671..00000000 --- a/examples/common/opengl-framework/src/TextureReaderWriter.h +++ /dev/null @@ -1,79 +0,0 @@ -/******************************************************************************** -* OpenGL-Framework * -* Copyright (c) 2013 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -#ifndef TEXTURE_READER_WRITER_H -#define TEXTURE_READER_WRITER_H - -// Libraries -#include "Texture2D.h" -#include -#include -#include - -namespace openglframework { - -// Class TextureReaderWriter -// This class is used to load or write a texture image in different picture format. -// It currently allows to read and write the following formats : .tga -class TextureReaderWriter { - - private : - - // ------------------- Constants ------------------- // - - // JPEG quality for compression (in percent) - static const uint JPEG_COMPRESSION_QUALITY; - - // -------------------- Methods -------------------- // - - // Constructor (private because we do not want instances of this class) - TextureReaderWriter(); - - // Read a TGA picture - static void readTGAPicture(const std::string& filename, Texture2D& textureToCreate); - - // Write a TGA picture - static void writeTGAPicture(const std::string& filename, const Texture2D& texture); - - // Read a JPEG picture - static void readJPEGPicture(const std::string& filename, Texture2D& textureToCreate); - - // Write a JPEG picture - static void writeJPEGPicture(const std::string& filename, const Texture2D& texture); - - public : - - // -------------------- Methods -------------------- // - - // Load a texture from a file - static void loadTextureFromFile(const std::string& filename, Texture2D& textureToCreate); - - // Write a texture to a file - static void writeTextureToFile(const std::string& filename, const Texture2D& texture); -}; - -} - -#endif diff --git a/examples/common/opengl-framework/src/VertexBufferObject.cpp b/examples/common/opengl-framework/src/VertexBufferObject.cpp deleted file mode 100644 index 8afd1daf..00000000 --- a/examples/common/opengl-framework/src/VertexBufferObject.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/******************************************************************************** -* OpenGL-Framework * -* Copyright (c) 2013 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -// Libraries -#include "VertexBufferObject.h" - -using namespace openglframework; - -// Constructor -VertexBufferObject::VertexBufferObject(GLenum targetData) - : mVertexBufferID(0), mTargetData(targetData) { - -} - -// Destructor -VertexBufferObject::~VertexBufferObject() { - -} - -// Create the vertex buffer object -bool VertexBufferObject::create() { - - // Destroy the current VBO - destroy(); - - // Check that the needed OpenGL extensions are available - bool isExtensionOK = checkOpenGLExtensions(); - if (!isExtensionOK) { - std::cerr << "Error : Impossible to use Vertex Buffer Object on this platform" << std::endl; - assert(false); - return false; - } - - // Generate a new VBO - glGenBuffers(1, &mVertexBufferID); - assert(mVertexBufferID != 0); - - return true; -} - -// Copy data into the VBO -void VertexBufferObject::copyDataIntoVBO(GLsizei size, const void* data, GLenum usage) { - - // Bind the VBO - bind(); - - // Copy the data into the VBO - glBufferData(mTargetData, size, data, usage); - - // Unbind the VBO - unbind(); -} - -// Destroy the VBO -void VertexBufferObject::destroy() { - - // Delete the vertex buffer object - if (mVertexBufferID) { - glDeleteFramebuffers(1, &mVertexBufferID); - mVertexBufferID = 0; - } -} diff --git a/examples/common/opengl-framework/src/VertexBufferObject.h b/examples/common/opengl-framework/src/VertexBufferObject.h deleted file mode 100644 index d697c659..00000000 --- a/examples/common/opengl-framework/src/VertexBufferObject.h +++ /dev/null @@ -1,106 +0,0 @@ -/******************************************************************************** -* OpenGL-Framework * -* Copyright (c) 2013 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -#ifndef VERTEX_BUFFER_OBJECT_H -#define VERTEX_BUFFER_OBJECT_H - -// Libraries -#include -#include -#include - -namespace openglframework { - - -// Class VertexBufferObject -class VertexBufferObject { - - private : - - // -------------------- Attributes -------------------- // - - /// ID of the Vertex Buffer Object - GLuint mVertexBufferID; - - /// Target data. This variable must be GL_ARRAY_BUFFER if the VBO contains vertex - /// data (vertex coordinates, texture coordinates, normals, colors) or must be - /// GL_ELEMENT_ARRAY_BUFFER if the VBO contains index data (index array). - GLenum mTargetData; - - public : - - // -------------------- Methods -------------------- // - - /// Constructor - VertexBufferObject(GLenum targetData); - - /// Destructor - ~VertexBufferObject(); - - /// Create the vertex buffer object - bool create(); - - /// Copy data into the VBO - void copyDataIntoVBO(GLsizei size, const void* data, GLenum usage); - - /// Bind the VBO - void bind() const; - - /// Unbind the VBO - void unbind() const; - - /// Return true if the needed OpenGL extensions are available for VBO - static bool checkOpenGLExtensions(); - - /// Destroy the VBO - void destroy(); -}; - -// Bind the VBO -inline void VertexBufferObject::bind() const { - assert(mVertexBufferID != 0); - - // Bind the VBO - glBindBuffer(mTargetData, mVertexBufferID); -} - -// Unbind the VBO -inline void VertexBufferObject::unbind() const { - assert(mVertexBufferID != 0); - - // Unbind the VBO - glBindBuffer(mTargetData, 0); -} - -// Return true if the needed OpenGL extensions are available for VBO -inline bool VertexBufferObject::checkOpenGLExtensions() { - - // Check that OpenGL version is at least 1.5 or there the vertex buffer object extension exists - return (GLEW_VERSION_1_5 || GL_ARB_vertex_buffer_object); -} - -} - -#endif diff --git a/examples/common/opengl-framework/src/definitions.h b/examples/common/opengl-framework/src/definitions.h deleted file mode 100644 index 5cacbdf4..00000000 --- a/examples/common/opengl-framework/src/definitions.h +++ /dev/null @@ -1,39 +0,0 @@ -/******************************************************************************** -* OpenGL-Framework * -* Copyright (c) 2013 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -#ifndef DEFINITIONS_H -#define DEFINITIONS_H - -namespace openglframework { - -// ------------------- Type definitions ------------------- // -typedef unsigned int uint; - -// ------------------- Constants ------------------- // -const float PI = 3.141592654f; - -} - -#endif diff --git a/examples/common/opengl-framework/src/maths/Color.h b/examples/common/opengl-framework/src/maths/Color.h deleted file mode 100644 index 3216a0a7..00000000 --- a/examples/common/opengl-framework/src/maths/Color.h +++ /dev/null @@ -1,85 +0,0 @@ -/******************************************************************************** -* OpenGL-Framework * -* Copyright (c) 2013 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -#ifndef COLOR_H -#define COLOR_H - -namespace openglframework { - -// Structure Color -// This structure represents a RGBA color. -struct Color { - - public: - - // -------------------- Attributes -------------------- // - - // RGBA color components - float r, g, b, a; - - // -------------------- Methods -------------------- // - - // Constructor - Color() : r(1), g(1), b(1), a(1) {} - - // Constructor - Color(float r, float g, float b, float a) : r(r), g(g), b(b), a(a) {} - - // Copy-constructor - Color(const Color& color) : r(color.r), g(color.g), b(color.b), a(color.a) {} - - // Destructor - ~Color() {} - - // Return the black color - static Color black() { return Color(0.0f, 0.0f, 0.0f, 1.0f);} - - // Return the white color - static Color white() { return Color(1.0f, 1.0f, 1.0f, 1.0f);} - - // Return the red color - static Color red() { return Color(1.0f, 0.0f, 0.0f, 1.0f);} - - // Return the green color - static Color green() { return Color(0.0f, 1.0f, 0.0f, 1.0f);} - - // Return the blue color - static Color blue() { return Color(0.0f, 0.0f, 1.0f, 1.0f);} - - // = operator - Color& operator=(const Color& color) { - if (&color != this) { - r = color.r; - g = color.g; - b = color.b; - a = color.a; - } - return *this; - } -}; - -} - -#endif diff --git a/examples/common/opengl-framework/src/maths/Matrix3.h b/examples/common/opengl-framework/src/maths/Matrix3.h deleted file mode 100644 index 5460f616..00000000 --- a/examples/common/opengl-framework/src/maths/Matrix3.h +++ /dev/null @@ -1,279 +0,0 @@ -/******************************************************************************** -* OpenGL-Framework * -* Copyright (c) 2013 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -#ifndef MATRIX3_H -#define MATRIX3_H - -// Libraries -#include -#include -#include "Vector3.h" - -namespace openglframework { - -// Class Matrix4 -// This class represents a 4x4 matrix -class Matrix3 { - - private : - - // -------------------- Attributes -------------------- // - - // Elements of the matrix - float m[3][3]; - - public : - - // Constructor - Matrix3() { - setToNull(); - } - - // Constructor - Matrix3(float a1, float a2, - float a3, float b1, float b2, float b3, - float c1, float c2, float c3) { - setAllValues(a1, a2, a3, b1, b2, b3, c1, c2, c3); - } - - // Constructor - Matrix3(float n[3][3]) { - m[0][0]=n[0][0]; m[0][1]=n[0][1]; m[0][2]=n[0][2]; - m[1][0]=n[1][0]; m[1][1]=n[1][1]; m[1][2]=n[1][2]; - m[2][0]=n[2][0]; m[2][1]=n[2][1]; m[2][2]=n[2][2]; - } - - // Constructor - Matrix3(const Vector3& a1, const Vector3& a2, const Vector3& a3) { - m[0][0] = a1.x; m[0][1] = a2.x; m[0][2] = a3.x; - m[1][0] = a1.y; m[1][1] = a2.y; m[1][2] = a3.y; - m[2][0] = a1.z; m[2][1] = a2.z; m[2][2] = a3.z; - } - - // Constructor - Matrix3(const Matrix3& matrix) { - setAllValues(matrix.m[0][0], matrix.m[0][1], matrix.m[0][2], - matrix.m[1][0], matrix.m[1][1], matrix.m[1][2], - matrix.m[2][0], matrix.m[2][1], matrix.m[2][2]); - } - - // Method to get a value in the matrix - float getValue(int i, int j) const { - assert(i>=0 && i<3 && j>=0 && j<3); - return m[i][j]; - } - - // Method to set a value in the matrix - void setValue(int i, int j, float value) { - assert(i>=0 && i<3 && j>=0 && j<3); - m[i][j] = value; - } - - // Method to set all the values in the matrix - void setAllValues(float a1, float a2, float a3, float b1, float b2, float b3, - float c1, float c2, float c3) { - m[0][0] = a1; m[0][1] = a2; m[0][2] = a3; - m[1][0] = b1; m[1][1] = b2; m[1][2] = b3; - m[2][0] = c1; m[2][1] = c2; m[2][2] = c3; - } - - // Return a column - Vector3 getColumn(int i) const { - assert(i>= 0 && i<3); - return Vector3(m[0][i], m[1][i], m[2][i]); - } - - // Return the transpose matrix - Matrix3 getTranspose() const { - // Return the transpose matrix - return Matrix3(m[0][0], m[1][0], m[2][0], - m[0][1], m[1][1], m[2][1], - m[0][2], m[1][2], m[2][2]); - } - - // Return the determinant of the matrix - float getDeterminant() const { - // Compute and return the determinant of the matrix - return (m[0][0]*(m[1][1]*m[2][2]-m[2][1]*m[1][2]) - m[0][1]*(m[1][0]*m[2][2]-m[2][0]*m[1][2]) + - m[0][2]*(m[1][0]*m[2][1]-m[2][0]*m[1][1])); - } - - // Return the trace of the matrix - float getTrace() const { - // Compute and return the trace - return (m[0][0] + m[1][1] + m[2][2]); - } - - void setToNull() { - m[0][0] = 0.0; m[0][1] = 0.0; m[0][2] = 0.0; - m[1][0] = 0.0; m[1][1] = 0.0; m[1][2] = 0.0; - m[2][0] = 0.0; m[2][1] = 0.0; m[2][2] = 0.0; - } - - bool isNull() const { - Matrix3 zero; - return *this == zero; - } - - // Set the matrix to the identity matrix - void setToIdentity() { - m[0][0] = 1.0; m[0][1] = 0.0; m[0][2] = 0.0; - m[1][0] = 0.0; m[1][1] = 1.0; m[1][2] = 0.0; - m[2][0] = 0.0; m[2][1] = 0.0; m[2][2] = 1.0; - } - - bool isIdentity() const { - Matrix3 I; - I.setToIdentity(); - return ( *this == I ); - } - - // Return the inverse matrix - Matrix3 getInverse() const { - - // Compute the determinant of the matrix - float determinant = getDeterminant(); - - // Check if the determinant is equal to zero - assert(determinant > std::numeric_limits::epsilon()); - - float invDeterminant = 1.0f / determinant; - Matrix3 tempMatrix((m[1][1]*m[2][2]-m[2][1]*m[1][2]), -(m[0][1]*m[2][2]-m[2][1]*m[0][2]), (m[0][1]*m[1][2]-m[0][2]*m[1][1]), - -(m[1][0]*m[2][2]-m[2][0]*m[1][2]), (m[0][0]*m[2][2]-m[2][0]*m[0][2]), -(m[0][0]*m[1][2]-m[1][0]*m[0][2]), - (m[1][0]*m[2][1]-m[2][0]*m[1][1]), -(m[0][0]*m[2][1]-m[2][0]*m[0][1]), (m[0][0]*m[1][1]-m[0][1]*m[1][0])); - - // Return the inverse matrix - return (tempMatrix * invDeterminant); - } - - // Display the matrix - void print() const { - for (int i=0; i<3; i++) { - for (int j=0; j<3; j++) { - std::cout << m[i][j] << " "; - } - std::cout << std::endl; - } - } - - // Overloaded operator = - Matrix3& operator=(const Matrix3& matrix) { - if (&matrix != this) { - setAllValues(matrix.m[0][0], matrix.m[0][1], matrix.m[0][2], - matrix.m[1][0], matrix.m[1][1], matrix.m[1][2], - matrix.m[2][0], matrix.m[2][1], matrix.m[2][2]); - } - return *this; - } - - - // Overloaded operator for addition - Matrix3 operator+(const Matrix3& matrix2) { - return Matrix3(m[0][0] + matrix2.m[0][0], m[0][1] + matrix2.m[0][1], m[0][2] + matrix2.m[0][2], - m[1][0] + matrix2.m[1][0], m[1][1] + matrix2.m[1][1], m[1][2] + matrix2.m[1][2], - m[2][0] + matrix2.m[2][0], m[2][1] + matrix2.m[2][1], m[2][2] + matrix2.m[2][2]); - } - - // Overloaded operator for substraction - Matrix3 operator-(const Matrix3& matrix2) { - return Matrix3(m[0][0] - matrix2.m[0][0], m[0][1] - matrix2.m[0][1], m[0][2] - matrix2.m[0][2], - m[1][0] - matrix2.m[1][0], m[1][1] - matrix2.m[1][1], m[1][2] - matrix2.m[1][2], - m[2][0] - matrix2.m[2][0], m[2][1] - matrix2.m[2][1], m[2][2] - matrix2.m[2][2]); - } - - // Overloaded operator for the negative of the matrix - Matrix3 operator-() { - return Matrix3(-m[0][0], -m[0][1], -m[0][2], - -m[1][0], -m[1][1], -m[1][2], - -m[2][0], -m[2][1], -m[2][2]); - } - - // Overloaded operator for multiplication with a number - Matrix3 operator*(float nb) { - return Matrix3(m[0][0] * nb, m[0][1] * nb, m[0][2] * nb, - m[1][0] * nb, m[1][1] * nb, m[1][2] * nb, - m[2][0] * nb, m[2][1] * nb, m[2][2] * nb); - } - - // Overloaded operator for matrix multiplication - Matrix3 operator*(const Matrix3& matrix2) { - return Matrix3(m[0][0]*matrix2.m[0][0] + m[0][1]*matrix2.m[1][0] + m[0][2]*matrix2.m[2][0], - m[0][0]*matrix2.m[0][1] + m[0][1]*matrix2.m[1][1] + m[0][2]*matrix2.m[2][1], - m[0][0]*matrix2.m[0][2] + m[0][1]*matrix2.m[1][2] + m[0][2]*matrix2.m[2][2], - m[1][0]*matrix2.m[0][0] + m[1][1]*matrix2.m[1][0] + m[1][2]*matrix2.m[2][0], - m[1][0]*matrix2.m[0][1] + m[1][1]*matrix2.m[1][1] + m[1][2]*matrix2.m[2][1], - m[1][0]*matrix2.m[0][2] + m[1][1]*matrix2.m[1][2] + m[1][2]*matrix2.m[2][2], - m[2][0]*matrix2.m[0][0] + m[2][1]*matrix2.m[1][0] + m[2][2]*matrix2.m[2][0], - m[2][0]*matrix2.m[0][1] + m[2][1]*matrix2.m[1][1] + m[2][2]*matrix2.m[2][1], - m[2][0]*matrix2.m[0][2] + m[2][1]*matrix2.m[1][2] + m[2][2]*matrix2.m[2][2]); - } - - // Overloaded operator for multiplication with a vector - Vector3 operator*(const Vector3& vector) { - return Vector3(m[0][0]*vector.x + m[0][1]*vector.y + m[0][2]*vector.z, - m[1][0]*vector.x + m[1][1]*vector.y + m[1][2]*vector.z, - m[2][0]*vector.x + m[2][1]*vector.y + m[2][2]*vector.z); - } - - // Overloaded operator for equality condition - bool operator==(const Matrix3& matrix) const { - return (m[0][0] == matrix.m[0][0] && m[0][1] == matrix.m[0][1] && m[0][2] == matrix.m[0][2] && - m[1][0] == matrix.m[1][0] && m[1][1] == matrix.m[1][1] && m[1][2] == matrix.m[1][2] && - m[2][0] == matrix.m[2][0] && m[2][1] == matrix.m[2][1] && m[2][2] == matrix.m[2][2]); - } - - // Overloaded operator for the is different condition - bool operator!= (const Matrix3& matrix) const { - return !(*this == matrix); - } - - // Overloaded operator for addition with assignment - Matrix3& operator+=(const Matrix3& matrix) { - m[0][0] += matrix.m[0][0]; m[0][1] += matrix.m[0][1]; m[0][2] += matrix.m[0][2]; - m[1][0] += matrix.m[1][0]; m[1][1] += matrix.m[1][1]; m[1][2] += matrix.m[1][2]; - m[2][0] += matrix.m[2][0]; m[2][1] += matrix.m[2][1]; m[2][2] += matrix.m[2][2]; - return *this; - } - - // Overloaded operator for substraction with assignment - Matrix3& operator-=(const Matrix3& matrix) { - m[0][0] -= matrix.m[0][0]; m[0][1] -= matrix.m[0][1]; m[0][2] -= matrix.m[0][2]; - m[1][0] -= matrix.m[1][0]; m[1][1] -= matrix.m[1][1]; m[1][2] -= matrix.m[1][2]; - m[2][0] -= matrix.m[2][0]; m[2][1] -= matrix.m[2][1]; m[2][2] -= matrix.m[2][2]; - return *this; - } - - // Overloaded operator for multiplication with a number with assignment - Matrix3& operator*=(float nb) { - m[0][0] *= nb; m[0][1] *= nb; m[0][2] *= nb; - m[1][0] *= nb; m[1][1] *= nb; m[1][2] *= nb; - m[2][0] *= nb; m[2][1] *= nb; m[2][2] *= nb; - return *this; - } -}; - -} - -#endif diff --git a/examples/common/opengl-framework/src/maths/Matrix4.h b/examples/common/opengl-framework/src/maths/Matrix4.h deleted file mode 100644 index bcfbcebd..00000000 --- a/examples/common/opengl-framework/src/maths/Matrix4.h +++ /dev/null @@ -1,427 +0,0 @@ -/******************************************************************************** -* OpenGL-Framework * -* Copyright (c) 2013 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -#ifndef MATRIX4_H -#define MATRIX4_H - -// Libraries -#include -#include -#include -#include "Vector3.h" -#include "Vector4.h" -#include "Matrix3.h" - -namespace openglframework { - -// Class Matrix4 -// This class represents a 4x4 matrix -class Matrix4 { - - public: - - // -------------------- Attributes -------------------- // - - // Elements of the matrix - float m[4][4]; - - // -------------------- Methods -------------------- // - - // Constructor - Matrix4(float m_00=0, float m_01=0, float m_02=0, float m_03=0, - float m_10=0, float m_11=0, float m_12=0, float m_13=0, - float m_20=0, float m_21=0, float m_22=0, float m_23=0, - float m_30=0, float m_31=0, float m_32=0, float m_33=0) { - m[0][0] = m_00; m[0][1] = m_01; m[0][2] = m_02; m[0][3] = m_03; - m[1][0] = m_10; m[1][1] = m_11; m[1][2] = m_12; m[1][3] = m_13; - m[2][0] = m_20; m[2][1] = m_21; m[2][2] = m_22; m[2][3] = m_23; - m[3][0] = m_30; m[3][1] = m_31; m[3][2] = m_32; m[3][3] = m_33; - } - - // Constructor - Matrix4(float n[4][4]) { - m[0][0]=n[0][0]; m[0][1]=n[0][1]; m[0][2]=n[0][2]; m[0][3]=n[0][3]; - m[1][0]=n[1][0]; m[1][1]=n[1][1]; m[1][2]=n[1][2]; m[1][3]=n[1][3]; - m[2][0]=n[2][0]; m[2][1]=n[2][1]; m[2][2]=n[2][2]; m[2][3]=n[2][3]; - m[3][0]=n[3][0]; m[3][1]=n[3][1]; m[3][2]=n[3][2]; m[3][3]=n[3][3]; - } - - // Constructor - Matrix4(const Vector3& a1, const Vector3& a2, const Vector3& a3) { - m[0][0] = a1.x; m[0][1] = a2.x; m[0][2] = a3.x; m[0][3] = 0.f; - m[1][0] = a1.y; m[1][1] = a2.y; m[1][2] = a3.y; m[1][3] = 0.f; - m[2][0] = a1.z; m[2][1] = a2.z; m[2][2] = a3.z; m[2][3] = 0.f; - m[3][0] = 0.f; m[3][1] = 0.f; m[3][2] = 0.f; m[3][3] = 1.f; - } - - // Constructor - Matrix4(const Vector4& a1, const Vector4& a2, const Vector4& a3) { - m[0][0] = a1.x; m[0][1] = a2.x; m[0][2] = a3.x; m[0][3] = 0.f; - m[1][0] = a1.y; m[1][1] = a2.y; m[1][2] = a3.y; m[1][3] = 0.f; - m[2][0] = a1.z; m[2][1] = a2.z; m[2][2] = a3.z; m[2][3] = 0.f; - m[3][0] = a1.w; m[3][1] = a2.w; m[3][2] = a3.w; m[3][3] = 1.f; - } - - // Constructor - Matrix4(const Matrix4& matrix) { - - setAllValues(matrix.m[0][0], matrix.m[0][1], matrix.m[0][2], matrix.m[0][3], - matrix.m[1][0], matrix.m[1][1], matrix.m[1][2], matrix.m[1][3], - matrix.m[2][0], matrix.m[2][1], matrix.m[2][2], matrix.m[2][3], - matrix.m[3][0], matrix.m[3][1], matrix.m[3][2], matrix.m[3][3]); - } - - // + operator - Matrix4 operator+(const Matrix4 &n) const { - return Matrix4(m[0][0]+n.m[0][0], m[0][1]+n.m[0][1], m[0][2]+n.m[0][2], m[0][3]+n.m[0][3], - m[1][0]+n.m[1][0], m[1][1]+n.m[1][1], m[1][2]+n.m[1][2], m[1][3]+n.m[1][3], - m[2][0]+n.m[2][0], m[2][1]+n.m[2][1], m[2][2]+n.m[2][2], m[2][3]+n.m[2][3], - m[3][0]+n.m[3][0], m[3][1]+n.m[3][1], m[3][2]+n.m[3][2], m[3][3]+n.m[3][3]); - } - - // += operator - Matrix4& operator+=(const Matrix4 &n) { - m[0][0]+=n.m[0][0]; m[0][1]+=n.m[0][1]; m[0][2]+=n.m[0][2]; m[0][3]+=n.m[0][3]; - m[1][0]+=n.m[1][0]; m[1][1]+=n.m[1][1]; m[1][2]+=n.m[1][2]; m[1][3]+=n.m[1][3]; - m[2][0]+=n.m[2][0]; m[2][1]+=n.m[2][1]; m[2][2]+=n.m[2][2]; m[2][3]+=n.m[2][3]; - m[3][0]+=n.m[3][0]; m[3][1]+=n.m[3][1]; m[3][2]+=n.m[3][2]; m[3][3]+=n.m[3][3]; - return *this; - } - - // - operator - Matrix4 operator-(const Matrix4 &n) const { - return Matrix4(m[0][0]-n.m[0][0], m[0][1]-n.m[0][1], m[0][2]-n.m[0][2], m[0][3]-n.m[0][3], - m[1][0]-n.m[1][0], m[1][1]-n.m[1][1], m[1][2]-n.m[1][2], m[1][3]-n.m[1][3], - m[2][0]-n.m[2][0], m[2][1]-n.m[2][1], m[2][2]-n.m[2][2], m[2][3]-n.m[2][3], - m[3][0]-n.m[3][0], m[3][1]-n.m[3][1], m[3][2]-n.m[3][2], m[3][3]-n.m[3][3]); - } - - // -= operator - Matrix4& operator-=(const Matrix4 &n) { - m[0][0]-=n.m[0][0]; m[0][1]-=n.m[0][1]; m[0][2]-=n.m[0][2]; m[0][3]-=n.m[0][3]; - m[1][0]-=n.m[1][0]; m[1][1]-=n.m[1][1]; m[1][2]-=n.m[1][2]; m[1][3]-=n.m[1][3]; - m[2][0]-=n.m[2][0]; m[2][1]-=n.m[2][1]; m[2][2]-=n.m[2][2]; m[2][3]-=n.m[2][3]; - m[3][0]-=n.m[3][0]; m[3][1]-=n.m[3][1]; m[3][2]-=n.m[3][2]; m[3][3]-=n.m[3][3]; - return *this; - } - - // = operator - Matrix4& operator=(const Matrix4& matrix) { - if (&matrix != this) { - setAllValues(matrix.m[0][0], matrix.m[0][1], matrix.m[0][2], matrix.m[0][3], - matrix.m[1][0], matrix.m[1][1], matrix.m[1][2], matrix.m[1][3], - matrix.m[2][0], matrix.m[2][1], matrix.m[2][2], matrix.m[2][3], - matrix.m[3][0], matrix.m[3][1], matrix.m[3][2], matrix.m[3][3]); - } - return *this; - } - - // == operator - bool operator==(const Matrix4 &n) const { - return m[0][0]==n.m[0][0] && m[0][1]==n.m[0][1] && m[0][2]==n.m[0][2] && m[0][3]==n.m[0][3] && - m[1][0]==n.m[1][0] && m[1][1]==n.m[1][1] && m[1][2]==n.m[1][2] && m[1][3]==n.m[1][3] && - m[2][0]==n.m[2][0] && m[2][1]==n.m[2][1] && m[2][2]==n.m[2][2] && m[2][3]==n.m[2][3] && - m[3][0]==n.m[3][0] && m[3][1]==n.m[3][1] && m[3][2]==n.m[3][2] && m[3][3]==n.m[3][3]; - } - - // * operator - Matrix4 operator*(const Matrix4 &n) const { - Matrix4 o; - for(int i = 0; i < 4; i++) { - for(int j = 0; j < 4; j++) { - float v = 0; - for(int k = 0; k < 4; k++) { - v += m[i][k] * n.m[k][j]; - } - o.m[i][j] = v; - } - } - return o; - } - - // * operator - Vector3 operator*(const Vector3 &v) const { - Vector3 u =Vector3(m[0][0]*v.x + m[0][1]*v.y + m[0][2]*v.z + m[0][3], - m[1][0]*v.x + m[1][1]*v.y + m[1][2]*v.z + m[1][3], - m[2][0]*v.x + m[2][1]*v.y + m[2][2]*v.z + m[2][3]); - float w = m[3][0]*v.x + m[3][1]*v.y + m[3][2]*v.z + m[3][3]; - return u/w; - } - - // * operator - Vector4 operator*(const Vector4 &v) const { - Vector4 u = Vector4(m[0][0]*v.x + m[0][1]*v.y + m[0][2]*v.z + v.w*m[0][3], - m[1][0]*v.x + m[1][1]*v.y + m[1][2]*v.z + v.w*m[1][3], - m[2][0]*v.x + m[2][1]*v.y + m[2][2]*v.z + v.w*m[2][3], - m[3][0]*v.x + m[3][1]*v.y + m[3][2]*v.z + v.w*m[3][3]); - if(u.w != 0) - return u/u.w; - else - return u; - } - - // * operator - Matrix4 operator*(float f) const { - return Matrix4(m[0][0]*f, m[0][1]*f, m[0][2]*f, m[0][3]*f, - m[1][0]*f, m[1][1]*f, m[1][2]*f, m[1][3]*f, - m[2][0]*f, m[2][1]*f, m[2][2]*f, m[2][3]*f, - m[3][0]*f, m[3][1]*f, m[3][2]*f, m[3][3]*f); - } - - // * operator - Matrix4 &operator*=(float f) { - m[0][0]*=f; m[0][1]*=f; m[0][2]*=f; m[0][3]*=f; - m[1][0]*=f; m[1][1]*=f; m[1][2]*=f; m[1][3]*=f; - m[2][0]*=f; m[2][1]*=f; m[2][2]*=f; m[2][3]*=f; - m[3][0]*=f; m[3][1]*=f; m[3][2]*=f; m[3][3]*=f; - return *this; - } - - // / operator - Matrix4 operator/(float f) const { - assert(f!=0); - return Matrix4(m[0][0]/f, m[0][1]/f, m[0][2]/f, m[0][3]/f, - m[1][0]/f, m[1][1]/f, m[1][2]/f, m[1][3]/f, - m[2][0]/f, m[2][1]/f, m[2][2]/f, m[2][3]/f, - m[3][0]/f, m[3][1]/f, m[3][2]/f, m[3][3]/f); - } - - // /= operator - Matrix4 &operator/=(float f) { - assert(f!=0); - m[0][0]/=f; m[0][1]/=f; m[0][2]/=f; m[0][3]/=f; - m[1][0]/=f; m[1][1]/=f; m[1][2]/=f; m[1][3]/=f; - m[2][0]/=f; m[2][1]/=f; m[2][2]/=f; m[2][3]/=f; - m[3][0]/=f; m[3][1]/=f; m[3][2]/=f; m[3][3]/=f; - return *this; - } - - // - operator - Matrix4 operator-() const { - return Matrix4(-m[0][0], -m[0][1], -m[0][2], -m[0][3], - -m[1][0], -m[1][1], -m[1][2], -m[1][3], - -m[2][0], -m[2][1], -m[2][2], -m[2][3], - -m[3][0], -m[3][1], -m[3][2], -m[3][3]); - } - - // Return the transpose matrix - Matrix4 getTranspose() const { - return Matrix4(m[0][0], m[1][0], m[2][0], m[3][0], - m[0][1], m[1][1], m[2][1], m[3][1], - m[0][2], m[1][2], m[2][2], m[3][2], - m[0][3], m[1][3], m[2][3], m[3][3]); - } - - // Return the 3x3 upper-left matrix - Matrix3 getUpperLeft3x3Matrix() const { - return Matrix3(m[0][0], m[0][1], m[0][2], - m[1][0], m[1][1], m[1][2], - m[2][0], m[2][1], m[2][2]); - } - - // Return the inversed matrix - Matrix4 getInverse() const { - int indxc[4], indxr[4]; - int ipiv[4] = { 0, 0, 0, 0 }; - float minv[4][4]; - float temp; - - for (int s=0; s<4; s++) { - for (int t=0; t<4; t++) { - minv[s][t] = m[s][t]; - } - } - - for (int i = 0; i < 4; i++) { - int irow = -1, icol = -1; - float big = 0.; - // Choose pivot - for (int j = 0; j < 4; j++) { - if (ipiv[j] != 1) { - for (int k = 0; k < 4; k++) { - if (ipiv[k] == 0) { - if (fabs(minv[j][k]) >= big) { - big = float(fabs(minv[j][k])); - irow = j; - icol = k; - } - } - else if (ipiv[k] > 1) { - std::cout << "ERROR: Singular matrix in MatrixInvert\n"; - } - } - } - } - ++ipiv[icol]; - // Swap rows _irow_ and _icol_ for pivot - if (irow != icol) { - for (int k = 0; k < 4; ++k){ - temp = minv[irow][k]; - minv[irow][k] = minv[icol][k]; - minv[icol][k] = temp; - } - } - indxr[i] = irow; - indxc[i] = icol; - if (minv[icol][icol] == 0.){ - std::cout << "Singular matrix in MatrixInvert\n"; - } - // Set $m[icol][icol]$ to one by scaling row _icol_ appropriately - float pivinv = 1.f / minv[icol][icol]; - minv[icol][icol] = 1.f; - for (int j = 0; j < 4; j++) { - minv[icol][j] *= pivinv; - } - - // Subtract this row from others to zero out their columns - for (int j = 0; j < 4; j++) { - if (j != icol) { - float save = minv[j][icol]; - minv[j][icol] = 0; - for (int k = 0; k < 4; k++) { - minv[j][k] -= minv[icol][k]*save; - } - } - } - } - // Swap columns to reflect permutation - for (int j = 3; j >= 0; j--) { - if (indxr[j] != indxc[j]) { - for (int k = 0; k < 4; k++){ - temp = minv[k][indxr[j]]; - minv[k][indxr[j]] = minv[k][indxc[j]]; - minv[k][indxc[j]] = temp; - } - } - } - return Matrix4(minv); - } - - // Method to set all the values in the matrix - void setAllValues(float a1, float a2, float a3, float a4, - float b1, float b2, float b3, float b4, - float c1, float c2, float c3, float c4, - float d1, float d2, float d3, float d4) { - m[0][0] = a1; m[0][1] = a2; m[0][2] = a3, m[0][3] = a4; - m[1][0] = b1; m[1][1] = b2; m[1][2] = b3; m[1][3] = b4; - m[2][0] = c1; m[2][1] = c2; m[2][2] = c3; m[2][3] = c4; - m[3][0] = d1; m[3][1] = d2; m[3][2] = d3; m[3][3] = d4; - } - - // Set the matrix to the identity matrix - Matrix4 setToIdentity() { - m[0][0] = 1.f; m[0][1] = 0.f; m[0][2] = 0.f; m[0][3] = 0.f; - m[1][0] = 0.f; m[1][1] = 1.f; m[1][2] = 0.f; m[1][3] = 0.f; - m[2][0] = 0.f; m[2][1] = 0.f; m[2][2] = 1.f; m[2][3] = 0.f; - m[3][0] = 0.f; m[3][1] = 0.f; m[3][2] = 0.f; m[3][3] = 1.f; - return *this; - } - - // Display the matrix - void print() const { - for (int i=0; i<4; i++) { - for (int j=0; j<4; j++) { - std::cout << m[i][j]; - } - std::cout << std::endl; - } - } - - // Return the pointer to the data array of the matrix - float* dataBlock() { - return m[0]; - } - - // Return the constant pointer to the data array of the matrix - const float* dataBlock() const { - return m[0]; - } - - // Return a given value from the matrix - float getValue(int i, int j) const { - assert(i >= 0 && i<4 && j >= 0 && j<4); - return m[i][j]; - } - - // Return the trace of the matrix - float getTrace() const { - // Compute and return the trace - return (m[0][0] + m[1][1] + m[2][2] + m[3][3]); - } - - // Return a 4x4 translation matrix - static Matrix4 translationMatrix(const Vector3& v); - - // Return a 4x4 rotation matrix - static Matrix4 rotationMatrix(const Vector3& axis, float angle); -}; - -// * operator -inline Matrix4 operator*(float f, const Matrix4 & m) { - return (m * f); -} - -// Return a 4x4 translation matrix -inline Matrix4 Matrix4::translationMatrix(const Vector3& v) { - return Matrix4(1, 0, 0, v.x, - 0, 1, 0, v.y, - 0, 0, 1, v.z, - 0, 0, 0, 1); -} - -// Return a 4x4 rotation matrix -inline Matrix4 Matrix4::rotationMatrix(const Vector3& axis, float angle) { - - float cosA = cos(angle); - float sinA = sin(angle); - Matrix4 rotationMatrix; - rotationMatrix.setToIdentity(); - - rotationMatrix.m[0][0] = cosA + (1-cosA) * axis.x * axis.x; - rotationMatrix.m[0][1] = (1-cosA) * axis.x * axis.y - axis.z * sinA; - rotationMatrix.m[0][2] = (1-cosA) * axis.x * axis.z + axis.y * sinA; - rotationMatrix.m[0][3] = 0.f; - - rotationMatrix.m[1][0] = (1-cosA) * axis.x * axis.y + axis.z * sinA; - rotationMatrix.m[1][1] = cosA + (1-cosA) * axis.y * axis.y; - rotationMatrix.m[1][2] = (1-cosA) * axis.y * axis.z - axis.x * sinA; - rotationMatrix.m[1][3] = 0.f; - - rotationMatrix.m[2][0] = (1-cosA) * axis.x * axis.z - axis.y * sinA; - rotationMatrix.m[2][1] = (1-cosA) * axis.y * axis.z + axis.x * sinA; - rotationMatrix.m[2][2] = cosA + (1-cosA) * axis.z * axis.z; - rotationMatrix.m[2][3] = 0.f; - - rotationMatrix.m[3][0] = 0.f; - rotationMatrix.m[3][1] = 0.f; - rotationMatrix.m[3][2] = 0.f; - rotationMatrix.m[3][3] = 1.f; - - return rotationMatrix; -} - -} - -#endif //_MATRIX4_H diff --git a/examples/common/opengl-framework/src/maths/Vector2.h b/examples/common/opengl-framework/src/maths/Vector2.h deleted file mode 100644 index 0bc0eb9c..00000000 --- a/examples/common/opengl-framework/src/maths/Vector2.h +++ /dev/null @@ -1,159 +0,0 @@ -/******************************************************************************** -* OpenGL-Framework * -* Copyright (c) 2013 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -#ifndef VECTOR2_H -#define VECTOR2_H - -// Libraries -#include -#include - -namespace openglframework { - -// Class Vector2 -// This class represents a 2D vector. -class Vector2 { - - public: - - // -------------------- Attributes -------------------- // - - // Components of the vector - float x, y; - - - // -------------------- Methods -------------------- // - - // Constructor - Vector2(float x=0, float y=0) : x(x), y(y) {} - - // Constructor - Vector2(const Vector2& vector) : x(vector.x), y(vector.y) {} - - // + operator - Vector2 operator+(const Vector2 &v) const { - return Vector2(x + v.x, y + v.y); - } - - // += operator - Vector2& operator+=(const Vector2 &v) { - x += v.x; y += v.y; - return *this; - } - - // - operator - Vector2 operator-(const Vector2 &v) const { - return Vector2(x - v.x, y - v.y); - } - - // -= operator - Vector2& operator-=(const Vector2 &v) { - x -= v.x; y -= v.y; - return *this; - } - - // = operator - Vector2& operator=(const Vector2& vector) { - if (&vector != this) { - x = vector.x; - y = vector.y; - } - return *this; - } - - // == operator - bool operator==(const Vector2 &v) const { - return x == v.x && y == v.y; - } - - // * operator - Vector2 operator*(float f) const { - return Vector2(f*x, f*y); - } - - // *= operator - Vector2 &operator*=(float f) { - x *= f; y *= f; - return *this; - } - - // / operator - Vector2 operator/(float f) const { - assert(f!=0); - float inv = 1.f / f; - return Vector2(x * inv, y * inv); - } - - // /= operator - Vector2 &operator/=(float f) { - assert(f!=0); - float inv = 1.f / f; - x *= inv; y *= inv; - return *this; - } - - // - operator - Vector2 operator-() const { - return Vector2(-x, -y); - } - - // [] operator - float &operator[](int i) { - assert(i >= 0 && i <= 1); - switch (i) { - case 0: return x; - case 1: return y; - } - return y; - } - - // Normalize the vector and return it - Vector2 normalize() { - float l = length(); - assert(l > 0); - x /= l; - y /= l; - return *this; - } - - // Clamp the vector values between 0 and 1 - Vector2 clamp01() { - if (x>1.f) x=1.f; - else if (x<0.f) x=0.f; - if (y>1.f) y=1.f; - else if (y<0.f) y=0.f; - return *this; - } - - // Return the squared length of the vector - float lengthSquared() const { return x*x + y*y; } - - // Return the length of the vector - float length() const { return sqrt(lengthSquared()); } -}; - -} - -#endif diff --git a/examples/common/opengl-framework/src/maths/Vector3.h b/examples/common/opengl-framework/src/maths/Vector3.h deleted file mode 100644 index adeecb7c..00000000 --- a/examples/common/opengl-framework/src/maths/Vector3.h +++ /dev/null @@ -1,203 +0,0 @@ -/******************************************************************************** -* OpenGL-Framework * -* Copyright (c) 2013 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -#ifndef OPENGLFRAMEWORK_VECTOR3_H -#define OPENGLFRAMEWORK_VECTOR3_H - -// Libraries -#include -#include -#include - -namespace openglframework { - -// Class Vector3 -// This class represents a 3D vector. -class Vector3 { - - public: - - // -------------------- Attributes -------------------- // - - // Components of the vector - float x, y, z; - - // -------------------- Methods -------------------- // - - // Constructor - Vector3(float x=0, float y=0, float z=0) : x(x), y(y), z(z) {} - - // Constructor - Vector3(const Vector3& vector) : x(vector.x), y(vector.y), z(vector.z) {} - - // Constructor - ~Vector3() {} - - // = operator - Vector3& operator=(const Vector3& vector) { - if (&vector != this) { - x = vector.x; - y = vector.y; - z = vector.z; - } - return *this; - } - - // + operator - Vector3 operator+(const Vector3 &v) const { - return Vector3(x + v.x, y + v.y, z + v.z); - } - - // += operator - Vector3& operator+=(const Vector3 &v) { - x += v.x; y += v.y; z += v.z; - return *this; - } - - // - operator - Vector3 operator-(const Vector3 &v) const { - return Vector3(x - v.x, y - v.y, z - v.z); - } - - // -= operator - Vector3& operator-=(const Vector3 &v) { - x -= v.x; y -= v.y; z -= v.z; - return *this; - } - - // == operator - bool operator==(const Vector3 &v) const { - return x == v.x && y == v.y && z == v.z; - } - - // != operator - bool operator!=(const Vector3 &v) const { - return !( *this == v ); - } - - // * operator - Vector3 operator*(float f) const { - return Vector3(f*x, f*y, f*z); - } - - // *= operator - Vector3 &operator*=(float f) { - x *= f; y *= f; z *= f; - return *this; - } - - // / operator - Vector3 operator/(float f) const { - assert(f > std::numeric_limits::epsilon() ); - float inv = 1.f / f; - return Vector3(x * inv, y * inv, z * inv); - } - - // /= operator - Vector3 &operator/=(float f) { - assert(f > std::numeric_limits::epsilon()); - float inv = 1.f / f; - x *= inv; y *= inv; z *= inv; - return *this; - } - - // - operator - Vector3 operator-() const { - return Vector3(-x, -y, -z); - } - - // [] operator - float &operator[](int i) { - assert(i >= 0 && i <= 2); - switch (i) { - case 0: return x; - case 1: return y; - case 2: return z; - } - return z; - } - - // [] operator - const float &operator[](int i) const { - assert(i >= 0 && i <= 2); - switch (i) { - case 0: return x; - case 1: return y; - case 2: return z; - } - return z; - } - - // Cross product operator - Vector3 cross(const Vector3 &v) const{ - return Vector3(y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x); - } - - // Dot product operator - float dot(const Vector3 &v) const{ - return x * v.x + y * v.y + z * v.z; - } - - // Normalize the vector and return it - Vector3 normalize() { - float l = length(); - if(l < std::numeric_limits::epsilon() ) { - assert(false); - } - x /= l; - y /= l; - z /= l; - return *this; - } - - bool isNull() const { - return( x == 0. && y == 0. && z == 0. ); - } - - // Clamp the values between 0 and 1 - Vector3 clamp01() { - if (x>1.f) x=1.f; - else if (x<0.f) x=0.f; - if (y>1.f) y=1.f; - else if (y<0.f) y=0.f; - if (z>1.f) z=1.f; - else if (z<0.f) z=0.f; - return *this; - } - - // Return the squared length of the vector - float lengthSquared() const { return x*x + y*y + z*z; } - - // Return the length of the vector - float length() const { return sqrt(lengthSquared()); } -}; - -inline Vector3 operator*(float f, const Vector3 & o) { - return o*f; -} - -} - -#endif diff --git a/examples/common/opengl-framework/src/maths/Vector4.h b/examples/common/opengl-framework/src/maths/Vector4.h deleted file mode 100644 index 3c4002d8..00000000 --- a/examples/common/opengl-framework/src/maths/Vector4.h +++ /dev/null @@ -1,167 +0,0 @@ -/******************************************************************************** -* OpenGL-Framework * -* Copyright (c) 2013 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -#ifndef VECTOR4_H -#define VECTOR4_H - -// Libraries -#include -#include - -namespace openglframework { - -// Class Vector4 -// This class represents a 4D vector. -class Vector4 { - - public: - - // -------------------- Attributes -------------------- // - - // Components of the vector - float x, y, z, w; - - // -------------------- Methods -------------------- // - - // Constructor - Vector4(float x=0, float y=0, float z=0, float w=0) : x(x), y(y), z(z), w(w) {} - - // Constructor - Vector4(const Vector4& vector) : x(vector.x), y(vector.y), z(vector.z), w(vector.w) {} - - // + operator - Vector4 operator+(const Vector4 &v) const { - return Vector4(x + v.x, y + v.y, z + v.z, w + v.w); - } - - // += operator - Vector4& operator+=(const Vector4 &v) { - x += v.x; y += v.y; z += v.z; w += v.w; - return *this; - } - - // - operator - Vector4 operator-(const Vector4 &v) const { - return Vector4(x - v.x, y - v.y, z - v.z, w - v.w); - } - - // -= operator - Vector4& operator-=(const Vector4 &v) { - x -= v.x; y -= v.y; z -= v.z, w -=v.w; - return *this; - } - - // = operator - Vector4& operator=(const Vector4& vector) { - if (&vector != this) { - x = vector.x; - y = vector.y; - z = vector.z; - w = vector.w; - } - return *this; - } - - // == operator - bool operator==(const Vector4 &v) const { - return x == v.x && y == v.y && z == v.z && w == v.w; - } - - // * operator - Vector4 operator*(float f) const { - return Vector4(f*x, f*y, f*z, f*w); - } - - // *= operator - Vector4 &operator*=(float f) { - x *= f; y *= f; z *= f; w *= f; - return *this; - } - - // / operator - Vector4 operator/(float f) const { - assert(f!=0); - float inv = 1.f / f; - return Vector4(x * inv, y * inv, z * inv, w * inv); - } - - // /= operator - Vector4 &operator/=(float f) { - assert(f!=0); - float inv = 1.f / f; - x *= inv; y *= inv; z *= inv; w *= inv; - return *this; - } - - // - operator - Vector4 operator-() const { - return Vector4(-x, -y, -z, -w); - } - - // [] operator - float &operator[](int i) { - assert(i >= 0 && i <= 3); - switch (i) { - case 0: return x; - case 1: return y; - case 2: return z; - case 3: return w; - } - return w; - } - - // Dot product operator - float dot(const Vector4 &v) const { - return x * v.x + y * v.y + z * v.z + w * v.w; - } - - // Multiply two vectors by their components - Vector4 componentMul(const Vector4 &v) const { - return Vector4(x * v.x, y * v.y, z * v.z, w * v.w); - } - - // Clamp the values between 0 and 1 - Vector4 clamp01() { - if (x>1.f) x=1.f; - else if (x<0.f) x=0.f; - if (y>1.f) y=1.f; - else if (y<0.f) y=0.f; - if (z>1.f) z=1.f; - else if (z<0.f) z=0.f; - if (w>1.f) w=1.f; - else if (w<0.f) w=0.f; - return *this; - } - - // Return the squared length of the vector - float lengthSquared() const { return x * x + y * y + z * z + w * w; } - - // Return the length of the vector - float length() const { return sqrt(lengthSquared()); } -}; - -} - -#endif //_VECTOR4_H diff --git a/examples/common/opengl-framework/src/openglframework.h b/examples/common/opengl-framework/src/openglframework.h deleted file mode 100644 index 4ac735d8..00000000 --- a/examples/common/opengl-framework/src/openglframework.h +++ /dev/null @@ -1,48 +0,0 @@ -/******************************************************************************** -* OpenGL-Framework * -* Copyright (c) 2013 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -#ifndef OPENGL_FRAMEWORK_H -#define OPENGL_FRAMEWORK_H - -// Libraries -#include "MeshReaderWriter.h" -#include "TextureReaderWriter.h" -#include "Camera.h" -#include "Light.h" -#include "Mesh.h" -#include "Shader.h" -#include "Texture2D.h" -#include "FrameBufferObject.h" -#include "VertexBufferObject.h" -#include "Shader.h" -#include "maths/Color.h" -#include "maths/Vector2.h" -#include "maths/Vector3.h" -#include "maths/Vector4.h" -#include "maths/Matrix4.h" -#include "maths/Matrix3.h" -#include "definitions.h" - -#endif diff --git a/examples/common/opengl-framework/src/shaders/depth.frag b/examples/common/opengl-framework/src/shaders/depth.frag deleted file mode 100644 index 4ef97b32..00000000 --- a/examples/common/opengl-framework/src/shaders/depth.frag +++ /dev/null @@ -1,32 +0,0 @@ -/******************************************************************************** -* OpenGL-Framework * -* Copyright (c) 2013 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -void main(void) { - - // Compute the depth of the pixel - float depth = - - gl_FragColor = vec4(depth, depth, depth, 1); -} diff --git a/examples/common/opengl-framework/src/shaders/depth.vert b/examples/common/opengl-framework/src/shaders/depth.vert deleted file mode 100644 index f320cc72..00000000 --- a/examples/common/opengl-framework/src/shaders/depth.vert +++ /dev/null @@ -1,36 +0,0 @@ -/******************************************************************************** -* OpenGL-Framework * -* Copyright (c) 2013 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -// Uniform variables -uniform mat4 modelToWorldMatrix; // Model too world coordinates matrix -uniform mat4 worldToCameraMatrix; // World to camera coordinates matrix -uniform mat4 projectionMatrix; // Projection matrix - -void main(void) { - - // Compute the clip-space vertex coordinates - gl_Position = projectionMatrix * worldToCameraMatrix * - modelToWorldMatrix * gl_Vertex; -} diff --git a/examples/common/opengl-framework/src/shaders/phong.frag b/examples/common/opengl-framework/src/shaders/phong.frag deleted file mode 100644 index f09777da..00000000 --- a/examples/common/opengl-framework/src/shaders/phong.frag +++ /dev/null @@ -1,67 +0,0 @@ -/******************************************************************************** -* OpenGL-Framework * -* Copyright (c) 2013 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -// Uniform variables -uniform vec3 lightAmbientColor; // Lights ambient color -uniform vec3 light0PosCameraSpace; // Camera-space position of the light -uniform vec3 light0DiffuseColor; // Light 0 diffuse color -uniform vec3 light0SpecularColor; // Light 0 specular color -uniform float shininess; // Shininess -uniform sampler2D texture; // Texture -uniform bool isTexture; // True if we need to use the texture -uniform vec4 vertexColor; // Vertex color - -// Varying variables -varying vec3 vertexPosCameraSpace; // Camera-space position of the vertex -varying vec3 vertexNormalCameraSpace; // Vertex normal in camera-space -varying vec2 texCoords; // Texture coordinates - -void main() { - - // Compute the ambient term - vec3 ambient = lightAmbientColor; - - // Get the texture color - vec3 textureColor = vertexColor.rgb; - if (isTexture) textureColor = texture2D(texture, texCoords).rgb; - - // Compute the surface normal vector - vec3 N = normalize(vertexNormalCameraSpace); - - // Compute the diffuse term of light 0 - vec3 L0 = normalize(light0PosCameraSpace - vertexPosCameraSpace); - float diffuseFactor = max(dot(N, L0), 0.0); - vec3 diffuse = light0DiffuseColor * diffuseFactor * textureColor; - - // Compute the specular term of light 0 - vec3 V = normalize(-vertexPosCameraSpace); - vec3 H0 = normalize(V + L0); - float specularFactor = pow(max(dot(N, H0), 0.0), shininess); - if (diffuseFactor < 0.0) specularFactor = 0.0; - vec3 specular = light0SpecularColor * specularFactor; - - // Compute the final color - gl_FragColor = vec4(ambient + diffuse + specular, 1.0); -} diff --git a/examples/common/opengl-framework/src/shaders/phong.vert b/examples/common/opengl-framework/src/shaders/phong.vert deleted file mode 100644 index 620344a9..00000000 --- a/examples/common/opengl-framework/src/shaders/phong.vert +++ /dev/null @@ -1,50 +0,0 @@ -/******************************************************************************** -* OpenGL-Framework * -* Copyright (c) 2013 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -// Uniform variables -uniform mat4 localToCameraMatrix; // Local-space to camera-space matrix -uniform mat4 projectionMatrix; // Projection matrix -uniform mat3 normalMatrix; // Normal matrix - -// Varying variables -varying vec3 vertexPosCameraSpace; // Camera-space position of the vertex -varying vec3 vertexNormalCameraSpace; // Vertex normal in camera-space -varying vec2 texCoords; // Texture coordinates - -void main() { - - // Compute the vertex position - vec4 positionCameraSpace = localToCameraMatrix * gl_Vertex; - vertexPosCameraSpace = positionCameraSpace.xyz; - - // Compute the world surface normal - vertexNormalCameraSpace = normalMatrix * gl_Normal; - - // Get the texture coordinates - texCoords = gl_MultiTexCoord0.xy; - - // Compute the clip-space vertex coordinates - gl_Position = projectionMatrix * positionCameraSpace; -} diff --git a/examples/cubes/CMakeLists.txt b/examples/cubes/CMakeLists.txt deleted file mode 100644 index 5239dc56..00000000 --- a/examples/cubes/CMakeLists.txt +++ /dev/null @@ -1,34 +0,0 @@ -# Minimum cmake version required -cmake_minimum_required(VERSION 2.6) - -# Project configuration -PROJECT(Cubes) - -# Where to build the executables -SET(EXECUTABLE_OUTPUT_PATH "${OUR_EXECUTABLE_OUTPUT_PATH}/cubes") -SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}) -SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${EXECUTABLE_OUTPUT_PATH}) -SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${EXECUTABLE_OUTPUT_PATH}) - -# Copy the shaders used for the demo into the build directory -FILE(COPY "${OPENGLFRAMEWORK_DIR}/src/shaders/" DESTINATION "${EXECUTABLE_OUTPUT_PATH}/shaders/") - -# Headers -INCLUDE_DIRECTORIES("${OPENGLFRAMEWORK_DIR}/src/" "../common/glfw/include/" "../common/") - -# Source files -SET(CUBES_SOURCES - Cubes.cpp - Scene.cpp - Scene.h - "../common/Box.cpp" - "../common/Box.h" - "../common/Viewer.cpp" - "../common/Viewer.h" -) - -# Create the executable -ADD_EXECUTABLE(cubes ${CUBES_SOURCES}) - -# Link with libraries -TARGET_LINK_LIBRARIES(cubes reactphysics3d openglframework glfw ${GLFW_LIBRARIES}) diff --git a/examples/cubes/Cubes.cpp b/examples/cubes/Cubes.cpp deleted file mode 100644 index f00cda72..00000000 --- a/examples/cubes/Cubes.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/******************************************************************************** -* ReactPhysics3D physics library, http://www.reactphysics3d.com * -* Copyright (c) 2010-2015 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -// Libraries -#include "Scene.h" -#include "Viewer.h" - -// Declarations -void simulate(); -void render(); -void update(); -void mouseButton(GLFWwindow* window, int button, int action, int mods); -void mouseMotion(GLFWwindow* window, double x, double y); -void keyboard(GLFWwindow* window, int key, int scancode, int action, int mods); -void scroll(GLFWwindow* window, double xAxis, double yAxis); -void init(); - -// Namespaces -using namespace openglframework; - -// Global variables -Viewer* viewer; -Scene* scene; - -// Main function -int main(int argc, char** argv) { - - // Create and initialize the Viewer - viewer = new Viewer(); - Vector2 windowsSize = Vector2(800, 600); - Vector2 windowsPosition = Vector2(100, 100); - viewer->init(argc, argv, "ReactPhysics3D Examples - Cubes", windowsSize, windowsPosition, true); - - // If the shaders folder is not specified as an argument - if (argc < 2) { - std::cerr << "Error : You need to specify the shaders folder as argument !" << std::endl; - return 1; - } - - // Get the path of the shaders folder - std::string shaderFolderPath(argv[1]); - - // Register callback methods - viewer->registerUpdateFunction(update); - viewer->registerKeyboardCallback(keyboard); - viewer->registerMouseButtonCallback(mouseButton); - viewer->registerMouseCursorCallback(mouseMotion); - viewer->registerScrollingCallback(scroll); - - // Create the scene - scene = new Scene(viewer, shaderFolderPath); - - init(); - - viewer->startMainLoop(); - - delete viewer; - delete scene; - - return 0; -} - -// Update function that is called each frame -void update() { - - // Take a simulation step - simulate(); - - // Render - render(); -} - -// Simulate function -void simulate() { - - // Physics simulation - scene->simulate(); - - // Compute the current framerate - viewer->computeFPS(); -} - -// Initialization -void init() { - - // Define the background color (black) - glClearColor(0.0, 0.0, 0.0, 1.0); -} - -// Callback method to receive keyboard events -void keyboard(GLFWwindow* window, int key, int scancode, int action, int mods) { - if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) { - glfwSetWindowShouldClose(window, GL_TRUE); - } - else if (key == GLFW_KEY_SPACE && action == GLFW_PRESS) { - scene->pauseContinueSimulation(); - } -} - -// Callback method to receive scrolling events -void scroll(GLFWwindow* window, double xAxis, double yAxis) { - viewer->scrollingEvent(static_cast(yAxis)); -} - -// Called when a mouse button event occurs -void mouseButton(GLFWwindow* window, int button, int action, int mods) { - viewer->mouseButtonEvent(button, action); -} - -// Called when a mouse motion event occurs -void mouseMotion(GLFWwindow* window, double x, double y) { - viewer->mouseMotionEvent(x, y); -} - -// Display the scene -void render() { - - // Render the scene - scene->render(); - - // Display the FPS - viewer->displayGUI(); - - // Check the OpenGL errors - Viewer::checkOpenGLErrors(); -} diff --git a/examples/cubes/Scene.cpp b/examples/cubes/Scene.cpp deleted file mode 100644 index 073ab02b..00000000 --- a/examples/cubes/Scene.cpp +++ /dev/null @@ -1,197 +0,0 @@ -/******************************************************************************** -* ReactPhysics3D physics library, http://www.reactphysics3d.com * -* Copyright (c) 2010-2015 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -// Libraries -#include "Scene.h" - -// Namespaces -using namespace openglframework; - -// Constructor -Scene::Scene(Viewer* viewer, const std::string& shaderFolderPath) - : mViewer(viewer), mLight0(0), - mPhongShader(shaderFolderPath + "phong.vert", shaderFolderPath + "phong.frag"), - mIsRunning(false) { - - // Move the light 0 - mLight0.translateWorld(Vector3(7, 15, 15)); - - // Compute the radius and the center of the scene - float radiusScene = 30.0f; - openglframework::Vector3 center(0, 5, 0); - - // Set the center of the scene - mViewer->setScenePosition(center, radiusScene); - - // Gravity vector in the dynamics world - rp3d::Vector3 gravity(0, rp3d::decimal(-5.81), 0); - - // Time step for the physics simulation - rp3d::decimal timeStep = 1.0f / 60.0f; - - // Create the dynamics world for the physics simulation - mDynamicsWorld = new rp3d::DynamicsWorld(gravity, timeStep); - - // Set the number of iterations of the constraint solver - mDynamicsWorld->setNbIterationsVelocitySolver(15); - - float radius = 2.0f; - - // Create all the cubes of the scene - for (int i=0; igetRigidBody()->getMaterial(); - material.setBounciness(rp3d::decimal(0.4)); - - // Add the box the list of box in the scene - mBoxes.push_back(cube); - } - - // Create the floor - openglframework::Vector3 floorPosition(0, 0, 0); - mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld); - - // The floor must be a static rigid body - mFloor->getRigidBody()->setType(rp3d::STATIC); - - // Change the material properties of the floor rigid body - rp3d::Material& material = mFloor->getRigidBody()->getMaterial(); - material.setBounciness(rp3d::decimal(0.3)); - - // Start the simulation - startSimulation(); - - counter=0; -} - -// Destructor -Scene::~Scene() { - - // Stop the physics simulation - stopSimulation(); - - // Destroy the shader - mPhongShader.destroy(); - - // Destroy all the cubes of the scene - for (std::vector::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { - - // Destroy the corresponding rigid body from the dynamics world - mDynamicsWorld->destroyRigidBody((*it)->getRigidBody()); - - // Destroy the cube - delete (*it); - } - - // Destroy the rigid body of the floor - mDynamicsWorld->destroyRigidBody(mFloor->getRigidBody()); - - // Destroy the floor - delete mFloor; - - // Destroy the dynamics world - delete mDynamicsWorld; -} - -// Take a step for the simulation -void Scene::simulate() { - - // If the physics simulation is running - if (mIsRunning) { - - counter++; - if (counter == 400) { - //mIsRunning = false; - } - - // Take a simulation step - mDynamicsWorld->update(); - - // Update the position and orientation of the boxes - for (std::vector::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { - - // Update the transform used for the rendering - (*it)->updateTransform(); - } - - mFloor->updateTransform(); - - // Set the color of the awake/sleeping bodies - for (uint i=0; igetRigidBody()->isSleeping()) { - mBoxes[i]->setColor(Color(1, 0, 0, 1)); - } - else { - mBoxes[i]->setColor(Color(0, 1, 0, 1)); - } - } - } -} - -// Render the scene -void Scene::render() { - - glEnable(GL_DEPTH_TEST); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glEnable(GL_CULL_FACE); - - // Get the world-space to camera-space matrix - const Camera& camera = mViewer->getCamera(); - const openglframework::Matrix4 worldToCameraMatrix = camera.getTransformMatrix().getInverse(); - - // Bind the shader - mPhongShader.bind(); - - // Set the variables of the shader - mPhongShader.setMatrix4x4Uniform("projectionMatrix", camera.getProjectionMatrix()); - mPhongShader.setVector3Uniform("light0PosCameraSpace",worldToCameraMatrix * mLight0.getOrigin()); - mPhongShader.setVector3Uniform("lightAmbientColor", Vector3(0.3f, 0.3f, 0.3f)); - const Color& diffCol = mLight0.getDiffuseColor(); - const Color& specCol = mLight0.getSpecularColor(); - mPhongShader.setVector3Uniform("light0DiffuseColor", Vector3(diffCol.r, diffCol.g, diffCol.b)); - mPhongShader.setVector3Uniform("light0SpecularColor", Vector3(specCol.r, specCol.g, specCol.b)); - mPhongShader.setFloatUniform("shininess", 60.0f); - - // Render all the cubes of the scene - for (std::vector::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { - (*it)->render(mPhongShader, worldToCameraMatrix); - } - - // Render the floor - mFloor->render(mPhongShader, worldToCameraMatrix); - - // Unbind the shader - mPhongShader.unbind(); -} diff --git a/examples/cubes/Scene.h b/examples/cubes/Scene.h deleted file mode 100644 index 2f79daed..00000000 --- a/examples/cubes/Scene.h +++ /dev/null @@ -1,120 +0,0 @@ -/******************************************************************************** -* ReactPhysics3D physics library, http://www.reactphysics3d.com * -* Copyright (c) 2010-2015 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -#ifndef SCENE_H -#define SCENE_H - -// Libraries -#include "openglframework.h" -#include "reactphysics3d.h" -#include "Box.h" -#include "Viewer.h" - -// Constants -const int NB_CUBES = 200; // Number of boxes in the scene -const openglframework::Vector3 BOX_SIZE(2, 2, 2); // Box dimensions in meters -const openglframework::Vector3 FLOOR_SIZE(50, 0.5f, 50); // Floor dimensions in meters -const float BOX_MASS = 1.0f; // Box mass in kilograms -const float FLOOR_MASS = 100.0f; // Floor mass in kilograms - -// Class Scene -class Scene { - - private : - - // -------------------- Attributes -------------------- // - - int counter; - - /// Pointer to the viewer - Viewer* mViewer; - - /// Light 0 - openglframework::Light mLight0; - - /// Phong shader - openglframework::Shader mPhongShader; - - /// All the boxes of the scene - std::vector mBoxes; - - /// Box for the floor - Box* mFloor; - - /// Dynamics world used for the physics simulation - rp3d::DynamicsWorld* mDynamicsWorld; - - /// True if the physics simulation is running - bool mIsRunning; - - public: - - // -------------------- Methods -------------------- // - - /// Constructor - Scene(Viewer* viewer, const std::string& shaderFolderPath); - - /// Destructor - ~Scene(); - - /// Take a step for the simulation - void simulate(); - - /// Stop the simulation - void stopSimulation(); - - /// Start the simulation - void startSimulation(); - - /// Pause or continue simulation - void pauseContinueSimulation(); - - /// Render the scene - void render(); -}; - -// Stop the simulation -inline void Scene::stopSimulation() { - mDynamicsWorld->stop(); - mIsRunning = false; -} - -// Start the simulation -inline void Scene::startSimulation() { - mDynamicsWorld->start(); - mIsRunning = true; -} - -// Pause or continue simulation -inline void Scene::pauseContinueSimulation() { - if (mIsRunning) { - stopSimulation(); - } - else { - startSimulation(); - } -} - -#endif diff --git a/examples/joints/CMakeLists.txt b/examples/joints/CMakeLists.txt deleted file mode 100644 index ba304b9d..00000000 --- a/examples/joints/CMakeLists.txt +++ /dev/null @@ -1,34 +0,0 @@ -# Minimum cmake version required -cmake_minimum_required(VERSION 2.6) - -# Project configuration -PROJECT(Joints) - -# Where to build the executables -SET(EXECUTABLE_OUTPUT_PATH "${OUR_EXECUTABLE_OUTPUT_PATH}/joints") -SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}) -SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${EXECUTABLE_OUTPUT_PATH}) -SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${EXECUTABLE_OUTPUT_PATH}) - -# Copy the shaders used for the demo into the build directory -FILE(COPY "${OPENGLFRAMEWORK_DIR}/src/shaders/" DESTINATION "${EXECUTABLE_OUTPUT_PATH}/shaders/") - -# Headers -INCLUDE_DIRECTORIES("${OPENGLFRAMEWORK_DIR}/src/" "../common/glfw/include/" "../common/") - -# Source files -SET(JOINTS_SOURCES - Joints.cpp - Scene.cpp - Scene.h - "../common/Box.cpp" - "../common/Box.h" - "../common/Viewer.cpp" - "../common/Viewer.h" -) - -# Create the executable -ADD_EXECUTABLE(joints ${JOINTS_SOURCES}) - -# Link with libraries -TARGET_LINK_LIBRARIES(joints reactphysics3d openglframework glfw ${GLFW_LIBRARIES}) diff --git a/examples/joints/Joints.cpp b/examples/joints/Joints.cpp deleted file mode 100644 index 1b1b7e00..00000000 --- a/examples/joints/Joints.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/******************************************************************************** -* ReactPhysics3D physics library, http://www.reactphysics3d.com * -* Copyright (c) 2010-2015 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -// Libraries -#include "Scene.h" -#include "../common/Viewer.h" - -// Declarations -void simulate(); -void update(); -void render(); -void mouseButton(GLFWwindow* window, int button, int action, int mods); -void mouseMotion(GLFWwindow* window, double x, double y); -void keyboard(GLFWwindow* window, int key, int scancode, int action, int mods); -void scroll(GLFWwindow* window, double xAxis, double yAxis); -void init(); - -// Namespaces -using namespace openglframework; - -// Global variables -Viewer* viewer; -Scene* scene; - -// Main function -int main(int argc, char** argv) { - - // Create and initialize the Viewer - viewer = new Viewer(); - Vector2 windowsSize = Vector2(800, 600); - Vector2 windowsPosition = Vector2(100, 100); - viewer->init(argc, argv, "ReactPhysics3D Examples - Joints", windowsSize, windowsPosition, true); - - // If the shaders folder is not specified as an argument - if (argc < 2) { - std::cerr << "Error : You need to specify the shaders folder as argument !" << std::endl; - return 1; - } - - // Get the path of the shaders folder - std::string shaderFolderPath(argv[1]); - - // Register callback methods - viewer->registerUpdateFunction(update); - viewer->registerKeyboardCallback(keyboard); - viewer->registerMouseButtonCallback(mouseButton); - viewer->registerMouseCursorCallback(mouseMotion); - viewer->registerScrollingCallback(scroll); - - // Create the scene - scene = new Scene(viewer, shaderFolderPath); - - init(); - - viewer->startMainLoop(); - - delete viewer; - delete scene; - - return 0; -} - -// Update function that is called each frame -void update() { - - // Take a simulation step - simulate(); - - // Render - render(); -} - -// Simulate function -void simulate() { - - // Physics simulation - scene->simulate(); - - viewer->computeFPS(); -} - -// Initialization -void init() { - - // Define the background color (black) - glClearColor(0.0, 0.0, 0.0, 1.0); -} - -// Callback method to receive keyboard events -void keyboard(GLFWwindow* window, int key, int scancode, int action, int mods) { - if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) { - glfwSetWindowShouldClose(window, GL_TRUE); - } - else if (key == GLFW_KEY_SPACE && action == GLFW_PRESS) { - scene->pauseContinueSimulation(); - } -} - -// Callback method to receive scrolling events -void scroll(GLFWwindow* window, double xAxis, double yAxis) { - viewer->scrollingEvent(static_cast(yAxis)); -} - -// Called when a mouse button event occurs -void mouseButton(GLFWwindow* window, int button, int action, int mods) { - viewer->mouseButtonEvent(button, action); -} - -// Called when a mouse motion event occurs -void mouseMotion(GLFWwindow* window, double x, double y) { - viewer->mouseMotionEvent(x, y); -} - -// Display the scene -void render() { - - // Render the scene - scene->render(); - - // Display the FPS - viewer->displayGUI(); - - // Check the OpenGL errors - Viewer::checkOpenGLErrors(); -} - - diff --git a/examples/joints/Scene.cpp b/examples/joints/Scene.cpp deleted file mode 100644 index def294fa..00000000 --- a/examples/joints/Scene.cpp +++ /dev/null @@ -1,394 +0,0 @@ -/******************************************************************************** -* ReactPhysics3D physics library, http://www.reactphysics3d.com * -* Copyright (c) 2010-2015 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -// Libraries -#include "Scene.h" -#include - -// Namespaces -using namespace openglframework; - -// Constructor -Scene::Scene(Viewer *viewer, const std::string& shaderFolderPath) - : mViewer(viewer), mLight0(0), mPhongShader(shaderFolderPath + "phong.vert", - shaderFolderPath + "phong.frag"), - mIsRunning(false) { - - // Move the light 0 - mLight0.translateWorld(Vector3(7, 15, 15)); - - // Compute the radius and the center of the scene - float radiusScene = 30.0f; - openglframework::Vector3 center(0, 5, 0); - - // Set the center of the scene - mViewer->setScenePosition(center, radiusScene); - - // Gravity vector in the dynamics world - rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0); - - // Time step for the physics simulation - rp3d::decimal timeStep = 1.0f / 60.0f; - - // Create the dynamics world for the physics simulation - mDynamicsWorld = new rp3d::DynamicsWorld(gravity, timeStep); - - // Set the number of iterations of the constraint solver - mDynamicsWorld->setNbIterationsVelocitySolver(15); - - // Create the Ball-and-Socket joint - createBallAndSocketJoints(); - - // Create the Slider joint - createSliderJoint(); - - // Create the Hinge joint - createPropellerHingeJoint(); - - // Create the Fixed joint - createFixedJoints(); - - // Create the floor - createFloor(); - - // Start the simulation - startSimulation(); -} - -// Destructor -Scene::~Scene() { - - // Stop the physics simulation - stopSimulation(); - - // Destroy the shader - mPhongShader.destroy(); - - // Destroy the joints - mDynamicsWorld->destroyJoint(mSliderJoint); - mDynamicsWorld->destroyJoint(mPropellerHingeJoint); - mDynamicsWorld->destroyJoint(mFixedJoint1); - mDynamicsWorld->destroyJoint(mFixedJoint2); - for (int i=0; idestroyJoint(mBallAndSocketJoints[i]); - } - - // Destroy all the rigid bodies of the scene - mDynamicsWorld->destroyRigidBody(mSliderJointBottomBox->getRigidBody()); - mDynamicsWorld->destroyRigidBody(mSliderJointTopBox->getRigidBody()); - mDynamicsWorld->destroyRigidBody(mPropellerBox->getRigidBody()); - mDynamicsWorld->destroyRigidBody(mFixedJointBox1->getRigidBody()); - mDynamicsWorld->destroyRigidBody(mFixedJointBox2->getRigidBody()); - for (int i=0; idestroyRigidBody(mBallAndSocketJointChainBoxes[i]->getRigidBody()); - } - - delete mSliderJointBottomBox; - delete mSliderJointTopBox; - delete mPropellerBox; - delete mFixedJointBox1; - delete mFixedJointBox2; - for (int i=0; idestroyRigidBody(mFloor->getRigidBody()); - delete mFloor; - - // Destroy the dynamics world - delete mDynamicsWorld; -} - -// Take a step for the simulation -void Scene::simulate() { - - // If the physics simulation is running - if (mIsRunning) { - - // Update the motor speed of the Slider Joint (to move up and down) - long double motorSpeed = 2 * cos(mDynamicsWorld->getPhysicsTime() * 1.5); - mSliderJoint->setMotorSpeed(rp3d::decimal(motorSpeed)); - - // Take a simulation step - mDynamicsWorld->update(); - - // Update the position and orientation of the boxes - mSliderJointBottomBox->updateTransform(); - mSliderJointTopBox->updateTransform(); - mPropellerBox->updateTransform(); - mFixedJointBox1->updateTransform(); - mFixedJointBox2->updateTransform(); - for (int i=0; iupdateTransform(); - } - - // Update the position and orientation of the floor - mFloor->updateTransform(); - } -} - -// Render the scene -void Scene::render() { - - glEnable(GL_DEPTH_TEST); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glEnable(GL_CULL_FACE); - - // Get the world-space to camera-space matrix - const Camera& camera = mViewer->getCamera(); - const openglframework::Matrix4 worldToCameraMatrix = camera.getTransformMatrix().getInverse(); - - // Bind the shader - mPhongShader.bind(); - - // Set the variables of the shader - mPhongShader.setVector3Uniform("light0PosCameraSpace",worldToCameraMatrix * mLight0.getOrigin()); - mPhongShader.setMatrix4x4Uniform("projectionMatrix", camera.getProjectionMatrix()); - mPhongShader.setVector3Uniform("lightAmbientColor", Vector3(0.3f, 0.3f, 0.3f)); - const Color& diffCol = mLight0.getDiffuseColor(); - const Color& specCol = mLight0.getSpecularColor(); - mPhongShader.setVector3Uniform("light0DiffuseColor", Vector3(diffCol.r, diffCol.g, diffCol.b)); - mPhongShader.setVector3Uniform("light0SpecularColor", Vector3(specCol.r, specCol.g, specCol.b)); - mPhongShader.setFloatUniform("shininess", 60.0f); - - // Render all the boxes - mSliderJointBottomBox->render(mPhongShader, worldToCameraMatrix); - mSliderJointTopBox->render(mPhongShader, worldToCameraMatrix); - mPropellerBox->render(mPhongShader, worldToCameraMatrix); - mFixedJointBox1->render(mPhongShader, worldToCameraMatrix); - mFixedJointBox2->render(mPhongShader, worldToCameraMatrix); - for (int i=0; irender(mPhongShader, worldToCameraMatrix); - } - - // Render the floor - mFloor->render(mPhongShader, worldToCameraMatrix); - - // Unbind the shader - mPhongShader.unbind(); -} - -// Create the boxes and joints for the Ball-and-Socket joint example -void Scene::createBallAndSocketJoints() { - - // --------------- Create the boxes --------------- // - - openglframework::Vector3 positionBox(0, 15, 5); - openglframework::Vector3 boxDimension(1, 1, 1); - const float boxMass = 0.5f; - - for (int i=0; igetRigidBody()->setType(rp3d::STATIC); - } - - // Add some angular velocity damping - mBallAndSocketJointChainBoxes[i]->getRigidBody()->setAngularDamping(rp3d::decimal(0.2)); - - // Change the material properties of the rigid body - rp3d::Material& material = mBallAndSocketJointChainBoxes[i]->getRigidBody()->getMaterial(); - material.setBounciness(rp3d::decimal(0.4)); - - positionBox.y -= boxDimension.y + 0.5f; - } - - // --------------- Create the joints --------------- // - - for (int i=0; igetRigidBody(); - rp3d::RigidBody* body2 = mBallAndSocketJointChainBoxes[i+1]->getRigidBody(); - rp3d::Vector3 body1Position = body1->getTransform().getPosition(); - rp3d::Vector3 body2Position = body2->getTransform().getPosition(); - const rp3d::Vector3 anchorPointWorldSpace = 0.5 * (body1Position + body2Position); - rp3d::BallAndSocketJointInfo jointInfo(body1, body2, anchorPointWorldSpace); - - // Create the joint in the dynamics world - mBallAndSocketJoints[i] = dynamic_cast( - mDynamicsWorld->createJoint(jointInfo)); - } -} - -/// Create the boxes and joint for the Slider joint example -void Scene::createSliderJoint() { - - // --------------- Create the first box --------------- // - - // Position of the box - openglframework::Vector3 positionBox1(0, 2.1f, 0); - - // Create a box and a corresponding rigid in the dynamics world - openglframework::Vector3 box1Dimension(2, 4, 2); - mSliderJointBottomBox = new Box(box1Dimension, positionBox1 , BOX_MASS, mDynamicsWorld); - - // The fist box cannot move - mSliderJointBottomBox->getRigidBody()->setType(rp3d::STATIC); - - // Change the material properties of the rigid body - rp3d::Material& material1 = mSliderJointBottomBox->getRigidBody()->getMaterial(); - material1.setBounciness(0.4f); - - // --------------- Create the second box --------------- // - - // Position of the box - openglframework::Vector3 positionBox2(0, 4.2f, 0); - - // Create a box and a corresponding rigid in the dynamics world - openglframework::Vector3 box2Dimension(1.5f, 4, 1.5f); - mSliderJointTopBox = new Box(box2Dimension, positionBox2 , BOX_MASS, mDynamicsWorld); - - // Change the material properties of the rigid body - rp3d::Material& material2 = mSliderJointTopBox->getRigidBody()->getMaterial(); - material2.setBounciness(0.4f); - - // --------------- Create the joint --------------- // - - // Create the joint info object - rp3d::RigidBody* body1 = mSliderJointBottomBox->getRigidBody(); - rp3d::RigidBody* body2 = mSliderJointTopBox->getRigidBody(); - const rp3d::Vector3& body1Position = body1->getTransform().getPosition(); - const rp3d::Vector3& body2Position = body2->getTransform().getPosition(); - const rp3d::Vector3 anchorPointWorldSpace = rp3d::decimal(0.5) * (body2Position + body1Position); - const rp3d::Vector3 sliderAxisWorldSpace = (body2Position - body1Position); - rp3d::SliderJointInfo jointInfo(body1, body2, anchorPointWorldSpace, sliderAxisWorldSpace, - rp3d::decimal(-1.7), rp3d::decimal(1.7)); - jointInfo.isMotorEnabled = true; - jointInfo.motorSpeed = 0.0; - jointInfo.maxMotorForce = 10000.0; - jointInfo.isCollisionEnabled = false; - - // Create the joint in the dynamics world - mSliderJoint = dynamic_cast(mDynamicsWorld->createJoint(jointInfo)); -} - -/// Create the boxes and joint for the Hinge joint example -void Scene::createPropellerHingeJoint() { - - // --------------- Create the propeller box --------------- // - - // Position of the box - openglframework::Vector3 positionBox1(0, 7, 0); - - // Create a box and a corresponding rigid in the dynamics world - openglframework::Vector3 boxDimension(10, 1, 1); - mPropellerBox = new Box(boxDimension, positionBox1 , BOX_MASS, mDynamicsWorld); - - // Change the material properties of the rigid body - rp3d::Material& material = mPropellerBox->getRigidBody()->getMaterial(); - material.setBounciness(rp3d::decimal(0.4)); - - // --------------- Create the Hinge joint --------------- // - - // Create the joint info object - rp3d::RigidBody* body1 = mPropellerBox->getRigidBody(); - rp3d::RigidBody* body2 = mSliderJointTopBox->getRigidBody(); - const rp3d::Vector3& body1Position = body1->getTransform().getPosition(); - const rp3d::Vector3& body2Position = body2->getTransform().getPosition(); - const rp3d::Vector3 anchorPointWorldSpace = 0.5 * (body2Position + body1Position); - const rp3d::Vector3 hingeAxisWorldSpace(0, 1, 0); - rp3d::HingeJointInfo jointInfo(body1, body2, anchorPointWorldSpace, hingeAxisWorldSpace); - jointInfo.isMotorEnabled = true; - jointInfo.motorSpeed = - rp3d::decimal(0.5) * PI; - jointInfo.maxMotorTorque = rp3d::decimal(60.0); - jointInfo.isCollisionEnabled = false; - - // Create the joint in the dynamics world - mPropellerHingeJoint = dynamic_cast(mDynamicsWorld->createJoint(jointInfo)); -} - -/// Create the boxes and joints for the fixed joints -void Scene::createFixedJoints() { - - // --------------- Create the first box --------------- // - - // Position of the box - openglframework::Vector3 positionBox1(5, 7, 0); - - // Create a box and a corresponding rigid in the dynamics world - openglframework::Vector3 boxDimension(1.5, 1.5, 1.5); - mFixedJointBox1 = new Box(boxDimension, positionBox1 , BOX_MASS, mDynamicsWorld); - - // Change the material properties of the rigid body - rp3d::Material& material1 = mFixedJointBox1->getRigidBody()->getMaterial(); - material1.setBounciness(rp3d::decimal(0.4)); - - // --------------- Create the second box --------------- // - - // Position of the box - openglframework::Vector3 positionBox2(-5, 7, 0); - - // Create a box and a corresponding rigid in the dynamics world - mFixedJointBox2 = new Box(boxDimension, positionBox2 , BOX_MASS, mDynamicsWorld); - - // Change the material properties of the rigid body - rp3d::Material& material2 = mFixedJointBox2->getRigidBody()->getMaterial(); - material2.setBounciness(rp3d::decimal(0.4)); - - // --------------- Create the first fixed joint --------------- // - - // Create the joint info object - rp3d::RigidBody* body1 = mFixedJointBox1->getRigidBody(); - rp3d::RigidBody* propellerBody = mPropellerBox->getRigidBody(); - const rp3d::Vector3 anchorPointWorldSpace1(5, 7, 0); - rp3d::FixedJointInfo jointInfo1(body1, propellerBody, anchorPointWorldSpace1); - jointInfo1.isCollisionEnabled = false; - - // Create the joint in the dynamics world - mFixedJoint1 = dynamic_cast(mDynamicsWorld->createJoint(jointInfo1)); - - // --------------- Create the second fixed joint --------------- // - - // Create the joint info object - rp3d::RigidBody* body2 = mFixedJointBox2->getRigidBody(); - const rp3d::Vector3 anchorPointWorldSpace2(-5, 7, 0); - rp3d::FixedJointInfo jointInfo2(body2, propellerBody, anchorPointWorldSpace2); - jointInfo2.isCollisionEnabled = false; - - // Create the joint in the dynamics world - mFixedJoint2 = dynamic_cast(mDynamicsWorld->createJoint(jointInfo2)); -} - -// Create the floor -void Scene::createFloor() { - - // Create the floor - openglframework::Vector3 floorPosition(0, 0, 0); - mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld); - - // The floor must be a static rigid body - mFloor->getRigidBody()->setType(rp3d::STATIC); - - // Change the material properties of the rigid body - rp3d::Material& material = mFloor->getRigidBody()->getMaterial(); - material.setBounciness(rp3d::decimal(0.3)); -} diff --git a/examples/joints/Scene.h b/examples/joints/Scene.h deleted file mode 100644 index 4467f3af..00000000 --- a/examples/joints/Scene.h +++ /dev/null @@ -1,172 +0,0 @@ -/******************************************************************************** -* ReactPhysics3D physics library, http://www.reactphysics3d.com * -* Copyright (c) 2010-2015 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -#ifndef SCENE_H -#define SCENE_H - -// Libraries -#include "openglframework.h" -#include "reactphysics3d.h" -#include "Box.h" -#include "../common/Viewer.h" - -// Constants -const openglframework::Vector3 BOX_SIZE(2, 2, 2); // Box dimensions in meters -const openglframework::Vector3 FLOOR_SIZE(20, 0.5f, 20); // Floor dimensions in meters -const float BOX_MASS = 1.0f; // Box mass in kilograms -const float FLOOR_MASS = 100.0f; // Floor mass in kilograms -const int NB_BALLSOCKETJOINT_BOXES = 7; // Number of Ball-And-Socket chain boxes -const int NB_HINGE_BOXES = 7; // Number of Hinge chain boxes - -// Class Scene -class Scene { - - private : - - // -------------------- Attributes -------------------- // - - /// Pointer to the viewer - Viewer* mViewer; - - /// Light 0 - openglframework::Light mLight0; - - /// Phong shader - openglframework::Shader mPhongShader; - - /// Boxes of Ball-And-Socket joint chain - Box* mBallAndSocketJointChainBoxes[NB_BALLSOCKETJOINT_BOXES]; - - /// Boxes of the Hinge joint chain - Box* mHingeJointChainBoxes[NB_HINGE_BOXES]; - - /// Ball-And-Socket joints of the chain - rp3d::BallAndSocketJoint* mBallAndSocketJoints[NB_BALLSOCKETJOINT_BOXES-1]; - - /// Hinge joints of the chain - rp3d::HingeJoint* mHingeJoints[NB_HINGE_BOXES-1]; - - /// Bottom box of the Slider joint - Box* mSliderJointBottomBox; - - /// Top box of the Slider joint - Box* mSliderJointTopBox; - - /// Slider joint - rp3d::SliderJoint* mSliderJoint; - - /// Propeller box - Box* mPropellerBox; - - /// Box 1 of Fixed joint - Box* mFixedJointBox1; - - /// Box 2 of Fixed joint - Box* mFixedJointBox2; - - /// Hinge joint - rp3d::HingeJoint* mPropellerHingeJoint; - - /// First Fixed joint - rp3d::FixedJoint* mFixedJoint1; - - /// Second Fixed joint - rp3d::FixedJoint* mFixedJoint2; - - /// Box for the floor - Box* mFloor; - - /// Dynamics world used for the physics simulation - rp3d::DynamicsWorld* mDynamicsWorld; - - /// True if the physics simulation is running - bool mIsRunning; - - // -------------------- Methods -------------------- // - - /// Create the boxes and joints for the Ball-and-Socket joint example - void createBallAndSocketJoints(); - - /// Create the boxes and joint for the Slider joint example - void createSliderJoint(); - - /// Create the boxes and joint for the Hinge joint example - void createPropellerHingeJoint(); - - /// Create the boxes and joint for the Fixed joint example - void createFixedJoints(); - - /// Create the floor - void createFloor(); - - public: - - // -------------------- Methods -------------------- // - - /// Constructor - Scene(Viewer* viewer, const std::string& shaderFolderPath); - - /// Destructor - ~Scene(); - - /// Take a step for the simulation - void simulate(); - - /// Stop the simulation - void stopSimulation(); - - /// Start the simulation - void startSimulation(); - - /// Pause or continue simulation - void pauseContinueSimulation(); - - /// Render the scene - void render(); -}; - -// Stop the simulation -inline void Scene::stopSimulation() { - mDynamicsWorld->stop(); - mIsRunning = false; -} - -// Start the simulation -inline void Scene::startSimulation() { - mDynamicsWorld->start(); - mIsRunning = true; -} - -// Pause or continue simulation -inline void Scene::pauseContinueSimulation() { - if (mIsRunning) { - stopSimulation(); - } - else { - startSimulation(); - } -} - -#endif diff --git a/examples/raycast/CMakeLists.txt b/examples/raycast/CMakeLists.txt deleted file mode 100644 index 01440b00..00000000 --- a/examples/raycast/CMakeLists.txt +++ /dev/null @@ -1,43 +0,0 @@ -# Minimum cmake version required -cmake_minimum_required(VERSION 2.6) - -# Project configuration -PROJECT(Raycast) - -# Where to build the executables -SET(EXECUTABLE_OUTPUT_PATH "${OUR_EXECUTABLE_OUTPUT_PATH}/raycast") -SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}) -SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${EXECUTABLE_OUTPUT_PATH}) -SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${EXECUTABLE_OUTPUT_PATH}) - -# Copy the shaders used for the demo into the build directory -FILE(COPY "${OPENGLFRAMEWORK_DIR}/src/shaders/" DESTINATION "${EXECUTABLE_OUTPUT_PATH}/shaders/") - -# Copy the meshes used for the demo into the build directory -FILE(COPY "../common/meshes/" DESTINATION "${EXECUTABLE_OUTPUT_PATH}/meshes/") - -# Headers -INCLUDE_DIRECTORIES("${OPENGLFRAMEWORK_DIR}/src/" "../common/glfw/include/" "../common/") - -# Source files -SET(RAYCAST_SOURCES - Raycast.cpp - Scene.cpp - Scene.h - "../common/VisualContactPoint.cpp" - "../common/ConvexMesh.cpp" - "../common/Capsule.cpp" - "../common/Sphere.cpp" - "../common/Line.cpp" - "../common/Cylinder.cpp" - "../common/Cone.cpp" - "../common/Dumbbell.cpp" - "../common/Box.cpp" - "../common/Viewer.cpp" -) - -# Create the executable -ADD_EXECUTABLE(raycast ${RAYCAST_SOURCES}) - -# Link with libraries -TARGET_LINK_LIBRARIES(raycast reactphysics3d openglframework glfw ${GLFW_LIBRARIES}) diff --git a/examples/raycast/Raycast.cpp b/examples/raycast/Raycast.cpp deleted file mode 100644 index e971069a..00000000 --- a/examples/raycast/Raycast.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/******************************************************************************** -* ReactPhysics3D physics library, http://www.reactphysics3d.com * -* Copyright (c) 2010-2015 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -// Libraries -#include "Scene.h" -#include "../common/Viewer.h" - -// Declarations -void simulate(); -void render(); -void update(); -void mouseButton(GLFWwindow* window, int button, int action, int mods); -void mouseMotion(GLFWwindow* window, double x, double y); -void keyboard(GLFWwindow* window, int key, int scancode, int action, int mods); -void scroll(GLFWwindow* window, double xAxis, double yAxis); -void init(); - -// Namespaces -using namespace openglframework; - -// Global variables -Viewer* viewer; -Scene* scene; - -// Main function -int main(int argc, char** argv) { - - // Create and initialize the Viewer - viewer = new Viewer(); - Vector2 windowsSize = Vector2(800, 600); - Vector2 windowsPosition = Vector2(100, 100); - viewer->init(argc, argv, "ReactPhysics3D Examples - Raycast", - windowsSize, windowsPosition, true); - - // If the shaders and meshes folders are not specified as an argument - if (argc < 3) { - std::cerr << "Error : You need to specify the shaders folder as the first argument" - << " and the meshes folder as the second argument" << std::endl; - return 1; - } - - // Get the path of the shaders folder - std::string shaderFolderPath(argv[1]); - std::string meshFolderPath(argv[2]); - - // Register callback methods - viewer->registerUpdateFunction(update); - viewer->registerKeyboardCallback(keyboard); - viewer->registerMouseButtonCallback(mouseButton); - viewer->registerMouseCursorCallback(mouseMotion); - viewer->registerScrollingCallback(scroll); - - // Create the scene - scene = new Scene(viewer, shaderFolderPath, meshFolderPath); - - init(); - - viewer->startMainLoop(); - - delete viewer; - delete scene; - - return 0; -} - -// Update function that is called each frame -void update() { - - // Take a simulation step - simulate(); - - // Render - render(); -} - -// Simulate function -void simulate() { - - // Physics simulation - scene->simulate(); - - viewer->computeFPS(); -} - -// Initialization -void init() { - - // Define the background color (black) - glClearColor(0.0, 0.0, 0.0, 1.0); -} - -// Callback method to receive keyboard events -void keyboard(GLFWwindow* window, int key, int scancode, int action, int mods) { - if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) { - glfwSetWindowShouldClose(window, GL_TRUE); - } - if (key == GLFW_KEY_SPACE && action == GLFW_PRESS) { - scene->changeBody(); - } - if (key == GLFW_KEY_N && action == GLFW_PRESS) { - scene->showHideNormals(); - } -} - -// Callback method to receive scrolling events -void scroll(GLFWwindow* window, double xAxis, double yAxis) { - viewer->scrollingEvent(static_cast(yAxis)); -} - -// Called when a mouse button event occurs -void mouseButton(GLFWwindow* window, int button, int action, int mods) { - viewer->mouseButtonEvent(button, action); -} - -// Called when a mouse motion event occurs -void mouseMotion(GLFWwindow* window, double x, double y) { - viewer->mouseMotionEvent(x, y); -} - -// Display the scene -void render() { - - // Render the scene - scene->render(); - - // Display the FPS - viewer->displayGUI(); - - // Check the OpenGL errors - Viewer::checkOpenGLErrors(); -} - - diff --git a/examples/raycast/Scene.cpp b/examples/raycast/Scene.cpp deleted file mode 100644 index da6423a3..00000000 --- a/examples/raycast/Scene.cpp +++ /dev/null @@ -1,307 +0,0 @@ -/******************************************************************************** -* ReactPhysics3D physics library, http://www.reactphysics3d.com * -* Copyright (c) 2010-2015 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -// Libraries -#include "Scene.h" - -// Namespaces -using namespace openglframework; - -// Constructor -Scene::Scene(Viewer* viewer, const std::string& shaderFolderPath, const std::string& meshFolderPath) - : mViewer(viewer), mLight0(0), mCurrentBodyIndex(-1), mAreNormalsDisplayed(false), - mPhongShader(shaderFolderPath + "phong.vert", - shaderFolderPath +"phong.frag") { - - // Move the light 0 - mLight0.translateWorld(Vector3(50, 50, 50)); - - // Compute the radius and the center of the scene - float radiusScene = 30.0f; - openglframework::Vector3 center(0, 0, 0); - - // Set the center of the scene - mViewer->setScenePosition(center, radiusScene); - - // Create the dynamics world for the physics simulation - mCollisionWorld = new rp3d::CollisionWorld(); - - // Create the static data for the visual contact points - VisualContactPoint::createStaticData(meshFolderPath); - - // ---------- Dumbbell ---------- // - openglframework::Vector3 position1(0, 0, 0); - - // Create a convex mesh and a corresponding collision body in the dynamics world - mDumbbell = new Dumbbell(position1, mCollisionWorld, meshFolderPath); - - // ---------- Box ---------- // - openglframework::Vector3 position2(0, 0, 0); - - // Create a box and a corresponding collision body in the dynamics world - mBox = new Box(BOX_SIZE, position2, mCollisionWorld); - mBox->getCollisionBody()->setIsActive(false); - - // ---------- Sphere ---------- // - openglframework::Vector3 position3(0, 0, 0); - - // Create a sphere and a corresponding collision body in the dynamics world - mSphere = new Sphere(SPHERE_RADIUS, position3, mCollisionWorld, - meshFolderPath); - - // ---------- Cone ---------- // - openglframework::Vector3 position4(0, 0, 0); - - // Create a cone and a corresponding collision body in the dynamics world - mCone = new Cone(CONE_RADIUS, CONE_HEIGHT, position4, mCollisionWorld, - meshFolderPath); - - // ---------- Cylinder ---------- // - openglframework::Vector3 position5(0, 0, 0); - - // Create a cylinder and a corresponding collision body in the dynamics world - mCylinder = new Cylinder(CYLINDER_RADIUS, CYLINDER_HEIGHT, position5, - mCollisionWorld, meshFolderPath); - - // ---------- Capsule ---------- // - openglframework::Vector3 position6(0, 0, 0); - - // Create a cylinder and a corresponding collision body in the dynamics world - mCapsule = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, position6 , - mCollisionWorld, meshFolderPath); - - // ---------- Convex Mesh ---------- // - openglframework::Vector3 position7(0, 0, 0); - - // Create a convex mesh and a corresponding collision body in the dynamics world - mConvexMesh = new ConvexMesh(position7, mCollisionWorld, meshFolderPath); - - // Create the lines that will be used for raycasting - createLines(); - - changeBody(); -} - -// Create the raycast lines -void Scene::createLines() { - - int nbRaysOneDimension = std::sqrt(float(NB_RAYS)); - - for (int i=0; i= NB_BODIES) mCurrentBodyIndex = 0; - - mSphere->getCollisionBody()->setIsActive(false); - mBox->getCollisionBody()->setIsActive(false); - mCone->getCollisionBody()->setIsActive(false); - mCylinder->getCollisionBody()->setIsActive(false); - mCapsule->getCollisionBody()->setIsActive(false); - mConvexMesh->getCollisionBody()->setIsActive(false); - mDumbbell->getCollisionBody()->setIsActive(false); - - switch(mCurrentBodyIndex) { - case 0: mSphere->getCollisionBody()->setIsActive(true); - break; - case 1: mBox->getCollisionBody()->setIsActive(true); - break; - case 2: mCone->getCollisionBody()->setIsActive(true); - break; - case 3: mCylinder->getCollisionBody()->setIsActive(true); - break; - case 4: mCapsule->getCollisionBody()->setIsActive(true); - break; - case 5: mConvexMesh->getCollisionBody()->setIsActive(true); - break; - case 6: mDumbbell->getCollisionBody()->setIsActive(true); - break; - - } -} - -// Destructor -Scene::~Scene() { - - // Destroy the shader - mPhongShader.destroy(); - - // Destroy the box rigid body from the dynamics world - mCollisionWorld->destroyCollisionBody(mBox->getCollisionBody()); - delete mBox; - - // Destroy the sphere - mCollisionWorld->destroyCollisionBody(mSphere->getCollisionBody()); - delete mSphere; - - // Destroy the corresponding rigid body from the dynamics world - mCollisionWorld->destroyCollisionBody(mCone->getCollisionBody()); - delete mCone; - - // Destroy the corresponding rigid body from the dynamics world - mCollisionWorld->destroyCollisionBody(mCylinder->getCollisionBody()); - - // Destroy the sphere - delete mCylinder; - - // Destroy the corresponding rigid body from the dynamics world - mCollisionWorld->destroyCollisionBody(mCapsule->getCollisionBody()); - - // Destroy the sphere - delete mCapsule; - - // Destroy the corresponding rigid body from the dynamics world - mCollisionWorld->destroyCollisionBody(mConvexMesh->getCollisionBody()); - - // Destroy the convex mesh - delete mConvexMesh; - - // Destroy the corresponding rigid body from the dynamics world - mCollisionWorld->destroyCollisionBody(mDumbbell->getCollisionBody()); - - // Destroy the convex mesh - delete mDumbbell; - - mRaycastManager.resetPoints(); - - // Destroy the static data for the visual contact points - VisualContactPoint::destroyStaticData(); - - // Destroy the collision world - delete mCollisionWorld; - - // Destroy the lines - for (std::vector::iterator it = mLines.begin(); it != mLines.end(); - ++it) { - delete (*it); - } -} - -// Take a step for the simulation -void Scene::simulate() { - - mRaycastManager.resetPoints(); - - // For each line of the scene - for (std::vector::iterator it = mLines.begin(); it != mLines.end(); - ++it) { - - Line* line = *it; - - // Create a ray corresponding to the line - openglframework::Vector3 p1 = line->getPoint1(); - openglframework::Vector3 p2 = line->getPoint2(); - - rp3d::Vector3 point1(p1.x, p1.y, p1.z); - rp3d::Vector3 point2(p2.x, p2.y, p2.z); - rp3d::Ray ray(point1, point2); - - // Perform a raycast query on the physics world by passing a raycast - // callback class in argument. - mCollisionWorld->raycast(ray, &mRaycastManager); - } -} - -// Render the scene -void Scene::render() { - - glEnable(GL_DEPTH_TEST); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glEnable(GL_CULL_FACE); - - // Get the world-space to camera-space matrix - const Camera& camera = mViewer->getCamera(); - const openglframework::Matrix4 worldToCameraMatrix = camera.getTransformMatrix().getInverse(); - - // Bind the shader - mPhongShader.bind(); - - openglframework::Vector4 grey(0.7, 0.7, 0.7, 1); - mPhongShader.setVector4Uniform("vertexColor", grey); - - // Set the variables of the shader - mPhongShader.setMatrix4x4Uniform("projectionMatrix", camera.getProjectionMatrix()); - mPhongShader.setVector3Uniform("light0PosCameraSpace", worldToCameraMatrix * mLight0.getOrigin()); - mPhongShader.setVector3Uniform("lightAmbientColor", Vector3(0.3f, 0.3f, 0.3f)); - const Color& diffColLight0 = mLight0.getDiffuseColor(); - const Color& specColLight0 = mLight0.getSpecularColor(); - mPhongShader.setVector3Uniform("light0DiffuseColor", Vector3(diffColLight0.r, diffColLight0.g, diffColLight0.b)); - mPhongShader.setVector3Uniform("light0SpecularColor", Vector3(specColLight0.r, specColLight0.g, specColLight0.b)); - mPhongShader.setFloatUniform("shininess", 200.0f); - - if (mBox->getCollisionBody()->isActive()) mBox->render(mPhongShader, worldToCameraMatrix); - if (mSphere->getCollisionBody()->isActive()) mSphere->render(mPhongShader, worldToCameraMatrix); - if (mCone->getCollisionBody()->isActive()) mCone->render(mPhongShader, worldToCameraMatrix); - if (mCylinder->getCollisionBody()->isActive()) mCylinder->render(mPhongShader, worldToCameraMatrix); - if (mCapsule->getCollisionBody()->isActive()) mCapsule->render(mPhongShader, worldToCameraMatrix); - if (mConvexMesh->getCollisionBody()->isActive()) mConvexMesh->render(mPhongShader, worldToCameraMatrix); - if (mDumbbell->getCollisionBody()->isActive()) mDumbbell->render(mPhongShader, worldToCameraMatrix); - - mPhongShader.unbind(); - mPhongShader.bind(); - - mPhongShader.setVector3Uniform("light0SpecularColor", Vector3(0, 0, 0)); - openglframework::Vector4 redColor(1, 0, 0, 1); - mPhongShader.setVector4Uniform("vertexColor", redColor); - - // Render all the raycast hit points - mRaycastManager.render(mPhongShader, worldToCameraMatrix, mAreNormalsDisplayed); - - mPhongShader.unbind(); - mPhongShader.bind(); - - openglframework::Vector4 blueColor(0, 0.62, 0.92, 1); - mPhongShader.setVector4Uniform("vertexColor", blueColor); - - // Render the lines - for (std::vector::iterator it = mLines.begin(); it != mLines.end(); - ++it) { - (*it)->render(mPhongShader, worldToCameraMatrix); - } - - // Unbind the shader - mPhongShader.unbind(); -} diff --git a/examples/raycast/Scene.h b/examples/raycast/Scene.h deleted file mode 100644 index 9b044e06..00000000 --- a/examples/raycast/Scene.h +++ /dev/null @@ -1,200 +0,0 @@ -/******************************************************************************** -* ReactPhysics3D physics library, http://www.reactphysics3d.com * -* Copyright (c) 2010-2015 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -#ifndef SCENE_H -#define SCENE_H - -// Libraries -#define _USE_MATH_DEFINES -#include -#include "openglframework.h" -#include "reactphysics3d.h" -#include "Sphere.h" -#include "Box.h" -#include "Cone.h" -#include "Cylinder.h" -#include "Capsule.h" -#include "Line.h" -#include "ConvexMesh.h" -#include "Dumbbell.h" -#include "VisualContactPoint.h" -#include "../common/Viewer.h" - -// Constants -const openglframework::Vector3 BOX_SIZE(4, 2, 1); -const float SPHERE_RADIUS = 3.0f; -const float CONE_RADIUS = 3.0f; -const float CONE_HEIGHT = 5.0f; -const float CYLINDER_RADIUS = 3.0f; -const float CYLINDER_HEIGHT = 5.0f; -const float CAPSULE_RADIUS = 3.0f; -const float CAPSULE_HEIGHT = 5.0f; -const float DUMBBELL_HEIGHT = 5.0f; -const int NB_RAYS = 100; -const float RAY_LENGTH = 30.0f; -const int NB_BODIES = 7; - -// Raycast manager -class RaycastManager : public rp3d::RaycastCallback { - - private: - - /// All the visual contact points - std::vector mHitPoints; - - /// All the normals at hit points - std::vector mNormals; - - public: - - virtual rp3d::decimal notifyRaycastHit(const rp3d::RaycastInfo& raycastInfo) { - rp3d::Vector3 hitPos = raycastInfo.worldPoint; - openglframework::Vector3 position(hitPos.x, hitPos.y, hitPos.z); - VisualContactPoint* point = new VisualContactPoint(position); - mHitPoints.push_back(point); - - // Create a line to display the normal at hit point - rp3d::Vector3 n = raycastInfo.worldNormal; - openglframework::Vector3 normal(n.x, n.y, n.z); - Line* normalLine = new Line(position, position + normal); - mNormals.push_back(normalLine); - - return raycastInfo.hitFraction; - } - - void render(openglframework::Shader& shader, - const openglframework::Matrix4& worldToCameraMatrix, - bool showNormals) { - - // Render all the raycast hit points - for (std::vector::iterator it = mHitPoints.begin(); - it != mHitPoints.end(); ++it) { - (*it)->render(shader, worldToCameraMatrix); - } - - if (showNormals) { - - // Render all the normals at hit points - for (std::vector::iterator it = mNormals.begin(); - it != mNormals.end(); ++it) { - (*it)->render(shader, worldToCameraMatrix); - } - } - } - - void resetPoints() { - - // Destroy all the visual contact points - for (std::vector::iterator it = mHitPoints.begin(); - it != mHitPoints.end(); ++it) { - delete (*it); - } - mHitPoints.clear(); - - // Destroy all the normals - for (std::vector::iterator it = mNormals.begin(); - it != mNormals.end(); ++it) { - delete (*it); - } - mNormals.clear(); - } -}; - -// Class Scene -class Scene { - - private : - - // -------------------- Attributes -------------------- // - - /// Pointer to the viewer - Viewer* mViewer; - - /// Raycast manager - RaycastManager mRaycastManager; - - /// Light 0 - openglframework::Light mLight0; - - /// Phong shader - openglframework::Shader mPhongShader; - - /// All the raycast lines - std::vector mLines; - - /// Current body index - int mCurrentBodyIndex; - - /// True if the hit points normals are displayed - bool mAreNormalsDisplayed; - - /// Raycast manager - - /// All objects on the scene - Box* mBox; - Sphere* mSphere; - Cone* mCone; - Cylinder* mCylinder; - Capsule* mCapsule; - ConvexMesh* mConvexMesh; - Dumbbell* mDumbbell; - - /// Collision world used for the physics simulation - rp3d::CollisionWorld* mCollisionWorld; - - /// Create the raycast lines - void createLines(); - - public: - - // -------------------- Methods -------------------- // - - /// Constructor - Scene(Viewer* viewer, const std::string& shaderFolderPath, - const std::string& meshFolderPath); - - /// Destructor - ~Scene(); - - /// Take a step for the simulation - void simulate(); - - /// Render the scene - void render(); - - /// Change the body to raycast - void changeBody(); - - /// Display or not the surface normals at hit points - void showHideNormals(); -}; - -// Display or not the surface normals at hit points -inline void Scene::showHideNormals() { - mAreNormalsDisplayed = !mAreNormalsDisplayed; -} - - -#endif From e31c7abffc3740bfd7489cc86cbf875d8b405ec5 Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Wed, 15 Apr 2015 23:11:27 +0200 Subject: [PATCH 03/36] Add the example scenes to the testbed application --- testbed/CMakeLists.txt | 60 +++++-- .../examples/collisionshapes/CMakeLists.txt | 42 ----- .../collisionshapes/CollisionShapes.cpp | 152 ----------------- testbed/examples/cubes/CMakeLists.txt | 34 ---- testbed/examples/cubes/Cubes.cpp | 148 ----------------- testbed/examples/joints/CMakeLists.txt | 34 ---- testbed/examples/joints/Joints.cpp | 149 ----------------- testbed/examples/raycast/CMakeLists.txt | 43 ----- testbed/examples/raycast/Raycast.cpp | 155 ------------------ .../collisionshapes/CollisionShapesScene.cpp} | 141 ++++++++-------- .../collisionshapes/CollisionShapesScene.h} | 59 ++----- .../Scene.cpp => scenes/cubes/CubesScene.cpp} | 81 +++++---- .../Scene.h => scenes/cubes/CubesScene.h} | 62 ++----- .../joints/JointsScene.cpp} | 78 ++++----- .../Scene.h => scenes/joints/JointsScene.h} | 60 ++----- .../raycast/RaycastScene.cpp} | 34 ++-- .../Scene.h => scenes/raycast/RaycastScene.h} | 29 ++-- testbed/{ => src}/Gui.cpp | 10 ++ testbed/{ => src}/Gui.h | 0 testbed/{ => src}/Main.cpp | 0 testbed/{ => src}/Scene.cpp | 51 +++--- testbed/{ => src}/Scene.h | 23 ++- testbed/{ => src}/TestbedApplication.cpp | 76 ++++++++- testbed/{ => src}/TestbedApplication.h | 8 +- 24 files changed, 407 insertions(+), 1122 deletions(-) delete mode 100644 testbed/examples/collisionshapes/CMakeLists.txt delete mode 100644 testbed/examples/collisionshapes/CollisionShapes.cpp delete mode 100644 testbed/examples/cubes/CMakeLists.txt delete mode 100644 testbed/examples/cubes/Cubes.cpp delete mode 100644 testbed/examples/joints/CMakeLists.txt delete mode 100644 testbed/examples/joints/Joints.cpp delete mode 100644 testbed/examples/raycast/CMakeLists.txt delete mode 100644 testbed/examples/raycast/Raycast.cpp rename testbed/{examples/collisionshapes/Scene.cpp => scenes/collisionshapes/CollisionShapesScene.cpp} (83%) rename testbed/{examples/collisionshapes/Scene.h => scenes/collisionshapes/CollisionShapesScene.h} (80%) rename testbed/{examples/cubes/Scene.cpp => scenes/cubes/CubesScene.cpp} (79%) rename testbed/{examples/cubes/Scene.h => scenes/cubes/CubesScene.h} (75%) rename testbed/{examples/joints/Scene.cpp => scenes/joints/JointsScene.cpp} (89%) rename testbed/{examples/joints/Scene.h => scenes/joints/JointsScene.h} (82%) rename testbed/{examples/raycast/Scene.cpp => scenes/raycast/RaycastScene.cpp} (93%) rename testbed/{examples/raycast/Scene.h => scenes/raycast/RaycastScene.h} (94%) rename testbed/{ => src}/Gui.cpp (96%) rename testbed/{ => src}/Gui.h (100%) rename testbed/{ => src}/Main.cpp (100%) rename testbed/{ => src}/Scene.cpp (82%) rename testbed/{ => src}/Scene.h (88%) rename testbed/{ => src}/TestbedApplication.cpp (77%) rename testbed/{ => src}/TestbedApplication.h (96%) diff --git a/testbed/CMakeLists.txt b/testbed/CMakeLists.txt index 1d0365f3..b5b2fdd7 100644 --- a/testbed/CMakeLists.txt +++ b/testbed/CMakeLists.txt @@ -16,23 +16,59 @@ ADD_SUBDIRECTORY(glfw/) # Copy the shaders used for the demo into the build directory FILE(COPY "shaders/" DESTINATION "${EXECUTABLE_OUTPUT_PATH}/shaders/") -# Headers -MESSAGE("Test" "${OPENGLFRAMEWORK_DIR}") -INCLUDE_DIRECTORIES("opengl-framework/src/" "glfw/include/" "common/") +# Copy the meshes used for the demo into the build directory +FILE(COPY "meshes/" DESTINATION "${EXECUTABLE_OUTPUT_PATH}/meshes/") -# Source files +# Headers +INCLUDE_DIRECTORIES("src" "opengl-framework/src/" "glfw/include/" "common/" "scenes/") + +# Testbed source files SET(TESTBED_SOURCES - Main.cpp - TestbedApplication.h - TestbedApplication.cpp - Gui.h - Gui.cpp - Scene.h - Scene.cpp + src/Main.cpp + src/TestbedApplication.h + src/TestbedApplication.cpp + src/Gui.h + src/Gui.cpp + src/Scene.h + src/Scene.cpp +) + +# Common source files +SET(COMMON_SOURCES + common/Box.h + common/Box.cpp + common/Cone.h + common/Cone.cpp + common/Sphere.h + common/Sphere.cpp + common/Line.h + common/Line.cpp + common/Capsule.h + common/Capsule.cpp + common/ConvexMesh.h + common/ConvexMesh.cpp + common/Cylinder.h + common/Cylinder.cpp + common/Dumbbell.h + common/Dumbbell.cpp + common/VisualContactPoint.h + common/VisualContactPoint.cpp +) + +# Examples scenes source files +SET(SCENES_SOURCES + scenes/cubes/CubesScene.h + scenes/cubes/CubesScene.cpp + scenes/joints/JointsScene.h + scenes/joints/JointsScene.cpp + scenes/raycast/RaycastScene.h + scenes/raycast/RaycastScene.cpp + scenes/collisionshapes/CollisionShapesScene.h + scenes/collisionshapes/CollisionShapesScene.cpp ) # Create the executable -ADD_EXECUTABLE(testbed ${TESTBED_SOURCES}) +ADD_EXECUTABLE(testbed ${TESTBED_SOURCES} ${SCENES_SOURCES} ${COMMON_SOURCES}) # Link with libraries TARGET_LINK_LIBRARIES(testbed reactphysics3d openglframework glfw ${GLFW_LIBRARIES}) diff --git a/testbed/examples/collisionshapes/CMakeLists.txt b/testbed/examples/collisionshapes/CMakeLists.txt deleted file mode 100644 index 6bdd5d3e..00000000 --- a/testbed/examples/collisionshapes/CMakeLists.txt +++ /dev/null @@ -1,42 +0,0 @@ -# Minimum cmake version required -cmake_minimum_required(VERSION 2.6) - -# Project configuration -PROJECT(CollisionShapes) - -# Where to build the executables -SET(EXECUTABLE_OUTPUT_PATH "${OUR_EXECUTABLE_OUTPUT_PATH}/collisionshapes") -SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}) -SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${EXECUTABLE_OUTPUT_PATH}) -SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${EXECUTABLE_OUTPUT_PATH}) - -# Copy the shaders used for the demo into the build directory -FILE(COPY "${OPENGLFRAMEWORK_DIR}/src/shaders/" DESTINATION "${EXECUTABLE_OUTPUT_PATH}/shaders/") - -# Copy the meshes used for the demo into the build directory -FILE(COPY "../common/meshes/" DESTINATION "${EXECUTABLE_OUTPUT_PATH}/meshes/") - -# Headers -INCLUDE_DIRECTORIES("${OPENGLFRAMEWORK_DIR}/src/" "../common/glfw/include/" "../common/") - -# Source files -SET(COLLISION_SHAPES_SOURCES - CollisionShapes.cpp - Scene.cpp - Scene.h - "../common/VisualContactPoint.cpp" - "../common/ConvexMesh.cpp" - "../common/Capsule.cpp" - "../common/Sphere.cpp" - "../common/Cylinder.cpp" - "../common/Cone.cpp" - "../common/Dumbbell.cpp" - "../common/Box.cpp" - "../common/Viewer.cpp" -) - -# Create the executable -ADD_EXECUTABLE(collisionshapes ${COLLISION_SHAPES_SOURCES}) - -# Link with libraries -TARGET_LINK_LIBRARIES(collisionshapes reactphysics3d openglframework glfw ${GLFW_LIBRARIES}) diff --git a/testbed/examples/collisionshapes/CollisionShapes.cpp b/testbed/examples/collisionshapes/CollisionShapes.cpp deleted file mode 100644 index f8affc1d..00000000 --- a/testbed/examples/collisionshapes/CollisionShapes.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/******************************************************************************** -* ReactPhysics3D physics library, http://www.reactphysics3d.com * -* Copyright (c) 2010-2015 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -// Libraries -#include "Scene.h" -#include "../common/Viewer.h" - -// Declarations -void simulate(); -void render(); -void update(); -void mouseButton(GLFWwindow* window, int button, int action, int mods); -void mouseMotion(GLFWwindow* window, double x, double y); -void keyboard(GLFWwindow* window, int key, int scancode, int action, int mods); -void scroll(GLFWwindow* window, double xAxis, double yAxis); -void init(); - -// Namespaces -using namespace openglframework; - -// Global variables -Viewer* viewer; -Scene* scene; - -// Main function -int main(int argc, char** argv) { - - // Create and initialize the Viewer - viewer = new Viewer(); - Vector2 windowsSize = Vector2(800, 600); - Vector2 windowsPosition = Vector2(100, 100); - viewer->init(argc, argv, "ReactPhysics3D Examples - Collision Shapes", - windowsSize, windowsPosition, true); - - // If the shaders and meshes folders are not specified as an argument - if (argc < 3) { - std::cerr << "Error : You need to specify the shaders folder as the first argument" - << " and the meshes folder as the second argument" << std::endl; - return 1; - } - - // Get the path of the shaders folder - std::string shaderFolderPath(argv[1]); - std::string meshFolderPath(argv[2]); - - // Register callback methods - viewer->registerUpdateFunction(update); - viewer->registerKeyboardCallback(keyboard); - viewer->registerMouseButtonCallback(mouseButton); - viewer->registerMouseCursorCallback(mouseMotion); - viewer->registerScrollingCallback(scroll); - - // Create the scene - scene = new Scene(viewer, shaderFolderPath, meshFolderPath); - - init(); - - viewer->startMainLoop(); - - delete viewer; - delete scene; - - return 0; -} - -// Update function that is called each frame -void update() { - - // Take a simulation step - simulate(); - - // Render - render(); -} - -// Simulate function -void simulate() { - - // Physics simulation - scene->simulate(); - - viewer->computeFPS(); -} - -// Initialization -void init() { - - // Define the background color (black) - glClearColor(0.0, 0.0, 0.0, 1.0); -} - -// Callback method to receive keyboard events -void keyboard(GLFWwindow* window, int key, int scancode, int action, int mods) { - if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) { - glfwSetWindowShouldClose(window, GL_TRUE); - } - else if (key == GLFW_KEY_SPACE && action == GLFW_PRESS) { - scene->pauseContinueSimulation(); - } -} - -// Callback method to receive scrolling events -void scroll(GLFWwindow* window, double xAxis, double yAxis) { - viewer->scrollingEvent(static_cast(yAxis)); -} - -// Called when a mouse button event occurs -void mouseButton(GLFWwindow* window, int button, int action, int mods) { - viewer->mouseButtonEvent(button, action); -} - -// Called when a mouse motion event occurs -void mouseMotion(GLFWwindow* window, double x, double y) { - viewer->mouseMotionEvent(x, y); -} - -// Display the scene -void render() { - - // Render the scene - scene->render(); - - // Display the FPS - viewer->displayGUI(); - - // Check the OpenGL errors - Viewer::checkOpenGLErrors(); -} - - diff --git a/testbed/examples/cubes/CMakeLists.txt b/testbed/examples/cubes/CMakeLists.txt deleted file mode 100644 index 5239dc56..00000000 --- a/testbed/examples/cubes/CMakeLists.txt +++ /dev/null @@ -1,34 +0,0 @@ -# Minimum cmake version required -cmake_minimum_required(VERSION 2.6) - -# Project configuration -PROJECT(Cubes) - -# Where to build the executables -SET(EXECUTABLE_OUTPUT_PATH "${OUR_EXECUTABLE_OUTPUT_PATH}/cubes") -SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}) -SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${EXECUTABLE_OUTPUT_PATH}) -SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${EXECUTABLE_OUTPUT_PATH}) - -# Copy the shaders used for the demo into the build directory -FILE(COPY "${OPENGLFRAMEWORK_DIR}/src/shaders/" DESTINATION "${EXECUTABLE_OUTPUT_PATH}/shaders/") - -# Headers -INCLUDE_DIRECTORIES("${OPENGLFRAMEWORK_DIR}/src/" "../common/glfw/include/" "../common/") - -# Source files -SET(CUBES_SOURCES - Cubes.cpp - Scene.cpp - Scene.h - "../common/Box.cpp" - "../common/Box.h" - "../common/Viewer.cpp" - "../common/Viewer.h" -) - -# Create the executable -ADD_EXECUTABLE(cubes ${CUBES_SOURCES}) - -# Link with libraries -TARGET_LINK_LIBRARIES(cubes reactphysics3d openglframework glfw ${GLFW_LIBRARIES}) diff --git a/testbed/examples/cubes/Cubes.cpp b/testbed/examples/cubes/Cubes.cpp deleted file mode 100644 index f00cda72..00000000 --- a/testbed/examples/cubes/Cubes.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/******************************************************************************** -* ReactPhysics3D physics library, http://www.reactphysics3d.com * -* Copyright (c) 2010-2015 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -// Libraries -#include "Scene.h" -#include "Viewer.h" - -// Declarations -void simulate(); -void render(); -void update(); -void mouseButton(GLFWwindow* window, int button, int action, int mods); -void mouseMotion(GLFWwindow* window, double x, double y); -void keyboard(GLFWwindow* window, int key, int scancode, int action, int mods); -void scroll(GLFWwindow* window, double xAxis, double yAxis); -void init(); - -// Namespaces -using namespace openglframework; - -// Global variables -Viewer* viewer; -Scene* scene; - -// Main function -int main(int argc, char** argv) { - - // Create and initialize the Viewer - viewer = new Viewer(); - Vector2 windowsSize = Vector2(800, 600); - Vector2 windowsPosition = Vector2(100, 100); - viewer->init(argc, argv, "ReactPhysics3D Examples - Cubes", windowsSize, windowsPosition, true); - - // If the shaders folder is not specified as an argument - if (argc < 2) { - std::cerr << "Error : You need to specify the shaders folder as argument !" << std::endl; - return 1; - } - - // Get the path of the shaders folder - std::string shaderFolderPath(argv[1]); - - // Register callback methods - viewer->registerUpdateFunction(update); - viewer->registerKeyboardCallback(keyboard); - viewer->registerMouseButtonCallback(mouseButton); - viewer->registerMouseCursorCallback(mouseMotion); - viewer->registerScrollingCallback(scroll); - - // Create the scene - scene = new Scene(viewer, shaderFolderPath); - - init(); - - viewer->startMainLoop(); - - delete viewer; - delete scene; - - return 0; -} - -// Update function that is called each frame -void update() { - - // Take a simulation step - simulate(); - - // Render - render(); -} - -// Simulate function -void simulate() { - - // Physics simulation - scene->simulate(); - - // Compute the current framerate - viewer->computeFPS(); -} - -// Initialization -void init() { - - // Define the background color (black) - glClearColor(0.0, 0.0, 0.0, 1.0); -} - -// Callback method to receive keyboard events -void keyboard(GLFWwindow* window, int key, int scancode, int action, int mods) { - if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) { - glfwSetWindowShouldClose(window, GL_TRUE); - } - else if (key == GLFW_KEY_SPACE && action == GLFW_PRESS) { - scene->pauseContinueSimulation(); - } -} - -// Callback method to receive scrolling events -void scroll(GLFWwindow* window, double xAxis, double yAxis) { - viewer->scrollingEvent(static_cast(yAxis)); -} - -// Called when a mouse button event occurs -void mouseButton(GLFWwindow* window, int button, int action, int mods) { - viewer->mouseButtonEvent(button, action); -} - -// Called when a mouse motion event occurs -void mouseMotion(GLFWwindow* window, double x, double y) { - viewer->mouseMotionEvent(x, y); -} - -// Display the scene -void render() { - - // Render the scene - scene->render(); - - // Display the FPS - viewer->displayGUI(); - - // Check the OpenGL errors - Viewer::checkOpenGLErrors(); -} diff --git a/testbed/examples/joints/CMakeLists.txt b/testbed/examples/joints/CMakeLists.txt deleted file mode 100644 index ba304b9d..00000000 --- a/testbed/examples/joints/CMakeLists.txt +++ /dev/null @@ -1,34 +0,0 @@ -# Minimum cmake version required -cmake_minimum_required(VERSION 2.6) - -# Project configuration -PROJECT(Joints) - -# Where to build the executables -SET(EXECUTABLE_OUTPUT_PATH "${OUR_EXECUTABLE_OUTPUT_PATH}/joints") -SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}) -SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${EXECUTABLE_OUTPUT_PATH}) -SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${EXECUTABLE_OUTPUT_PATH}) - -# Copy the shaders used for the demo into the build directory -FILE(COPY "${OPENGLFRAMEWORK_DIR}/src/shaders/" DESTINATION "${EXECUTABLE_OUTPUT_PATH}/shaders/") - -# Headers -INCLUDE_DIRECTORIES("${OPENGLFRAMEWORK_DIR}/src/" "../common/glfw/include/" "../common/") - -# Source files -SET(JOINTS_SOURCES - Joints.cpp - Scene.cpp - Scene.h - "../common/Box.cpp" - "../common/Box.h" - "../common/Viewer.cpp" - "../common/Viewer.h" -) - -# Create the executable -ADD_EXECUTABLE(joints ${JOINTS_SOURCES}) - -# Link with libraries -TARGET_LINK_LIBRARIES(joints reactphysics3d openglframework glfw ${GLFW_LIBRARIES}) diff --git a/testbed/examples/joints/Joints.cpp b/testbed/examples/joints/Joints.cpp deleted file mode 100644 index 1b1b7e00..00000000 --- a/testbed/examples/joints/Joints.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/******************************************************************************** -* ReactPhysics3D physics library, http://www.reactphysics3d.com * -* Copyright (c) 2010-2015 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -// Libraries -#include "Scene.h" -#include "../common/Viewer.h" - -// Declarations -void simulate(); -void update(); -void render(); -void mouseButton(GLFWwindow* window, int button, int action, int mods); -void mouseMotion(GLFWwindow* window, double x, double y); -void keyboard(GLFWwindow* window, int key, int scancode, int action, int mods); -void scroll(GLFWwindow* window, double xAxis, double yAxis); -void init(); - -// Namespaces -using namespace openglframework; - -// Global variables -Viewer* viewer; -Scene* scene; - -// Main function -int main(int argc, char** argv) { - - // Create and initialize the Viewer - viewer = new Viewer(); - Vector2 windowsSize = Vector2(800, 600); - Vector2 windowsPosition = Vector2(100, 100); - viewer->init(argc, argv, "ReactPhysics3D Examples - Joints", windowsSize, windowsPosition, true); - - // If the shaders folder is not specified as an argument - if (argc < 2) { - std::cerr << "Error : You need to specify the shaders folder as argument !" << std::endl; - return 1; - } - - // Get the path of the shaders folder - std::string shaderFolderPath(argv[1]); - - // Register callback methods - viewer->registerUpdateFunction(update); - viewer->registerKeyboardCallback(keyboard); - viewer->registerMouseButtonCallback(mouseButton); - viewer->registerMouseCursorCallback(mouseMotion); - viewer->registerScrollingCallback(scroll); - - // Create the scene - scene = new Scene(viewer, shaderFolderPath); - - init(); - - viewer->startMainLoop(); - - delete viewer; - delete scene; - - return 0; -} - -// Update function that is called each frame -void update() { - - // Take a simulation step - simulate(); - - // Render - render(); -} - -// Simulate function -void simulate() { - - // Physics simulation - scene->simulate(); - - viewer->computeFPS(); -} - -// Initialization -void init() { - - // Define the background color (black) - glClearColor(0.0, 0.0, 0.0, 1.0); -} - -// Callback method to receive keyboard events -void keyboard(GLFWwindow* window, int key, int scancode, int action, int mods) { - if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) { - glfwSetWindowShouldClose(window, GL_TRUE); - } - else if (key == GLFW_KEY_SPACE && action == GLFW_PRESS) { - scene->pauseContinueSimulation(); - } -} - -// Callback method to receive scrolling events -void scroll(GLFWwindow* window, double xAxis, double yAxis) { - viewer->scrollingEvent(static_cast(yAxis)); -} - -// Called when a mouse button event occurs -void mouseButton(GLFWwindow* window, int button, int action, int mods) { - viewer->mouseButtonEvent(button, action); -} - -// Called when a mouse motion event occurs -void mouseMotion(GLFWwindow* window, double x, double y) { - viewer->mouseMotionEvent(x, y); -} - -// Display the scene -void render() { - - // Render the scene - scene->render(); - - // Display the FPS - viewer->displayGUI(); - - // Check the OpenGL errors - Viewer::checkOpenGLErrors(); -} - - diff --git a/testbed/examples/raycast/CMakeLists.txt b/testbed/examples/raycast/CMakeLists.txt deleted file mode 100644 index 01440b00..00000000 --- a/testbed/examples/raycast/CMakeLists.txt +++ /dev/null @@ -1,43 +0,0 @@ -# Minimum cmake version required -cmake_minimum_required(VERSION 2.6) - -# Project configuration -PROJECT(Raycast) - -# Where to build the executables -SET(EXECUTABLE_OUTPUT_PATH "${OUR_EXECUTABLE_OUTPUT_PATH}/raycast") -SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}) -SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${EXECUTABLE_OUTPUT_PATH}) -SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${EXECUTABLE_OUTPUT_PATH}) - -# Copy the shaders used for the demo into the build directory -FILE(COPY "${OPENGLFRAMEWORK_DIR}/src/shaders/" DESTINATION "${EXECUTABLE_OUTPUT_PATH}/shaders/") - -# Copy the meshes used for the demo into the build directory -FILE(COPY "../common/meshes/" DESTINATION "${EXECUTABLE_OUTPUT_PATH}/meshes/") - -# Headers -INCLUDE_DIRECTORIES("${OPENGLFRAMEWORK_DIR}/src/" "../common/glfw/include/" "../common/") - -# Source files -SET(RAYCAST_SOURCES - Raycast.cpp - Scene.cpp - Scene.h - "../common/VisualContactPoint.cpp" - "../common/ConvexMesh.cpp" - "../common/Capsule.cpp" - "../common/Sphere.cpp" - "../common/Line.cpp" - "../common/Cylinder.cpp" - "../common/Cone.cpp" - "../common/Dumbbell.cpp" - "../common/Box.cpp" - "../common/Viewer.cpp" -) - -# Create the executable -ADD_EXECUTABLE(raycast ${RAYCAST_SOURCES}) - -# Link with libraries -TARGET_LINK_LIBRARIES(raycast reactphysics3d openglframework glfw ${GLFW_LIBRARIES}) diff --git a/testbed/examples/raycast/Raycast.cpp b/testbed/examples/raycast/Raycast.cpp deleted file mode 100644 index e971069a..00000000 --- a/testbed/examples/raycast/Raycast.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/******************************************************************************** -* ReactPhysics3D physics library, http://www.reactphysics3d.com * -* Copyright (c) 2010-2015 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -// Libraries -#include "Scene.h" -#include "../common/Viewer.h" - -// Declarations -void simulate(); -void render(); -void update(); -void mouseButton(GLFWwindow* window, int button, int action, int mods); -void mouseMotion(GLFWwindow* window, double x, double y); -void keyboard(GLFWwindow* window, int key, int scancode, int action, int mods); -void scroll(GLFWwindow* window, double xAxis, double yAxis); -void init(); - -// Namespaces -using namespace openglframework; - -// Global variables -Viewer* viewer; -Scene* scene; - -// Main function -int main(int argc, char** argv) { - - // Create and initialize the Viewer - viewer = new Viewer(); - Vector2 windowsSize = Vector2(800, 600); - Vector2 windowsPosition = Vector2(100, 100); - viewer->init(argc, argv, "ReactPhysics3D Examples - Raycast", - windowsSize, windowsPosition, true); - - // If the shaders and meshes folders are not specified as an argument - if (argc < 3) { - std::cerr << "Error : You need to specify the shaders folder as the first argument" - << " and the meshes folder as the second argument" << std::endl; - return 1; - } - - // Get the path of the shaders folder - std::string shaderFolderPath(argv[1]); - std::string meshFolderPath(argv[2]); - - // Register callback methods - viewer->registerUpdateFunction(update); - viewer->registerKeyboardCallback(keyboard); - viewer->registerMouseButtonCallback(mouseButton); - viewer->registerMouseCursorCallback(mouseMotion); - viewer->registerScrollingCallback(scroll); - - // Create the scene - scene = new Scene(viewer, shaderFolderPath, meshFolderPath); - - init(); - - viewer->startMainLoop(); - - delete viewer; - delete scene; - - return 0; -} - -// Update function that is called each frame -void update() { - - // Take a simulation step - simulate(); - - // Render - render(); -} - -// Simulate function -void simulate() { - - // Physics simulation - scene->simulate(); - - viewer->computeFPS(); -} - -// Initialization -void init() { - - // Define the background color (black) - glClearColor(0.0, 0.0, 0.0, 1.0); -} - -// Callback method to receive keyboard events -void keyboard(GLFWwindow* window, int key, int scancode, int action, int mods) { - if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) { - glfwSetWindowShouldClose(window, GL_TRUE); - } - if (key == GLFW_KEY_SPACE && action == GLFW_PRESS) { - scene->changeBody(); - } - if (key == GLFW_KEY_N && action == GLFW_PRESS) { - scene->showHideNormals(); - } -} - -// Callback method to receive scrolling events -void scroll(GLFWwindow* window, double xAxis, double yAxis) { - viewer->scrollingEvent(static_cast(yAxis)); -} - -// Called when a mouse button event occurs -void mouseButton(GLFWwindow* window, int button, int action, int mods) { - viewer->mouseButtonEvent(button, action); -} - -// Called when a mouse motion event occurs -void mouseMotion(GLFWwindow* window, double x, double y) { - viewer->mouseMotionEvent(x, y); -} - -// Display the scene -void render() { - - // Render the scene - scene->render(); - - // Display the FPS - viewer->displayGUI(); - - // Check the OpenGL errors - Viewer::checkOpenGLErrors(); -} - - diff --git a/testbed/examples/collisionshapes/Scene.cpp b/testbed/scenes/collisionshapes/CollisionShapesScene.cpp similarity index 83% rename from testbed/examples/collisionshapes/Scene.cpp rename to testbed/scenes/collisionshapes/CollisionShapesScene.cpp index 740a48e6..b6bebe79 100644 --- a/testbed/examples/collisionshapes/Scene.cpp +++ b/testbed/scenes/collisionshapes/CollisionShapesScene.cpp @@ -24,16 +24,17 @@ ********************************************************************************/ // Libraries -#include "Scene.h" +#include "CollisionShapesScene.h" // Namespaces using namespace openglframework; +using namespace collisionshapesscene; // Constructor -Scene::Scene(Viewer* viewer, const std::string& shaderFolderPath, const std::string& meshFolderPath) - : mViewer(viewer), mLight0(0), - mPhongShader(shaderFolderPath + "phong.vert", - shaderFolderPath +"phong.frag"), mIsRunning(false) { +CollisionShapesScene::CollisionShapesScene(const std::string& name) + : Scene(name), mLight0(0), mPhongShader("shaders/phong.vert", "shaders/phong.frag") { + + std::string meshFolderPath("meshes/"); // Move the light 0 mLight0.translateWorld(Vector3(50, 50, 50)); @@ -43,7 +44,7 @@ Scene::Scene(Viewer* viewer, const std::string& shaderFolderPath, const std::str openglframework::Vector3 center(0, 5, 0); // Set the center of the scene - mViewer->setScenePosition(center, radiusScene); + setScenePosition(center, radiusScene); // Gravity vector in the dynamics world rp3d::Vector3 gravity(0, -9.81, 0); @@ -217,14 +218,11 @@ Scene::Scene(Viewer* viewer, const std::string& shaderFolderPath, const std::str material.setBounciness(rp3d::decimal(0.2)); // Start the simulation - startSimulation(); + mDynamicsWorld->start(); } // Destructor -Scene::~Scene() { - - // Stop the physics simulation - stopSimulation(); +CollisionShapesScene::~CollisionShapesScene() { // Destroy the shader mPhongShader.destroy(); @@ -312,85 +310,81 @@ Scene::~Scene() { } // Take a step for the simulation -void Scene::simulate() { +void CollisionShapesScene::update() { - // If the physics simulation is running - if (mIsRunning) { - // Take a simulation step - mDynamicsWorld->update(); + // Take a simulation step + mDynamicsWorld->update(); - // Update the position and orientation of the boxes - for (std::vector::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { + // Update the position and orientation of the boxes + for (std::vector::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { - // Update the transform used for the rendering - (*it)->updateTransform(); - } - - // Update the position and orientation of the sphere - for (std::vector::iterator it = mSpheres.begin(); it != mSpheres.end(); ++it) { - - // Update the transform used for the rendering - (*it)->updateTransform(); - } - - // Update the position and orientation of the cones - for (std::vector::iterator it = mCones.begin(); it != mCones.end(); ++it) { - - // Update the transform used for the rendering - (*it)->updateTransform(); - } - - // Update the position and orientation of the cylinders - for (std::vector::iterator it = mCylinders.begin(); it != mCylinders.end(); ++it) { - - // Update the transform used for the rendering - (*it)->updateTransform(); - } - - // Update the position and orientation of the capsules - for (std::vector::iterator it = mCapsules.begin(); it != mCapsules.end(); ++it) { - - // Update the transform used for the rendering - (*it)->updateTransform(); - } - - // Update the position and orientation of the convex meshes - for (std::vector::iterator it = mConvexMeshes.begin(); - it != mConvexMeshes.end(); ++it) { - - // Update the transform used for the rendering - (*it)->updateTransform(); - } - - // Update the position and orientation of the dumbbells - for (std::vector::iterator it = mDumbbells.begin(); - it != mDumbbells.end(); ++it) { - - // Update the transform used for the rendering - (*it)->updateTransform(); - } - - mFloor->updateTransform(); + // Update the transform used for the rendering + (*it)->updateTransform(); } + + // Update the position and orientation of the sphere + for (std::vector::iterator it = mSpheres.begin(); it != mSpheres.end(); ++it) { + + // Update the transform used for the rendering + (*it)->updateTransform(); + } + + // Update the position and orientation of the cones + for (std::vector::iterator it = mCones.begin(); it != mCones.end(); ++it) { + + // Update the transform used for the rendering + (*it)->updateTransform(); + } + + // Update the position and orientation of the cylinders + for (std::vector::iterator it = mCylinders.begin(); it != mCylinders.end(); ++it) { + + // Update the transform used for the rendering + (*it)->updateTransform(); + } + + // Update the position and orientation of the capsules + for (std::vector::iterator it = mCapsules.begin(); it != mCapsules.end(); ++it) { + + // Update the transform used for the rendering + (*it)->updateTransform(); + } + + // Update the position and orientation of the convex meshes + for (std::vector::iterator it = mConvexMeshes.begin(); + it != mConvexMeshes.end(); ++it) { + + // Update the transform used for the rendering + (*it)->updateTransform(); + } + + // Update the position and orientation of the dumbbells + for (std::vector::iterator it = mDumbbells.begin(); + it != mDumbbells.end(); ++it) { + + // Update the transform used for the rendering + (*it)->updateTransform(); + } + + mFloor->updateTransform(); } // Render the scene -void Scene::render() { +void CollisionShapesScene::render() { glEnable(GL_DEPTH_TEST); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_CULL_FACE); // Get the world-space to camera-space matrix - const Camera& camera = mViewer->getCamera(); - const openglframework::Matrix4 worldToCameraMatrix = camera.getTransformMatrix().getInverse(); + const openglframework::Matrix4 worldToCameraMatrix = mCamera.getTransformMatrix().getInverse(); // Bind the shader mPhongShader.bind(); // Set the variables of the shader - mPhongShader.setMatrix4x4Uniform("projectionMatrix", camera.getProjectionMatrix()); + mPhongShader.setMatrix4x4Uniform("projectionMatrix", mCamera.getProjectionMatrix()); mPhongShader.setVector3Uniform("light0PosCameraSpace", worldToCameraMatrix * mLight0.getOrigin()); mPhongShader.setVector3Uniform("lightAmbientColor", Vector3(0.3f, 0.3f, 0.3f)); const Color& diffColLight0 = mLight0.getDiffuseColor(); @@ -442,3 +436,8 @@ void Scene::render() { // Unbind the shader mPhongShader.unbind(); } + +/// Reset the scene +void CollisionShapesScene::reset() { + +} diff --git a/testbed/examples/collisionshapes/Scene.h b/testbed/scenes/collisionshapes/CollisionShapesScene.h similarity index 80% rename from testbed/examples/collisionshapes/Scene.h rename to testbed/scenes/collisionshapes/CollisionShapesScene.h index 61a2e7a7..a9b79e45 100644 --- a/testbed/examples/collisionshapes/Scene.h +++ b/testbed/scenes/collisionshapes/CollisionShapesScene.h @@ -23,12 +23,13 @@ * * ********************************************************************************/ -#ifndef SCENE_H -#define SCENE_H +#ifndef COLLISION_SHAPES_SCENE_H +#define COLLISION_SHAPES_SCENE_H // Libraries #include "openglframework.h" #include "reactphysics3d.h" +#include "Scene.h" #include "Sphere.h" #include "Box.h" #include "Cone.h" @@ -39,6 +40,9 @@ #include "VisualContactPoint.h" #include "../common/Viewer.h" +namespace collisionshapesscene { + + // Constants const int NB_BOXES = 2; const int NB_CUBES = 1; @@ -64,16 +68,13 @@ const float CAPSULE_MASS = 1.0f; const float MESH_MASS = 1.0f; const float FLOOR_MASS = 100.0f; // Floor mass in kilograms -// Class Scene -class Scene { +// Class CollisionShapesScene +class CollisionShapesScene : public Scene{ private : // -------------------- Attributes -------------------- // - /// Pointer to the viewer - Viewer* mViewer; - /// Light 0 openglframework::Light mLight0; @@ -103,56 +104,26 @@ class Scene { /// Dynamics world used for the physics simulation rp3d::DynamicsWorld* mDynamicsWorld; - /// True if the physics simulation is running - bool mIsRunning; - public: // -------------------- Methods -------------------- // /// Constructor - Scene(Viewer* viewer, const std::string& shaderFolderPath, - const std::string& meshFolderPath); + CollisionShapesScene(const std::string& name); /// Destructor - ~Scene(); + virtual ~CollisionShapesScene(); /// Take a step for the simulation - void simulate(); - - /// Stop the simulation - void stopSimulation(); - - /// Start the simulation - void startSimulation(); - - /// Pause or continue simulation - void pauseContinueSimulation(); + virtual void update(); /// Render the scene - void render(); + virtual void render(); + + /// Reset the scene + virtual void reset(); }; -// Stop the simulation -inline void Scene::stopSimulation() { - mDynamicsWorld->stop(); - mIsRunning = false; -} - -// Start the simulation -inline void Scene::startSimulation() { - mDynamicsWorld->start(); - mIsRunning = true; -} - -// Pause or continue simulation -inline void Scene::pauseContinueSimulation() { - if (mIsRunning) { - stopSimulation(); - } - else { - startSimulation(); - } } #endif diff --git a/testbed/examples/cubes/Scene.cpp b/testbed/scenes/cubes/CubesScene.cpp similarity index 79% rename from testbed/examples/cubes/Scene.cpp rename to testbed/scenes/cubes/CubesScene.cpp index 073ab02b..eb31d77e 100644 --- a/testbed/examples/cubes/Scene.cpp +++ b/testbed/scenes/cubes/CubesScene.cpp @@ -24,16 +24,16 @@ ********************************************************************************/ // Libraries -#include "Scene.h" +#include "CubesScene.h" // Namespaces using namespace openglframework; +using namespace cubesscene; // Constructor -Scene::Scene(Viewer* viewer, const std::string& shaderFolderPath) - : mViewer(viewer), mLight0(0), - mPhongShader(shaderFolderPath + "phong.vert", shaderFolderPath + "phong.frag"), - mIsRunning(false) { +CubesScene::CubesScene(const std::string& name) + : Scene(name), mLight0(0), + mPhongShader("shaders/phong.vert", "shaders/phong.frag") { // Move the light 0 mLight0.translateWorld(Vector3(7, 15, 15)); @@ -43,7 +43,7 @@ Scene::Scene(Viewer* viewer, const std::string& shaderFolderPath) openglframework::Vector3 center(0, 5, 0); // Set the center of the scene - mViewer->setScenePosition(center, radiusScene); + setScenePosition(center, radiusScene); // Gravity vector in the dynamics world rp3d::Vector3 gravity(0, rp3d::decimal(-5.81), 0); @@ -91,16 +91,15 @@ Scene::Scene(Viewer* viewer, const std::string& shaderFolderPath) material.setBounciness(rp3d::decimal(0.3)); // Start the simulation - startSimulation(); + mDynamicsWorld->start(); counter=0; } // Destructor -Scene::~Scene() { +CubesScene::~CubesScene() { - // Stop the physics simulation - stopSimulation(); + mDynamicsWorld->stop(); // Destroy the shader mPhongShader.destroy(); @@ -126,56 +125,51 @@ Scene::~Scene() { } // Take a step for the simulation -void Scene::simulate() { +void CubesScene::update() { - // If the physics simulation is running - if (mIsRunning) { + counter++; + if (counter == 400) { + //mIsRunning = false; + } - counter++; - if (counter == 400) { - //mIsRunning = false; + // Take a simulation step + mDynamicsWorld->update(); + + // Update the position and orientation of the boxes + for (std::vector::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { + + // Update the transform used for the rendering + (*it)->updateTransform(); + } + + mFloor->updateTransform(); + + // Set the color of the awake/sleeping bodies + for (uint i=0; igetRigidBody()->isSleeping()) { + mBoxes[i]->setColor(Color(1, 0, 0, 1)); } - - // Take a simulation step - mDynamicsWorld->update(); - - // Update the position and orientation of the boxes - for (std::vector::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { - - // Update the transform used for the rendering - (*it)->updateTransform(); - } - - mFloor->updateTransform(); - - // Set the color of the awake/sleeping bodies - for (uint i=0; igetRigidBody()->isSleeping()) { - mBoxes[i]->setColor(Color(1, 0, 0, 1)); - } - else { - mBoxes[i]->setColor(Color(0, 1, 0, 1)); - } + else { + mBoxes[i]->setColor(Color(0, 1, 0, 1)); } } } // Render the scene -void Scene::render() { +void CubesScene::render() { glEnable(GL_DEPTH_TEST); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_CULL_FACE); // Get the world-space to camera-space matrix - const Camera& camera = mViewer->getCamera(); - const openglframework::Matrix4 worldToCameraMatrix = camera.getTransformMatrix().getInverse(); + const openglframework::Matrix4 worldToCameraMatrix = mCamera.getTransformMatrix().getInverse(); // Bind the shader mPhongShader.bind(); // Set the variables of the shader - mPhongShader.setMatrix4x4Uniform("projectionMatrix", camera.getProjectionMatrix()); + mPhongShader.setMatrix4x4Uniform("projectionMatrix", mCamera.getProjectionMatrix()); mPhongShader.setVector3Uniform("light0PosCameraSpace",worldToCameraMatrix * mLight0.getOrigin()); mPhongShader.setVector3Uniform("lightAmbientColor", Vector3(0.3f, 0.3f, 0.3f)); const Color& diffCol = mLight0.getDiffuseColor(); @@ -195,3 +189,8 @@ void Scene::render() { // Unbind the shader mPhongShader.unbind(); } + +// Reset the scene +void CubesScene::reset() { + +} diff --git a/testbed/examples/cubes/Scene.h b/testbed/scenes/cubes/CubesScene.h similarity index 75% rename from testbed/examples/cubes/Scene.h rename to testbed/scenes/cubes/CubesScene.h index 2f79daed..54b1f79d 100644 --- a/testbed/examples/cubes/Scene.h +++ b/testbed/scenes/cubes/CubesScene.h @@ -23,14 +23,16 @@ * * ********************************************************************************/ -#ifndef SCENE_H -#define SCENE_H +#ifndef CUBES_SCENE_H +#define CUBES_SCENE_H // Libraries #include "openglframework.h" #include "reactphysics3d.h" #include "Box.h" -#include "Viewer.h" +#include "Scene.h" + +namespace cubesscene { // Constants const int NB_CUBES = 200; // Number of boxes in the scene @@ -39,18 +41,15 @@ const openglframework::Vector3 FLOOR_SIZE(50, 0.5f, 50); // Floor dimensions i const float BOX_MASS = 1.0f; // Box mass in kilograms const float FLOOR_MASS = 100.0f; // Floor mass in kilograms -// Class Scene -class Scene { +// Class CubesScene +class CubesScene : public Scene { - private : + protected : // -------------------- Attributes -------------------- // int counter; - /// Pointer to the viewer - Viewer* mViewer; - /// Light 0 openglframework::Light mLight0; @@ -66,55 +65,26 @@ class Scene { /// Dynamics world used for the physics simulation rp3d::DynamicsWorld* mDynamicsWorld; - /// True if the physics simulation is running - bool mIsRunning; - public: // -------------------- Methods -------------------- // /// Constructor - Scene(Viewer* viewer, const std::string& shaderFolderPath); + CubesScene(const std::string& name); /// Destructor - ~Scene(); + virtual ~CubesScene(); - /// Take a step for the simulation - void simulate(); - - /// Stop the simulation - void stopSimulation(); - - /// Start the simulation - void startSimulation(); - - /// Pause or continue simulation - void pauseContinueSimulation(); + /// Update the scene (take a simulation step) + virtual void update(); /// Render the scene - void render(); + virtual void render(); + + /// Reset the scene + virtual void reset(); }; -// Stop the simulation -inline void Scene::stopSimulation() { - mDynamicsWorld->stop(); - mIsRunning = false; -} - -// Start the simulation -inline void Scene::startSimulation() { - mDynamicsWorld->start(); - mIsRunning = true; -} - -// Pause or continue simulation -inline void Scene::pauseContinueSimulation() { - if (mIsRunning) { - stopSimulation(); - } - else { - startSimulation(); - } } #endif diff --git a/testbed/examples/joints/Scene.cpp b/testbed/scenes/joints/JointsScene.cpp similarity index 89% rename from testbed/examples/joints/Scene.cpp rename to testbed/scenes/joints/JointsScene.cpp index def294fa..8ca3f2a6 100644 --- a/testbed/examples/joints/Scene.cpp +++ b/testbed/scenes/joints/JointsScene.cpp @@ -24,17 +24,17 @@ ********************************************************************************/ // Libraries -#include "Scene.h" +#include "JointsScene.h" #include // Namespaces using namespace openglframework; +using namespace jointsscene; // Constructor -Scene::Scene(Viewer *viewer, const std::string& shaderFolderPath) - : mViewer(viewer), mLight0(0), mPhongShader(shaderFolderPath + "phong.vert", - shaderFolderPath + "phong.frag"), - mIsRunning(false) { +JointsScene::JointsScene(const std::string& name) + : Scene(name), mLight0(0), mPhongShader("shaders/phong.vert", + "shaders/phong.frag") { // Move the light 0 mLight0.translateWorld(Vector3(7, 15, 15)); @@ -44,7 +44,7 @@ Scene::Scene(Viewer *viewer, const std::string& shaderFolderPath) openglframework::Vector3 center(0, 5, 0); // Set the center of the scene - mViewer->setScenePosition(center, radiusScene); + setScenePosition(center, radiusScene); // Gravity vector in the dynamics world rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0); @@ -74,14 +74,14 @@ Scene::Scene(Viewer *viewer, const std::string& shaderFolderPath) createFloor(); // Start the simulation - startSimulation(); + mDynamicsWorld->start(); } // Destructor -Scene::~Scene() { +JointsScene::~JointsScene() { // Stop the physics simulation - stopSimulation(); + mDynamicsWorld->stop(); // Destroy the shader mPhongShader.destroy(); @@ -123,50 +123,45 @@ Scene::~Scene() { } // Take a step for the simulation -void Scene::simulate() { +void JointsScene::update() { - // If the physics simulation is running - if (mIsRunning) { + // Update the motor speed of the Slider Joint (to move up and down) + long double motorSpeed = 2 * cos(mDynamicsWorld->getPhysicsTime() * 1.5); + mSliderJoint->setMotorSpeed(rp3d::decimal(motorSpeed)); - // Update the motor speed of the Slider Joint (to move up and down) - long double motorSpeed = 2 * cos(mDynamicsWorld->getPhysicsTime() * 1.5); - mSliderJoint->setMotorSpeed(rp3d::decimal(motorSpeed)); + // Take a simulation step + mDynamicsWorld->update(); - // Take a simulation step - mDynamicsWorld->update(); - - // Update the position and orientation of the boxes - mSliderJointBottomBox->updateTransform(); - mSliderJointTopBox->updateTransform(); - mPropellerBox->updateTransform(); - mFixedJointBox1->updateTransform(); - mFixedJointBox2->updateTransform(); - for (int i=0; iupdateTransform(); - } - - // Update the position and orientation of the floor - mFloor->updateTransform(); + // Update the position and orientation of the boxes + mSliderJointBottomBox->updateTransform(); + mSliderJointTopBox->updateTransform(); + mPropellerBox->updateTransform(); + mFixedJointBox1->updateTransform(); + mFixedJointBox2->updateTransform(); + for (int i=0; iupdateTransform(); } + + // Update the position and orientation of the floor + mFloor->updateTransform(); } // Render the scene -void Scene::render() { +void JointsScene::render() { glEnable(GL_DEPTH_TEST); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_CULL_FACE); // Get the world-space to camera-space matrix - const Camera& camera = mViewer->getCamera(); - const openglframework::Matrix4 worldToCameraMatrix = camera.getTransformMatrix().getInverse(); + const openglframework::Matrix4 worldToCameraMatrix = mCamera.getTransformMatrix().getInverse(); // Bind the shader mPhongShader.bind(); // Set the variables of the shader mPhongShader.setVector3Uniform("light0PosCameraSpace",worldToCameraMatrix * mLight0.getOrigin()); - mPhongShader.setMatrix4x4Uniform("projectionMatrix", camera.getProjectionMatrix()); + mPhongShader.setMatrix4x4Uniform("projectionMatrix", mCamera.getProjectionMatrix()); mPhongShader.setVector3Uniform("lightAmbientColor", Vector3(0.3f, 0.3f, 0.3f)); const Color& diffCol = mLight0.getDiffuseColor(); const Color& specCol = mLight0.getSpecularColor(); @@ -191,8 +186,13 @@ void Scene::render() { mPhongShader.unbind(); } +// Reset the scene +void JointsScene::reset() { + +} + // Create the boxes and joints for the Ball-and-Socket joint example -void Scene::createBallAndSocketJoints() { +void JointsScene::createBallAndSocketJoints() { // --------------- Create the boxes --------------- // @@ -240,7 +240,7 @@ void Scene::createBallAndSocketJoints() { } /// Create the boxes and joint for the Slider joint example -void Scene::createSliderJoint() { +void JointsScene::createSliderJoint() { // --------------- Create the first box --------------- // @@ -292,7 +292,7 @@ void Scene::createSliderJoint() { } /// Create the boxes and joint for the Hinge joint example -void Scene::createPropellerHingeJoint() { +void JointsScene::createPropellerHingeJoint() { // --------------- Create the propeller box --------------- // @@ -327,7 +327,7 @@ void Scene::createPropellerHingeJoint() { } /// Create the boxes and joints for the fixed joints -void Scene::createFixedJoints() { +void JointsScene::createFixedJoints() { // --------------- Create the first box --------------- // @@ -379,7 +379,7 @@ void Scene::createFixedJoints() { } // Create the floor -void Scene::createFloor() { +void JointsScene::createFloor() { // Create the floor openglframework::Vector3 floorPosition(0, 0, 0); diff --git a/testbed/examples/joints/Scene.h b/testbed/scenes/joints/JointsScene.h similarity index 82% rename from testbed/examples/joints/Scene.h rename to testbed/scenes/joints/JointsScene.h index 4467f3af..18920700 100644 --- a/testbed/examples/joints/Scene.h +++ b/testbed/scenes/joints/JointsScene.h @@ -23,14 +23,16 @@ * * ********************************************************************************/ -#ifndef SCENE_H -#define SCENE_H +#ifndef JOINTS_SCENE_H +#define JOINTS_SCENE_H // Libraries #include "openglframework.h" #include "reactphysics3d.h" #include "Box.h" -#include "../common/Viewer.h" +#include "Scene.h" + +namespace jointsscene { // Constants const openglframework::Vector3 BOX_SIZE(2, 2, 2); // Box dimensions in meters @@ -40,16 +42,13 @@ const float FLOOR_MASS = 100.0f; // Floor mass in kil const int NB_BALLSOCKETJOINT_BOXES = 7; // Number of Ball-And-Socket chain boxes const int NB_HINGE_BOXES = 7; // Number of Hinge chain boxes -// Class Scene -class Scene { +// Class JointsScene +class JointsScene : public Scene { - private : + protected : // -------------------- Attributes -------------------- // - /// Pointer to the viewer - Viewer* mViewer; - /// Light 0 openglframework::Light mLight0; @@ -101,9 +100,6 @@ class Scene { /// Dynamics world used for the physics simulation rp3d::DynamicsWorld* mDynamicsWorld; - /// True if the physics simulation is running - bool mIsRunning; - // -------------------- Methods -------------------- // /// Create the boxes and joints for the Ball-and-Socket joint example @@ -126,47 +122,21 @@ class Scene { // -------------------- Methods -------------------- // /// Constructor - Scene(Viewer* viewer, const std::string& shaderFolderPath); + JointsScene(const std::string& name); /// Destructor - ~Scene(); + virtual ~JointsScene(); /// Take a step for the simulation - void simulate(); - - /// Stop the simulation - void stopSimulation(); - - /// Start the simulation - void startSimulation(); - - /// Pause or continue simulation - void pauseContinueSimulation(); + virtual void update(); /// Render the scene - void render(); + virtual void render(); + + /// Reset the scene + virtual void reset(); }; -// Stop the simulation -inline void Scene::stopSimulation() { - mDynamicsWorld->stop(); - mIsRunning = false; -} - -// Start the simulation -inline void Scene::startSimulation() { - mDynamicsWorld->start(); - mIsRunning = true; -} - -// Pause or continue simulation -inline void Scene::pauseContinueSimulation() { - if (mIsRunning) { - stopSimulation(); - } - else { - startSimulation(); - } } #endif diff --git a/testbed/examples/raycast/Scene.cpp b/testbed/scenes/raycast/RaycastScene.cpp similarity index 93% rename from testbed/examples/raycast/Scene.cpp rename to testbed/scenes/raycast/RaycastScene.cpp index da6423a3..0eef3411 100644 --- a/testbed/examples/raycast/Scene.cpp +++ b/testbed/scenes/raycast/RaycastScene.cpp @@ -24,16 +24,18 @@ ********************************************************************************/ // Libraries -#include "Scene.h" +#include "RaycastScene.h" // Namespaces using namespace openglframework; +using namespace raycastscene; // Constructor -Scene::Scene(Viewer* viewer, const std::string& shaderFolderPath, const std::string& meshFolderPath) - : mViewer(viewer), mLight0(0), mCurrentBodyIndex(-1), mAreNormalsDisplayed(false), - mPhongShader(shaderFolderPath + "phong.vert", - shaderFolderPath +"phong.frag") { +RaycastScene::RaycastScene(const std::string& name) + : Scene(name), mLight0(0), mCurrentBodyIndex(-1), mAreNormalsDisplayed(false), + mPhongShader("shaders/phong.vert", "shaders/phong.frag") { + + std::string meshFolderPath("meshes/"); // Move the light 0 mLight0.translateWorld(Vector3(50, 50, 50)); @@ -43,7 +45,7 @@ Scene::Scene(Viewer* viewer, const std::string& shaderFolderPath, const std::str openglframework::Vector3 center(0, 0, 0); // Set the center of the scene - mViewer->setScenePosition(center, radiusScene); + setScenePosition(center, radiusScene); // Create the dynamics world for the physics simulation mCollisionWorld = new rp3d::CollisionWorld(); @@ -105,7 +107,7 @@ Scene::Scene(Viewer* viewer, const std::string& shaderFolderPath, const std::str } // Create the raycast lines -void Scene::createLines() { +void RaycastScene::createLines() { int nbRaysOneDimension = std::sqrt(float(NB_RAYS)); @@ -131,7 +133,7 @@ void Scene::createLines() { } // Change the body to raycast and to display -void Scene::changeBody() { +void RaycastScene::changeBody() { mCurrentBodyIndex++; if (mCurrentBodyIndex >= NB_BODIES) mCurrentBodyIndex = 0; @@ -163,8 +165,13 @@ void Scene::changeBody() { } } +// Reset the scene +void RaycastScene::reset() { + +} + // Destructor -Scene::~Scene() { +RaycastScene::~RaycastScene() { // Destroy the shader mPhongShader.destroy(); @@ -221,7 +228,7 @@ Scene::~Scene() { } // Take a step for the simulation -void Scene::simulate() { +void RaycastScene::update() { mRaycastManager.resetPoints(); @@ -246,15 +253,14 @@ void Scene::simulate() { } // Render the scene -void Scene::render() { +void RaycastScene::render() { glEnable(GL_DEPTH_TEST); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_CULL_FACE); // Get the world-space to camera-space matrix - const Camera& camera = mViewer->getCamera(); - const openglframework::Matrix4 worldToCameraMatrix = camera.getTransformMatrix().getInverse(); + const openglframework::Matrix4 worldToCameraMatrix = mCamera.getTransformMatrix().getInverse(); // Bind the shader mPhongShader.bind(); @@ -263,7 +269,7 @@ void Scene::render() { mPhongShader.setVector4Uniform("vertexColor", grey); // Set the variables of the shader - mPhongShader.setMatrix4x4Uniform("projectionMatrix", camera.getProjectionMatrix()); + mPhongShader.setMatrix4x4Uniform("projectionMatrix", mCamera.getProjectionMatrix()); mPhongShader.setVector3Uniform("light0PosCameraSpace", worldToCameraMatrix * mLight0.getOrigin()); mPhongShader.setVector3Uniform("lightAmbientColor", Vector3(0.3f, 0.3f, 0.3f)); const Color& diffColLight0 = mLight0.getDiffuseColor(); diff --git a/testbed/examples/raycast/Scene.h b/testbed/scenes/raycast/RaycastScene.h similarity index 94% rename from testbed/examples/raycast/Scene.h rename to testbed/scenes/raycast/RaycastScene.h index 9b044e06..fc809731 100644 --- a/testbed/examples/raycast/Scene.h +++ b/testbed/scenes/raycast/RaycastScene.h @@ -23,14 +23,15 @@ * * ********************************************************************************/ -#ifndef SCENE_H -#define SCENE_H +#ifndef RAYCAST_SCENE_H +#define RAYCAST_SCENE_H // Libraries #define _USE_MATH_DEFINES #include #include "openglframework.h" #include "reactphysics3d.h" +#include "Scene.h" #include "Sphere.h" #include "Box.h" #include "Cone.h" @@ -42,6 +43,8 @@ #include "VisualContactPoint.h" #include "../common/Viewer.h" +namespace raycastscene { + // Constants const openglframework::Vector3 BOX_SIZE(4, 2, 1); const float SPHERE_RADIUS = 3.0f; @@ -122,16 +125,13 @@ class RaycastManager : public rp3d::RaycastCallback { } }; -// Class Scene -class Scene { +// Class RaycastScene +class RaycastScene : public Scene { private : // -------------------- Attributes -------------------- // - /// Pointer to the viewer - Viewer* mViewer; - /// Raycast manager RaycastManager mRaycastManager; @@ -172,17 +172,19 @@ class Scene { // -------------------- Methods -------------------- // /// Constructor - Scene(Viewer* viewer, const std::string& shaderFolderPath, - const std::string& meshFolderPath); + RaycastScene(const std::string& name); /// Destructor - ~Scene(); + virtual ~RaycastScene(); /// Take a step for the simulation - void simulate(); + virtual void update(); /// Render the scene - void render(); + virtual void render(); + + /// Reset the scene + virtual void reset(); /// Change the body to raycast void changeBody(); @@ -192,9 +194,10 @@ class Scene { }; // Display or not the surface normals at hit points -inline void Scene::showHideNormals() { +inline void RaycastScene::showHideNormals() { mAreNormalsDisplayed = !mAreNormalsDisplayed; } +} #endif diff --git a/testbed/Gui.cpp b/testbed/src/Gui.cpp similarity index 96% rename from testbed/Gui.cpp rename to testbed/src/Gui.cpp index f7ff23eb..e8c9552f 100644 --- a/testbed/Gui.cpp +++ b/testbed/src/Gui.cpp @@ -26,6 +26,16 @@ // Libraries #include "Gui.h" +// Constructor +Gui::Gui() { + +} + +// Destructor +Gui::~Gui() { + +} + // Display the GUI void Gui::display() { diff --git a/testbed/Gui.h b/testbed/src/Gui.h similarity index 100% rename from testbed/Gui.h rename to testbed/src/Gui.h diff --git a/testbed/Main.cpp b/testbed/src/Main.cpp similarity index 100% rename from testbed/Main.cpp rename to testbed/src/Main.cpp diff --git a/testbed/Scene.cpp b/testbed/src/Scene.cpp similarity index 82% rename from testbed/Scene.cpp rename to testbed/src/Scene.cpp index c5db2d5f..497e79ae 100644 --- a/testbed/Scene.cpp +++ b/testbed/src/Scene.cpp @@ -25,6 +25,7 @@ // Libraries #include "Scene.h" +#include using namespace openglframework; @@ -33,6 +34,11 @@ Scene::Scene(const std::string& name) : mName(name) { } +// Destructor +Scene::~Scene() { + +} + // Set the scene position (where the camera needs to look at) void Scene::setScenePosition(const openglframework::Vector3& position, float sceneRadius) { @@ -59,15 +65,12 @@ void Scene::resetCameraToViewAll() { } // Map the mouse x,y coordinates to a point on a sphere -bool Scene::mapMouseCoordinatesToSphere(double xMouse, double yMouse, Vector3& spherePoint) const { +bool Scene::mapMouseCoordinatesToSphere(double xMouse, double yMouse, + Vector3& spherePoint) const { - // Get the window dimension - int width, height; - glfwGetWindowSize(mWindow, &width, &height); - - if ((xMouse >= 0) && (xMouse <= width) && (yMouse >= 0) && (yMouse <= height)) { - float x = float(xMouse - 0.5f * width) / float(width); - float y = float(0.5f * height - yMouse) / float(height); + if ((xMouse >= 0) && (xMouse <= mWindowWidth) && (yMouse >= 0) && (yMouse <= mWindowHeight)) { + float x = float(xMouse - 0.5f * mWindowWidth) / float(mWindowWidth); + float y = float(0.5f * mWindowHeight - yMouse) / float(mWindowHeight); float sinx = sin(PI * x * 0.5f); float siny = sin(PI * y * 0.5f); float sinx2siny2 = sinx * sinx + siny * siny; @@ -84,17 +87,14 @@ bool Scene::mapMouseCoordinatesToSphere(double xMouse, double yMouse, Vector3& s } // Called when a mouse button event occurs -void Scene::mouseButtonEvent(int button, int action, int mods) { - - // Get the mouse cursor position - double x, y; - glfwGetCursorPos(mWindow, &x, &y); +void Scene::mouseButtonEvent(int button, int action, int mods, + double mousePosX, double mousePosY) { // If the mouse button is pressed if (action == GLFW_PRESS) { - mLastMouseX = x; - mLastMouseY = y; - mIsLastPointOnSphereValid = mapMouseCoordinatesToSphere(x, y, mLastPointOnSphere); + mLastMouseX = mousePosX; + mLastMouseY = mousePosY; + mIsLastPointOnSphereValid = mapMouseCoordinatesToSphere(mousePosX, mousePosY, mLastPointOnSphere); } else { // If the mouse button is released mIsLastPointOnSphereValid = false; @@ -102,22 +102,15 @@ void Scene::mouseButtonEvent(int button, int action, int mods) { } // Called when a mouse motion event occurs -void Scene::mouseMotionEvent(double xMouse, double yMouse) { - - int leftButtonState = glfwGetMouseButton(mWindow, GLFW_MOUSE_BUTTON_LEFT); - int rightButtonState = glfwGetMouseButton(mWindow, GLFW_MOUSE_BUTTON_RIGHT); - int middleButtonState = glfwGetMouseButton(mWindow, GLFW_MOUSE_BUTTON_MIDDLE); - int altKeyState = glfwGetKey(mWindow, GLFW_KEY_LEFT_ALT); +void Scene::mouseMotionEvent(double xMouse, double yMouse, int leftButtonState, + int rightButtonState, int middleButtonState, + int altKeyState) { // Zoom if (leftButtonState == GLFW_PRESS && altKeyState == GLFW_PRESS) { - // Get the window dimension - int width, height; - glfwGetWindowSize(mWindow, &width, &height); - float dy = static_cast(yMouse - mLastMouseY); - float h = static_cast(height); + float h = static_cast(mWindowHeight); // Zoom the camera zoom(-dy / h); @@ -139,8 +132,8 @@ void Scene::mouseMotionEvent(double xMouse, double yMouse) { } // Called when a scrolling event occurs -void Scene::scrollingEvent(float xAxis, float yAxis) { - zoom(yAxis * SCROLL_SENSITIVITY); +void Scene::scrollingEvent(float xAxis, float yAxis, float scrollSensitivy) { + zoom(yAxis * scrollSensitivy); } // Zoom the camera diff --git a/testbed/Scene.h b/testbed/src/Scene.h similarity index 88% rename from testbed/Scene.h rename to testbed/src/Scene.h index 7251da60..ebe3476a 100644 --- a/testbed/Scene.h +++ b/testbed/src/Scene.h @@ -49,6 +49,9 @@ class Scene { /// Last mouse coordinates on the windows double mLastMouseX, mLastMouseY; + /// Window dimension + int mWindowWidth, mWindowHeight; + /// Last point computed on a sphere (for camera rotation) openglframework::Vector3 mLastPointOnSphere; @@ -87,9 +90,6 @@ class Scene { /// Destructor virtual ~Scene(); - /// Initialize the scene - virtual void init()=0; - /// Reshape the view virtual void reshape(int width, int height); @@ -106,13 +106,18 @@ class Scene { virtual void keyboardEvent(int key, int scancode, int action, int mods); /// Called when a mouse button event occurs - virtual void mouseButtonEvent(int button, int action, int mods); + virtual void mouseButtonEvent(int button, int action, int mods, + double mousePosX, double mousePosY); /// Called when a mouse motion event occurs - virtual void mouseMotionEvent(double xMouse, double yMouse); + virtual void mouseMotionEvent(double xMouse, double yMouse, int leftButtonState, + int rightButtonState, int middleButtonState, int altKeyState); /// Called when a scrolling event occurs - virtual void scrollingEvent(float xAxis, float yAxis); + virtual void scrollingEvent(float xAxis, float yAxis, float scrollSensitivy); + + /// Set the window dimension + void setWindowDimension(int width, int height); /// Return a reference to the camera const openglframework::Camera& getCamera() const; @@ -133,5 +138,11 @@ inline const openglframework::Camera& Scene::getCamera() const { return mCamera; } +// Set the window dimension +inline void Scene::setWindowDimension(int width, int height) { + mWindowWidth = width; + mWindowHeight = height; +} + #endif diff --git a/testbed/TestbedApplication.cpp b/testbed/src/TestbedApplication.cpp similarity index 77% rename from testbed/TestbedApplication.cpp rename to testbed/src/TestbedApplication.cpp index ef695cca..0b7e8a55 100644 --- a/testbed/TestbedApplication.cpp +++ b/testbed/src/TestbedApplication.cpp @@ -29,8 +29,16 @@ #include #include #include +#include "cubes/CubesScene.h" +#include "joints/JointsScene.h" +#include "collisionshapes/CollisionShapesScene.h" +#include "raycast/RaycastScene.h" using namespace openglframework; +using namespace jointsscene; +using namespace cubesscene; +using namespace raycastscene; +using namespace collisionshapesscene; // Initialization of static variables const float TestbedApplication::SCROLL_SENSITIVITY = 0.02f; @@ -54,6 +62,9 @@ TestbedApplication::~TestbedApplication() { // TODO : Check that this method is called at the end + // Destroy all the scenes + destroyScenes(); + // Destroy the window glfwDestroyWindow(mWindow); @@ -110,6 +121,42 @@ void TestbedApplication::init() { // Define the background color (black) glClearColor(0.0, 0.0, 0.0, 1.0); + + // Create all the scenes + createScenes(); +} + +// Create all the scenes +void TestbedApplication::createScenes() { + + // Cubes scene + CubesScene* cubeScene = new CubesScene("Cubes"); + mScenes.push_back(cubeScene); + + // Joints scene + JointsScene* jointsScene = new JointsScene("Joints"); + mScenes.push_back(jointsScene); + + // Collision shapes scene + CollisionShapesScene* collisionShapesScene = new CollisionShapesScene("Collision Shapes"); + mScenes.push_back(collisionShapesScene); + + // Raycast scene + RaycastScene* raycastScene = new RaycastScene("Raycast"); + mScenes.push_back(raycastScene); + + assert(mScenes.size() > 0); + mCurrentScene = mScenes[0]; +} + +// Remove all the scenes +void TestbedApplication::destroyScenes() { + + for (int i=0; ireshape(width, height); + // Resize the OpenGL viewport glViewport(0, 0, width, height); + + // Update the window size of the scene + int windowWidth, windowHeight; + glfwGetWindowSize(mWindow, &windowWidth, &windowHeight); + mCurrentScene->setWindowDimension(windowWidth, windowHeight); } // Start the main loop where rendering occur @@ -159,6 +212,9 @@ void TestbedApplication::startMainLoop() { // Call the update function update(); + // Render the application + render(); + // Swap front and back buffers glfwSwapBuffers(mWindow); @@ -249,15 +305,27 @@ void TestbedApplication::keyboard(GLFWwindow* window, int key, int scancode, // Callback method to receive scrolling events void TestbedApplication::scroll(GLFWwindow* window, double xAxis, double yAxis) { - getInstance().mCurrentScene->scrollingEvent(xAxis, yAxis); + getInstance().mCurrentScene->scrollingEvent(xAxis, yAxis, SCROLL_SENSITIVITY); } // Called when a mouse button event occurs void TestbedApplication::mouseButton(GLFWwindow* window, int button, int action, int mods) { - getInstance().mCurrentScene->mouseButtonEvent(button, action, mods); + + // Get the mouse cursor position + double x, y; + glfwGetCursorPos(window, &x, &y); + + getInstance().mCurrentScene->mouseButtonEvent(button, action, mods, x, y); } // Called when a mouse motion event occurs void TestbedApplication::mouseMotion(GLFWwindow* window, double x, double y) { - getInstance().mCurrentScene->mouseMotionEvent(x, y); + + int leftButtonState = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT); + int rightButtonState = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_RIGHT); + int middleButtonState = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_MIDDLE); + int altKeyState = glfwGetKey(window, GLFW_KEY_LEFT_ALT); + + getInstance().mCurrentScene->mouseMotionEvent(x, y, leftButtonState, rightButtonState, + middleButtonState, altKeyState); } diff --git a/testbed/TestbedApplication.h b/testbed/src/TestbedApplication.h similarity index 96% rename from testbed/TestbedApplication.h rename to testbed/src/TestbedApplication.h index 8165d84c..7472bbee 100644 --- a/testbed/TestbedApplication.h +++ b/testbed/src/TestbedApplication.h @@ -121,6 +121,12 @@ class TestbedApplication { /// Called when a mouse motion event occurs static void mouseMotion(GLFWwindow* window, double x, double y); + /// Initialize all the scenes + void createScenes(); + + /// Remove all the scenes + void destroyScenes() ; + public : // -------------------- Methods -------------------- // @@ -131,7 +137,7 @@ class TestbedApplication { /// Destructor ~TestbedApplication(); - /// Initialize the viewer + /// Initialize the application void init(); /// Start the main loop where rendering occur From fb90eac00382156633b833f6e52d316a1589b075 Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Sat, 18 Apr 2015 18:33:25 +0200 Subject: [PATCH 04/36] The time accumulator and frame interpolation should now be done outside the physics engine --- CMakeLists.txt | 2 - src/body/CollisionBody.cpp | 2 - src/body/CollisionBody.h | 23 ---- src/body/RigidBody.cpp | 2 +- src/configuration.h | 3 - src/engine/DynamicsWorld.cpp | 109 +++++++------------ src/engine/DynamicsWorld.h | 30 ++---- src/engine/Timer.cpp | 66 ------------ src/engine/Timer.h | 200 ----------------------------------- 9 files changed, 45 insertions(+), 392 deletions(-) delete mode 100644 src/engine/Timer.cpp delete mode 100644 src/engine/Timer.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 10ddb5cb..3ece2602 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -117,8 +117,6 @@ SET (REACTPHYSICS3D_SOURCES "src/engine/OverlappingPair.cpp" "src/engine/Profiler.h" "src/engine/Profiler.cpp" - "src/engine/Timer.h" - "src/engine/Timer.cpp" "src/mathematics/mathematics.h" "src/mathematics/mathematics_functions.h" "src/mathematics/Matrix2x2.h" diff --git a/src/body/CollisionBody.cpp b/src/body/CollisionBody.cpp index 0c782d31..f9a4702d 100644 --- a/src/body/CollisionBody.cpp +++ b/src/body/CollisionBody.cpp @@ -41,8 +41,6 @@ CollisionBody::CollisionBody(const Transform& transform, CollisionWorld& world, : Body(id), mType(DYNAMIC), mTransform(transform), mProxyCollisionShapes(NULL), mNbCollisionShapes(0), mContactManifoldsList(NULL), mWorld(world) { - mInterpolationFactor = 0.0; - // Initialize the old transform mOldTransform = transform; } diff --git a/src/body/CollisionBody.h b/src/body/CollisionBody.h index c0d5547b..c75631a5 100644 --- a/src/body/CollisionBody.h +++ b/src/body/CollisionBody.h @@ -76,9 +76,6 @@ class CollisionBody : public Body { /// Last position and orientation of the body Transform mOldTransform; - /// Interpolation factor used for the state interpolation - decimal mInterpolationFactor; - /// First element of the linked list of proxy collision shapes of this body ProxyShape* mProxyCollisionShapes; @@ -118,9 +115,6 @@ class CollisionBody : public Body { /// Reset the mIsAlreadyInIsland variable of the body and contact manifolds int resetIsAlreadyInIslandAndCountManifolds(); - /// Set the interpolation factor of the body - void setInterpolationFactor(decimal factor); - public : // -------------------- Methods -------------------- // @@ -153,9 +147,6 @@ class CollisionBody : public Body { /// Remove a collision shape from the body virtual void removeCollisionShape(const ProxyShape* proxyShape); - /// Return the interpolated transform for rendering - Transform getInterpolatedTransform() const; - /// Return the first element of the linked list of contact manifolds involving this body const ContactManifoldListElement* getContactManifoldsList() const; @@ -227,20 +218,6 @@ inline void CollisionBody::setType(BodyType type) { } } -// Return the interpolated transform for rendering -/** - * @return The current interpolated transformation (between previous and current frame) - */ -inline Transform CollisionBody::getInterpolatedTransform() const { - return Transform::interpolateTransforms(mOldTransform, mTransform, mInterpolationFactor); -} - -// Set the interpolation factor of the body -inline void CollisionBody::setInterpolationFactor(decimal factor) { - // Set the factor - mInterpolationFactor = factor; -} - // Return the current position and orientation /** * @return The current transformation of the body that transforms the local-space diff --git a/src/body/RigidBody.cpp b/src/body/RigidBody.cpp index 3ba985b6..ddf1ea83 100644 --- a/src/body/RigidBody.cpp +++ b/src/body/RigidBody.cpp @@ -343,7 +343,7 @@ void RigidBody::updateBroadPhaseState() const { PROFILE("RigidBody::updateBroadPhaseState()"); DynamicsWorld& world = dynamic_cast(mWorld); - const Vector3 displacement = world.mTimer.getTimeStep() * mLinearVelocity; + const Vector3 displacement = world.mTimeStep* mLinearVelocity; // For all the proxy collision shapes of the body for (ProxyShape* shape = mProxyCollisionShapes; shape != NULL; shape = shape->mNext) { diff --git a/src/configuration.h b/src/configuration.h index b4c91f62..50d1872c 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -83,9 +83,6 @@ const decimal PI = decimal(3.14159265); /// 2*Pi constant const decimal PI_TIMES_2 = decimal(6.28318530); -/// Default internal constant timestep in seconds -const decimal DEFAULT_TIMESTEP = decimal(1.0 / 60.0); - /// Default friction coefficient for a rigid body const decimal DEFAULT_FRICTION_COEFFICIENT = decimal(0.3); diff --git a/src/engine/DynamicsWorld.cpp b/src/engine/DynamicsWorld.cpp index f5637077..927b28ee 100644 --- a/src/engine/DynamicsWorld.cpp +++ b/src/engine/DynamicsWorld.cpp @@ -37,10 +37,9 @@ using namespace std; // Constructor /** * @param gravity Gravity vector in the world (in meters per second squared) - * @param timeStep Time step for an internal physics tick (in seconds) */ -DynamicsWorld::DynamicsWorld(const Vector3 &gravity, decimal timeStep = DEFAULT_TIMESTEP) - : CollisionWorld(), mTimer(timeStep), +DynamicsWorld::DynamicsWorld(const Vector3 &gravity) + : CollisionWorld(), mContactSolver(mMapBodyToConstrainedVelocityIndex), mConstraintSolver(mMapBodyToConstrainedVelocityIndex), mNbVelocitySolverIterations(DEFAULT_VELOCITY_SOLVER_NB_ITERATIONS), @@ -95,7 +94,10 @@ DynamicsWorld::~DynamicsWorld() { } // Update the physics simulation -void DynamicsWorld::update() { +/** + * @param timeStep The amount of time to step the simulation by (in seconds) + */ +void DynamicsWorld::update(decimal timeStep) { #ifdef IS_PROFILING_ACTIVE // Increment the frame counter of the profiler @@ -104,49 +106,39 @@ void DynamicsWorld::update() { PROFILE("DynamicsWorld::update()"); - assert(mTimer.getIsRunning()); - - // Compute the time since the last update() call and update the timer - mTimer.update(); + mTimeStep = timeStep; - // While the time accumulator is not empty - while(mTimer.isPossibleToTakeStep()) { + // Notify the event listener about the beginning of an internal tick + if (mEventListener != NULL) mEventListener->beginInternalTick(); - // Notify the event listener about the beginning of an internal tick - if (mEventListener != NULL) mEventListener->beginInternalTick(); + // Reset all the contact manifolds lists of each body + resetContactManifoldListsOfBodies(); - // Reset all the contact manifolds lists of each body - resetContactManifoldListsOfBodies(); - - // Compute the collision detection - mCollisionDetection.computeCollisionDetection(); + // Compute the collision detection + mCollisionDetection.computeCollisionDetection(); - // Compute the islands (separate groups of bodies with constraints between each others) - computeIslands(); + // Compute the islands (separate groups of bodies with constraints between each others) + computeIslands(); - // Integrate the velocities - integrateRigidBodiesVelocities(); + // Integrate the velocities + integrateRigidBodiesVelocities(); - // Update the timer - mTimer.nextStep(); + // Solve the contacts and constraints + solveContactsAndConstraints(); - // Solve the contacts and constraints - solveContactsAndConstraints(); + // Integrate the position and orientation of each body + integrateRigidBodiesPositions(); - // Integrate the position and orientation of each body - integrateRigidBodiesPositions(); + // Solve the position correction for constraints + solvePositionCorrection(); - // Solve the position correction for constraints - solvePositionCorrection(); + // Update the state (positions and velocities) of the bodies + updateBodiesState(); - // Update the state (positions and velocities) of the bodies - updateBodiesState(); + if (mIsSleepingEnabled) updateSleepingBodies(); - if (mIsSleepingEnabled) updateSleepingBodies(); - - // Notify the event listener about the end of an internal tick - if (mEventListener != NULL) mEventListener->endInternalTick(); - } + // Notify the event listener about the end of an internal tick + if (mEventListener != NULL) mEventListener->endInternalTick(); // Reset the external force and torque applied to the bodies resetBodiesForceAndTorque(); @@ -161,8 +153,6 @@ void DynamicsWorld::update() { void DynamicsWorld::integrateRigidBodiesPositions() { PROFILE("DynamicsWorld::integrateRigidBodiesPositions()"); - - decimal dt = static_cast(mTimer.getTimeStep()); // For each island of the world for (uint i=0; i < mNbIslands; i++) { @@ -190,10 +180,10 @@ void DynamicsWorld::integrateRigidBodiesPositions() { const Quaternion& currentOrientation = bodies[b]->getTransform().getOrientation(); // Update the new constrained position and orientation of the body - mConstrainedPositions[indexArray] = currentPosition + newLinVelocity * dt; + mConstrainedPositions[indexArray] = currentPosition + newLinVelocity * mTimeStep; mConstrainedOrientations[indexArray] = currentOrientation + Quaternion(0, newAngVelocity) * - currentOrientation * decimal(0.5) * dt; + currentOrientation * decimal(0.5) * mTimeStep; } } } @@ -232,23 +222,6 @@ void DynamicsWorld::updateBodiesState() { } } -// Compute and set the interpolation factor to all bodies -void DynamicsWorld::setInterpolationFactorToAllBodies() { - - PROFILE("DynamicsWorld::setInterpolationFactorToAllBodies()"); - - // Compute the interpolation factor - decimal factor = mTimer.computeInterpolationFactor(); - assert(factor >= 0.0 && factor <= 1.0); - - // Set the factor to all bodies - set::iterator it; - for (it = mRigidBodies.begin(); it != mRigidBodies.end(); ++it) { - - (*it)->setInterpolationFactor(factor); - } -} - // Initialize the bodies velocities arrays for the next simulation step. void DynamicsWorld::initVelocityArrays() { @@ -305,8 +278,6 @@ void DynamicsWorld::integrateRigidBodiesVelocities() { // Initialize the bodies velocity arrays initVelocityArrays(); - decimal dt = static_cast(mTimer.getTimeStep()); - // For each island of the world for (uint i=0; i < mNbIslands; i++) { @@ -323,16 +294,16 @@ void DynamicsWorld::integrateRigidBodiesVelocities() { // Integrate the external force to get the new velocity of the body mConstrainedLinearVelocities[indexBody] = bodies[b]->getLinearVelocity() + - dt * bodies[b]->mMassInverse * bodies[b]->mExternalForce; + mTimeStep * bodies[b]->mMassInverse * bodies[b]->mExternalForce; mConstrainedAngularVelocities[indexBody] = bodies[b]->getAngularVelocity() + - dt * bodies[b]->getInertiaTensorInverseWorld() * + mTimeStep * bodies[b]->getInertiaTensorInverseWorld() * bodies[b]->mExternalTorque; // If the gravity has to be applied to this rigid body if (bodies[b]->isGravityEnabled() && mIsGravityEnabled) { // Integrate the gravity force - mConstrainedLinearVelocities[indexBody] += dt * bodies[b]->mMassInverse * + mConstrainedLinearVelocities[indexBody] += mTimeStep * bodies[b]->mMassInverse * bodies[b]->getMass() * mGravity; } @@ -351,9 +322,9 @@ void DynamicsWorld::integrateRigidBodiesVelocities() { // => v2 = v1 * (1 - c * dt) decimal linDampingFactor = bodies[b]->getLinearDamping(); decimal angDampingFactor = bodies[b]->getAngularDamping(); - decimal linearDamping = clamp(decimal(1.0) - dt * linDampingFactor, + decimal linearDamping = clamp(decimal(1.0) - mTimeStep * linDampingFactor, decimal(0.0), decimal(1.0)); - decimal angularDamping = clamp(decimal(1.0) - dt * angDampingFactor, + decimal angularDamping = clamp(decimal(1.0) - mTimeStep * angDampingFactor, decimal(0.0), decimal(1.0)); mConstrainedLinearVelocities[indexBody] *= clamp(linearDamping, decimal(0.0), decimal(1.0)); @@ -373,9 +344,6 @@ void DynamicsWorld::solveContactsAndConstraints() { PROFILE("DynamicsWorld::solveContactsAndConstraints()"); - // Get the current time step - decimal dt = static_cast(mTimer.getTimeStep()); - // Set the velocities arrays mContactSolver.setSplitVelocitiesArrays(mSplitLinearVelocities, mSplitAngularVelocities); mContactSolver.setConstrainedVelocitiesArrays(mConstrainedLinearVelocities, @@ -399,7 +367,7 @@ void DynamicsWorld::solveContactsAndConstraints() { if (isContactsToSolve) { // Initialize the solver - mContactSolver.initializeForIsland(dt, mIslands[islandIndex]); + mContactSolver.initializeForIsland(mTimeStep, mIslands[islandIndex]); // Warm start the contact solver mContactSolver.warmStart(); @@ -409,7 +377,7 @@ void DynamicsWorld::solveContactsAndConstraints() { if (isConstraintsToSolve) { // Initialize the constraint solver - mConstraintSolver.initializeForIsland(dt, mIslands[islandIndex]); + mConstraintSolver.initializeForIsland(mTimeStep, mIslands[islandIndex]); } // For each iteration of the velocity solver @@ -811,7 +779,6 @@ void DynamicsWorld::updateSleepingBodies() { PROFILE("DynamicsWorld::updateSleepingBodies()"); - const decimal dt = static_cast(mTimer.getTimeStep()); const decimal sleepLinearVelocitySquare = mSleepLinearVelocity * mSleepLinearVelocity; const decimal sleepAngularVelocitySquare = mSleepAngularVelocity * mSleepAngularVelocity; @@ -839,7 +806,7 @@ void DynamicsWorld::updateSleepingBodies() { else { // If the body velocity is bellow the sleeping velocity threshold // Increase the sleep time - bodies[b]->mSleepTime += dt; + bodies[b]->mSleepTime += mTimeStep; if (bodies[b]->mSleepTime < minSleepTime) { minSleepTime = bodies[b]->mSleepTime; } diff --git a/src/engine/DynamicsWorld.h b/src/engine/DynamicsWorld.h index b03df610..bb0e9acb 100644 --- a/src/engine/DynamicsWorld.h +++ b/src/engine/DynamicsWorld.h @@ -32,7 +32,6 @@ #include "ContactSolver.h" #include "ConstraintSolver.h" #include "body/RigidBody.h" -#include "Timer.h" #include "Island.h" #include "configuration.h" @@ -51,9 +50,6 @@ class DynamicsWorld : public CollisionWorld { // -------------------- Attributes -------------------- // - /// Timer of the physics engine - Timer mTimer; - /// Contact solver ContactSolver mContactSolver; @@ -78,6 +74,9 @@ class DynamicsWorld : public CollisionWorld { /// Gravity vector of the world Vector3 mGravity; + /// Current frame time step (in seconds) + decimal mTimeStep; + /// True if the gravity force is on bool mIsGravityEnabled; @@ -182,7 +181,7 @@ class DynamicsWorld : public CollisionWorld { // -------------------- Methods -------------------- // /// Constructor - DynamicsWorld(const Vector3& mGravity, decimal timeStep); + DynamicsWorld(const Vector3& mGravity); /// Destructor virtual ~DynamicsWorld(); @@ -194,7 +193,7 @@ class DynamicsWorld : public CollisionWorld { void stop(); /// Update the physics simulation - void update(); + void update(decimal timeStep); /// Set the number of iterations for the velocity constraint solver void setNbIterationsVelocitySolver(uint nbIterations); @@ -312,16 +311,7 @@ inline void DynamicsWorld::resetBodiesForceAndTorque() { (*it)->mExternalForce.setToZero(); (*it)->mExternalTorque.setToZero(); } -} - -// Start the physics simulation -inline void DynamicsWorld::start() { - mTimer.start(); -} - -inline void DynamicsWorld::stop() { - mTimer.stop(); -} +} // Set the number of iterations for the velocity constraint solver /** @@ -434,14 +424,6 @@ inline std::set::iterator DynamicsWorld::getRigidBodiesEndIterator() return mRigidBodies.end(); } -// Return the current physics time (in seconds) -/** - * @return The current physics time (in seconds) - */ -inline long double DynamicsWorld::getPhysicsTime() const { - return mTimer.getPhysicsTime(); -} - // Return true if the sleeping technique is enabled /** * @return True if the sleeping technique is enabled and false otherwise diff --git a/src/engine/Timer.cpp b/src/engine/Timer.cpp deleted file mode 100644 index 30698fd4..00000000 --- a/src/engine/Timer.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/******************************************************************************** -* ReactPhysics3D physics library, http://www.reactphysics3d.com * -* Copyright (c) 2010-2015 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -// Libraries -#include "Timer.h" - -// We want to use the ReactPhysics3D namespace -using namespace reactphysics3d; - -// Constructor -Timer::Timer(double timeStep) : mTimeStep(timeStep), mIsRunning(false) { - assert(timeStep > 0.0); -} - -// Destructor -Timer::~Timer() { - -} - -// Return the current time of the system in seconds -long double Timer::getCurrentSystemTime() { - - #if defined(WINDOWS_OS) - LARGE_INTEGER ticksPerSecond; - LARGE_INTEGER ticks; - QueryPerformanceFrequency(&ticksPerSecond); - QueryPerformanceCounter(&ticks); - return (long double(ticks.QuadPart) / long double(ticksPerSecond.QuadPart)); - #else - // Initialize the lastUpdateTime with the current time in seconds - timeval timeValue; - gettimeofday(&timeValue, NULL); - return (timeValue.tv_sec + (timeValue.tv_usec / 1000000.0)); - #endif -} - - - - - - - - - diff --git a/src/engine/Timer.h b/src/engine/Timer.h deleted file mode 100644 index be7a7cac..00000000 --- a/src/engine/Timer.h +++ /dev/null @@ -1,200 +0,0 @@ -/******************************************************************************** -* ReactPhysics3D physics library, http://www.reactphysics3d.com * -* Copyright (c) 2010-2015 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -#ifndef REACTPHYSICS3D_TIMER_H -#define REACTPHYSICS3D_TIMER_H - -// Libraries -#include -#include -#include -#include -#include "configuration.h" - -#if defined(WINDOWS_OS) // For Windows platform - #define NOMINMAX // This is used to avoid definition of max() and min() macros - #include -#else // For Mac OS or Linux platform - #include -#endif - - -/// Namespace ReactPhysics3D -namespace reactphysics3d { - -// Class Timer -/** - * This class will take care of the time in the physics engine. It - * uses functions that depend on the current platform to get the - * current time. - */ -class Timer { - - private : - - // -------------------- Attributes -------------------- // - - /// Timestep dt of the physics engine (timestep > 0.0) - double mTimeStep; - - /// Last time the timer has been updated - long double mLastUpdateTime; - - /// Time difference between the two last timer update() calls - long double mDeltaTime; - - /// Used to fix the time step and avoid strange time effects - double mAccumulator; - - /// True if the timer is running - bool mIsRunning; - - // -------------------- Methods -------------------- // - - /// Private copy-constructor - Timer(const Timer& timer); - - /// Private assignment operator - Timer& operator=(const Timer& timer); - - public : - - // -------------------- Methods -------------------- // - - /// Constructor - Timer(double timeStep); - - /// Destructor - virtual ~Timer(); - - /// Return the timestep of the physics engine - double getTimeStep() const; - - /// Set the timestep of the physics engine - void setTimeStep(double timeStep); - - /// Return the current time of the physics engine - long double getPhysicsTime() const; - - /// Start the timer - void start(); - - /// Stop the timer - void stop(); - - /// Return true if the timer is running - bool getIsRunning() const; - - /// True if it's possible to take a new step - bool isPossibleToTakeStep() const; - - /// Compute the time since the last update() call and add it to the accumulator - void update(); - - /// Take a new step => update the timer by adding the timeStep value to the current time - void nextStep(); - - /// Compute the interpolation factor - decimal computeInterpolationFactor(); - - /// Return the current time of the system in seconds - static long double getCurrentSystemTime(); -}; - -// Return the timestep of the physics engine -inline double Timer::getTimeStep() const { - return mTimeStep; -} - -// Set the timestep of the physics engine -inline void Timer::setTimeStep(double timeStep) { - assert(timeStep > 0.0f); - mTimeStep = timeStep; -} - -// Return the current time -inline long double Timer::getPhysicsTime() const { - return mLastUpdateTime; -} - -// Return if the timer is running -inline bool Timer::getIsRunning() const { - return mIsRunning; -} - -// Start the timer -inline void Timer::start() { - if (!mIsRunning) { - - // Get the current system time - mLastUpdateTime = getCurrentSystemTime(); - - mAccumulator = 0.0; - mIsRunning = true; - } -} - -// Stop the timer -inline void Timer::stop() { - mIsRunning = false; -} - -// True if it's possible to take a new step -inline bool Timer::isPossibleToTakeStep() const { - return (mAccumulator >= mTimeStep); -} - -// Take a new step => update the timer by adding the timeStep value to the current time -inline void Timer::nextStep() { - assert(mIsRunning); - - // Update the accumulator value - mAccumulator -= mTimeStep; -} - -// Compute the interpolation factor -inline decimal Timer::computeInterpolationFactor() { - return (decimal(mAccumulator / mTimeStep)); -} - -// Compute the time since the last update() call and add it to the accumulator -inline void Timer::update() { - - // Get the current system time - long double currentTime = getCurrentSystemTime(); - - // Compute the delta display time between two display frames - mDeltaTime = currentTime - mLastUpdateTime; - - // Update the current display time - mLastUpdateTime = currentTime; - - // Update the accumulator value - mAccumulator += mDeltaTime; -} - -} - - #endif From b8192db3ef82dc06b48ebea08047bd22f1eb7c5a Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Mon, 20 Apr 2015 23:22:22 +0200 Subject: [PATCH 05/36] Fix compilation error in DynamicsWorld --- src/engine/DynamicsWorld.cpp | 3 --- src/engine/DynamicsWorld.h | 9 --------- 2 files changed, 12 deletions(-) diff --git a/src/engine/DynamicsWorld.cpp b/src/engine/DynamicsWorld.cpp index 927b28ee..242c8af9 100644 --- a/src/engine/DynamicsWorld.cpp +++ b/src/engine/DynamicsWorld.cpp @@ -142,9 +142,6 @@ void DynamicsWorld::update(decimal timeStep) { // Reset the external force and torque applied to the bodies resetBodiesForceAndTorque(); - - // Compute and set the interpolation factor to all the bodies - setInterpolationFactorToAllBodies(); } // Integrate position and orientation of the rigid bodies. diff --git a/src/engine/DynamicsWorld.h b/src/engine/DynamicsWorld.h index bb0e9acb..482bc66e 100644 --- a/src/engine/DynamicsWorld.h +++ b/src/engine/DynamicsWorld.h @@ -186,12 +186,6 @@ class DynamicsWorld : public CollisionWorld { /// Destructor virtual ~DynamicsWorld(); - /// Start the physics simulation - void start(); - - /// Stop the physics simulation - void stop(); - /// Update the physics simulation void update(decimal timeStep); @@ -238,9 +232,6 @@ class DynamicsWorld : public CollisionWorld { /// Return the number of joints in the world uint getNbJoints() const; - /// Return the current physics time (in seconds) - long double getPhysicsTime() const; - /// Return an iterator to the beginning of the rigid bodies of the physics world std::set::iterator getRigidBodiesBeginIterator(); From e35db3f150c4ce39d2173f72857c4149735dfd7a Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Mon, 20 Apr 2015 23:23:46 +0200 Subject: [PATCH 06/36] Update the testbed application to perform the interpolation externally --- testbed/CMakeLists.txt | 4 +- testbed/common/Box.cpp | 15 +- testbed/common/Box.h | 5 +- testbed/common/Capsule.cpp | 15 +- testbed/common/Capsule.h | 5 +- testbed/common/Cone.cpp | 15 +- testbed/common/Cone.h | 5 +- testbed/common/ConvexMesh.cpp | 15 +- testbed/common/ConvexMesh.h | 5 +- testbed/common/Cylinder.cpp | 15 +- testbed/common/Cylinder.h | 5 +- testbed/common/Dumbbell.cpp | 15 +- testbed/common/Dumbbell.h | 5 +- testbed/common/Line.h | 3 - testbed/common/Sphere.cpp | 15 +- testbed/common/Sphere.h | 5 +- .../collisionshapes/CollisionShapesScene.cpp | 32 ++-- .../collisionshapes/CollisionShapesScene.h | 4 + testbed/scenes/cubes/CubesScene.cpp | 28 +-- testbed/scenes/cubes/CubesScene.h | 6 +- testbed/scenes/joints/JointsScene.cpp | 34 ++-- testbed/scenes/joints/JointsScene.h | 4 + testbed/scenes/raycast/RaycastScene.cpp | 5 + testbed/scenes/raycast/RaycastScene.h | 4 + testbed/src/Scene.cpp | 2 +- testbed/src/Scene.h | 37 +++- testbed/src/TestbedApplication.cpp | 35 +++- testbed/src/TestbedApplication.h | 10 + testbed/src/Timer.cpp | 64 +++++++ testbed/src/Timer.h | 177 ++++++++++++++++++ 30 files changed, 493 insertions(+), 96 deletions(-) create mode 100644 testbed/src/Timer.cpp create mode 100644 testbed/src/Timer.h diff --git a/testbed/CMakeLists.txt b/testbed/CMakeLists.txt index b5b2fdd7..9a488e1a 100644 --- a/testbed/CMakeLists.txt +++ b/testbed/CMakeLists.txt @@ -20,7 +20,7 @@ FILE(COPY "shaders/" DESTINATION "${EXECUTABLE_OUTPUT_PATH}/shaders/") FILE(COPY "meshes/" DESTINATION "${EXECUTABLE_OUTPUT_PATH}/meshes/") # Headers -INCLUDE_DIRECTORIES("src" "opengl-framework/src/" "glfw/include/" "common/" "scenes/") +INCLUDE_DIRECTORIES("src/" "opengl-framework/src/" "glfw/include/" "common/" "scenes/") # Testbed source files SET(TESTBED_SOURCES @@ -31,6 +31,8 @@ SET(TESTBED_SOURCES src/Gui.cpp src/Scene.h src/Scene.cpp + src/Timer.h + src/Timer.cpp ) # Common source files diff --git a/testbed/common/Box.cpp b/testbed/common/Box.cpp index d0c7a1df..4a95aab0 100644 --- a/testbed/common/Box.cpp +++ b/testbed/common/Box.cpp @@ -85,6 +85,8 @@ Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &p rp3d::Quaternion initOrientation = rp3d::Quaternion::identity(); rp3d::Transform transform(initPosition, initOrientation); + mPreviousTransform = transform; + // Create a rigid body in the dynamics world mRigidBody = world->createCollisionBody(transform); @@ -205,14 +207,19 @@ void Box::render(openglframework::Shader& shader, } // Update the transform matrix of the box -void Box::updateTransform() { +void Box::updateTransform(float interpolationFactor) { - // Get the interpolated transform of the rigid body - rp3d::Transform transform = mRigidBody->getInterpolatedTransform(); + // Get the transform of the rigid body + rp3d::Transform transform = mRigidBody->getTransform(); + + // Interpolate the transform between the previous one and the new one + rp3d::Transform interpolatedTransform = rp3d::Transform::interpolateTransforms(mPreviousTransform, + transform, + interpolationFactor); // Compute the transform used for rendering the box rp3d::decimal matrix[16]; - transform.getOpenGLMatrix(matrix); + interpolatedTransform.getOpenGLMatrix(matrix); openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12], matrix[1], matrix[5], matrix[9], matrix[13], matrix[2], matrix[6], matrix[10], matrix[14], diff --git a/testbed/common/Box.h b/testbed/common/Box.h index 2cc333d8..97c86e5b 100644 --- a/testbed/common/Box.h +++ b/testbed/common/Box.h @@ -56,6 +56,9 @@ class Box : public openglframework::Object3D { /// Rigid body used to simulate the dynamics of the box rp3d::CollisionBody* mRigidBody; + /// Previous transform of the body (for interpolation) + rp3d::Transform mPreviousTransform; + /// Scaling matrix (applied to a cube to obtain the correct box dimensions) openglframework::Matrix4 mScalingMatrix; @@ -104,7 +107,7 @@ class Box : public openglframework::Object3D { reactphysics3d::RigidBody* getRigidBody(); /// Update the transform matrix of the box - void updateTransform(); + void updateTransform(float interpolationFactor); /// Render the cube at the correct position and with the correct orientation void render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix); diff --git a/testbed/common/Capsule.cpp b/testbed/common/Capsule.cpp index faf8484e..7df79f85 100644 --- a/testbed/common/Capsule.cpp +++ b/testbed/common/Capsule.cpp @@ -57,6 +57,8 @@ Capsule::Capsule(float radius, float height, const openglframework::Vector3& pos rp3d::Quaternion initOrientation = rp3d::Quaternion::identity(); rp3d::Transform transform(initPosition, initOrientation); + mPreviousTransform = transform; + // Create a rigid body corresponding in the dynamics world mRigidBody = world->createCollisionBody(transform); @@ -161,14 +163,19 @@ void Capsule::render(openglframework::Shader& shader, } // Update the transform matrix of the sphere -void Capsule::updateTransform() { +void Capsule::updateTransform(float interpolationFactor) { - // Get the interpolated transform of the rigid body - rp3d::Transform transform = mRigidBody->getInterpolatedTransform(); + // Get the transform of the rigid body + rp3d::Transform transform = mRigidBody->getTransform(); + + // Interpolate the transform between the previous one and the new one + rp3d::Transform interpolatedTransform = rp3d::Transform::interpolateTransforms(mPreviousTransform, + transform, + interpolationFactor); // Compute the transform used for rendering the sphere rp3d::decimal matrix[16]; - transform.getOpenGLMatrix(matrix); + interpolatedTransform.getOpenGLMatrix(matrix); openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12], matrix[1], matrix[5], matrix[9], matrix[13], matrix[2], matrix[6], matrix[10], matrix[14], diff --git a/testbed/common/Capsule.h b/testbed/common/Capsule.h index 2ce438d1..6954fb85 100644 --- a/testbed/common/Capsule.h +++ b/testbed/common/Capsule.h @@ -49,6 +49,9 @@ class Capsule : public openglframework::Mesh { /// Scaling matrix (applied to a sphere to obtain the correct sphere dimensions) openglframework::Matrix4 mScalingMatrix; + /// Previous transform (for interpolation) + rp3d::Transform mPreviousTransform; + // -------------------- Methods -------------------- // public : @@ -74,7 +77,7 @@ class Capsule : public openglframework::Mesh { reactphysics3d::RigidBody* getRigidBody(); /// Update the transform matrix of the sphere - void updateTransform(); + void updateTransform(float interpolationFactor); /// Render the sphere at the correct position and with the correct orientation void render(openglframework::Shader& shader, diff --git a/testbed/common/Cone.cpp b/testbed/common/Cone.cpp index 9e3f24b6..c6cbc070 100644 --- a/testbed/common/Cone.cpp +++ b/testbed/common/Cone.cpp @@ -57,6 +57,8 @@ Cone::Cone(float radius, float height, const openglframework::Vector3 &position, rp3d::Quaternion initOrientation = rp3d::Quaternion::identity(); rp3d::Transform transform(initPosition, initOrientation); + mPreviousTransform = transform; + // Create a rigid body corresponding to the cone in the dynamics world mRigidBody = world->createCollisionBody(transform); @@ -161,14 +163,19 @@ void Cone::render(openglframework::Shader& shader, } // Update the transform matrix of the cone -void Cone::updateTransform() { +void Cone::updateTransform(float interpolationFactor) { - // Get the interpolated transform of the rigid body - rp3d::Transform transform = mRigidBody->getInterpolatedTransform(); + // Get the transform of the rigid body + rp3d::Transform transform = mRigidBody->getTransform(); + + // Interpolate the transform between the previous one and the new one + rp3d::Transform interpolatedTransform = rp3d::Transform::interpolateTransforms(mPreviousTransform, + transform, + interpolationFactor); // Compute the transform used for rendering the cone rp3d::decimal matrix[16]; - transform.getOpenGLMatrix(matrix); + interpolatedTransform.getOpenGLMatrix(matrix); openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12], matrix[1], matrix[5], matrix[9], matrix[13], matrix[2], matrix[6], matrix[10], matrix[14], diff --git a/testbed/common/Cone.h b/testbed/common/Cone.h index d3002eab..56e3e9db 100644 --- a/testbed/common/Cone.h +++ b/testbed/common/Cone.h @@ -49,6 +49,9 @@ class Cone : public openglframework::Mesh { /// Scaling matrix (applied to a sphere to obtain the correct cone dimensions) openglframework::Matrix4 mScalingMatrix; + /// Previous transform (for interpolation) + rp3d::Transform mPreviousTransform; + // -------------------- Methods -------------------- // public : @@ -73,7 +76,7 @@ class Cone : public openglframework::Mesh { reactphysics3d::RigidBody* getRigidBody(); /// Update the transform matrix of the cone - void updateTransform(); + void updateTransform(float interpolationFactor); /// Render the cone at the correct position and with the correct orientation void render(openglframework::Shader& shader, diff --git a/testbed/common/ConvexMesh.cpp b/testbed/common/ConvexMesh.cpp index dbb2c28a..b7d9a59d 100644 --- a/testbed/common/ConvexMesh.cpp +++ b/testbed/common/ConvexMesh.cpp @@ -79,6 +79,8 @@ ConvexMesh::ConvexMesh(const openglframework::Vector3 &position, rp3d::Quaternion initOrientation = rp3d::Quaternion::identity(); rp3d::Transform transform(initPosition, initOrientation); + mPreviousTransform = transform; + // Create a rigid body corresponding to the sphere in the dynamics world mRigidBody = world->createCollisionBody(transform); @@ -200,14 +202,19 @@ void ConvexMesh::render(openglframework::Shader& shader, } // Update the transform matrix of the sphere -void ConvexMesh::updateTransform() { +void ConvexMesh::updateTransform(float interpolationFactor) { - // Get the interpolated transform of the rigid body - rp3d::Transform transform = mRigidBody->getInterpolatedTransform(); + // Get the transform of the rigid body + rp3d::Transform transform = mRigidBody->getTransform(); + + // Interpolate the transform between the previous one and the new one + rp3d::Transform interpolatedTransform = rp3d::Transform::interpolateTransforms(mPreviousTransform, + transform, + interpolationFactor); // Compute the transform used for rendering the sphere rp3d::decimal matrix[16]; - transform.getOpenGLMatrix(matrix); + interpolatedTransform.getOpenGLMatrix(matrix); openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12], matrix[1], matrix[5], matrix[9], matrix[13], matrix[2], matrix[6], matrix[10], matrix[14], diff --git a/testbed/common/ConvexMesh.h b/testbed/common/ConvexMesh.h index f97ec5ec..8f3457dc 100644 --- a/testbed/common/ConvexMesh.h +++ b/testbed/common/ConvexMesh.h @@ -40,6 +40,9 @@ class ConvexMesh : public openglframework::Mesh { /// Rigid body used to simulate the dynamics of the mesh rp3d::CollisionBody* mRigidBody; + /// Previous transform (for interpolation) + rp3d::Transform mPreviousTransform; + // -------------------- Methods -------------------- // public : @@ -64,7 +67,7 @@ class ConvexMesh : public openglframework::Mesh { reactphysics3d::RigidBody* getRigidBody(); /// Update the transform matrix of the mesh - void updateTransform(); + void updateTransform(float interpolationFactor); /// Render the mesh at the correct position and with the correct orientation void render(openglframework::Shader& shader, diff --git a/testbed/common/Cylinder.cpp b/testbed/common/Cylinder.cpp index 7c2b7690..a66d4664 100644 --- a/testbed/common/Cylinder.cpp +++ b/testbed/common/Cylinder.cpp @@ -57,6 +57,8 @@ Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& p rp3d::Quaternion initOrientation = rp3d::Quaternion::identity(); rp3d::Transform transform(initPosition, initOrientation); + mPreviousTransform = transform; + // Create a rigid body corresponding to the cylinder in the dynamics world mRigidBody = world->createCollisionBody(transform); @@ -161,14 +163,19 @@ void Cylinder::render(openglframework::Shader& shader, } // Update the transform matrix of the cylinder -void Cylinder::updateTransform() { +void Cylinder::updateTransform(float interpolationFactor) { - // Get the interpolated transform of the rigid body - rp3d::Transform transform = mRigidBody->getInterpolatedTransform(); + // Get the transform of the rigid body + rp3d::Transform transform = mRigidBody->getTransform(); + + // Interpolate the transform between the previous one and the new one + rp3d::Transform interpolatedTransform = rp3d::Transform::interpolateTransforms(mPreviousTransform, + transform, + interpolationFactor); // Compute the transform used for rendering the cylinder rp3d::decimal matrix[16]; - transform.getOpenGLMatrix(matrix); + interpolatedTransform.getOpenGLMatrix(matrix); openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12], matrix[1], matrix[5], matrix[9], matrix[13], matrix[2], matrix[6], matrix[10], matrix[14], diff --git a/testbed/common/Cylinder.h b/testbed/common/Cylinder.h index 9236fe20..bfea6f4e 100644 --- a/testbed/common/Cylinder.h +++ b/testbed/common/Cylinder.h @@ -49,6 +49,9 @@ class Cylinder : public openglframework::Mesh { /// Scaling matrix (applied to a sphere to obtain the correct cylinder dimensions) openglframework::Matrix4 mScalingMatrix; + /// Previous transform (for interpolation) + rp3d::Transform mPreviousTransform; + // -------------------- Methods -------------------- // public : @@ -73,7 +76,7 @@ class Cylinder : public openglframework::Mesh { reactphysics3d::RigidBody* getRigidBody(); /// Update the transform matrix of the cylinder - void updateTransform(); + void updateTransform(float interpolationFactor); /// Render the cylinder at the correct position and with the correct orientation void render(openglframework::Shader& shader, diff --git a/testbed/common/Dumbbell.cpp b/testbed/common/Dumbbell.cpp index a358db61..3059d974 100644 --- a/testbed/common/Dumbbell.cpp +++ b/testbed/common/Dumbbell.cpp @@ -64,6 +64,8 @@ Dumbbell::Dumbbell(const openglframework::Vector3 &position, rp3d::Quaternion initOrientation(angleAroundX, 0, 0); rp3d::Transform transformBody(initPosition, initOrientation); + mPreviousTransform = transformBody; + // Initial transform of the first sphere collision shape of the dumbbell (in local-space) rp3d::Transform transformSphereShape1(rp3d::Vector3(0, 4.0, 0), rp3d::Quaternion::identity()); @@ -197,14 +199,19 @@ void Dumbbell::render(openglframework::Shader& shader, } // Update the transform matrix of the sphere -void Dumbbell::updateTransform() { +void Dumbbell::updateTransform(float interpolationFactor) { - // Get the interpolated transform of the rigid body - rp3d::Transform transform = mBody->getInterpolatedTransform(); + // Get the transform of the rigid body + rp3d::Transform transform = mBody->getTransform(); + + // Interpolate the transform between the previous one and the new one + rp3d::Transform interpolatedTransform = rp3d::Transform::interpolateTransforms(mPreviousTransform, + transform, + interpolationFactor); // Compute the transform used for rendering the sphere rp3d::decimal matrix[16]; - transform.getOpenGLMatrix(matrix); + interpolatedTransform.getOpenGLMatrix(matrix); openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12], matrix[1], matrix[5], matrix[9], matrix[13], matrix[2], matrix[6], matrix[10], matrix[14], diff --git a/testbed/common/Dumbbell.h b/testbed/common/Dumbbell.h index ff673951..d2dc0bbd 100644 --- a/testbed/common/Dumbbell.h +++ b/testbed/common/Dumbbell.h @@ -46,6 +46,9 @@ class Dumbbell : public openglframework::Mesh { /// Scaling matrix (applied to a sphere to obtain the correct sphere dimensions) openglframework::Matrix4 mScalingMatrix; + /// Previous transform (for interpolation) + rp3d::Transform mPreviousTransform; + // -------------------- Methods -------------------- // public : @@ -71,7 +74,7 @@ class Dumbbell : public openglframework::Mesh { rp3d::CollisionBody* getCollisionBody(); /// Update the transform matrix of the sphere - void updateTransform(); + void updateTransform(float interpolationFactor); /// Render the sphere at the correct position and with the correct orientation void render(openglframework::Shader& shader, diff --git a/testbed/common/Line.h b/testbed/common/Line.h index 41de3266..5f6b0d1f 100644 --- a/testbed/common/Line.h +++ b/testbed/common/Line.h @@ -58,9 +58,6 @@ class Line : public openglframework::Object3D { /// Return the second point of the line openglframework::Vector3 getPoint2() const; - /// Update the transform matrix of the sphere - void updateTransform(); - /// Render the line at the correct position and with the correct orientation void render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix); diff --git a/testbed/common/Sphere.cpp b/testbed/common/Sphere.cpp index 56882569..280ddd73 100644 --- a/testbed/common/Sphere.cpp +++ b/testbed/common/Sphere.cpp @@ -57,6 +57,8 @@ Sphere::Sphere(float radius, const openglframework::Vector3 &position, rp3d::Quaternion initOrientation = rp3d::Quaternion::identity(); rp3d::Transform transform(initPosition, initOrientation); + mPreviousTransform = transform; + // Create a rigid body corresponding to the sphere in the dynamics world mRigidBody = world->createCollisionBody(transform); @@ -161,14 +163,19 @@ void Sphere::render(openglframework::Shader& shader, } // Update the transform matrix of the sphere -void Sphere::updateTransform() { +void Sphere::updateTransform(float interpolationFactor) { - // Get the interpolated transform of the rigid body - rp3d::Transform transform = mRigidBody->getInterpolatedTransform(); + // Get the transform of the rigid body + rp3d::Transform transform = mRigidBody->getTransform(); + + // Interpolate the transform between the previous one and the new one + rp3d::Transform interpolatedTransform = rp3d::Transform::interpolateTransforms(mPreviousTransform, + transform, + interpolationFactor); // Compute the transform used for rendering the sphere rp3d::decimal matrix[16]; - transform.getOpenGLMatrix(matrix); + interpolatedTransform.getOpenGLMatrix(matrix); openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12], matrix[1], matrix[5], matrix[9], matrix[13], matrix[2], matrix[6], matrix[10], matrix[14], diff --git a/testbed/common/Sphere.h b/testbed/common/Sphere.h index 08a335f7..84b6739d 100644 --- a/testbed/common/Sphere.h +++ b/testbed/common/Sphere.h @@ -46,6 +46,9 @@ class Sphere : public openglframework::Mesh { /// Scaling matrix (applied to a sphere to obtain the correct sphere dimensions) openglframework::Matrix4 mScalingMatrix; + /// Previous transform (for interpolation) + rp3d::Transform mPreviousTransform; + // -------------------- Methods -------------------- // public : @@ -70,7 +73,7 @@ class Sphere : public openglframework::Mesh { reactphysics3d::RigidBody* getRigidBody(); /// Update the transform matrix of the sphere - void updateTransform(); + void updateTransform(float interpolationFactor); /// Render the sphere at the correct position and with the correct orientation void render(openglframework::Shader& shader, diff --git a/testbed/scenes/collisionshapes/CollisionShapesScene.cpp b/testbed/scenes/collisionshapes/CollisionShapesScene.cpp index b6bebe79..3dd02d24 100644 --- a/testbed/scenes/collisionshapes/CollisionShapesScene.cpp +++ b/testbed/scenes/collisionshapes/CollisionShapesScene.cpp @@ -53,7 +53,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name) rp3d::decimal timeStep = 1.0f / 60.0f; // Create the dynamics world for the physics simulation - mDynamicsWorld = new rp3d::DynamicsWorld(gravity, timeStep); + mDynamicsWorld = new rp3d::DynamicsWorld(gravity); // Set the number of iterations of the constraint solver mDynamicsWorld->setNbIterationsVelocitySolver(15); @@ -216,9 +216,6 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name) // Change the material properties of the rigid body rp3d::Material& material = mFloor->getRigidBody()->getMaterial(); material.setBounciness(rp3d::decimal(0.2)); - - // Start the simulation - mDynamicsWorld->start(); } // Destructor @@ -309,46 +306,49 @@ CollisionShapesScene::~CollisionShapesScene() { delete mDynamicsWorld; } -// Take a step for the simulation -void CollisionShapesScene::update() { - +// Update the physics world (take a simulation step) +void CollisionShapesScene::updatePhysics() { // Take a simulation step - mDynamicsWorld->update(); + mDynamicsWorld->update(mEngineSettings.timeStep); +} + +// Take a step for the simulation +void CollisionShapesScene::update() { // Update the position and orientation of the boxes for (std::vector::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { // Update the transform used for the rendering - (*it)->updateTransform(); + (*it)->updateTransform(mInterpolationFactor); } // Update the position and orientation of the sphere for (std::vector::iterator it = mSpheres.begin(); it != mSpheres.end(); ++it) { // Update the transform used for the rendering - (*it)->updateTransform(); + (*it)->updateTransform(mInterpolationFactor); } // Update the position and orientation of the cones for (std::vector::iterator it = mCones.begin(); it != mCones.end(); ++it) { // Update the transform used for the rendering - (*it)->updateTransform(); + (*it)->updateTransform(mInterpolationFactor); } // Update the position and orientation of the cylinders for (std::vector::iterator it = mCylinders.begin(); it != mCylinders.end(); ++it) { // Update the transform used for the rendering - (*it)->updateTransform(); + (*it)->updateTransform(mInterpolationFactor); } // Update the position and orientation of the capsules for (std::vector::iterator it = mCapsules.begin(); it != mCapsules.end(); ++it) { // Update the transform used for the rendering - (*it)->updateTransform(); + (*it)->updateTransform(mInterpolationFactor); } // Update the position and orientation of the convex meshes @@ -356,7 +356,7 @@ void CollisionShapesScene::update() { it != mConvexMeshes.end(); ++it) { // Update the transform used for the rendering - (*it)->updateTransform(); + (*it)->updateTransform(mInterpolationFactor); } // Update the position and orientation of the dumbbells @@ -364,10 +364,10 @@ void CollisionShapesScene::update() { it != mDumbbells.end(); ++it) { // Update the transform used for the rendering - (*it)->updateTransform(); + (*it)->updateTransform(mInterpolationFactor); } - mFloor->updateTransform(); + mFloor->updateTransform(mInterpolationFactor); } // Render the scene diff --git a/testbed/scenes/collisionshapes/CollisionShapesScene.h b/testbed/scenes/collisionshapes/CollisionShapesScene.h index a9b79e45..4a4e49b3 100644 --- a/testbed/scenes/collisionshapes/CollisionShapesScene.h +++ b/testbed/scenes/collisionshapes/CollisionShapesScene.h @@ -114,6 +114,10 @@ class CollisionShapesScene : public Scene{ /// Destructor virtual ~CollisionShapesScene(); + /// Update the physics world (take a simulation step) + /// Can be called several times per frame + virtual void updatePhysics(); + /// Take a step for the simulation virtual void update(); diff --git a/testbed/scenes/cubes/CubesScene.cpp b/testbed/scenes/cubes/CubesScene.cpp index eb31d77e..e44d10e1 100644 --- a/testbed/scenes/cubes/CubesScene.cpp +++ b/testbed/scenes/cubes/CubesScene.cpp @@ -52,7 +52,7 @@ CubesScene::CubesScene(const std::string& name) rp3d::decimal timeStep = 1.0f / 60.0f; // Create the dynamics world for the physics simulation - mDynamicsWorld = new rp3d::DynamicsWorld(gravity, timeStep); + mDynamicsWorld = new rp3d::DynamicsWorld(gravity); // Set the number of iterations of the constraint solver mDynamicsWorld->setNbIterationsVelocitySolver(15); @@ -89,18 +89,11 @@ CubesScene::CubesScene(const std::string& name) // Change the material properties of the floor rigid body rp3d::Material& material = mFloor->getRigidBody()->getMaterial(); material.setBounciness(rp3d::decimal(0.3)); - - // Start the simulation - mDynamicsWorld->start(); - - counter=0; } // Destructor CubesScene::~CubesScene() { - mDynamicsWorld->stop(); - // Destroy the shader mPhongShader.destroy(); @@ -124,25 +117,24 @@ CubesScene::~CubesScene() { delete mDynamicsWorld; } -// Take a step for the simulation -void CubesScene::update() { - - counter++; - if (counter == 400) { - //mIsRunning = false; - } +// Update the physics world (take a simulation step) +void CubesScene::updatePhysics() { // Take a simulation step - mDynamicsWorld->update(); + mDynamicsWorld->update(mEngineSettings.timeStep); +} + +// Update the scene +void CubesScene::update() { // Update the position and orientation of the boxes for (std::vector::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { // Update the transform used for the rendering - (*it)->updateTransform(); + (*it)->updateTransform(mInterpolationFactor); } - mFloor->updateTransform(); + mFloor->updateTransform(mInterpolationFactor); // Set the color of the awake/sleeping bodies for (uint i=0; isetNbIterationsVelocitySolver(15); @@ -72,17 +72,11 @@ JointsScene::JointsScene(const std::string& name) // Create the floor createFloor(); - - // Start the simulation - mDynamicsWorld->start(); } // Destructor JointsScene::~JointsScene() { - // Stop the physics simulation - mDynamicsWorld->stop(); - // Destroy the shader mPhongShader.destroy(); @@ -122,28 +116,32 @@ JointsScene::~JointsScene() { delete mDynamicsWorld; } -// Take a step for the simulation -void JointsScene::update() { +// Update the physics world (take a simulation step) +void JointsScene::updatePhysics() { // Update the motor speed of the Slider Joint (to move up and down) - long double motorSpeed = 2 * cos(mDynamicsWorld->getPhysicsTime() * 1.5); + long double motorSpeed = 2 * cos(mEngineSettings.elapsedTime * 1.5); mSliderJoint->setMotorSpeed(rp3d::decimal(motorSpeed)); // Take a simulation step - mDynamicsWorld->update(); + mDynamicsWorld->update(mEngineSettings.timeStep); +} + +// Take a step for the simulation +void JointsScene::update() { // Update the position and orientation of the boxes - mSliderJointBottomBox->updateTransform(); - mSliderJointTopBox->updateTransform(); - mPropellerBox->updateTransform(); - mFixedJointBox1->updateTransform(); - mFixedJointBox2->updateTransform(); + mSliderJointBottomBox->updateTransform(mInterpolationFactor); + mSliderJointTopBox->updateTransform(mInterpolationFactor); + mPropellerBox->updateTransform(mInterpolationFactor); + mFixedJointBox1->updateTransform(mInterpolationFactor); + mFixedJointBox2->updateTransform(mInterpolationFactor); for (int i=0; iupdateTransform(); + mBallAndSocketJointChainBoxes[i]->updateTransform(mInterpolationFactor); } // Update the position and orientation of the floor - mFloor->updateTransform(); + mFloor->updateTransform(mInterpolationFactor); } // Render the scene diff --git a/testbed/scenes/joints/JointsScene.h b/testbed/scenes/joints/JointsScene.h index 18920700..a55682e9 100644 --- a/testbed/scenes/joints/JointsScene.h +++ b/testbed/scenes/joints/JointsScene.h @@ -127,6 +127,10 @@ class JointsScene : public Scene { /// Destructor virtual ~JointsScene(); + /// Update the physics world (take a simulation step) + /// Can be called several times per frame + virtual void updatePhysics(); + /// Take a step for the simulation virtual void update(); diff --git a/testbed/scenes/raycast/RaycastScene.cpp b/testbed/scenes/raycast/RaycastScene.cpp index 0eef3411..d3d42eb4 100644 --- a/testbed/scenes/raycast/RaycastScene.cpp +++ b/testbed/scenes/raycast/RaycastScene.cpp @@ -227,6 +227,11 @@ RaycastScene::~RaycastScene() { } } +// Update the physics world (take a simulation step) +void RaycastScene::updatePhysics() { + +} + // Take a step for the simulation void RaycastScene::update() { diff --git a/testbed/scenes/raycast/RaycastScene.h b/testbed/scenes/raycast/RaycastScene.h index fc809731..f3e6ed4d 100644 --- a/testbed/scenes/raycast/RaycastScene.h +++ b/testbed/scenes/raycast/RaycastScene.h @@ -177,6 +177,10 @@ class RaycastScene : public Scene { /// Destructor virtual ~RaycastScene(); + /// Update the physics world (take a simulation step) + /// Can be called several times per frame + virtual void updatePhysics(); + /// Take a step for the simulation virtual void update(); diff --git a/testbed/src/Scene.cpp b/testbed/src/Scene.cpp index 497e79ae..5d832746 100644 --- a/testbed/src/Scene.cpp +++ b/testbed/src/Scene.cpp @@ -30,7 +30,7 @@ using namespace openglframework; // Constructor -Scene::Scene(const std::string& name) : mName(name) { +Scene::Scene(const std::string& name) : mName(name), mInterpolationFactor(0.0f) { } diff --git a/testbed/src/Scene.h b/testbed/src/Scene.h index ebe3476a..501aa970 100644 --- a/testbed/src/Scene.h +++ b/testbed/src/Scene.h @@ -29,6 +29,16 @@ // Libraries #include "openglframework.h" +/// Structure EngineSettings +/// This structure contains several physics engine parameters +struct EngineSettings { + + public: + + float elapsedTime; // Elapsed time (in seconds) + float timeStep; // Current time step (in seconds) +}; + // Class Scene // Abstract class that represents a 3D scene. class Scene { @@ -40,6 +50,9 @@ class Scene { /// Scene name std::string mName; + /// Physics engine settings + EngineSettings mEngineSettings; + /// Camera openglframework::Camera mCamera; @@ -58,6 +71,9 @@ class Scene { /// True if the last point computed on a sphere (for camera rotation) is valid bool mIsLastPointOnSphereValid; + /// Interpolation factor for the bodies in the current frame + float mInterpolationFactor; + // -------------------- Methods -------------------- // /// Set the scene position (where the camera needs to look at) @@ -93,7 +109,11 @@ class Scene { /// Reshape the view virtual void reshape(int width, int height); - /// Update the scene (take a simulation step) + /// Update the physics world (take a simulation step) + /// Can be called several times per frame + virtual void updatePhysics()=0; + + /// Update the scene virtual void update()=0; /// Render the scene @@ -121,6 +141,12 @@ class Scene { /// Return a reference to the camera const openglframework::Camera& getCamera() const; + + /// Set the engine settings + void setEngineSettings(const EngineSettings& settings); + + /// Set the interpolation factor + void setInterpolationFactor(float interpolationFactor); }; // Called when a keyboard event occurs @@ -144,5 +170,14 @@ inline void Scene::setWindowDimension(int width, int height) { mWindowHeight = height; } +// Set the engine settings +inline void Scene::setEngineSettings(const EngineSettings& settings) { + mEngineSettings = settings; +} + +// Set the interpolation factor +inline void Scene::setInterpolationFactor(float interpolationFactor) { + mInterpolationFactor = interpolationFactor; +} #endif diff --git a/testbed/src/TestbedApplication.cpp b/testbed/src/TestbedApplication.cpp index 0b7e8a55..a4ca82f8 100644 --- a/testbed/src/TestbedApplication.cpp +++ b/testbed/src/TestbedApplication.cpp @@ -124,6 +124,8 @@ void TestbedApplication::init() { // Create all the scenes createScenes(); + + mTimer.start(); } // Create all the scenes @@ -159,9 +161,40 @@ void TestbedApplication::destroyScenes() { mCurrentScene = NULL; } +// Update the physics of the current scene +void TestbedApplication::updatePhysics() { + + // Set the engine settings + mEngineSettings.elapsedTime = mTimer.getPhysicsTime(); + mCurrentScene->setEngineSettings(mEngineSettings); + + if (mTimer.isRunning()) { + + // Compute the time since the last update() call and update the timer + mTimer.update(); + + // While the time accumulator is not empty + while(mTimer.isPossibleToTakeStep()) { + + // Take a physics simulation step + mCurrentScene->updatePhysics(); + + // Update the timer + mTimer.nextStep(); + } + } +} + void TestbedApplication::update() { - // Physics simulation + // Compute the interpolation factor + float factor = mTimer.computeInterpolationFactor(mEngineSettings.timeStep); + assert(factor >= 0.0f && factor <= 1.0f); + + // Notify the scene about the interpolation factor + mCurrentScene->setInterpolationFactor(factor); + + // Update the scene mCurrentScene->update(); // Compute the current framerate diff --git a/testbed/src/TestbedApplication.h b/testbed/src/TestbedApplication.h index 7472bbee..e3c5121a 100644 --- a/testbed/src/TestbedApplication.h +++ b/testbed/src/TestbedApplication.h @@ -30,6 +30,7 @@ #include "openglframework.h" #include "GUI.h" #include "Scene.h" +#include "Timer.h" #include /// Class TestbedApplication @@ -50,12 +51,18 @@ class TestbedApplication { /// Graphical User Interface Gui mGUI; + /// Timer + Timer mTimer; + /// List of 3D scenes std::vector mScenes; /// Current 3D scene Scene* mCurrentScene; + /// Physics engine settings + EngineSettings mEngineSettings; + /// Current number of frames per seconds double mFPS; @@ -85,6 +92,9 @@ class TestbedApplication { /// Private assignment operator (for the singleton class) void operator=(TestbedApplication const&); + /// Update the physics of the current scene + void updatePhysics(); + /// Update void update(); diff --git a/testbed/src/Timer.cpp b/testbed/src/Timer.cpp new file mode 100644 index 00000000..a7849534 --- /dev/null +++ b/testbed/src/Timer.cpp @@ -0,0 +1,64 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Libraries +#include "Timer.h" + + +// Constructor +Timer::Timer() : mIsRunning(false) { + +} + +// Destructor +Timer::~Timer() { + +} + +// Return the current time of the system in seconds +long double Timer::getCurrentSystemTime() { + + #if defined(WINDOWS_OS) + LARGE_INTEGER ticksPerSecond; + LARGE_INTEGER ticks; + QueryPerformanceFrequency(&ticksPerSecond); + QueryPerformanceCounter(&ticks); + return (long double(ticks.QuadPart) / long double(ticksPerSecond.QuadPart)); + #else + // Initialize the lastUpdateTime with the current time in seconds + timeval timeValue; + gettimeofday(&timeValue, NULL); + return (timeValue.tv_sec + (timeValue.tv_usec / 1000000.0)); + #endif +} + + + + + + + + + diff --git a/testbed/src/Timer.h b/testbed/src/Timer.h new file mode 100644 index 00000000..f551ec1f --- /dev/null +++ b/testbed/src/Timer.h @@ -0,0 +1,177 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +#ifndef TIMER_H +#define TIMER_H + +// Libraries +#include +#include +#include +#include +#include "configuration.h" + +#if defined(WINDOWS_OS) // For Windows platform + #define NOMINMAX // This is used to avoid definition of max() and min() macros + #include +#else // For Mac OS or Linux platform + #include +#endif + +// Class Timer +/** + * This class will take care of the time in the physics engine. It + * uses functions that depend on the current platform to get the + * current time. + */ +class Timer { + + private : + + // -------------------- Attributes -------------------- // + + /// Timestep dt of the physics engine (timestep > 0.0) + double mTimeStep; + + /// Last time the timer has been updated + long double mLastUpdateTime; + + /// Time difference between the two last timer update() calls + long double mDeltaTime; + + /// Used to fix the time step and avoid strange time effects + double mAccumulator; + + /// True if the timer is running + bool mIsRunning; + + // -------------------- Methods -------------------- // + + /// Private copy-constructor + Timer(const Timer& timer); + + /// Private assignment operator + Timer& operator=(const Timer& timer); + + public : + + // -------------------- Methods -------------------- // + + /// Constructor + Timer(); + + /// Destructor + virtual ~Timer(); + + /// Return the current time of the physics engine + long double getPhysicsTime() const; + + /// Start the timer + void start(); + + /// Stop the timer + void stop(); + + /// Return true if the timer is running + bool isRunning() const; + + /// True if it's possible to take a new step + bool isPossibleToTakeStep() const; + + /// Compute the time since the last update() call and add it to the accumulator + void update(); + + /// Take a new step => update the timer by adding the timeStep value to the current time + void nextStep(); + + /// Compute the interpolation factor + float computeInterpolationFactor(float timeStep); + + /// Return the current time of the system in seconds + static long double getCurrentSystemTime(); +}; + +// Return the current time +inline long double Timer::getPhysicsTime() const { + return mLastUpdateTime; +} + +// Return if the timer is running +inline bool Timer::isRunning() const { + return mIsRunning; +} + +// Start the timer +inline void Timer::start() { + if (!mIsRunning) { + + // Get the current system time + mLastUpdateTime = getCurrentSystemTime(); + + mAccumulator = 0.0; + mIsRunning = true; + } +} + +// Stop the timer +inline void Timer::stop() { + mIsRunning = false; +} + +// True if it's possible to take a new step +inline bool Timer::isPossibleToTakeStep() const { + return (mAccumulator >= mTimeStep); +} + +// Take a new step => update the timer by adding the timeStep value to the current time +inline void Timer::nextStep() { + assert(mIsRunning); + + // Update the accumulator value + mAccumulator -= mTimeStep; +} + +// Compute the interpolation factor +inline float Timer::computeInterpolationFactor(float timeStep) { + return (float(mAccumulator) / timeStep); +} + +// Compute the time since the last update() call and add it to the accumulator +inline void Timer::update() { + + // Get the current system time + long double currentTime = getCurrentSystemTime(); + + // Compute the delta display time between two display frames + mDeltaTime = currentTime - mLastUpdateTime; + + // Update the current display time + mLastUpdateTime = currentTime; + + // Update the accumulator value + mAccumulator += mDeltaTime; +} + + #endif From 28b7a0c0593d62f127b36f0559be20bbbd7de91c Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Wed, 22 Apr 2015 20:54:17 +0200 Subject: [PATCH 07/36] fix issue with interpolation in testbed application --- testbed/common/Box.cpp | 1 + testbed/common/Capsule.cpp | 1 + testbed/common/Cone.cpp | 2 ++ testbed/common/ConvexMesh.cpp | 1 + testbed/common/Cylinder.cpp | 1 + testbed/common/Dumbbell.cpp | 1 + testbed/common/Sphere.cpp | 1 + testbed/src/Scene.h | 5 +++++ testbed/src/TestbedApplication.cpp | 12 +++++++++--- testbed/src/TestbedApplication.h | 3 +++ testbed/src/Timer.h | 15 ++++++--------- 11 files changed, 31 insertions(+), 12 deletions(-) diff --git a/testbed/common/Box.cpp b/testbed/common/Box.cpp index 4a95aab0..68d213e7 100644 --- a/testbed/common/Box.cpp +++ b/testbed/common/Box.cpp @@ -216,6 +216,7 @@ void Box::updateTransform(float interpolationFactor) { rp3d::Transform interpolatedTransform = rp3d::Transform::interpolateTransforms(mPreviousTransform, transform, interpolationFactor); + mPreviousTransform = transform; // Compute the transform used for rendering the box rp3d::decimal matrix[16]; diff --git a/testbed/common/Capsule.cpp b/testbed/common/Capsule.cpp index 7df79f85..81b6fcbe 100644 --- a/testbed/common/Capsule.cpp +++ b/testbed/common/Capsule.cpp @@ -172,6 +172,7 @@ void Capsule::updateTransform(float interpolationFactor) { rp3d::Transform interpolatedTransform = rp3d::Transform::interpolateTransforms(mPreviousTransform, transform, interpolationFactor); + mPreviousTransform = transform; // Compute the transform used for rendering the sphere rp3d::decimal matrix[16]; diff --git a/testbed/common/Cone.cpp b/testbed/common/Cone.cpp index c6cbc070..274c18e2 100644 --- a/testbed/common/Cone.cpp +++ b/testbed/common/Cone.cpp @@ -173,6 +173,8 @@ void Cone::updateTransform(float interpolationFactor) { transform, interpolationFactor); + mPreviousTransform = transform; + // Compute the transform used for rendering the cone rp3d::decimal matrix[16]; interpolatedTransform.getOpenGLMatrix(matrix); diff --git a/testbed/common/ConvexMesh.cpp b/testbed/common/ConvexMesh.cpp index b7d9a59d..91351ece 100644 --- a/testbed/common/ConvexMesh.cpp +++ b/testbed/common/ConvexMesh.cpp @@ -211,6 +211,7 @@ void ConvexMesh::updateTransform(float interpolationFactor) { rp3d::Transform interpolatedTransform = rp3d::Transform::interpolateTransforms(mPreviousTransform, transform, interpolationFactor); + mPreviousTransform = transform; // Compute the transform used for rendering the sphere rp3d::decimal matrix[16]; diff --git a/testbed/common/Cylinder.cpp b/testbed/common/Cylinder.cpp index a66d4664..5d11764d 100644 --- a/testbed/common/Cylinder.cpp +++ b/testbed/common/Cylinder.cpp @@ -172,6 +172,7 @@ void Cylinder::updateTransform(float interpolationFactor) { rp3d::Transform interpolatedTransform = rp3d::Transform::interpolateTransforms(mPreviousTransform, transform, interpolationFactor); + mPreviousTransform = transform; // Compute the transform used for rendering the cylinder rp3d::decimal matrix[16]; diff --git a/testbed/common/Dumbbell.cpp b/testbed/common/Dumbbell.cpp index 3059d974..ca35377f 100644 --- a/testbed/common/Dumbbell.cpp +++ b/testbed/common/Dumbbell.cpp @@ -208,6 +208,7 @@ void Dumbbell::updateTransform(float interpolationFactor) { rp3d::Transform interpolatedTransform = rp3d::Transform::interpolateTransforms(mPreviousTransform, transform, interpolationFactor); + mPreviousTransform = transform; // Compute the transform used for rendering the sphere rp3d::decimal matrix[16]; diff --git a/testbed/common/Sphere.cpp b/testbed/common/Sphere.cpp index 280ddd73..3fd64a98 100644 --- a/testbed/common/Sphere.cpp +++ b/testbed/common/Sphere.cpp @@ -172,6 +172,7 @@ void Sphere::updateTransform(float interpolationFactor) { rp3d::Transform interpolatedTransform = rp3d::Transform::interpolateTransforms(mPreviousTransform, transform, interpolationFactor); + mPreviousTransform = transform; // Compute the transform used for rendering the sphere rp3d::decimal matrix[16]; diff --git a/testbed/src/Scene.h b/testbed/src/Scene.h index 501aa970..e37a9e20 100644 --- a/testbed/src/Scene.h +++ b/testbed/src/Scene.h @@ -37,6 +37,11 @@ struct EngineSettings { float elapsedTime; // Elapsed time (in seconds) float timeStep; // Current time step (in seconds) + + /// Constructor + EngineSettings() : elapsedTime(0.0f), timeStep(0.0f) { + + } }; // Class Scene diff --git a/testbed/src/TestbedApplication.cpp b/testbed/src/TestbedApplication.cpp index a4ca82f8..914a28a8 100644 --- a/testbed/src/TestbedApplication.cpp +++ b/testbed/src/TestbedApplication.cpp @@ -50,8 +50,10 @@ TestbedApplication& TestbedApplication::getInstance() { } // Constructor -TestbedApplication::TestbedApplication() : mFPS(0), mNbFrames(0), mPreviousTime(0) { +TestbedApplication::TestbedApplication() : mFPS(0), mNbFrames(0), mPreviousTime(0){ + mCurrentScene = NULL; + mEngineSettings.timeStep = DEFAULT_TIMESTEP; mIsMultisamplingActive = true; mWidth = 1000; mHeight = 800; @@ -174,22 +176,26 @@ void TestbedApplication::updatePhysics() { mTimer.update(); // While the time accumulator is not empty - while(mTimer.isPossibleToTakeStep()) { + while(mTimer.isPossibleToTakeStep(mEngineSettings.timeStep)) { // Take a physics simulation step mCurrentScene->updatePhysics(); // Update the timer - mTimer.nextStep(); + mTimer.nextStep(mEngineSettings.timeStep); } } } void TestbedApplication::update() { + // Update the physics + updatePhysics(); + // Compute the interpolation factor float factor = mTimer.computeInterpolationFactor(mEngineSettings.timeStep); assert(factor >= 0.0f && factor <= 1.0f); + std::cout << "Factor : " << factor << std::endl; // Notify the scene about the interpolation factor mCurrentScene->setInterpolationFactor(factor); diff --git a/testbed/src/TestbedApplication.h b/testbed/src/TestbedApplication.h index e3c5121a..f928f21e 100644 --- a/testbed/src/TestbedApplication.h +++ b/testbed/src/TestbedApplication.h @@ -33,6 +33,9 @@ #include "Timer.h" #include +// Constants +const float DEFAULT_TIMESTEP = 1.0f / 60.0f; + /// Class TestbedApplication /// Singleton class representing the application. class TestbedApplication { diff --git a/testbed/src/Timer.h b/testbed/src/Timer.h index f551ec1f..0a75d010 100644 --- a/testbed/src/Timer.h +++ b/testbed/src/Timer.h @@ -52,9 +52,6 @@ class Timer { // -------------------- Attributes -------------------- // - /// Timestep dt of the physics engine (timestep > 0.0) - double mTimeStep; - /// Last time the timer has been updated long double mLastUpdateTime; @@ -98,13 +95,13 @@ class Timer { bool isRunning() const; /// True if it's possible to take a new step - bool isPossibleToTakeStep() const; + bool isPossibleToTakeStep(float timeStep) const; /// Compute the time since the last update() call and add it to the accumulator void update(); /// Take a new step => update the timer by adding the timeStep value to the current time - void nextStep(); + void nextStep(float timeStep); /// Compute the interpolation factor float computeInterpolationFactor(float timeStep); @@ -141,16 +138,16 @@ inline void Timer::stop() { } // True if it's possible to take a new step -inline bool Timer::isPossibleToTakeStep() const { - return (mAccumulator >= mTimeStep); +inline bool Timer::isPossibleToTakeStep(float timeStep) const { + return (mAccumulator >= timeStep); } // Take a new step => update the timer by adding the timeStep value to the current time -inline void Timer::nextStep() { +inline void Timer::nextStep(float timeStep) { assert(mIsRunning); // Update the accumulator value - mAccumulator -= mTimeStep; + mAccumulator -= timeStep; } // Compute the interpolation factor From f7f74873041e8b0128967cb49edc7f1a88c068a0 Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Tue, 28 Apr 2015 23:47:29 +0200 Subject: [PATCH 08/36] Start using the imgui graphical user interface --- testbed/CMakeLists.txt | 14 +- testbed/imgui/LICENSE | 21 + testbed/imgui/imconfig.h | 58 + testbed/imgui/imgui.cpp | 11499 +++++++++++++++++++++++++++ testbed/imgui/imgui.h | 1048 +++ testbed/imgui/stb_rect_pack.h | 547 ++ testbed/imgui/stb_textedit.h | 1254 +++ testbed/imgui/stb_truetype.h | 2658 +++++++ testbed/src/Gui.cpp | 357 +- testbed/src/Gui.h | 45 +- testbed/src/TestbedApplication.cpp | 8 +- testbed/src/TestbedApplication.h | 3 - 12 files changed, 17499 insertions(+), 13 deletions(-) create mode 100644 testbed/imgui/LICENSE create mode 100644 testbed/imgui/imconfig.h create mode 100644 testbed/imgui/imgui.cpp create mode 100644 testbed/imgui/imgui.h create mode 100644 testbed/imgui/stb_rect_pack.h create mode 100644 testbed/imgui/stb_textedit.h create mode 100644 testbed/imgui/stb_truetype.h diff --git a/testbed/CMakeLists.txt b/testbed/CMakeLists.txt index 9a488e1a..dd6faefc 100644 --- a/testbed/CMakeLists.txt +++ b/testbed/CMakeLists.txt @@ -20,7 +20,7 @@ FILE(COPY "shaders/" DESTINATION "${EXECUTABLE_OUTPUT_PATH}/shaders/") FILE(COPY "meshes/" DESTINATION "${EXECUTABLE_OUTPUT_PATH}/meshes/") # Headers -INCLUDE_DIRECTORIES("src/" "opengl-framework/src/" "glfw/include/" "common/" "scenes/") +INCLUDE_DIRECTORIES("src/" "opengl-framework/src/" "glfw/include/" "common/" "scenes/" "imgui/") # Testbed source files SET(TESTBED_SOURCES @@ -35,6 +35,16 @@ SET(TESTBED_SOURCES src/Timer.cpp ) +# IMGUI source files +SET(IMGUI_SOURCES + imgui/imgui.h + imgui/imgui.cpp + imgui/imconfig.h + imgui/stb_rect_pack.h + imgui/stb_textedit.h + imgui/stb_truetype.h +) + # Common source files SET(COMMON_SOURCES common/Box.h @@ -70,7 +80,7 @@ SET(SCENES_SOURCES ) # Create the executable -ADD_EXECUTABLE(testbed ${TESTBED_SOURCES} ${SCENES_SOURCES} ${COMMON_SOURCES}) +ADD_EXECUTABLE(testbed ${TESTBED_SOURCES} ${SCENES_SOURCES} ${COMMON_SOURCES} ${IMGUI_SOURCES}) # Link with libraries TARGET_LINK_LIBRARIES(testbed reactphysics3d openglframework glfw ${GLFW_LIBRARIES}) diff --git a/testbed/imgui/LICENSE b/testbed/imgui/LICENSE new file mode 100644 index 00000000..b28ef225 --- /dev/null +++ b/testbed/imgui/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014-2015 Omar Cornut and ImGui contributors + +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: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +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. diff --git a/testbed/imgui/imconfig.h b/testbed/imgui/imconfig.h new file mode 100644 index 00000000..24d61148 --- /dev/null +++ b/testbed/imgui/imconfig.h @@ -0,0 +1,58 @@ +//----------------------------------------------------------------------------- +// USER IMPLEMENTATION +// This file contains compile-time options for ImGui. +// Other options (memory allocation overrides, callbacks, etc.) can be set at runtime via the ImGuiIO structure - ImGui::GetIO(). +//----------------------------------------------------------------------------- + +#pragma once + +//---- Define your own ImVector<> type if you don't want to use the provided implementation defined in imgui.h +//#include +//#define ImVector std::vector +//#define ImVector MyVector + +//---- Define assertion handler. Defaults to calling assert(). +//#define IM_ASSERT(_EXPR) MyAssert(_EXPR) + +//---- Define attributes of all API symbols declarations, e.g. for DLL under Windows. +//#define IMGUI_API __declspec( dllexport ) +//#define IMGUI_API __declspec( dllimport ) + +//---- Include imgui_user.inl at the end of imgui.cpp so you can include code that extends ImGui using its private data/functions. +//#define IMGUI_INCLUDE_IMGUI_USER_INL + +//---- Include imgui_user.h at the end of imgui.h +//#define IMGUI_INCLUDE_IMGUI_USER_H + +//---- Don't implement default handlers for Windows (so as not to link with OpenClipboard() and others Win32 functions) +//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS +//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS + +//---- Don't implement help and test window functionality (ShowUserGuide()/ShowStyleEditor()/ShowTestWindow() methods will be empty) +//#define IMGUI_DISABLE_TEST_WINDOWS + +//---- Implement STB libraries in a namespace to avoid conflicts +//#define IMGUI_STB_NAMESPACE ImStb + +//---- Define constructor and implicit cast operators to convert back<>forth from your math types and ImVec2/ImVec4. +/* +#define IM_VEC2_CLASS_EXTRA \ + ImVec2(const MyVec2& f) { x = f.x; y = f.y; } \ + operator MyVec2() const { return MyVec2(x,y); } + +#define IM_VEC4_CLASS_EXTRA \ + ImVec4(const MyVec4& f) { x = f.x; y = f.y; z = f.z; w = f.w; } \ + operator MyVec4() const { return MyVec4(x,y,z,w); } +*/ + +//---- Freely implement extra functions within the ImGui:: namespace. +//---- Declare helpers or widgets implemented in imgui_user.inl or elsewhere, so end-user doesn't need to include multiple files. +//---- e.g. you can create variants of the ImGui::Value() helper for your low-level math types, or your own widgets/helpers. +/* +namespace ImGui +{ + void Value(const char* prefix, const MyVec2& v, const char* float_format = NULL); + void Value(const char* prefix, const MyVec4& v, const char* float_format = NULL); +} +*/ + diff --git a/testbed/imgui/imgui.cpp b/testbed/imgui/imgui.cpp new file mode 100644 index 00000000..a0f0fe4a --- /dev/null +++ b/testbed/imgui/imgui.cpp @@ -0,0 +1,11499 @@ +// ImGui library v1.39 WIP +// See ImGui::ShowTestWindow() for sample code. +// Read 'Programmer guide' below for notes on how to setup ImGui in your codebase. +// Get latest version at https://github.com/ocornut/imgui +// Developed by Omar Cornut and ImGui contributors. + +/* + + Index + - MISSION STATEMENT + - END-USER GUIDE + - PROGRAMMER GUIDE (read me!) + - API BREAKING CHANGES (read me when you update!) + - FREQUENTLY ASKED QUESTIONS (FAQ), TIPS + - Can I have multiple widgets with the same label? (Yes) + - How do I update to a newer version of ImGui? + - Why is my text output blurry? + - How can I load a different font than the default? + - How can I load multiple fonts? + - How can I display and input Chinese, Japanese, Korean characters? + - ISSUES & TODO-LIST + - CODE + - SAMPLE CODE + - FONT DATA + + + MISSION STATEMENT + ================= + + - easy to use to create code-driven and data-driven tools + - easy to use to create ad hoc short-lived tools and long-lived, more elaborate tools + - easy to hack and improve + - minimize screen real-estate usage + - minimize setup and maintenance + - minimize state storage on user side + - portable, minimize dependencies, run on target (consoles, phones, etc.) + - efficient runtime (NB- we do allocate when "growing" content - creating a window / opening a tree node for the first time, etc. - but a typical frame won't allocate anything) + - read about immediate-mode gui principles @ http://mollyrocket.com/861, http://mollyrocket.com/forums/index.html + + Designed for developers and content-creators, not the typical end-user! Some of the weaknesses includes: + - doesn't look fancy, doesn't animate + - limited layout features, intricate layouts are typically crafted in code + - occasionally uses statically sized buffers for string manipulations - won't crash, but some very long pieces of text may be clipped. functions like ImGui::TextUnformatted() don't have such restriction. + + + END-USER GUIDE + ============== + + - double-click title bar to collapse window + - click upper right corner to close a window, available when 'bool* p_opened' is passed to ImGui::Begin() + - click and drag on lower right corner to resize window + - click and drag on any empty space to move window + - double-click/double-tap on lower right corner grip to auto-fit to content + - TAB/SHIFT+TAB to cycle through keyboard editable fields + - use mouse wheel to scroll + - use CTRL+mouse wheel to zoom window contents (if IO.FontAllowScaling is true) + - CTRL+Click on a slider to input value as text + - text editor: + - Hold SHIFT or use mouse to select text. + - CTRL+Left/Right to word jump + - CTRL+Shift+Left/Right to select words + - CTRL+A our Double-Click to select all + - CTRL+X,CTRL+C,CTRL+V to use OS clipboard + - CTRL+Z,CTRL+Y to undo/redo + - ESCAPE to revert text to its original value + - You can apply arithmetic operators +,*,/ on numerical values. Use +- to subtract (because - would set a negative value!) + + + PROGRAMMER GUIDE + ================ + + - read the FAQ below this section! + - your code creates the UI, if your code doesn't run the UI is gone! == very dynamic UI, no construction/destructions steps, less data retention on your side, no state duplication, less sync, less bugs. + - call and read ImGui::ShowTestWindow() for sample code demonstrating most features. + - see examples/ folder for standalone sample applications. e.g. examples/opengl_example/ + - customization: PushStyleColor()/PushStyleVar() or the style editor to tweak the look of the interface (e.g. if you want a more compact UI or a different color scheme). + + - getting started: + - initialisation: call ImGui::GetIO() to retrieve the ImGuiIO structure and fill the 'Settings' data. + - every frame: + 1/ in your mainloop or right after you got your keyboard/mouse info, call ImGui::GetIO() and fill the 'Input' data, then call ImGui::NewFrame(). + 2/ use any ImGui function you want between NewFrame() and Render() + 3/ ImGui::Render() to render all the accumulated command-lists. it will call your RenderDrawListFn handler that you set in the IO structure. + - all rendering information are stored into command-lists until ImGui::Render() is called. + - ImGui never touches or know about your GPU state. the only function that knows about GPU is the RenderDrawListFn handler that you must provide. + - effectively it means you can create widgets at any time in your code, regardless of "update" vs "render" considerations. + - refer to the examples applications in the examples/ folder for instruction on how to setup your code. + - a typical application skeleton may be: + + // Application init + ImGuiIO& io = ImGui::GetIO(); + io.DisplaySize.x = 1920.0f; + io.DisplaySize.y = 1280.0f; + io.DeltaTime = 1.0f/60.0f; + io.IniFilename = "imgui.ini"; + // TODO: Fill others settings of the io structure + + // Load texture + unsigned char* pixels; + int width, height, bytes_per_pixels; + io.Fonts->GetTexDataAsRGBA32(pixels, &width, &height, &bytes_per_pixels); + // TODO: copy texture to graphics memory. + // TODO: store your texture pointer/identifier in 'io.Fonts->TexID' + + // Application main loop + while (true) + { + // 1) get low-level input + // e.g. on Win32, GetKeyboardState(), or poll your events, etc. + + // 2) TODO: fill all fields of IO structure and call NewFrame + ImGuiIO& io = ImGui::GetIO(); + io.MousePos = mouse_pos; + io.MouseDown[0] = mouse_button_0; + io.KeysDown[i] = ... + ImGui::NewFrame(); + + // 3) most of your application code here - you can use any of ImGui::* functions at any point in the frame + ImGui::Begin("My window"); + ImGui::Text("Hello, world."); + ImGui::End(); + GameUpdate(); + GameRender(); + + // 4) render & swap video buffers + ImGui::Render(); + // swap video buffer, etc. + } + + - after calling ImGui::NewFrame() you can read back 'io.WantCaptureMouse' and 'io.WantCaptureKeyboard' to tell if ImGui + wants to use your inputs. if it does you can discard/hide the inputs from the rest of your application. + + API BREAKING CHANGES + ==================== + + Occasionally introducing changes that are breaking the API. The breakage are generally minor and easy to fix. + Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. + + - 2015/04/13 (1.38) - renamed IsClipped() to IsRectClipped(). Kept inline redirection function (will obsolete). + - 2015/04/09 (1.38) - renamed ImDrawList::AddArc() to ImDrawList::AddArcFast() for compatibility with future API + - 2015/04/03 (1.38) - removed ImGuiCol_CheckHovered, ImGuiCol_CheckActive, replaced with the more general ImGuiCol_FrameBgHovered, ImGuiCol_FrameBgActive. + - 2014/04/03 (1.38) - removed support for passing -FLT_MAX..+FLT_MAX as the range for a SliderFloat(). Use DragFloat() or Inputfloat() instead. + - 2015/03/17 (1.36) - renamed GetItemRectMin()/GetItemRectMax()/IsMouseHoveringBox() to GetItemRectMin()/GetItemRectMax()/IsMouseHoveringRect(). Kept inline redirection function (will obsolete). + - 2015/03/15 (1.36) - renamed style.TreeNodeSpacing to style.IndentSpacing, ImGuiStyleVar_TreeNodeSpacing to ImGuiStyleVar_IndentSpacing + - 2015/03/13 (1.36) - renamed GetWindowIsFocused() to IsWindowFocused(). Kept inline redirection function (will obsolete). + - 2015/03/08 (1.35) - renamed style.ScrollBarWidth to style.ScrollbarWidth + - 2015/02/27 (1.34) - renamed OpenNextNode(bool) to SetNextTreeNodeOpened(bool, ImGuiSetCond). Kept inline redirection function (will obsolete). + - 2015/02/27 (1.34) - renamed ImGuiSetCondition_*** to ImGuiSetCond_***, and _FirstUseThisSession becomes _Once. + - 2015/02/11 (1.32) - changed text input callback ImGuiTextEditCallback return type from void-->int. reserved for future use, return 0 for now. + - 2015/02/10 (1.32) - renamed GetItemWidth() to CalcItemWidth() to clarify its evolving behavior + - 2015/02/08 (1.31) - renamed GetTextLineSpacing() to GetTextLineHeightWithSpacing() + - 2015/02/01 (1.31) - removed IO.MemReallocFn (unused) + - 2015/01/19 (1.30) - renamed ImGuiStorage::GetIntPtr()/GetFloatPtr() to GetIntRef()/GetIntRef() because Ptr was conflicting with actual pointer storage functions. + - 2015/01/11 (1.30) - big font/image API change! now loads TTF file. allow for multiple fonts. no need for a PNG loader. + (1.30) - removed GetDefaultFontData(). uses io.Fonts->GetTextureData*() API to retrieve uncompressed pixels. + this sequence: + const void* png_data; + unsigned int png_size; + ImGui::GetDefaultFontData(NULL, NULL, &png_data, &png_size); + // + became: + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); + // + io.Fonts->TexID = (your_texture_identifier); + you now have much more flexibility to load multiple TTF fonts and manage the texture buffer for internal needs. + it is now recommended your sample the font texture with bilinear interpolation. + (1.30) - added texture identifier in ImDrawCmd passed to your render function (we can now render images). make sure to set io.Fonts->TexID. + (1.30) - removed IO.PixelCenterOffset (unnecessary, can be handled in user projection matrix) + (1.30) - removed ImGui::IsItemFocused() in favor of ImGui::IsItemActive() which handles all widgets + - 2014/12/10 (1.18) - removed SetNewWindowDefaultPos() in favor of new generic API SetNextWindowPos(pos, ImGuiSetCondition_FirstUseEver) + - 2014/11/28 (1.17) - moved IO.Font*** options to inside the IO.Font-> structure (FontYOffset, FontTexUvForWhite, FontBaseScale, FontFallbackGlyph) + - 2014/11/26 (1.17) - reworked syntax of IMGUI_ONCE_UPON_A_FRAME helper macro to increase compiler compatibility + - 2014/11/07 (1.15) - renamed IsHovered() to IsItemHovered() + - 2014/10/02 (1.14) - renamed IMGUI_INCLUDE_IMGUI_USER_CPP to IMGUI_INCLUDE_IMGUI_USER_INL and imgui_user.cpp to imgui_user.inl (more IDE friendly) + - 2014/09/25 (1.13) - removed 'text_end' parameter from IO.SetClipboardTextFn (the string is now always zero-terminated for simplicity) + - 2014/09/24 (1.12) - renamed SetFontScale() to SetWindowFontScale() + - 2014/09/24 (1.12) - moved IM_MALLOC/IM_REALLOC/IM_FREE preprocessor defines to IO.MemAllocFn/IO.MemReallocFn/IO.MemFreeFn + - 2014/08/30 (1.09) - removed IO.FontHeight (now computed automatically) + - 2014/08/30 (1.09) - moved IMGUI_FONT_TEX_UV_FOR_WHITE preprocessor define to IO.FontTexUvForWhite + - 2014/08/28 (1.09) - changed the behavior of IO.PixelCenterOffset following various rendering fixes + + + FREQUENTLY ASKED QUESTIONS (FAQ), TIPS + ====================================== + + Q: Can I have multiple widgets with the same label? + A: Yes. A primer on the use of labels/IDs in ImGui.. + + - Interactive widgets require state to be carried over multiple frames (most typically ImGui often needs to remember what is the "active" widget). + to do so they need an unique ID. unique ID are typically derived from a string label, an integer index or a pointer. + + Button("OK"); // Label = "OK", ID = hash of "OK" + Button("Cancel"); // Label = "Cancel", ID = hash of "Cancel" + + - Elements that are not clickable, such as Text() items don't need an ID. + + - ID are uniquely scoped within windows, tree nodes, etc. so no conflict can happen if you have two buttons called "OK" in two different windows + or in two different locations of a tree. + + - if you have a same ID twice in the same location, you'll have a conflict: + + Button("OK"); + Button("OK"); // ID collision! Both buttons will be treated as the same. + + Fear not! this is easy to solve and there are many ways to solve it! + + - when passing a label you can optionally specify extra unique ID information within string itself. This helps solving the simpler collision cases. + use "##" to pass a complement to the ID that won't be visible to the end-user: + + Button("Play##0"); // Label = "Play", ID = hash of "Play##0" + Button("Play##1"); // Label = "Play", ID = hash of "Play##1" (different from above) + + - occasionally (rarely) you might want change a label while preserving a constant ID. This allows you to animate labels. + use "###" to pass a label that isn't part of ID: + + Button("Hello###ID"; // Label = "Hello", ID = hash of "ID" + Button("World###ID"; // Label = "World", ID = hash of "ID" (same as above) + + - use PushID() / PopID() to create scopes and avoid ID conflicts within the same Window. + this is the most convenient way of distinguish ID if you are iterating and creating many UI elements. + you can push a pointer, a string or an integer value. remember that ID are formed from the addition of everything in the ID stack! + + for (int i = 0; i < 100; i++) + { + PushID(i); + Button("Click"); // Label = "Click", ID = hash of integer + "label" (unique) + PopID(); + } + + for (int i = 0; i < 100; i++) + { + MyObject* obj = Objects[i]; + PushID(obj); + Button("Click"); // Label = "Click", ID = hash of pointer + "label" (unique) + PopID(); + } + + for (int i = 0; i < 100; i++) + { + MyObject* obj = Objects[i]; + PushID(obj->Name); + Button("Click"); // Label = "Click", ID = hash of string + "label" (unique) + PopID(); + } + + - more example showing that you can stack multiple prefixes into the ID stack: + + Button("Click"); // Label = "Click", ID = hash of "Click" + PushID("node"); + Button("Click"); // Label = "Click", ID = hash of "node" + "Click" + PushID(my_ptr); + Button("Click"); // Label = "Click", ID = hash of "node" + ptr + "Click" + PopID(); + PopID(); + + - tree nodes implicitly creates a scope for you by calling PushID(). + + Button("Click"); // Label = "Click", ID = hash of "Click" + if (TreeNode("node")) + { + Button("Click"); // Label = "Click", ID = hash of "node" + "Click" + TreePop(); + } + + - when working with trees, ID are used to preserve the opened/closed state of each tree node. + depending on your use cases you may want to use strings, indices or pointers as ID. + e.g. when displaying a single object that may change over time (1-1 relationship), using a static string as ID will preserve your node open/closed state when the targeted object change. + e.g. when displaying a list of objects, using indices or pointers as ID will preserve the node open/closed state differently. experiment and see what makes more sense! + + Q: How do I update to a newer version of ImGui? + A: Overwrite the following files: + imgui.cpp + imgui.h + stb_rect_pack.h + stb_textedit.h + stb_truetype.h + Check the "API BREAKING CHANGES" sections for a list of occasional API breaking changes. + + Q: Why is my text output blurry? + A: In your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) + + Q: How can I load a different font than the default? (default is an embedded version of ProggyClean.ttf, rendered at size 13) + A: Use the font atlas to load the TTF file you want: + + io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels); + io.Fonts->GetTexDataAsRGBA32() or GetTexDataAsAlpha8() + + Q: How can I load multiple fonts? + A: Use the font atlas to pack them into a single texture: + + ImFont* font0 = io.Fonts->AddFontDefault(); + ImFont* font1 = io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels); + ImFont* font2 = io.Fonts->AddFontFromFileTTF("myfontfile2.ttf", size_in_pixels); + io.Fonts->GetTexDataAsRGBA32() or GetTexDataAsAlpha8() + // the first loaded font gets used by default + // use ImGui::PushFont()/ImGui::PopFont() to change the font at runtime + + Q: How can I render and input Chinese, Japanese, Korean characters? + A: When loading a font, pass custom Unicode ranges to specify the glyphs to load. ImGui will support UTF-8 encoding across the board. + Character input depends on you passing the right character code to io.AddInputCharacter(). The example applications do that. + + io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels, io.Fonts->GetGlyphRangesJapanese()); // Load Japanese characters + io.Fonts->GetTexDataAsRGBA32() or GetTexDataAsAlpha8() + io.ImeWindowHandle = MY_HWND; // To input using Microsoft IME, give ImGui the hwnd of your application + + - tip: the construct 'IMGUI_ONCE_UPON_A_FRAME { ... }' will run the block of code only once a frame. You can use it to quickly add custom UI in the middle of a deep nested inner loop in your code. + - tip: you can create widgets without a Begin()/End() block, they will go in an implicit window called "Debug" + - tip: you can call Begin() multiple times with the same name during the same frame, it will keep appending to the same window. + - tip: you can call Render() multiple times (e.g for VR renders). + - tip: call and read the ShowTestWindow() code for more example of how to use ImGui! + + + ISSUES & TODO-LIST + ================== + + - misc: merge or clarify ImVec4 vs ImRect? + - window: add horizontal scroll + - window: fix resize grip rendering scaling along with Rounding style setting + - window: autofit feedback loop when user relies on any dynamic layout (window width multiplier, column). maybe just clearly drop manual autofit? + - window: add a way for very transient windows (non-saved, temporary overlay over hundreds of objects) to "clean" up from the global window list. + - window: allow resizing of child windows (possibly given min/max for each axis?) + - window: background options for child windows, border option (disable rounding) + - window: resizing from any sides? + mouse cursor directives for app. + - widgets: display mode: widget-label, label-widget (aligned on column or using fixed size), label-newline-tab-widget etc. + - widgets: clean up widgets internal toward exposing everything. + - main: considering adding EndFrame()/Init(). some constructs are awkward in the implementation because of the lack of them. + - main: IsItemHovered() make it more consistent for various type of widgets, widgets with multiple components, etc. also effectively IsHovered() region sometimes differs from hot region, e.g tree nodes + - main: IsItemHovered() info stored in a stack? so that 'if TreeNode() { Text; TreePop; } if IsHovered' return the hover state of the TreeNode? +!- input number: large int not reliably supported because of int<>float conversions. + - input number: optional range min/max for Input*() functions + - input number: holding [-]/[+] buttons could increase the step speed non-linearly (or user-controlled) + - input number: use mouse wheel to step up/down + - input number: non-decimal input. + - text: proper alignment options + - layout: horizontal layout helper (github issue #97) + - layout: more generic alignment state (left/right/centered) for single items? + - layout: clean up the InputFloatN/SliderFloatN/ColorEdit4 layout code. item width should include frame padding. + - columns: separator function or parameter that works within the column (currently Separator() bypass all columns) (github issue #125) + - columns: declare column set (each column: fixed size, %, fill, distribute default size among fills) (github issue #125) + - columns: columns header to act as button (~sort op) and allow resize/reorder (github issue #125) + - columns: user specify columns size (github issue #125) + - popup: border options. richer api like BeginChild() perhaps? (github issue #197) + - combo: turn child handling code into pop up helper + - combo: contents should extends to fit label if combo widget is small + - listbox: multiple selection + - listbox: user may want to initial scroll to focus on the one selected value? + ! menubar, menus (github issue #126) + - tabs + - gauge: various forms of gauge/loading bars widgets + - color: better color editor. + - plot: make it easier for user to draw extra stuff into the graph (e.g: draw basis, highlight certain points, 2d plots, multiple plots) + - plot: "smooth" automatic scale over time, user give an input 0.0(full user scale) 1.0(full derived from value) + - plot: add a helper e.g. Plot(char* label, float value, float time_span=2.0f) that stores values and Plot them for you - probably another function name. and/or automatically allow to plot ANY displayed value (more reliance on stable ID) + - file selection widget -> build the tool in our codebase to improve model-dialog idioms + - slider: allow using the [-]/[+] buttons used by InputFloat()/InputInt() + - slider: initial absolute click is imprecise. change to relative movement slider (same as scrollbar). + - slider: add dragging-based widgets to edit values with mouse (on 2 axises), saving screen real-estate. + - text edit: clean up the mess caused by converting UTF-8 <> wchar. the code is rather inefficient right now. + - text edit: centered text for slider as input text so it matches typical positioning. + - text edit: flag to disable live update of the user buffer. + - text edit: field resize behavior - field could stretch when being edited? hover tooltip shows more text? + - text edit: add multi-line text edit + - tree: add treenode/treepush int variants? because (void*) cast from int warns on some platforms/settings + - settings: write more decent code to allow saving/loading new fields + - settings: api for per-tool simple persistent data (bool,int,float,columns sizes,etc.) in .ini file + ! style: store rounded corners in texture to use 1 quad per corner (filled and wireframe). so rounding have minor cost. + - style: checkbox: padding for "active" color should be a multiplier of the + - style: colorbox not always square? + - text: simple markup language for color change? + - log: LogButtons() options for specifying depth and/or hiding depth slider + - log: have more control over the log scope (e.g. stop logging when leaving current tree node scope) + - log: be able to log anything (e.g. right-click on a window/tree-node, shows context menu? log into tty/file/clipboard) + - log: let user copy any window content to clipboard easily (CTRL+C on windows? while moving it? context menu?). code is commented because it fails with multiple Begin/End pairs. + - filters: set a current filter that tree node can automatically query to hide themselves + - filters: handle wildcards (with implicit leading/trailing *), regexps + - shortcuts: add a shortcut api, e.g. parse "&Save" and/or "Save (CTRL+S)", pass in to widgets or provide simple ways to use (button=activate, input=focus) + ! keyboard: tooltip & combo boxes are messing up / not honoring keyboard tabbing + - keyboard: full keyboard navigation and focus. + - input: rework IO to be able to pass actual events to fix temporal aliasing issues. + - input: support track pad style scrolling & slider edit. + - tooltip: move to fit within screen (e.g. when mouse cursor is right of the screen). + - portability: big-endian test/support (github issue #81) + - misc: mark printf compiler attributes on relevant functions + - misc: provide a way to compile out the entire implementation while providing a dummy API (e.g. #define IMGUI_DUMMY_IMPL) + - misc: double-clicking on title bar to minimize isn't consistent, perhaps move to single-click on left-most collapse icon? + - style editor: have a more global HSV setter (e.g. alter hue on all elements). consider replacing active/hovered by offset in HSV space? + - style editor: color child window height expressed in multiple of line height. + - optimization/render: use indexed rendering to reduce vertex data cost (e.g. for remote/networked imgui) + - optimization/render: merge command-lists with same clip-rect into one even if they aren't sequential? (as long as in-between clip rectangle don't overlap)? + - optimization: turn some the various stack vectors into statically-sized arrays + - optimization: better clipping for multi-component widgets +*/ + +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include "imgui.h" +#include // toupper, isprint +#include // sqrtf, fabsf, fmodf, powf, cosf, sinf, floorf, ceilf +#include // intptr_t +#include // vsnprintf, sscanf +#include // new (ptr) + +#ifdef _MSC_VER +#pragma warning (disable: 4505) // unreferenced local function has been removed (stb stuff) +#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen +#endif + +// Clang warnings with -Weverything +#ifdef __clang__ +#pragma clang diagnostic ignored "-Wold-style-cast" // warning : use of old-style cast // yes, they are more terse. +#pragma clang diagnostic ignored "-Wfloat-equal" // warning : comparing floating point with == or != is unsafe // storing and comparing against same constants ok. +#pragma clang diagnostic ignored "-Wformat-nonliteral" // warning : format string is not a string literal // passing non-literal to vsnformat(). yes, user passing incorrect format strings can crash the code. +#pragma clang diagnostic ignored "-Wexit-time-destructors" // warning : declaration requires an exit-time destructor // exit-time destruction order is undefined. if MemFree() leads to users code that has been disabled before exit it might cause problems. ImGui coding style welcomes static/globals. +#pragma clang diagnostic ignored "-Wglobal-constructors" // warning : declaration requires a global destructor // similar to above, not sure what the exact difference it. +#pragma clang diagnostic ignored "-Wsign-conversion" // warning : implicit conversion changes signedness // +#pragma clang diagnostic ignored "-Wmissing-noreturn" // warning : function xx could be declared with attribute 'noreturn' warning // GetDefaultFontData() asserts which some implementation makes it never return. +#endif +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used +#endif + +//------------------------------------------------------------------------- +// STB libraries implementation +//------------------------------------------------------------------------- + +struct ImGuiTextEditState; + +//#define IMGUI_STB_NAMESPACE ImStb +//#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION +//#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION + +#ifdef IMGUI_STB_NAMESPACE +namespace IMGUI_STB_NAMESPACE +{ +#endif + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunused-function" +#pragma clang diagnostic ignored "-Wmissing-prototypes" +#endif + +#define STBRP_ASSERT(x) IM_ASSERT(x) +#ifndef IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION +#define STBRP_STATIC +#define STB_RECT_PACK_IMPLEMENTATION +#endif +#include "stb_rect_pack.h" + +#define STBTT_malloc(x,u) ((void)(u), ImGui::MemAlloc(x)) +#define STBTT_free(x,u) ((void)(u), ImGui::MemFree(x)) +#define STBTT_assert(x) IM_ASSERT(x) +#ifndef IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION +#define STBTT_STATIC +#define STB_TRUETYPE_IMPLEMENTATION +#endif +#include "stb_truetype.h" + +#undef STB_TEXTEDIT_STRING +#undef STB_TEXTEDIT_CHARTYPE +#define STB_TEXTEDIT_STRING ImGuiTextEditState +#define STB_TEXTEDIT_CHARTYPE ImWchar +#include "stb_textedit.h" + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +#ifdef IMGUI_STB_NAMESPACE +} // namespace ImStb +using namespace IMGUI_STB_NAMESPACE; +#endif + +//------------------------------------------------------------------------- +// Forward Declarations +//------------------------------------------------------------------------- + +struct ImRect; +struct ImGuiColMod; +struct ImGuiStyleMod; +struct ImGuiDrawContext; +struct ImGuiTextEditState; +struct ImGuiIniData; +struct ImGuiState; +struct ImGuiWindow; + +static bool ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, bool allow_key_modifiers, bool repeat = false, bool pressed_on_click = false); +static void LogText(const ImVec2& ref_pos, const char* text, const char* text_end = NULL); + +static void RenderText(ImVec2 pos, const char* text, const char* text_end = NULL, bool hide_text_after_hash = true); +static void RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width); +static void RenderTextClipped(ImVec2 pos, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& clip_max); +static void RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border = true, float rounding = 0.0f); +static void RenderCollapseTriangle(ImVec2 p_min, bool opened, float scale = 1.0f, bool shadow = false); + +static void SetFont(ImFont* font); +static bool ItemAdd(const ImRect& bb, const ImGuiID* id); +static void ItemSize(ImVec2 size, float text_offset_y = 0.0f); +static void ItemSize(const ImRect& bb, float text_offset_y = 0.0f); +static void PushColumnClipRect(int column_index = -1); +static bool IsClippedEx(const ImRect& bb, const ImGuiID* id, bool clip_even_when_logged); + +static bool IsMouseHoveringRect(const ImRect& bb); +static bool IsKeyPressedMap(ImGuiKey key, bool repeat = true); + +static void Scrollbar(ImGuiWindow* window); +static bool CloseWindowButton(bool* p_opened = NULL); +static void FocusWindow(ImGuiWindow* window); +static ImGuiWindow* FindHoveredWindow(ImVec2 pos, bool excluding_childs); + +// Helpers: String +static int ImStricmp(const char* str1, const char* str2); +static int ImStrnicmp(const char* str1, const char* str2, int count); +static char* ImStrdup(const char *str); +static size_t ImStrlenW(const ImWchar* str); +static const char* ImStristr(const char* haystack, const char* needle, const char* needle_end); +static size_t ImFormatString(char* buf, size_t buf_size, const char* fmt, ...); +static size_t ImFormatStringV(char* buf, size_t buf_size, const char* fmt, va_list args); + +// Helpers: Misc +static ImU32 ImHash(const void* data, size_t data_size, ImU32 seed); +static bool ImLoadFileToMemory(const char* filename, const char* file_open_mode, void** out_file_data, size_t* out_file_size, size_t padding_bytes = 0); +static inline int ImUpperPowerOfTwo(int v) { v--; v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; v++; return v; } +static inline bool ImCharIsSpace(int c) { return c == ' ' || c == '\t' || c == 0x3000; } + +// Helpers: UTF-8 <> wchar +static int ImTextCharToUtf8(char* buf, size_t buf_size, unsigned int in_char); // return output UTF-8 bytes count +static ptrdiff_t ImTextStrToUtf8(char* buf, size_t buf_size, const ImWchar* in_text, const ImWchar* in_text_end); // return output UTF-8 bytes count +static int ImTextCharFromUtf8(unsigned int* out_char, const char* in_text, const char* in_text_end); // return input UTF-8 bytes count +static ptrdiff_t ImTextStrFromUtf8(ImWchar* buf, size_t buf_size, const char* in_text, const char* in_text_end, const char** in_remaining = NULL); // return input UTF-8 bytes count +static int ImTextCountCharsFromUtf8(const char* in_text, const char* in_text_end); // return number of UTF-8 code-points (NOT bytes count) +static int ImTextCountUtf8BytesFromStr(const ImWchar* in_text, const ImWchar* in_text_end); // return number of bytes to express string as UTF-8 code-points + +//----------------------------------------------------------------------------- +// Platform dependent default implementations +//----------------------------------------------------------------------------- + +static const char* GetClipboardTextFn_DefaultImpl(); +static void SetClipboardTextFn_DefaultImpl(const char* text); +static void ImeSetInputScreenPosFn_DefaultImpl(int x, int y); + +//----------------------------------------------------------------------------- +// User facing structures +//----------------------------------------------------------------------------- + +ImGuiStyle::ImGuiStyle() +{ + Alpha = 1.0f; // Global alpha applies to everything in ImGui + WindowPadding = ImVec2(8,8); // Padding within a window + WindowMinSize = ImVec2(32,32); // Minimum window size + WindowRounding = 9.0f; // Radius of window corners rounding. Set to 0.0f to have rectangular windows + ChildWindowRounding = 0.0f; // Radius of child window corners rounding. Set to 0.0f to have rectangular windows + FramePadding = ImVec2(4,3); // Padding within a framed rectangle (used by most widgets) + FrameRounding = 0.0f; // Radius of frame corners rounding. Set to 0.0f to have rectangular frames (used by most widgets). + ItemSpacing = ImVec2(8,4); // Horizontal and vertical spacing between widgets/lines + ItemInnerSpacing = ImVec2(4,4); // Horizontal and vertical spacing between within elements of a composed widget (e.g. a slider and its label) + TouchExtraPadding = ImVec2(0,0); // Expand reactive bounding box for touch-based system where touch position is not accurate enough. Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget. So don't grow this too much! + AutoFitPadding = ImVec2(8,8); // Extra space after auto-fit (double-clicking on resize grip) + WindowFillAlphaDefault = 0.70f; // Default alpha of window background, if not specified in ImGui::Begin() + IndentSpacing = 22.0f; // Horizontal spacing when e.g. entering a tree node + ColumnsMinSpacing = 6.0f; // Minimum horizontal spacing between two columns + ScrollbarWidth = 16.0f; // Width of the vertical scrollbar + GrabMinSize = 10.0f; // Minimum width/height of a slider or scrollbar grab + DisplaySafeAreaPadding = ImVec2(22,22); // Window positions are clamped to be visible within the display area. If you cannot see the edge of your screen (e.g. on a TV) increase the safe area padding + + Colors[ImGuiCol_Text] = ImVec4(0.90f, 0.90f, 0.90f, 1.00f); + Colors[ImGuiCol_WindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f); + Colors[ImGuiCol_ChildWindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + Colors[ImGuiCol_Border] = ImVec4(0.70f, 0.70f, 0.70f, 1.00f); + Colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.60f); + Colors[ImGuiCol_FrameBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.30f); // Background of checkbox, radio button, plot, slider, text input + Colors[ImGuiCol_FrameBgHovered] = ImVec4(0.90f, 0.80f, 0.80f, 0.40f); + Colors[ImGuiCol_FrameBgActive] = ImVec4(0.90f, 0.65f, 0.65f, 0.45f); + Colors[ImGuiCol_TitleBg] = ImVec4(0.50f, 0.50f, 1.00f, 0.45f); + Colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.40f, 0.40f, 0.80f, 0.20f); + Colors[ImGuiCol_ScrollbarBg] = ImVec4(0.40f, 0.40f, 0.80f, 0.15f); + Colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.40f, 0.40f, 0.80f, 0.30f); + Colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.40f, 0.40f, 0.80f, 0.40f); + Colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.80f, 0.50f, 0.50f, 0.40f); + Colors[ImGuiCol_ComboBg] = ImVec4(0.20f, 0.20f, 0.20f, 0.99f); + Colors[ImGuiCol_CheckMark] = ImVec4(0.90f, 0.90f, 0.90f, 0.50f); + Colors[ImGuiCol_SliderGrab] = ImVec4(1.00f, 1.00f, 1.00f, 0.30f); + Colors[ImGuiCol_SliderGrabActive] = ImVec4(0.80f, 0.50f, 0.50f, 1.00f); + Colors[ImGuiCol_Button] = ImVec4(0.67f, 0.40f, 0.40f, 0.60f); + Colors[ImGuiCol_ButtonHovered] = ImVec4(0.67f, 0.40f, 0.40f, 1.00f); + Colors[ImGuiCol_ButtonActive] = ImVec4(0.80f, 0.50f, 0.50f, 1.00f); + Colors[ImGuiCol_Header] = ImVec4(0.40f, 0.40f, 0.90f, 0.45f); + Colors[ImGuiCol_HeaderHovered] = ImVec4(0.45f, 0.45f, 0.90f, 0.80f); + Colors[ImGuiCol_HeaderActive] = ImVec4(0.53f, 0.53f, 0.87f, 0.80f); + Colors[ImGuiCol_Column] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f); + Colors[ImGuiCol_ColumnHovered] = ImVec4(0.70f, 0.60f, 0.60f, 1.00f); + Colors[ImGuiCol_ColumnActive] = ImVec4(0.90f, 0.70f, 0.70f, 1.00f); + Colors[ImGuiCol_ResizeGrip] = ImVec4(1.00f, 1.00f, 1.00f, 0.30f); + Colors[ImGuiCol_ResizeGripHovered] = ImVec4(1.00f, 1.00f, 1.00f, 0.60f); + Colors[ImGuiCol_ResizeGripActive] = ImVec4(1.00f, 1.00f, 1.00f, 0.90f); + Colors[ImGuiCol_CloseButton] = ImVec4(0.50f, 0.50f, 0.90f, 0.50f); + Colors[ImGuiCol_CloseButtonHovered] = ImVec4(0.70f, 0.70f, 0.90f, 0.60f); + Colors[ImGuiCol_CloseButtonActive] = ImVec4(0.70f, 0.70f, 0.70f, 1.00f); + Colors[ImGuiCol_PlotLines] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); + Colors[ImGuiCol_PlotLinesHovered] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); + Colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); + Colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f); + Colors[ImGuiCol_TextSelectedBg] = ImVec4(0.00f, 0.00f, 1.00f, 0.35f); + Colors[ImGuiCol_TooltipBg] = ImVec4(0.05f, 0.05f, 0.10f, 0.90f); +} + +// Statically allocated font atlas. This is merely a maneuver to keep ImFontAtlas definition at the bottom of the .h file (otherwise it'd be inside ImGuiIO) +// Also we wouldn't be able to new() one at this point, before users may define IO.MemAllocFn. +static ImFontAtlas GDefaultFontAtlas; + +ImGuiIO::ImGuiIO() +{ + // Most fields are initialized with zero + memset(this, 0, sizeof(*this)); + + DisplaySize = ImVec2(-1.0f, -1.0f); + DeltaTime = 1.0f/60.0f; + IniSavingRate = 5.0f; + IniFilename = "imgui.ini"; + LogFilename = "imgui_log.txt"; + Fonts = &GDefaultFontAtlas; + FontGlobalScale = 1.0f; + MousePos = ImVec2(-1,-1); + MousePosPrev = ImVec2(-1,-1); + MouseDoubleClickTime = 0.30f; + MouseDoubleClickMaxDist = 6.0f; + MouseDragThreshold = 6.0f; + UserData = NULL; + + // User functions + RenderDrawListsFn = NULL; + MemAllocFn = malloc; + MemFreeFn = free; + GetClipboardTextFn = GetClipboardTextFn_DefaultImpl; // Platform dependent default implementations + SetClipboardTextFn = SetClipboardTextFn_DefaultImpl; + ImeSetInputScreenPosFn = ImeSetInputScreenPosFn_DefaultImpl; +} + +// Pass in translated ASCII characters for text input. +// - with glfw you can get those from the callback set in glfwSetCharCallback() +// - on Windows you can get those using ToAscii+keyboard state, or via the WM_CHAR message +void ImGuiIO::AddInputCharacter(ImWchar c) +{ + const size_t n = ImStrlenW(InputCharacters); + if (n + 1 < sizeof(InputCharacters) / sizeof(InputCharacters[0])) + { + InputCharacters[n] = c; + InputCharacters[n+1] = 0; + } +} + +//----------------------------------------------------------------------------- +// Helpers +//----------------------------------------------------------------------------- + +#define IM_ARRAYSIZE(_ARR) ((int)(sizeof(_ARR)/sizeof(*_ARR))) + +#undef PI +const float PI = 3.14159265358979323846f; + +#ifdef INT_MAX +#define IM_INT_MIN INT_MIN +#define IM_INT_MAX INT_MAX +#else +#define IM_INT_MIN (-2147483647-1) +#define IM_INT_MAX (2147483647) +#endif + +// Play it nice with Windows users. Notepad in 2015 still doesn't display text data with Unix-style \n. +#ifdef _MSC_VER +#define STR_NEWLINE "\r\n" +#else +#define STR_NEWLINE "\n" +#endif + +// Math bits +// We are keeping those static in the .cpp file so as not to leak them outside, in the case the user has implicit cast operators between ImVec2 and its own types. +static inline ImVec2 operator*(const ImVec2& lhs, const float rhs) { return ImVec2(lhs.x*rhs, lhs.y*rhs); } +//static inline ImVec2 operator/(const ImVec2& lhs, const float rhs) { return ImVec2(lhs.x/rhs, lhs.y/rhs); } +static inline ImVec2 operator+(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x+rhs.x, lhs.y+rhs.y); } +static inline ImVec2 operator-(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x-rhs.x, lhs.y-rhs.y); } +static inline ImVec2 operator*(const ImVec2& lhs, const ImVec2 rhs) { return ImVec2(lhs.x*rhs.x, lhs.y*rhs.y); } +static inline ImVec2 operator/(const ImVec2& lhs, const ImVec2 rhs) { return ImVec2(lhs.x/rhs.x, lhs.y/rhs.y); } +static inline ImVec2& operator+=(ImVec2& lhs, const ImVec2& rhs) { lhs.x += rhs.x; lhs.y += rhs.y; return lhs; } +static inline ImVec2& operator-=(ImVec2& lhs, const ImVec2& rhs) { lhs.x -= rhs.x; lhs.y -= rhs.y; return lhs; } +static inline ImVec2& operator*=(ImVec2& lhs, const float rhs) { lhs.x *= rhs; lhs.y *= rhs; return lhs; } +//static inline ImVec2& operator/=(ImVec2& lhs, const float rhs) { lhs.x /= rhs; lhs.y /= rhs; return lhs; } + +static inline int ImMin(int lhs, int rhs) { return lhs < rhs ? lhs : rhs; } +static inline int ImMax(int lhs, int rhs) { return lhs >= rhs ? lhs : rhs; } +static inline float ImMin(float lhs, float rhs) { return lhs < rhs ? lhs : rhs; } +static inline float ImMax(float lhs, float rhs) { return lhs >= rhs ? lhs : rhs; } +static inline ImVec2 ImMin(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(ImMin(lhs.x,rhs.x), ImMin(lhs.y,rhs.y)); } +static inline ImVec2 ImMax(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(ImMax(lhs.x,rhs.x), ImMax(lhs.y,rhs.y)); } +static inline int ImClamp(int v, int mn, int mx) { return (v < mn) ? mn : (v > mx) ? mx : v; } +static inline float ImClamp(float v, float mn, float mx) { return (v < mn) ? mn : (v > mx) ? mx : v; } +static inline ImVec2 ImClamp(const ImVec2& f, const ImVec2& mn, ImVec2 mx) { return ImVec2(ImClamp(f.x,mn.x,mx.x), ImClamp(f.y,mn.y,mx.y)); } +static inline float ImSaturate(float f) { return (f < 0.0f) ? 0.0f : (f > 1.0f) ? 1.0f : f; } +static inline float ImLerp(float a, float b, float t) { return a + (b - a) * t; } +static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, const ImVec2& t) { return ImVec2(a.x + (b.x - a.x) * t.x, a.y + (b.y - a.y) * t.y); } +static inline float ImLengthSqr(const ImVec2& lhs) { return lhs.x*lhs.x + lhs.y*lhs.y; } + +static int ImStricmp(const char* str1, const char* str2) +{ + int d; + while ((d = toupper(*str2) - toupper(*str1)) == 0 && *str1) { str1++; str2++; } + return d; +} + +static int ImStrnicmp(const char* str1, const char* str2, int count) +{ + int d = 0; + while (count > 0 && (d = toupper(*str2) - toupper(*str1)) == 0 && *str1) { str1++; str2++; count--; } + return d; +} + +static char* ImStrdup(const char *str) +{ + char *buff = (char*)ImGui::MemAlloc(strlen(str) + 1); + IM_ASSERT(buff); + strcpy(buff, str); + return buff; +} + +static size_t ImStrlenW(const ImWchar* str) +{ + size_t n = 0; + while (*str++) n++; + return n; +} + +static const char* ImStristr(const char* haystack, const char* needle, const char* needle_end) +{ + if (!needle_end) + needle_end = needle + strlen(needle); + + const char un0 = (char)toupper(*needle); + while (*haystack) + { + if (toupper(*haystack) == un0) + { + const char* b = needle + 1; + for (const char* a = haystack + 1; b < needle_end; a++, b++) + if (toupper(*a) != toupper(*b)) + break; + if (b == needle_end) + return haystack; + } + haystack++; + } + return NULL; +} + +// Pass data_size==0 for zero-terminated string +// Try to replace with FNV1a hash? +static ImU32 ImHash(const void* data, size_t data_size, ImU32 seed = 0) +{ + static ImU32 crc32_lut[256] = { 0 }; + if (!crc32_lut[1]) + { + const ImU32 polynomial = 0xEDB88320; + for (ImU32 i = 0; i < 256; i++) + { + ImU32 crc = i; + for (ImU32 j = 0; j < 8; j++) + crc = (crc >> 1) ^ (ImU32(-int(crc & 1)) & polynomial); + crc32_lut[i] = crc; + } + } + + seed = ~seed; + ImU32 crc = seed; + const unsigned char* current = (const unsigned char*)data; + + if (data_size > 0) + { + // Known size + while (data_size--) + crc = (crc >> 8) ^ crc32_lut[(crc & 0xFF) ^ *current++]; + } + else + { + // Zero-terminated string + while (unsigned char c = *current++) + { + // We support a syntax of "label###id" where only "###id" is included in the hash, and only "label" gets displayed. + // Because this syntax is rarely used we are optimizing for the common case. + // - If we reach ### in the string we discard the hash so far and reset to the seed. + // - We don't do 'current += 2; continue;' after handling ### to keep the code smaller. + if (c == '#' && current[0] == '#' && current[1] == '#') + crc = seed; + + crc = (crc >> 8) ^ crc32_lut[(crc & 0xFF) ^ c]; + } + } + return ~crc; +} + +static size_t ImFormatString(char* buf, size_t buf_size, const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + int w = vsnprintf(buf, buf_size, fmt, args); + va_end(args); + buf[buf_size-1] = 0; + return (w == -1) ? buf_size : (size_t)w; +} + +static size_t ImFormatStringV(char* buf, size_t buf_size, const char* fmt, va_list args) +{ + int w = vsnprintf(buf, buf_size, fmt, args); + buf[buf_size-1] = 0; + return (w == -1) ? buf_size : (size_t)w; +} + +ImU32 ImGui::ColorConvertFloat4ToU32(const ImVec4& in) +{ + ImU32 out = ((ImU32)(ImSaturate(in.x)*255.f)); + out |= ((ImU32)(ImSaturate(in.y)*255.f) << 8); + out |= ((ImU32)(ImSaturate(in.z)*255.f) << 16); + out |= ((ImU32)(ImSaturate(in.w)*255.f) << 24); + return out; +} + +// Convert rgb floats ([0-1],[0-1],[0-1]) to hsv floats ([0-1],[0-1],[0-1]), from Foley & van Dam p592 +// Optimized http://lolengine.net/blog/2013/01/13/fast-rgb-to-hsv +void ImGui::ColorConvertRGBtoHSV(float r, float g, float b, float& out_h, float& out_s, float& out_v) +{ + float K = 0.f; + if (g < b) + { + const float tmp = g; g = b; b = tmp; + K = -1.f; + } + if (r < g) + { + const float tmp = r; r = g; g = tmp; + K = -2.f / 6.f - K; + } + + const float chroma = r - (g < b ? g : b); + out_h = fabsf(K + (g - b) / (6.f * chroma + 1e-20f)); + out_s = chroma / (r + 1e-20f); + out_v = r; +} + +// Convert hsv floats ([0-1],[0-1],[0-1]) to rgb floats ([0-1],[0-1],[0-1]), from Foley & van Dam p593 +// also http://en.wikipedia.org/wiki/HSL_and_HSV +void ImGui::ColorConvertHSVtoRGB(float h, float s, float v, float& out_r, float& out_g, float& out_b) +{ + if (s == 0.0f) + { + // gray + out_r = out_g = out_b = v; + return; + } + + h = fmodf(h, 1.0f) / (60.0f/360.0f); + int i = (int)h; + float f = h - (float)i; + float p = v * (1.0f - s); + float q = v * (1.0f - s * f); + float t = v * (1.0f - s * (1.0f - f)); + + switch (i) + { + case 0: out_r = v; out_g = t; out_b = p; break; + case 1: out_r = q; out_g = v; out_b = p; break; + case 2: out_r = p; out_g = v; out_b = t; break; + case 3: out_r = p; out_g = q; out_b = v; break; + case 4: out_r = t; out_g = p; out_b = v; break; + case 5: default: out_r = v; out_g = p; out_b = q; break; + } +} + +// Load file content into memory +// Memory allocated with ImGui::MemAlloc(), must be freed by user using ImGui::MemFree() +static bool ImLoadFileToMemory(const char* filename, const char* file_open_mode, void** out_file_data, size_t* out_file_size, size_t padding_bytes) +{ + IM_ASSERT(filename && file_open_mode && out_file_data && out_file_size); + *out_file_data = NULL; + *out_file_size = 0; + + FILE* f; + if ((f = fopen(filename, file_open_mode)) == NULL) + return false; + + long file_size_signed; + if (fseek(f, 0, SEEK_END) || (file_size_signed = ftell(f)) == -1 || fseek(f, 0, SEEK_SET)) + { + fclose(f); + return false; + } + + size_t file_size = (size_t)file_size_signed; + void* file_data = ImGui::MemAlloc(file_size + padding_bytes); + if (file_data == NULL) + { + fclose(f); + return false; + } + if (fread(file_data, 1, file_size, f) != file_size) + { + fclose(f); + ImGui::MemFree(file_data); + return false; + } + if (padding_bytes > 0) + memset((void *)(((char*)file_data) + file_size), 0, padding_bytes); + + fclose(f); + *out_file_data = file_data; + *out_file_size = file_size; + + return true; +} + +//----------------------------------------------------------------------------- + +struct ImGuiColMod // Color modifier, backup of modified data so we can restore it +{ + ImGuiCol Col; + ImVec4 PreviousValue; +}; + +struct ImGuiStyleMod // Style modifier, backup of modified data so we can restore it +{ + ImGuiStyleVar Var; + ImVec2 PreviousValue; +}; + +struct ImRect // 2D axis aligned bounding-box +{ + ImVec2 Min; + ImVec2 Max; + + ImRect() { Min = ImVec2(FLT_MAX,FLT_MAX); Max = ImVec2(-FLT_MAX,-FLT_MAX); } + ImRect(const ImVec2& min, const ImVec2& max) { Min = min; Max = max; } + ImRect(const ImVec4& v) { Min.x = v.x; Min.y = v.y; Max.x = v.z; Max.y = v.w; } + ImRect(float x1, float y1, float x2, float y2) { Min.x = x1; Min.y = y1; Max.x = x2; Max.y = y2; } + + ImVec2 GetCenter() const { return Min + (Max-Min)*0.5f; } + ImVec2 GetSize() const { return Max-Min; } + float GetWidth() const { return (Max-Min).x; } + float GetHeight() const { return (Max-Min).y; } + ImVec2 GetTL() const { return Min; } + ImVec2 GetTR() const { return ImVec2(Max.x,Min.y); } + ImVec2 GetBL() const { return ImVec2(Min.x,Max.y); } + ImVec2 GetBR() const { return Max; } + bool Contains(const ImVec2& p) const { return p.x >= Min.x && p.y >= Min.y && p.x < Max.x && p.y < Max.y; } + bool Contains(const ImRect& r) const { return r.Min.x >= Min.x && r.Min.y >= Min.y && r.Max.x < Max.x && r.Max.y < Max.y; } + bool Overlaps(const ImRect& r) const { return r.Min.y < Max.y && r.Max.y > Min.y && r.Min.x < Max.x && r.Max.x > Min.x; } + void Add(const ImVec2& rhs) { Min.x = ImMin(Min.x, rhs.x); Min.y = ImMin(Min.y, rhs.y); Max.x = ImMax(Max.x, rhs.x); Max.y = ImMax(Max.x, rhs.x); } + void Add(const ImRect& rhs) { Min.x = ImMin(Min.x, rhs.Min.x); Min.y = ImMin(Min.y, rhs.Min.y); Max.x = ImMax(Max.x, rhs.Max.x); Max.y = ImMax(Max.y, rhs.Max.y); } + void Expand(const float amount) { Min.x -= amount; Min.y -= amount; Max.x += amount; Max.y += amount; } + void Expand(const ImVec2& amount) { Min -= amount; Max += amount; } + void Clip(const ImRect& clip) { Min.x = ImMax(Min.x, clip.Min.x); Min.y = ImMax(Min.y, clip.Min.y); Max.x = ImMin(Max.x, clip.Max.x); Max.y = ImMin(Max.y, clip.Max.y); } + ImVec2 GetClosestPoint(ImVec2 p, bool on_edge) const + { + if (!on_edge && Contains(p)) + return p; + if (p.x > Max.x) p.x = Max.x; + else if (p.x < Min.x) p.x = Min.x; + if (p.y > Max.y) p.y = Max.y; + else if (p.y < Min.y) p.y = Min.y; + return p; + } +}; +typedef ImRect ImGuiAabb; // FIXME-OBSOLETE + +struct ImGuiGroupData +{ + ImVec2 BackupCursorPos; + ImVec2 BackupCursorMaxPos; + float BackupColumnsStartX; + float BackupCurrentLineHeight; + float BackupCurrentLineTextBaseOffset; + float BackupLogLinePosY; +}; + +// Temporary per-window data, reset at the beginning of the frame +struct ImGuiDrawContext +{ + ImVec2 CursorPos; + ImVec2 CursorPosPrevLine; + ImVec2 CursorStartPos; + ImVec2 CursorMaxPos; // Implicitly calculate the size of our contents, always extending. Saved into window->SizeContents at the end of the frame + float CurrentLineHeight; + float CurrentLineTextBaseOffset; + float PrevLineHeight; + float PrevLineTextBaseOffset; + float LogLinePosY; + int TreeDepth; + ImGuiID LastItemID; + ImRect LastItemRect; + bool LastItemHoveredAndUsable; + bool LastItemHoveredRect; + ImVector ChildWindows; + ImVector AllowKeyboardFocus; + ImVector ItemWidth; // 0.0: default, >0.0: width in pixels, <0.0: align xx pixels to the right of window + ImVector TextWrapPos; + ImVector GroupStack; + ImGuiColorEditMode ColorEditMode; + ImGuiStorage* StateStorage; + + float ColumnsStartX; // Indentation / start position from left of window (increased by TreePush/TreePop, etc.) + float ColumnsOffsetX; // Offset to the current column (if ColumnsCurrent > 0). FIXME: This and the above should be a stack to allow use cases like Tree->Column->Tree. Need revamp columns API. + int ColumnsCurrent; + int ColumnsCount; + ImVec2 ColumnsStartPos; + float ColumnsCellMinY; + float ColumnsCellMaxY; + bool ColumnsShowBorders; + ImGuiID ColumnsSetID; + ImVector ColumnsOffsetsT; // Columns offset normalized 0.0 (far left) -> 1.0 (far right) + + ImGuiDrawContext() + { + CursorPos = CursorPosPrevLine = CursorStartPos = CursorMaxPos = ImVec2(0.0f, 0.0f); + CurrentLineHeight = PrevLineHeight = 0.0f; + CurrentLineTextBaseOffset = PrevLineTextBaseOffset = 0.0f; + LogLinePosY = -1.0f; + TreeDepth = 0; + LastItemID = 0; + LastItemRect = ImRect(0.0f,0.0f,0.0f,0.0f); + LastItemHoveredAndUsable = LastItemHoveredRect = false; + ColorEditMode = ImGuiColorEditMode_RGB; + StateStorage = NULL; + + ColumnsStartX = 0.0f; + ColumnsOffsetX = 0.0f; + ColumnsCurrent = 0; + ColumnsCount = 1; + ColumnsStartPos = ImVec2(0.0f, 0.0f); + ColumnsCellMinY = ColumnsCellMaxY = 0.0f; + ColumnsShowBorders = true; + ColumnsSetID = 0; + } +}; + +// Internal state of the currently focused/edited text input box +struct ImGuiTextEditState +{ + ImGuiID Id; // widget id owning the text state + ImWchar Text[1024]; // edit buffer, we need to persist but can't guarantee the persistence of the user-provided buffer. so we copy into own buffer. + char InitialText[1024*3+1]; // backup of end-user buffer at the time of focus (in UTF-8, unaltered) + size_t CurLenA, CurLenW; // we need to maintain our buffer length in both UTF-8 and wchar format. + size_t BufSizeA; // end-user buffer size, <= 1024 (or increase above) + float Width; // widget width + float ScrollX; + STB_TexteditState StbState; + float CursorAnim; + ImVec2 InputCursorScreenPos; // Cursor position in screen space to be used by IME callback. + bool SelectedAllMouseLock; + ImFont* Font; + float FontSize; + + ImGuiTextEditState() { memset(this, 0, sizeof(*this)); } + + void CursorAnimReset() { CursorAnim = -0.30f; } // After a user-input the cursor stays on for a while without blinking + bool CursorIsVisible() const { return CursorAnim <= 0.0f || fmodf(CursorAnim, 1.20f) <= 0.80f; } // Blinking + bool HasSelection() const { return StbState.select_start != StbState.select_end; } + void SelectAll() { StbState.select_start = 0; StbState.select_end = (int)ImStrlenW(Text); StbState.cursor = StbState.select_end; StbState.has_preferred_x = false; } + + void OnKeyPressed(int key); + void UpdateScrollOffset(); + ImVec2 CalcDisplayOffsetFromCharIdx(int i) const; + + // Static functions because they are used to render non-focused instances of a text input box + static const char* GetTextPointerClippedA(ImFont* font, float font_size, const char* text, float width, ImVec2* out_text_size = NULL); + static const ImWchar* GetTextPointerClippedW(ImFont* font, float font_size, const ImWchar* text, float width, ImVec2* out_text_size = NULL); + static void RenderTextScrolledClipped(ImFont* font, float font_size, const char* text, ImVec2 pos_base, float width, float scroll_x); +}; + +// Data saved in imgui.ini file +struct ImGuiIniData +{ + char* Name; + ImGuiID ID; + ImVec2 Pos; + ImVec2 Size; + bool Collapsed; + + ImGuiIniData() { memset(this, 0, sizeof(*this)); } + ~ImGuiIniData() { if (Name) { ImGui::MemFree(Name); Name = NULL; } } +}; + +struct ImGuiMouseCursorData +{ + ImGuiMouseCursor Type; + ImVec2 Offset; + ImVec2 Size; + ImVec2 TexUvMin[2]; + ImVec2 TexUvMax[2]; +}; + +// Main state for ImGui +struct ImGuiState +{ + bool Initialized; + ImGuiIO IO; + ImGuiStyle Style; + ImFont* Font; // (Shortcut) == FontStack.empty() ? IO.Font : FontStack.back() + float FontSize; // (Shortcut) == FontBaseSize * g.CurrentWindow->FontWindowScale == window->FontSize() + float FontBaseSize; // (Shortcut) == IO.FontGlobalScale * Font->Scale * Font->FontSize. Size of characters. + ImVec2 FontTexUvWhitePixel; // (Shortcut) == Font->TexUvForWhite + + float Time; + int FrameCount; + int FrameCountRendered; + ImVector Windows; + ImVector WindowsSortBuffer; + ImGuiWindow* CurrentWindow; // Being drawn into + ImVector CurrentWindowStack; + ImGuiWindow* FocusedWindow; // Will catch keyboard inputs + ImGuiWindow* HoveredWindow; // Will catch mouse inputs + ImGuiWindow* HoveredRootWindow; // Will catch mouse inputs (for focus/move only) + ImGuiID HoveredId; // Hovered widget + ImGuiID ActiveId; // Active widget + ImGuiID ActiveIdPreviousFrame; + bool ActiveIdIsAlive; + bool ActiveIdIsJustActivated; // Set when + bool ActiveIdIsFocusedOnly; // Set only by active widget. Denote focus but no active interaction. + ImGuiWindow* MovedWindow; // Track the child window we clicked on to move a window. Only valid if ActiveID is the "#MOVE" identifier of a window. + float SettingsDirtyTimer; + ImVector Settings; + int DisableHideTextAfterDoubleHash; + ImVector ColorModifiers; + ImVector StyleModifiers; + ImVector FontStack; + + ImVec2 SetNextWindowPosVal; + ImGuiSetCond SetNextWindowPosCond; + ImVec2 SetNextWindowSizeVal; + ImGuiSetCond SetNextWindowSizeCond; + bool SetNextWindowCollapsedVal; + ImGuiSetCond SetNextWindowCollapsedCond; + bool SetNextWindowFocus; + bool SetNextTreeNodeOpenedVal; + ImGuiSetCond SetNextTreeNodeOpenedCond; + + // Render + ImVector RenderDrawLists[3]; + + // Mouse cursor + ImGuiMouseCursor MouseCursor; + ImDrawList MouseCursorDrawList; // Optional software render of mouse cursors, if io.MouseDrawCursor is set + ImGuiMouseCursorData MouseCursorData[ImGuiMouseCursor_Count_]; + + // Widget state + ImGuiTextEditState InputTextState; + ImGuiID ScalarAsInputTextId; // Temporary text input when CTRL+clicking on a slider, etc. + ImGuiStorage ColorEditModeStorage; // for user selection + ImGuiID ActiveComboID; + ImVec2 ActiveClickDeltaToCenter; + float DragCurrentValue; // current dragged value, always float, not rounded by end-user precision settings + ImVec2 DragLastMouseDelta; + float DragSpeedDefaultRatio; // if speed == 0.0f, uses (max-min) * DragSpeedDefaultRatio + float DragSpeedScaleSlow; + float DragSpeedScaleFast; + float ScrollbarClickDeltaToGrabCenter; // distance between mouse and center of grab box, normalized in parent space + char Tooltip[1024]; + char* PrivateClipboard; // if no custom clipboard handler is defined + + // Logging + bool LogEnabled; + FILE* LogFile; + ImGuiTextBuffer* LogClipboard; // pointer so our GImGui static constructor doesn't call heap allocators. + int LogStartDepth; + int LogAutoExpandMaxDepth; + + // Misc + float FramerateSecPerFrame[120]; // calculate estimate of framerate for user + int FramerateSecPerFrameIdx; + float FramerateSecPerFrameAccum; + char TempBuffer[1024*3+1]; // temporary text buffer + + ImGuiState() + { + Initialized = false; + Font = NULL; + FontBaseSize = FontSize = 0.0f; + FontTexUvWhitePixel = ImVec2(0.0f, 0.0f); + + Time = 0.0f; + FrameCount = 0; + FrameCountRendered = -1; + CurrentWindow = NULL; + FocusedWindow = NULL; + HoveredWindow = NULL; + HoveredRootWindow = NULL; + HoveredId = 0; + ActiveId = 0; + ActiveIdPreviousFrame = 0; + ActiveIdIsAlive = false; + ActiveIdIsJustActivated = false; + ActiveIdIsFocusedOnly = false; + MovedWindow = NULL; + SettingsDirtyTimer = 0.0f; + DisableHideTextAfterDoubleHash = 0; + + SetNextWindowPosVal = ImVec2(0.0f, 0.0f); + SetNextWindowPosCond = 0; + SetNextWindowSizeVal = ImVec2(0.0f, 0.0f); + SetNextWindowSizeCond = 0; + SetNextWindowCollapsedVal = false; + SetNextWindowCollapsedCond = 0; + SetNextWindowFocus = false; + SetNextTreeNodeOpenedVal = false; + SetNextTreeNodeOpenedCond = 0; + + ScalarAsInputTextId = 0; + ActiveComboID = 0; + ActiveClickDeltaToCenter = ImVec2(0.0f, 0.0f); + DragCurrentValue = 0.0f; + DragLastMouseDelta = ImVec2(0.0f, 0.0f); + DragSpeedDefaultRatio = 0.01f; + DragSpeedScaleSlow = 0.01f; + DragSpeedScaleFast = 10.0f; + ScrollbarClickDeltaToGrabCenter = 0.0f; + memset(Tooltip, 0, sizeof(Tooltip)); + PrivateClipboard = NULL; + + MouseCursor = ImGuiMouseCursor_Arrow; + + LogEnabled = false; + LogFile = NULL; + LogClipboard = NULL; + LogStartDepth = 0; + LogAutoExpandMaxDepth = 2; + + memset(FramerateSecPerFrame, 0, sizeof(FramerateSecPerFrame)); + FramerateSecPerFrameIdx = 0; + FramerateSecPerFrameAccum = 0.0f; + } +}; + +static ImGuiState GImDefaultState; // Internal state storage +static ImGuiState* GImGui = &GImDefaultState; // We access everything through this pointer. NB: this pointer is always assumed to be != NULL + +struct ImGuiWindow +{ + char* Name; + ImGuiID ID; + ImGuiWindowFlags Flags; + ImVec2 PosFloat; + ImVec2 Pos; // Position rounded-up to nearest pixel + ImVec2 Size; // Current size (==SizeFull or collapsed title bar size) + ImVec2 SizeFull; // Size when non collapsed + ImVec2 SizeContents; // Size of contents (== extents reach of the drawing cursor) from previous frame + ImGuiID MoveID; // == window->GetID("#MOVE") + float ScrollY; + float NextScrollY; + bool ScrollbarY; + bool Visible; // Set to true on Begin() + bool WasVisible; + bool Accessed; // Set to true when any widget access the current window + bool Collapsed; // Set when collapsing window to become only title-bar + bool SkipItems; // == Visible && !Collapsed + int AutoFitFrames; + bool AutoFitOnlyGrows; + int SetWindowPosAllowFlags; // bit ImGuiSetCond_*** specify if SetWindowPos() call will succeed with this particular flag. + int SetWindowSizeAllowFlags; // bit ImGuiSetCond_*** specify if SetWindowSize() call will succeed with this particular flag. + int SetWindowCollapsedAllowFlags; // bit ImGuiSetCond_*** specify if SetWindowCollapsed() call will succeed with this particular flag. + + ImGuiDrawContext DC; // Temporary per-window data, reset at the beginning of the frame + ImVector IDStack; // ID stack. ID are hashes seeded with the value at the top of the stack + ImVector ClipRectStack; // Scissoring / clipping rectangle. x1, y1, x2, y2. + ImRect ClippedRect; // = ClipRectStack.front() after setup in Begin() + int LastFrameDrawn; + float ItemWidthDefault; + ImGuiStorage StateStorage; + float FontWindowScale; // Scale multiplier per-window + ImDrawList* DrawList; + ImGuiWindow* RootWindow; + + // Focus + int FocusIdxAllCounter; // Start at -1 and increase as assigned via FocusItemRegister() + int FocusIdxTabCounter; // (same, but only count widgets which you can Tab through) + int FocusIdxAllRequestCurrent; // Item being requested for focus + int FocusIdxTabRequestCurrent; // Tab-able item being requested for focus + int FocusIdxAllRequestNext; // Item being requested for focus, for next update (relies on layout to be stable between the frame pressing TAB and the next frame) + int FocusIdxTabRequestNext; // " + +public: + ImGuiWindow(const char* name); + ~ImGuiWindow(); + + ImGuiID GetID(const char* str, const char* str_end = NULL); + ImGuiID GetID(const void* ptr); + + bool FocusItemRegister(bool is_active, bool tab_stop = true); // Return true if focus is requested + void FocusItemUnregister(); + + ImRect Rect() const { return ImRect(Pos, Pos+Size); } + float CalcFontSize() const { return GImGui->FontBaseSize * FontWindowScale; } + float TitleBarHeight() const { return (Flags & ImGuiWindowFlags_NoTitleBar) ? 0 : CalcFontSize() + GImGui->Style.FramePadding.y * 2.0f; } + ImRect TitleBarRect() const { return ImRect(Pos, Pos + ImVec2(SizeFull.x, TitleBarHeight())); } + ImVec2 WindowPadding() const { return ((Flags & ImGuiWindowFlags_ChildWindow) && !(Flags & ImGuiWindowFlags_ShowBorders) && !(Flags & ImGuiWindowFlags_ComboBox)) ? ImVec2(0,0) : GImGui->Style.WindowPadding; } + ImU32 Color(ImGuiCol idx, float a=1.f) const { ImVec4 c = GImGui->Style.Colors[idx]; c.w *= GImGui->Style.Alpha * a; return ImGui::ColorConvertFloat4ToU32(c); } + ImU32 Color(const ImVec4& col) const { ImVec4 c = col; c.w *= GImGui->Style.Alpha; return ImGui::ColorConvertFloat4ToU32(c); } +}; + +static inline ImGuiWindow* GetCurrentWindow() +{ + // If this ever crash it probably means that ImGui::NewFrame() hasn't been called. We should always have a CurrentWindow in the stack (there is an implicit "Debug" window) + ImGuiState& g = *GImGui; + g.CurrentWindow->Accessed = true; + return g.CurrentWindow; +} + +static inline void SetCurrentWindow(ImGuiWindow* window) +{ + ImGuiState& g = *GImGui; + g.CurrentWindow = window; + if (window) + g.FontSize = window->CalcFontSize(); +} + +static inline ImGuiWindow* GetParentWindow() +{ + ImGuiState& g = *GImGui; + IM_ASSERT(g.CurrentWindowStack.size() >= 2); + return g.CurrentWindowStack[g.CurrentWindowStack.size() - 2]; +} + +static void SetActiveId(ImGuiID id) +{ + ImGuiState& g = *GImGui; + g.ActiveId = id; + g.ActiveIdIsFocusedOnly = false; + g.ActiveIdIsJustActivated = true; +} + +static void RegisterAliveId(ImGuiID id) +{ + ImGuiState& g = *GImGui; + if (g.ActiveId == id) + g.ActiveIdIsAlive = true; +} + +//----------------------------------------------------------------------------- + +// Helper: Key->value storage +void ImGuiStorage::Clear() +{ + Data.clear(); +} + +// std::lower_bound but without the bullshit +static ImVector::iterator LowerBound(ImVector& data, ImU32 key) +{ + ImVector::iterator first = data.begin(); + ImVector::iterator last = data.end(); + int count = (int)(last - first); + while (count > 0) + { + int count2 = count / 2; + ImVector::iterator mid = first + count2; + if (mid->key < key) + { + first = ++mid; + count -= count2 + 1; + } + else + { + count = count2; + } + } + return first; +} + +int ImGuiStorage::GetInt(ImU32 key, int default_val) const +{ + ImVector::iterator it = LowerBound(const_cast&>(Data), key); + if (it == Data.end() || it->key != key) + return default_val; + return it->val_i; +} + +float ImGuiStorage::GetFloat(ImU32 key, float default_val) const +{ + ImVector::iterator it = LowerBound(const_cast&>(Data), key); + if (it == Data.end() || it->key != key) + return default_val; + return it->val_f; +} + +void* ImGuiStorage::GetVoidPtr(ImGuiID key) const +{ + ImVector::iterator it = LowerBound(const_cast&>(Data), key); + if (it == Data.end() || it->key != key) + return NULL; + return it->val_p; +} + +// References are only valid until a new value is added to the storage. Calling a Set***() function or a Get***Ref() function invalidates the pointer. +int* ImGuiStorage::GetIntRef(ImGuiID key, int default_val) +{ + ImVector::iterator it = LowerBound(Data, key); + if (it == Data.end() || it->key != key) + it = Data.insert(it, Pair(key, default_val)); + return &it->val_i; +} + +float* ImGuiStorage::GetFloatRef(ImGuiID key, float default_val) +{ + ImVector::iterator it = LowerBound(Data, key); + if (it == Data.end() || it->key != key) + it = Data.insert(it, Pair(key, default_val)); + return &it->val_f; +} + +void** ImGuiStorage::GetVoidPtrRef(ImGuiID key, void* default_val) +{ + ImVector::iterator it = LowerBound(Data, key); + if (it == Data.end() || it->key != key) + it = Data.insert(it, Pair(key, default_val)); + return &it->val_p; +} + +// FIXME-OPT: Wasting CPU because all SetInt() are preceeded by GetInt() calls so we should have the result from lower_bound already in place. +// However we only use SetInt() on explicit user action (so that's maximum once a frame) so the optimisation isn't much needed. +void ImGuiStorage::SetInt(ImU32 key, int val) +{ + ImVector::iterator it = LowerBound(Data, key); + if (it == Data.end() || it->key != key) + { + Data.insert(it, Pair(key, val)); + return; + } + it->val_i = val; +} + +void ImGuiStorage::SetFloat(ImU32 key, float val) +{ + ImVector::iterator it = LowerBound(Data, key); + if (it == Data.end() || it->key != key) + { + Data.insert(it, Pair(key, val)); + return; + } + it->val_f = val; +} + +void ImGuiStorage::SetVoidPtr(ImU32 key, void* val) +{ + ImVector::iterator it = LowerBound(Data, key); + if (it == Data.end() || it->key != key) + { + Data.insert(it, Pair(key, val)); + return; + } + it->val_p = val; +} + +void ImGuiStorage::SetAllInt(int v) +{ + for (size_t i = 0; i < Data.size(); i++) + Data[i].val_i = v; +} + +//----------------------------------------------------------------------------- + +// Helper: Parse and apply text filters. In format "aaaaa[,bbbb][,ccccc]" +ImGuiTextFilter::ImGuiTextFilter(const char* default_filter) +{ + if (default_filter) + { + ImFormatString(InputBuf, IM_ARRAYSIZE(InputBuf), "%s", default_filter); + Build(); + } + else + { + InputBuf[0] = 0; + CountGrep = 0; + } +} + +void ImGuiTextFilter::Draw(const char* label, float width) +{ + if (width > 0.0f) + ImGui::PushItemWidth(width); + ImGui::InputText(label, InputBuf, IM_ARRAYSIZE(InputBuf)); + if (width > 0.0f) + ImGui::PopItemWidth(); + Build(); +} + +void ImGuiTextFilter::TextRange::split(char separator, ImVector& out) +{ + out.resize(0); + const char* wb = b; + const char* we = wb; + while (we < e) + { + if (*we == separator) + { + out.push_back(TextRange(wb, we)); + wb = we + 1; + } + we++; + } + if (wb != we) + out.push_back(TextRange(wb, we)); +} + +void ImGuiTextFilter::Build() +{ + Filters.resize(0); + TextRange input_range(InputBuf, InputBuf+strlen(InputBuf)); + input_range.split(',', Filters); + + CountGrep = 0; + for (size_t i = 0; i != Filters.size(); i++) + { + Filters[i].trim_blanks(); + if (Filters[i].empty()) + continue; + if (Filters[i].front() != '-') + CountGrep += 1; + } +} + +bool ImGuiTextFilter::PassFilter(const char* val) const +{ + if (Filters.empty()) + return true; + + if (val == NULL) + val = ""; + + for (size_t i = 0; i != Filters.size(); i++) + { + const TextRange& f = Filters[i]; + if (f.empty()) + continue; + if (f.front() == '-') + { + // Subtract + if (ImStristr(val, f.begin()+1, f.end()) != NULL) + return false; + } + else + { + // Grep + if (ImStristr(val, f.begin(), f.end()) != NULL) + return true; + } + } + + // Implicit * grep + if (CountGrep == 0) + return true; + + return false; +} + +//----------------------------------------------------------------------------- + +// On some platform vsnprintf() takes va_list by reference and modifies it. +// va_copy is the 'correct' way to copy a va_list but Visual Studio prior to 2013 doesn't have it. +#ifndef va_copy +#define va_copy(dest, src) (dest = src) +#endif + +// Helper: Text buffer for logging/accumulating text +void ImGuiTextBuffer::appendv(const char* fmt, va_list args) +{ + va_list args_copy; + va_copy(args_copy, args); + + int len = vsnprintf(NULL, 0, fmt, args); // FIXME-OPT: could do a first pass write attempt, likely successful on first pass. + if (len <= 0) + return; + + const size_t write_off = Buf.size(); + const size_t needed_sz = write_off + (size_t)len; + if (write_off + (size_t)len >= Buf.capacity()) + { + const size_t double_capacity = Buf.capacity() * 2; + Buf.reserve(needed_sz > double_capacity ? needed_sz : double_capacity); + } + + Buf.resize(needed_sz); + ImFormatStringV(&Buf[write_off] - 1, (size_t)len+1, fmt, args_copy); +} + +void ImGuiTextBuffer::append(const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + appendv(fmt, args); + va_end(args); +} + +//----------------------------------------------------------------------------- + +ImGuiWindow::ImGuiWindow(const char* name) +{ + Name = ImStrdup(name); + ID = ImHash(name, 0); + IDStack.push_back(ID); + MoveID = GetID("#MOVE"); + + Flags = 0; + PosFloat = Pos = ImVec2(0.0f, 0.0f); + Size = SizeFull = ImVec2(0.0f, 0.0f); + SizeContents = ImVec2(0.0f, 0.0f); + ScrollY = 0.0f; + NextScrollY = 0.0f; + ScrollbarY = false; + Visible = WasVisible = false; + Accessed = false; + Collapsed = false; + SkipItems = false; + AutoFitFrames = -1; + AutoFitOnlyGrows = false; + SetWindowPosAllowFlags = SetWindowSizeAllowFlags = SetWindowCollapsedAllowFlags = ImGuiSetCond_Always | ImGuiSetCond_Once | ImGuiSetCond_FirstUseEver; + + LastFrameDrawn = -1; + ItemWidthDefault = 0.0f; + FontWindowScale = 1.0f; + + DrawList = (ImDrawList*)ImGui::MemAlloc(sizeof(ImDrawList)); + new(DrawList) ImDrawList(); + RootWindow = NULL; + + FocusIdxAllCounter = FocusIdxTabCounter = -1; + FocusIdxAllRequestCurrent = FocusIdxTabRequestCurrent = IM_INT_MAX; + FocusIdxAllRequestNext = FocusIdxTabRequestNext = IM_INT_MAX; +} + +ImGuiWindow::~ImGuiWindow() +{ + DrawList->~ImDrawList(); + ImGui::MemFree(DrawList); + DrawList = NULL; + ImGui::MemFree(Name); + Name = NULL; +} + +ImGuiID ImGuiWindow::GetID(const char* str, const char* str_end) +{ + ImGuiID seed = IDStack.back(); + const ImGuiID id = ImHash(str, str_end ? str_end - str : 0, seed); + RegisterAliveId(id); + return id; +} + +ImGuiID ImGuiWindow::GetID(const void* ptr) +{ + ImGuiID seed = IDStack.back(); + const ImGuiID id = ImHash(&ptr, sizeof(void*), seed); + RegisterAliveId(id); + return id; +} + +bool ImGuiWindow::FocusItemRegister(bool is_active, bool tab_stop) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + + const bool allow_keyboard_focus = window->DC.AllowKeyboardFocus.back(); + FocusIdxAllCounter++; + if (allow_keyboard_focus) + FocusIdxTabCounter++; + + // Process keyboard input at this point: TAB, Shift-TAB switch focus + // We can always TAB out of a widget that doesn't allow tabbing in. + if (tab_stop && FocusIdxAllRequestNext == IM_INT_MAX && FocusIdxTabRequestNext == IM_INT_MAX && is_active && IsKeyPressedMap(ImGuiKey_Tab)) + { + // Modulo on index will be applied at the end of frame once we've got the total counter of items. + FocusIdxTabRequestNext = FocusIdxTabCounter + (g.IO.KeyShift ? (allow_keyboard_focus ? -1 : 0) : +1); + } + + if (FocusIdxAllCounter == FocusIdxAllRequestCurrent) + return true; + + if (allow_keyboard_focus) + if (FocusIdxTabCounter == FocusIdxTabRequestCurrent) + return true; + + return false; +} + +void ImGuiWindow::FocusItemUnregister() +{ + FocusIdxAllCounter--; + FocusIdxTabCounter--; +} + +static inline void AddDrawListToRenderList(ImVector& out_render_list, ImDrawList* draw_list) +{ + if (!draw_list->commands.empty() && !draw_list->vtx_buffer.empty()) + { + if (draw_list->commands.back().vtx_count == 0) + draw_list->commands.pop_back(); + out_render_list.push_back(draw_list); + GImGui->IO.MetricsRenderVertices += (int)draw_list->vtx_buffer.size(); + } +} + +static void AddWindowToRenderList(ImVector& out_render_list, ImGuiWindow* window) +{ + AddDrawListToRenderList(out_render_list, window->DrawList); + for (size_t i = 0; i < window->DC.ChildWindows.size(); i++) + { + ImGuiWindow* child = window->DC.ChildWindows[i]; + if (child->Visible) // clipped children may have been marked not Visible + AddWindowToRenderList(out_render_list, child); + } +} + +//----------------------------------------------------------------------------- + +void* ImGui::MemAlloc(size_t sz) +{ + return GImGui->IO.MemAllocFn(sz); +} + +void ImGui::MemFree(void* ptr) +{ + return GImGui->IO.MemFreeFn(ptr); +} + +static ImGuiIniData* FindWindowSettings(const char* name) +{ + ImGuiState& g = *GImGui; + ImGuiID id = ImHash(name, 0); + for (size_t i = 0; i != g.Settings.size(); i++) + { + ImGuiIniData* ini = g.Settings[i]; + if (ini->ID == id) + return ini; + } + return NULL; +} + +static ImGuiIniData* AddWindowSettings(const char* name) +{ + ImGuiIniData* ini = (ImGuiIniData*)ImGui::MemAlloc(sizeof(ImGuiIniData)); + new(ini) ImGuiIniData(); + ini->Name = ImStrdup(name); + ini->ID = ImHash(name, 0); + ini->Collapsed = false; + ini->Pos = ImVec2(FLT_MAX,FLT_MAX); + ini->Size = ImVec2(0,0); + GImGui->Settings.push_back(ini); + return ini; +} + +// Zero-tolerance, poor-man .ini parsing +// FIXME: Write something less rubbish +static void LoadSettings() +{ + ImGuiState& g = *GImGui; + const char* filename = g.IO.IniFilename; + if (!filename) + return; + + char* file_data; + size_t file_size; + if (!ImLoadFileToMemory(filename, "rb", (void**)&file_data, &file_size, 1)) + return; + + ImGuiIniData* settings = NULL; + const char* buf_end = file_data + file_size; + for (const char* line_start = file_data; line_start < buf_end; ) + { + const char* line_end = line_start; + while (line_end < buf_end && *line_end != '\n' && *line_end != '\r') + line_end++; + + if (line_start[0] == '[' && line_end > line_start && line_end[-1] == ']') + { + char name[64]; + ImFormatString(name, IM_ARRAYSIZE(name), "%.*s", line_end-line_start-2, line_start+1); + settings = FindWindowSettings(name); + if (!settings) + settings = AddWindowSettings(name); + } + else if (settings) + { + float x, y; + int i; + if (sscanf(line_start, "Pos=%f,%f", &x, &y) == 2) + settings->Pos = ImVec2(x, y); + else if (sscanf(line_start, "Size=%f,%f", &x, &y) == 2) + settings->Size = ImMax(ImVec2(x, y), g.Style.WindowMinSize); + else if (sscanf(line_start, "Collapsed=%d", &i) == 1) + settings->Collapsed = (i != 0); + } + + line_start = line_end+1; + } + + ImGui::MemFree(file_data); +} + +static void SaveSettings() +{ + ImGuiState& g = *GImGui; + const char* filename = g.IO.IniFilename; + if (!filename) + return; + + // Gather data from windows that were active during this session + for (size_t i = 0; i != g.Windows.size(); i++) + { + ImGuiWindow* window = g.Windows[i]; + if (window->Flags & ImGuiWindowFlags_NoSavedSettings) + continue; + ImGuiIniData* settings = FindWindowSettings(window->Name); + settings->Pos = window->Pos; + settings->Size = window->SizeFull; + settings->Collapsed = window->Collapsed; + } + + // Write .ini file + // If a window wasn't opened in this session we preserve its settings + FILE* f = fopen(filename, "wt"); + if (!f) + return; + for (size_t i = 0; i != g.Settings.size(); i++) + { + const ImGuiIniData* settings = g.Settings[i]; + if (settings->Pos.x == FLT_MAX) + continue; + const char* name = settings->Name; + if (const char* p = strstr(name, "###")) // Skip to the "###" marker if any. We don't skip past to match the behavior of GetID() + name = p; + fprintf(f, "[%s]\n", name); + fprintf(f, "Pos=%d,%d\n", (int)settings->Pos.x, (int)settings->Pos.y); + fprintf(f, "Size=%d,%d\n", (int)settings->Size.x, (int)settings->Size.y); + fprintf(f, "Collapsed=%d\n", settings->Collapsed); + fprintf(f, "\n"); + } + + fclose(f); +} + +static void MarkSettingsDirty() +{ + ImGuiState& g = *GImGui; + + if (g.SettingsDirtyTimer <= 0.0f) + g.SettingsDirtyTimer = g.IO.IniSavingRate; +} + +const char* ImGui::GetVersion() +{ + return IMGUI_VERSION; +} + +// Internal state access - if you want to share ImGui state between modules (e.g. DLL) or allocate it yourself +// Note that we still point to some static data and members (such as GFontAtlas), so the state instance you end up using will point to the static data within its module +void* ImGui::GetInternalState() +{ + return GImGui; +} + +size_t ImGui::GetInternalStateSize() +{ + return sizeof(ImGuiState); +} + +void ImGui::SetInternalState(void* state, bool construct) +{ + if (construct) + new (state) ImGuiState(); + + GImGui = (ImGuiState*)state; +} + +ImGuiIO& ImGui::GetIO() +{ + return GImGui->IO; +} + +ImGuiStyle& ImGui::GetStyle() +{ + return GImGui->Style; +} + +void ImGui::NewFrame() +{ + ImGuiState& g = *GImGui; + + // Check user data + IM_ASSERT(g.IO.DeltaTime > 0.0f); + IM_ASSERT(g.IO.DisplaySize.x >= 0.0f && g.IO.DisplaySize.y >= 0.0f); + IM_ASSERT(g.IO.RenderDrawListsFn != NULL); // Must be implemented + IM_ASSERT(g.IO.Fonts->Fonts.size() > 0); // Font Atlas not created. Did you call io.Fonts->GetTexDataAsRGBA32 / GetTexDataAsAlpha8 ? + IM_ASSERT(g.IO.Fonts->Fonts[0]->IsLoaded()); // Font Atlas not created. Did you call io.Fonts->GetTexDataAsRGBA32 / GetTexDataAsAlpha8 ? + + if (!g.Initialized) + { + // Initialize on first frame + g.LogClipboard = (ImGuiTextBuffer*)ImGui::MemAlloc(sizeof(ImGuiTextBuffer)); + new(g.LogClipboard) ImGuiTextBuffer(); + + IM_ASSERT(g.Settings.empty()); + LoadSettings(); + g.Initialized = true; + } + + SetFont(g.IO.Fonts->Fonts[0]); + + g.Time += g.IO.DeltaTime; + g.FrameCount += 1; + g.Tooltip[0] = '\0'; + + // Update inputs state + if (g.IO.MousePos.x < 0 && g.IO.MousePos.y < 0) + g.IO.MousePos = ImVec2(-9999.0f, -9999.0f); + if ((g.IO.MousePos.x < 0 && g.IO.MousePos.y < 0) || (g.IO.MousePosPrev.x < 0 && g.IO.MousePosPrev.y < 0)) // if mouse just appeared or disappeared (negative coordinate) we cancel out movement in MouseDelta + g.IO.MouseDelta = ImVec2(0.0f, 0.0f); + else + g.IO.MouseDelta = g.IO.MousePos - g.IO.MousePosPrev; + g.IO.MousePosPrev = g.IO.MousePos; + for (size_t i = 0; i < IM_ARRAYSIZE(g.IO.MouseDown); i++) + { + g.IO.MouseDownTime[i] = g.IO.MouseDown[i] ? (g.IO.MouseDownTime[i] < 0.0f ? 0.0f : g.IO.MouseDownTime[i] + g.IO.DeltaTime) : -1.0f; + g.IO.MouseClicked[i] = (g.IO.MouseDownTime[i] == 0.0f); + g.IO.MouseDoubleClicked[i] = false; + if (g.IO.MouseClicked[i]) + { + if (g.Time - g.IO.MouseClickedTime[i] < g.IO.MouseDoubleClickTime) + { + if (ImLengthSqr(g.IO.MousePos - g.IO.MouseClickedPos[i]) < g.IO.MouseDoubleClickMaxDist * g.IO.MouseDoubleClickMaxDist) + g.IO.MouseDoubleClicked[i] = true; + g.IO.MouseClickedTime[i] = -FLT_MAX; // so the third click isn't turned into a double-click + } + else + { + g.IO.MouseClickedTime[i] = g.Time; + } + g.IO.MouseClickedPos[i] = g.IO.MousePos; + g.IO.MouseDragMaxDistanceSqr[i] = 0.0f; + } + else if (g.IO.MouseDown[i]) + { + g.IO.MouseDragMaxDistanceSqr[i] = ImMax(g.IO.MouseDragMaxDistanceSqr[i], ImLengthSqr(g.IO.MousePos - g.IO.MouseClickedPos[i])); + } + } + for (size_t i = 0; i < IM_ARRAYSIZE(g.IO.KeysDown); i++) + g.IO.KeysDownTime[i] = g.IO.KeysDown[i] ? (g.IO.KeysDownTime[i] < 0.0f ? 0.0f : g.IO.KeysDownTime[i] + g.IO.DeltaTime) : -1.0f; + + // Calculate frame-rate for the user, as a purely luxurious feature + g.FramerateSecPerFrameAccum += g.IO.DeltaTime - g.FramerateSecPerFrame[g.FramerateSecPerFrameIdx]; + g.FramerateSecPerFrame[g.FramerateSecPerFrameIdx] = g.IO.DeltaTime; + g.FramerateSecPerFrameIdx = (g.FramerateSecPerFrameIdx + 1) % IM_ARRAYSIZE(g.FramerateSecPerFrame); + g.IO.Framerate = 1.0f / (g.FramerateSecPerFrameAccum / (float)IM_ARRAYSIZE(g.FramerateSecPerFrame)); + + // Clear reference to active widget if the widget isn't alive anymore + g.HoveredId = 0; + if (!g.ActiveIdIsAlive && g.ActiveIdPreviousFrame == g.ActiveId && g.ActiveId != 0) + SetActiveId(0); + g.ActiveIdPreviousFrame = g.ActiveId; + g.ActiveIdIsAlive = false; + g.ActiveIdIsJustActivated = false; + if (!g.ActiveId) + g.MovedWindow = NULL; + + // Delay saving settings so we don't spam disk too much + if (g.SettingsDirtyTimer > 0.0f) + { + g.SettingsDirtyTimer -= g.IO.DeltaTime; + if (g.SettingsDirtyTimer <= 0.0f) + SaveSettings(); + } + + // Find the window we are hovering. Child windows can extend beyond the limit of their parent so we need to derive HoveredRootWindow from HoveredWindow + g.HoveredWindow = FindHoveredWindow(g.IO.MousePos, false); + if (g.HoveredWindow && (g.HoveredWindow->Flags & ImGuiWindowFlags_ChildWindow)) + g.HoveredRootWindow = g.HoveredWindow->RootWindow; + else + g.HoveredRootWindow = FindHoveredWindow(g.IO.MousePos, true); + + // Are we using inputs? Tell user so they can capture/discard the inputs away from the rest of their application. + // When clicking outside of a window we assume the click is owned by the application and won't request capture. + int mouse_earliest_button_down = -1; + for (int i = 0; i < IM_ARRAYSIZE(g.IO.MouseDown); i++) + { + if (g.IO.MouseClicked[i]) + g.IO.MouseDownOwned[i] = (g.HoveredWindow != NULL); + if (g.IO.MouseDown[i]) + if (mouse_earliest_button_down == -1 || g.IO.MouseClickedTime[mouse_earliest_button_down] > g.IO.MouseClickedTime[i]) + mouse_earliest_button_down = i; + } + bool mouse_owned_by_application = mouse_earliest_button_down != -1 && !g.IO.MouseDownOwned[mouse_earliest_button_down]; + g.IO.WantCaptureMouse = (!mouse_owned_by_application && g.HoveredWindow != NULL) || (g.ActiveId != 0); + g.IO.WantCaptureKeyboard = (g.ActiveId != 0); + g.MouseCursor = ImGuiMouseCursor_Arrow; + + // If mouse was first clicked outside of ImGui bounds we also cancel out hovering. + if (mouse_owned_by_application) + g.HoveredWindow = g.HoveredRootWindow = NULL; + + // Scale & Scrolling + if (g.HoveredWindow && g.IO.MouseWheel != 0.0f) + { + ImGuiWindow* window = g.HoveredWindow; + if (g.IO.KeyCtrl) + { + if (g.IO.FontAllowUserScaling) + { + // Zoom / Scale window + float new_font_scale = ImClamp(window->FontWindowScale + g.IO.MouseWheel * 0.10f, 0.50f, 2.50f); + float scale = new_font_scale / window->FontWindowScale; + window->FontWindowScale = new_font_scale; + + const ImVec2 offset = window->Size * (1.0f - scale) * (g.IO.MousePos - window->Pos) / window->Size; + window->Pos += offset; + window->PosFloat += offset; + window->Size *= scale; + window->SizeFull *= scale; + } + } + else + { + // Scroll + if (!(window->Flags & ImGuiWindowFlags_NoScrollWithMouse)) + { + const int scroll_lines = (window->Flags & ImGuiWindowFlags_ComboBox) ? 3 : 5; + window->NextScrollY -= g.IO.MouseWheel * window->CalcFontSize() * scroll_lines; + } + } + } + + // Pressing TAB activate widget focus + // NB: Don't discard FocusedWindow if it isn't active, so that a window that go on/off programatically won't lose its keyboard focus. + if (g.ActiveId == 0 && g.FocusedWindow != NULL && g.FocusedWindow->Visible && IsKeyPressedMap(ImGuiKey_Tab, false)) + { + g.FocusedWindow->FocusIdxTabRequestNext = 0; + } + + // Mark all windows as not visible + for (size_t i = 0; i != g.Windows.size(); i++) + { + ImGuiWindow* window = g.Windows[i]; + window->WasVisible = window->Visible; + window->Visible = false; + window->Accessed = false; + } + + // No window should be open at the beginning of the frame. + // But in order to allow the user to call NewFrame() multiple times without calling Render(), we are doing an explicit clear. + g.CurrentWindowStack.resize(0); + + // Create implicit window - we will only render it if the user has added something to it. + ImGui::SetNextWindowSize(ImVec2(400,400), ImGuiSetCond_FirstUseEver); + ImGui::Begin("Debug"); +} + +// NB: behavior of ImGui after Shutdown() is not tested/guaranteed at the moment. This function is merely here to free heap allocations. +void ImGui::Shutdown() +{ + ImGuiState& g = *GImGui; + if (!g.Initialized) + return; + + SaveSettings(); + + for (size_t i = 0; i < g.Windows.size(); i++) + { + g.Windows[i]->~ImGuiWindow(); + ImGui::MemFree(g.Windows[i]); + } + g.Windows.clear(); + g.WindowsSortBuffer.clear(); + g.CurrentWindowStack.clear(); + g.FocusedWindow = NULL; + g.HoveredWindow = NULL; + g.HoveredRootWindow = NULL; + for (size_t i = 0; i < g.Settings.size(); i++) + { + g.Settings[i]->~ImGuiIniData(); + ImGui::MemFree(g.Settings[i]); + } + g.Settings.clear(); + g.ColorModifiers.clear(); + g.StyleModifiers.clear(); + g.FontStack.clear(); + for (size_t i = 0; i < IM_ARRAYSIZE(g.RenderDrawLists); i++) + g.RenderDrawLists[i].clear(); + g.MouseCursorDrawList.ClearFreeMemory(); + g.ColorEditModeStorage.Clear(); + if (g.PrivateClipboard) + { + ImGui::MemFree(g.PrivateClipboard); + g.PrivateClipboard = NULL; + } + + if (g.LogFile && g.LogFile != stdout) + { + fclose(g.LogFile); + g.LogFile = NULL; + } + if (g.LogClipboard) + { + g.LogClipboard->~ImGuiTextBuffer(); + ImGui::MemFree(g.LogClipboard); + } + + g.IO.Fonts->Clear(); + + g.Initialized = false; +} + +// FIXME: Add a more explicit sort order in the window structure. +static int ChildWindowComparer(const void* lhs, const void* rhs) +{ + const ImGuiWindow* a = *(const ImGuiWindow**)lhs; + const ImGuiWindow* b = *(const ImGuiWindow**)rhs; + if (int d = (a->Flags & ImGuiWindowFlags_Popup) - (b->Flags & ImGuiWindowFlags_Popup)) + return d; + if (int d = (a->Flags & ImGuiWindowFlags_Tooltip) - (b->Flags & ImGuiWindowFlags_Tooltip)) + return d; + if (int d = (a->Flags & ImGuiWindowFlags_ComboBox) - (b->Flags & ImGuiWindowFlags_ComboBox)) + return d; + return 0; +} + +static void AddWindowToSortedBuffer(ImVector& out_sorted_windows, ImGuiWindow* window) +{ + out_sorted_windows.push_back(window); + if (window->Visible) + { + const size_t count = window->DC.ChildWindows.size(); + if (count > 1) + qsort(window->DC.ChildWindows.begin(), count, sizeof(ImGuiWindow*), ChildWindowComparer); + for (size_t i = 0; i < count; i++) + { + ImGuiWindow* child = window->DC.ChildWindows[i]; + if (child->Visible) + AddWindowToSortedBuffer(out_sorted_windows, child); + } + } +} + +static void PushClipRect(const ImVec4& clip_rect, bool clipped = true) +{ + ImGuiWindow* window = GetCurrentWindow(); + + ImVec4 cr = clip_rect; + if (clipped && !window->ClipRectStack.empty()) + { + // Clip with existing clip rect + const ImVec4 cur_cr = window->ClipRectStack.back(); + cr = ImVec4(ImMax(cr.x, cur_cr.x), ImMax(cr.y, cur_cr.y), ImMin(cr.z, cur_cr.z), ImMin(cr.w, cur_cr.w)); + } + cr.z = ImMax(cr.x, cr.z); + cr.w = ImMax(cr.y, cr.w); + + IM_ASSERT(cr.x <= cr.z && cr.y <= cr.w); + window->ClipRectStack.push_back(cr); + window->DrawList->PushClipRect(cr); +} + +static void PopClipRect() +{ + ImGuiWindow* window = GetCurrentWindow(); + window->ClipRectStack.pop_back(); + window->DrawList->PopClipRect(); +} + +void ImGui::Render() +{ + ImGuiState& g = *GImGui; + IM_ASSERT(g.Initialized); // Forgot to call ImGui::NewFrame() + + const bool first_render_of_the_frame = (g.FrameCountRendered != g.FrameCount); + g.FrameCountRendered = g.FrameCount; + + if (first_render_of_the_frame) + { + // Hide implicit window if it hasn't been used + IM_ASSERT(g.CurrentWindowStack.size() == 1); // Mismatched Begin/End + if (g.CurrentWindow && !g.CurrentWindow->Accessed) + g.CurrentWindow->Visible = false; + ImGui::End(); + + if (g.ActiveId == 0 && g.HoveredId == 0 && g.IO.MouseClicked[0]) + { + if (g.HoveredRootWindow != NULL) + { + // Select window for move/focus when we're done with all our widgets (we use the root window ID here) + IM_ASSERT(g.MovedWindow == NULL); + g.MovedWindow = g.HoveredWindow; + SetActiveId(g.HoveredRootWindow->MoveID); + } + else if (g.FocusedWindow != NULL) + { + // Clicking on void disable focus + FocusWindow(NULL); + } + } + + // Sort the window list so that all child windows are after their parent + // We cannot do that on FocusWindow() because childs may not exist yet + g.WindowsSortBuffer.resize(0); + g.WindowsSortBuffer.reserve(g.Windows.size()); + for (size_t i = 0; i != g.Windows.size(); i++) + { + ImGuiWindow* window = g.Windows[i]; + if (window->Flags & ImGuiWindowFlags_ChildWindow) // if a child is visible its parent will add it + if (window->Visible) + continue; + AddWindowToSortedBuffer(g.WindowsSortBuffer, window); + } + IM_ASSERT(g.Windows.size() == g.WindowsSortBuffer.size()); // we done something wrong + g.Windows.swap(g.WindowsSortBuffer); + + // Clear data for next frame + g.IO.MouseWheel = 0.0f; + memset(g.IO.InputCharacters, 0, sizeof(g.IO.InputCharacters)); + } + + // Skip render altogether if alpha is 0.0 + // Note that vertex buffers have been created, so it is best practice that you don't call Begin/End in the first place. + if (g.Style.Alpha > 0.0f) + { + // Render tooltip + if (g.Tooltip[0]) + { + // Use a dummy window to render the tooltip + ImGui::BeginTooltip(); + ImGui::TextUnformatted(g.Tooltip); + ImGui::EndTooltip(); + } + + // Gather windows to render + g.IO.MetricsRenderVertices = 0; + for (size_t i = 0; i < IM_ARRAYSIZE(g.RenderDrawLists); i++) + g.RenderDrawLists[i].resize(0); + for (size_t i = 0; i != g.Windows.size(); i++) + { + ImGuiWindow* window = g.Windows[i]; + if (window->Visible && (window->Flags & (ImGuiWindowFlags_ChildWindow)) == 0) + { + // FIXME: Generalize this with a proper layering system so we can stack. + if (window->Flags & ImGuiWindowFlags_Popup) + AddWindowToRenderList(g.RenderDrawLists[1], window); + else if (window->Flags & ImGuiWindowFlags_Tooltip) + AddWindowToRenderList(g.RenderDrawLists[2], window); + else + AddWindowToRenderList(g.RenderDrawLists[0], window); + } + } + + // Flatten layers + size_t n = g.RenderDrawLists[0].size(); + size_t flattened_size = n; + for (size_t i = 1; i < IM_ARRAYSIZE(g.RenderDrawLists); i++) + flattened_size += g.RenderDrawLists[i].size(); + g.RenderDrawLists[0].resize(flattened_size); + for (size_t i = 1; i < IM_ARRAYSIZE(g.RenderDrawLists); i++) + { + ImVector& layer = g.RenderDrawLists[i]; + if (!layer.empty()) + { + memcpy(&g.RenderDrawLists[0][n], &layer[0], layer.size() * sizeof(ImDrawList*)); + n += layer.size(); + } + } + + if (g.IO.MouseDrawCursor) + { + const ImGuiMouseCursorData& cursor_data = g.MouseCursorData[g.MouseCursor]; + const ImVec2 pos = g.IO.MousePos - cursor_data.Offset; + const ImVec2 size = cursor_data.Size; + const ImTextureID tex_id = g.IO.Fonts->TexID; + g.MouseCursorDrawList.Clear(); + g.MouseCursorDrawList.PushTextureID(tex_id); + g.MouseCursorDrawList.AddImage(tex_id, pos+ImVec2(1,0), pos+ImVec2(1,0) + size, cursor_data.TexUvMin[1], cursor_data.TexUvMax[1], 0x30000000); // Shadow + g.MouseCursorDrawList.AddImage(tex_id, pos+ImVec2(2,0), pos+ImVec2(2,0) + size, cursor_data.TexUvMin[1], cursor_data.TexUvMax[1], 0x30000000); // Shadow + g.MouseCursorDrawList.AddImage(tex_id, pos, pos + size, cursor_data.TexUvMin[1], cursor_data.TexUvMax[1], 0xFF000000); // Black border + g.MouseCursorDrawList.AddImage(tex_id, pos, pos + size, cursor_data.TexUvMin[0], cursor_data.TexUvMax[0], 0xFFFFFFFF); // White fill + g.MouseCursorDrawList.PopTextureID(); + AddDrawListToRenderList(g.RenderDrawLists[0], &g.MouseCursorDrawList); + } + + // Render + if (!g.RenderDrawLists[0].empty()) + g.IO.RenderDrawListsFn(&g.RenderDrawLists[0][0], (int)g.RenderDrawLists[0].size()); + } +} + +// Find the optional ## from which we stop displaying text. +static const char* FindTextDisplayEnd(const char* text, const char* text_end = NULL) +{ + const char* text_display_end = text; + if (!text_end) + text_end = (const char*)-1; + + ImGuiState& g = *GImGui; + if (g.DisableHideTextAfterDoubleHash > 0) + { + while (text_display_end < text_end && *text_display_end != '\0') + text_display_end++; + } + else + { + while (text_display_end < text_end && *text_display_end != '\0' && (text_display_end[0] != '#' || text_display_end[1] != '#')) + text_display_end++; + } + return text_display_end; +} + +// Pass text data straight to log (without being displayed) +void ImGui::LogText(const char* fmt, ...) +{ + ImGuiState& g = *GImGui; + if (!g.LogEnabled) + return; + + va_list args; + va_start(args, fmt); + if (g.LogFile) + { + vfprintf(g.LogFile, fmt, args); + } + else + { + g.LogClipboard->appendv(fmt, args); + } + va_end(args); +} + +// Internal version that takes a position to decide on newline placement and pad items according to their depth. +// We split text into individual lines to add current tree level padding +static void LogText(const ImVec2& ref_pos, const char* text, const char* text_end) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + + if (!text_end) + text_end = FindTextDisplayEnd(text, text_end); + + const bool log_new_line = ref_pos.y > window->DC.LogLinePosY+1; + window->DC.LogLinePosY = ref_pos.y; + + const char* text_remaining = text; + if (g.LogStartDepth > window->DC.TreeDepth) // Re-adjust padding if we have popped out of our starting depth + g.LogStartDepth = window->DC.TreeDepth; + const int tree_depth = (window->DC.TreeDepth - g.LogStartDepth); + for (;;) + { + // Split the string. Each new line (after a '\n') is followed by spacing corresponding to the current depth of our log entry. + const char* line_end = text_remaining; + while (line_end < text_end) + if (*line_end == '\n') + break; + else + line_end++; + if (line_end >= text_end) + line_end = NULL; + + const bool is_first_line = (text == text_remaining); + bool is_last_line = false; + if (line_end == NULL) + { + is_last_line = true; + line_end = text_end; + } + if (line_end != NULL && !(is_last_line && (line_end - text_remaining)==0)) + { + const int char_count = (int)(line_end - text_remaining); + if (log_new_line || !is_first_line) + ImGui::LogText(STR_NEWLINE "%*s%.*s", tree_depth*4, "", char_count, text_remaining); + else + ImGui::LogText(" %.*s", char_count, text_remaining); + } + + if (is_last_line) + break; + text_remaining = line_end + 1; + } +} + +static float CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x) +{ + if (wrap_pos_x < 0.0f) + return 0.0f; + + ImGuiWindow* window = GetCurrentWindow(); + if (wrap_pos_x == 0.0f) + wrap_pos_x = ImGui::GetContentRegionMax().x; + if (wrap_pos_x > 0.0f) + wrap_pos_x += window->Pos.x; // wrap_pos_x is provided is window local space + + const float wrap_width = wrap_pos_x > 0.0f ? ImMax(wrap_pos_x - pos.x, 0.00001f) : 0.0f; + return wrap_width; +} + +// Internal ImGui functions to render text +// RenderText***() functions calls ImDrawList::AddText() calls ImBitmapFont::RenderText() +static void RenderText(ImVec2 pos, const char* text, const char* text_end, bool hide_text_after_hash) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + + // Hide anything after a '##' string + const char* text_display_end; + if (hide_text_after_hash) + { + text_display_end = FindTextDisplayEnd(text, text_end); + } + else + { + if (!text_end) + text_end = text + strlen(text); // FIXME-OPT + text_display_end = text_end; + } + + const int text_len = (int)(text_display_end - text); + if (text_len > 0) + { + // Render + window->DrawList->AddText(g.Font, g.FontSize, pos, window->Color(ImGuiCol_Text), text, text_display_end); + + // Log as text + if (g.LogEnabled) + LogText(pos, text, text_display_end); + } +} + +static void RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + + if (!text_end) + text_end = text + strlen(text); // FIXME-OPT + + const int text_len = (int)(text_end - text); + if (text_len > 0) + { + // Render + window->DrawList->AddText(g.Font, g.FontSize, pos, window->Color(ImGuiCol_Text), text, text_end, wrap_width); + + // Log as text + if (g.LogEnabled) + LogText(pos, text, text_end); + } +} + +static void RenderTextClipped(ImVec2 pos, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& clip_max) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + + // Hide anything after a '##' string + const char* text_display_end = FindTextDisplayEnd(text, text_end); + const int text_len = (int)(text_display_end - text); + if (text_len > 0) + { + const ImVec2 text_size = text_size_if_known ? *text_size_if_known : ImGui::CalcTextSize(text, text_display_end, false, 0.0f); + + // Perform CPU side clipping for single clipped element to avoid using scissor state + const bool need_clipping = (pos.x + text_size.x >= clip_max.x) || (pos.y + text_size.y >= clip_max.y); + + // Render + window->DrawList->AddText(g.Font, g.FontSize, pos, window->Color(ImGuiCol_Text), text, text_display_end, 0.0f, need_clipping ? &clip_max : NULL); + + // Log as text + if (g.LogEnabled) + LogText(pos, text, text_display_end); + } +} + +// Render a rectangle shaped with optional rounding and borders +static void RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border, float rounding) +{ + ImGuiWindow* window = GetCurrentWindow(); + + window->DrawList->AddRectFilled(p_min, p_max, fill_col, rounding); + if (border && (window->Flags & ImGuiWindowFlags_ShowBorders)) + { + // FIXME: This is the best I've found that works on multiple renderer/back ends. Bit dodgy. + window->DrawList->AddRect(p_min+ImVec2(1.5f,1.5f), p_max+ImVec2(1,1), window->Color(ImGuiCol_BorderShadow), rounding); + window->DrawList->AddRect(p_min+ImVec2(0.5f,0.5f), p_max+ImVec2(0,0), window->Color(ImGuiCol_Border), rounding); + } +} + +// Render a triangle to denote expanded/collapsed state +static void RenderCollapseTriangle(ImVec2 p_min, bool opened, float scale, bool shadow) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + + const float h = g.FontSize * 1.00f; + const float r = h * 0.40f * scale; + ImVec2 center = p_min + ImVec2(h*0.50f, h*0.50f*scale); + + ImVec2 a, b, c; + if (opened) + { + center.y -= r*0.25f; + a = center + ImVec2(0,1)*r; + b = center + ImVec2(-0.866f,-0.5f)*r; + c = center + ImVec2(0.866f,-0.5f)*r; + } + else + { + a = center + ImVec2(1,0)*r; + b = center + ImVec2(-0.500f,0.866f)*r; + c = center + ImVec2(-0.500f,-0.866f)*r; + } + + if (shadow && (window->Flags & ImGuiWindowFlags_ShowBorders) != 0) + window->DrawList->AddTriangleFilled(a+ImVec2(2,2), b+ImVec2(2,2), c+ImVec2(2,2), window->Color(ImGuiCol_BorderShadow)); + window->DrawList->AddTriangleFilled(a, b, c, window->Color(ImGuiCol_Text)); +} + +// Calculate text size. Text can be multi-line. Optionally ignore text after a ## marker. +// CalcTextSize("") should return ImVec2(0.0f, GImGui->FontSize) +ImVec2 ImGui::CalcTextSize(const char* text, const char* text_end, bool hide_text_after_double_hash, float wrap_width) +{ + ImGuiState& g = *GImGui; + + const char* text_display_end; + if (hide_text_after_double_hash) + text_display_end = FindTextDisplayEnd(text, text_end); // Hide anything after a '##' string + else + text_display_end = text_end; + + ImFont* font = g.Font; + const float font_size = g.FontSize; + ImVec2 text_size = font->CalcTextSizeA(font_size, FLT_MAX, wrap_width, text, text_display_end, NULL); + + // Cancel out character spacing for the last character of a line (it is baked into glyph->XAdvance field) + const float font_scale = font_size / font->FontSize; + const float character_spacing_x = 1.0f * font_scale; + if (text_size.x > 0.0f) + text_size.x -= character_spacing_x; + + return text_size; +} + +// Helper to calculate coarse clipping of large list of evenly sized items. +// If you are displaying thousands of items and you have a random access to the list, you can perform clipping yourself to save on CPU. +// { +// float item_height = ImGui::GetTextLineHeightWithSpacing(); +// int display_start, display_end; +// ImGui::CalcListClipping(count, item_height, &display_start, &display_end); // calculate how many to clip/display +// ImGui::SetCursorPosY(ImGui::GetCursorPosY() + (display_start) * item_height); // advance cursor +// for (int i = display_start; i < display_end; i++) // display only visible items +// // TODO: display visible item +// ImGui::SetCursorPosY(ImGui::GetCursorPosY() + (count - display_end) * item_height); // advance cursor +// } +void ImGui::CalcListClipping(int items_count, float items_height, int* out_items_display_start, int* out_items_display_end) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + + if (g.LogEnabled) + { + // If logging is active, do not perform any clipping + *out_items_display_start = 0; + *out_items_display_end = items_count; + return; + } + + const ImVec2 pos = window->DC.CursorPos; + const ImVec4 clip_rect = window->ClipRectStack.back(); + const float clip_y1 = clip_rect.y; + const float clip_y2 = clip_rect.w; + + int start = (int)((clip_y1 - pos.y) / items_height); + int end = (int)((clip_y2 - pos.y) / items_height); + start = ImClamp(start, 0, items_count); + end = ImClamp(end + 1, start, items_count); + + *out_items_display_start = start; + *out_items_display_end = end; +} + +// Find window given position, search front-to-back +static ImGuiWindow* FindHoveredWindow(ImVec2 pos, bool excluding_childs) +{ + ImGuiState& g = *GImGui; + for (int i = (int)g.Windows.size()-1; i >= 0; i--) + { + ImGuiWindow* window = g.Windows[(size_t)i]; + if (!window->Visible) + continue; + if (excluding_childs && (window->Flags & ImGuiWindowFlags_ChildWindow) != 0) + continue; + + // Using the clipped AABB so a child window will typically be clipped by its parent. + ImRect bb(window->ClippedRect.Min - g.Style.TouchExtraPadding, window->ClippedRect.Max + g.Style.TouchExtraPadding); + if (bb.Contains(pos)) + return window; + } + return NULL; +} + +// Test if mouse cursor is hovering given rectangle +// NB- Rectangle is clipped by our current clip setting +// NB- Expand the rectangle to be generous on imprecise inputs systems (g.Style.TouchExtraPadding) +static bool IsMouseHoveringRect(const ImRect& rect) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + + // Clip + ImRect rect_clipped = rect; + if (!window->ClipRectStack.empty()) + { + const ImVec4 clip_rect = window->ClipRectStack.back(); + rect_clipped.Clip(ImRect(ImVec2(clip_rect.x, clip_rect.y), ImVec2(clip_rect.z, clip_rect.w))); + } + + // Expand for touch input + const ImRect rect_for_touch(rect_clipped.Min - g.Style.TouchExtraPadding, rect_clipped.Max + g.Style.TouchExtraPadding); + return rect_for_touch.Contains(g.IO.MousePos); +} + +bool ImGui::IsMouseHoveringRect(const ImVec2& rect_min, const ImVec2& rect_max) +{ + return IsMouseHoveringRect(ImRect(rect_min, rect_max)); +} + +bool ImGui::IsMouseHoveringWindow() +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + return g.HoveredWindow == window; +} + +bool ImGui::IsMouseHoveringAnyWindow() +{ + ImGuiState& g = *GImGui; + return g.HoveredWindow != NULL; +} + +bool ImGui::IsPosHoveringAnyWindow(const ImVec2& pos) +{ + return FindHoveredWindow(pos, false) != NULL; +} + +static bool IsKeyPressedMap(ImGuiKey key, bool repeat) +{ + ImGuiState& g = *GImGui; + const int key_index = g.IO.KeyMap[key]; + return ImGui::IsKeyPressed(key_index, repeat); +} + +bool ImGui::IsKeyPressed(int key_index, bool repeat) +{ + ImGuiState& g = *GImGui; + IM_ASSERT(key_index >= 0 && key_index < IM_ARRAYSIZE(g.IO.KeysDown)); + const float t = g.IO.KeysDownTime[key_index]; + if (t == 0.0f) + return true; + + // FIXME: Repeat rate should be provided elsewhere? + const float KEY_REPEAT_DELAY = 0.250f; + const float KEY_REPEAT_RATE = 0.020f; + if (repeat && t > KEY_REPEAT_DELAY) + if ((fmodf(t - KEY_REPEAT_DELAY, KEY_REPEAT_RATE) > KEY_REPEAT_RATE*0.5f) != (fmodf(t - KEY_REPEAT_DELAY - g.IO.DeltaTime, KEY_REPEAT_RATE) > KEY_REPEAT_RATE*0.5f)) + return true; + + return false; +} + +bool ImGui::IsMouseClicked(int button, bool repeat) +{ + ImGuiState& g = *GImGui; + IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); + const float t = g.IO.MouseDownTime[button]; + if (t == 0.0f) + return true; + + // FIXME: Repeat rate should be provided elsewhere? + const float MOUSE_REPEAT_DELAY = 0.250f; + const float MOUSE_REPEAT_RATE = 0.020f; + if (repeat && t > MOUSE_REPEAT_DELAY) + if ((fmodf(t - MOUSE_REPEAT_DELAY, MOUSE_REPEAT_RATE) > MOUSE_REPEAT_RATE*0.5f) != (fmodf(t - MOUSE_REPEAT_DELAY - g.IO.DeltaTime, MOUSE_REPEAT_RATE) > MOUSE_REPEAT_RATE*0.5f)) + return true; + + return false; +} + +bool ImGui::IsMouseDoubleClicked(int button) +{ + ImGuiState& g = *GImGui; + IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); + return g.IO.MouseDoubleClicked[button]; +} + +bool ImGui::IsMouseDragging(int button, float lock_threshold) +{ + ImGuiState& g = *GImGui; + IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); + if (lock_threshold < 0.0f) + lock_threshold = g.IO.MouseDragThreshold; + return g.IO.MouseDragMaxDistanceSqr[button] >= lock_threshold * lock_threshold; +} + +ImVec2 ImGui::GetMousePos() +{ + return GImGui->IO.MousePos; +} + +ImVec2 ImGui::GetMouseDragDelta(int button, float lock_threshold) +{ + ImGuiState& g = *GImGui; + IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); + if (lock_threshold < 0.0f) + lock_threshold = g.IO.MouseDragThreshold; + if (g.IO.MouseDown[button]) + if (g.IO.MouseDragMaxDistanceSqr[button] >= lock_threshold * lock_threshold) + return g.IO.MousePos - g.IO.MouseClickedPos[button]; // Assume we can only get active with left-mouse button (at the moment). + return ImVec2(0.0f, 0.0f); +} + +void ImGui::ResetMouseDragDelta(int button) +{ + ImGuiState& g = *GImGui; + IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); + // NB: We don't need to reset g.IO.MouseDragMaxDistanceSqr + g.IO.MouseClickedPos[button] = g.IO.MousePos; +} + +ImGuiMouseCursor ImGui::GetMouseCursor() +{ + return GImGui->MouseCursor; +} + +void ImGui::SetMouseCursor(ImGuiMouseCursor cursor_type) +{ + GImGui->MouseCursor = cursor_type; +} + +bool ImGui::IsItemHovered() +{ + ImGuiWindow* window = GetCurrentWindow(); + return window->DC.LastItemHoveredAndUsable; +} + +bool ImGui::IsItemHoveredRect() +{ + ImGuiWindow* window = GetCurrentWindow(); + return window->DC.LastItemHoveredRect; +} + +bool ImGui::IsItemActive() +{ + ImGuiState& g = *GImGui; + if (g.ActiveId) + { + ImGuiWindow* window = GetCurrentWindow(); + return g.ActiveId == window->DC.LastItemID; + } + return false; +} + +bool ImGui::IsAnyItemActive() +{ + ImGuiState& g = *GImGui; + return g.ActiveId != 0; +} + +bool ImGui::IsItemVisible() +{ + ImGuiWindow* window = GetCurrentWindow(); + ImRect r(window->ClipRectStack.back()); + return r.Overlaps(window->DC.LastItemRect); +} + +ImVec2 ImGui::GetItemRectMin() +{ + ImGuiWindow* window = GetCurrentWindow(); + return window->DC.LastItemRect.Min; +} + +ImVec2 ImGui::GetItemRectMax() +{ + ImGuiWindow* window = GetCurrentWindow(); + return window->DC.LastItemRect.Max; +} + +ImVec2 ImGui::GetItemRectSize() +{ + ImGuiWindow* window = GetCurrentWindow(); + return window->DC.LastItemRect.GetSize(); +} + +ImVec2 ImGui::CalcItemRectClosestPoint(const ImVec2& pos, bool on_edge, float outward) +{ + ImGuiWindow* window = GetCurrentWindow(); + ImRect rect = window->DC.LastItemRect; + rect.Expand(outward); + return rect.GetClosestPoint(pos, on_edge); +} + +// Tooltip is stored and turned into a BeginTooltip()/EndTooltip() sequence at the end of the frame. Each call override previous value. +void ImGui::SetTooltipV(const char* fmt, va_list args) +{ + ImGuiState& g = *GImGui; + ImFormatStringV(g.Tooltip, IM_ARRAYSIZE(g.Tooltip), fmt, args); +} + +void ImGui::SetTooltip(const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + SetTooltipV(fmt, args); + va_end(args); +} + +float ImGui::GetTime() +{ + return GImGui->Time; +} + +int ImGui::GetFrameCount() +{ + return GImGui->FrameCount; +} + +void ImGui::BeginTooltip() +{ + ImGuiState& g = *GImGui; + ImGuiWindowFlags flags = ImGuiWindowFlags_Tooltip|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_AlwaysAutoResize; + ImGui::Begin("##Tooltip", NULL, ImVec2(0,0), g.Style.Colors[ImGuiCol_TooltipBg].w, flags); +} + +void ImGui::EndTooltip() +{ + IM_ASSERT(GetCurrentWindow()->Flags & ImGuiWindowFlags_Tooltip); + ImGui::End(); +} + +void ImGui::BeginPopup(bool* p_opened) +{ + IM_ASSERT(p_opened != NULL); // Must provide a bool at the moment + + ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); + ImGuiWindowFlags flags = ImGuiWindowFlags_Popup|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_AlwaysAutoResize; + ImGui::Begin("##Popup", p_opened, flags); +} + +void ImGui::EndPopup() +{ + IM_ASSERT(GetCurrentWindow()->Flags & ImGuiWindowFlags_Popup); + ImGui::End(); + ImGui::PopStyleVar(); +} + +bool ImGui::BeginChild(const char* str_id, const ImVec2& size_arg, bool border, ImGuiWindowFlags extra_flags) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + + ImGuiWindowFlags flags = ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_ChildWindow; + + const ImVec2 content_max = window->Pos + ImGui::GetContentRegionMax(); + const ImVec2 cursor_pos = window->Pos + ImGui::GetCursorPos(); + ImVec2 size = size_arg; + if (size.x <= 0.0f) + { + if (size.x == 0.0f) + flags |= ImGuiWindowFlags_ChildWindowAutoFitX; + size.x = ImMax(content_max.x - cursor_pos.x, g.Style.WindowMinSize.x) - fabsf(size.x); + } + if (size.y <= 0.0f) + { + if (size.y == 0.0f) + flags |= ImGuiWindowFlags_ChildWindowAutoFitY; + size.y = ImMax(content_max.y - cursor_pos.y, g.Style.WindowMinSize.y) - fabsf(size.y); + } + if (border) + flags |= ImGuiWindowFlags_ShowBorders; + flags |= extra_flags; + + char title[256]; + ImFormatString(title, IM_ARRAYSIZE(title), "%s.%s", window->Name, str_id); + + const float alpha = 1.0f; + bool ret = ImGui::Begin(title, NULL, size, alpha, flags); + + if (!(window->Flags & ImGuiWindowFlags_ShowBorders)) + g.CurrentWindow->Flags &= ~ImGuiWindowFlags_ShowBorders; + + return ret; +} + +bool ImGui::BeginChild(ImGuiID id, const ImVec2& size, bool border, ImGuiWindowFlags extra_flags) +{ + char str_id[32]; + ImFormatString(str_id, IM_ARRAYSIZE(str_id), "child_%x", id); + bool ret = ImGui::BeginChild(str_id, size, border, extra_flags); + return ret; +} + +void ImGui::EndChild() +{ + ImGuiWindow* window = GetCurrentWindow(); + + IM_ASSERT(window->Flags & ImGuiWindowFlags_ChildWindow); + if (window->Flags & ImGuiWindowFlags_ComboBox) + { + ImGui::End(); + } + else + { + // When using auto-filling child window, we don't provide full width/height to ItemSize so that it doesn't feed back into automatic size-fitting. + ImGuiState& g = *GImGui; + ImVec2 sz = ImGui::GetWindowSize(); + if (window->Flags & ImGuiWindowFlags_ChildWindowAutoFitX) + sz.x = ImMax(g.Style.WindowMinSize.x, sz.x - g.Style.AutoFitPadding.x); + if (window->Flags & ImGuiWindowFlags_ChildWindowAutoFitY) + sz.y = ImMax(g.Style.WindowMinSize.y, sz.y - g.Style.AutoFitPadding.y); + + ImGui::End(); + + window = GetCurrentWindow(); + ImRect bb(window->DC.CursorPos, window->DC.CursorPos + sz); + ItemSize(sz); + ItemAdd(bb, NULL); + } +} + +// Helper to create a child window / scrolling region that looks like a normal widget frame. +void ImGui::BeginChildFrame(ImGuiID id, const ImVec2& size) +{ + ImGuiState& g = *GImGui; + const ImGuiStyle& style = g.Style; + ImGui::PushStyleColor(ImGuiCol_ChildWindowBg, style.Colors[ImGuiCol_FrameBg]); + ImGui::PushStyleVar(ImGuiStyleVar_ChildWindowRounding, style.FrameRounding); + ImGui::BeginChild(id, size); +} + +void ImGui::EndChildFrame() +{ + ImGui::EndChild(); + ImGui::PopStyleVar(); + ImGui::PopStyleColor(); +} + +static ImGuiWindow* FindWindowByName(const char* name) +{ + // FIXME-OPT: Store sorted hashes -> pointers. + ImGuiState& g = *GImGui; + ImGuiID id = ImHash(name, 0); + for (size_t i = 0; i < g.Windows.size(); i++) + if (g.Windows[i]->ID == id) + return g.Windows[i]; + return NULL; +} + +static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFlags flags) +{ + ImGuiState& g = *GImGui; + + // Create window the first time + ImGuiWindow* window = (ImGuiWindow*)ImGui::MemAlloc(sizeof(ImGuiWindow)); + new(window) ImGuiWindow(name); + window->Flags = flags; + + if (flags & ImGuiWindowFlags_NoSavedSettings) + { + // User can disable loading and saving of settings. Tooltip and child windows also don't store settings. + window->Size = window->SizeFull = size; + } + else + { + // Retrieve settings from .ini file + // Use SetWindowPos() or SetNextWindowPos() with the appropriate condition flag to change the initial position of a window. + window->PosFloat = ImVec2(60, 60); + window->Pos = ImVec2((float)(int)window->PosFloat.x, (float)(int)window->PosFloat.y); + + ImGuiIniData* settings = FindWindowSettings(name); + if (!settings) + { + settings = AddWindowSettings(name); + } + else + { + window->SetWindowPosAllowFlags &= ~ImGuiSetCond_FirstUseEver; + window->SetWindowSizeAllowFlags &= ~ImGuiSetCond_FirstUseEver; + window->SetWindowCollapsedAllowFlags &= ~ImGuiSetCond_FirstUseEver; + } + + if (settings->Pos.x != FLT_MAX) + { + window->PosFloat = settings->Pos; + window->Pos = ImVec2((float)(int)window->PosFloat.x, (float)(int)window->PosFloat.y); + window->Collapsed = settings->Collapsed; + } + + if (ImLengthSqr(settings->Size) > 0.00001f && !(flags & ImGuiWindowFlags_NoResize)) + size = settings->Size; + window->Size = window->SizeFull = size; + } + + if ((flags & ImGuiWindowFlags_AlwaysAutoResize) != 0) + { + window->AutoFitFrames = 2; + window->AutoFitOnlyGrows = false; + } + else if (ImLengthSqr(window->Size) < 0.00001f) + { + window->AutoFitFrames = 2; + window->AutoFitOnlyGrows = true; + } + + g.Windows.push_back(window); + return window; +} + +// Push a new ImGui window to add widgets to. +// - 'size' for a regular window denote the initial size for first-time creation (no saved data) and isn't that useful. Use SetNextWindowSize() prior to calling Begin() for more flexible window manipulation. +// - A default window called "Debug" is automatically stacked at the beginning of every frame so you can use widgets without explicitly calling a Begin/End pair. +// - Begin/End can be called multiple times during the frame with the same window name to append content. +// - The window name is used as a unique identifier to preserve window information across frames (and save rudimentary information to the .ini file). +// You can use the "##" or "###" markers to use the same label with different id, or same id with different label. See documentation at the top of this file. +// - Return false when window is collapsed, so you can early out in your code. You always need to call ImGui::End() even if false is returned. +// - Passing 'bool* p_opened' displays a Close button on the upper-right corner of the window, the pointed value will be set to false when the button is pressed. +// - Passing non-zero 'size' is roughly equivalent to calling SetNextWindowSize(size, ImGuiSetCond_FirstUseEver) prior to calling Begin(). +bool ImGui::Begin(const char* name, bool* p_opened, ImGuiWindowFlags flags) +{ + return ImGui::Begin(name, p_opened, ImVec2(0.f, 0.f), -1.0f, flags); +} + +bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_use, float bg_alpha, ImGuiWindowFlags flags) +{ + ImGuiState& g = *GImGui; + const ImGuiStyle& style = g.Style; + IM_ASSERT(g.Initialized); // Forgot to call ImGui::NewFrame() + IM_ASSERT(name != NULL); // Must pass a name + + // Find or create + bool window_is_new = false; + ImGuiWindow* window = FindWindowByName(name); + if (!window) + { + window = CreateNewWindow(name, size_on_first_use, flags); + window_is_new = true; + } + window->Flags = (ImGuiWindowFlags)flags; + + // Add to stack + g.CurrentWindowStack.push_back(window); + SetCurrentWindow(window); + + // Process SetNextWindow***() calls + bool window_pos_set_by_api = false; + if (g.SetNextWindowPosCond) + { + const ImVec2 backup_cursor_pos = window->DC.CursorPos; // FIXME: not sure of the exact reason of this anymore :( need to look into that. + ImGui::SetWindowPos(g.SetNextWindowPosVal, g.SetNextWindowPosCond); + window->DC.CursorPos = backup_cursor_pos; + window_pos_set_by_api = true; + g.SetNextWindowPosCond = 0; + } + if (g.SetNextWindowSizeCond) + { + ImGui::SetWindowSize(g.SetNextWindowSizeVal, g.SetNextWindowSizeCond); + g.SetNextWindowSizeCond = 0; + } + if (g.SetNextWindowCollapsedCond) + { + ImGui::SetWindowCollapsed(g.SetNextWindowCollapsedVal, g.SetNextWindowCollapsedCond); + g.SetNextWindowCollapsedCond = 0; + } + if (g.SetNextWindowFocus) + { + ImGui::SetWindowFocus(); + g.SetNextWindowFocus = false; + } + + // Find parent + ImGuiWindow* parent_window = (flags & ImGuiWindowFlags_ChildWindow) != 0 ? g.CurrentWindowStack[g.CurrentWindowStack.size()-2] : NULL; + + // Update known root window (if we are a child window, otherwise window == window->RootWindow) + size_t root_idx = g.CurrentWindowStack.size() - 1; + while (root_idx > 0) + { + if ((g.CurrentWindowStack[root_idx]->Flags & ImGuiWindowFlags_ChildWindow) == 0) + break; + root_idx--; + } + window->RootWindow = g.CurrentWindowStack[root_idx]; + + // Default alpha + if (bg_alpha < 0.0f) + bg_alpha = style.WindowFillAlphaDefault; + + // When reusing window again multiple times a frame, just append content (don't need to setup again) + const int current_frame = ImGui::GetFrameCount(); + const bool first_begin_of_the_frame = (window->LastFrameDrawn != current_frame); + if (first_begin_of_the_frame) + { + window->DrawList->Clear(); + window->Visible = true; + + // New windows appears in front + if (!(flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Tooltip)) + { + if (window->LastFrameDrawn < current_frame - 1) + { + FocusWindow(window); + + // Popup position themselves when they first appear + if (flags & ImGuiWindowFlags_Popup) + { + if (!window_pos_set_by_api) + window->PosFloat = g.IO.MousePos; + } + } + } + + window->LastFrameDrawn = current_frame; + window->ClipRectStack.resize(0); + + // Reset contents size for auto-fitting + window->SizeContents = window_is_new ? ImVec2(0.0f, 0.0f) : window->DC.CursorMaxPos - window->Pos; + window->SizeContents.y += window->ScrollY; + + if (flags & ImGuiWindowFlags_ChildWindow) + { + parent_window->DC.ChildWindows.push_back(window); + window->Pos = window->PosFloat = parent_window->DC.CursorPos; + window->SizeFull = size_on_first_use; + } + } + + // Setup texture + window->DrawList->PushTextureID(g.Font->ContainerAtlas->TexID); + + // Setup outer clipping rectangle + if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_ComboBox)) + PushClipRect(parent_window->ClipRectStack.back()); + else if (g.IO.DisplayVisibleMin.x != g.IO.DisplayVisibleMax.x && g.IO.DisplayVisibleMin.y != g.IO.DisplayVisibleMax.y) + PushClipRect(ImVec4(g.IO.DisplayVisibleMin.x, g.IO.DisplayVisibleMin.y, g.IO.DisplayVisibleMax.x, g.IO.DisplayVisibleMax.y)); + else + PushClipRect(ImVec4(0.0f, 0.0f, g.IO.DisplaySize.x, g.IO.DisplaySize.y)); + + // Setup and draw window + if (first_begin_of_the_frame) + { + // Reset ID stack + window->IDStack.resize(1); + + // Move window (at the beginning of the frame to avoid input lag or sheering). Only valid for root windows. + RegisterAliveId(window->MoveID); + if (g.ActiveId == window->MoveID) + { + if (g.IO.MouseDown[0]) + { + if (!(window->Flags & ImGuiWindowFlags_NoMove)) + { + window->PosFloat += g.IO.MouseDelta; + if (!(window->Flags & ImGuiWindowFlags_NoSavedSettings)) + MarkSettingsDirty(); + } + IM_ASSERT(g.MovedWindow != NULL); + FocusWindow(g.MovedWindow); + } + else + { + SetActiveId(0); + g.MovedWindow = NULL; // Not strictly necessary but doing it for sanity. + } + } + + // Tooltips always follows mouse + if (!window_pos_set_by_api && (window->Flags & ImGuiWindowFlags_Tooltip) != 0) + { + window->PosFloat = g.IO.MousePos + ImVec2(32,16) - style.FramePadding*2; + } + + // Clamp into view + if (!(window->Flags & ImGuiWindowFlags_ChildWindow) && !(window->Flags & ImGuiWindowFlags_Tooltip)) + { + if (window->AutoFitFrames <= 0 && g.IO.DisplaySize.x > 0.0f && g.IO.DisplaySize.y > 0.0f) // Ignore zero-sized display explicitly to avoid losing positions if a window manager reports zero-sized window when initializing or minimizing. + { + ImVec2 clip_min = style.DisplaySafeAreaPadding; + ImVec2 clip_max = g.IO.DisplaySize - style.DisplaySafeAreaPadding; + window->PosFloat = ImMax(window->PosFloat + window->Size, clip_min) - window->Size; + window->PosFloat = ImMin(window->PosFloat, clip_max); + } + window->SizeFull = ImMax(window->SizeFull, style.WindowMinSize); + } + window->Pos = ImVec2((float)(int)window->PosFloat.x, (float)(int)window->PosFloat.y); + + // Default item width. Make it proportional to window size if window manually resizes + if (window->Size.x > 0.0f && !(window->Flags & ImGuiWindowFlags_Tooltip) && !(window->Flags & ImGuiWindowFlags_AlwaysAutoResize)) + window->ItemWidthDefault = (float)(int)(window->Size.x * 0.65f); + else + window->ItemWidthDefault = 200.0f; + + // Prepare for focus requests + if (window->FocusIdxAllRequestNext == IM_INT_MAX || window->FocusIdxAllCounter == -1) + window->FocusIdxAllRequestCurrent = IM_INT_MAX; + else + window->FocusIdxAllRequestCurrent = (window->FocusIdxAllRequestNext + (window->FocusIdxAllCounter+1)) % (window->FocusIdxAllCounter+1); + if (window->FocusIdxTabRequestNext == IM_INT_MAX || window->FocusIdxTabCounter == -1) + window->FocusIdxTabRequestCurrent = IM_INT_MAX; + else + window->FocusIdxTabRequestCurrent = (window->FocusIdxTabRequestNext + (window->FocusIdxTabCounter+1)) % (window->FocusIdxTabCounter+1); + window->FocusIdxAllCounter = window->FocusIdxTabCounter = -1; + window->FocusIdxAllRequestNext = window->FocusIdxTabRequestNext = IM_INT_MAX; + + ImRect title_bar_rect = window->TitleBarRect(); + + // Apply and ImClamp scrolling + window->ScrollY = window->NextScrollY; + window->ScrollY = ImMax(window->ScrollY, 0.0f); + if (!window->Collapsed && !window->SkipItems) + window->ScrollY = ImMin(window->ScrollY, ImMax(0.0f, window->SizeContents.y - window->SizeFull.y)); + window->NextScrollY = window->ScrollY; + + // At this point we don't have a clipping rectangle setup yet, so we can test and draw in title bar + // Collapse window by double-clicking on title bar + if (!(window->Flags & ImGuiWindowFlags_NoTitleBar)) + { + if (!(window->Flags & ImGuiWindowFlags_NoCollapse) && g.HoveredWindow == window && IsMouseHoveringRect(title_bar_rect) && g.IO.MouseDoubleClicked[0]) + { + window->Collapsed = !window->Collapsed; + if (!(window->Flags & ImGuiWindowFlags_NoSavedSettings)) + MarkSettingsDirty(); + FocusWindow(window); + } + } + else + { + window->Collapsed = false; + } + + // Calculate auto-fit size + ImVec2 size_auto_fit; + if ((window->Flags & ImGuiWindowFlags_Tooltip) != 0) + { + // Tooltip always resize. We keep the spacing symmetric on both axises for aesthetic purpose. + size_auto_fit = window->SizeContents + style.WindowPadding - ImVec2(0.0f, style.ItemSpacing.y); + } + else + { + size_auto_fit = ImClamp(window->SizeContents + style.AutoFitPadding, style.WindowMinSize, ImMax(style.WindowMinSize, g.IO.DisplaySize - style.AutoFitPadding)); + if (size_auto_fit.y < window->SizeContents.y + style.AutoFitPadding.y) + size_auto_fit.x += style.ScrollbarWidth; + } + + const float window_rounding = (window->Flags & ImGuiWindowFlags_ChildWindow) ? style.ChildWindowRounding : style.WindowRounding; + if (window->Collapsed) + { + // We still process initial auto-fit on collapsed windows to get a window width + // But otherwise we don't honor ImGuiWindowFlags_AlwaysAutoResize when collapsed. + if (window->AutoFitFrames > 0) + { + window->SizeFull = window->AutoFitOnlyGrows ? ImMax(window->SizeFull, size_auto_fit) : size_auto_fit; + title_bar_rect = window->TitleBarRect(); + } + + // Draw title bar only + window->Size = title_bar_rect.GetSize(); + window->DrawList->AddRectFilled(title_bar_rect.GetTL(), title_bar_rect.GetBR(), window->Color(ImGuiCol_TitleBgCollapsed), window_rounding); + if (window->Flags & ImGuiWindowFlags_ShowBorders) + { + window->DrawList->AddRect(title_bar_rect.GetTL()+ImVec2(1,1), title_bar_rect.GetBR()+ImVec2(1,1), window->Color(ImGuiCol_BorderShadow), window_rounding); + window->DrawList->AddRect(title_bar_rect.GetTL(), title_bar_rect.GetBR(), window->Color(ImGuiCol_Border), window_rounding); + } + } + else + { + ImU32 resize_col = 0; + if ((window->Flags & ImGuiWindowFlags_Tooltip) != 0) + { + window->Size = window->SizeFull = size_auto_fit; + } + else + { + if ((window->Flags & ImGuiWindowFlags_AlwaysAutoResize) != 0) + { + // Don't continuously mark settings as dirty, the size of the window doesn't need to be stored. + window->SizeFull = size_auto_fit; + } + else if (window->AutoFitFrames > 0) + { + // Auto-fit only grows during the first few frames + window->SizeFull = window->AutoFitOnlyGrows ? ImMax(window->SizeFull, size_auto_fit) : size_auto_fit; + if (!(window->Flags & ImGuiWindowFlags_NoSavedSettings)) + MarkSettingsDirty(); + } + else if (!(window->Flags & ImGuiWindowFlags_NoResize)) + { + // Manual resize grip + const ImRect resize_rect(window->Rect().GetBR()-ImVec2(14,14), window->Rect().GetBR()); + const ImGuiID resize_id = window->GetID("#RESIZE"); + bool hovered, held; + ButtonBehavior(resize_rect, resize_id, &hovered, &held, true); + resize_col = window->Color(held ? ImGuiCol_ResizeGripActive : hovered ? ImGuiCol_ResizeGripHovered : ImGuiCol_ResizeGrip); + + if (hovered || held) + g.MouseCursor = ImGuiMouseCursor_ResizeNWSE; + + if (g.HoveredWindow == window && held && g.IO.MouseDoubleClicked[0]) + { + // Manual auto-fit when double-clicking + window->SizeFull = size_auto_fit; + if (!(window->Flags & ImGuiWindowFlags_NoSavedSettings)) + MarkSettingsDirty(); + SetActiveId(0); + } + else if (held) + { + // Resize + window->SizeFull = ImMax(window->SizeFull + g.IO.MouseDelta, style.WindowMinSize); + if (!(window->Flags & ImGuiWindowFlags_NoSavedSettings)) + MarkSettingsDirty(); + } + } + + // Update rectangle immediately so that rendering right below us isn't one frame late + window->Size = window->SizeFull; + title_bar_rect = window->TitleBarRect(); + } + + // Scrollbar + window->ScrollbarY = (window->SizeContents.y > window->Size.y) && !(window->Flags & ImGuiWindowFlags_NoScrollbar); + + // Window background + if (bg_alpha > 0.0f) + { + if ((window->Flags & ImGuiWindowFlags_ComboBox) != 0) + window->DrawList->AddRectFilled(window->Pos, window->Pos+window->Size, window->Color(ImGuiCol_ComboBg, bg_alpha), window_rounding); + else if ((window->Flags & ImGuiWindowFlags_Tooltip) != 0) + window->DrawList->AddRectFilled(window->Pos, window->Pos+window->Size, window->Color(ImGuiCol_TooltipBg, bg_alpha), window_rounding); + else if ((window->Flags & ImGuiWindowFlags_ChildWindow) != 0) + window->DrawList->AddRectFilled(window->Pos, window->Pos+window->Size-ImVec2(window->ScrollbarY?style.ScrollbarWidth:0.0f,0.0f), window->Color(ImGuiCol_ChildWindowBg, bg_alpha), window_rounding, window->ScrollbarY ? (1|8) : (0xF)); + else + window->DrawList->AddRectFilled(window->Pos, window->Pos+window->Size, window->Color(ImGuiCol_WindowBg, bg_alpha), window_rounding); + } + + // Title bar + if (!(window->Flags & ImGuiWindowFlags_NoTitleBar)) + window->DrawList->AddRectFilled(title_bar_rect.GetTL(), title_bar_rect.GetBR(), window->Color(ImGuiCol_TitleBg), window_rounding, 1|2); + + // Borders + if (window->Flags & ImGuiWindowFlags_ShowBorders) + { + window->DrawList->AddRect(window->Pos+ImVec2(1,1), window->Pos+window->Size+ImVec2(1,1), window->Color(ImGuiCol_BorderShadow), window_rounding); + window->DrawList->AddRect(window->Pos, window->Pos+window->Size, window->Color(ImGuiCol_Border), window_rounding); + if (!(window->Flags & ImGuiWindowFlags_NoTitleBar)) + window->DrawList->AddLine(title_bar_rect.GetBL(), title_bar_rect.GetBR(), window->Color(ImGuiCol_Border)); + } + + // Scrollbar + if (window->ScrollbarY) + Scrollbar(window); + + // Render resize grip + // (after the input handling so we don't have a frame of latency) + if (!(window->Flags & ImGuiWindowFlags_NoResize)) + { + const float r = window_rounding; + const ImVec2 br = window->Rect().GetBR(); + if (r == 0.0f) + { + window->DrawList->AddTriangleFilled(br, br-ImVec2(0,14), br-ImVec2(14,0), resize_col); + } + else + { + // FIXME: We should draw 4 triangles and decide on a size that's not dependent on the rounding size (previously used 18) + window->DrawList->AddArcFast(br - ImVec2(r,r), r, resize_col, 6, 9, true); + window->DrawList->AddTriangleFilled(br+ImVec2(0,-2*r),br+ImVec2(0,-r),br+ImVec2(-r,-r), resize_col); + window->DrawList->AddTriangleFilled(br+ImVec2(-r,-r), br+ImVec2(-r,0),br+ImVec2(-2*r,0), resize_col); + } + } + } + + // Setup drawing context + window->DC.ColumnsStartX = window->WindowPadding().x; + window->DC.ColumnsOffsetX = 0.0f; + window->DC.CursorStartPos = window->Pos + ImVec2(window->DC.ColumnsStartX + window->DC.ColumnsOffsetX, window->TitleBarHeight() + window->WindowPadding().y) - ImVec2(0.0f, window->ScrollY); + window->DC.CursorPos = window->DC.CursorStartPos; + window->DC.CursorPosPrevLine = window->DC.CursorPos; + window->DC.CursorMaxPos = window->DC.CursorStartPos; + window->DC.CurrentLineHeight = window->DC.PrevLineHeight = 0.0f; + window->DC.CurrentLineTextBaseOffset = window->DC.PrevLineTextBaseOffset = 0.0f; + window->DC.LogLinePosY = window->DC.CursorPos.y - 9999.0f; + window->DC.ChildWindows.resize(0); + window->DC.ItemWidth.resize(0); + window->DC.ItemWidth.push_back(window->ItemWidthDefault); + window->DC.AllowKeyboardFocus.resize(0); + window->DC.AllowKeyboardFocus.push_back(true); + window->DC.TextWrapPos.resize(0); + window->DC.TextWrapPos.push_back(-1.0f); // disabled + window->DC.ColorEditMode = ImGuiColorEditMode_UserSelect; + window->DC.ColumnsCurrent = 0; + window->DC.ColumnsCount = 1; + window->DC.ColumnsStartPos = window->DC.CursorPos; + window->DC.ColumnsCellMinY = window->DC.ColumnsCellMaxY = window->DC.ColumnsStartPos.y; + window->DC.TreeDepth = 0; + window->DC.StateStorage = &window->StateStorage; + window->DC.GroupStack.resize(0); + + if (window->AutoFitFrames > 0) + window->AutoFitFrames--; + + // Title bar + if (!(window->Flags & ImGuiWindowFlags_NoTitleBar)) + { + if (p_opened != NULL) + CloseWindowButton(p_opened); + + ImVec2 text_min = window->Pos + style.FramePadding; + if (!(window->Flags & ImGuiWindowFlags_NoCollapse)) + { + RenderCollapseTriangle(window->Pos + style.FramePadding, !window->Collapsed, 1.0f, true); + text_min.x += g.FontSize + style.ItemInnerSpacing.x; + } + + const ImVec2 text_size = CalcTextSize(name, NULL, true); + const ImVec2 text_max = window->Pos + ImVec2(window->Size.x - (p_opened ? (title_bar_rect.GetHeight()-3) : style.FramePadding.x), style.FramePadding.y*2 + text_size.y); + RenderTextClipped(text_min, name, NULL, &text_size, text_max); + } + if (window->Flags & ImGuiWindowFlags_Popup) + { + if (p_opened) + { + if (g.IO.MouseClicked[0] && (!g.HoveredWindow || g.HoveredWindow->RootWindow != window)) + *p_opened = false; + else if (!g.FocusedWindow) + *p_opened = false; + else if (g.FocusedWindow->RootWindow != window)// && !(g.FocusedWindow->RootWindow->Flags & ImGuiWindowFlags_Tooltip)) + *p_opened = false; + } + } + + // Save clipped aabb so we can access it in constant-time in FindHoveredWindow() + window->ClippedRect = window->Rect(); + window->ClippedRect.Clip(window->ClipRectStack.front()); + + // Pressing CTRL+C while holding on a window copy its content to the clipboard + // This works but 1. doesn't handle multiple Begin/End pairs, 2. recursing into another Begin/End pair - so we need to work that out and add better logging scope. + // Maybe we can support CTRL+C on every element? + /* + if (g.ActiveId == move_id) + if (g.IO.KeyCtrl && IsKeyPressedMap(ImGuiKey_C)) + ImGui::LogToClipboard(); + */ + } + + // Inner clipping rectangle + // We set this up after processing the resize grip so that our clip rectangle doesn't lag by a frame + // Note that if our window is collapsed we will end up with a null clipping rectangle which is the correct behavior. + const ImRect title_bar_rect = window->TitleBarRect(); + ImVec4 clip_rect(title_bar_rect.Min.x+0.5f+window->WindowPadding().x*0.5f, title_bar_rect.Max.y+0.5f, window->Rect().Max.x+0.5f-window->WindowPadding().x*0.5f, window->Rect().Max.y-1.5f); + if (window->ScrollbarY) + clip_rect.z -= style.ScrollbarWidth; + PushClipRect(clip_rect); + + // Clear 'accessed' flag last thing + if (first_begin_of_the_frame) + window->Accessed = false; + + // Child window can be out of sight and have "negative" clip windows. + // Mark them as collapsed so commands are skipped earlier (we can't manually collapse because they have no title bar). + if (flags & ImGuiWindowFlags_ChildWindow) + { + IM_ASSERT((flags & ImGuiWindowFlags_NoTitleBar) != 0); + window->Collapsed = parent_window && parent_window->Collapsed; + + const ImVec4 clip_rect_t = window->ClipRectStack.back(); + window->Collapsed |= (clip_rect_t.x >= clip_rect_t.z || clip_rect_t.y >= clip_rect_t.w); + + // We also hide the window from rendering because we've already added its border to the command list. + // (we could perform the check earlier in the function but it is simpler at this point) + if (window->Collapsed) + window->Visible = false; + } + if (style.Alpha <= 0.0f) + window->Visible = false; + + // Return false if we don't intend to display anything to allow user to perform an early out optimization + window->SkipItems = (window->Collapsed || !window->Visible) && window->AutoFitFrames <= 0; + return !window->SkipItems; +} + +void ImGui::End() +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + + ImGui::Columns(1, "#CloseColumns"); + PopClipRect(); // inner window clip rectangle + PopClipRect(); // outer window clip rectangle + window->DrawList->PopTextureID(); + + // Stop logging + if (!(window->Flags & ImGuiWindowFlags_ChildWindow)) // FIXME: add more options for scope of logging + ImGui::LogFinish(); + + // Pop + // NB: we don't clear 'window->RootWindow'. The pointer is allowed to live until the next call to Begin(). + g.CurrentWindowStack.pop_back(); + SetCurrentWindow(g.CurrentWindowStack.empty() ? NULL : g.CurrentWindowStack.back()); +} + +// Vertical scrollbar +// The entire piece of code below is rather confusing because: +// - We handle absolute seeking (when first clicking outside the grab) and relative manipulation (afterward or when clicking inside the grab) +// - We store values as ratio and in a form that allows the window content to change while we are holding on a scrollbar +static void Scrollbar(ImGuiWindow* window) +{ + ImGuiState& g = *GImGui; + const ImGuiStyle& style = g.Style; + const ImGuiID id = window->GetID("#SCROLLY"); + + // Render background + ImRect bb(window->Rect().Max.x - style.ScrollbarWidth, window->Pos.y + window->TitleBarHeight()+1, window->Rect().Max.x, window->Rect().Max.y-1); + window->DrawList->AddRectFilled(bb.Min, bb.Max, window->Color(ImGuiCol_ScrollbarBg)); + bb.Expand(-3.0f); + const float scrollbar_height = bb.GetHeight(); + + // The grabable box size generally represent the amount visible (vs the total scrollable amount) + // But we maintain a minimum size in pixel to allow for the user to still aim inside. + const float grab_h_pixels = ImMin(ImMax(scrollbar_height * ImSaturate(window->Size.y / ImMax(window->SizeContents.y, window->Size.y)), style.GrabMinSize), scrollbar_height); + const float grab_h_norm = grab_h_pixels / scrollbar_height; + + // Handle input right away. None of the code of Begin() is relying on scrolling position before calling Scrollbar(). + bool held = false; + bool hovered = false; + const bool previously_held = (g.ActiveId == id); + ButtonBehavior(bb, id, &hovered, &held, true); + + const float scroll_max = ImMax(1.0f, window->SizeContents.y - window->Size.y); + float scroll_ratio = ImSaturate(window->ScrollY / scroll_max); + float grab_y_norm = scroll_ratio * (scrollbar_height - grab_h_pixels) / scrollbar_height; + if (held) + { + const float clicked_y_norm = ImSaturate((g.IO.MousePos.y - bb.Min.y) / scrollbar_height); // Click position in scrollbar space (0.0f->1.0f) + g.HoveredId = id; + + bool seek_absolute = false; + if (!previously_held) + { + // On initial click calculate the distance between mouse and the center of the grab + if (clicked_y_norm >= grab_y_norm && clicked_y_norm <= grab_y_norm + grab_h_norm) + { + g.ScrollbarClickDeltaToGrabCenter = clicked_y_norm - grab_y_norm - grab_h_norm*0.5f; + } + else + { + seek_absolute = true; + g.ScrollbarClickDeltaToGrabCenter = 0; + } + } + + // Apply scroll + const float scroll_y_norm = ImSaturate((clicked_y_norm - g.ScrollbarClickDeltaToGrabCenter - grab_h_norm*0.5f) / (1.0f - grab_h_norm)); + window->ScrollY = (float)(int)(0.5f + scroll_y_norm * (window->SizeContents.y - window->Size.y)); + window->NextScrollY = window->ScrollY; + + // Update values for rendering + scroll_ratio = ImSaturate(window->ScrollY / scroll_max); + grab_y_norm = scroll_ratio * (scrollbar_height - grab_h_pixels) / scrollbar_height; + + // Update distance to grab now that we have seeked and saturated + if (seek_absolute) + g.ScrollbarClickDeltaToGrabCenter = clicked_y_norm - grab_y_norm - grab_h_norm*0.5f; + } + + // Render + const ImU32 grab_col = window->Color(held ? ImGuiCol_ScrollbarGrabActive : hovered ? ImGuiCol_ScrollbarGrabHovered : ImGuiCol_ScrollbarGrab); + window->DrawList->AddRectFilled(ImVec2(bb.Min.x, ImLerp(bb.Min.y, bb.Max.y, grab_y_norm)), ImVec2(bb.Max.x, ImLerp(bb.Min.y, bb.Max.y, grab_y_norm) + grab_h_pixels), grab_col); +} + +// Moving window to front of display (which happens to be back of our sorted list) +static void FocusWindow(ImGuiWindow* window) +{ + ImGuiState& g = *GImGui; + + // Always mark the window we passed as focused. This is used for keyboard interactions such as tabbing. + g.FocusedWindow = window; + + // Passing NULL allow to disable keyboard focus + if (!window) + return; + + // And move its root window to the top of the pile + if (window->RootWindow) + window = window->RootWindow; + + if (g.Windows.back() == window) + return; + + for (size_t i = 0; i < g.Windows.size(); i++) + if (g.Windows[i] == window) + { + g.Windows.erase(g.Windows.begin() + i); + break; + } + g.Windows.push_back(window); +} + +void ImGui::PushItemWidth(float item_width) +{ + ImGuiWindow* window = GetCurrentWindow(); + window->DC.ItemWidth.push_back(item_width == 0.0f ? window->ItemWidthDefault : item_width); +} + +void ImGui::PopItemWidth() +{ + ImGuiWindow* window = GetCurrentWindow(); + window->DC.ItemWidth.pop_back(); +} + +float ImGui::CalcItemWidth() +{ + ImGuiWindow* window = GetCurrentWindow(); + float w = window->DC.ItemWidth.back(); + if (w < 0.0f) + { + // Align to a right-side limit. We include 1 frame padding in the calculation because this is how the width is always used (we add 2 frame padding to it), but we could move that responsibility to the widget as well. + ImGuiState& g = *GImGui; + w = -w; + float width_to_right_edge = window->Pos.x + ImGui::GetContentRegionMax().x - window->DC.CursorPos.x; + w = ImMax(1.0f, width_to_right_edge - w - g.Style.FramePadding.x * 2.0f); + } + w = (float)(int)w; + return w; +} + +static void SetFont(ImFont* font) +{ + ImGuiState& g = *GImGui; + + IM_ASSERT(font && font->IsLoaded()); + IM_ASSERT(font->Scale > 0.0f); + g.Font = font; + g.FontBaseSize = g.IO.FontGlobalScale * g.Font->FontSize * g.Font->Scale; + g.FontSize = g.CurrentWindow ? g.CurrentWindow->CalcFontSize() : 0.0f; + g.FontTexUvWhitePixel = g.Font->ContainerAtlas->TexUvWhitePixel; +} + +void ImGui::PushFont(ImFont* font) +{ + ImGuiState& g = *GImGui; + + if (!font) + font = g.IO.Fonts->Fonts[0]; + + SetFont(font); + g.FontStack.push_back(font); + g.CurrentWindow->DrawList->PushTextureID(font->ContainerAtlas->TexID); +} + +void ImGui::PopFont() +{ + ImGuiState& g = *GImGui; + + g.CurrentWindow->DrawList->PopTextureID(); + g.FontStack.pop_back(); + SetFont(g.FontStack.empty() ? g.IO.Fonts->Fonts[0] : g.FontStack.back()); +} + +void ImGui::PushAllowKeyboardFocus(bool allow_keyboard_focus) +{ + ImGuiWindow* window = GetCurrentWindow(); + window->DC.AllowKeyboardFocus.push_back(allow_keyboard_focus); +} + +void ImGui::PopAllowKeyboardFocus() +{ + ImGuiWindow* window = GetCurrentWindow(); + window->DC.AllowKeyboardFocus.pop_back(); +} + +void ImGui::PushTextWrapPos(float wrap_x) +{ + ImGuiWindow* window = GetCurrentWindow(); + window->DC.TextWrapPos.push_back(wrap_x); +} + +void ImGui::PopTextWrapPos() +{ + ImGuiWindow* window = GetCurrentWindow(); + window->DC.TextWrapPos.pop_back(); +} + +void ImGui::PushStyleColor(ImGuiCol idx, const ImVec4& col) +{ + ImGuiState& g = *GImGui; + + ImGuiColMod backup; + backup.Col = idx; + backup.PreviousValue = g.Style.Colors[idx]; + g.ColorModifiers.push_back(backup); + g.Style.Colors[idx] = col; +} + +void ImGui::PopStyleColor(int count) +{ + ImGuiState& g = *GImGui; + + while (count > 0) + { + ImGuiColMod& backup = g.ColorModifiers.back(); + g.Style.Colors[backup.Col] = backup.PreviousValue; + g.ColorModifiers.pop_back(); + count--; + } +} + +static float* GetStyleVarFloatAddr(ImGuiStyleVar idx) +{ + ImGuiState& g = *GImGui; + switch (idx) + { + case ImGuiStyleVar_Alpha: return &g.Style.Alpha; + case ImGuiStyleVar_WindowRounding: return &g.Style.WindowRounding; + case ImGuiStyleVar_ChildWindowRounding: return &g.Style.ChildWindowRounding; + case ImGuiStyleVar_FrameRounding: return &g.Style.FrameRounding; + case ImGuiStyleVar_IndentSpacing: return &g.Style.IndentSpacing; + case ImGuiStyleVar_GrabMinSize: return &g.Style.GrabMinSize; + } + return NULL; +} + +static ImVec2* GetStyleVarVec2Addr(ImGuiStyleVar idx) +{ + ImGuiState& g = *GImGui; + switch (idx) + { + case ImGuiStyleVar_WindowPadding: return &g.Style.WindowPadding; + case ImGuiStyleVar_FramePadding: return &g.Style.FramePadding; + case ImGuiStyleVar_ItemSpacing: return &g.Style.ItemSpacing; + case ImGuiStyleVar_ItemInnerSpacing: return &g.Style.ItemInnerSpacing; + } + return NULL; +} + +void ImGui::PushStyleVar(ImGuiStyleVar idx, float val) +{ + ImGuiState& g = *GImGui; + + float* pvar = GetStyleVarFloatAddr(idx); + IM_ASSERT(pvar != NULL); // Called function with wrong-type? Variable is not a float. + ImGuiStyleMod backup; + backup.Var = idx; + backup.PreviousValue = ImVec2(*pvar, 0.0f); + g.StyleModifiers.push_back(backup); + *pvar = val; +} + + +void ImGui::PushStyleVar(ImGuiStyleVar idx, const ImVec2& val) +{ + ImGuiState& g = *GImGui; + + ImVec2* pvar = GetStyleVarVec2Addr(idx); + IM_ASSERT(pvar != NULL); // Called function with wrong-type? Variable is not a ImVec2. + ImGuiStyleMod backup; + backup.Var = idx; + backup.PreviousValue = *pvar; + g.StyleModifiers.push_back(backup); + *pvar = val; +} + +void ImGui::PopStyleVar(int count) +{ + ImGuiState& g = *GImGui; + + while (count > 0) + { + ImGuiStyleMod& backup = g.StyleModifiers.back(); + if (float* pvar_f = GetStyleVarFloatAddr(backup.Var)) + *pvar_f = backup.PreviousValue.x; + else if (ImVec2* pvar_v = GetStyleVarVec2Addr(backup.Var)) + *pvar_v = backup.PreviousValue; + g.StyleModifiers.pop_back(); + count--; + } +} + +const char* ImGui::GetStyleColName(ImGuiCol idx) +{ + // Create switch-case from enum with regexp: ImGuiCol_{.*}, --> case ImGuiCol_\1: return "\1"; + switch (idx) + { + case ImGuiCol_Text: return "Text"; + case ImGuiCol_WindowBg: return "WindowBg"; + case ImGuiCol_ChildWindowBg: return "ChildWindowBg"; + case ImGuiCol_Border: return "Border"; + case ImGuiCol_BorderShadow: return "BorderShadow"; + case ImGuiCol_FrameBg: return "FrameBg"; + case ImGuiCol_FrameBgHovered: return "FrameBgHovered"; + case ImGuiCol_FrameBgActive: return "FrameBgActive"; + case ImGuiCol_TitleBg: return "TitleBg"; + case ImGuiCol_TitleBgCollapsed: return "TitleBgCollapsed"; + case ImGuiCol_ScrollbarBg: return "ScrollbarBg"; + case ImGuiCol_ScrollbarGrab: return "ScrollbarGrab"; + case ImGuiCol_ScrollbarGrabHovered: return "ScrollbarGrabHovered"; + case ImGuiCol_ScrollbarGrabActive: return "ScrollbarGrabActive"; + case ImGuiCol_ComboBg: return "ComboBg"; + case ImGuiCol_CheckMark: return "CheckMark"; + case ImGuiCol_SliderGrab: return "SliderGrab"; + case ImGuiCol_SliderGrabActive: return "SliderGrabActive"; + case ImGuiCol_Button: return "Button"; + case ImGuiCol_ButtonHovered: return "ButtonHovered"; + case ImGuiCol_ButtonActive: return "ButtonActive"; + case ImGuiCol_Header: return "Header"; + case ImGuiCol_HeaderHovered: return "HeaderHovered"; + case ImGuiCol_HeaderActive: return "HeaderActive"; + case ImGuiCol_Column: return "Column"; + case ImGuiCol_ColumnHovered: return "ColumnHovered"; + case ImGuiCol_ColumnActive: return "ColumnActive"; + case ImGuiCol_ResizeGrip: return "ResizeGrip"; + case ImGuiCol_ResizeGripHovered: return "ResizeGripHovered"; + case ImGuiCol_ResizeGripActive: return "ResizeGripActive"; + case ImGuiCol_CloseButton: return "CloseButton"; + case ImGuiCol_CloseButtonHovered: return "CloseButtonHovered"; + case ImGuiCol_CloseButtonActive: return "CloseButtonActive"; + case ImGuiCol_PlotLines: return "PlotLines"; + case ImGuiCol_PlotLinesHovered: return "PlotLinesHovered"; + case ImGuiCol_PlotHistogram: return "PlotHistogram"; + case ImGuiCol_PlotHistogramHovered: return "PlotHistogramHovered"; + case ImGuiCol_TextSelectedBg: return "TextSelectedBg"; + case ImGuiCol_TooltipBg: return "TooltipBg"; + } + IM_ASSERT(0); + return "Unknown"; +} + +bool ImGui::IsWindowFocused() +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + return g.FocusedWindow == window; +} + +bool ImGui::IsRootWindowFocused() +{ + ImGuiState& g = *GImGui; + ImGuiWindow* root_window = GetCurrentWindow()->RootWindow; + return g.FocusedWindow == root_window; +} + +bool ImGui::IsRootWindowOrAnyChildFocused() +{ + ImGuiState& g = *GImGui; + ImGuiWindow* root_window = GetCurrentWindow()->RootWindow; + return g.FocusedWindow && g.FocusedWindow->RootWindow == root_window; +} + +float ImGui::GetWindowWidth() +{ + ImGuiWindow* window = GetCurrentWindow(); + return window->Size.x; +} + +ImVec2 ImGui::GetWindowPos() +{ + ImGuiWindow* window = GetCurrentWindow(); + return window->Pos; +} + +static void SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiSetCond cond) +{ + // Test condition (NB: bit 0 is always true) and clear flags for next time + if (cond && (window->SetWindowPosAllowFlags & cond) == 0) + return; + window->SetWindowPosAllowFlags &= ~(ImGuiSetCond_Once | ImGuiSetCond_FirstUseEver); + + // Set + const ImVec2 old_pos = window->Pos; + window->PosFloat = pos; + window->Pos = ImVec2((float)(int)window->PosFloat.x, (float)(int)window->PosFloat.y); + window->DC.CursorPos += (window->Pos - old_pos); // As we happen to move the window while it is being appended to (which is a bad idea - will smear) let's at least offset the cursor + window->DC.CursorMaxPos += (window->Pos - old_pos); // And more importantly we need to adjust this so size calculation doesn't get affected. +} + +void ImGui::SetWindowPos(const ImVec2& pos, ImGuiSetCond cond) +{ + ImGuiWindow* window = GetCurrentWindow(); + SetWindowPos(window, pos, cond); +} + +void ImGui::SetWindowPos(const char* name, const ImVec2& pos, ImGuiSetCond cond) +{ + ImGuiWindow* window = FindWindowByName(name); + if (window) + SetWindowPos(window, pos, cond); +} + +ImVec2 ImGui::GetWindowSize() +{ + ImGuiWindow* window = GetCurrentWindow(); + return window->Size; +} + +static void SetWindowSize(ImGuiWindow* window, const ImVec2& size, ImGuiSetCond cond) +{ + // Test condition (NB: bit 0 is always true) and clear flags for next time + if (cond && (window->SetWindowSizeAllowFlags & cond) == 0) + return; + window->SetWindowSizeAllowFlags &= ~(ImGuiSetCond_Once | ImGuiSetCond_FirstUseEver); + + // Set + if (ImLengthSqr(size) > 0.00001f) + { + window->SizeFull = size; + window->AutoFitFrames = 0; + } + else + { + // Autofit + window->AutoFitFrames = 2; + window->AutoFitOnlyGrows = false; + } +} + +void ImGui::SetWindowSize(const ImVec2& size, ImGuiSetCond cond) +{ + ImGuiWindow* window = GetCurrentWindow(); + SetWindowSize(window, size, cond); +} + +void ImGui::SetWindowSize(const char* name, const ImVec2& size, ImGuiSetCond cond) +{ + ImGuiWindow* window = FindWindowByName(name); + if (window) + SetWindowSize(window, size, cond); +} + +static void SetWindowCollapsed(ImGuiWindow* window, bool collapsed, ImGuiSetCond cond) +{ + // Test condition (NB: bit 0 is always true) and clear flags for next time + if (cond && (window->SetWindowCollapsedAllowFlags & cond) == 0) + return; + window->SetWindowCollapsedAllowFlags &= ~(ImGuiSetCond_Once | ImGuiSetCond_FirstUseEver); + + // Set + window->Collapsed = collapsed; +} + +void ImGui::SetWindowCollapsed(bool collapsed, ImGuiSetCond cond) +{ + ImGuiWindow* window = GetCurrentWindow(); + SetWindowCollapsed(window, collapsed, cond); +} + +bool ImGui::GetWindowCollapsed() +{ + ImGuiWindow* window = GetCurrentWindow(); + return window->Collapsed; +} + +void ImGui::SetWindowCollapsed(const char* name, bool collapsed, ImGuiSetCond cond) +{ + ImGuiWindow* window = FindWindowByName(name); + if (window) + SetWindowCollapsed(window, collapsed, cond); +} + +void ImGui::SetWindowFocus() +{ + ImGuiWindow* window = GetCurrentWindow(); + FocusWindow(window); +} + +void ImGui::SetWindowFocus(const char* name) +{ + if (name) + { + ImGuiWindow* window = FindWindowByName(name); + if (window) + FocusWindow(window); + } + else + { + FocusWindow(NULL); + } +} + +void ImGui::SetNextWindowPos(const ImVec2& pos, ImGuiSetCond cond) +{ + ImGuiState& g = *GImGui; + g.SetNextWindowPosVal = pos; + g.SetNextWindowPosCond = cond ? cond : ImGuiSetCond_Always; +} + +void ImGui::SetNextWindowSize(const ImVec2& size, ImGuiSetCond cond) +{ + ImGuiState& g = *GImGui; + g.SetNextWindowSizeVal = size; + g.SetNextWindowSizeCond = cond ? cond : ImGuiSetCond_Always; +} + +void ImGui::SetNextWindowCollapsed(bool collapsed, ImGuiSetCond cond) +{ + ImGuiState& g = *GImGui; + g.SetNextWindowCollapsedVal = collapsed; + g.SetNextWindowCollapsedCond = cond ? cond : ImGuiSetCond_Always; +} + +void ImGui::SetNextWindowFocus() +{ + ImGuiState& g = *GImGui; + g.SetNextWindowFocus = true; +} + +ImVec2 ImGui::GetContentRegionMax() +{ + ImGuiWindow* window = GetCurrentWindow(); + ImVec2 window_padding = window->WindowPadding(); + ImVec2 mx = window->Size - window_padding; + if (window->DC.ColumnsCount != 1) + { + mx.x = ImGui::GetColumnOffset(window->DC.ColumnsCurrent + 1); + mx.x -= window_padding.x; + } + else + { + if (window->ScrollbarY) + mx.x -= GImGui->Style.ScrollbarWidth; + } + return mx; +} + +ImVec2 ImGui::GetWindowContentRegionMin() +{ + ImGuiWindow* window = GetCurrentWindow(); + return ImVec2(0, window->TitleBarHeight()) + window->WindowPadding(); +} + +ImVec2 ImGui::GetWindowContentRegionMax() +{ + ImGuiWindow* window = GetCurrentWindow(); + ImVec2 m = window->Size - window->WindowPadding(); + if (window->ScrollbarY) + m.x -= GImGui->Style.ScrollbarWidth; + return m; +} + +float ImGui::GetTextLineHeight() +{ + ImGuiState& g = *GImGui; + return g.FontSize; +} + +float ImGui::GetTextLineHeightWithSpacing() +{ + ImGuiState& g = *GImGui; + return g.FontSize + g.Style.ItemSpacing.y; +} + +ImDrawList* ImGui::GetWindowDrawList() +{ + ImGuiWindow* window = GetCurrentWindow(); + return window->DrawList; +} + +ImFont* ImGui::GetWindowFont() +{ + ImGuiState& g = *GImGui; + return g.Font; +} + +float ImGui::GetWindowFontSize() +{ + ImGuiState& g = *GImGui; + return g.FontSize; +} + +void ImGui::SetWindowFontScale(float scale) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + window->FontWindowScale = scale; + g.FontSize = window->CalcFontSize(); +} + +// NB: internally we store CursorPos in absolute screen coordinates because it is more convenient. +// Conversion happens as we pass the value to user, but it makes our naming convention dodgy. May want to rename 'DC.CursorPos'. +ImVec2 ImGui::GetCursorPos() +{ + ImGuiWindow* window = GetCurrentWindow(); + return window->DC.CursorPos - window->Pos; +} + +float ImGui::GetCursorPosX() +{ + return ImGui::GetCursorPos().x; +} + +float ImGui::GetCursorPosY() +{ + return ImGui::GetCursorPos().y; +} + +void ImGui::SetCursorPos(const ImVec2& pos) +{ + ImGuiWindow* window = GetCurrentWindow(); + window->DC.CursorPos = window->Pos + pos; + window->DC.CursorMaxPos = ImMax(window->DC.CursorMaxPos, window->DC.CursorPos); +} + +void ImGui::SetCursorPosX(float x) +{ + ImGuiWindow* window = GetCurrentWindow(); + window->DC.CursorPos.x = window->Pos.x + x; + window->DC.CursorMaxPos.x = ImMax(window->DC.CursorMaxPos.x, window->DC.CursorPos.x); +} + +void ImGui::SetCursorPosY(float y) +{ + ImGuiWindow* window = GetCurrentWindow(); + window->DC.CursorPos.y = window->Pos.y + y; + window->DC.CursorMaxPos.y = ImMax(window->DC.CursorMaxPos.y, window->DC.CursorPos.y); +} + +ImVec2 ImGui::GetCursorScreenPos() +{ + ImGuiWindow* window = GetCurrentWindow(); + return window->DC.CursorPos; +} + +void ImGui::SetCursorScreenPos(const ImVec2& screen_pos) +{ + ImGuiWindow* window = GetCurrentWindow(); + window->DC.CursorPos = screen_pos; +} + +float ImGui::GetScrollPosY() +{ + ImGuiWindow* window = GetCurrentWindow(); + return window->ScrollY; +} + +float ImGui::GetScrollMaxY() +{ + ImGuiWindow* window = GetCurrentWindow(); + return window->SizeContents.y - window->SizeFull.y; +} + +void ImGui::SetScrollPosHere() +{ + ImGuiWindow* window = GetCurrentWindow(); + window->NextScrollY = (window->DC.CursorPos.y + window->ScrollY) - (window->Pos.y + window->SizeFull.y * 0.5f) - (window->TitleBarHeight() + window->WindowPadding().y); +} + +void ImGui::SetKeyboardFocusHere(int offset) +{ + ImGuiWindow* window = GetCurrentWindow(); + window->FocusIdxAllRequestNext = window->FocusIdxAllCounter + 1 + offset; + window->FocusIdxTabRequestNext = IM_INT_MAX; +} + +void ImGui::SetStateStorage(ImGuiStorage* tree) +{ + ImGuiWindow* window = GetCurrentWindow(); + window->DC.StateStorage = tree ? tree : &window->StateStorage; +} + +ImGuiStorage* ImGui::GetStateStorage() +{ + ImGuiWindow* window = GetCurrentWindow(); + return window->DC.StateStorage; +} + +void ImGui::TextV(const char* fmt, va_list args) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + + const char* text_end = g.TempBuffer + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args); + TextUnformatted(g.TempBuffer, text_end); +} + +void ImGui::Text(const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + TextV(fmt, args); + va_end(args); +} + +void ImGui::TextColoredV(const ImVec4& col, const char* fmt, va_list args) +{ + ImGui::PushStyleColor(ImGuiCol_Text, col); + TextV(fmt, args); + ImGui::PopStyleColor(); +} + +void ImGui::TextColored(const ImVec4& col, const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + TextColoredV(col, fmt, args); + va_end(args); +} + +void ImGui::TextWrappedV(const char* fmt, va_list args) +{ + ImGui::PushTextWrapPos(0.0f); + TextV(fmt, args); + ImGui::PopTextWrapPos(); +} + +void ImGui::TextWrapped(const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + TextWrappedV(fmt, args); + va_end(args); +} + +void ImGui::TextUnformatted(const char* text, const char* text_end) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + + IM_ASSERT(text != NULL); + const char* text_begin = text; + if (text_end == NULL) + text_end = text + strlen(text); // FIXME-OPT + + const float wrap_pos_x = window->DC.TextWrapPos.back(); + const bool wrap_enabled = wrap_pos_x >= 0.0f; + if (text_end - text > 2000 && !wrap_enabled) + { + // Long text! + // Perform manual coarse clipping to optimize for long multi-line text + // From this point we will only compute the width of lines that are visible. Optimization only available when word-wrapping is disabled. + // We also don't vertically center the text within the line full height, which is unlikely to matter because we are likely the biggest and only item on the line. + const char* line = text; + const float line_height = ImGui::GetTextLineHeight(); + const ImVec2 text_pos = window->DC.CursorPos + ImVec2(0.0f, window->DC.CurrentLineTextBaseOffset); + const ImVec4 clip_rect = window->ClipRectStack.back(); + ImVec2 text_size(0,0); + + if (text_pos.y <= clip_rect.w) + { + ImVec2 pos = text_pos; + + // Lines to skip (can't skip when logging text) + if (!g.LogEnabled) + { + int lines_skippable = (int)((clip_rect.y - text_pos.y) / line_height) - 1; + if (lines_skippable > 0) + { + int lines_skipped = 0; + while (line < text_end && lines_skipped <= lines_skippable) + { + const char* line_end = strchr(line, '\n'); + line = line_end + 1; + lines_skipped++; + } + pos.y += lines_skipped * line_height; + } + } + + // Lines to render + if (line < text_end) + { + ImRect line_rect(pos, pos + ImVec2(ImGui::GetWindowWidth(), line_height)); + while (line < text_end) + { + const char* line_end = strchr(line, '\n'); + if (IsClippedEx(line_rect, NULL, false)) + break; + + const ImVec2 line_size = CalcTextSize(line, line_end, false); + text_size.x = ImMax(text_size.x, line_size.x); + RenderText(pos, line, line_end, false); + if (!line_end) + line_end = text_end; + line = line_end + 1; + line_rect.Min.y += line_height; + line_rect.Max.y += line_height; + pos.y += line_height; + } + + // Count remaining lines + int lines_skipped = 0; + while (line < text_end) + { + const char* line_end = strchr(line, '\n'); + if (!line_end) + line_end = text_end; + line = line_end + 1; + lines_skipped++; + } + pos.y += lines_skipped * line_height; + } + + text_size.y += (pos - text_pos).y; + } + + ImRect bb(text_pos, text_pos + text_size); + ItemSize(bb); + ItemAdd(bb, NULL); + } + else + { + const float wrap_width = wrap_enabled ? CalcWrapWidthForPos(window->DC.CursorPos, wrap_pos_x) : 0.0f; + const ImVec2 text_size = CalcTextSize(text_begin, text_end, false, wrap_width); + + // Account of baseline offset + ImVec2 text_pos = window->DC.CursorPos; + text_pos.y += window->DC.CurrentLineTextBaseOffset; + + ImRect bb(text_pos, text_pos + text_size); + ItemSize(bb.GetSize()); + if (!ItemAdd(bb, NULL)) + return; + + // Render (we don't hide text after ## in this end-user function) + RenderTextWrapped(bb.Min, text_begin, text_end, wrap_width); + } +} + +void ImGui::AlignFirstTextHeightToWidgets() +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + + // Declare a dummy item size to that upcoming items that are smaller will center-align on the newly expanded line height. + ItemSize(ImVec2(0, g.FontSize + g.Style.FramePadding.y*2), g.Style.FramePadding.y); + ImGui::SameLine(0, 0); +} + +// Add a label+text combo aligned to other label+value widgets +void ImGui::LabelTextV(const char* label, const char* fmt, va_list args) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + + const ImGuiStyle& style = g.Style; + const float w = ImGui::CalcItemWidth(); + + const char* value_text_begin = &g.TempBuffer[0]; + const char* value_text_end = value_text_begin + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args); + + const ImVec2 label_size = CalcTextSize(label, NULL, true); + const ImRect value_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w + style.FramePadding.x*2, label_size.y + style.FramePadding.y*2)); + const ImRect total_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w + style.FramePadding.x*2 + (label_size.x > 0.0f ? style.ItemInnerSpacing.x : 0.0f), style.FramePadding.y*2) + label_size); + ItemSize(total_bb, style.FramePadding.y); + if (!ItemAdd(total_bb, NULL)) + return; + + // Render + RenderTextClipped(ImVec2(value_bb.Min.x, value_bb.Min.y + style.FramePadding.y), value_text_begin, value_text_end, NULL, value_bb.Max); + RenderText(ImVec2(value_bb.Max.x + style.ItemInnerSpacing.x, value_bb.Min.y + style.FramePadding.y), label); +} + +void ImGui::LabelText(const char* label, const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + LabelTextV(label, fmt, args); + va_end(args); +} + +static inline bool IsWindowContentHoverable(ImGuiWindow* window) +{ + ImGuiState& g = *GImGui; + + // An active popup disable hovering on other windows (apart from its own children) + if (ImGuiWindow* focused_window = g.FocusedWindow) + if (ImGuiWindow* focused_root_window = focused_window->RootWindow) + if ((focused_root_window->Flags & ImGuiWindowFlags_Popup) != 0 && focused_root_window->WasVisible && focused_root_window != window->RootWindow) + return false; + + return true; +} + +static bool IsHovered(const ImRect& bb, ImGuiID id) +{ + ImGuiState& g = *GImGui; + if (g.HoveredId == 0) + { + ImGuiWindow* window = GetCurrentWindow(); + if (g.HoveredRootWindow == window->RootWindow) + if ((g.ActiveId == 0 || g.ActiveId == id || g.ActiveIdIsFocusedOnly) && IsMouseHoveringRect(bb)) + if (IsWindowContentHoverable(g.HoveredRootWindow)) + return true; + } + return false; +} + +static bool ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, bool allow_key_modifiers, bool repeat, bool pressed_on_click) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + + const bool hovered = IsHovered(bb, id); + bool pressed = false; + if (hovered) + { + g.HoveredId = id; + if (allow_key_modifiers || (!g.IO.KeyCtrl && !g.IO.KeyShift && !g.IO.KeyAlt)) + { + if (g.IO.MouseClicked[0]) + { + if (pressed_on_click) + { + pressed = true; + SetActiveId(0); + } + else + { + SetActiveId(id); + } + FocusWindow(window); + } + else if (repeat && g.ActiveId && ImGui::IsMouseClicked(0, true)) + { + pressed = true; + } + } + } + + bool held = false; + if (g.ActiveId == id) + { + if (g.IO.MouseDown[0]) + { + held = true; + } + else + { + if (hovered) + pressed = true; + SetActiveId(0); + } + } + + if (out_hovered) *out_hovered = hovered; + if (out_held) *out_held = held; + + return pressed; +} + +bool ImGui::Button(const char* label, const ImVec2& size_arg, bool repeat_when_held) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + const ImGuiStyle& style = g.Style; + const ImGuiID id = window->GetID(label); + const ImVec2 label_size = CalcTextSize(label, NULL, true); + + const ImVec2 size(size_arg.x != 0.0f ? size_arg.x : (label_size.x + style.FramePadding.x*2), size_arg.y != 0.0f ? size_arg.y : (label_size.y + style.FramePadding.y*2)); + const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); + ItemSize(bb, style.FramePadding.y); + if (!ItemAdd(bb, &id)) + return false; + + bool hovered, held; + bool pressed = ButtonBehavior(bb, id, &hovered, &held, true, repeat_when_held); + + // Render + const ImU32 col = window->Color((hovered && held) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button); + RenderFrame(bb.Min, bb.Max, col, true, style.FrameRounding); + + const ImVec2 off = ImVec2(ImMax(0.0f, size.x - label_size.x) * 0.5f, ImMax(0.0f, size.y - label_size.y) * 0.5f); // Center (only applies if we explicitly gave a size bigger than the text size, which isn't the common path) + RenderTextClipped(bb.Min + off, label, NULL, &label_size, bb.Max); // Render clip (only applies if we explicitly gave a size smaller than the text size, which isn't the commmon path) + + return pressed; +} + +// Small buttons fits within text without additional spacing. +bool ImGui::SmallButton(const char* label) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + const ImGuiStyle& style = g.Style; + const ImGuiID id = window->GetID(label); + const ImVec2 label_size = CalcTextSize(label, NULL, true); + + ImVec2 text_pos = window->DC.CursorPos; + text_pos.y += window->DC.CurrentLineTextBaseOffset; + ImRect bb(text_pos, text_pos + label_size + ImVec2(style.FramePadding.x*2,0)); + ItemSize(bb); + if (!ItemAdd(bb, &id)) + return false; + + bool hovered, held; + bool pressed = ButtonBehavior(bb, id, &hovered, &held, true); + + // Render + const ImU32 col = window->Color((hovered && held) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button); + RenderFrame(bb.Min, bb.Max, col); + RenderText(bb.Min + ImVec2(style.FramePadding.x,0), label); + + return pressed; +} + +// Tip: use ImGui::PushID()/PopID() to push indices or pointers in the ID stack. +// Then you can keep 'str_id' empty or the same for all your buttons (instead of creating a string based on a non-string id) +bool ImGui::InvisibleButton(const char* str_id, const ImVec2& size) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + const ImGuiID id = window->GetID(str_id); + const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); + ItemSize(bb); + if (!ItemAdd(bb, &id)) + return false; + + bool hovered, held; + bool pressed = ButtonBehavior(bb, id, &hovered, &held, true); + + return pressed; +} + +// Upper-right button to close a window. +static bool CloseWindowButton(bool* p_opened) +{ + ImGuiWindow* window = GetCurrentWindow(); + + const ImGuiID id = window->GetID("#CLOSE"); + const float size = window->TitleBarHeight() - 4.0f; + const ImRect bb(window->Rect().GetTR() + ImVec2(-3.0f-size,2.0f), window->Rect().GetTR() + ImVec2(-3.0f,2.0f+size)); + + bool hovered, held; + bool pressed = ButtonBehavior(bb, id, &hovered, &held, true); + + // Render + const ImU32 col = window->Color((held && hovered) ? ImGuiCol_CloseButtonActive : hovered ? ImGuiCol_CloseButtonHovered : ImGuiCol_CloseButton); + const ImVec2 center = bb.GetCenter(); + window->DrawList->AddCircleFilled(center, ImMax(2.0f,size*0.5f), col, 16); + + const float cross_extent = (size * 0.5f * 0.7071f) - 1.0f; + if (hovered) + { + window->DrawList->AddLine(center + ImVec2(+cross_extent,+cross_extent), center + ImVec2(-cross_extent,-cross_extent), window->Color(ImGuiCol_Text)); + window->DrawList->AddLine(center + ImVec2(+cross_extent,-cross_extent), center + ImVec2(-cross_extent,+cross_extent), window->Color(ImGuiCol_Text)); + } + + if (p_opened != NULL && pressed) + *p_opened = !*p_opened; + + return pressed; +} + +void ImGui::Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& tint_col, const ImVec4& border_col) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + + ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); + if (border_col.w > 0.0f) + bb.Max += ImVec2(2,2); + ItemSize(bb); + if (!ItemAdd(bb, NULL)) + return; + + if (border_col.w > 0.0f) + { + window->DrawList->AddRect(bb.Min, bb.Max, window->Color(border_col), 0.0f); + window->DrawList->AddImage(user_texture_id, bb.Min+ImVec2(1,1), bb.Max-ImVec2(1,1), uv0, uv1, window->Color(tint_col)); + } + else + { + window->DrawList->AddImage(user_texture_id, bb.Min, bb.Max, uv0, uv1, window->Color(tint_col)); + } +} + +// frame_padding < 0: uses FramePadding from style (default) +// frame_padding = 0: no framing +// frame_padding > 0: set framing size +// The color used are the button colors. +bool ImGui::ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, int frame_padding, const ImVec4& bg_col, const ImVec4& tint_col) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + const ImGuiStyle& style = g.Style; + + // Default to using texture ID as ID. User can still push string/integer prefixes. + // We could hash the size/uv to create a unique ID but that would prevent the user from animating buttons. + ImGui::PushID((void *)user_texture_id); + const ImGuiID id = window->GetID("#image"); + ImGui::PopID(); + + const ImVec2 padding = (frame_padding >= 0) ? ImVec2((float)frame_padding, (float)frame_padding) : style.FramePadding; + const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size + padding*2); + const ImRect image_bb(window->DC.CursorPos + padding, window->DC.CursorPos + padding + size); + ItemSize(bb); + if (!ItemAdd(bb, &id)) + return false; + + bool hovered, held; + bool pressed = ButtonBehavior(bb, id, &hovered, &held, true); + + // Render + const ImU32 col = window->Color((hovered && held) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button); + if (padding.x > 0.0f || padding.y > 0.0f) + RenderFrame(bb.Min, bb.Max, col); + if (bg_col.w > 0.0f) + window->DrawList->AddRectFilled(image_bb.Min, image_bb.Max, window->Color(bg_col)); + window->DrawList->AddImage(user_texture_id, image_bb.Min, image_bb.Max, uv0, uv1, window->Color(tint_col)); + + return pressed; +} + +// Start logging ImGui output to TTY +void ImGui::LogToTTY(int max_depth) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (g.LogEnabled) + return; + + g.LogEnabled = true; + g.LogFile = stdout; + g.LogStartDepth = window->DC.TreeDepth; + if (max_depth >= 0) + g.LogAutoExpandMaxDepth = max_depth; +} + +// Start logging ImGui output to given file +void ImGui::LogToFile(int max_depth, const char* filename) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (g.LogEnabled) + return; + if (!filename) + { + filename = g.IO.LogFilename; + if (!filename) + return; + } + + g.LogFile = fopen(filename, "ab"); + if (!g.LogFile) + { + IM_ASSERT(g.LogFile != NULL); // Consider this an error + return; + } + g.LogEnabled = true; + g.LogStartDepth = window->DC.TreeDepth; + if (max_depth >= 0) + g.LogAutoExpandMaxDepth = max_depth; +} + +// Start logging ImGui output to clipboard +void ImGui::LogToClipboard(int max_depth) +{ + ImGuiWindow* window = GetCurrentWindow(); + ImGuiState& g = *GImGui; + if (g.LogEnabled) + return; + + g.LogEnabled = true; + g.LogFile = NULL; + g.LogStartDepth = window->DC.TreeDepth; + if (max_depth >= 0) + g.LogAutoExpandMaxDepth = max_depth; +} + +void ImGui::LogFinish() +{ + ImGuiState& g = *GImGui; + if (!g.LogEnabled) + return; + + ImGui::LogText(STR_NEWLINE); + g.LogEnabled = false; + if (g.LogFile != NULL) + { + if (g.LogFile == stdout) + fflush(g.LogFile); + else + fclose(g.LogFile); + g.LogFile = NULL; + } + if (g.LogClipboard->size() > 1) + { + if (g.IO.SetClipboardTextFn) + g.IO.SetClipboardTextFn(g.LogClipboard->begin()); + g.LogClipboard->clear(); + } +} + +// Helper to display logging buttons +void ImGui::LogButtons() +{ + ImGuiState& g = *GImGui; + + ImGui::PushID("LogButtons"); + const bool log_to_tty = ImGui::Button("Log To TTY"); + ImGui::SameLine(); + const bool log_to_file = ImGui::Button("Log To File"); + ImGui::SameLine(); + const bool log_to_clipboard = ImGui::Button("Log To Clipboard"); + ImGui::SameLine(); + + ImGui::PushItemWidth(80.0f); + ImGui::PushAllowKeyboardFocus(false); + ImGui::SliderInt("Depth", &g.LogAutoExpandMaxDepth, 0, 9, NULL); + ImGui::PopAllowKeyboardFocus(); + ImGui::PopItemWidth(); + ImGui::PopID(); + + // Start logging at the end of the function so that the buttons don't appear in the log + if (log_to_tty) + LogToTTY(g.LogAutoExpandMaxDepth); + if (log_to_file) + LogToFile(g.LogAutoExpandMaxDepth, g.IO.LogFilename); + if (log_to_clipboard) + LogToClipboard(g.LogAutoExpandMaxDepth); +} + +bool ImGui::CollapsingHeader(const char* label, const char* str_id, bool display_frame, bool default_open) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + const ImGuiStyle& style = g.Style; + + IM_ASSERT(str_id != NULL || label != NULL); + if (str_id == NULL) + str_id = label; + if (label == NULL) + label = str_id; + const ImGuiID id = window->GetID(str_id); + + // We only write to the tree storage if the user clicks (or explicitely use SetNextTreeNode*** functions) + ImGuiStorage* storage = window->DC.StateStorage; + bool opened; + if (g.SetNextTreeNodeOpenedCond != 0) + { + if (g.SetNextTreeNodeOpenedCond & ImGuiSetCond_Always) + { + opened = g.SetNextTreeNodeOpenedVal; + storage->SetInt(id, opened); + } + else + { + // We treat ImGuiSetCondition_Once and ImGuiSetCondition_FirstUseEver the same because tree node state are not saved persistently. + const int stored_value = storage->GetInt(id, -1); + if (stored_value == -1) + { + opened = g.SetNextTreeNodeOpenedVal; + storage->SetInt(id, opened); + } + else + { + opened = stored_value != 0; + } + } + g.SetNextTreeNodeOpenedCond = 0; + } + else + { + opened = storage->GetInt(id, default_open) != 0; + } + + // Framed header expand a little outside the default padding + const ImVec2 window_padding = window->WindowPadding(); + const ImVec2 label_size = CalcTextSize(label, NULL, true); + const ImVec2 pos_min = window->DC.CursorPos; + const ImVec2 pos_max = window->Pos + GetContentRegionMax(); + ImRect bb = ImRect(pos_min, ImVec2(pos_max.x, pos_min.y + label_size.y)); + if (display_frame) + { + bb.Min.x -= window_padding.x*0.5f - 1; + bb.Max.x += window_padding.x*0.5f - 1; + bb.Max.y += style.FramePadding.y * 2; + } + + // FIXME: we don't provide our width so that it doesn't get feed back into AutoFit. Should manage that better so we can still hover without extending ContentsSize + const ImRect text_bb(bb.Min, bb.Min + ImVec2(g.FontSize + style.FramePadding.x*2*2,0) + label_size); + ItemSize(ImVec2(text_bb.GetSize().x, bb.GetSize().y), display_frame ? style.FramePadding.y : 0.0f); + + // When logging is enabled, if automatically expand tree nodes (but *NOT* collapsing headers.. seems like sensible behavior). + // NB- If we are above max depth we still allow manually opened nodes to be logged. + if (g.LogEnabled && !display_frame && window->DC.TreeDepth < g.LogAutoExpandMaxDepth) + opened = true; + + if (!ItemAdd(bb, &id)) + return opened; + + bool hovered, held; + bool pressed = ButtonBehavior(display_frame ? bb : text_bb, id, &hovered, &held, false); + if (pressed) + { + opened = !opened; + storage->SetInt(id, opened); + } + + // Render + const ImU32 col = window->Color((held && hovered) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header); + if (display_frame) + { + // Framed type + RenderFrame(bb.Min, bb.Max, col, true, style.FrameRounding); + RenderCollapseTriangle(bb.Min + style.FramePadding, opened, 1.0f, true); + if (g.LogEnabled) + { + // NB: '##' is normally used to hide text (as a library-wide feature), so we need to specify the text range to make sure the ## aren't stripped out here. + const char log_prefix[] = "\n##"; + LogText(bb.Min + style.FramePadding, log_prefix, log_prefix+3); + } + RenderText(bb.Min + style.FramePadding + ImVec2(g.FontSize + style.FramePadding.x*2,0), label); + if (g.LogEnabled) + { + const char log_suffix[] = "##"; + LogText(bb.Min + style.FramePadding, log_suffix, log_suffix+2); + } + } + else + { + // Unframed typed for tree nodes + if ((held && hovered) || hovered) + RenderFrame(bb.Min, bb.Max, col, false); + RenderCollapseTriangle(bb.Min + ImVec2(style.FramePadding.x, g.FontSize*0.15f), opened, 0.70f, false); + if (g.LogEnabled) + LogText(bb.Min, ">"); + RenderText(bb.Min + ImVec2(g.FontSize + style.FramePadding.x*2,0), label); + } + + return opened; +} + +void ImGui::Bullet() +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + + const ImGuiStyle& style = g.Style; + const float line_height = g.FontSize; + const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(line_height, line_height)); + ItemSize(bb); + if (!ItemAdd(bb, NULL)) + return; + + // Render + const float bullet_size = line_height*0.15f; + window->DrawList->AddCircleFilled(bb.Min + ImVec2(style.FramePadding.x + line_height*0.5f, line_height*0.5f), bullet_size, window->Color(ImGuiCol_Text)); + + // Stay on same line + ImGui::SameLine(0, -1); +} + +// Text with a little bullet aligned to the typical tree node. +void ImGui::BulletTextV(const char* fmt, va_list args) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + + const char* text_begin = g.TempBuffer; + const char* text_end = text_begin + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args); + + const ImGuiStyle& style = g.Style; + const float line_height = g.FontSize; + const ImVec2 label_size = CalcTextSize(text_begin, text_end, true); + const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(line_height + (label_size.x > 0.0f ? (style.FramePadding.x*2) : 0.0f),0) + label_size); // Empty text doesn't add padding + ItemSize(bb); + if (!ItemAdd(bb, NULL)) + return; + + // Render + const float bullet_size = line_height*0.15f; + window->DrawList->AddCircleFilled(bb.Min + ImVec2(style.FramePadding.x + line_height*0.5f, line_height*0.5f), bullet_size, window->Color(ImGuiCol_Text)); + RenderText(bb.Min+ImVec2(g.FontSize + style.FramePadding.x*2,0), text_begin, text_end); +} + +void ImGui::BulletText(const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + BulletTextV(fmt, args); + va_end(args); +} + +// If returning 'true' the node is open and the user is responsible for calling TreePop +bool ImGui::TreeNodeV(const char* str_id, const char* fmt, va_list args) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args); + + if (!str_id || !str_id[0]) + str_id = fmt; + + ImGui::PushID(str_id); + const bool opened = ImGui::CollapsingHeader(g.TempBuffer, "", false); + ImGui::PopID(); + + if (opened) + ImGui::TreePush(str_id); + + return opened; +} + +bool ImGui::TreeNode(const char* str_id, const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + bool s = TreeNodeV(str_id, fmt, args); + va_end(args); + return s; +} + +// If returning 'true' the node is open and the user is responsible for calling TreePop +bool ImGui::TreeNodeV(const void* ptr_id, const char* fmt, va_list args) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args); + + if (!ptr_id) + ptr_id = fmt; + + ImGui::PushID(ptr_id); + const bool opened = ImGui::CollapsingHeader(g.TempBuffer, "", false); + ImGui::PopID(); + + if (opened) + ImGui::TreePush(ptr_id); + + return opened; +} + +bool ImGui::TreeNode(const void* ptr_id, const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + bool s = TreeNodeV(ptr_id, fmt, args); + va_end(args); + return s; +} + +bool ImGui::TreeNode(const char* str_label_id) +{ + return TreeNode(str_label_id, "%s", str_label_id); +} + +void ImGui::SetNextTreeNodeOpened(bool opened, ImGuiSetCond cond) +{ + ImGuiState& g = *GImGui; + g.SetNextTreeNodeOpenedVal = opened; + g.SetNextTreeNodeOpenedCond = cond ? cond : ImGuiSetCond_Always; +} + +void ImGui::PushID(const char* str_id) +{ + ImGuiWindow* window = GetCurrentWindow(); + window->IDStack.push_back(window->GetID(str_id)); +} + +void ImGui::PushID(const char* str_id_begin, const char* str_id_end) +{ + ImGuiWindow* window = GetCurrentWindow(); + window->IDStack.push_back(window->GetID(str_id_begin, str_id_end)); +} + +void ImGui::PushID(const void* ptr_id) +{ + ImGuiWindow* window = GetCurrentWindow(); + window->IDStack.push_back(window->GetID(ptr_id)); +} + +void ImGui::PushID(const int int_id) +{ + const void* ptr_id = (void*)(intptr_t)int_id; + ImGuiWindow* window = GetCurrentWindow(); + window->IDStack.push_back(window->GetID(ptr_id)); +} + +void ImGui::PopID() +{ + ImGuiWindow* window = GetCurrentWindow(); + window->IDStack.pop_back(); +} + +ImGuiID ImGui::GetID(const char* str_id) +{ + ImGuiWindow* window = GetCurrentWindow(); + return window->GetID(str_id); +} + +ImGuiID ImGui::GetID(const char* str_id_begin, const char* str_id_end) +{ + ImGuiWindow* window = GetCurrentWindow(); + return window->GetID(str_id_begin, str_id_end); +} + +ImGuiID ImGui::GetID(const void* ptr_id) +{ + ImGuiWindow* window = GetCurrentWindow(); + return window->GetID(ptr_id); +} + +// User can input math operators (e.g. +100) to edit a numerical values. +// NB: only call right after InputText because we are using its InitialValue storage +static void ApplyNumericalTextInput(const char* buf, float *v) +{ + while (ImCharIsSpace(*buf)) + buf++; + + // We don't support '-' op because it would conflict with inputing negative value. + // Instead you can use +-100 to subtract from an existing value + char op = buf[0]; + if (op == '+' || op == '*' || op == '/') + { + buf++; + while (ImCharIsSpace(*buf)) + buf++; + } + else + { + op = 0; + } + if (!buf[0]) + return; + + float ref_v = *v; + if (op) + if (sscanf(GImGui->InputTextState.InitialText, "%f", &ref_v) < 1) + return; + + float op_v = 0.0f; + if (sscanf(buf, "%f", &op_v) < 1) + return; + + if (op == '+') + *v = ref_v + op_v; + else if (op == '*') + *v = ref_v * op_v; + else if (op == '/') + { + if (op_v == 0.0f) + return; + *v = ref_v / op_v; + } + else + *v = op_v; +} + +// Create text input in place of a slider (when CTRL+Clicking on slider) +static bool SliderFloatAsInputText(const char* label, float* v, ImGuiID id, int decimal_precision) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + + char text_buf[64]; + ImFormatString(text_buf, IM_ARRAYSIZE(text_buf), "%.*f", decimal_precision, *v); + + SetActiveId(g.ScalarAsInputTextId); + g.HoveredId = 0; + + // Our replacement widget will override the focus ID (registered previously to allow for a TAB focus to happen) + window->FocusItemUnregister(); + + bool value_changed = ImGui::InputText(label, text_buf, IM_ARRAYSIZE(text_buf), ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_AutoSelectAll); + if (g.ScalarAsInputTextId == 0) + { + // First frame + IM_ASSERT(g.ActiveId == id); // InputText ID expected to match the Slider ID (else we'd need to store them both, which is also possible) + g.ScalarAsInputTextId = g.ActiveId; + g.HoveredId = id; + } + else if (g.ActiveId != g.ScalarAsInputTextId) + { + // Release + g.ScalarAsInputTextId = 0; + } + if (value_changed) + { + ApplyNumericalTextInput(text_buf, v); + } + return value_changed; +} + +// Parse display precision back from the display format string +static inline void ParseFormat(const char* fmt, int& decimal_precision) +{ + while ((fmt = strchr(fmt, '%')) != NULL) + { + fmt++; + if (fmt[0] == '%') { fmt++; continue; } // Ignore "%%" + while (*fmt >= '0' && *fmt <= '9') + fmt++; + if (*fmt == '.') + { + decimal_precision = atoi(fmt + 1); + if (decimal_precision < 0 || decimal_precision > 10) + decimal_precision = 3; + } + break; + } +} + +static inline float RoundScalar(float value, int decimal_precision) +{ + // Round past decimal precision + // 0: 1, 1: 0.1, 2: 0.01, etc. + // So when our value is 1.99999 with a precision of 0.001 we'll end up rounding to 2.0 + // FIXME: Investigate better rounding methods + const float min_step = 1.0f / powf(10.0f, (float)decimal_precision); + const float remainder = fmodf(value, min_step); + if (remainder <= min_step*0.5f) + value -= remainder; + else + value += (min_step - remainder); + return value; +} + +static bool SliderScalarBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_min, float v_max, float power, int decimal_precision, bool horizontal) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + const ImGuiStyle& style = g.Style; + + // Draw frame + RenderFrame(frame_bb.Min, frame_bb.Max, window->Color(ImGuiCol_FrameBg), true, style.FrameRounding); + + const bool is_non_linear = fabsf(power - 1.0f) > 0.0001f; + + const float padding = horizontal ? style.FramePadding.x : style.FramePadding.y; + const float slider_sz = horizontal ? (frame_bb.GetWidth() - padding * 2.0f) : (frame_bb.GetHeight() - padding * 2.0f); + float grab_sz; + if (decimal_precision > 0) + grab_sz = ImMin(style.GrabMinSize, slider_sz); + else + grab_sz = ImMin(ImMax(1.0f * (slider_sz / (v_max-v_min+1.0f)), style.GrabMinSize), slider_sz); // Integer sliders, if possible have the grab size represent 1 unit + const float slider_usable_sz = slider_sz - grab_sz; + const float slider_usable_pos_min = (horizontal ? frame_bb.Min.x : frame_bb.Min.y) + padding + grab_sz*0.5f; + const float slider_usable_pos_max = (horizontal ? frame_bb.Max.x : frame_bb.Max.y) - padding - grab_sz*0.5f; + + bool value_changed = false; + + // For logarithmic sliders that cross over sign boundary we want the exponential increase to be symmetric around 0.0f + float linear_zero_pos = 0.0f; // 0.0->1.0f + if (v_min * v_max < 0.0f) + { + // Different sign + const float linear_dist_min_to_0 = powf(fabsf(0.0f - v_min), 1.0f/power); + const float linear_dist_max_to_0 = powf(fabsf(v_max - 0.0f), 1.0f/power); + linear_zero_pos = linear_dist_min_to_0 / (linear_dist_min_to_0+linear_dist_max_to_0); + } + else + { + // Same sign + linear_zero_pos = v_min < 0.0f ? 1.0f : 0.0f; + } + + // Process clicking on the slider + if (g.ActiveId == id) + { + if (g.IO.MouseDown[0]) + { + const float mouse_abs_pos = horizontal ? g.IO.MousePos.x : g.IO.MousePos.y; + float normalized_pos = ImClamp((mouse_abs_pos - slider_usable_pos_min) / slider_usable_sz, 0.0f, 1.0f); + if (!horizontal) + normalized_pos = 1.0f - normalized_pos; + + float new_value; + if (is_non_linear) + { + // Account for logarithmic scale on both sides of the zero + if (normalized_pos < linear_zero_pos) + { + // Negative: rescale to the negative range before powering + float a = 1.0f - (normalized_pos / linear_zero_pos); + a = powf(a, power); + new_value = ImLerp(ImMin(v_max,0.0f), v_min, a); + } + else + { + // Positive: rescale to the positive range before powering + float a; + if (fabsf(linear_zero_pos - 1.0f) > 1.e-6) + a = (normalized_pos - linear_zero_pos) / (1.0f - linear_zero_pos); + else + a = normalized_pos; + a = powf(a, power); + new_value = ImLerp(ImMax(v_min,0.0f), v_max, a); + } + } + else + { + // Linear slider + new_value = ImLerp(v_min, v_max, normalized_pos); + } + + // Round past decimal precision + new_value = RoundScalar(new_value, decimal_precision); + + if (*v != new_value) + { + *v = new_value; + value_changed = true; + } + } + else + { + SetActiveId(0); + } + } + + // Calculate slider grab positioning + float grab_t; + if (is_non_linear) + { + float v_clamped = ImClamp(*v, v_min, v_max); + if (v_clamped < 0.0f) + { + const float f = 1.0f - (v_clamped - v_min) / (ImMin(0.0f,v_max) - v_min); + grab_t = (1.0f - powf(f, 1.0f/power)) * linear_zero_pos; + } + else + { + const float f = (v_clamped - ImMax(0.0f,v_min)) / (v_max - ImMax(0.0f,v_min)); + grab_t = linear_zero_pos + powf(f, 1.0f/power) * (1.0f - linear_zero_pos); + } + } + else + { + // Linear slider + grab_t = (ImClamp(*v, v_min, v_max) - v_min) / (v_max - v_min); + } + + // Draw + if (!horizontal) + grab_t = 1.0f - grab_t; + const float grab_pos = ImLerp(slider_usable_pos_min, slider_usable_pos_max, grab_t); + ImRect grab_bb; + if (horizontal) + grab_bb = ImRect(ImVec2(grab_pos - grab_sz*0.5f, frame_bb.Min.y + 2.0f), ImVec2(grab_pos + grab_sz*0.5f, frame_bb.Max.y - 2.0f)); + else + grab_bb = ImRect(ImVec2(frame_bb.Min.x + 2.0f, grab_pos - grab_sz*0.5f), ImVec2(frame_bb.Max.x - 2.0f, grab_pos + grab_sz*0.5f)); + window->DrawList->AddRectFilled(grab_bb.Min, grab_bb.Max, window->Color(g.ActiveId == id ? ImGuiCol_SliderGrabActive : ImGuiCol_SliderGrab)); + + return value_changed; +} + +// Use power!=1.0 for logarithmic sliders. +// Adjust display_format to decorate the value with a prefix or a suffix. +// "%.3f" 1.234 +// "%5.2f secs" 01.23 secs +// "Gold: %.0f" Gold: 1 +bool ImGui::SliderFloat(const char* label, float* v, float v_min, float v_max, const char* display_format, float power) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + const ImGuiStyle& style = g.Style; + const ImGuiID id = window->GetID(label); + const float w = ImGui::CalcItemWidth(); + + const ImVec2 label_size = CalcTextSize(label, NULL, true); + const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y) + style.FramePadding*2.0f); + const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f)); + + // NB- we don't call ItemSize() yet because we may turn into a text edit box below + if (!ItemAdd(total_bb, &id)) + { + ItemSize(total_bb, style.FramePadding.y); + return false; + } + + const bool hovered = IsHovered(frame_bb, id); + if (hovered) + g.HoveredId = id; + + if (!display_format) + display_format = "%.3f"; + int decimal_precision = 3; + ParseFormat(display_format, decimal_precision); + + // Tabbing or CTRL-clicking on Slider turns it into an input box + bool start_text_input = false; + const bool tab_focus_requested = window->FocusItemRegister(g.ActiveId == id); + if (tab_focus_requested || (hovered && g.IO.MouseClicked[0])) + { + SetActiveId(id); + FocusWindow(window); + + const bool is_ctrl_down = g.IO.KeyCtrl; + if (tab_focus_requested || is_ctrl_down) + { + start_text_input = true; + g.ScalarAsInputTextId = 0; + } + } + if (start_text_input || (g.ActiveId == id && g.ScalarAsInputTextId == id)) + return SliderFloatAsInputText(label, v, id, decimal_precision); + + ItemSize(total_bb, style.FramePadding.y); + + // Actual slider behavior + render grab + const bool value_changed = SliderScalarBehavior(frame_bb, id, v, v_min, v_max, power, decimal_precision, true); + + // Display value using user-provided display format so user can add prefix/suffix/decorations to the value. + char value_buf[64]; + const char* value_buf_end = value_buf + ImFormatString(value_buf, IM_ARRAYSIZE(value_buf), display_format, *v); + const ImVec2 value_text_size = CalcTextSize(value_buf, value_buf_end, true); + RenderTextClipped(ImVec2(ImMax(frame_bb.Min.x + style.FramePadding.x, frame_bb.GetCenter().x - value_text_size.x*0.5f), frame_bb.Min.y + style.FramePadding.y), value_buf, value_buf_end, &value_text_size, frame_bb.Max); + + if (label_size.x > 0.0f) + RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); + + return value_changed; +} + +bool ImGui::VSliderFloat(const char* label, const ImVec2& size, float* v, float v_min, float v_max, const char* display_format, float power) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + const ImGuiStyle& style = g.Style; + const ImGuiID id = window->GetID(label); + + const ImVec2 label_size = CalcTextSize(label, NULL, true); + const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + size); + const ImRect bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f)); + + ItemSize(bb, style.FramePadding.y); + if (!ItemAdd(frame_bb, &id)) + return false; + + const bool hovered = IsHovered(frame_bb, id); + if (hovered) + g.HoveredId = id; + + if (!display_format) + display_format = "%.3f"; + int decimal_precision = 3; + ParseFormat(display_format, decimal_precision); + + if (hovered && g.IO.MouseClicked[0]) + { + SetActiveId(id); + FocusWindow(window); + } + + // Actual slider behavior + render grab + bool value_changed = SliderScalarBehavior(frame_bb, id, v, v_min, v_max, power, decimal_precision, false); + + // Display value using user-provided display format so user can add prefix/suffix/decorations to the value. + // For the vertical slider we allow centered text to overlap the frame padding + char value_buf[64]; + char* value_buf_end = value_buf + ImFormatString(value_buf, IM_ARRAYSIZE(value_buf), display_format, *v); + const ImVec2 value_text_size = CalcTextSize(value_buf, value_buf_end, true); + RenderTextClipped(ImVec2(ImMax(frame_bb.Min.x, frame_bb.GetCenter().x - value_text_size.x*0.5f), frame_bb.Min.y + style.FramePadding.y), value_buf, value_buf_end, &value_text_size, frame_bb.Max); + + if (label_size.x > 0.0f) + RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); + + return value_changed; +} + +bool ImGui::SliderAngle(const char* label, float* v_rad, float v_degrees_min, float v_degrees_max) +{ + float v_deg = (*v_rad) * 360.0f / (2*PI); + bool value_changed = ImGui::SliderFloat(label, &v_deg, v_degrees_min, v_degrees_max, "%.0f deg", 1.0f); + *v_rad = v_deg * (2*PI) / 360.0f; + return value_changed; +} + +bool ImGui::SliderInt(const char* label, int* v, int v_min, int v_max, const char* display_format) +{ + if (!display_format) + display_format = "%.0f"; + float v_f = (float)*v; + bool value_changed = ImGui::SliderFloat(label, &v_f, (float)v_min, (float)v_max, display_format, 1.0f); + *v = (int)v_f; + return value_changed; +} + +bool ImGui::VSliderInt(const char* label, const ImVec2& size, int* v, int v_min, int v_max, const char* display_format) +{ + if (!display_format) + display_format = "%.0f"; + float v_f = (float)*v; + bool value_changed = ImGui::VSliderFloat(label, size, &v_f, (float)v_min, (float)v_max, display_format, 1.0f); + *v = (int)v_f; + return value_changed; +} + +// Add multiple sliders on 1 line for compact edition of multiple components +static bool SliderFloatN(const char* label, float* v, int components, float v_min, float v_max, const char* display_format, float power) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + const ImGuiStyle& style = g.Style; + const float w_full = ImGui::CalcItemWidth(); + const float w_item_one = ImMax(1.0f, (float)(int)((w_full - (style.FramePadding.x*2.0f + style.ItemInnerSpacing.x)*(components-1)) / (float)components)); + const float w_item_last = ImMax(1.0f, (float)(int)(w_full - (w_item_one + style.FramePadding.x*2.0f + style.ItemInnerSpacing.x)*(components-1))); + + bool value_changed = false; + ImGui::BeginGroup(); + ImGui::PushID(label); + ImGui::PushItemWidth(w_item_one); + for (int i = 0; i < components; i++) + { + ImGui::PushID(i); + if (i + 1 == components) + { + ImGui::PopItemWidth(); + ImGui::PushItemWidth(w_item_last); + } + value_changed |= ImGui::SliderFloat("##v", &v[i], v_min, v_max, display_format, power); + ImGui::SameLine(0, (int)style.ItemInnerSpacing.x); + ImGui::PopID(); + } + ImGui::PopItemWidth(); + ImGui::PopID(); + + ImGui::TextUnformatted(label, FindTextDisplayEnd(label)); + ImGui::EndGroup(); + + return value_changed; +} + +bool ImGui::SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* display_format, float power) +{ + return SliderFloatN(label, v, 2, v_min, v_max, display_format, power); +} + +bool ImGui::SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* display_format, float power) +{ + return SliderFloatN(label, v, 3, v_min, v_max, display_format, power); +} + +bool ImGui::SliderFloat4(const char* label, float v[4], float v_min, float v_max, const char* display_format, float power) +{ + return SliderFloatN(label, v, 4, v_min, v_max, display_format, power); +} + +static bool SliderIntN(const char* label, int* v, int components, int v_min, int v_max, const char* display_format) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + const ImGuiStyle& style = g.Style; + const float w_full = ImGui::CalcItemWidth(); + const float w_item_one = ImMax(1.0f, (float)(int)((w_full - (style.FramePadding.x*2.0f + style.ItemInnerSpacing.x)*(components-1)) / (float)components)); + const float w_item_last = ImMax(1.0f, (float)(int)(w_full - (w_item_one + style.FramePadding.x*2.0f + style.ItemInnerSpacing.x)*(components-1))); + + bool value_changed = false; + ImGui::BeginGroup(); + ImGui::PushID(label); + ImGui::PushItemWidth(w_item_one); + for (int i = 0; i < components; i++) + { + ImGui::PushID(i); + if (i + 1 == components) + { + ImGui::PopItemWidth(); + ImGui::PushItemWidth(w_item_last); + } + value_changed |= ImGui::SliderInt("##v", &v[i], v_min, v_max, display_format); + ImGui::SameLine(0, (int)style.ItemInnerSpacing.x); + ImGui::PopID(); + } + ImGui::PopItemWidth(); + ImGui::PopID(); + + ImGui::TextUnformatted(label, FindTextDisplayEnd(label)); + ImGui::EndGroup(); + + return value_changed; +} + +bool ImGui::SliderInt2(const char* label, int v[2], int v_min, int v_max, const char* display_format) +{ + return SliderIntN(label, v, 2, v_min, v_max, display_format); +} + +bool ImGui::SliderInt3(const char* label, int v[3], int v_min, int v_max, const char* display_format) +{ + return SliderIntN(label, v, 3, v_min, v_max, display_format); +} + +bool ImGui::SliderInt4(const char* label, int v[4], int v_min, int v_max, const char* display_format) +{ + return SliderIntN(label, v, 4, v_min, v_max, display_format); +} + +// FIXME-WIP: Work in progress. May change API / behavior. +static bool DragScalarBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_speed, float v_min, float v_max, int decimal_precision, float power) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + const ImGuiStyle& style = g.Style; + + // Draw frame + const ImU32 frame_col = window->Color(g.ActiveId == id ? ImGuiCol_FrameBgActive : g.HoveredId == id ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg); + RenderFrame(frame_bb.Min, frame_bb.Max, frame_col, true, style.FrameRounding); + + bool value_changed = false; + + // Process clicking on the drag + if (g.ActiveId == id) + { + if (g.IO.MouseDown[0]) + { + if (g.ActiveIdIsJustActivated) + { + // Lock current value on click + g.DragCurrentValue = *v; + g.DragLastMouseDelta = ImVec2(0.f, 0.f); + } + + const ImVec2 mouse_drag_delta = ImGui::GetMouseDragDelta(0, 1.0f); + if (fabsf(mouse_drag_delta.x - g.DragLastMouseDelta.x) > 0.0f) + { + float speed = v_speed; + if (speed == 0.0f && (v_max - v_min) != 0.0f && (v_max - v_min) < FLT_MAX) + speed = (v_max - v_min) * g.DragSpeedDefaultRatio; + if (g.IO.KeyShift && g.DragSpeedScaleFast >= 0.0f) + speed = speed * g.DragSpeedScaleFast; + if (g.IO.KeyAlt && g.DragSpeedScaleSlow >= 0.0f) + speed = speed * g.DragSpeedScaleSlow; + + float v_cur = g.DragCurrentValue; + float delta = (mouse_drag_delta.x - g.DragLastMouseDelta.x) * speed; + if (fabsf(power - 1.0f) > 0.001f) + { + // Logarithmic curve on both side of 0.0 + float v0_abs = v_cur >= 0.0f ? v_cur : -v_cur; + float v0_sign = v_cur >= 0.0f ? 1.0f : -1.0f; + float v1 = powf(v0_abs, 1.0f / power) + (delta * v0_sign); + float v1_abs = v1 >= 0.0f ? v1 : -v1; + float v1_sign = v1 >= 0.0f ? 1.0f : -1.0f; // Crossed sign line + v_cur = powf(v1_abs, power) * v0_sign * v1_sign; // Reapply sign + } + else + { + v_cur += delta; + } + g.DragLastMouseDelta.x = mouse_drag_delta.x; + + // Clamp + if (v_min < v_max) + v_cur = ImClamp(v_cur, v_min, v_max); + g.DragCurrentValue = v_cur; + + // Round to user desired precision, then apply + v_cur = RoundScalar(v_cur, decimal_precision); + if (*v != v_cur) + { + *v = v_cur; + value_changed = true; + } + } + } + else + { + SetActiveId(0); + } + } + + return value_changed; +} + +bool ImGui::DragFloat(const char* label, float *v, float v_speed, float v_min, float v_max, const char* display_format, float power) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + const ImGuiStyle& style = g.Style; + const ImGuiID id = window->GetID(label); + const float w = ImGui::CalcItemWidth(); + + const ImVec2 label_size = CalcTextSize(label, NULL, true); + const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y) + style.FramePadding*2.0f); + const ImRect inner_bb(frame_bb.Min + style.FramePadding, frame_bb.Max - style.FramePadding); + const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f)); + + // NB- we don't call ItemSize() yet because we may turn into a text edit box below + if (!ItemAdd(total_bb, &id)) + { + ItemSize(total_bb, style.FramePadding.y); + return false; + } + + const bool hovered = IsHovered(frame_bb, id); + if (hovered) + g.HoveredId = id; + + if (!display_format) + display_format = "%.3f"; + int decimal_precision = 3; + ParseFormat(display_format, decimal_precision); + + // Tabbing or CTRL-clicking on Drag turns it into an input box + bool start_text_input = false; + const bool tab_focus_requested = window->FocusItemRegister(g.ActiveId == id); + if (tab_focus_requested || (hovered && (g.IO.MouseClicked[0] | g.IO.MouseDoubleClicked[0]))) + { + SetActiveId(id); + FocusWindow(window); + + if (tab_focus_requested || g.IO.KeyCtrl || g.IO.MouseDoubleClicked[0]) + { + start_text_input = true; + g.ScalarAsInputTextId = 0; + } + } + if (start_text_input || (g.ActiveId == id && g.ScalarAsInputTextId == id)) + return SliderFloatAsInputText(label, v, id, decimal_precision); + + ItemSize(total_bb, style.FramePadding.y); + + // Actual drag behavior + const bool value_changed = DragScalarBehavior(frame_bb, id, v, v_speed, v_min, v_max, decimal_precision, power); + + // Display value using user-provided display format so user can add prefix/suffix/decorations to the value. + char value_buf[64]; + const char* value_buf_end = value_buf + ImFormatString(value_buf, IM_ARRAYSIZE(value_buf), display_format, *v); + const ImVec2 value_text_size = CalcTextSize(value_buf, value_buf_end, true); + RenderTextClipped(ImVec2(ImMax(frame_bb.Min.x + style.FramePadding.x, inner_bb.GetCenter().x - value_text_size.x*0.5f), frame_bb.Min.y + style.FramePadding.y), value_buf, value_buf_end, &value_text_size, frame_bb.Max); + + if (label_size.x > 0.0f) + RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, inner_bb.Min.y), label); + + return value_changed; +} + +static bool DragFloatN(const char* label, float* v, int components, float v_speed, float v_min, float v_max, const char* display_format, float power) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + const ImGuiStyle& style = g.Style; + const float w_full = ImGui::CalcItemWidth(); + const float w_item_one = ImMax(1.0f, (float)(int)((w_full - (style.FramePadding.x*2.0f + style.ItemInnerSpacing.x)*(components-1)) / (float)components)); + const float w_item_last = ImMax(1.0f, (float)(int)(w_full - (w_item_one + style.FramePadding.x*2.0f + style.ItemInnerSpacing.x)*(components-1))); + + bool value_changed = false; + ImGui::BeginGroup(); + ImGui::PushID(label); + ImGui::PushItemWidth(w_item_one); + for (int i = 0; i < components; i++) + { + ImGui::PushID(i); + if (i + 1 == components) + { + ImGui::PopItemWidth(); + ImGui::PushItemWidth(w_item_last); + } + value_changed |= ImGui::DragFloat("##v", &v[i], v_speed, v_min, v_max, display_format, power); + ImGui::SameLine(0, (int)style.ItemInnerSpacing.x); + ImGui::PopID(); + } + ImGui::PopItemWidth(); + ImGui::PopID(); + + ImGui::TextUnformatted(label, FindTextDisplayEnd(label)); + ImGui::EndGroup(); + + return value_changed; +} + +bool ImGui::DragFloat2(const char* label, float v[2], float v_speed, float v_min, float v_max, const char* display_format, float power) +{ + return DragFloatN(label, v, 2, v_speed, v_min, v_max, display_format, power); +} + +bool ImGui::DragFloat3(const char* label, float v[2], float v_speed, float v_min, float v_max, const char* display_format, float power) +{ + return DragFloatN(label, v, 3, v_speed, v_min, v_max, display_format, power); +} + +bool ImGui::DragFloat4(const char* label, float v[2], float v_speed, float v_min, float v_max, const char* display_format, float power) +{ + return DragFloatN(label, v, 4, v_speed, v_min, v_max, display_format, power); +} + +// NB: v_speed is float to allow adjusting the drag speed with more precision +bool ImGui::DragInt(const char* label, int* v, float v_speed, int v_min, int v_max, const char* display_format) +{ + if (!display_format) + display_format = "%.0f"; + float v_f = (float)*v; + bool value_changed = ImGui::DragFloat(label, &v_f, v_speed, (float)v_min, (float)v_max, display_format); + *v = (int)v_f; + return value_changed; +} + +static bool DragIntN(const char* label, int* v, int components, float v_speed, int v_min, int v_max, const char* display_format) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + const ImGuiStyle& style = g.Style; + const float w_full = ImGui::CalcItemWidth(); + const float w_item_one = ImMax(1.0f, (float)(int)((w_full - (style.FramePadding.x*2.0f + style.ItemInnerSpacing.x)*(components-1)) / (float)components)); + const float w_item_last = ImMax(1.0f, (float)(int)(w_full - (w_item_one + style.FramePadding.x*2.0f + style.ItemInnerSpacing.x)*(components-1))); + + bool value_changed = false; + ImGui::BeginGroup(); + ImGui::PushID(label); + ImGui::PushItemWidth(w_item_one); + for (int i = 0; i < components; i++) + { + ImGui::PushID(i); + if (i + 1 == components) + { + ImGui::PopItemWidth(); + ImGui::PushItemWidth(w_item_last); + } + value_changed |= ImGui::DragInt("##v", &v[i], v_speed, v_min, v_max, display_format); + ImGui::SameLine(0, (int)style.ItemInnerSpacing.x); + ImGui::PopID(); + } + ImGui::PopItemWidth(); + ImGui::PopID(); + + ImGui::TextUnformatted(label, FindTextDisplayEnd(label)); + ImGui::EndGroup(); + + return value_changed; +} + +bool ImGui::DragInt2(const char* label, int v[2], float v_speed, int v_min, int v_max, const char* display_format) +{ + return DragIntN(label, v, 2, v_speed, v_min, v_max, display_format); +} + +bool ImGui::DragInt3(const char* label, int v[3], float v_speed, int v_min, int v_max, const char* display_format) +{ + return DragIntN(label, v, 3, v_speed, v_min, v_max, display_format); +} + +bool ImGui::DragInt4(const char* label, int v[4], float v_speed, int v_min, int v_max, const char* display_format) +{ + return DragIntN(label, v, 4, v_speed, v_min, v_max, display_format); +} + +enum ImGuiPlotType +{ + ImGuiPlotType_Lines, + ImGuiPlotType_Histogram +}; + +static void Plot(ImGuiPlotType plot_type, const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + + const ImGuiStyle& style = g.Style; + + const ImVec2 label_size = ImGui::CalcTextSize(label, NULL, true); + if (graph_size.x == 0.0f) + graph_size.x = ImGui::CalcItemWidth() + (style.FramePadding.x * 2); + if (graph_size.y == 0.0f) + graph_size.y = label_size.y + (style.FramePadding.y * 2); + + const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(graph_size.x, graph_size.y)); + const ImRect inner_bb(frame_bb.Min + style.FramePadding, frame_bb.Max - style.FramePadding); + const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0)); + ItemSize(total_bb, style.FramePadding.y); + if (!ItemAdd(total_bb, NULL)) + return; + + // Determine scale from values if not specified + if (scale_min == FLT_MAX || scale_max == FLT_MAX) + { + float v_min = FLT_MAX; + float v_max = -FLT_MAX; + for (int i = 0; i < values_count; i++) + { + const float v = values_getter(data, i); + v_min = ImMin(v_min, v); + v_max = ImMax(v_max, v); + } + if (scale_min == FLT_MAX) + scale_min = v_min; + if (scale_max == FLT_MAX) + scale_max = v_max; + } + + RenderFrame(frame_bb.Min, frame_bb.Max, window->Color(ImGuiCol_FrameBg), true, style.FrameRounding); + + int res_w = ImMin((int)graph_size.x, values_count); + if (plot_type == ImGuiPlotType_Lines) + res_w -= 1; + + // Tooltip on hover + int v_hovered = -1; + if (IsMouseHoveringRect(inner_bb)) + { + const float t = ImClamp((g.IO.MousePos.x - inner_bb.Min.x) / (inner_bb.Max.x - inner_bb.Min.x), 0.0f, 0.9999f); + const int v_idx = (int)(t * (values_count + ((plot_type == ImGuiPlotType_Lines) ? -1 : 0))); + IM_ASSERT(v_idx >= 0 && v_idx < values_count); + + const float v0 = values_getter(data, (v_idx + values_offset) % values_count); + const float v1 = values_getter(data, (v_idx + 1 + values_offset) % values_count); + if (plot_type == ImGuiPlotType_Lines) + ImGui::SetTooltip("%d: %8.4g\n%d: %8.4g", v_idx, v0, v_idx+1, v1); + else if (plot_type == ImGuiPlotType_Histogram) + ImGui::SetTooltip("%d: %8.4g", v_idx, v0); + v_hovered = v_idx; + } + + const float t_step = 1.0f / (float)res_w; + + float v0 = values_getter(data, (0 + values_offset) % values_count); + float t0 = 0.0f; + ImVec2 p0 = ImVec2( t0, 1.0f - ImSaturate((v0 - scale_min) / (scale_max - scale_min)) ); + + const ImU32 col_base = window->Color((plot_type == ImGuiPlotType_Lines) ? ImGuiCol_PlotLines : ImGuiCol_PlotHistogram); + const ImU32 col_hovered = window->Color((plot_type == ImGuiPlotType_Lines) ? ImGuiCol_PlotLinesHovered : ImGuiCol_PlotHistogramHovered); + + for (int n = 0; n < res_w; n++) + { + const float t1 = t0 + t_step; + const int v_idx = (int)(t0 * values_count); + IM_ASSERT(v_idx >= 0 && v_idx < values_count); + const float v1 = values_getter(data, (v_idx + values_offset + 1) % values_count); + const ImVec2 p1 = ImVec2( t1, 1.0f - ImSaturate((v1 - scale_min) / (scale_max - scale_min)) ); + + // NB- Draw calls are merged together by the DrawList system. + if (plot_type == ImGuiPlotType_Lines) + window->DrawList->AddLine(ImLerp(inner_bb.Min, inner_bb.Max, p0), ImLerp(inner_bb.Min, inner_bb.Max, p1), v_hovered == v_idx ? col_hovered : col_base); + else if (plot_type == ImGuiPlotType_Histogram) + window->DrawList->AddRectFilled(ImLerp(inner_bb.Min, inner_bb.Max, p0), ImLerp(inner_bb.Min, inner_bb.Max, ImVec2(p1.x, 1.0f))+ImVec2(-1,0), v_hovered == v_idx ? col_hovered : col_base); + + t0 = t1; + p0 = p1; + } + + // Text overlay + if (overlay_text) + RenderText(ImVec2(inner_bb.GetCenter().x - ImGui::CalcTextSize(overlay_text, NULL, true).x*0.5f, frame_bb.Min.y + style.FramePadding.y), overlay_text); + + RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, inner_bb.Min.y), label); +} + +struct ImGuiPlotArrayGetterData +{ + const float* Values; + size_t Stride; + + ImGuiPlotArrayGetterData(const float* values, size_t stride) { Values = values; Stride = stride; } +}; + +static float Plot_ArrayGetter(void* data, int idx) +{ + ImGuiPlotArrayGetterData* plot_data = (ImGuiPlotArrayGetterData*)data; + const float v = *(float*)(void*)((unsigned char*)plot_data->Values + (size_t)idx * plot_data->Stride); + return v; +} + +void ImGui::PlotLines(const char* label, const float* values, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size, size_t stride) +{ + ImGuiPlotArrayGetterData data(values, stride); + Plot(ImGuiPlotType_Lines, label, &Plot_ArrayGetter, (void*)&data, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size); +} + +void ImGui::PlotLines(const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size) +{ + Plot(ImGuiPlotType_Lines, label, values_getter, data, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size); +} + +void ImGui::PlotHistogram(const char* label, const float* values, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size, size_t stride) +{ + ImGuiPlotArrayGetterData data(values, stride); + Plot(ImGuiPlotType_Histogram, label, &Plot_ArrayGetter, (void*)&data, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size); +} + +void ImGui::PlotHistogram(const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size) +{ + Plot(ImGuiPlotType_Histogram, label, values_getter, data, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size); +} + +bool ImGui::Checkbox(const char* label, bool* v) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + const ImGuiStyle& style = g.Style; + const ImGuiID id = window->GetID(label); + const ImVec2 label_size = CalcTextSize(label, NULL, true); + + const ImRect check_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(label_size.y + style.FramePadding.y*2, label_size.y + style.FramePadding.y*2)); + ItemSize(check_bb, style.FramePadding.y); + + ImRect total_bb = check_bb; + if (label_size.x > 0) + SameLine(0, (int)style.ItemInnerSpacing.x); + const ImRect text_bb(window->DC.CursorPos + ImVec2(0,style.FramePadding.y), window->DC.CursorPos + ImVec2(0,style.FramePadding.y) + label_size); + if (label_size.x > 0) + { + ItemSize(ImVec2(text_bb.GetWidth(), check_bb.GetHeight()), style.FramePadding.y); + total_bb = ImRect(ImMin(check_bb.Min, text_bb.Min), ImMax(check_bb.Max, text_bb.Max)); + } + + if (!ItemAdd(total_bb, &id)) + return false; + + bool hovered, held; + bool pressed = ButtonBehavior(total_bb, id, &hovered, &held, true); + if (pressed) + *v = !(*v); + + RenderFrame(check_bb.Min, check_bb.Max, window->Color((held && hovered) ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg), true, style.FrameRounding); + if (*v) + { + const float check_sz = ImMin(check_bb.GetWidth(), check_bb.GetHeight()); + const float pad = check_sz < 8.0f ? 1.0f : check_sz < 13.0f ? 2.0f : 3.0f; + window->DrawList->AddRectFilled(check_bb.Min+ImVec2(pad,pad), check_bb.Max-ImVec2(pad,pad), window->Color(ImGuiCol_CheckMark), style.FrameRounding); + } + + if (g.LogEnabled) + LogText(text_bb.GetTL(), *v ? "[x]" : "[ ]"); + RenderText(text_bb.GetTL(), label); + + return pressed; +} + +bool ImGui::CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value) +{ + bool v = (*flags & flags_value) ? true : false; + bool pressed = ImGui::Checkbox(label, &v); + if (v) + *flags |= flags_value; + else + *flags &= ~flags_value; + return pressed; +} + +bool ImGui::RadioButton(const char* label, bool active) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + const ImGuiStyle& style = g.Style; + const ImGuiID id = window->GetID(label); + const ImVec2 label_size = CalcTextSize(label, NULL, true); + + const ImRect check_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(label_size.y + style.FramePadding.y*2-1, label_size.y + style.FramePadding.y*2-1)); + ItemSize(check_bb, style.FramePadding.y); + + ImRect total_bb = check_bb; + if (label_size.x > 0) + SameLine(0, (int)style.ItemInnerSpacing.x); + const ImRect text_bb(window->DC.CursorPos + ImVec2(0, style.FramePadding.y), window->DC.CursorPos + ImVec2(0, style.FramePadding.y) + label_size); + if (label_size.x > 0) + { + ItemSize(ImVec2(text_bb.GetWidth(), check_bb.GetHeight()), style.FramePadding.y); + total_bb.Add(text_bb); + } + + if (!ItemAdd(total_bb, &id)) + return false; + + ImVec2 center = check_bb.GetCenter(); + center.x = (float)(int)center.x + 0.5f; + center.y = (float)(int)center.y + 0.5f; + const float radius = check_bb.GetHeight() * 0.5f; + + bool hovered, held; + bool pressed = ButtonBehavior(total_bb, id, &hovered, &held, true); + + window->DrawList->AddCircleFilled(center, radius, window->Color((held && hovered) ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg), 16); + if (active) + { + const float check_sz = ImMin(check_bb.GetWidth(), check_bb.GetHeight()); + const float pad = check_sz < 8.0f ? 1.0f : check_sz < 13.0f ? 2.0f : 3.0f; + window->DrawList->AddCircleFilled(center, radius-pad, window->Color(ImGuiCol_CheckMark), 16); + } + + if (window->Flags & ImGuiWindowFlags_ShowBorders) + { + window->DrawList->AddCircle(center+ImVec2(1,1), radius, window->Color(ImGuiCol_BorderShadow), 16); + window->DrawList->AddCircle(center, radius, window->Color(ImGuiCol_Border), 16); + } + + if (g.LogEnabled) + LogText(text_bb.GetTL(), active ? "(x)" : "( )"); + RenderText(text_bb.GetTL(), label); + + return pressed; +} + +bool ImGui::RadioButton(const char* label, int* v, int v_button) +{ + const bool pressed = ImGui::RadioButton(label, *v == v_button); + if (pressed) + { + *v = v_button; + } + return pressed; +} + +// Wrapper for stb_textedit.h to edit text (our wrapper is for: statically sized buffer, single-line, wchar characters. InputText converts between UTF-8 and wchar) +static int STB_TEXTEDIT_STRINGLEN(const STB_TEXTEDIT_STRING* obj) { return (int)ImStrlenW(obj->Text); } +static ImWchar STB_TEXTEDIT_GETCHAR(const STB_TEXTEDIT_STRING* obj, int idx) { return obj->Text[idx]; } +static float STB_TEXTEDIT_GETWIDTH(STB_TEXTEDIT_STRING* obj, int line_start_idx, int char_idx) { (void)line_start_idx; return obj->Font->CalcTextSizeW(obj->FontSize, FLT_MAX, &obj->Text[char_idx], &obj->Text[char_idx]+1, NULL).x; } +static int STB_TEXTEDIT_KEYTOTEXT(int key) { return key >= 0x10000 ? 0 : key; } +static ImWchar STB_TEXTEDIT_NEWLINE = '\n'; +static void STB_TEXTEDIT_LAYOUTROW(StbTexteditRow* r, STB_TEXTEDIT_STRING* obj, int line_start_idx) +{ + const ImWchar* text_remaining = NULL; + const ImVec2 size = obj->Font->CalcTextSizeW(obj->FontSize, FLT_MAX, obj->Text + line_start_idx, NULL, &text_remaining); + r->x0 = 0.0f; + r->x1 = size.x; + r->baseline_y_delta = size.y; + r->ymin = 0.0f; + r->ymax = size.y; + r->num_chars = (int)(text_remaining - (obj->Text + line_start_idx)); +} + +static bool is_separator(unsigned int c) { return c==',' || c==';' || c=='(' || c==')' || c=='{' || c=='}' || c=='[' || c==']' || c=='|'; } +#define STB_TEXTEDIT_IS_SPACE(CH) ( ImCharIsSpace((unsigned int)CH) || is_separator((unsigned int)CH) ) +static void STB_TEXTEDIT_DELETECHARS(STB_TEXTEDIT_STRING* obj, int pos, int n) +{ + ImWchar* dst = obj->Text + pos; + + // We maintain our buffer length in both UTF-8 and wchar formats + obj->CurLenA -= ImTextCountUtf8BytesFromStr(dst, dst + n); + obj->CurLenW -= n; + + // Offset remaining text + const ImWchar* src = obj->Text + pos + n; + while (ImWchar c = *src++) + *dst++ = c; + *dst = '\0'; +} + +static bool STB_TEXTEDIT_INSERTCHARS(STB_TEXTEDIT_STRING* obj, int pos, const ImWchar* new_text, int new_text_len) +{ + const size_t text_len = obj->CurLenW; + if ((size_t)new_text_len + text_len + 1 > IM_ARRAYSIZE(obj->Text)) + return false; + + const int new_text_len_utf8 = ImTextCountUtf8BytesFromStr(new_text, new_text + new_text_len); + if ((size_t)new_text_len_utf8 + obj->CurLenA + 1 > obj->BufSizeA) + return false; + + if (pos != (int)text_len) + memmove(obj->Text + (size_t)pos + new_text_len, obj->Text + (size_t)pos, (text_len - (size_t)pos) * sizeof(ImWchar)); + memcpy(obj->Text + (size_t)pos, new_text, (size_t)new_text_len * sizeof(ImWchar)); + + obj->CurLenW += new_text_len; + obj->CurLenA += new_text_len_utf8; + obj->Text[obj->CurLenW] = '\0'; + + return true; +} + +// We don't use an enum so we can build even with conflicting symbols (if another user of stb_textedit.h leak their STB_TEXTEDIT_K_* symbols) +#define STB_TEXTEDIT_K_LEFT 0x10000 // keyboard input to move cursor left +#define STB_TEXTEDIT_K_RIGHT 0x10001 // keyboard input to move cursor right +#define STB_TEXTEDIT_K_UP 0x10002 // keyboard input to move cursor up +#define STB_TEXTEDIT_K_DOWN 0x10003 // keyboard input to move cursor down +#define STB_TEXTEDIT_K_LINESTART 0x10004 // keyboard input to move cursor to start of line +#define STB_TEXTEDIT_K_LINEEND 0x10005 // keyboard input to move cursor to end of line +#define STB_TEXTEDIT_K_TEXTSTART 0x10006 // keyboard input to move cursor to start of text +#define STB_TEXTEDIT_K_TEXTEND 0x10007 // keyboard input to move cursor to end of text +#define STB_TEXTEDIT_K_DELETE 0x10008 // keyboard input to delete selection or character under cursor +#define STB_TEXTEDIT_K_BACKSPACE 0x10009 // keyboard input to delete selection or character left of cursor +#define STB_TEXTEDIT_K_UNDO 0x1000A // keyboard input to perform undo +#define STB_TEXTEDIT_K_REDO 0x1000B // keyboard input to perform redo +#define STB_TEXTEDIT_K_WORDLEFT 0x1000C // keyboard input to move cursor left one word +#define STB_TEXTEDIT_K_WORDRIGHT 0x1000D // keyboard input to move cursor right one word +#define STB_TEXTEDIT_K_SHIFT 0x20000 + +#ifdef IMGUI_STB_NAMESPACE +namespace IMGUI_STB_NAMESPACE +{ +#endif +#define STB_TEXTEDIT_IMPLEMENTATION +#include "stb_textedit.h" +#ifdef IMGUI_STB_NAMESPACE +} +#endif + +void ImGuiTextEditState::OnKeyPressed(int key) +{ + stb_textedit_key(this, &StbState, key); + CursorAnimReset(); +} + +void ImGuiTextEditState::UpdateScrollOffset() +{ + // Scroll in chunks of quarter width + const float scroll_x_increment = Width * 0.25f; + const float cursor_offset_x = Font->CalcTextSizeW(FontSize, FLT_MAX, Text, Text+StbState.cursor, NULL).x; + + // If widget became bigger than text (because of a resize), reset horizontal scrolling + if (ScrollX > 0.0f) + { + const float text_width = cursor_offset_x + Font->CalcTextSizeW(FontSize, FLT_MAX, Text+StbState.cursor, NULL, NULL).x; + if (text_width < Width) + { + ScrollX = 0.0f; + return; + } + } + + if (cursor_offset_x < ScrollX) + ScrollX = ImMax(0.0f, cursor_offset_x - scroll_x_increment); + else if (cursor_offset_x - Width >= ScrollX) + ScrollX = cursor_offset_x - Width + scroll_x_increment; +} + +ImVec2 ImGuiTextEditState::CalcDisplayOffsetFromCharIdx(int i) const +{ + const ImWchar* text_start = GetTextPointerClippedW(Font, FontSize, Text, ScrollX, NULL); + const ImWchar* text_end = (Text+i >= text_start) ? Text+i : text_start; // Clip if requested character is outside of display + IM_ASSERT(text_end >= text_start); + + const ImVec2 offset = Font->CalcTextSizeW(FontSize, Width+1, text_start, text_end, NULL); + return offset; +} + +// [Static] +const char* ImGuiTextEditState::GetTextPointerClippedA(ImFont* font, float font_size, const char* text, float width, ImVec2* out_text_size) +{ + if (width <= 0.0f) + return text; + + const char* text_clipped_end = NULL; + const ImVec2 text_size = font->CalcTextSizeA(font_size, width, 0.0f, text, NULL, &text_clipped_end); + if (out_text_size) + *out_text_size = text_size; + return text_clipped_end; +} + +// [Static] +const ImWchar* ImGuiTextEditState::GetTextPointerClippedW(ImFont* font, float font_size, const ImWchar* text, float width, ImVec2* out_text_size) +{ + if (width <= 0.0f) + return text; + + const ImWchar* text_clipped_end = NULL; + const ImVec2 text_size = font->CalcTextSizeW(font_size, width, text, NULL, &text_clipped_end); + if (out_text_size) + *out_text_size = text_size; + return text_clipped_end; +} + +// [Static] +void ImGuiTextEditState::RenderTextScrolledClipped(ImFont* font, float font_size, const char* buf, ImVec2 pos, float width, float scroll_x) +{ + ImGuiWindow* window = GetCurrentWindow(); + const ImU32 font_color = window->Color(ImGuiCol_Text); + //window->DrawList->AddLine(pos, pos+ImVec2(width,0), 0xFF00FFFF); + + // Determine start and end of visible string + // FIXME-OPT: This is pretty slow for what it does. + const char* text_start = scroll_x <= 0.0f ? buf : GetTextPointerClippedA(font, font_size, buf, scroll_x, NULL); + const char* text_end = GetTextPointerClippedA(font, font_size, text_start, width + 1, NULL); // +1 to allow character spacing to fit outside the allowed width + window->DrawList->AddText(font, font_size, pos, font_color, text_start, text_end); + + // Log as text + if (GImGui->LogEnabled) + LogText(pos, buf, NULL); +} + +bool ImGui::InputFloat(const char* label, float *v, float step, float step_fast, int decimal_precision, ImGuiInputTextFlags extra_flags) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + const ImGuiStyle& style = g.Style; + const float w = ImGui::CalcItemWidth(); + const ImVec2 label_size = CalcTextSize(label, NULL, true); + const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y) + style.FramePadding*2.0f); + + ImGui::BeginGroup(); + ImGui::PushID(label); + const ImVec2 button_sz = ImVec2(g.FontSize, g.FontSize) + style.FramePadding * 2; + if (step > 0.0f) + ImGui::PushItemWidth(ImMax(1.0f, w - (button_sz.x + style.ItemInnerSpacing.x)*2)); + + char buf[64]; + if (decimal_precision < 0) + ImFormatString(buf, IM_ARRAYSIZE(buf), "%f", *v); // Ideally we'd have a minimum decimal precision of 1 to visually denote that it is a float, while hiding non-significant digits? + else + ImFormatString(buf, IM_ARRAYSIZE(buf), "%.*f", decimal_precision, *v); + bool value_changed = false; + const ImGuiInputTextFlags flags = extra_flags | (ImGuiInputTextFlags_CharsDecimal|ImGuiInputTextFlags_AutoSelectAll); + if (ImGui::InputText("", buf, IM_ARRAYSIZE(buf), flags)) + { + ApplyNumericalTextInput(buf, v); + value_changed = true; + } + + // Step buttons + if (step > 0.0f) + { + ImGui::PopItemWidth(); + ImGui::SameLine(0, (int)style.ItemInnerSpacing.x); + if (ImGui::Button("-", button_sz, true)) + { + *v -= g.IO.KeyCtrl && step_fast > 0.0f ? step_fast : step; + value_changed = true; + } + ImGui::SameLine(0, (int)style.ItemInnerSpacing.x); + if (ImGui::Button("+", button_sz, true)) + { + *v += g.IO.KeyCtrl && step_fast > 0.0f ? step_fast : step; + value_changed = true; + } + } + + ImGui::PopID(); + + if (label_size.x > 0) + { + ImGui::SameLine(0, (int)style.ItemInnerSpacing.x); + RenderText(ImVec2(window->DC.CursorPos.x, window->DC.CursorPos.y + style.FramePadding.y), label); + ItemSize(label_size, style.FramePadding.y); + } + + ImGui::EndGroup(); + + return value_changed; +} + +bool ImGui::InputInt(const char* label, int *v, int step, int step_fast, ImGuiInputTextFlags extra_flags) +{ + float f = (float)*v; + const bool value_changed = ImGui::InputFloat(label, &f, (float)step, (float)step_fast, 0, extra_flags); + if (value_changed) + *v = (int)f; + return value_changed; +} + +// Public API to manipulate UTF-8 text +// We expose UTF-8 to the user (unlike the STB_TEXTEDIT_* functions which are manipulating wchar) +void ImGuiTextEditCallbackData::DeleteChars(int pos, int bytes_count) +{ + char* dst = Buf + pos; + const char* src = Buf + pos + bytes_count; + while (char c = *src++) + *dst++ = c; + *dst = '\0'; + + BufDirty = true; + if (CursorPos + bytes_count >= pos) + CursorPos -= bytes_count; + else if (CursorPos >= pos) + CursorPos = pos; + SelectionStart = SelectionEnd = CursorPos; +} + +void ImGuiTextEditCallbackData::InsertChars(int pos, const char* new_text, const char* new_text_end) +{ + const size_t text_len = strlen(Buf); + if (!new_text_end) + new_text_end = new_text + strlen(new_text); + const size_t new_text_len = (size_t)(new_text_end - new_text); + + if (new_text_len + text_len + 1 >= BufSize) + return; + + size_t upos = (size_t)pos; + if (text_len != upos) + memmove(Buf + upos + new_text_len, Buf + upos, text_len - upos); + memcpy(Buf + upos, new_text, new_text_len * sizeof(char)); + Buf[text_len + new_text_len] = '\0'; + + BufDirty = true; + if (CursorPos >= pos) + CursorPos += (int)new_text_len; + SelectionStart = SelectionEnd = CursorPos; +} + +// Return false to discard a character. +static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags flags, ImGuiTextEditCallback callback, void* user_data) +{ + unsigned int c = *p_char; + + if (c < 128 && c != ' ' && !isprint((int)(c & 0xFF))) + return false; + + if (c >= 0xE000 && c <= 0xF8FF) // Filter private Unicode range. I don't imagine anybody would want to input them. GLFW on OSX seems to send private characters for special keys like arrow keys. + return false; + + if (flags & (ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase | ImGuiInputTextFlags_CharsNoBlank)) + { + if (flags & ImGuiInputTextFlags_CharsDecimal) + if (!(c >= '0' && c <= '9') && (c != '.') && (c != '-') && (c != '+') && (c != '*') && (c != '/')) + return false; + + if (flags & ImGuiInputTextFlags_CharsHexadecimal) + if (!(c >= '0' && c <= '9') && !(c >= 'a' && c <= 'f') && !(c >= 'A' && c <= 'F')) + return false; + + if (flags & ImGuiInputTextFlags_CharsUppercase) + if (c >= 'a' && c <= 'z') + *p_char = (c += (unsigned int)('A'-'a')); + + if (flags & ImGuiInputTextFlags_CharsNoBlank) + if (ImCharIsSpace(c)) + return false; + } + + if (flags & ImGuiInputTextFlags_CallbackCharFilter) + { + ImGuiTextEditCallbackData callback_data; + memset(&callback_data, 0, sizeof(ImGuiTextEditCallbackData)); + callback_data.EventFlag = ImGuiInputTextFlags_CallbackCharFilter; + callback_data.EventChar = (ImWchar)c; + callback_data.Flags = flags; + callback_data.UserData = user_data; + if (callback(&callback_data) != 0) + return false; + *p_char = callback_data.EventChar; + if (!callback_data.EventChar) + return false; + } + + return true; +} + +// Edit a string of text +bool ImGui::InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags, ImGuiTextEditCallback callback, void* user_data) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + const ImGuiIO& io = g.IO; + const ImGuiStyle& style = g.Style; + + const ImGuiID id = window->GetID(label); + const float w = ImGui::CalcItemWidth(); + + const ImVec2 label_size = CalcTextSize(label, NULL, true); + const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y) + style.FramePadding*2.0f); + const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? (style.ItemInnerSpacing.x + label_size.x) : 0.0f, 0.0f)); + ItemSize(total_bb, style.FramePadding.y); + if (!ItemAdd(total_bb, &id)) + return false; + + // NB: we are only allowed to access 'edit_state' if we are the active widget. + ImGuiTextEditState& edit_state = g.InputTextState; + + const bool is_ctrl_down = io.KeyCtrl; + const bool is_shift_down = io.KeyShift; + const bool focus_requested = window->FocusItemRegister(g.ActiveId == id, (flags & ImGuiInputTextFlags_CallbackCompletion) == 0); // Using completion callback disable keyboard tabbing + const bool focus_requested_by_code = focus_requested && (window->FocusIdxAllCounter == window->FocusIdxAllRequestCurrent); + const bool focus_requested_by_tab = focus_requested && !focus_requested_by_code; + + const bool hovered = IsHovered(frame_bb, id); + if (hovered) + { + g.HoveredId = id; + g.MouseCursor = ImGuiMouseCursor_TextInput; + } + const bool user_clicked = hovered && io.MouseClicked[0]; + + bool select_all = (g.ActiveId != id) && (flags & ImGuiInputTextFlags_AutoSelectAll) != 0; + if (focus_requested || user_clicked) + { + if (g.ActiveId != id) + { + // Start edition + // Take a copy of the initial buffer value (both in original UTF-8 format and converted to wchar) + // From the moment we focused we are ignoring the content of 'buf' + ImFormatString(edit_state.InitialText, IM_ARRAYSIZE(edit_state.InitialText), "%s", buf); + const char* buf_end = NULL; + edit_state.CurLenW = ImTextStrFromUtf8(edit_state.Text, IM_ARRAYSIZE(edit_state.Text), buf, NULL, &buf_end); + edit_state.CurLenA = buf_end - buf; // We can't get the result from ImFormatString() above because it is not UTF-8 aware. Here we'll cut off malformed UTF-8. + edit_state.Width = w + style.FramePadding.x; + edit_state.InputCursorScreenPos = ImVec2(-1.f,-1.f); + edit_state.CursorAnimReset(); + + if (edit_state.Id != id) + { + edit_state.Id = id; + edit_state.ScrollX = 0.0f; + stb_textedit_initialize_state(&edit_state.StbState, true); + if (focus_requested_by_code) + select_all = true; + } + else + { + // Recycle existing cursor/selection/undo stack but clamp position + // Note a single mouse click will override the cursor/position immediately by calling stb_textedit_click handler. + edit_state.StbState.cursor = ImMin(edit_state.StbState.cursor, (int)edit_state.CurLenW); + edit_state.StbState.select_start = ImMin(edit_state.StbState.select_start, (int)edit_state.CurLenW); + edit_state.StbState.select_end = ImMin(edit_state.StbState.select_end, (int)edit_state.CurLenW); + } + if (focus_requested_by_tab || (user_clicked && is_ctrl_down)) + select_all = true; + } + SetActiveId(id); + FocusWindow(window); + } + else if (io.MouseClicked[0]) + { + // Release focus when we click outside + if (g.ActiveId == id) + { + SetActiveId(0); + } + } + + // Although we are active we don't prevent mouse from hovering other elements unless we are interacting right now with the widget. + // Down the line we should have a cleaner concept of focused vs active in the library. + if (g.ActiveId == id) + g.ActiveIdIsFocusedOnly = !io.MouseDown[0]; + + bool value_changed = false; + bool cancel_edit = false; + bool enter_pressed = false; + if (g.ActiveId == id) + //if (edit_state.Id == id) // Works, but double-click to select-all sets cursors to end which in turn tends to scroll toward the right when shrinking widget. + { + // Update some data if we are active or last active + edit_state.Width = w + style.FramePadding.x; + edit_state.BufSizeA = buf_size; + edit_state.Font = g.Font; + edit_state.FontSize = g.FontSize; + edit_state.UpdateScrollOffset(); + } + if (g.ActiveId == id) + { + // Edit in progress + const float mx = g.IO.MousePos.x - frame_bb.Min.x - style.FramePadding.x; + const float my = g.FontSize*0.5f; // Flatten mouse because we are doing a single-line edit + + if (select_all || (hovered && io.MouseDoubleClicked[0])) + { + edit_state.SelectAll(); + edit_state.SelectedAllMouseLock = true; + } + else if (io.MouseClicked[0] && !edit_state.SelectedAllMouseLock) + { + stb_textedit_click(&edit_state, &edit_state.StbState, mx + edit_state.ScrollX, my); + edit_state.CursorAnimReset(); + } + else if (io.MouseDown[0] && !edit_state.SelectedAllMouseLock) + { + stb_textedit_drag(&edit_state, &edit_state.StbState, mx + edit_state.ScrollX, my); + edit_state.CursorAnimReset(); + } + if (edit_state.SelectedAllMouseLock && !io.MouseDown[0]) + edit_state.SelectedAllMouseLock = false; + + if (g.IO.InputCharacters[0]) + { + // Process text input (before we check for Return because using some IME will effectively send a Return?) + for (int n = 0; n < IM_ARRAYSIZE(g.IO.InputCharacters) && g.IO.InputCharacters[n]; n++) + { + unsigned int c = (unsigned int)g.IO.InputCharacters[n]; + if (c) + { + // Insert character if they pass filtering + if (!InputTextFilterCharacter(&c, flags, callback, user_data)) + continue; + edit_state.OnKeyPressed((int)c); + } + } + + // Consume characters + memset(g.IO.InputCharacters, 0, sizeof(g.IO.InputCharacters)); + } + + const int k_mask = (is_shift_down ? STB_TEXTEDIT_K_SHIFT : 0); + if (IsKeyPressedMap(ImGuiKey_LeftArrow)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_WORDLEFT | k_mask : STB_TEXTEDIT_K_LEFT | k_mask); } + else if (IsKeyPressedMap(ImGuiKey_RightArrow)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_WORDRIGHT | k_mask : STB_TEXTEDIT_K_RIGHT | k_mask); } + else if (IsKeyPressedMap(ImGuiKey_Home)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_TEXTSTART | k_mask : STB_TEXTEDIT_K_LINESTART | k_mask); } + else if (IsKeyPressedMap(ImGuiKey_End)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_TEXTEND | k_mask : STB_TEXTEDIT_K_LINEEND | k_mask); } + else if (IsKeyPressedMap(ImGuiKey_Delete)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_DELETE | k_mask); } + else if (IsKeyPressedMap(ImGuiKey_Backspace)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_BACKSPACE | k_mask); } + else if (IsKeyPressedMap(ImGuiKey_Enter)) { SetActiveId(0); enter_pressed = true; } + else if (IsKeyPressedMap(ImGuiKey_Escape)) { SetActiveId(0); cancel_edit = true; } + else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_Z)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_UNDO); } + else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_Y)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_REDO); } + else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_A)) { edit_state.SelectAll(); } + else if (is_ctrl_down && (IsKeyPressedMap(ImGuiKey_X) || IsKeyPressedMap(ImGuiKey_C))) + { + // Cut, Copy + const bool cut = IsKeyPressedMap(ImGuiKey_X); + if (cut && !edit_state.HasSelection()) + edit_state.SelectAll(); + + if (g.IO.SetClipboardTextFn) + { + const int ib = edit_state.HasSelection() ? ImMin(edit_state.StbState.select_start, edit_state.StbState.select_end) : 0; + const int ie = edit_state.HasSelection() ? ImMax(edit_state.StbState.select_start, edit_state.StbState.select_end) : (int)edit_state.CurLenW; + ImTextStrToUtf8(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), edit_state.Text+ib, edit_state.Text+ie); + g.IO.SetClipboardTextFn(g.TempBuffer); + } + + if (cut) + stb_textedit_cut(&edit_state, &edit_state.StbState); + } + else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_V)) + { + // Paste + if (g.IO.GetClipboardTextFn) + { + if (const char* clipboard = g.IO.GetClipboardTextFn()) + { + // Remove new-line from pasted buffer + const size_t clipboard_len = strlen(clipboard); + ImWchar* clipboard_filtered = (ImWchar*)ImGui::MemAlloc((clipboard_len+1) * sizeof(ImWchar)); + int clipboard_filtered_len = 0; + for (const char* s = clipboard; *s; ) + { + unsigned int c; + s += ImTextCharFromUtf8(&c, s, NULL); + if (c == 0) + break; + if (c >= 0x10000) + continue; + if (!InputTextFilterCharacter(&c, flags, callback, user_data)) + continue; + clipboard_filtered[clipboard_filtered_len++] = (ImWchar)c; + } + clipboard_filtered[clipboard_filtered_len] = 0; + if (clipboard_filtered_len > 0) // If everything was filtered, ignore the pasting operation + stb_textedit_paste(&edit_state, &edit_state.StbState, clipboard_filtered, clipboard_filtered_len); + ImGui::MemFree(clipboard_filtered); + } + } + } + + edit_state.CursorAnim += g.IO.DeltaTime; + edit_state.UpdateScrollOffset(); + + if (cancel_edit) + { + // Restore initial value + ImFormatString(buf, buf_size, "%s", edit_state.InitialText); + value_changed = true; + } + else + { + // Apply new value immediately - copy modified buffer back + // Note that as soon as we can focus into the input box, the in-widget value gets priority over any underlying modification of the input buffer + // FIXME: We actually always render 'buf' in RenderTextScrolledClipped + // FIXME-OPT: CPU waste to do this every time the widget is active, should mark dirty state from the stb_textedit callbacks + ImTextStrToUtf8(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), edit_state.Text, NULL); + + // User callback + if ((flags & (ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_CallbackHistory | ImGuiInputTextFlags_CallbackAlways)) != 0) + { + IM_ASSERT(callback != NULL); + + // The reason we specify the usage semantic (Completion/History) is that Completion needs to disable keyboard TABBING at the moment. + ImGuiInputTextFlags event_flag = 0; + ImGuiKey event_key = ImGuiKey_COUNT; + if ((flags & ImGuiInputTextFlags_CallbackCompletion) != 0 && IsKeyPressedMap(ImGuiKey_Tab)) + { + event_flag = ImGuiInputTextFlags_CallbackCompletion; + event_key = ImGuiKey_Tab; + } + else if ((flags & ImGuiInputTextFlags_CallbackHistory) != 0 && IsKeyPressedMap(ImGuiKey_UpArrow)) + { + event_flag = ImGuiInputTextFlags_CallbackHistory; + event_key = ImGuiKey_UpArrow; + } + else if ((flags & ImGuiInputTextFlags_CallbackHistory) != 0 && IsKeyPressedMap(ImGuiKey_DownArrow)) + { + event_flag = ImGuiInputTextFlags_CallbackHistory; + event_key = ImGuiKey_DownArrow; + } + + if (event_key != ImGuiKey_COUNT || (flags & ImGuiInputTextFlags_CallbackAlways) != 0) + { + ImGuiTextEditCallbackData callback_data; + callback_data.EventFlag = event_flag; + callback_data.EventKey = event_key; + callback_data.Buf = g.TempBuffer; + callback_data.BufSize = edit_state.BufSizeA; + callback_data.BufDirty = false; + callback_data.Flags = flags; + callback_data.UserData = user_data; + + // We have to convert from position from wchar to UTF-8 positions + const int utf8_cursor_pos = callback_data.CursorPos = ImTextCountUtf8BytesFromStr(edit_state.Text, edit_state.Text + edit_state.StbState.cursor); + const int utf8_selection_start = callback_data.SelectionStart = ImTextCountUtf8BytesFromStr(edit_state.Text, edit_state.Text + edit_state.StbState.select_start); + const int utf8_selection_end = callback_data.SelectionEnd = ImTextCountUtf8BytesFromStr(edit_state.Text, edit_state.Text + edit_state.StbState.select_end); + + // Call user code + callback(&callback_data); + + // Read back what user may have modified + IM_ASSERT(callback_data.Buf == g.TempBuffer); // Invalid to modify those fields + IM_ASSERT(callback_data.BufSize == edit_state.BufSizeA); + IM_ASSERT(callback_data.Flags == flags); + if (callback_data.CursorPos != utf8_cursor_pos) edit_state.StbState.cursor = ImTextCountCharsFromUtf8(callback_data.Buf, callback_data.Buf + callback_data.CursorPos); + if (callback_data.SelectionStart != utf8_selection_start) edit_state.StbState.select_start = ImTextCountCharsFromUtf8(callback_data.Buf, callback_data.Buf + callback_data.SelectionStart); + if (callback_data.SelectionEnd != utf8_selection_end) edit_state.StbState.select_end = ImTextCountCharsFromUtf8(callback_data.Buf, callback_data.Buf + callback_data.SelectionEnd); + if (callback_data.BufDirty) + { + ImTextStrFromUtf8(edit_state.Text, IM_ARRAYSIZE(edit_state.Text), g.TempBuffer, NULL); + edit_state.CursorAnimReset(); + } + } + } + + if (strcmp(g.TempBuffer, buf) != 0) + { + ImFormatString(buf, buf_size, "%s", g.TempBuffer); + value_changed = true; + } + } + } + + RenderFrame(frame_bb.Min, frame_bb.Max, window->Color(ImGuiCol_FrameBg), true, style.FrameRounding); + + const ImVec2 font_off_up = ImVec2(0.0f, g.FontSize+1.0f); // FIXME: those offsets are part of the style or font API + const ImVec2 font_off_dn = ImVec2(0.0f, 2.0f); + + if (g.ActiveId == id) + { + // Draw selection + const int select_begin_idx = edit_state.StbState.select_start; + const int select_end_idx = edit_state.StbState.select_end; + if (select_begin_idx != select_end_idx) + { + const ImVec2 select_begin_pos = frame_bb.Min + style.FramePadding + edit_state.CalcDisplayOffsetFromCharIdx(ImMin(select_begin_idx,select_end_idx)); + const ImVec2 select_end_pos = frame_bb.Min + style.FramePadding + edit_state.CalcDisplayOffsetFromCharIdx(ImMax(select_begin_idx,select_end_idx)); + window->DrawList->AddRectFilled(select_begin_pos - font_off_up, select_end_pos + font_off_dn, window->Color(ImGuiCol_TextSelectedBg)); + } + } + + //const float render_scroll_x = (g.ActiveId == id) ? edit_state.ScrollX : 0.0f; + const float render_scroll_x = (edit_state.Id == id) ? edit_state.ScrollX : 0.0f; + ImGuiTextEditState::RenderTextScrolledClipped(g.Font, g.FontSize, buf, frame_bb.Min + style.FramePadding, w + style.FramePadding.x, render_scroll_x); + + if (g.ActiveId == id) + { + const ImVec2 cursor_pos = frame_bb.Min + style.FramePadding + edit_state.CalcDisplayOffsetFromCharIdx(edit_state.StbState.cursor); + + // Draw blinking cursor + if (g.InputTextState.CursorIsVisible()) + window->DrawList->AddRect(cursor_pos - font_off_up + ImVec2(0,2), cursor_pos + font_off_dn - ImVec2(0,3), window->Color(ImGuiCol_Text)); + + // Notify OS of text input position for advanced IME + if (io.ImeSetInputScreenPosFn && ImLengthSqr(edit_state.InputCursorScreenPos - cursor_pos) > 0.0001f) + io.ImeSetInputScreenPosFn((int)cursor_pos.x - 1, (int)(cursor_pos.y - g.FontSize)); // -1 x offset so that Windows IME can cover our cursor. Bit of an extra nicety. + + edit_state.InputCursorScreenPos = cursor_pos; + } + + if (label_size.x > 0) + RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); + + if ((flags & ImGuiInputTextFlags_EnterReturnsTrue) != 0) + return enter_pressed; + else + return value_changed; +} + +static bool InputFloatN(const char* label, float* v, int components, int decimal_precision) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + const ImGuiStyle& style = g.Style; + const float w_full = ImGui::CalcItemWidth(); + const float w_item_one = ImMax(1.0f, (float)(int)((w_full - (style.FramePadding.x*2.0f + style.ItemInnerSpacing.x) * (components-1)) / (float)components)); + const float w_item_last = ImMax(1.0f, (float)(int)(w_full - (w_item_one + style.FramePadding.x*2.0f + style.ItemInnerSpacing.x) * (components-1))); + + bool value_changed = false; + ImGui::BeginGroup(); + ImGui::PushID(label); + ImGui::PushItemWidth(w_item_one); + for (int i = 0; i < components; i++) + { + ImGui::PushID(i); + if (i + 1 == components) + { + ImGui::PopItemWidth(); + ImGui::PushItemWidth(w_item_last); + } + value_changed |= ImGui::InputFloat("##v", &v[i], 0, 0, decimal_precision); + ImGui::SameLine(0, (int)style.ItemInnerSpacing.x); + ImGui::PopID(); + } + ImGui::PopItemWidth(); + ImGui::PopID(); + + window->DC.CurrentLineTextBaseOffset = ImMax(window->DC.CurrentLineTextBaseOffset, style.FramePadding.y); + ImGui::TextUnformatted(label, FindTextDisplayEnd(label)); + ImGui::EndGroup(); + + return value_changed; +} + +bool ImGui::InputFloat2(const char* label, float v[2], int decimal_precision) +{ + return InputFloatN(label, v, 2, decimal_precision); +} + +bool ImGui::InputFloat3(const char* label, float v[3], int decimal_precision) +{ + return InputFloatN(label, v, 3, decimal_precision); +} + +bool ImGui::InputFloat4(const char* label, float v[4], int decimal_precision) +{ + return InputFloatN(label, v, 4, decimal_precision); +} + +static bool InputIntN(const char* label, int* v, int components) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + const ImGuiStyle& style = g.Style; + const float w_full = ImGui::CalcItemWidth(); + const float w_item_one = ImMax(1.0f, (float)(int)((w_full - (style.FramePadding.x*2.0f + style.ItemInnerSpacing.x) * (components-1)) / (float)components)); + const float w_item_last = ImMax(1.0f, (float)(int)(w_full - (w_item_one + style.FramePadding.x*2.0f + style.ItemInnerSpacing.x) * (components-1))); + + bool value_changed = false; + ImGui::BeginGroup(); + ImGui::PushID(label); + ImGui::PushItemWidth(w_item_one); + for (int i = 0; i < components; i++) + { + ImGui::PushID(i); + if (i + 1 == components) + { + ImGui::PopItemWidth(); + ImGui::PushItemWidth(w_item_last); + } + value_changed |= ImGui::InputInt("##v", &v[i], 0, 0); + ImGui::SameLine(0, (int)style.ItemInnerSpacing.x); + ImGui::PopID(); + } + ImGui::PopItemWidth(); + ImGui::PopID(); + + window->DC.CurrentLineTextBaseOffset = ImMax(window->DC.CurrentLineTextBaseOffset, style.FramePadding.y); + ImGui::TextUnformatted(label, FindTextDisplayEnd(label)); + ImGui::EndGroup(); + + return value_changed; +} + +bool ImGui::InputInt2(const char* label, int v[2]) +{ + return InputIntN(label, v, 2); +} + +bool ImGui::InputInt3(const char* label, int v[3]) +{ + return InputIntN(label, v, 3); +} + +bool ImGui::InputInt4(const char* label, int v[4]) +{ + return InputIntN(label, v, 4); +} + +static bool Items_ArrayGetter(void* data, int idx, const char** out_text) +{ + const char** items = (const char**)data; + if (out_text) + *out_text = items[idx]; + return true; +} + +static bool Items_SingleStringGetter(void* data, int idx, const char** out_text) +{ + // FIXME-OPT: we could pre-compute the indices to fasten this. But only 1 active combo means the waste is limited. + const char* items_separated_by_zeros = (const char*)data; + int items_count = 0; + const char* p = items_separated_by_zeros; + while (*p) + { + if (idx == items_count) + break; + p += strlen(p) + 1; + items_count++; + } + if (!*p) + return false; + if (out_text) + *out_text = p; + return true; +} + +// Combo box helper allowing to pass an array of strings. +bool ImGui::Combo(const char* label, int* current_item, const char** items, int items_count, int height_in_items) +{ + const bool value_changed = Combo(label, current_item, Items_ArrayGetter, (void*)items, items_count, height_in_items); + return value_changed; +} + +// Combo box helper allowing to pass all items in a single string. +bool ImGui::Combo(const char* label, int* current_item, const char* items_separated_by_zeros, int height_in_items) +{ + int items_count = 0; + const char* p = items_separated_by_zeros; // FIXME-OPT: Avoid computing this + while (*p) + { + p += strlen(p) + 1; + items_count++; + } + bool value_changed = Combo(label, current_item, Items_SingleStringGetter, (void*)items_separated_by_zeros, items_count, height_in_items); + return value_changed; +} + +// Combo box function. +bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(void*, int, const char**), void* data, int items_count, int height_in_items) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + const ImGuiStyle& style = g.Style; + const ImGuiID id = window->GetID(label); + const float w = ImGui::CalcItemWidth(); + + const ImVec2 label_size = CalcTextSize(label, NULL, true); + const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y) + style.FramePadding*2.0f); + const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(style.ItemInnerSpacing.x + label_size.x,0)); + ItemSize(total_bb, style.FramePadding.y); + if (!ItemAdd(total_bb, &id)) + return false; + + const float arrow_size = (g.FontSize + style.FramePadding.x * 2.0f); + const bool hovered = IsHovered(frame_bb, id); + + bool value_changed = false; + const ImRect value_bb(frame_bb.Min, frame_bb.Max - ImVec2(arrow_size, 0.0f)); + RenderFrame(frame_bb.Min, frame_bb.Max, window->Color(ImGuiCol_FrameBg), true, style.FrameRounding); + RenderFrame(ImVec2(frame_bb.Max.x-arrow_size, frame_bb.Min.y), frame_bb.Max, window->Color(hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button), true, style.FrameRounding); // FIXME-ROUNDING + RenderCollapseTriangle(ImVec2(frame_bb.Max.x-arrow_size, frame_bb.Min.y) + style.FramePadding, true); + + if (*current_item >= 0 && *current_item < items_count) + { + const char* item_text; + if (items_getter(data, *current_item, &item_text)) + RenderTextClipped(frame_bb.Min + style.FramePadding, item_text, NULL, NULL, value_bb.Max); + } + + if (label_size.x > 0) + RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); + + ImGui::PushID((int)id); + bool menu_toggled = false; + if (hovered) + { + g.HoveredId = id; + if (g.IO.MouseClicked[0]) + { + menu_toggled = true; + g.ActiveComboID = (g.ActiveComboID == id) ? 0 : id; + if (g.ActiveComboID) + FocusWindow(window); + } + } + + if (g.ActiveComboID == id) + { + // Size default to hold ~7 items + if (height_in_items < 0) + height_in_items = 7; + + const ImVec2 backup_pos = ImGui::GetCursorPos(); + const float popup_off_x = 0.0f;//style.ItemInnerSpacing.x; + const float popup_height = (label_size.y + style.ItemSpacing.y) * ImMin(items_count, height_in_items) + (style.FramePadding.y * 3); + const ImRect popup_rect(ImVec2(frame_bb.Min.x+popup_off_x, frame_bb.Max.y), ImVec2(frame_bb.Max.x+popup_off_x, frame_bb.Max.y + popup_height)); + ImGui::SetCursorPos(popup_rect.Min - window->Pos); + + const ImGuiWindowFlags flags = ImGuiWindowFlags_ComboBox | ((window->Flags & ImGuiWindowFlags_ShowBorders) ? ImGuiWindowFlags_ShowBorders : 0); + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, style.FramePadding); + ImGui::BeginChild("#ComboBox", popup_rect.GetSize(), false, flags); + ImGui::Spacing(); + + bool combo_item_active = false; + combo_item_active |= (g.ActiveId == GetCurrentWindow()->GetID("#SCROLLY")); + + // Display items + for (int i = 0; i < items_count; i++) + { + ImGui::PushID((void*)(intptr_t)i); + const bool item_selected = (i == *current_item); + const char* item_text; + if (!items_getter(data, i, &item_text)) + item_text = "*Unknown item*"; + if (ImGui::Selectable(item_text, item_selected)) + { + SetActiveId(0); + g.ActiveComboID = 0; + value_changed = true; + *current_item = i; + } + if (item_selected && menu_toggled) + ImGui::SetScrollPosHere(); + combo_item_active |= ImGui::IsItemActive(); + ImGui::PopID(); + } + ImGui::EndChild(); + ImGui::PopStyleVar(); + ImGui::SetCursorPos(backup_pos); + + if (!combo_item_active && g.ActiveId != 0) + g.ActiveComboID = 0; + } + + ImGui::PopID(); + + return value_changed; +} + +// Tip: pass an empty label (e.g. "##dummy") then you can use the space to draw other text or image. +// But you need to make sure the ID is unique, e.g. enclose calls in PushID/PopID. +bool ImGui::Selectable(const char* label, bool selected, const ImVec2& size_arg) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + const ImGuiStyle& style = g.Style; + const ImGuiID id = window->GetID(label); + const ImVec2 label_size = CalcTextSize(label, NULL, true); + + const float w = ImMax(label_size.x, window->Pos.x + ImGui::GetContentRegionMax().x - style.AutoFitPadding.x - window->DC.CursorPos.x); + const ImVec2 size(size_arg.x != 0.0f ? size_arg.x : w, size_arg.y != 0.0f ? size_arg.y : label_size.y); + ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); + ItemSize(bb); + if (size_arg.x == 0.0f) + bb.Max.x += style.AutoFitPadding.x; + + // Selectables are meant to be tightly packed together. So for both rendering and collision we extend to compensate for spacing. + ImRect bb_with_spacing = bb; + const float spacing_L = (float)(int)(style.ItemSpacing.x * 0.5f); + const float spacing_U = (float)(int)(style.ItemSpacing.y * 0.5f); + const float spacing_R = style.ItemSpacing.x - spacing_L; + const float spacing_D = style.ItemSpacing.y - spacing_U; + bb_with_spacing.Min.x -= spacing_L; + bb_with_spacing.Min.y -= spacing_U; + bb_with_spacing.Max.x += spacing_R; + bb_with_spacing.Max.y += spacing_D; + if (!ItemAdd(bb_with_spacing, &id)) + return false; + + bool hovered, held; + bool pressed = ButtonBehavior(bb_with_spacing, id, &hovered, &held, true, false, false); + + // Render + if (hovered || selected) + { + const ImU32 col = window->Color((held && hovered) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header); + RenderFrame(bb_with_spacing.Min, bb_with_spacing.Max, col, false, style.FrameRounding); + } + + //const ImVec2 off = ImVec2(ImMax(0.0f, size.x - text_size.x) * 0.5f, ImMax(0.0f, size.y - text_size.y) * 0.5f); + RenderTextClipped(bb.Min, label, NULL, &label_size, bb_with_spacing.Max); + + return pressed; +} + +bool ImGui::Selectable(const char* label, bool* p_selected, const ImVec2& size_arg) +{ + if (ImGui::Selectable(label, *p_selected, size_arg)) + { + *p_selected = !*p_selected; + return true; + } + return false; +} + +// Helper to calculate the size of a listbox and display a label on the right. +// Tip: To have a list filling the entire window width, PushItemWidth(-1) and pass an empty label "##empty" +bool ImGui::ListBoxHeader(const char* label, const ImVec2& size_arg) +{ + ImGuiWindow* window = GetCurrentWindow(); + + const ImGuiStyle& style = ImGui::GetStyle(); + const ImGuiID id = ImGui::GetID(label); + const ImVec2 label_size = ImGui::CalcTextSize(label, NULL, true); + + // Size default to hold ~7 items. Fractional number of items helps seeing that we can scroll down/up without looking at scrollbar. + ImVec2 size; + size.x = (size_arg.x != 0.0f) ? (size_arg.x) : ImGui::CalcItemWidth() + style.FramePadding.x * 2.0f; + size.y = (size_arg.y != 0.0f) ? (size_arg.y) : ImGui::GetTextLineHeightWithSpacing() * 7.4f + style.ItemSpacing.y; + const ImVec2 frame_size = ImVec2(size.x, ImMax(size.y, label_size.y)); + const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + frame_size); + const ImRect bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f)); + window->DC.LastItemRect = bb; + + ImGui::BeginGroup(); + if (label_size.x > 0) + RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); + + ImGui::BeginChildFrame(id, frame_bb.GetSize()); + return true; +} + +bool ImGui::ListBoxHeader(const char* label, int items_count, int height_in_items) +{ + // Size default to hold ~7 items. Fractional number of items helps seeing that we can scroll down/up without looking at scrollbar. + // However we don't add +0.40f if items_count <= height_in_items. It is slightly dodgy, because it means a dynamic list of items will make the widget resize occasionally when it crosses that size. + // I am expecting that someone will come and complain about this behavior in a remote future, then we can advise on a better solution. + if (height_in_items < 0) + height_in_items = ImMin(items_count, 7); + float height_in_items_f = height_in_items < items_count ? (height_in_items + 0.40f) : (height_in_items + 0.00f); + + // We include ItemSpacing.y so that a list sized for the exact number of items doesn't make a scrollbar appears. We could also enforce that by passing a flag to BeginChild(). + ImVec2 size; + size.x = 0.0f; + size.y = ImGui::GetTextLineHeightWithSpacing() * height_in_items_f + ImGui::GetStyle().ItemSpacing.y; + return ImGui::ListBoxHeader(label, size); +} + +void ImGui::ListBoxFooter() +{ + ImGuiWindow* parent_window = GetParentWindow(); + const ImRect bb = parent_window->DC.LastItemRect; + const ImGuiStyle& style = ImGui::GetStyle(); + + ImGui::EndChildFrame(); + + // Redeclare item size so that it includes the label (we have stored the full size in LastItemRect) + // We call SameLine() to restore DC.CurrentLine* data + ImGui::SameLine(); + parent_window->DC.CursorPos = bb.Min; + ItemSize(bb, style.FramePadding.y); + ImGui::EndGroup(); +} + +bool ImGui::ListBox(const char* label, int* current_item, const char** items, int items_count, int height_items) +{ + const bool value_changed = ListBox(label, current_item, Items_ArrayGetter, (void*)items, items_count, height_items); + return value_changed; +} + +bool ImGui::ListBox(const char* label, int* current_item, bool (*items_getter)(void*, int, const char**), void* data, int items_count, int height_in_items) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + if (!ImGui::ListBoxHeader(label, items_count, height_in_items)) + return false; + + bool value_changed = false; + for (int i = 0; i < items_count; i++) + { + const bool item_selected = (i == *current_item); + const char* item_text; + if (!items_getter(data, i, &item_text)) + item_text = "*Unknown item*"; + + ImGui::PushID(i); + if (ImGui::Selectable(item_text, item_selected)) + { + *current_item = i; + value_changed = true; + } + ImGui::PopID(); + } + + ImGui::ListBoxFooter(); + return value_changed; +} + +// A little colored square. Return true when clicked. +bool ImGui::ColorButton(const ImVec4& col, bool small_height, bool outline_border) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + const ImGuiStyle& style = g.Style; + const ImGuiID id = window->GetID("#colorbutton"); + const float square_size = g.FontSize; + const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(square_size + style.FramePadding.x*2, square_size + (small_height ? 0 : style.FramePadding.y*2))); + ItemSize(bb, small_height ? 0.0f : style.FramePadding.y); + if (!ItemAdd(bb, &id)) + return false; + + bool hovered, held; + bool pressed = ButtonBehavior(bb, id, &hovered, &held, true); + RenderFrame(bb.Min, bb.Max, window->Color(col), outline_border, style.FrameRounding); + + if (hovered) + { + int ix = (int)(col.x * 255.0f + 0.5f); + int iy = (int)(col.y * 255.0f + 0.5f); + int iz = (int)(col.z * 255.0f + 0.5f); + int iw = (int)(col.w * 255.0f + 0.5f); + ImGui::SetTooltip("Color:\n(%.2f,%.2f,%.2f,%.2f)\n#%02X%02X%02X%02X", col.x, col.y, col.z, col.w, ix, iy, iz, iw); + } + + return pressed; +} + +bool ImGui::ColorEdit3(const char* label, float col[3]) +{ + float col4[4]; + col4[0] = col[0]; + col4[1] = col[1]; + col4[2] = col[2]; + col4[3] = 1.0f; + const bool value_changed = ImGui::ColorEdit4(label, col4, false); + col[0] = col4[0]; + col[1] = col4[1]; + col[2] = col4[2]; + return value_changed; +} + +// Edit colors components (each component in 0.0f..1.0f range +// Use CTRL-Click to input value and TAB to go to next item. +bool ImGui::ColorEdit4(const char* label, float col[4], bool alpha) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + const ImGuiStyle& style = g.Style; + const ImGuiID id = window->GetID(label); + const float w_full = ImGui::CalcItemWidth(); + const float square_sz = (g.FontSize + style.FramePadding.x * 2.0f); + + ImGuiColorEditMode edit_mode = window->DC.ColorEditMode; + if (edit_mode == ImGuiColorEditMode_UserSelect || edit_mode == ImGuiColorEditMode_UserSelectShowButton) + edit_mode = g.ColorEditModeStorage.GetInt(id, 0) % 3; + + float f[4] = { col[0], col[1], col[2], col[3] }; + + if (edit_mode == ImGuiColorEditMode_HSV) + ImGui::ColorConvertRGBtoHSV(f[0], f[1], f[2], f[0], f[1], f[2]); + + int i[4] = { (int)(f[0] * 255.0f + 0.5f), (int)(f[1] * 255.0f + 0.5f), (int)(f[2] * 255.0f + 0.5f), (int)(f[3] * 255.0f + 0.5f) }; + + int components = alpha ? 4 : 3; + bool value_changed = false; + + ImGui::BeginGroup(); + ImGui::PushID(label); + + const bool hsv = (edit_mode == 1); + switch (edit_mode) + { + case ImGuiColorEditMode_RGB: + case ImGuiColorEditMode_HSV: + { + // RGB/HSV 0..255 Sliders + const float w_items_all = w_full - (square_sz + style.ItemInnerSpacing.x); + const float w_item_one = ImMax(1.0f, (float)(int)((w_items_all - (style.FramePadding.x*2.0f + style.ItemInnerSpacing.x) * (components-1)) / (float)components)); + const float w_item_last = ImMax(1.0f, (float)(int)(w_items_all - (w_item_one + style.FramePadding.x*2.0f + style.ItemInnerSpacing.x) * (components-1))); + + const bool hide_prefix = (w_item_one <= CalcTextSize("M:999").x); + const char* ids[4] = { "##X", "##Y", "##Z", "##W" }; + const char* fmt_table[3][4] = + { + { "%3.0f", "%3.0f", "%3.0f", "%3.0f" }, + { "R:%3.0f", "G:%3.0f", "B:%3.0f", "A:%3.0f" }, + { "H:%3.0f", "S:%3.0f", "V:%3.0f", "A:%3.0f" } + }; + const char** fmt = hide_prefix ? fmt_table[0] : hsv ? fmt_table[2] : fmt_table[1]; + + ImGui::PushItemWidth(w_item_one); + for (int n = 0; n < components; n++) + { + if (n > 0) + ImGui::SameLine(0, (int)style.ItemInnerSpacing.x); + if (n + 1 == components) + ImGui::PushItemWidth(w_item_last); + value_changed |= ImGui::DragInt(ids[n], &i[n], 1.0f, 0, 255, fmt[n]); + } + ImGui::PopItemWidth(); + ImGui::PopItemWidth(); + } + break; + case ImGuiColorEditMode_HEX: + { + // RGB Hexadecimal Input + const float w_slider_all = w_full - square_sz; + char buf[64]; + if (alpha) + ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X%02X", i[0], i[1], i[2], i[3]); + else + ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X", i[0], i[1], i[2]); + ImGui::PushItemWidth(w_slider_all - style.ItemInnerSpacing.x); + value_changed |= ImGui::InputText("##Text", buf, IM_ARRAYSIZE(buf), ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase); + ImGui::PopItemWidth(); + char* p = buf; + while (*p == '#' || ImCharIsSpace(*p)) + p++; + + // Treat at unsigned (%X is unsigned) + i[0] = i[1] = i[2] = i[3] = 0; + if (alpha) + sscanf(p, "%02X%02X%02X%02X", (unsigned int*)&i[0], (unsigned int*)&i[1], (unsigned int*)&i[2], (unsigned int*)&i[3]); + else + sscanf(p, "%02X%02X%02X", (unsigned int*)&i[0], (unsigned int*)&i[1], (unsigned int*)&i[2]); + } + break; + } + + ImGui::SameLine(0, (int)style.ItemInnerSpacing.x); + + const ImVec4 col_display(col[0], col[1], col[2], 1.0f); + if (ImGui::ColorButton(col_display)) + g.ColorEditModeStorage.SetInt(id, (edit_mode + 1) % 3); // Don't set local copy of 'edit_mode' right away! + + if (window->DC.ColorEditMode == ImGuiColorEditMode_UserSelectShowButton) + { + ImGui::SameLine(0, (int)style.ItemInnerSpacing.x); + const char* button_titles[3] = { "RGB", "HSV", "HEX" }; + if (ImGui::Button(button_titles[edit_mode])) + g.ColorEditModeStorage.SetInt(id, (edit_mode + 1) % 3); // Don't set local copy of 'edit_mode' right away! + ImGui::SameLine(); + } + else + { + ImGui::SameLine(0, (int)style.ItemInnerSpacing.x); + } + + ImGui::TextUnformatted(label, FindTextDisplayEnd(label)); + + // Convert back + for (int n = 0; n < 4; n++) + f[n] = i[n] / 255.0f; + if (edit_mode == 1) + ImGui::ColorConvertHSVtoRGB(f[0], f[1], f[2], f[0], f[1], f[2]); + + if (value_changed) + { + col[0] = f[0]; + col[1] = f[1]; + col[2] = f[2]; + if (alpha) + col[3] = f[3]; + } + + ImGui::PopID(); + ImGui::EndGroup(); + + return value_changed; +} + +void ImGui::ColorEditMode(ImGuiColorEditMode mode) +{ + ImGuiWindow* window = GetCurrentWindow(); + window->DC.ColorEditMode = mode; +} + +// Horizontal separating line. +void ImGui::Separator() +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + + if (window->DC.ColumnsCount > 1) + PopClipRect(); + + const ImRect bb(ImVec2(window->Pos.x, window->DC.CursorPos.y), ImVec2(window->Pos.x + window->Size.x, window->DC.CursorPos.y)); + ItemSize(ImVec2(0.0f, bb.GetSize().y)); // NB: we don't provide our width so that it doesn't get feed back into AutoFit + if (!ItemAdd(bb, NULL)) + { + if (window->DC.ColumnsCount > 1) + PushColumnClipRect(); + return; + } + + window->DrawList->AddLine(bb.Min, bb.Max, window->Color(ImGuiCol_Border)); + + ImGuiState& g = *GImGui; + if (g.LogEnabled) + ImGui::LogText(STR_NEWLINE "--------------------------------"); + + if (window->DC.ColumnsCount > 1) + { + PushColumnClipRect(); + window->DC.ColumnsCellMinY = window->DC.CursorPos.y; + } +} + +// A little vertical spacing. +void ImGui::Spacing() +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + + ItemSize(ImVec2(0,0)); +} + +// Advance cursor given item size. +static void ItemSize(ImVec2 size, float text_offset_y) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + + // Always align ourselves on pixel boundaries + const float line_height = ImMax(window->DC.CurrentLineHeight, size.y); + const float text_base_offset = ImMax(window->DC.CurrentLineTextBaseOffset, text_offset_y); + window->DC.CursorPosPrevLine = ImVec2(window->DC.CursorPos.x + size.x, window->DC.CursorPos.y); + window->DC.CursorPos = ImVec2((float)(int)(window->Pos.x + window->DC.ColumnsStartX + window->DC.ColumnsOffsetX), (float)(int)(window->DC.CursorPos.y + line_height + g.Style.ItemSpacing.y)); + window->DC.CursorMaxPos.x = ImMax(window->DC.CursorMaxPos.x, window->DC.CursorPosPrevLine.x); + window->DC.CursorMaxPos.y = ImMax(window->DC.CursorMaxPos.y, window->DC.CursorPos.y); + + //window->DrawList->AddCircle(window->DC.CursorMaxPos, 3.0f, 0xFF0000FF, 4); // Debug + + window->DC.PrevLineHeight = line_height; + window->DC.PrevLineTextBaseOffset = text_base_offset; + window->DC.CurrentLineHeight = window->DC.CurrentLineTextBaseOffset = 0.0f; +} + +static inline void ItemSize(const ImRect& bb, float text_offset_y) +{ + ItemSize(bb.GetSize(), text_offset_y); +} + +static bool IsClippedEx(const ImRect& bb, const ImGuiID* id, bool clip_even_when_logged) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + + if (!bb.Overlaps(ImRect(window->ClipRectStack.back()))) + { + if (!id || *id != GImGui->ActiveId) + if (clip_even_when_logged || !g.LogEnabled) + return true; + } + return false; +} + +bool ImGui::IsRectClipped(const ImVec2& size) +{ + ImGuiWindow* window = GetCurrentWindow(); + return IsClippedEx(ImRect(window->DC.CursorPos, window->DC.CursorPos + size), NULL, true); +} + +static bool ItemAdd(const ImRect& bb, const ImGuiID* id) +{ + ImGuiWindow* window = GetCurrentWindow(); + window->DC.LastItemID = id ? *id : 0; + window->DC.LastItemRect = bb; + if (IsClippedEx(bb, id, false)) + { + window->DC.LastItemHoveredAndUsable = window->DC.LastItemHoveredRect = false; + return false; + } + + // This is a sensible default, but widgets are free to override it after calling ItemAdd() + ImGuiState& g = *GImGui; + if (IsMouseHoveringRect(bb)) + { + // Matching the behavior of IsHovered() but ignore if ActiveId==window->MoveID (we clicked on the window background) + // So that clicking on items with no active id such as Text() still returns true with IsItemHovered() + window->DC.LastItemHoveredRect = true; + window->DC.LastItemHoveredAndUsable = false; + if (g.HoveredRootWindow == window->RootWindow) + if (g.ActiveId == 0 || (id && g.ActiveId == *id) || g.ActiveIdIsFocusedOnly || (g.ActiveId == window->MoveID)) + if (IsWindowContentHoverable(window)) + window->DC.LastItemHoveredAndUsable = true; + } + else + { + window->DC.LastItemHoveredAndUsable = window->DC.LastItemHoveredRect = false; + } + + return true; +} + +void ImGui::BeginGroup() +{ + ImGuiWindow* window = GetCurrentWindow(); + + window->DC.GroupStack.resize(window->DC.GroupStack.size() + 1); + ImGuiGroupData& group_data = window->DC.GroupStack.back(); + group_data.BackupCursorPos = window->DC.CursorPos; + group_data.BackupCursorMaxPos = window->DC.CursorMaxPos; + group_data.BackupColumnsStartX = window->DC.ColumnsStartX; + group_data.BackupCurrentLineHeight = window->DC.CurrentLineHeight; + group_data.BackupCurrentLineTextBaseOffset = window->DC.CurrentLineTextBaseOffset; + group_data.BackupLogLinePosY = window->DC.LogLinePosY; + + window->DC.ColumnsStartX = window->DC.CursorPos.x - window->Pos.x; + window->DC.CursorMaxPos = window->DC.CursorPos; + window->DC.CurrentLineHeight = 0.0f; + window->DC.LogLinePosY = window->DC.CursorPos.y - 9999.0f; +} + +void ImGui::EndGroup() +{ + ImGuiWindow* window = GetCurrentWindow(); + ImGuiStyle& style = ImGui::GetStyle(); + + IM_ASSERT(!window->DC.GroupStack.empty()); + + ImGuiGroupData& group_data = window->DC.GroupStack.back(); + + ImRect group_bb(group_data.BackupCursorPos, window->DC.CursorMaxPos); + group_bb.Max.y -= style.ItemSpacing.y; // Cancel out last vertical spacing because we are adding one ourselves. + group_bb.Max = ImMax(group_bb.Min, group_bb.Max); + + window->DC.CursorPos = group_data.BackupCursorPos; + window->DC.CursorMaxPos = ImMax(group_data.BackupCursorMaxPos, window->DC.CursorMaxPos); + window->DC.CurrentLineHeight = group_data.BackupCurrentLineHeight; + window->DC.CurrentLineTextBaseOffset = group_data.BackupCurrentLineTextBaseOffset; // FIXME: Ideally we'll grab the base offset from the first line of the group. + window->DC.ColumnsStartX = group_data.BackupColumnsStartX; + window->DC.LogLinePosY = window->DC.CursorPos.y - 9999.0f; + + ItemSize(group_bb.GetSize(), group_data.BackupCurrentLineTextBaseOffset); + ItemAdd(group_bb, NULL); + + window->DC.GroupStack.pop_back(); + + //window->DrawList->AddRect(group_bb.Min, group_bb.Max, 0xFFFF00FF); // Debug +} + +// Gets back to previous line and continue with horizontal layout +// column_x == 0 : follow on previous item +// columm_x != 0 : align to specified column +// spacing_w < 0 : use default spacing if column_x==0, no spacing if column_x!=0 +// spacing_w >= 0 : enforce spacing +void ImGui::SameLine(int column_x, int spacing_w) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + + float x, y; + if (column_x != 0) + { + if (spacing_w < 0) spacing_w = 0; + x = window->Pos.x + (float)column_x + (float)spacing_w; + y = window->DC.CursorPosPrevLine.y; + } + else + { + if (spacing_w < 0) spacing_w = (int)g.Style.ItemSpacing.x; + x = window->DC.CursorPosPrevLine.x + (float)spacing_w; + y = window->DC.CursorPosPrevLine.y; + } + window->DC.CurrentLineHeight = window->DC.PrevLineHeight; + window->DC.CurrentLineTextBaseOffset = window->DC.PrevLineTextBaseOffset; + window->DC.CursorPos = ImVec2(x, y); +} + +void ImGui::NextColumn() +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + + if (window->DC.ColumnsCount > 1) + { + ImGui::PopItemWidth(); + PopClipRect(); + + window->DC.ColumnsCellMaxY = ImMax(window->DC.ColumnsCellMaxY, window->DC.CursorPos.y); + if (++window->DC.ColumnsCurrent < window->DC.ColumnsCount) + { + window->DC.ColumnsOffsetX = ImGui::GetColumnOffset(window->DC.ColumnsCurrent) - window->DC.ColumnsStartX + g.Style.ItemSpacing.x; + } + else + { + window->DC.ColumnsCurrent = 0; + window->DC.ColumnsOffsetX = 0.0f; + window->DC.ColumnsCellMinY = window->DC.ColumnsCellMaxY; + } + window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.ColumnsStartX + window->DC.ColumnsOffsetX); + window->DC.CursorPos.y = window->DC.ColumnsCellMinY; + window->DC.CurrentLineHeight = 0.0f; + window->DC.CurrentLineTextBaseOffset = 0.0f; + + PushColumnClipRect(); + ImGui::PushItemWidth(ImGui::GetColumnWidth() * 0.65f); // FIXME + } +} + +int ImGui::GetColumnIndex() +{ + ImGuiWindow* window = GetCurrentWindow(); + return window->DC.ColumnsCurrent; +} + +int ImGui::GetColumnsCount() +{ + ImGuiWindow* window = GetCurrentWindow(); + return window->DC.ColumnsCount; +} + +static float GetDraggedColumnOffset(int column_index) +{ + // Active (dragged) column always follow mouse. The reason we need this is that dragging a column to the right edge of an auto-resizing + // window creates a feedback loop because we store normalized positions/ So while dragging we enforce absolute positioning + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + IM_ASSERT(g.ActiveId == window->DC.ColumnsSetID + ImGuiID(column_index)); + + float x = g.IO.MousePos.x + g.ActiveClickDeltaToCenter.x; + x -= window->Pos.x; + x = ImClamp(x, ImGui::GetColumnOffset(column_index-1)+g.Style.ColumnsMinSpacing, ImGui::GetColumnOffset(column_index+1)-g.Style.ColumnsMinSpacing); + + return x; +} + +float ImGui::GetColumnOffset(int column_index) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (column_index < 0) + column_index = window->DC.ColumnsCurrent; + + if (g.ActiveId) + { + const ImGuiID column_id = window->DC.ColumnsSetID + ImGuiID(column_index); + if (g.ActiveId == column_id) + return GetDraggedColumnOffset(column_index); + } + + // Read from cache + IM_ASSERT(column_index < (int)window->DC.ColumnsOffsetsT.size()); + const float t = window->DC.ColumnsOffsetsT[column_index]; + + const float min_x = window->DC.ColumnsStartX; + const float max_x = window->Size.x - (g.Style.ScrollbarWidth);// - window->WindowPadding().x; + const float offset = min_x + t * (max_x - min_x); + return offset; +} + +void ImGui::SetColumnOffset(int column_index, float offset) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (column_index < 0) + column_index = window->DC.ColumnsCurrent; + + IM_ASSERT(column_index < (int)window->DC.ColumnsOffsetsT.size()); + const ImGuiID column_id = window->DC.ColumnsSetID + ImGuiID(column_index); + + const float min_x = window->DC.ColumnsStartX; + const float max_x = window->Size.x - (g.Style.ScrollbarWidth);// - window->WindowPadding().x; + const float t = (offset - min_x) / (max_x - min_x); + window->DC.StateStorage->SetFloat(column_id, t); + window->DC.ColumnsOffsetsT[column_index] = t; +} + +float ImGui::GetColumnWidth(int column_index) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (column_index < 0) + column_index = window->DC.ColumnsCurrent; + + const float w = GetColumnOffset(column_index+1) - GetColumnOffset(column_index); + return w; +} + +static void PushColumnClipRect(int column_index) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (column_index < 0) + column_index = window->DC.ColumnsCurrent; + + const float x1 = window->Pos.x + ImGui::GetColumnOffset(column_index) - 1; + const float x2 = window->Pos.x + ImGui::GetColumnOffset(column_index+1) - 1; + PushClipRect(ImVec4(x1,-FLT_MAX,x2,+FLT_MAX)); +} + +void ImGui::Columns(int columns_count, const char* id, bool border) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + + if (window->DC.ColumnsCount != 1) + { + if (window->DC.ColumnsCurrent != 0) + ItemSize(ImVec2(0,0)); // Advance to column 0 + ImGui::PopItemWidth(); + PopClipRect(); + + window->DC.ColumnsCellMaxY = ImMax(window->DC.ColumnsCellMaxY, window->DC.CursorPos.y); + window->DC.CursorPos.y = window->DC.ColumnsCellMaxY; + } + + // Draw columns borders and handle resize at the time of "closing" a columns set + if (window->DC.ColumnsCount != columns_count && window->DC.ColumnsCount != 1 && window->DC.ColumnsShowBorders && !window->SkipItems) + { + const float y1 = window->DC.ColumnsStartPos.y; + const float y2 = window->DC.CursorPos.y; + for (int i = 1; i < window->DC.ColumnsCount; i++) + { + float x = window->Pos.x + GetColumnOffset(i); + + const ImGuiID column_id = window->DC.ColumnsSetID + ImGuiID(i); + const ImRect column_rect(ImVec2(x-4,y1),ImVec2(x+4,y2)); + + if (IsClippedEx(column_rect, &column_id, false)) + continue; + + bool hovered, held; + ButtonBehavior(column_rect, column_id, &hovered, &held, true); + if (hovered || held) + g.MouseCursor = ImGuiMouseCursor_ResizeEW; + + // Draw before resize so our items positioning are in sync with the line being drawn + const ImU32 col = window->Color(held ? ImGuiCol_ColumnActive : hovered ? ImGuiCol_ColumnHovered : ImGuiCol_Column); + const float xi = (float)(int)x; + window->DrawList->AddLine(ImVec2(xi, y1), ImVec2(xi, y2), col); + + if (held) + { + if (g.ActiveIdIsJustActivated) + g.ActiveClickDeltaToCenter.x = x - g.IO.MousePos.x; + + x = GetDraggedColumnOffset(i); + SetColumnOffset(i, x); + } + } + } + + // Set state for first column + window->DC.ColumnsSetID = window->GetID(id ? id : ""); + window->DC.ColumnsCurrent = 0; + window->DC.ColumnsCount = columns_count; + window->DC.ColumnsShowBorders = border; + window->DC.ColumnsStartPos = window->DC.CursorPos; + window->DC.ColumnsCellMinY = window->DC.ColumnsCellMaxY = window->DC.CursorPos.y; + window->DC.ColumnsOffsetX = 0.0f; + window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.ColumnsStartX + window->DC.ColumnsOffsetX); + + if (window->DC.ColumnsCount != 1) + { + // Cache column offsets + window->DC.ColumnsOffsetsT.resize((size_t)columns_count + 1); + for (int column_index = 0; column_index < columns_count + 1; column_index++) + { + const ImGuiID column_id = window->DC.ColumnsSetID + ImGuiID(column_index); + RegisterAliveId(column_id); + const float default_t = column_index / (float)window->DC.ColumnsCount; + const float t = window->DC.StateStorage->GetFloat(column_id, default_t); // Cheaply store our floating point value inside the integer (could store an union into the map?) + window->DC.ColumnsOffsetsT[column_index] = t; + } + + PushColumnClipRect(); + ImGui::PushItemWidth(ImGui::GetColumnWidth() * 0.65f); + } + else + { + window->DC.ColumnsOffsetsT.resize(2); + window->DC.ColumnsOffsetsT[0] = 0.0f; + window->DC.ColumnsOffsetsT[1] = 1.0f; + } +} + + +inline void ImGui::Indent() +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + window->DC.ColumnsStartX += g.Style.IndentSpacing; + window->DC.CursorPos.x = window->Pos.x + window->DC.ColumnsStartX + window->DC.ColumnsOffsetX; +} + +inline void ImGui::Unindent() +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + window->DC.ColumnsStartX -= g.Style.IndentSpacing; + window->DC.CursorPos.x = window->Pos.x + window->DC.ColumnsStartX + window->DC.ColumnsOffsetX; +} + +void ImGui::TreePush(const char* str_id) +{ + ImGuiWindow* window = GetCurrentWindow(); + ImGui::Indent(); + window->DC.TreeDepth++; + PushID(str_id ? str_id : "#TreePush"); +} + +void ImGui::TreePush(const void* ptr_id) +{ + ImGuiWindow* window = GetCurrentWindow(); + ImGui::Indent(); + window->DC.TreeDepth++; + PushID(ptr_id ? ptr_id : (const void*)"#TreePush"); +} + +void ImGui::TreePop() +{ + ImGuiWindow* window = GetCurrentWindow(); + ImGui::Unindent(); + window->DC.TreeDepth--; + PopID(); +} + +void ImGui::Value(const char* prefix, bool b) +{ + ImGui::Text("%s: %s", prefix, (b ? "true" : "false")); +} + +void ImGui::Value(const char* prefix, int v) +{ + ImGui::Text("%s: %d", prefix, v); +} + +void ImGui::Value(const char* prefix, unsigned int v) +{ + ImGui::Text("%s: %d", prefix, v); +} + +void ImGui::Value(const char* prefix, float v, const char* float_format) +{ + if (float_format) + { + char fmt[64]; + ImFormatString(fmt, IM_ARRAYSIZE(fmt), "%%s: %s", float_format); + ImGui::Text(fmt, prefix, v); + } + else + { + ImGui::Text("%s: %.3f", prefix, v); + } +} + +void ImGui::Color(const char* prefix, const ImVec4& v) +{ + ImGui::Text("%s: (%.2f,%.2f,%.2f,%.2f)", prefix, v.x, v.y, v.z, v.w); + ImGui::SameLine(); + ImGui::ColorButton(v, true); +} + +void ImGui::Color(const char* prefix, unsigned int v) +{ + ImGui::Text("%s: %08X", prefix, v); + ImGui::SameLine(); + + ImVec4 col; + col.x = (float)((v >> 0) & 0xFF) / 255.0f; + col.y = (float)((v >> 8) & 0xFF) / 255.0f; + col.z = (float)((v >> 16) & 0xFF) / 255.0f; + col.w = (float)((v >> 24) & 0xFF) / 255.0f; + ImGui::ColorButton(col, true); +} + +//----------------------------------------------------------------------------- +// ImDrawList +//----------------------------------------------------------------------------- + +static ImVec4 GNullClipRect(-9999.0f,-9999.0f, +9999.0f, +9999.0f); + +void ImDrawList::Clear() +{ + commands.resize(0); + vtx_buffer.resize(0); + vtx_write = NULL; + clip_rect_stack.resize(0); + texture_id_stack.resize(0); +} + +void ImDrawList::ClearFreeMemory() +{ + commands.clear(); + vtx_buffer.clear(); + vtx_write = NULL; + clip_rect_stack.clear(); + texture_id_stack.clear(); +} + +void ImDrawList::AddDrawCmd() +{ + ImDrawCmd draw_cmd; + draw_cmd.vtx_count = 0; + draw_cmd.clip_rect = clip_rect_stack.empty() ? GNullClipRect : clip_rect_stack.back(); + draw_cmd.texture_id = texture_id_stack.empty() ? NULL : texture_id_stack.back(); + draw_cmd.user_callback = NULL; + draw_cmd.user_callback_data = NULL; + + IM_ASSERT(draw_cmd.clip_rect.x <= draw_cmd.clip_rect.z && draw_cmd.clip_rect.y <= draw_cmd.clip_rect.w); + commands.push_back(draw_cmd); +} + +void ImDrawList::AddCallback(ImDrawCallback callback, void* callback_data) +{ + ImDrawCmd* current_cmd = commands.empty() ? NULL : &commands.back(); + if (!current_cmd || current_cmd->vtx_count != 0 || current_cmd->user_callback != NULL) + { + AddDrawCmd(); + current_cmd = &commands.back(); + } + current_cmd->user_callback = callback; + current_cmd->user_callback_data = callback_data; + + // Force a new command after us + // We function this way so that the most common calls (AddLine, AddRect..) always have a command to add to without doing any check. + AddDrawCmd(); +} + +void ImDrawList::UpdateClipRect() +{ + ImDrawCmd* current_cmd = commands.empty() ? NULL : &commands.back(); + if (!current_cmd || (current_cmd->vtx_count != 0) || current_cmd->user_callback != NULL) + { + AddDrawCmd(); + } + else + { + current_cmd->clip_rect = clip_rect_stack.empty() ? GNullClipRect : clip_rect_stack.back(); + } +} + +// Scissoring. The values in clip_rect are x1, y1, x2, y2. +void ImDrawList::PushClipRect(const ImVec4& clip_rect) +{ + clip_rect_stack.push_back(clip_rect); + UpdateClipRect(); +} + +void ImDrawList::PushClipRectFullScreen() +{ + PushClipRect(GNullClipRect); + + // This would be more correct but we're not supposed to access ImGuiState from here? + //ImGuiState& g = *GImGui; + //if (g.IO.DisplayVisibleMin.x != g.IO.DisplayVisibleMax.x && g.IO.DisplayVisibleMin.y != g.IO.DisplayVisibleMax.y) + // PushClipRect(ImVec4(g.IO.DisplayVisibleMin.x, g.IO.DisplayVisibleMin.y, g.IO.DisplayVisibleMax.x, g.IO.DisplayVisibleMax.y)); + //else + // PushClipRect(ImVec4(0.0f, 0.0f, g.IO.DisplaySize.x, g.IO.DisplaySize.y)); +} + +void ImDrawList::PopClipRect() +{ + IM_ASSERT(clip_rect_stack.size() > 0); + clip_rect_stack.pop_back(); + UpdateClipRect(); +} + +void ImDrawList::UpdateTextureID() +{ + ImDrawCmd* current_cmd = commands.empty() ? NULL : &commands.back(); + const ImTextureID texture_id = texture_id_stack.empty() ? NULL : texture_id_stack.back(); + if (!current_cmd || (current_cmd->vtx_count != 0 && current_cmd->texture_id != texture_id) || current_cmd->user_callback != NULL) + { + AddDrawCmd(); + } + else + { + current_cmd->texture_id = texture_id; + } +} + +void ImDrawList::PushTextureID(const ImTextureID& texture_id) +{ + texture_id_stack.push_back(texture_id); + UpdateTextureID(); +} + +void ImDrawList::PopTextureID() +{ + IM_ASSERT(texture_id_stack.size() > 0); + texture_id_stack.pop_back(); + UpdateTextureID(); +} + +void ImDrawList::PrimReserve(unsigned int vtx_count) +{ + ImDrawCmd& draw_cmd = commands.back(); + draw_cmd.vtx_count += vtx_count; + + size_t vtx_buffer_size = vtx_buffer.size(); + vtx_buffer.resize(vtx_buffer_size + vtx_count); + vtx_write = &vtx_buffer[vtx_buffer_size]; +} + +void ImDrawList::PrimTriangle(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col) +{ + const ImVec2 uv = GImGui->FontTexUvWhitePixel; + vtx_write[0].pos = a; vtx_write[0].uv = uv; vtx_write[0].col = col; + vtx_write[1].pos = b; vtx_write[1].uv = uv; vtx_write[1].col = col; + vtx_write[2].pos = c; vtx_write[2].uv = uv; vtx_write[2].col = col; + vtx_write += 3; +} + +void ImDrawList::PrimRect(const ImVec2& a, const ImVec2& c, ImU32 col) +{ + const ImVec2 uv = GImGui->FontTexUvWhitePixel; + const ImVec2 b(c.x, a.y); + const ImVec2 d(a.x, c.y); + vtx_write[0].pos = a; vtx_write[0].uv = uv; vtx_write[0].col = col; + vtx_write[1].pos = b; vtx_write[1].uv = uv; vtx_write[1].col = col; + vtx_write[2].pos = c; vtx_write[2].uv = uv; vtx_write[2].col = col; + vtx_write[3].pos = a; vtx_write[3].uv = uv; vtx_write[3].col = col; + vtx_write[4].pos = c; vtx_write[4].uv = uv; vtx_write[4].col = col; + vtx_write[5].pos = d; vtx_write[5].uv = uv; vtx_write[5].col = col; + vtx_write += 6; +} + +void ImDrawList::PrimRectUV(const ImVec2& a, const ImVec2& c, const ImVec2& uv_a, const ImVec2& uv_c, ImU32 col) +{ + const ImVec2 b(c.x, a.y); + const ImVec2 d(a.x, c.y); + const ImVec2 uv_b(uv_c.x, uv_a.y); + const ImVec2 uv_d(uv_a.x, uv_c.y); + vtx_write[0].pos = a; vtx_write[0].uv = uv_a; vtx_write[0].col = col; + vtx_write[1].pos = b; vtx_write[1].uv = uv_b; vtx_write[1].col = col; + vtx_write[2].pos = c; vtx_write[2].uv = uv_c; vtx_write[2].col = col; + vtx_write[3].pos = a; vtx_write[3].uv = uv_a; vtx_write[3].col = col; + vtx_write[4].pos = c; vtx_write[4].uv = uv_c; vtx_write[4].col = col; + vtx_write[5].pos = d; vtx_write[5].uv = uv_d; vtx_write[5].col = col; + vtx_write += 6; +} + +void ImDrawList::PrimQuad(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, ImU32 col) +{ + const ImVec2 uv = GImGui->FontTexUvWhitePixel; + vtx_write[0].pos = a; vtx_write[0].uv = uv; vtx_write[0].col = col; + vtx_write[1].pos = b; vtx_write[1].uv = uv; vtx_write[1].col = col; + vtx_write[2].pos = c; vtx_write[2].uv = uv; vtx_write[2].col = col; + vtx_write[3].pos = a; vtx_write[3].uv = uv; vtx_write[3].col = col; + vtx_write[4].pos = c; vtx_write[4].uv = uv; vtx_write[4].col = col; + vtx_write[5].pos = d; vtx_write[5].uv = uv; vtx_write[5].col = col; + vtx_write += 6; +} + +// FIXME-OPT: In many instances the caller could provide a normal. +void ImDrawList::PrimLine(const ImVec2& a, const ImVec2& b, ImU32 col, float thickness) +{ + const float inv_length = 1.0f / sqrtf(ImLengthSqr(b - a)); + const float dx = (b.x - a.x) * (thickness * 0.5f * inv_length); // line direction, halved + const float dy = (b.y - a.y) * (thickness * 0.5f * inv_length); // line direction, halved + + const ImVec2 pa(a.x + dy, a.y - dx); + const ImVec2 pb(b.x + dy, b.y - dx); + const ImVec2 pc(b.x - dy, b.y + dx); + const ImVec2 pd(a.x - dy, a.y + dx); + PrimQuad(pa, pb, pc, pd, col); +} + +void ImDrawList::AddLine(const ImVec2& a, const ImVec2& b, ImU32 col, float thickness) +{ + if ((col >> 24) == 0) + return; + + PrimReserve(6); + PrimLine(a, b, col, thickness); +} + +void ImDrawList::AddArcFast(const ImVec2& center, float radius, ImU32 col, int a_min, int a_max, bool filled, const ImVec2& third_point_offset) +{ + if ((col >> 24) == 0) + return; + + const int SAMPLES = 12; + static ImVec2 circle_vtx[SAMPLES]; + static bool circle_vtx_builds = false; + if (!circle_vtx_builds) + { + for (int i = 0; i < SAMPLES; i++) + { + const float a = ((float)i / (float)SAMPLES) * 2*PI; + circle_vtx[i].x = cosf(a + PI); + circle_vtx[i].y = sinf(a + PI); + } + circle_vtx_builds = true; + } + + const ImVec2 uv = GImGui->FontTexUvWhitePixel; + if (filled) + { + PrimReserve((unsigned int)(a_max-a_min) * 3); + for (int a0 = a_min; a0 < a_max; a0++) + { + int a1 = (a0 + 1 == SAMPLES) ? 0 : a0 + 1; + PrimVtx(center + circle_vtx[a0] * radius, uv, col); + PrimVtx(center + circle_vtx[a1] * radius, uv, col); + PrimVtx(center + third_point_offset, uv, col); + } + } + else + { + PrimReserve((unsigned int)(a_max-a_min) * 6); + for (int a0 = a_min; a0 < a_max; a0++) + { + int a1 = (a0 + 1 == SAMPLES) ? 0 : a0 + 1; + PrimLine(center + circle_vtx[a0] * radius, center + circle_vtx[a1] * radius, col); + } + } +} + +void ImDrawList::AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding, int rounding_corners) +{ + if ((col >> 24) == 0) + return; + + float r = rounding; + r = ImMin(r, fabsf(b.x-a.x) * ( ((rounding_corners&(1|2))==(1|2)) || ((rounding_corners&(4|8))==(4|8)) ? 0.5f : 1.0f )); + r = ImMin(r, fabsf(b.y-a.y) * ( ((rounding_corners&(1|8))==(1|8)) || ((rounding_corners&(2|4))==(2|4)) ? 0.5f : 1.0f )); + + if (r == 0.0f || rounding_corners == 0) + { + PrimReserve(4*6); + PrimLine(ImVec2(a.x,a.y), ImVec2(b.x,a.y), col); + PrimLine(ImVec2(b.x,a.y), ImVec2(b.x,b.y), col); + PrimLine(ImVec2(b.x,b.y), ImVec2(a.x,b.y), col); + PrimLine(ImVec2(a.x,b.y), ImVec2(a.x,a.y), col); + } + else + { + PrimReserve(4*6); + PrimLine(ImVec2(a.x + ((rounding_corners & 1)?r:0), a.y), ImVec2(b.x - ((rounding_corners & 2)?r:0), a.y), col); + PrimLine(ImVec2(b.x, a.y + ((rounding_corners & 2)?r:0)), ImVec2(b.x, b.y - ((rounding_corners & 4)?r:0)), col); + PrimLine(ImVec2(b.x - ((rounding_corners & 4)?r:0), b.y), ImVec2(a.x + ((rounding_corners & 8)?r:0), b.y), col); + PrimLine(ImVec2(a.x, b.y - ((rounding_corners & 8)?r:0)), ImVec2(a.x, a.y + ((rounding_corners & 1)?r:0)), col); + + if (rounding_corners & 1) AddArcFast(ImVec2(a.x+r,a.y+r), r, col, 0, 3); + if (rounding_corners & 2) AddArcFast(ImVec2(b.x-r,a.y+r), r, col, 3, 6); + if (rounding_corners & 4) AddArcFast(ImVec2(b.x-r,b.y-r), r, col, 6, 9); + if (rounding_corners & 8) AddArcFast(ImVec2(a.x+r,b.y-r), r, col, 9, 12); + } +} + +void ImDrawList::AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding, int rounding_corners) +{ + if ((col >> 24) == 0) + return; + + float r = rounding; + r = ImMin(r, fabsf(b.x-a.x) * ( ((rounding_corners&(1|2))==(1|2)) || ((rounding_corners&(4|8))==(4|8)) ? 0.5f : 1.0f )); + r = ImMin(r, fabsf(b.y-a.y) * ( ((rounding_corners&(1|8))==(1|8)) || ((rounding_corners&(2|4))==(2|4)) ? 0.5f : 1.0f )); + + if (r == 0.0f || rounding_corners == 0) + { + // Use triangle so we can merge more draw calls together (at the cost of extra vertices) + PrimReserve(6); + PrimRect(a, b, col); + } + else + { + PrimReserve(6+6*2); + PrimRect(ImVec2(a.x+r,a.y), ImVec2(b.x-r,b.y), col); + + float top_y = (rounding_corners & 1) ? a.y+r : a.y; + float bot_y = (rounding_corners & 8) ? b.y-r : b.y; + PrimRect(ImVec2(a.x,top_y), ImVec2(a.x+r,bot_y), col); + + top_y = (rounding_corners & 2) ? a.y+r : a.y; + bot_y = (rounding_corners & 4) ? b.y-r : b.y; + PrimRect(ImVec2(b.x-r,top_y), ImVec2(b.x,bot_y), col); + + if (rounding_corners & 1) AddArcFast(ImVec2(a.x+r,a.y+r), r, col, 0, 3, true); + if (rounding_corners & 2) AddArcFast(ImVec2(b.x-r,a.y+r), r, col, 3, 6, true); + if (rounding_corners & 4) AddArcFast(ImVec2(b.x-r,b.y-r), r, col, 6, 9, true); + if (rounding_corners & 8) AddArcFast(ImVec2(a.x+r,b.y-r), r, col, 9, 12, true); + } +} + +void ImDrawList::AddTriangleFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col) +{ + if ((col >> 24) == 0) + return; + + PrimReserve(3); + PrimTriangle(a, b, c, col); +} + +void ImDrawList::AddCircle(const ImVec2& centre, float radius, ImU32 col, int num_segments) +{ + if ((col >> 24) == 0) + return; + + PrimReserve((unsigned int)num_segments*6); + const float a_step = 2*PI/(float)num_segments; + float a0 = 0.0f; + for (int i = 0; i < num_segments; i++) + { + const float a1 = (i + 1) == num_segments ? 0.0f : a0 + a_step; + PrimLine(centre + ImVec2(cosf(a0), sinf(a0))*radius, centre + ImVec2(cosf(a1), sinf(a1))*radius, col); + a0 = a1; + } +} + +void ImDrawList::AddCircleFilled(const ImVec2& centre, float radius, ImU32 col, int num_segments) +{ + if ((col >> 24) == 0) + return; + + const ImVec2 uv = GImGui->FontTexUvWhitePixel; + PrimReserve((unsigned int)num_segments*3); + const float a_step = 2*PI/(float)num_segments; + float a0 = 0.0f; + for (int i = 0; i < num_segments; i++) + { + const float a1 = (i + 1) == num_segments ? 0.0f : a0 + a_step; + PrimVtx(centre + ImVec2(cosf(a0), sinf(a0))*radius, uv, col); + PrimVtx(centre + ImVec2(cosf(a1), sinf(a1))*radius, uv, col); + PrimVtx(centre, uv, col); + a0 = a1; + } +} + +void ImDrawList::AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end, float wrap_width, const ImVec2* cpu_clip_max) +{ + if ((col >> 24) == 0) + return; + + if (text_end == NULL) + text_end = text_begin + strlen(text_begin); + if (text_begin == text_end) + return; + + IM_ASSERT(font->ContainerAtlas->TexID == texture_id_stack.back()); // Use high-level ImGui::PushFont() or low-level ImDrawList::PushTextureId() to change font. + + // reserve vertices for worse case + const unsigned int char_count = (unsigned int)(text_end - text_begin); + const unsigned int vtx_count_max = char_count * 6; + const size_t vtx_begin = vtx_buffer.size(); + PrimReserve(vtx_count_max); + + font->RenderText(font_size, pos, col, clip_rect_stack.back(), text_begin, text_end, this, wrap_width, cpu_clip_max); + + // give back unused vertices + vtx_buffer.resize((size_t)(vtx_write - &vtx_buffer.front())); + const size_t vtx_count = vtx_buffer.size() - vtx_begin; + commands.back().vtx_count -= (unsigned int)(vtx_count_max - vtx_count); + vtx_write -= (vtx_count_max - vtx_count); +} + +void ImDrawList::AddImage(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv0, const ImVec2& uv1, ImU32 col) +{ + if ((col >> 24) == 0) + return; + + // FIXME-OPT: This is wasting draw calls. + const bool push_texture_id = texture_id_stack.empty() || user_texture_id != texture_id_stack.back(); + if (push_texture_id) + PushTextureID(user_texture_id); + + PrimReserve(6); + PrimRectUV(a, b, uv0, uv1, col); + + if (push_texture_id) + PopTextureID(); +} + +//----------------------------------------------------------------------------- +// ImFontAtlias +//----------------------------------------------------------------------------- + +struct ImFontAtlas::ImFontAtlasData +{ + // Input + ImFont* OutFont; // Load into this font + void* TTFData; // TTF data, we own the memory + size_t TTFDataSize; // TTF data size, in bytes + float SizePixels; // Desired output size, in pixels + const ImWchar* GlyphRanges; // List of Unicode range (2 value per range, values are inclusive, zero-terminated list) + int FontNo; // Index of font within .TTF file (0) + + // Temporary Build Data + stbtt_fontinfo FontInfo; + stbrp_rect* Rects; + stbtt_pack_range* Ranges; + int RangesCount; +}; + +ImFontAtlas::ImFontAtlas() +{ + TexID = NULL; + TexPixelsAlpha8 = NULL; + TexPixelsRGBA32 = NULL; + TexWidth = TexHeight = 0; + TexUvWhitePixel = ImVec2(0, 0); +} + +ImFontAtlas::~ImFontAtlas() +{ + Clear(); +} + +void ImFontAtlas::ClearInputData() +{ + for (size_t i = 0; i < InputData.size(); i++) + { + if (InputData[i]->TTFData) + ImGui::MemFree(InputData[i]->TTFData); + ImGui::MemFree(InputData[i]); + } + InputData.clear(); +} + +void ImFontAtlas::ClearTexData() +{ + if (TexPixelsAlpha8) + ImGui::MemFree(TexPixelsAlpha8); + if (TexPixelsRGBA32) + ImGui::MemFree(TexPixelsRGBA32); + TexPixelsAlpha8 = NULL; + TexPixelsRGBA32 = NULL; +} + +void ImFontAtlas::Clear() +{ + ClearInputData(); + ClearTexData(); + for (size_t i = 0; i < Fonts.size(); i++) + { + Fonts[i]->~ImFont(); + ImGui::MemFree(Fonts[i]); + } + Fonts.clear(); +} + +void ImGui::GetDefaultFontData(const void** fnt_data, unsigned int* fnt_size, const void** png_data, unsigned int* png_size) +{ + printf("GetDefaultFontData() is obsoleted in ImGui 1.30.\n"); + printf("Please use ImGui::GetIO().Fonts->GetTexDataAsRGBA32() or GetTexDataAsAlpha8() functions to retrieve uncompressed texture data.\n"); + if (fnt_data) *fnt_data = NULL; + if (fnt_size) *fnt_size = 0; + if (png_data) *png_data = NULL; + if (png_size) *png_size = 0; + IM_ASSERT(false); +} + +void ImFontAtlas::GetTexDataAsAlpha8(unsigned char** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel) +{ + // Lazily build + if (TexPixelsAlpha8 == NULL) + { + if (InputData.empty()) + AddFontDefault(); + Build(); + } + + *out_pixels = TexPixelsAlpha8; + if (out_width) *out_width = TexWidth; + if (out_height) *out_height = TexHeight; + if (out_bytes_per_pixel) *out_bytes_per_pixel = 1; +} + +void ImFontAtlas::GetTexDataAsRGBA32(unsigned char** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel) +{ + // Lazily convert to RGBA32 format + // Although it is likely to be the most commonly used format, our font rendering is 8 bpp + if (!TexPixelsRGBA32) + { + unsigned char* pixels; + GetTexDataAsAlpha8(&pixels, NULL, NULL); + TexPixelsRGBA32 = (unsigned int*)ImGui::MemAlloc((size_t)(TexWidth * TexHeight * 4)); + const unsigned char* src = pixels; + unsigned int* dst = TexPixelsRGBA32; + for (int n = TexWidth * TexHeight; n > 0; n--) + *dst++ = ((unsigned int)(*src++) << 24) | 0x00FFFFFF; + } + + *out_pixels = (unsigned char*)TexPixelsRGBA32; + if (out_width) *out_width = TexWidth; + if (out_height) *out_height = TexHeight; + if (out_bytes_per_pixel) *out_bytes_per_pixel = 4; +} + +static void GetDefaultCompressedFontDataTTF(const void** ttf_compressed_data, unsigned int* ttf_compressed_size); +static unsigned int stb_decompress_length(unsigned char *input); +static unsigned int stb_decompress(unsigned char *output, unsigned char *i, unsigned int length); + +// Load embedded ProggyClean.ttf at size 13 +ImFont* ImFontAtlas::AddFontDefault() +{ + unsigned int ttf_compressed_size; + const void* ttf_compressed; + GetDefaultCompressedFontDataTTF(&ttf_compressed, &ttf_compressed_size); + ImFont* font = AddFontFromMemoryCompressedTTF(ttf_compressed, ttf_compressed_size, 13.0f, GetGlyphRangesDefault(), 0); + font->DisplayOffset.y += 1; + return font; +} + +ImFont* ImFontAtlas::AddFontFromFileTTF(const char* filename, float size_pixels, const ImWchar* glyph_ranges, int font_no) +{ + void* data = NULL; + size_t data_size = 0; + if (!ImLoadFileToMemory(filename, "rb", (void**)&data, &data_size)) + { + IM_ASSERT(0); // Could not load file. + return NULL; + } + + ImFont* font = AddFontFromMemoryTTF(data, (unsigned int)data_size, size_pixels, glyph_ranges, font_no); + return font; +} + +// NB: ownership of 'data' is given to ImFontAtlas which will clear it. +ImFont* ImFontAtlas::AddFontFromMemoryTTF(void* in_ttf_data, unsigned int in_ttf_data_size, float size_pixels, const ImWchar* glyph_ranges, int font_no) +{ + // Create new font + ImFont* font = (ImFont*)ImGui::MemAlloc(sizeof(ImFont)); + new (font) ImFont(); + Fonts.push_back(font); + + // Add to build list + ImFontAtlasData* data = (ImFontAtlasData*)ImGui::MemAlloc(sizeof(ImFontAtlasData)); + memset(data, 0, sizeof(ImFontAtlasData)); + data->OutFont = font; + data->TTFData = in_ttf_data; + data->TTFDataSize = in_ttf_data_size; + data->SizePixels = size_pixels; + data->GlyphRanges = glyph_ranges; + data->FontNo = font_no; + InputData.push_back(data); + + // Invalidate texture + ClearTexData(); + + return font; +} + +ImFont* ImFontAtlas::AddFontFromMemoryCompressedTTF(const void* in_compressed_ttf_data, unsigned int in_compressed_ttf_data_size, float size_pixels, const ImWchar* glyph_ranges, int font_no) +{ + // Decompress + const size_t buf_decompressed_size = stb_decompress_length((unsigned char*)in_compressed_ttf_data); + unsigned char* buf_decompressed = (unsigned char *)ImGui::MemAlloc(buf_decompressed_size); + stb_decompress(buf_decompressed, (unsigned char*)in_compressed_ttf_data, in_compressed_ttf_data_size); + + // Add + ImFont* font = AddFontFromMemoryTTF(buf_decompressed, (unsigned int)buf_decompressed_size, size_pixels, glyph_ranges, font_no); + return font; +} + +bool ImFontAtlas::Build() +{ + IM_ASSERT(InputData.size() > 0); + + TexID = NULL; + TexWidth = TexHeight = 0; + TexUvWhitePixel = ImVec2(0, 0); + ClearTexData(); + + // Initialize font information early (so we can error without any cleanup) + count glyphs + int total_glyph_count = 0; + int total_glyph_range_count = 0; + for (size_t input_i = 0; input_i < InputData.size(); input_i++) + { + ImFontAtlasData& data = *InputData[input_i]; + IM_ASSERT(data.OutFont && !data.OutFont->IsLoaded()); + const int font_offset = stbtt_GetFontOffsetForIndex((unsigned char*)data.TTFData, data.FontNo); + IM_ASSERT(font_offset >= 0); + if (!stbtt_InitFont(&data.FontInfo, (unsigned char*)data.TTFData, font_offset)) + return false; + + if (!data.GlyphRanges) + data.GlyphRanges = GetGlyphRangesDefault(); + for (const ImWchar* in_range = data.GlyphRanges; in_range[0] && in_range[1]; in_range += 2) + { + total_glyph_count += (in_range[1] - in_range[0]) + 1; + total_glyph_range_count++; + } + } + + // Start packing + TexWidth = (total_glyph_count > 1000) ? 1024 : 512; // Width doesn't actually matters. + TexHeight = 0; + const int max_tex_height = 1024*32; + stbtt_pack_context spc; + int ret = stbtt_PackBegin(&spc, NULL, TexWidth, max_tex_height, 0, 1, NULL); + IM_ASSERT(ret); + stbtt_PackSetOversampling(&spc, 1, 1); + + // Pack our extra data rectangles first, so it will be on the upper-left corner of our texture (UV will have small values). + ImVector extra_rects; + RenderCustomTexData(0, &extra_rects); + stbrp_pack_rects((stbrp_context*)spc.pack_info, &extra_rects[0], (int)extra_rects.size()); + for (size_t i = 0; i < extra_rects.size(); i++) + if (extra_rects[i].was_packed) + TexHeight = ImMax(TexHeight, extra_rects[i].y + extra_rects[i].h); + + // Allocate packing character data and flag packed characters buffer as non-packed (x0=y0=x1=y1=0) + int buf_packedchars_n = 0, buf_rects_n = 0, buf_ranges_n = 0; + stbtt_packedchar* buf_packedchars = (stbtt_packedchar*)ImGui::MemAlloc(total_glyph_count * sizeof(stbtt_packedchar)); + stbrp_rect* buf_rects = (stbrp_rect*)ImGui::MemAlloc(total_glyph_count * sizeof(stbrp_rect)); + stbtt_pack_range* buf_ranges = (stbtt_pack_range*)ImGui::MemAlloc(total_glyph_range_count * sizeof(stbtt_pack_range)); + memset(buf_packedchars, 0, total_glyph_count * sizeof(stbtt_packedchar)); + memset(buf_rects, 0, total_glyph_count * sizeof(stbrp_rect)); // Unnecessary but let's clear this for the sake of sanity. + memset(buf_ranges, 0, total_glyph_range_count * sizeof(stbtt_pack_range)); + + // First font pass: pack all glyphs (no rendering at this point, we are working with glyph sizes only) + for (size_t input_i = 0; input_i < InputData.size(); input_i++) + { + ImFontAtlasData& data = *InputData[input_i]; + + // Setup ranges + int glyph_count = 0; + int glyph_ranges_count = 0; + for (const ImWchar* in_range = data.GlyphRanges; in_range[0] && in_range[1]; in_range += 2) + { + glyph_count += (in_range[1] - in_range[0]) + 1; + glyph_ranges_count++; + } + data.Ranges = buf_ranges + buf_ranges_n; + data.RangesCount = glyph_ranges_count; + buf_ranges_n += glyph_ranges_count; + for (int i = 0; i < glyph_ranges_count; i++) + { + const ImWchar* in_range = &data.GlyphRanges[i * 2]; + stbtt_pack_range& range = data.Ranges[i]; + range.font_size = data.SizePixels; + range.first_unicode_char_in_range = in_range[0]; + range.num_chars_in_range = (in_range[1] - in_range[0]) + 1; + range.chardata_for_range = buf_packedchars + buf_packedchars_n; + buf_packedchars_n += range.num_chars_in_range; + } + + // Pack + data.Rects = buf_rects + buf_rects_n; + buf_rects_n += glyph_count; + const int n = stbtt_PackFontRangesGatherRects(&spc, &data.FontInfo, data.Ranges, data.RangesCount, data.Rects); + stbrp_pack_rects((stbrp_context*)spc.pack_info, data.Rects, n); + + // Extend texture height + for (int i = 0; i < n; i++) + if (data.Rects[i].was_packed) + TexHeight = ImMax(TexHeight, data.Rects[i].y + data.Rects[i].h); + } + IM_ASSERT(buf_rects_n == total_glyph_count); + IM_ASSERT(buf_packedchars_n == total_glyph_count); + IM_ASSERT(buf_ranges_n == total_glyph_range_count); + + // Create texture + TexHeight = ImUpperPowerOfTwo(TexHeight); + TexPixelsAlpha8 = (unsigned char*)ImGui::MemAlloc(TexWidth * TexHeight); + memset(TexPixelsAlpha8, 0, TexWidth * TexHeight); + spc.pixels = TexPixelsAlpha8; + spc.height = TexHeight; + + // Second pass: render characters + for (size_t input_i = 0; input_i < InputData.size(); input_i++) + { + ImFontAtlasData& data = *InputData[input_i]; + ret = stbtt_PackFontRangesRenderIntoRects(&spc, &data.FontInfo, data.Ranges, data.RangesCount, data.Rects); + data.Rects = NULL; + } + + // End packing + stbtt_PackEnd(&spc); + ImGui::MemFree(buf_rects); + buf_rects = NULL; + + // Third pass: setup ImFont and glyphs for runtime + for (size_t input_i = 0; input_i < InputData.size(); input_i++) + { + ImFontAtlasData& data = *InputData[input_i]; + data.OutFont->ContainerAtlas = this; + data.OutFont->FontSize = data.SizePixels; + + const float font_scale = stbtt_ScaleForPixelHeight(&data.FontInfo, data.SizePixels); + int font_ascent, font_descent, font_line_gap; + stbtt_GetFontVMetrics(&data.FontInfo, &font_ascent, &font_descent, &font_line_gap); + + const float uv_scale_x = 1.0f / TexWidth; + const float uv_scale_y = 1.0f / TexHeight; + const int character_spacing_x = 1; + for (int i = 0; i < data.RangesCount; i++) + { + stbtt_pack_range& range = data.Ranges[i]; + for (int char_idx = 0; char_idx < range.num_chars_in_range; char_idx += 1) + { + const int codepoint = range.first_unicode_char_in_range + char_idx; + const stbtt_packedchar& pc = range.chardata_for_range[char_idx]; + if (!pc.x0 && !pc.x1 && !pc.y0 && !pc.y1) + continue; + + data.OutFont->Glyphs.resize(data.OutFont->Glyphs.size() + 1); + ImFont::Glyph& glyph = data.OutFont->Glyphs.back(); + glyph.Codepoint = (ImWchar)codepoint; + glyph.Width = (signed short)pc.x1 - pc.x0 + 1; + glyph.Height = (signed short)pc.y1 - pc.y0 + 1; + glyph.XOffset = (signed short)(pc.xoff); + glyph.YOffset = (signed short)(pc.yoff + (int)(font_ascent * font_scale)); + glyph.XAdvance = (signed short)(pc.xadvance + character_spacing_x); // Bake spacing into XAdvance + glyph.U0 = ((float)pc.x0 - 0.5f) * uv_scale_x; + glyph.V0 = ((float)pc.y0 - 0.5f) * uv_scale_y; + glyph.U1 = ((float)pc.x0 - 0.5f + glyph.Width) * uv_scale_x; + glyph.V1 = ((float)pc.y0 - 0.5f + glyph.Height) * uv_scale_y; + } + } + + data.OutFont->BuildLookupTable(); + } + + // Cleanup temporaries + ImGui::MemFree(buf_packedchars); + ImGui::MemFree(buf_ranges); + buf_packedchars = NULL; + buf_ranges = NULL; + ClearInputData(); + + // Render into our custom data block + RenderCustomTexData(1, &extra_rects); + + return true; +} + +void ImFontAtlas::RenderCustomTexData(int pass, void* p_rects) +{ + // . = white layer, X = black layer, others are blank + const int TEX_DATA_W = 90; + const int TEX_DATA_H = 27; + const char texture_data[TEX_DATA_W*TEX_DATA_H+1] = + { + "..- -XXXXXXX- X - X -XXXXXXX - XXXXXXX" + "..- -X.....X- X.X - X.X -X.....X - X.....X" + "--- -XXX.XXX- X...X - X...X -X....X - X....X" + "X - X.X - X.....X - X.....X -X...X - X...X" + "XX - X.X -X.......X- X.......X -X..X.X - X.X..X" + "X.X - X.X -XXXX.XXXX- XXXX.XXXX -X.X X.X - X.X X.X" + "X..X - X.X - X.X - X.X -XX X.X - X.X XX" + "X...X - X.X - X.X - XX X.X XX - X.X - X.X " + "X....X - X.X - X.X - X.X X.X X.X - X.X - X.X " + "X.....X - X.X - X.X - X..X X.X X..X - X.X - X.X " + "X......X - X.X - X.X - X...XXXXXX.XXXXXX...X - X.X XX-XX X.X " + "X.......X - X.X - X.X -X.....................X- X.X X.X-X.X X.X " + "X........X - X.X - X.X - X...XXXXXX.XXXXXX...X - X.X..X-X..X.X " + "X.........X -XXX.XXX- X.X - X..X X.X X..X - X...X-X...X " + "X..........X-X.....X- X.X - X.X X.X X.X - X....X-X....X " + "X......XXXXX-XXXXXXX- X.X - XX X.X XX - X.....X-X.....X " + "X...X..X --------- X.X - X.X - XXXXXXX-XXXXXXX " + "X..X X..X - -XXXX.XXXX- XXXX.XXXX ------------------------------------" + "X.X X..X - -X.......X- X.......X - XX XX - " + "XX X..X - - X.....X - X.....X - X.X X.X - " + " X..X - X...X - X...X - X..X X..X - " + " XX - X.X - X.X - X...XXXXXXXXXXXXX...X - " + "------------ - X - X -X.....................X- " + " ----------------------------------- X...XXXXXXXXXXXXX...X - " + " - X..X X..X - " + " - X.X X.X - " + " - XX XX - " + }; + + ImVector& rects = *(ImVector*)p_rects; + if (pass == 0) + { + stbrp_rect r; + memset(&r, 0, sizeof(r)); + r.w = (TEX_DATA_W*2)+1; + r.h = TEX_DATA_H+1; + rects.push_back(r); + } + else if (pass == 1) + { + // Copy pixels + const stbrp_rect& r = rects[0]; + for (int y = 0, n = 0; y < TEX_DATA_H; y++) + for (int x = 0; x < TEX_DATA_W; x++, n++) + { + const int offset0 = (int)(r.x + x) + (int)(r.y + y) * TexWidth; + const int offset1 = offset0 + 1 + TEX_DATA_W; + TexPixelsAlpha8[offset0] = texture_data[n] == '.' ? 0xFF : 0x00; + TexPixelsAlpha8[offset1] = texture_data[n] == 'X' ? 0xFF : 0x00; + } + const ImVec2 tex_uv_scale(1.0f / TexWidth, 1.0f / TexHeight); + TexUvWhitePixel = ImVec2(r.x + 0.5f, r.y + 0.5f) * tex_uv_scale; + + const ImVec2 cursor_datas[ImGuiMouseCursor_Count_][3] = + { + // Pos ........ Size ......... Offset ...... + { ImVec2(0,3), ImVec2(12,19), ImVec2( 0, 0) }, // ImGuiMouseCursor_Arrow + { ImVec2(13,0), ImVec2(7,16), ImVec2( 4, 8) }, // ImGuiMouseCursor_TextInput + { ImVec2(31,0), ImVec2(23,23), ImVec2(11,11) }, // ImGuiMouseCursor_Move + { ImVec2(21,0), ImVec2( 9,23), ImVec2( 5,11) }, // ImGuiMouseCursor_ResizeNS + { ImVec2(55,18),ImVec2(23, 9), ImVec2(11, 5) }, // ImGuiMouseCursor_ResizeEW + { ImVec2(73,0), ImVec2(17,17), ImVec2( 9, 9) }, // ImGuiMouseCursor_ResizeNESW + { ImVec2(55,0), ImVec2(17,17), ImVec2( 9, 9) }, // ImGuiMouseCursor_ResizeNWSE + }; + + for (int type = 0; type < ImGuiMouseCursor_Count_; type++) + { + ImGuiMouseCursorData& cursor_data = GImGui->MouseCursorData[type]; + ImVec2 pos = cursor_datas[type][0] + ImVec2((float)r.x, (float)r.y); + const ImVec2 size = cursor_datas[type][1]; + cursor_data.Type = type; + cursor_data.Size = size; + cursor_data.Offset = cursor_datas[type][2]; + cursor_data.TexUvMin[0] = (pos) * tex_uv_scale; + cursor_data.TexUvMax[0] = (pos + size) * tex_uv_scale; + pos.x += TEX_DATA_W+1; + cursor_data.TexUvMin[1] = (pos) * tex_uv_scale; + cursor_data.TexUvMax[1] = (pos + size) * tex_uv_scale; + } + } +} + +//----------------------------------------------------------------------------- +// ImFont +//----------------------------------------------------------------------------- + +ImFont::ImFont() +{ + Scale = 1.0f; + FallbackChar = (ImWchar)'?'; + Clear(); +} + +ImFont::~ImFont() +{ + // Invalidate active font so that the user gets a clear crash instead of a dangling pointer. + // If you want to delete fonts you need to do it between Render() and NewFrame(). + ImGuiState& g = *GImGui; + if (g.Font == this) + g.Font = NULL; + Clear(); +} + +void ImFont::Clear() +{ + FontSize = 0.0f; + DisplayOffset = ImVec2(-0.5f, 0.5f); + ContainerAtlas = NULL; + Glyphs.clear(); + FallbackGlyph = NULL; + FallbackXAdvance = 0.0f; + IndexXAdvance.clear(); + IndexLookup.clear(); +} + +// Retrieve list of range (2 int per range, values are inclusive) +const ImWchar* ImFontAtlas::GetGlyphRangesDefault() +{ + static const ImWchar ranges[] = + { + 0x0020, 0x00FF, // Basic Latin + Latin Supplement + 0, + }; + return &ranges[0]; +} + +const ImWchar* ImFontAtlas::GetGlyphRangesChinese() +{ + static const ImWchar ranges[] = + { + 0x0020, 0x00FF, // Basic Latin + Latin Supplement + 0x3000, 0x30FF, // Punctuations, Hiragana, Katakana + 0x31F0, 0x31FF, // Katakana Phonetic Extensions + 0xFF00, 0xFFEF, // Half-width characters + 0x4e00, 0x9FAF, // CJK Ideograms + 0, + }; + return &ranges[0]; +} + +const ImWchar* ImFontAtlas::GetGlyphRangesJapanese() +{ + // Store the 1946 ideograms code points as successive offsets from the initial unicode codepoint 0x4E00. Each offset has an implicit +1. + // This encoding helps us reduce the source code size. + static const short offsets_from_0x4E00[] = + { + -1,0,1,3,0,0,0,0,1,0,5,1,1,0,7,4,6,10,0,1,9,9,7,1,3,19,1,10,7,1,0,1,0,5,1,0,6,4,2,6,0,0,12,6,8,0,3,5,0,1,0,9,0,0,8,1,1,3,4,5,13,0,0,8,2,17, + 4,3,1,1,9,6,0,0,0,2,1,3,2,22,1,9,11,1,13,1,3,12,0,5,9,2,0,6,12,5,3,12,4,1,2,16,1,1,4,6,5,3,0,6,13,15,5,12,8,14,0,0,6,15,3,6,0,18,8,1,6,14,1, + 5,4,12,24,3,13,12,10,24,0,0,0,1,0,1,1,2,9,10,2,2,0,0,3,3,1,0,3,8,0,3,2,4,4,1,6,11,10,14,6,15,3,4,15,1,0,0,5,2,2,0,0,1,6,5,5,6,0,3,6,5,0,0,1,0, + 11,2,2,8,4,7,0,10,0,1,2,17,19,3,0,2,5,0,6,2,4,4,6,1,1,11,2,0,3,1,2,1,2,10,7,6,3,16,0,8,24,0,0,3,1,1,3,0,1,6,0,0,0,2,0,1,5,15,0,1,0,0,2,11,19, + 1,4,19,7,6,5,1,0,0,0,0,5,1,0,1,9,0,0,5,0,2,0,1,0,3,0,11,3,0,2,0,0,0,0,0,9,3,6,4,12,0,14,0,0,29,10,8,0,14,37,13,0,31,16,19,0,8,30,1,20,8,3,48, + 21,1,0,12,0,10,44,34,42,54,11,18,82,0,2,1,2,12,1,0,6,2,17,2,12,7,0,7,17,4,2,6,24,23,8,23,39,2,16,23,1,0,5,1,2,15,14,5,6,2,11,0,8,6,2,2,2,14, + 20,4,15,3,4,11,10,10,2,5,2,1,30,2,1,0,0,22,5,5,0,3,1,5,4,1,0,0,2,2,21,1,5,1,2,16,2,1,3,4,0,8,4,0,0,5,14,11,2,16,1,13,1,7,0,22,15,3,1,22,7,14, + 22,19,11,24,18,46,10,20,64,45,3,2,0,4,5,0,1,4,25,1,0,0,2,10,0,0,0,1,0,1,2,0,0,9,1,2,0,0,0,2,5,2,1,1,5,5,8,1,1,1,5,1,4,9,1,3,0,1,0,1,1,2,0,0, + 2,0,1,8,22,8,1,0,0,0,0,4,2,1,0,9,8,5,0,9,1,30,24,2,6,4,39,0,14,5,16,6,26,179,0,2,1,1,0,0,0,5,2,9,6,0,2,5,16,7,5,1,1,0,2,4,4,7,15,13,14,0,0, + 3,0,1,0,0,0,2,1,6,4,5,1,4,9,0,3,1,8,0,0,10,5,0,43,0,2,6,8,4,0,2,0,0,9,6,0,9,3,1,6,20,14,6,1,4,0,7,2,3,0,2,0,5,0,3,1,0,3,9,7,0,3,4,0,4,9,1,6,0, + 9,0,0,2,3,10,9,28,3,6,2,4,1,2,32,4,1,18,2,0,3,1,5,30,10,0,2,2,2,0,7,9,8,11,10,11,7,2,13,7,5,10,0,3,40,2,0,1,6,12,0,4,5,1,5,11,11,21,4,8,3,7, + 8,8,33,5,23,0,0,19,8,8,2,3,0,6,1,1,1,5,1,27,4,2,5,0,3,5,6,3,1,0,3,1,12,5,3,3,2,0,7,7,2,1,0,4,0,1,1,2,0,10,10,6,2,5,9,7,5,15,15,21,6,11,5,20, + 4,3,5,5,2,5,0,2,1,0,1,7,28,0,9,0,5,12,5,5,18,30,0,12,3,3,21,16,25,32,9,3,14,11,24,5,66,9,1,2,0,5,9,1,5,1,8,0,8,3,3,0,1,15,1,4,8,1,2,7,0,7,2, + 8,3,7,5,3,7,10,2,1,0,0,2,25,0,6,4,0,10,0,4,2,4,1,12,5,38,4,0,4,1,10,5,9,4,0,14,4,2,5,18,20,21,1,3,0,5,0,7,0,3,7,1,3,1,1,8,1,0,0,0,3,2,5,2,11, + 6,0,13,1,3,9,1,12,0,16,6,2,1,0,2,1,12,6,13,11,2,0,28,1,7,8,14,13,8,13,0,2,0,5,4,8,10,2,37,42,19,6,6,7,4,14,11,18,14,80,7,6,0,4,72,12,36,27, + 7,7,0,14,17,19,164,27,0,5,10,7,3,13,6,14,0,2,2,5,3,0,6,13,0,0,10,29,0,4,0,3,13,0,3,1,6,51,1,5,28,2,0,8,0,20,2,4,0,25,2,10,13,10,0,16,4,0,1,0, + 2,1,7,0,1,8,11,0,0,1,2,7,2,23,11,6,6,4,16,2,2,2,0,22,9,3,3,5,2,0,15,16,21,2,9,20,15,15,5,3,9,1,0,0,1,7,7,5,4,2,2,2,38,24,14,0,0,15,5,6,24,14, + 5,5,11,0,21,12,0,3,8,4,11,1,8,0,11,27,7,2,4,9,21,59,0,1,39,3,60,62,3,0,12,11,0,3,30,11,0,13,88,4,15,5,28,13,1,4,48,17,17,4,28,32,46,0,16,0, + 18,11,1,8,6,38,11,2,6,11,38,2,0,45,3,11,2,7,8,4,30,14,17,2,1,1,65,18,12,16,4,2,45,123,12,56,33,1,4,3,4,7,0,0,0,3,2,0,16,4,2,4,2,0,7,4,5,2,26, + 2,25,6,11,6,1,16,2,6,17,77,15,3,35,0,1,0,5,1,0,38,16,6,3,12,3,3,3,0,9,3,1,3,5,2,9,0,18,0,25,1,3,32,1,72,46,6,2,7,1,3,14,17,0,28,1,40,13,0,20, + 15,40,6,38,24,12,43,1,1,9,0,12,6,0,6,2,4,19,3,7,1,48,0,9,5,0,5,6,9,6,10,15,2,11,19,3,9,2,0,1,10,1,27,8,1,3,6,1,14,0,26,0,27,16,3,4,9,6,2,23, + 9,10,5,25,2,1,6,1,1,48,15,9,15,14,3,4,26,60,29,13,37,21,1,6,4,0,2,11,22,23,16,16,2,2,1,3,0,5,1,6,4,0,0,4,0,0,8,3,0,2,5,0,7,1,7,3,13,2,4,10, + 3,0,2,31,0,18,3,0,12,10,4,1,0,7,5,7,0,5,4,12,2,22,10,4,2,15,2,8,9,0,23,2,197,51,3,1,1,4,13,4,3,21,4,19,3,10,5,40,0,4,1,1,10,4,1,27,34,7,21, + 2,17,2,9,6,4,2,3,0,4,2,7,8,2,5,1,15,21,3,4,4,2,2,17,22,1,5,22,4,26,7,0,32,1,11,42,15,4,1,2,5,0,19,3,1,8,6,0,10,1,9,2,13,30,8,2,24,17,19,1,4, + 4,25,13,0,10,16,11,39,18,8,5,30,82,1,6,8,18,77,11,13,20,75,11,112,78,33,3,0,0,60,17,84,9,1,1,12,30,10,49,5,32,158,178,5,5,6,3,3,1,3,1,4,7,6, + 19,31,21,0,2,9,5,6,27,4,9,8,1,76,18,12,1,4,0,3,3,6,3,12,2,8,30,16,2,25,1,5,5,4,3,0,6,10,2,3,1,0,5,1,19,3,0,8,1,5,2,6,0,0,0,19,1,2,0,5,1,2,5, + 1,3,7,0,4,12,7,3,10,22,0,9,5,1,0,2,20,1,1,3,23,30,3,9,9,1,4,191,14,3,15,6,8,50,0,1,0,0,4,0,0,1,0,2,4,2,0,2,3,0,2,0,2,2,8,7,0,1,1,1,3,3,17,11, + 91,1,9,3,2,13,4,24,15,41,3,13,3,1,20,4,125,29,30,1,0,4,12,2,21,4,5,5,19,11,0,13,11,86,2,18,0,7,1,8,8,2,2,22,1,2,6,5,2,0,1,2,8,0,2,0,5,2,1,0, + 2,10,2,0,5,9,2,1,2,0,1,0,4,0,0,10,2,5,3,0,6,1,0,1,4,4,33,3,13,17,3,18,6,4,7,1,5,78,0,4,1,13,7,1,8,1,0,35,27,15,3,0,0,0,1,11,5,41,38,15,22,6, + 14,14,2,1,11,6,20,63,5,8,27,7,11,2,2,40,58,23,50,54,56,293,8,8,1,5,1,14,0,1,12,37,89,8,8,8,2,10,6,0,0,0,4,5,2,1,0,1,1,2,7,0,3,3,0,4,6,0,3,2, + 19,3,8,0,0,0,4,4,16,0,4,1,5,1,3,0,3,4,6,2,17,10,10,31,6,4,3,6,10,126,7,3,2,2,0,9,0,0,5,20,13,0,15,0,6,0,2,5,8,64,50,3,2,12,2,9,0,0,11,8,20, + 109,2,18,23,0,0,9,61,3,0,28,41,77,27,19,17,81,5,2,14,5,83,57,252,14,154,263,14,20,8,13,6,57,39,38, + }; + static int ranges_unpacked = false; + static ImWchar ranges[8 + IM_ARRAYSIZE(offsets_from_0x4E00)*2 + 1] = + { + 0x0020, 0x00FF, // Basic Latin + Latin Supplement + 0x3000, 0x30FF, // Punctuations, Hiragana, Katakana + 0x31F0, 0x31FF, // Katakana Phonetic Extensions + 0xFF00, 0xFFEF, // Half-width characters + }; + if (!ranges_unpacked) + { + // Unpack + int codepoint = 0x4e00; + ImWchar* dst = &ranges[8]; + for (int n = 0; n < IM_ARRAYSIZE(offsets_from_0x4E00); n++, dst += 2) + dst[0] = dst[1] = (ImWchar)(codepoint += (offsets_from_0x4E00[n] + 1)); + dst[0] = 0; + ranges_unpacked = true; + } + return &ranges[0]; +} + +void ImFont::BuildLookupTable() +{ + int max_codepoint = 0; + for (size_t i = 0; i != Glyphs.size(); i++) + max_codepoint = ImMax(max_codepoint, (int)Glyphs[i].Codepoint); + + IndexXAdvance.clear(); + IndexXAdvance.resize((size_t)max_codepoint + 1); + IndexLookup.clear(); + IndexLookup.resize((size_t)max_codepoint + 1); + for (size_t i = 0; i < (size_t)max_codepoint + 1; i++) + { + IndexXAdvance[i] = -1.0f; + IndexLookup[i] = -1; + } + for (size_t i = 0; i < Glyphs.size(); i++) + { + const size_t codepoint = (int)Glyphs[i].Codepoint; + IndexXAdvance[codepoint] = Glyphs[i].XAdvance; + IndexLookup[codepoint] = (int)i; + } + + // Create a glyph to handle TAB + // FIXME: Needs proper TAB handling but it needs to be contextualized (can arbitrary say that each string starts at "column 0" + if (FindGlyph((unsigned short)' ')) + { + if (Glyphs.back().Codepoint != '\t') // So we can call this function multiple times + Glyphs.resize(Glyphs.size() + 1); + ImFont::Glyph& tab_glyph = Glyphs.back(); + tab_glyph = *FindGlyph((unsigned short)' '); + tab_glyph.Codepoint = '\t'; + tab_glyph.XAdvance *= 4; + IndexXAdvance[(size_t)tab_glyph.Codepoint] = (float)tab_glyph.XAdvance; + IndexLookup[(size_t)tab_glyph.Codepoint] = (int)(Glyphs.size()-1); + } + + FallbackGlyph = NULL; + FallbackGlyph = FindGlyph(FallbackChar); + FallbackXAdvance = FallbackGlyph ? FallbackGlyph->XAdvance : 0.0f; + for (size_t i = 0; i < (size_t)max_codepoint + 1; i++) + if (IndexXAdvance[i] < 0.0f) + IndexXAdvance[i] = FallbackXAdvance; +} + +void ImFont::SetFallbackChar(ImWchar c) +{ + FallbackChar = c; + BuildLookupTable(); +} + +const ImFont::Glyph* ImFont::FindGlyph(unsigned short c) const +{ + if (c < (int)IndexLookup.size()) + { + const int i = IndexLookup[c]; + if (i != -1) + return &Glyphs[i]; + } + return FallbackGlyph; +} + +// Convert UTF-8 to 32-bits character, process single character input. +// Based on stb_from_utf8() from github.com/nothings/stb/ +// We handle UTF-8 decoding error by skipping forward. +static int ImTextCharFromUtf8(unsigned int* out_char, const char* in_text, const char* in_text_end) +{ + unsigned int c = (unsigned int)-1; + const unsigned char* str = (const unsigned char*)in_text; + if (!(*str & 0x80)) + { + c = (unsigned int)(*str++); + *out_char = c; + return 1; + } + if ((*str & 0xe0) == 0xc0) + { + *out_char = 0; + if (in_text_end && in_text_end - (const char*)str < 2) return 0; + if (*str < 0xc2) return 0; + c = (unsigned int)((*str++ & 0x1f) << 6); + if ((*str & 0xc0) != 0x80) return 0; + c += (*str++ & 0x3f); + *out_char = c; + return 2; + } + if ((*str & 0xf0) == 0xe0) + { + *out_char = 0; + if (in_text_end && in_text_end - (const char*)str < 3) return 0; + if (*str == 0xe0 && (str[1] < 0xa0 || str[1] > 0xbf)) return 0; + if (*str == 0xed && str[1] > 0x9f) return 0; // str[1] < 0x80 is checked below + c = (unsigned int)((*str++ & 0x0f) << 12); + if ((*str & 0xc0) != 0x80) return 0; + c += (unsigned int)((*str++ & 0x3f) << 6); + if ((*str & 0xc0) != 0x80) return 0; + c += (*str++ & 0x3f); + *out_char = c; + return 3; + } + if ((*str & 0xf8) == 0xf0) + { + *out_char = 0; + if (in_text_end && in_text_end - (const char*)str < 4) return 0; + if (*str > 0xf4) return 0; + if (*str == 0xf0 && (str[1] < 0x90 || str[1] > 0xbf)) return 0; + if (*str == 0xf4 && str[1] > 0x8f) return 0; // str[1] < 0x80 is checked below + c = (unsigned int)((*str++ & 0x07) << 18); + if ((*str & 0xc0) != 0x80) return 0; + c += (unsigned int)((*str++ & 0x3f) << 12); + if ((*str & 0xc0) != 0x80) return 0; + c += (unsigned int)((*str++ & 0x3f) << 6); + if ((*str & 0xc0) != 0x80) return 0; + c += (*str++ & 0x3f); + // utf-8 encodings of values used in surrogate pairs are invalid + if ((c & 0xFFFFF800) == 0xD800) return 0; + *out_char = c; + return 4; + } + *out_char = 0; + return 0; +} + +static ptrdiff_t ImTextStrFromUtf8(ImWchar* buf, size_t buf_size, const char* in_text, const char* in_text_end, const char** in_text_remaining) +{ + ImWchar* buf_out = buf; + ImWchar* buf_end = buf + buf_size; + while (buf_out < buf_end-1 && (!in_text_end || in_text < in_text_end) && *in_text) + { + unsigned int c; + in_text += ImTextCharFromUtf8(&c, in_text, in_text_end); + if (c == 0) + break; + if (c < 0x10000) // FIXME: Losing characters that don't fit in 2 bytes + *buf_out++ = (ImWchar)c; + } + *buf_out = 0; + if (in_text_remaining) + *in_text_remaining = in_text; + return buf_out - buf; +} + +static int ImTextCountCharsFromUtf8(const char* in_text, const char* in_text_end) +{ + int char_count = 0; + while ((!in_text_end || in_text < in_text_end) && *in_text) + { + unsigned int c; + in_text += ImTextCharFromUtf8(&c, in_text, in_text_end); + if (c == 0) + break; + if (c < 0x10000) + char_count++; + } + return char_count; +} + +// Based on stb_to_utf8() from github.com/nothings/stb/ +static int ImTextCharToUtf8(char* buf, size_t buf_size, unsigned int c) +{ + if (c) + { + size_t i = 0; + size_t n = buf_size; + if (c < 0x80) + { + if (i+1 > n) return 0; + buf[i++] = (char)c; + return 1; + } + else if (c < 0x800) + { + if (i+2 > n) return 0; + buf[i++] = (char)(0xc0 + (c >> 6)); + buf[i++] = (char)(0x80 + (c & 0x3f)); + return 2; + } + else if (c >= 0xdc00 && c < 0xe000) + { + return 0; + } + else if (c >= 0xd800 && c < 0xdc00) + { + if (i+4 > n) return 0; + buf[i++] = (char)(0xf0 + (c >> 18)); + buf[i++] = (char)(0x80 + ((c >> 12) & 0x3f)); + buf[i++] = (char)(0x80 + ((c >> 6) & 0x3f)); + buf[i++] = (char)(0x80 + ((c ) & 0x3f)); + return 4; + } + //else if (c < 0x10000) + { + if (i+3 > n) return 0; + buf[i++] = (char)(0xe0 + (c >> 12)); + buf[i++] = (char)(0x80 + ((c>> 6) & 0x3f)); + buf[i++] = (char)(0x80 + ((c ) & 0x3f)); + return 3; + } + } + return 0; +} + +static ptrdiff_t ImTextStrToUtf8(char* buf, size_t buf_size, const ImWchar* in_text, const ImWchar* in_text_end) +{ + char* buf_out = buf; + const char* buf_end = buf + buf_size; + while (buf_out < buf_end-1 && (!in_text_end || in_text < in_text_end) && *in_text) + { + buf_out += ImTextCharToUtf8(buf_out, (uintptr_t)(buf_end-buf_out-1), (unsigned int)*in_text); + in_text++; + } + *buf_out = 0; + return buf_out - buf; +} + +static int ImTextCountUtf8BytesFromStr(const ImWchar* in_text, const ImWchar* in_text_end) +{ + int bytes_count = 0; + while ((!in_text_end || in_text < in_text_end) && *in_text) + { + char dummy[5]; // FIXME-OPT + bytes_count += ImTextCharToUtf8(dummy, 5, (unsigned int)*in_text); + in_text++; + } + return bytes_count; +} + +const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) const +{ + // Simple word-wrapping for English, not full-featured. Please submit failing cases! + // FIXME: Much possible improvements (don't cut things like "word !", "word!!!" but cut within "word,,,,", more sensible support for punctuations, support for Unicode punctuations, etc.) + + // For references, possible wrap point marked with ^ + // "aaa bbb, ccc,ddd. eee fff. ggg!" + // ^ ^ ^ ^ ^__ ^ ^ + + // List of hardcoded separators: .,;!?'" + + // Skip extra blanks after a line returns (that includes not counting them in width computation) + // e.g. "Hello world" --> "Hello" "World" + + // Cut words that cannot possibly fit within one line. + // e.g.: "The tropical fish" with ~5 characters worth of width --> "The tr" "opical" "fish" + + float line_width = 0.0f; + float word_width = 0.0f; + float blank_width = 0.0f; + + const char* word_end = text; + const char* prev_word_end = NULL; + bool inside_word = true; + + const char* s = text; + while (s < text_end) + { + unsigned int c = (unsigned int)*s; + const char* next_s; + if (c < 0x80) + next_s = s + 1; + else + next_s = s + ImTextCharFromUtf8(&c, s, text_end); + if (c == 0) + break; + + if (c == '\n') + { + line_width = word_width = blank_width = 0.0f; + inside_word = true; + s = next_s; + continue; + } + + const float char_width = ((size_t)c < IndexXAdvance.size()) ? IndexXAdvance[(size_t)c] * scale : FallbackXAdvance; + if (ImCharIsSpace(c)) + { + if (inside_word) + { + line_width += blank_width; + blank_width = 0.0f; + } + blank_width += char_width; + inside_word = false; + } + else + { + word_width += char_width; + if (inside_word) + { + word_end = next_s; + } + else + { + prev_word_end = word_end; + line_width += word_width + blank_width; + word_width = blank_width = 0.0f; + } + + // Allow wrapping after punctuation. + inside_word = !(c == '.' || c == ',' || c == ';' || c == '!' || c == '?' || c == '\"'); + } + + // We ignore blank width at the end of the line (they can be skipped) + if (line_width + word_width >= wrap_width) + { + // Words that cannot possibly fit within an entire line will be cut anywhere. + if (word_width < wrap_width) + s = prev_word_end ? prev_word_end : word_end; + break; + } + + s = next_s; + } + + return s; +} + +ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end, const char** remaining) const +{ + if (!text_end) + text_end = text_begin + strlen(text_begin); // FIXME-OPT: Need to avoid this. + + const float scale = size / FontSize; + const float line_height = FontSize * scale; + + ImVec2 text_size = ImVec2(0,0); + float line_width = 0.0f; + + const bool word_wrap_enabled = (wrap_width > 0.0f); + const char* word_wrap_eol = NULL; + + const char* s = text_begin; + while (s < text_end) + { + if (word_wrap_enabled) + { + // Calculate how far we can render. Requires two passes on the string data but keeps the code simple and not intrusive for what's essentially an uncommon feature. + if (!word_wrap_eol) + { + word_wrap_eol = CalcWordWrapPositionA(scale, s, text_end, wrap_width - line_width); + if (word_wrap_eol == s) // Wrap_width is too small to fit anything. Force displaying 1 character to minimize the height discontinuity. + word_wrap_eol++; // +1 may not be a character start point in UTF-8 but it's ok because we use s >= word_wrap_eol below + } + + if (s >= word_wrap_eol) + { + if (text_size.x < line_width) + text_size.x = line_width; + text_size.y += line_height; + line_width = 0.0f; + word_wrap_eol = NULL; + + // Wrapping skips upcoming blanks + while (s < text_end) + { + const char c = *s; + if (ImCharIsSpace(c)) { s++; } else if (c == '\n') { s++; break; } else { break; } + } + continue; + } + } + + // Decode and advance source (handle unlikely UTF-8 decoding failure by skipping to the next byte) + const char* prev_s = s; + unsigned int c = (unsigned int)*s; + if (c < 0x80) + { + s += 1; + } + else + { + s += ImTextCharFromUtf8(&c, s, text_end); + if (c == 0) + break; + } + + if (c == '\n') + { + text_size.x = ImMax(text_size.x, line_width); + text_size.y += line_height; + line_width = 0.0f; + continue; + } + + const float char_width = ((size_t)c < IndexXAdvance.size()) ? IndexXAdvance[(size_t)c] * scale : FallbackXAdvance; + if (line_width + char_width >= max_width) + { + s = prev_s; + break; + } + + line_width += char_width; + } + + if (line_width > 0 || text_size.y == 0.0f) + { + if (text_size.x < line_width) + text_size.x = line_width; + text_size.y += line_height; + } + + if (remaining) + *remaining = s; + + return text_size; +} + +ImVec2 ImFont::CalcTextSizeW(float size, float max_width, const ImWchar* text_begin, const ImWchar* text_end, const ImWchar** remaining) const +{ + if (!text_end) + text_end = text_begin + ImStrlenW(text_begin); + + const float scale = size / FontSize; + const float line_height = FontSize * scale; + + ImVec2 text_size = ImVec2(0,0); + float line_width = 0.0f; + + const ImWchar* s = text_begin; + while (s < text_end) + { + const unsigned int c = (unsigned int)(*s++); + + if (c == '\n') + { + text_size.x = ImMax(text_size.x, line_width); + text_size.y += line_height; + line_width = 0.0f; + continue; + } + + const float char_width = ((size_t)c < IndexXAdvance.size()) ? IndexXAdvance[(size_t)c] * scale : FallbackXAdvance; + if (line_width + char_width >= max_width) + { + s--; + break; + } + + line_width += char_width; + } + + if (line_width > 0 || text_size.y == 0.0f) + { + if (text_size.x < line_width) + text_size.x = line_width; + text_size.y += line_height; + } + + if (remaining) + *remaining = s; + + return text_size; +} + +void ImFont::RenderText(float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect_ref, const char* text_begin, const char* text_end, ImDrawList* draw_list, float wrap_width, const ImVec2* cpu_clip_max) const +{ + if (!text_end) + text_end = text_begin + strlen(text_begin); + + const float scale = size / FontSize; + const float line_height = FontSize * scale; + + // Align to be pixel perfect + pos.x = (float)(int)pos.x + DisplayOffset.x; + pos.y = (float)(int)pos.y + DisplayOffset.y; + + const bool word_wrap_enabled = (wrap_width > 0.0f); + const char* word_wrap_eol = NULL; + + ImVec4 clip_rect = clip_rect_ref; + if (cpu_clip_max) + { + clip_rect.z = ImMin(clip_rect.z, cpu_clip_max->x); + clip_rect.w = ImMin(clip_rect.w, cpu_clip_max->y); + } + float x = pos.x; + float y = pos.y; + + ImDrawVert* out_vertices = draw_list->vtx_write; + + const char* s = text_begin; + while (s < text_end) + { + if (word_wrap_enabled) + { + // Calculate how far we can render. Requires two passes on the string data but keeps the code simple and not intrusive for what's essentially an uncommon feature. + if (!word_wrap_eol) + { + word_wrap_eol = CalcWordWrapPositionA(scale, s, text_end, wrap_width - (x - pos.x)); + if (word_wrap_eol == s) // Wrap_width is too small to fit anything. Force displaying 1 character to minimize the height discontinuity. + word_wrap_eol++; // +1 may not be a character start point in UTF-8 but it's ok because we use s >= word_wrap_eol below + } + + if (s >= word_wrap_eol) + { + x = pos.x; + y += line_height; + word_wrap_eol = NULL; + + // Wrapping skips upcoming blanks + while (s < text_end) + { + const char c = *s; + if (ImCharIsSpace(c)) { s++; } else if (c == '\n') { s++; break; } else { break; } + } + continue; + } + } + + // Decode and advance source (handle unlikely UTF-8 decoding failure by skipping to the next byte) + unsigned int c = (unsigned int)*s; + if (c < 0x80) + { + s += 1; + } + else + { + s += ImTextCharFromUtf8(&c, s, text_end); + if (c == 0) + break; + } + + if (c == '\n') + { + x = pos.x; + y += line_height; + continue; + } + + float char_width = 0.0f; + if (const Glyph* glyph = FindGlyph((unsigned short)c)) + { + char_width = glyph->XAdvance * scale; + if (c != ' ' && c != '\t') + { + // Clipping on Y is more likely + float y1 = (float)(y + glyph->YOffset * scale); + float y2 = (float)(y1 + glyph->Height * scale); + if (y1 <= clip_rect.w && y2 >= clip_rect.y) + { + float x1 = (float)(x + glyph->XOffset * scale); + float x2 = (float)(x1 + glyph->Width * scale); + if (x1 <= clip_rect.z && x2 >= clip_rect.x) + { + // Render a character + float u1 = glyph->U0; + float v1 = glyph->V0; + float u2 = glyph->U1; + float v2 = glyph->V1; + + // CPU side clipping used to fit text in their frame when the frame is too small. Only does clipping for axis aligned quad and in the "max" direction (bottom-right) + if (cpu_clip_max) + { + if (x2 > cpu_clip_max->x) + { + const float clip_tx = (cpu_clip_max->x - x1) / (x2 - x1); + x2 = cpu_clip_max->x; + u2 = u1 + clip_tx * (u2 - u1); + } + if (y2 > cpu_clip_max->y) + { + const float clip_ty = (cpu_clip_max->y - y1) / (y2 - y1); + y2 = cpu_clip_max->y; + v2 = v1 + clip_ty * (v2 - v1); + } + } + + // NB: we are not calling PrimRectUV() here because non-inlined causes too much overhead in a debug build. + out_vertices[0].pos = ImVec2(x1, y1); + out_vertices[0].uv = ImVec2(u1, v1); + out_vertices[0].col = col; + + out_vertices[1].pos = ImVec2(x2, y1); + out_vertices[1].uv = ImVec2(u2, v1); + out_vertices[1].col = col; + + out_vertices[2].pos = ImVec2(x2, y2); + out_vertices[2].uv = ImVec2(u2, v2); + out_vertices[2].col = col; + + out_vertices[3] = out_vertices[0]; + out_vertices[4] = out_vertices[2]; + + out_vertices[5].pos = ImVec2(x1, y2); + out_vertices[5].uv = ImVec2(u1, v2); + out_vertices[5].col = col; + + out_vertices += 6; + } + } + } + } + + x += char_width; + } + + draw_list->vtx_write = out_vertices; +} + +//----------------------------------------------------------------------------- +// PLATFORM DEPENDANT HELPERS +//----------------------------------------------------------------------------- + +#if defined(_MSC_VER) && !defined(IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS) + +#ifndef _WINDOWS_ +#define WIN32_LEAN_AND_MEAN +#include +#endif + +// Win32 API clipboard implementation +static const char* GetClipboardTextFn_DefaultImpl() +{ + static char* buf_local = NULL; + if (buf_local) + { + ImGui::MemFree(buf_local); + buf_local = NULL; + } + if (!OpenClipboard(NULL)) + return NULL; + HANDLE wbuf_handle = GetClipboardData(CF_UNICODETEXT); + if (wbuf_handle == NULL) + return NULL; + if (ImWchar* wbuf_global = (ImWchar*)GlobalLock(wbuf_handle)) + { + int buf_len = ImTextCountUtf8BytesFromStr(wbuf_global, NULL) + 1; + buf_local = (char*)ImGui::MemAlloc(buf_len * sizeof(char)); + ImTextStrToUtf8(buf_local, buf_len, wbuf_global, NULL); + } + GlobalUnlock(wbuf_handle); + CloseClipboard(); + return buf_local; +} + +// Win32 API clipboard implementation +static void SetClipboardTextFn_DefaultImpl(const char* text) +{ + if (!OpenClipboard(NULL)) + return; + + const int wbuf_length = ImTextCountCharsFromUtf8(text, NULL) + 1; + HGLOBAL wbuf_handle = GlobalAlloc(GMEM_MOVEABLE, (SIZE_T)wbuf_length * sizeof(ImWchar)); + if (wbuf_handle == NULL) + return; + ImWchar* wbuf_global = (ImWchar*)GlobalLock(wbuf_handle); + ImTextStrFromUtf8(wbuf_global, wbuf_length, text, NULL); + GlobalUnlock(wbuf_handle); + EmptyClipboard(); + SetClipboardData(CF_UNICODETEXT, wbuf_handle); + CloseClipboard(); +} + +#else + +// Local ImGui-only clipboard implementation, if user hasn't defined better clipboard handlers +static const char* GetClipboardTextFn_DefaultImpl() +{ + return GImGui->PrivateClipboard; +} + +// Local ImGui-only clipboard implementation, if user hasn't defined better clipboard handlers +static void SetClipboardTextFn_DefaultImpl(const char* text) +{ + ImGuiState& g = *GImGui; + if (g.PrivateClipboard) + { + ImGui::MemFree(g.PrivateClipboard); + g.PrivateClipboard = NULL; + } + const char* text_end = text + strlen(text); + g.PrivateClipboard = (char*)ImGui::MemAlloc((size_t)(text_end - text) + 1); + memcpy(g.PrivateClipboard, text, (size_t)(text_end - text)); + g.PrivateClipboard[(size_t)(text_end - text)] = 0; +} + +#endif + +#if defined(_MSC_VER) && !defined(IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS) + +#ifndef _WINDOWS_ +#define WIN32_LEAN_AND_MEAN +#include +#endif +#include +#pragma comment(lib, "imm32") + +static void ImeSetInputScreenPosFn_DefaultImpl(int x, int y) +{ + // Notify OS Input Method Editor of text input position + if (HWND hwnd = (HWND)GImGui->IO.ImeWindowHandle) + if (HIMC himc = ImmGetContext(hwnd)) + { + COMPOSITIONFORM cf; + cf.ptCurrentPos.x = x; + cf.ptCurrentPos.y = y; + cf.dwStyle = CFS_FORCE_POSITION; + ImmSetCompositionWindow(himc, &cf); + } +} + +#else + +static void ImeSetInputScreenPosFn_DefaultImpl(int, int) +{ +} + +#endif + +#ifdef IMGUI_DISABLE_TEST_WINDOWS + +void ImGui::ShowUserGuide() {} +void ImGui::ShowStyleEditor(ImGuiStyle*) {} +void ImGui::ShowTestWindow(bool*) {} +void ImGui::ShowMetricsWindow(bool*) {} + +#else + +//----------------------------------------------------------------------------- +// HELP +//----------------------------------------------------------------------------- + +void ImGui::ShowUserGuide() +{ + ImGuiState& g = *GImGui; + + ImGui::BulletText("Double-click on title bar to collapse window."); + ImGui::BulletText("Click and drag on lower right corner to resize window."); + ImGui::BulletText("Click and drag on any empty space to move window."); + ImGui::BulletText("Mouse Wheel to scroll."); + if (g.IO.FontAllowUserScaling) + ImGui::BulletText("CTRL+Mouse Wheel to zoom window contents."); + ImGui::BulletText("TAB/SHIFT+TAB to cycle through keyboard editable fields."); + ImGui::BulletText("CTRL+Click on a slider to input text."); + ImGui::BulletText( + "While editing text:\n" + "- Hold SHIFT or use mouse to select text\n" + "- CTRL+Left/Right to word jump\n" + "- CTRL+A select all\n" + "- CTRL+X,CTRL+C,CTRL+V clipboard\n" + "- CTRL+Z,CTRL+Y undo/redo\n" + "- ESCAPE to revert\n" + "- You can apply arithmetic operators +,*,/ on numerical values.\n" + " Use +- to subtract.\n"); +} + +void ImGui::ShowStyleEditor(ImGuiStyle* ref) +{ + ImGuiState& g = *GImGui; + ImGuiStyle& style = g.Style; + + const ImGuiStyle def; // Default style + + if (ImGui::Button("Revert Style")) + g.Style = ref ? *ref : def; + if (ref) + { + ImGui::SameLine(); + if (ImGui::Button("Save Style")) + *ref = g.Style; + } + + ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.55f); + + if (ImGui::TreeNode("Sizes")) + { + ImGui::SliderFloat("Alpha", &style.Alpha, 0.20f, 1.0f, "%.2f"); // Not exposing zero here so user doesn't "lose" the UI. But application code could have a toggle to switch between zero and non-zero. + ImGui::SliderFloat2("WindowPadding", (float*)&style.WindowPadding, 0.0f, 20.0f, "%.0f"); + ImGui::SliderFloat("WindowRounding", &style.WindowRounding, 0.0f, 16.0f, "%.0f"); + ImGui::SliderFloat("ChildWindowRounding", &style.ChildWindowRounding, 0.0f, 16.0f, "%.0f"); + ImGui::SliderFloat2("FramePadding", (float*)&style.FramePadding, 0.0f, 20.0f, "%.0f"); + ImGui::SliderFloat("FrameRounding", &style.FrameRounding, 0.0f, 16.0f, "%.0f"); + ImGui::SliderFloat2("ItemSpacing", (float*)&style.ItemSpacing, 0.0f, 20.0f, "%.0f"); + ImGui::SliderFloat2("ItemInnerSpacing", (float*)&style.ItemInnerSpacing, 0.0f, 20.0f, "%.0f"); + ImGui::SliderFloat2("TouchExtraPadding", (float*)&style.TouchExtraPadding, 0.0f, 10.0f, "%.0f"); + ImGui::SliderFloat("IndentSpacing", &style.IndentSpacing, 0.0f, 20.0f, "%.0f"); + ImGui::SliderFloat("ScrollBarWidth", &style.ScrollbarWidth, 1.0f, 20.0f, "%.0f"); + ImGui::SliderFloat("GrabMinSize", &style.GrabMinSize, 1.0f, 20.0f, "%.0f"); + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Colors")) + { + static int output_dest = 0; + static bool output_only_modified = false; + if (ImGui::Button("Output Colors")) + { + if (output_dest == 0) + ImGui::LogToClipboard(); + else + ImGui::LogToTTY(); + ImGui::LogText("ImGuiStyle& style = ImGui::GetStyle();" STR_NEWLINE); + for (int i = 0; i < ImGuiCol_COUNT; i++) + { + const ImVec4& col = style.Colors[i]; + const char* name = ImGui::GetStyleColName(i); + if (!output_only_modified || memcmp(&col, (ref ? &ref->Colors[i] : &def.Colors[i]), sizeof(ImVec4)) != 0) + ImGui::LogText("style.Colors[ImGuiCol_%s]%*s= ImVec4(%.2ff, %.2ff, %.2ff, %.2ff);" STR_NEWLINE, name, 22 - strlen(name), "", col.x, col.y, col.z, col.w); + } + ImGui::LogFinish(); + } + ImGui::SameLine(); ImGui::PushItemWidth(150); ImGui::Combo("##output_type", &output_dest, "To Clipboard\0To TTY"); ImGui::PopItemWidth(); + ImGui::SameLine(); ImGui::Checkbox("Only Modified Fields", &output_only_modified); + + static ImGuiColorEditMode edit_mode = ImGuiColorEditMode_RGB; + ImGui::RadioButton("RGB", &edit_mode, ImGuiColorEditMode_RGB); + ImGui::SameLine(); + ImGui::RadioButton("HSV", &edit_mode, ImGuiColorEditMode_HSV); + ImGui::SameLine(); + ImGui::RadioButton("HEX", &edit_mode, ImGuiColorEditMode_HEX); + //ImGui::Text("Tip: Click on colored square to change edit mode."); + + static ImGuiTextFilter filter; + filter.Draw("Filter colors", 200); + + ImGui::BeginChild("#colors", ImVec2(0, 300), true); + + ImGui::ColorEditMode(edit_mode); + for (int i = 0; i < ImGuiCol_COUNT; i++) + { + const char* name = ImGui::GetStyleColName(i); + if (!filter.PassFilter(name)) + continue; + ImGui::PushID(i); + ImGui::ColorEdit4(name, (float*)&style.Colors[i], true); + if (memcmp(&style.Colors[i], (ref ? &ref->Colors[i] : &def.Colors[i]), sizeof(ImVec4)) != 0) + { + ImGui::SameLine(); if (ImGui::Button("Revert")) style.Colors[i] = ref ? ref->Colors[i] : def.Colors[i]; + if (ref) { ImGui::SameLine(); if (ImGui::Button("Save")) ref->Colors[i] = style.Colors[i]; } + } + ImGui::PopID(); + } + ImGui::EndChild(); + + ImGui::TreePop(); + } + + ImGui::PopItemWidth(); +} + +//----------------------------------------------------------------------------- +// SAMPLE CODE +//----------------------------------------------------------------------------- + +static void ShowExampleAppConsole(bool* opened); +static void ShowExampleAppLongText(bool* opened); +static void ShowExampleAppAutoResize(bool* opened); +static void ShowExampleAppFixedOverlay(bool* opened); +static void ShowExampleAppManipulatingWindowTitle(bool* opened); +static void ShowExampleAppCustomRendering(bool* opened); + +// Demonstrate ImGui features (unfortunately this makes this function a little bloated!) +void ImGui::ShowTestWindow(bool* opened) +{ + // Examples apps + static bool show_app_metrics = false; + static bool show_app_console = false; + static bool show_app_long_text = false; + static bool show_app_auto_resize = false; + static bool show_app_fixed_overlay = false; + static bool show_app_custom_rendering = false; + static bool show_app_manipulating_window_title = false; + if (show_app_metrics) + ImGui::ShowMetricsWindow(&show_app_metrics); + if (show_app_console) + ShowExampleAppConsole(&show_app_console); + if (show_app_long_text) + ShowExampleAppLongText(&show_app_long_text); + if (show_app_auto_resize) + ShowExampleAppAutoResize(&show_app_auto_resize); + if (show_app_fixed_overlay) + ShowExampleAppFixedOverlay(&show_app_fixed_overlay); + if (show_app_manipulating_window_title) + ShowExampleAppManipulatingWindowTitle(&show_app_manipulating_window_title); + if (show_app_custom_rendering) + ShowExampleAppCustomRendering(&show_app_custom_rendering); + + static bool no_titlebar = false; + static bool no_border = true; + static bool no_resize = false; + static bool no_move = false; + static bool no_scrollbar = false; + static bool no_collapse = false; + static float bg_alpha = 0.65f; + + // Demonstrate the various window flags. Typically you would just use the default. + ImGuiWindowFlags window_flags = 0; + if (no_titlebar) window_flags |= ImGuiWindowFlags_NoTitleBar; + if (!no_border) window_flags |= ImGuiWindowFlags_ShowBorders; + if (no_resize) window_flags |= ImGuiWindowFlags_NoResize; + if (no_move) window_flags |= ImGuiWindowFlags_NoMove; + if (no_scrollbar) window_flags |= ImGuiWindowFlags_NoScrollbar; + if (no_collapse) window_flags |= ImGuiWindowFlags_NoCollapse; + if (!ImGui::Begin("ImGui Test", opened, ImVec2(550,680), bg_alpha, window_flags)) + { + // Early out if the window is collapsed, as an optimization. + ImGui::End(); + return; + } + + //ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.65f); // 2/3 of the space for widget and 1/3 for labels + ImGui::PushItemWidth(-140); // Right align, keep 140 pixels for labels + + ImGui::Text("ImGui says hello."); + //ImGui::Text("MousePos (%g, %g)", ImGui::GetIO().MousePos.x, ImGui::GetIO().MousePos.y); + //ImGui::Text("MouseWheel %d", ImGui::GetIO().MouseWheel); + //ImGui::Text("KeyMods %s%s%s", ImGui::GetIO().KeyCtrl ? "CTRL" : "", ImGui::GetIO().KeyShift ? "SHIFT" : "", ImGui::GetIO().KeyAlt? "ALT" : ""); + //ImGui::Text("WantCaptureMouse: %d", ImGui::GetIO().WantCaptureMouse); + //ImGui::Text("WantCaptureKeyboard: %d", ImGui::GetIO().WantCaptureKeyboard); + + ImGui::Spacing(); + if (ImGui::CollapsingHeader("Help")) + { + ImGui::TextWrapped("This window is being created by the ShowTestWindow() function. Please refer to the code for programming reference.\n\nUser Guide:"); + ImGui::ShowUserGuide(); + } + + if (ImGui::CollapsingHeader("Window options")) + { + ImGui::Checkbox("no titlebar", &no_titlebar); ImGui::SameLine(150); + ImGui::Checkbox("no border", &no_border); ImGui::SameLine(300); + ImGui::Checkbox("no resize", &no_resize); + ImGui::Checkbox("no move", &no_move); ImGui::SameLine(150); + ImGui::Checkbox("no scrollbar", &no_scrollbar); ImGui::SameLine(300); + ImGui::Checkbox("no collapse", &no_collapse); + ImGui::SliderFloat("bg alpha", &bg_alpha, 0.0f, 1.0f); + + if (ImGui::TreeNode("Style")) + { + ImGui::ShowStyleEditor(); + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Fonts")) + { + ImGui::TextWrapped("Tip: Load fonts with GetIO().Fonts->AddFontFromFileTTF()."); + for (size_t i = 0; i < ImGui::GetIO().Fonts->Fonts.size(); i++) + { + ImFont* font = ImGui::GetIO().Fonts->Fonts[i]; + ImGui::BulletText("Font %d: %.2f pixels, %d glyphs", i, font->FontSize, font->Glyphs.size()); + ImGui::TreePush((void*)i); + ImGui::PushFont(font); + ImGui::Text("The quick brown fox jumps over the lazy dog"); + ImGui::PopFont(); + if (i > 0 && ImGui::Button("Set as default")) + { + ImGui::GetIO().Fonts->Fonts[i] = ImGui::GetIO().Fonts->Fonts[0]; + ImGui::GetIO().Fonts->Fonts[0] = font; + } + ImGui::SliderFloat("font scale", &font->Scale, 0.3f, 2.0f, "%.1f"); // scale only this font + ImGui::TreePop(); + } + static float window_scale = 1.0f; + ImGui::SliderFloat("this window scale", &window_scale, 0.3f, 2.0f, "%.1f"); // scale only this window + ImGui::SliderFloat("global scale", &ImGui::GetIO().FontGlobalScale, 0.3f, 2.0f, "%.1f"); // scale everything + ImGui::SetWindowFontScale(window_scale); + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Logging")) + { + ImGui::LogButtons(); + ImGui::TreePop(); + } + } + + if (ImGui::CollapsingHeader("Widgets")) + { + static bool a=false; + if (ImGui::Button("Button")) { printf("Clicked\n"); a ^= 1; } + if (a) + { + ImGui::SameLine(); + ImGui::Text("Thanks for clicking me!"); + } + + if (ImGui::TreeNode("Tree")) + { + for (size_t i = 0; i < 5; i++) + { + if (ImGui::TreeNode((void*)i, "Child %d", i)) + { + ImGui::Text("blah blah"); + ImGui::SameLine(); + if (ImGui::SmallButton("print")) + printf("Child %d pressed", (int)i); + ImGui::TreePop(); + } + } + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Bullets")) + { + ImGui::BulletText("Bullet point 1"); + ImGui::BulletText("Bullet point 2\nOn multiple lines"); + ImGui::Bullet(); ImGui::Text("Bullet point 3 (two calls)"); + ImGui::Bullet(); ImGui::SmallButton("Button 1"); + ImGui::Bullet(); ImGui::SmallButton("Button 2"); + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Colored Text")) + { + // Using shortcut. You can use PushStyleColor()/PopStyleColor() for more flexibility. + ImGui::TextColored(ImVec4(1.0f,0.0f,1.0f,1.0f), "Pink"); + ImGui::TextColored(ImVec4(1.0f,1.0f,0.0f,1.0f), "Yellow"); + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Word Wrapping")) + { + // Using shortcut. You can use PushTextWrapPos()/PopTextWrapPos() for more flexibility. + ImGui::TextWrapped("This text should automatically wrap on the edge of the window. The current implementation for text wrapping follows simple rules that works for English and possibly other languages."); + ImGui::Spacing(); + + static float wrap_width = 200.0f; + ImGui::SliderFloat("Wrap width", &wrap_width, -20, 600, "%.0f"); + + ImGui::Text("Test paragraph 1:"); + ImGui::GetWindowDrawList()->AddRectFilled(ImGui::GetCursorScreenPos() + ImVec2(wrap_width, 0.0f), ImGui::GetCursorScreenPos() + ImVec2(wrap_width+10, ImGui::GetTextLineHeight()), 0xFFFF00FF); + ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + wrap_width); + ImGui::Text("lazy dog. This paragraph is made to fit within %.0f pixels. The quick brown fox jumps over the lazy dog.", wrap_width); + ImGui::GetWindowDrawList()->AddRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), 0xFF00FFFF); + ImGui::PopTextWrapPos(); + + ImGui::Text("Test paragraph 2:"); + ImGui::GetWindowDrawList()->AddRectFilled(ImGui::GetCursorScreenPos() + ImVec2(wrap_width, 0.0f), ImGui::GetCursorScreenPos() + ImVec2(wrap_width+10, ImGui::GetTextLineHeight()), 0xFFFF00FF); + ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + wrap_width); + ImGui::Text("aaaaaaaa bbbbbbbb, cccccccc,dddddddd. eeeeeeee ffffffff. gggggggg!hhhhhhhh"); + ImGui::GetWindowDrawList()->AddRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), 0xFF00FFFF); + ImGui::PopTextWrapPos(); + + ImGui::TreePop(); + } + + if (ImGui::TreeNode("UTF-8 Text")) + { + // UTF-8 test with Japanese characters + // (needs a suitable font, try Arial Unicode or M+ fonts http://mplus-fonts.sourceforge.jp/mplus-outline-fonts/index-en.html) + // Most compiler appears to support UTF-8 in source code (with Visual Studio you need to save your file as 'UTF-8 without signature') + // However for the sake for maximum portability here we are *not* including raw UTF-8 character in this source file, instead we encode the string with hexadecimal constants. + // In your own application be reasonable and use UTF-8 in source or retrieve the data from file system! + // Note that characters values are preserved even if the font cannot be displayed, so you can safely copy & paste garbled characters into another application. + ImGui::TextWrapped("CJK text will only appears if the font was loaded with the appropriate CJK character ranges. Call io.Font->LoadFromFileTTF() manually to load extra character ranges."); + ImGui::Text("Hiragana: \xe3\x81\x8b\xe3\x81\x8d\xe3\x81\x8f\xe3\x81\x91\xe3\x81\x93 (kakikukeko)"); + ImGui::Text("Kanjis: \xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e (nihongo)"); + static char buf[32] = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e"; + ImGui::InputText("UTF-8 input", buf, IM_ARRAYSIZE(buf)); + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Clipping")) + { + static ImVec2 size(80, 20); + ImGui::TextWrapped("On a per-widget basis we are occasionally clipping text if it won't fit in its frame."); + ImGui::SliderFloat2("size", (float*)&size, 5.0f, 200.0f); + ImGui::Button("Line 1 hello\nLine 2 clip me!", size); + ImGui::TextWrapped("Otherwise we are doing coarser clipping + passing a scissor rectangle to the renderer. The system is designed to try minimizing both execution and rendering cost."); + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Images")) + { + ImGui::TextWrapped("Below we are displaying the font texture (which is the only texture we have access to in this demo). Use the 'ImTextureID' type as storage to pass pointers or identifier to your own texture data. Hover the texture for a zoomed view!"); + ImVec2 tex_screen_pos = ImGui::GetCursorScreenPos(); + float tex_w = (float)ImGui::GetIO().Fonts->TexWidth; + float tex_h = (float)ImGui::GetIO().Fonts->TexHeight; + ImTextureID tex_id = ImGui::GetIO().Fonts->TexID; + ImGui::Image(tex_id, ImVec2(tex_w, tex_h), ImVec2(0,0), ImVec2(1,1), ImColor(255,255,255,255), ImColor(255,255,255,128)); + if (ImGui::IsItemHovered()) + { + ImGui::BeginTooltip(); + float focus_sz = 32.0f; + float focus_x = ImClamp(ImGui::GetMousePos().x - tex_screen_pos.x - focus_sz * 0.5f, 0.0f, tex_w - focus_sz); + float focus_y = ImClamp(ImGui::GetMousePos().y - tex_screen_pos.y - focus_sz * 0.5f, 0.0f, tex_h - focus_sz); + ImGui::Text("Min: (%.2f, %.2f)", focus_x, focus_y); + ImGui::Text("Max: (%.2f, %.2f)", focus_x + focus_sz, focus_y + focus_sz); + ImVec2 uv0 = ImVec2((focus_x) / tex_w, (focus_y) / tex_h); + ImVec2 uv1 = ImVec2((focus_x + focus_sz) / tex_w, (focus_y + focus_sz) / tex_h); + ImGui::Image(tex_id, ImVec2(128,128), uv0, uv1, ImColor(255,255,255,255), ImColor(255,255,255,128)); + ImGui::EndTooltip(); + } + ImGui::TextWrapped("And now some textured buttons.."); + static int pressed_count = 0; + for (int i = 0; i < 8; i++) + { + if (i > 0) + ImGui::SameLine(); + ImGui::PushID(i); + int frame_padding = -1 + i; // -1 padding uses default padding + if (ImGui::ImageButton(tex_id, ImVec2(32,32), ImVec2(0,0), ImVec2(32.0f/tex_w,32/tex_h), frame_padding)) + pressed_count += 1; + ImGui::PopID(); + } + ImGui::Text("Pressed %d times.", pressed_count); + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Selectables")) + { + if (ImGui::TreeNode("Basic")) + { + static bool selected[3] = { false, true, false }; + ImGui::Selectable("1. I am selectable", &selected[0]); + ImGui::Selectable("2. I am selectable", &selected[1]); + ImGui::Text("3. I am not selectable"); + ImGui::Selectable("4. I am selectable", &selected[2]); + ImGui::TreePop(); + } + if (ImGui::TreeNode("Rendering more text into the same block")) + { + static bool selected[3] = { false, false, false }; + ImGui::Selectable("main.c", &selected[0]); ImGui::SameLine(300); ImGui::Text(" 2,345 bytes"); + ImGui::Selectable("Hello.cpp", &selected[1]); ImGui::SameLine(300); ImGui::Text("12,345 bytes"); + ImGui::Selectable("Hello.h", &selected[2]); ImGui::SameLine(300); ImGui::Text(" 2,345 bytes"); + ImGui::TreePop(); + } + if (ImGui::TreeNode("Grid")) + { + static bool selected[16] = { true, false, false, false, false, true, false, false, false, false, true, false, false, false, false, true }; + for (int i = 0; i < 16; i++) + { + ImGui::PushID(i); + if (ImGui::Selectable("Me", &selected[i], ImVec2(50,50))) + { + int x = i % 4, y = i / 4; + if (x > 0) selected[i - 1] ^= 1; + if (x < 3) selected[i + 1] ^= 1; + if (y > 0) selected[i - 4] ^= 1; + if (y < 3) selected[i + 4] ^= 1; + } + if ((i % 4) < 3) ImGui::SameLine(); + ImGui::PopID(); + } + ImGui::TreePop(); + } + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Popup")) + { + static bool popup_open = false; + static int selected_fish = -1; + const char* fishes[] = { "Bream", "Haddock", "Mackerel", "Pollock", "Tilefish" }; + if (ImGui::Button("Select..")) + popup_open = true; + ImGui::SameLine(); + ImGui::Text(selected_fish == -1 ? "" : fishes[selected_fish]); + if (popup_open) + { + ImGui::BeginPopup(&popup_open); + ImGui::Text("Aquarium"); + ImGui::Separator(); + for (int i = 0; i < IM_ARRAYSIZE(fishes); i++) + { + if (ImGui::Selectable(fishes[i], false)) + { + selected_fish = i; + popup_open = false; + } + } + ImGui::EndPopup(); + } + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Filtered Text Input")) + { + static char buf1[64] = ""; ImGui::InputText("default", buf1, 64); + static char buf2[64] = ""; ImGui::InputText("decimal", buf2, 64, ImGuiInputTextFlags_CharsDecimal); + static char buf3[64] = ""; ImGui::InputText("hexadecimal", buf3, 64, ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase); + static char buf4[64] = ""; ImGui::InputText("uppercase", buf4, 64, ImGuiInputTextFlags_CharsUppercase); + static char buf5[64] = ""; ImGui::InputText("no blank", buf5, 64, ImGuiInputTextFlags_CharsNoBlank); + struct TextFilters { static int FilterImGuiLetters(ImGuiTextEditCallbackData* data) { if (data->EventChar < 256 && strchr("imgui", (char)data->EventChar)) return 0; return 1; } }; + static char buf6[64] = ""; ImGui::InputText("\"imgui\" letters", buf6, 64, ImGuiInputTextFlags_CallbackCharFilter, TextFilters::FilterImGuiLetters); + ImGui::TreePop(); + } + + static bool check = true; + ImGui::Checkbox("checkbox", &check); + + static int e = 0; + ImGui::RadioButton("radio a", &e, 0); ImGui::SameLine(); + ImGui::RadioButton("radio b", &e, 1); ImGui::SameLine(); + ImGui::RadioButton("radio c", &e, 2); + + // Color buttons, demonstrate using PushID() to add unique identifier in the ID stack, and changing style. + for (int i = 0; i < 7; i++) + { + if (i > 0) ImGui::SameLine(); + ImGui::PushID(i); + ImGui::PushStyleColor(ImGuiCol_Button, ImColor::HSV(i/7.0f, 0.6f, 0.6f)); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImColor::HSV(i/7.0f, 0.7f, 0.7f)); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImColor::HSV(i/7.0f, 0.8f, 0.8f)); + ImGui::Button("Click"); + ImGui::PopStyleColor(3); + ImGui::PopID(); + } + + ImGui::Text("Hover over me"); + if (ImGui::IsItemHovered()) + ImGui::SetTooltip("I am a tooltip"); + + ImGui::SameLine(); + ImGui::Text("- or me"); + if (ImGui::IsItemHovered()) + { + ImGui::BeginTooltip(); + ImGui::Text("I am a fancy tooltip"); + static float arr[] = { 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f }; + ImGui::PlotLines("Curve", arr, IM_ARRAYSIZE(arr)); + ImGui::EndTooltip(); + } + + // Testing IMGUI_ONCE_UPON_A_FRAME macro + //for (int i = 0; i < 5; i++) + //{ + // IMGUI_ONCE_UPON_A_FRAME + // { + // ImGui::Text("This will be displayed only once."); + // } + //} + + ImGui::Separator(); + + ImGui::LabelText("label", "Value"); + + static int item = 1; + ImGui::Combo("combo", &item, "aaaa\0bbbb\0cccc\0dddd\0eeee\0\0"); + + const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK" }; + static int item2 = -1; + ImGui::Combo("combo scroll", &item2, items, IM_ARRAYSIZE(items)); + + { + static char str0[128] = "Hello, world!"; + static int i0=123; + static float f0=0.001f; + ImGui::InputText("input text", str0, IM_ARRAYSIZE(str0)); + ImGui::InputInt("input int", &i0); + ImGui::InputFloat("input float", &f0, 0.01f, 1.0f); + + static float vec4a[4] = { 0.10f, 0.20f, 0.30f, 0.44f }; + ImGui::InputFloat3("input float3", vec4a); + } + + { + static int i1=50; + static int i2=42; + ImGui::DragInt("drag int", &i1, 1); + ImGui::SameLine(); + ImGui::TextColored(ImColor(170,170,170,255), "(?)"); + if (ImGui::IsItemHovered()) + ImGui::SetTooltip("Click and drag to edit value.\nHold SHIFT/ALT for faster/slower edit.\nDouble-click or CTRL+click to input text"); + + ImGui::DragInt("drag int 0..100", &i2, 1, 0, 100, "%.0f%%"); + + static float f1=1.00f; + static float f2=0.0067f; + ImGui::DragFloat("drag float", &f1, 1.0f); + ImGui::DragFloat("drag small float", &f2, 0.0001f, 0.0f, 0.0f, "%.06f ns"); + } + + { + static int i1=0; + //static int i2=42; + ImGui::SliderInt("slider int 0..3", &i1, 0, 3); + //ImGui::SliderInt("slider int -100..100", &i2, -100, 100); + + static float f1=0.123f; + static float f2=0.0f; + ImGui::SliderFloat("slider float", &f1, 0.0f, 1.0f, "ratio = %.3f"); + ImGui::SliderFloat("slider log float", &f2, -10.0f, 10.0f, "%.4f", 3.0f); + static float angle = 0.0f; + ImGui::SliderAngle("slider angle", &angle); + } + + static float col1[3] = { 1.0f,0.0f,0.2f }; + static float col2[4] = { 0.4f,0.7f,0.0f,0.5f }; + ImGui::ColorEdit3("color 1", col1); + ImGui::ColorEdit4("color 2", col2); + + const char* listbox_items[] = { "Apple", "Banana", "Cherry", "Kiwi", "Mango", "Orange", "Pineapple", "Strawberry", "Watermelon" }; + static int listbox_item_current = 1; + ImGui::ListBox("listbox\n(single select)", &listbox_item_current, listbox_items, IM_ARRAYSIZE(listbox_items), 4); + + //static int listbox_item_current2 = 2; + //ImGui::PushItemWidth(-1); + //ImGui::ListBox("##listbox2", &listbox_item_current2, listbox_items, IM_ARRAYSIZE(listbox_items), 4); + //ImGui::PopItemWidth(); + + if (ImGui::TreeNode("Multi-component Widgets")) + { + ImGui::Unindent(); + + static float vec4f[4] = { 0.10f, 0.20f, 0.30f, 0.44f }; + static int vec4i[4] = { 1, 5, 100, 255 }; + + ImGui::InputFloat2("input float2", vec4f); + ImGui::DragFloat2("drag float2", vec4f, 0.01f, 0.0f, 1.0f); + ImGui::SliderFloat2("slider float2", vec4f, 0.0f, 1.0f); + ImGui::DragInt2("drag int2", vec4i, 1, 0, 255); + ImGui::InputInt2("input int2", vec4i); + ImGui::SliderInt2("slider int2", vec4i, 0, 255); + + ImGui::InputFloat3("input float3", vec4f); + ImGui::DragFloat3("drag float3", vec4f, 0.01f, 0.0f, 1.0f); + ImGui::SliderFloat3("slider float3", vec4f, 0.0f, 1.0f); + ImGui::DragInt3("drag int3", vec4i, 1, 0, 255); + ImGui::InputInt3("input int3", vec4i); + ImGui::SliderInt3("slider int3", vec4i, 0, 255); + + ImGui::InputFloat4("input float4", vec4f); + ImGui::DragFloat4("drag float4", vec4f, 0.01f, 0.0f, 1.0f); + ImGui::SliderFloat4("slider float4", vec4f, 0.0f, 1.0f); + ImGui::InputInt4("input int4", vec4i); + ImGui::DragInt4("drag int4", vec4i, 1, 0, 255); + ImGui::SliderInt4("slider int4", vec4i, 0, 255); + + ImGui::Indent(); + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Vertical Sliders")) + { + ImGui::Unindent(); + const float spacing = 4; + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(spacing, spacing)); + + static int int_value = 0; + ImGui::VSliderInt("##int", ImVec2(18,160), &int_value, 0, 5); + ImGui::SameLine(); + + static float values[7] = { 0.0f, 0.60f, 0.35f, 0.9f, 0.70f, 0.20f, 0.0f }; + ImGui::PushID("set1"); + for (int i = 0; i < 7; i++) + { + if (i > 0) ImGui::SameLine(); + ImGui::PushID(i); + ImGui::PushStyleColor(ImGuiCol_FrameBg, ImColor::HSV(i/7.0f, 0.5f, 0.5f)); + ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, ImColor::HSV(i/7.0f, 0.6f, 0.5f)); + ImGui::PushStyleColor(ImGuiCol_FrameBgActive, ImColor::HSV(i/7.0f, 0.7f, 0.5f)); + ImGui::PushStyleColor(ImGuiCol_SliderGrab, ImColor::HSV(i/7.0f, 0.9f, 0.9f)); + ImGui::VSliderFloat("##v", ImVec2(18,160), &values[i], 0.0f, 1.0f, ""); + if (ImGui::IsItemActive() || ImGui::IsItemHovered()) + ImGui::SetTooltip("%.3f", values[i]); + ImGui::PopStyleColor(4); + ImGui::PopID(); + } + ImGui::PopID(); + + ImGui::SameLine(); + ImGui::PushID("set2"); + static float values2[4] = { 0.20f, 0.80f, 0.40f, 0.25f }; + const int rows = 3; + const ImVec2 small_slider_size(18, (160.0f-(rows-1)*spacing)/rows); + for (int nx = 0; nx < 4; nx++) + { + if (nx > 0) ImGui::SameLine(); + ImGui::BeginGroup(); + for (int ny = 0; ny < rows; ny++) + { + ImGui::PushID(nx*rows+ny); + ImGui::VSliderFloat("##v", small_slider_size, &values2[nx], 0.0f, 1.0f, ""); + if (ImGui::IsItemActive() || ImGui::IsItemHovered()) + ImGui::SetTooltip("%.3f", values2[nx]); + ImGui::PopID(); + } + ImGui::EndGroup(); + } + ImGui::PopID(); + + ImGui::SameLine(); + ImGui::PushID("set3"); + for (int i = 0; i < 4; i++) + { + if (i > 0) ImGui::SameLine(); + ImGui::PushID(i); + ImGui::PushStyleVar(ImGuiStyleVar_GrabMinSize, 40); + ImGui::VSliderFloat("##v", ImVec2(40,160), &values[i], 0.0f, 1.0f, "%.2f"); + ImGui::PopStyleVar(); + ImGui::PopID(); + } + ImGui::PopID(); + + ImGui::Indent(); + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Dragging")) + { + // You can use ImGui::GetItemActiveDragDelta() to query for the dragged amount on any widget. + static ImVec2 value_raw(0.0f, 0.0f); + static ImVec2 value_with_lock_threshold(0.0f, 0.0f); + ImGui::Button("Drag Me"); + if (ImGui::IsItemActive()) + { + value_raw = ImGui::GetMouseDragDelta(0, 0.0f); + value_with_lock_threshold = ImGui::GetMouseDragDelta(0); + //ImGui::SetTooltip("Delta: %.1f, %.1f", value.x, value.y); + + // Draw a line between the button and the mouse cursor + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + draw_list->PushClipRectFullScreen(); + draw_list->AddLine(ImGui::CalcItemRectClosestPoint(ImGui::GetIO().MousePos, true, -2.0f), ImGui::GetIO().MousePos, ImColor(ImGui::GetStyle().Colors[ImGuiCol_Button]), 4.0f); + draw_list->PopClipRect(); + } + ImGui::SameLine(); ImGui::Text("Raw (%.1f, %.1f), WithLockThresold (%.1f, %.1f)", value_raw.x, value_raw.y, value_with_lock_threshold.x, value_with_lock_threshold.y); + ImGui::TreePop(); + } + } + + if (ImGui::CollapsingHeader("Graphs widgets")) + { + static float arr[] = { 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f }; + ImGui::PlotLines("Frame Times", arr, IM_ARRAYSIZE(arr)); + + static bool pause; + static ImVector values; if (values.empty()) { values.resize(90); memset(&values.front(), 0, values.size()*sizeof(float)); } + static size_t values_offset = 0; + if (!pause) + { + // create dummy data at fixed 60 hz rate + static float refresh_time = -1.0f; + if (ImGui::GetTime() > refresh_time + 1.0f/60.0f) + { + refresh_time = ImGui::GetTime(); + static float phase = 0.0f; + values[values_offset] = cosf(phase); + values_offset = (values_offset+1)%values.size(); + phase += 0.10f*values_offset; + } + } + ImGui::PlotLines("##Graph", &values.front(), (int)values.size(), (int)values_offset, "avg 0.0", -1.0f, 1.0f, ImVec2(0,80)); + ImGui::SameLine(0, (int)ImGui::GetStyle().ItemInnerSpacing.x); + ImGui::BeginGroup(); + ImGui::Text("Graph"); + ImGui::Checkbox("pause", &pause); + ImGui::EndGroup(); + ImGui::PlotHistogram("Histogram", arr, IM_ARRAYSIZE(arr), 0, NULL, 0.0f, 1.0f, ImVec2(0,80)); + } + + if (ImGui::CollapsingHeader("Layout")) + { + if (ImGui::TreeNode("Widgets Alignment")) + { + static float f = 0.0f; + ImGui::Text("Fixed: 100 pixels"); + ImGui::PushItemWidth(100); + ImGui::InputFloat("float##1", &f); + ImGui::PopItemWidth(); + + ImGui::Text("Proportional: 50%% of window width"); + ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.5f); + ImGui::InputFloat("float##2", &f); + ImGui::PopItemWidth(); + + ImGui::Text("Right-aligned: Leave 100 pixels for label"); + ImGui::PushItemWidth(-100); + ImGui::InputFloat("float##3", &f); + ImGui::PopItemWidth(); + + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Basic Horizontal Layout")) + { + ImGui::TextWrapped("(Use ImGui::SameLine() to keep adding items to the right of the preceeding item)"); + + // Text + ImGui::Text("Two items: Hello"); + ImGui::SameLine(); + ImGui::TextColored(ImVec4(1,1,0,1), "World"); + + // Adjust spacing + ImGui::Text("More spacing: Hello"); + ImGui::SameLine(0, 20); + ImGui::TextColored(ImVec4(1,1,0,1), "World"); + + // Button + ImGui::AlignFirstTextHeightToWidgets(); + ImGui::Text("Normal buttons"); ImGui::SameLine(); + ImGui::Button("Banana"); ImGui::SameLine(); + ImGui::Button("Apple"); ImGui::SameLine(); + ImGui::Button("Corniflower"); + + // Button + ImGui::Text("Small buttons"); ImGui::SameLine(); + ImGui::SmallButton("Like this one"); ImGui::SameLine(); + ImGui::Text("can fit within a text block."); + + // Aligned to arbitrary position. Easy/cheap column. + ImGui::Text("Aligned"); + ImGui::SameLine(150); ImGui::Text("x=150"); + ImGui::SameLine(300); ImGui::Text("x=300"); + ImGui::Text("Aligned"); + ImGui::SameLine(150); ImGui::SmallButton("x=150"); + ImGui::SameLine(300); ImGui::SmallButton("x=300"); + + // Checkbox + static bool c1=false,c2=false,c3=false,c4=false; + ImGui::Checkbox("My", &c1); ImGui::SameLine(); + ImGui::Checkbox("Tailor", &c2); ImGui::SameLine(); + ImGui::Checkbox("Is", &c3); ImGui::SameLine(); + ImGui::Checkbox("Rich", &c4); + + // Various + static float f0=1.0f, f1=2.0f, f2=3.0f; + ImGui::PushItemWidth(80); + const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD" }; + static int item = -1; + ImGui::Combo("Combo", &item, items, IM_ARRAYSIZE(items)); ImGui::SameLine(); + ImGui::SliderFloat("X", &f0, 0.0f,5.0f); ImGui::SameLine(); + ImGui::SliderFloat("Y", &f1, 0.0f,5.0f); ImGui::SameLine(); + ImGui::SliderFloat("Z", &f2, 0.0f,5.0f); + ImGui::PopItemWidth(); + + ImGui::PushItemWidth(80); + ImGui::Text("Lists:"); + static int selection[4] = { 0, 1, 2, 3 }; + for (int i = 0; i < 4; i++) + { + if (i > 0) ImGui::SameLine(); + ImGui::PushID(i); + ImGui::ListBox("", &selection[i], items, IM_ARRAYSIZE(items)); + ImGui::PopID(); + //if (ImGui::IsItemHovered()) ImGui::SetTooltip("ListBox %d hovered", i); + } + ImGui::PopItemWidth(); + + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Groups")) + { + ImGui::TextWrapped("(Using ImGui::BeginGroup()/EndGroup() to layout items)"); + + ImVec2 size; + ImGui::BeginGroup(); + { + ImGui::BeginGroup(); + ImGui::Button("AAA"); + ImGui::SameLine(); + ImGui::Button("BBB"); + ImGui::SameLine(); + ImGui::BeginGroup(); + ImGui::Button("CCC"); + ImGui::Button("DDD"); + ImGui::EndGroup(); + if (ImGui::IsItemHovered()) + ImGui::SetTooltip("Group hovered"); + ImGui::SameLine(); + ImGui::Button("EEE"); + ImGui::EndGroup(); + + // Capture the group size and create widgets using the same size + size = ImGui::GetItemRectSize(); + const float values[5] = { 0.5f, 0.20f, 0.80f, 0.60f, 0.25f }; + ImGui::PlotHistogram("##values", values, IM_ARRAYSIZE(values), 0, NULL, 0.0f, 1.0f, size); + } + ImGui::Button("ACTION", ImVec2((size.x - ImGui::GetStyle().ItemSpacing.x)*0.5f,size.y)); + ImGui::SameLine(); + ImGui::Button("REACTION", ImVec2((size.x - ImGui::GetStyle().ItemSpacing.x)*0.5f,size.y)); + ImGui::EndGroup(); + ImGui::SameLine(); + + ImGui::Button("LEVERAGE\nBUZZWORD", size); + ImGui::SameLine(); + + ImGui::ListBoxHeader("List", size); + ImGui::Selectable("Selected", true); + ImGui::Selectable("Not Selected", false); + ImGui::ListBoxFooter(); + + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Text Baseline Alignment")) + { + ImGui::TextWrapped("(This is testing the vertical alignment that occurs on text to keep it at the same baseline as widgets. Lines only composed of text or \"small\" widgets fit in less vertical spaces than lines with normal widgets)"); + + ImGui::Text("One\nTwo\nThree"); ImGui::SameLine(); + ImGui::Text("Hello\nWorld"); ImGui::SameLine(); + ImGui::Text("Banana"); + + ImGui::Text("Banana"); ImGui::SameLine(); + ImGui::Text("Hello\nWorld"); ImGui::SameLine(); + ImGui::Text("One\nTwo\nThree"); + + ImGui::Button("HOP"); ImGui::SameLine(); + ImGui::Text("Banana"); ImGui::SameLine(); + ImGui::Text("Hello\nWorld"); ImGui::SameLine(); + ImGui::Text("Banana"); + + ImGui::Button("HOP"); ImGui::SameLine(); + ImGui::Text("Hello\nWorld"); ImGui::SameLine(); + ImGui::Text("Banana"); + + ImGui::Button("TEST"); ImGui::SameLine(); + ImGui::Text("TEST"); ImGui::SameLine(); + ImGui::SmallButton("TEST"); + + ImGui::AlignFirstTextHeightToWidgets(); // If your line starts with text, call this to align it to upcoming widgets. + ImGui::Text("Text aligned to Widget"); ImGui::SameLine(); + ImGui::Button("Widget"); ImGui::SameLine(); + ImGui::Text("Widget"); ImGui::SameLine(); + ImGui::SmallButton("Widget"); + + ImGui::TreePop(); + } + } + + if (ImGui::CollapsingHeader("Child regions")) + { + ImGui::Text("Without border"); + static int line = 50; + bool goto_line = ImGui::Button("Goto"); + ImGui::SameLine(); + ImGui::PushItemWidth(100); + goto_line |= ImGui::InputInt("##Line", &line, 0, 0, ImGuiInputTextFlags_EnterReturnsTrue); + ImGui::PopItemWidth(); + ImGui::BeginChild("Sub1", ImVec2(ImGui::GetWindowWidth() * 0.5f,300)); + for (int i = 0; i < 100; i++) + { + ImGui::Text("%04d: scrollable region", i); + if (goto_line && line == i) + ImGui::SetScrollPosHere(); + } + if (goto_line && line >= 100) + ImGui::SetScrollPosHere(); + ImGui::EndChild(); + + ImGui::SameLine(); + + ImGui::PushStyleVar(ImGuiStyleVar_ChildWindowRounding, 5.0f); + ImGui::BeginChild("Sub2", ImVec2(0,300), true); + ImGui::Text("With border"); + ImGui::Columns(2); + for (int i = 0; i < 100; i++) + { + if (i == 50) + ImGui::NextColumn(); + char buf[32]; + ImFormatString(buf, IM_ARRAYSIZE(buf), "%08x", i*5731); + ImGui::Button(buf); + } + ImGui::EndChild(); + ImGui::PopStyleVar(); + } + + if (ImGui::CollapsingHeader("Columns")) + { + // Basic columns + ImGui::Text("Basic:"); + ImGui::Columns(4, "mycolumns"); + ImGui::Separator(); + ImGui::Text("ID"); ImGui::NextColumn(); + ImGui::Text("Name"); ImGui::NextColumn(); + ImGui::Text("Path"); ImGui::NextColumn(); + ImGui::Text("Flags"); ImGui::NextColumn(); + ImGui::Separator(); + const char* names[3] = { "Robert", "Stephanie", "C64" }; + const char* paths[3] = { "/path/robert", "/path/stephanie", "/path/computer" }; + for (int i = 0; i < 3; i++) + { + ImGui::Text("%04d", i); ImGui::NextColumn(); + ImGui::Text(names[i]); ImGui::NextColumn(); + ImGui::Text(paths[i]); ImGui::NextColumn(); + ImGui::Text("...."); ImGui::NextColumn(); + } + ImGui::Columns(1); + + ImGui::Separator(); + ImGui::Spacing(); + + // Scrolling columns + /* + ImGui::Text("Scrolling:"); + ImGui::BeginChild("##header", ImVec2(0, ImGui::GetTextLineHeightWithSpacing()+ImGui::GetStyle().ItemSpacing.y)); + ImGui::Columns(3); + ImGui::Text("ID"); ImGui::NextColumn(); + ImGui::Text("Name"); ImGui::NextColumn(); + ImGui::Text("Path"); ImGui::NextColumn(); + ImGui::Columns(1); + ImGui::Separator(); + ImGui::EndChild(); + ImGui::BeginChild("##scrollingregion", ImVec2(0, 60)); + ImGui::Columns(3); + for (int i = 0; i < 10; i++) + { + ImGui::Text("%04d", i); ImGui::NextColumn(); + ImGui::Text("Foobar"); ImGui::NextColumn(); + ImGui::Text("/path/foobar/%04d/", i); ImGui::NextColumn(); + } + ImGui::Columns(1); + ImGui::EndChild(); + + ImGui::Separator(); + ImGui::Spacing(); + */ + + // Create multiple items in a same cell before switching to next column + ImGui::Text("Mixed items:"); + ImGui::Columns(3, "mixed"); + ImGui::Separator(); + + static int e = 0; + ImGui::Text("Hello"); + ImGui::Button("Banana"); + ImGui::RadioButton("radio a", &e, 0); + ImGui::NextColumn(); + + ImGui::Text("ImGui"); + ImGui::Button("Apple"); + ImGui::RadioButton("radio b", &e, 1); + static float foo = 1.0f; + ImGui::InputFloat("red", &foo, 0.05f, 0, 3); + ImGui::Text("An extra line here."); + ImGui::NextColumn(); + + ImGui::Text("World!"); + ImGui::Button("Corniflower"); + ImGui::RadioButton("radio c", &e, 2); + static float bar = 1.0f; + ImGui::InputFloat("blue", &bar, 0.05f, 0, 3); + ImGui::NextColumn(); + + if (ImGui::CollapsingHeader("Category A")) ImGui::Text("Blah blah blah"); ImGui::NextColumn(); + if (ImGui::CollapsingHeader("Category B")) ImGui::Text("Blah blah blah"); ImGui::NextColumn(); + if (ImGui::CollapsingHeader("Category C")) ImGui::Text("Blah blah blah"); ImGui::NextColumn(); + ImGui::Columns(1); + + ImGui::Separator(); + ImGui::Spacing(); + + // Tree items + ImGui::Text("Tree items:"); + ImGui::Columns(2, "tree items"); + ImGui::Separator(); + if (ImGui::TreeNode("Hello")) { ImGui::BulletText("World"); ImGui::TreePop(); } ImGui::NextColumn(); + if (ImGui::TreeNode("Bonjour")) { ImGui::BulletText("Monde"); ImGui::TreePop(); } ImGui::NextColumn(); + ImGui::Columns(1); + + ImGui::Separator(); + ImGui::Spacing(); + + // Word-wrapping + ImGui::Text("Word-wrapping:"); + ImGui::Columns(2, "word-wrapping"); + ImGui::Separator(); + ImGui::TextWrapped("The quick brown fox jumps over the lazy dog."); + ImGui::Text("Hello Left"); + ImGui::NextColumn(); + ImGui::TextWrapped("The quick brown fox jumps over the lazy dog."); + ImGui::Text("Hello Right"); + ImGui::Columns(1); + + ImGui::Separator(); + ImGui::Spacing(); + + if (ImGui::TreeNode("Inside a tree..")) + { + if (ImGui::TreeNode("node 1 (with borders)")) + { + ImGui::Columns(4); + for (int i = 0; i < 8; i++) + { + ImGui::Text("%c%c%c", 'a'+i, 'a'+i, 'a'+i); + ImGui::NextColumn(); + } + ImGui::Columns(1); + ImGui::TreePop(); + } + if (ImGui::TreeNode("node 2 (without borders)")) + { + ImGui::Columns(4, NULL, false); + for (int i = 0; i < 8; i++) + { + ImGui::Text("%c%c%c", 'a'+i, 'a'+i, 'a'+i); + ImGui::NextColumn(); + } + ImGui::Columns(1); + ImGui::TreePop(); + } + ImGui::TreePop(); + } + } + + if (ImGui::CollapsingHeader("Filtering")) + { + static ImGuiTextFilter filter; + ImGui::Text("Filter usage:\n" + " \"\" display all lines\n" + " \"xxx\" display lines containing \"xxx\"\n" + " \"xxx,yyy\" display lines containing \"xxx\" or \"yyy\"\n" + " \"-xxx\" hide lines containing \"xxx\""); + filter.Draw(); + const char* lines[] = { "aaa1.c", "bbb1.c", "ccc1.c", "aaa2.cpp", "bbb2.cpp", "ccc2.cpp", "abc.h", "hello, world" }; + for (size_t i = 0; i < IM_ARRAYSIZE(lines); i++) + if (filter.PassFilter(lines[i])) + ImGui::BulletText("%s", lines[i]); + } + + if (ImGui::CollapsingHeader("Keyboard, Mouse & Focus")) + { + if (ImGui::TreeNode("Tabbing")) + { + ImGui::Text("Use TAB/SHIFT+TAB to cycle thru keyboard editable fields."); + static char buf[32] = "dummy"; + ImGui::InputText("1", buf, IM_ARRAYSIZE(buf)); + ImGui::InputText("2", buf, IM_ARRAYSIZE(buf)); + ImGui::InputText("3", buf, IM_ARRAYSIZE(buf)); + ImGui::PushAllowKeyboardFocus(false); + ImGui::InputText("4 (tab skip)", buf, IM_ARRAYSIZE(buf)); + //ImGui::SameLine(); ImGui::Text("(?)"); if (ImGui::IsHovered()) ImGui::SetTooltip("Use ImGui::PushAllowKeyboardFocus(bool)\nto disable tabbing through certain widgets."); + ImGui::PopAllowKeyboardFocus(); + ImGui::InputText("5", buf, IM_ARRAYSIZE(buf)); + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Focus from code")) + { + bool focus_1 = ImGui::Button("Focus on 1"); ImGui::SameLine(); + bool focus_2 = ImGui::Button("Focus on 2"); ImGui::SameLine(); + bool focus_3 = ImGui::Button("Focus on 3"); + int has_focus = 0; + static char buf[128] = "click on a button to set focus"; + + if (focus_1) ImGui::SetKeyboardFocusHere(); + ImGui::InputText("1", buf, IM_ARRAYSIZE(buf)); + if (ImGui::IsItemActive()) has_focus = 1; + + if (focus_2) ImGui::SetKeyboardFocusHere(); + ImGui::InputText("2", buf, IM_ARRAYSIZE(buf)); + if (ImGui::IsItemActive()) has_focus = 2; + + ImGui::PushAllowKeyboardFocus(false); + if (focus_3) ImGui::SetKeyboardFocusHere(); + ImGui::InputText("3 (tab skip)", buf, IM_ARRAYSIZE(buf)); + if (ImGui::IsItemActive()) has_focus = 3; + ImGui::PopAllowKeyboardFocus(); + if (has_focus) + ImGui::Text("Item with focus: %d", has_focus); + else + ImGui::Text("Item with focus: "); + ImGui::TextWrapped("Cursor & selection are preserved when refocusing last used item in code."); + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Mouse cursors")) + { + ImGui::TextWrapped("(Your application can render a different mouse cursor based on what ImGui::GetMouseCursor() returns. You can also set io.MouseDrawCursor to ask ImGui to render the cursor for you in software)"); + ImGui::Checkbox("io.MouseDrawCursor", &ImGui::GetIO().MouseDrawCursor); + ImGui::Text("Hover to see mouse cursors:"); + for (int i = 0; i < ImGuiMouseCursor_Count_; i++) + { + char label[32]; + sprintf(label, "Mouse cursor %d", i); + ImGui::Bullet(); ImGui::Selectable(label, false); + if (ImGui::IsItemHovered()) + ImGui::SetMouseCursor(i); + } + ImGui::TreePop(); + } + } + + if (ImGui::CollapsingHeader("App Examples")) + { + ImGui::Checkbox("Metrics", &show_app_metrics); + ImGui::Checkbox("Console", &show_app_console); + ImGui::Checkbox("Long text display", &show_app_long_text); + ImGui::Checkbox("Auto-resizing window", &show_app_auto_resize); + ImGui::Checkbox("Simple overlay", &show_app_fixed_overlay); + ImGui::Checkbox("Manipulating window title", &show_app_manipulating_window_title); + ImGui::Checkbox("Custom rendering", &show_app_custom_rendering); + } + + ImGui::End(); +} + +void ImGui::ShowMetricsWindow(bool* opened) +{ + if (ImGui::Begin("ImGui Metrics", opened)) + { + ImGui::Text("ImGui %s", ImGui::GetVersion()); + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + ImGui::Text("%d vertices", ImGui::GetIO().MetricsRenderVertices); + ImGui::Separator(); + + struct Funcs + { + static void NodeDrawList(ImDrawList* draw_list, const char* label) + { + bool node_opened = ImGui::TreeNode(draw_list, "%s: %d vtx, %d cmds", label, draw_list->vtx_buffer.size(), draw_list->commands.size()); + if (draw_list == ImGui::GetWindowDrawList()) + { + ImGui::SameLine(); + ImGui::TextColored(ImColor(255,100,100), "CURRENTLY APPENDING"); // Can't display stats for active draw list! (we don't have the data double-buffered) + } + if (!node_opened) + return; + for (const ImDrawCmd* pcmd = draw_list->commands.begin(); pcmd < draw_list->commands.end(); pcmd++) + if (pcmd->user_callback) + ImGui::BulletText("Callback %p, user_data %p", pcmd->user_callback, pcmd->user_callback_data); + else + ImGui::BulletText("Draw %d vtx, tex = %p", pcmd->vtx_count, pcmd->texture_id); + ImGui::TreePop(); + } + + static void NodeWindows(ImVector& windows, const char* label) + { + if (!ImGui::TreeNode(label, "%s (%d)", label, (int)windows.size())) + return; + for (int i = 0; i < (int)windows.size(); i++) + Funcs::NodeWindow(windows[i], "Window"); + ImGui::TreePop(); + } + + static void NodeWindow(ImGuiWindow* window, const char* label) + { + if (!ImGui::TreeNode(window, "%s '%s', %d @ 0x%p", label, window->Name, window->Visible, window)) + return; + NodeDrawList(window->DrawList, "DrawList"); + if (window->RootWindow != window) NodeWindow(window->RootWindow, "RootWindow"); + if (window->DC.ChildWindows.size() > 0) NodeWindows(window->DC.ChildWindows, "ChildWindows"); + ImGui::TreePop(); + } + }; + + ImGuiState& g = *GImGui; // Access private state + g.DisableHideTextAfterDoubleHash++; // Not exposed (yet). Disable processing that hides text after '##' markers. + Funcs::NodeWindows(g.Windows, "Windows"); + if (ImGui::TreeNode("DrawList", "Active DrawLists (%d)", (int)g.RenderDrawLists[0].size())) + { + for (int i = 0; i < (int)g.RenderDrawLists[0].size(); i++) + Funcs::NodeDrawList(g.RenderDrawLists[0][i], "DrawList"); + ImGui::TreePop(); + } + g.DisableHideTextAfterDoubleHash--; + } + ImGui::End(); +} + +static void ShowExampleAppAutoResize(bool* opened) +{ + if (!ImGui::Begin("Example: Auto-Resizing Window", opened, ImGuiWindowFlags_AlwaysAutoResize)) + { + ImGui::End(); + return; + } + + static int lines = 10; + ImGui::TextWrapped("Window will resize every-frame to the size of its content. Note that you don't want to query the window size to output your content because that would create a feedback loop."); + ImGui::SliderInt("Number of lines", &lines, 1, 20); + for (int i = 0; i < lines; i++) + ImGui::Text("%*sThis is line %d", i*4, "", i); // Pad with space to extend size horizontally + + ImGui::End(); +} + +static void ShowExampleAppFixedOverlay(bool* opened) +{ + ImGui::SetNextWindowPos(ImVec2(10,10)); + if (!ImGui::Begin("Example: Fixed Overlay", opened, ImVec2(0,0), 0.3f, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoSavedSettings)) + { + ImGui::End(); + return; + } + + ImGui::Text("Simple overlay\non the top-left side of the screen."); + ImGui::Separator(); + ImGui::Text("Mouse Position: (%.1f,%.1f)", ImGui::GetIO().MousePos.x, ImGui::GetIO().MousePos.y); + + ImGui::End(); +} + +static void ShowExampleAppManipulatingWindowTitle(bool* opened) +{ + (void)opened; + + // By default, Windows are uniquely identified by their title. + // You can use the "##" and "###" markers to manipulate the display/ID. Read FAQ at the top of this file! + + // Using "##" to display same title but have unique identifier. + ImGui::SetNextWindowPos(ImVec2(100,100), ImGuiSetCond_FirstUseEver); + ImGui::Begin("Same title as another window##1"); + ImGui::Text("This is window 1.\nMy title is the same as window 2, but my identifier is unique."); + ImGui::End(); + + ImGui::SetNextWindowPos(ImVec2(100,200), ImGuiSetCond_FirstUseEver); + ImGui::Begin("Same title as another window##2"); + ImGui::Text("This is window 2.\nMy title is the same as window 1, but my identifier is unique."); + ImGui::End(); + + // Using "###" to display a changing title but keep a static identifier "AnimatedTitle" + char buf[128]; + ImFormatString(buf, IM_ARRAYSIZE(buf), "Animated title %c %d###AnimatedTitle", "|/-\\"[(int)(ImGui::GetTime()/0.25f)&3], rand()); + ImGui::SetNextWindowPos(ImVec2(100,300), ImGuiSetCond_FirstUseEver); + ImGui::Begin(buf); + ImGui::Text("This window has a changing title."); + ImGui::End(); +} + +static void ShowExampleAppCustomRendering(bool* opened) +{ + ImGui::SetNextWindowSize(ImVec2(300,350), ImGuiSetCond_FirstUseEver); + if (!ImGui::Begin("Example: Custom Rendering", opened)) + { + ImGui::End(); + return; + } + + // Tip: If you do a lot of custom rendering, you probably want to use your own geometrical types and benefit of overloaded operators, etc. + // Define IM_VEC2_CLASS_EXTRA in imconfig.h to create implicit conversions between your types and ImVec2/ImVec4. + // ImGui defines overloaded operators but they are internal to imgui.cpp and not exposed outside (to avoid messing with your types) + // In this example we aren't using the operators. + + static ImVector points; + static bool adding_line = false; + if (ImGui::Button("Clear")) points.clear(); + if (points.size() >= 2) { ImGui::SameLine(); if (ImGui::Button("Undo")) { points.pop_back(); points.pop_back(); } } + ImGui::Text("Left-click and drag to add lines"); + ImGui::Text("Right-click to undo"); + + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + + // Here we are using InvisibleButton() as a convenience to 1) advance the cursor and 2) allows us to use IsItemHovered() + // However you can draw directly and poll mouse/keyboard by yourself. You can manipulate the cursor using GetCursorPos() and SetCursorPos(). + // If you only use the ImDrawList API, you can notify the owner window of its extends by using SetCursorPos(max). + ImVec2 canvas_pos = ImGui::GetCursorScreenPos(); // ImDrawList API uses screen coordinates! + ImVec2 canvas_size = ImVec2(ImMax(50.0f,ImGui::GetWindowContentRegionMax().x-ImGui::GetCursorPos().x), ImMax(50.0f,ImGui::GetWindowContentRegionMax().y-ImGui::GetCursorPos().y)); // Resize canvas what's available + draw_list->AddRect(canvas_pos, ImVec2(canvas_pos.x + canvas_size.x, canvas_pos.y + canvas_size.y), 0xFFFFFFFF); + bool adding_preview = false; + ImGui::InvisibleButton("canvas", canvas_size); + if (ImGui::IsItemHovered()) + { + ImVec2 mouse_pos_in_canvas = ImVec2(ImGui::GetIO().MousePos.x - canvas_pos.x, ImGui::GetIO().MousePos.y - canvas_pos.y); + if (!adding_line && ImGui::GetIO().MouseClicked[0]) + { + points.push_back(mouse_pos_in_canvas); + adding_line = true; + } + if (adding_line) + { + adding_preview = true; + points.push_back(mouse_pos_in_canvas); + if (!ImGui::GetIO().MouseDown[0]) + adding_line = adding_preview = false; + } + if (ImGui::GetIO().MouseClicked[1] && !points.empty()) + { + adding_line = false; + points.pop_back(); + points.pop_back(); + } + } + draw_list->PushClipRect(ImVec4(canvas_pos.x, canvas_pos.y, canvas_pos.x+canvas_size.x, canvas_pos.y+canvas_size.y)); // clip lines within the canvas (if we resize it, etc.) + for (int i = 0; i < (int)points.size() - 1; i += 2) + draw_list->AddLine(ImVec2(canvas_pos.x + points[i].x, canvas_pos.y + points[i].y), ImVec2(canvas_pos.x + points[i+1].x, canvas_pos.y + points[i+1].y), 0xFF00FFFF); + draw_list->PopClipRect(); + if (adding_preview) + points.pop_back(); + ImGui::End(); +} + +struct ExampleAppConsole +{ + char InputBuf[256]; + ImVector Items; + bool ScrollToBottom; + ImVector History; + int HistoryPos; // -1: new line, 0..History.size()-1 browsing history. + ImVector Commands; + + ExampleAppConsole() + { + ClearLog(); + HistoryPos = -1; + Commands.push_back("HELP"); + Commands.push_back("HISTORY"); + Commands.push_back("CLEAR"); + Commands.push_back("CLASSIFY"); // "classify" is here to provide an example of "C"+[tab] completing to "CL" and displaying matches. + } + ~ExampleAppConsole() + { + ClearLog(); + for (size_t i = 0; i < Items.size(); i++) + ImGui::MemFree(History[i]); + } + + void ClearLog() + { + for (size_t i = 0; i < Items.size(); i++) + ImGui::MemFree(Items[i]); + Items.clear(); + ScrollToBottom = true; + } + + void AddLog(const char* fmt, ...) + { + char buf[1024]; + va_list args; + va_start(args, fmt); + ImFormatStringV(buf, IM_ARRAYSIZE(buf), fmt, args); + va_end(args); + Items.push_back(ImStrdup(buf)); + ScrollToBottom = true; + } + + void Run(const char* title, bool* opened) + { + ImGui::SetNextWindowSize(ImVec2(520,600), ImGuiSetCond_FirstUseEver); + if (!ImGui::Begin(title, opened)) + { + ImGui::End(); + return; + } + + ImGui::TextWrapped("This example implements a console with basic coloring, completion and history. A more elaborate implementation may want to store entries along with extra data such as timestamp, emitter, etc."); + ImGui::TextWrapped("Enter 'HELP' for help, press TAB to use text completion."); + + // TODO: display from bottom + // TODO: clip manually + + if (ImGui::SmallButton("Add Dummy Text")) { AddLog("%d some text", Items.size()); AddLog("some more text"); AddLog("display very important message here!"); } ImGui::SameLine(); + if (ImGui::SmallButton("Add Dummy Error")) AddLog("[error] something went wrong"); ImGui::SameLine(); + if (ImGui::SmallButton("Clear")) ClearLog(); + //static float t = 0.0f; if (ImGui::GetTime() - t > 0.02f) { t = ImGui::GetTime(); AddLog("Spam %f", t); } + + ImGui::Separator(); + + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0,0)); + static ImGuiTextFilter filter; + filter.Draw("Filter (\"incl,-excl\") (\"error\")", 180); + //if (ImGui::IsItemHovered()) ImGui::SetKeyboardFocusHere(-1); // Auto focus on hover + ImGui::PopStyleVar(); + ImGui::Separator(); + + // Display every line as a separate entry so we can change their color or add custom widgets. If you only want raw text you can use ImGui::TextUnformatted(log.begin(), log.end()); + // NB- if you have thousands of entries this approach may be too inefficient. You can seek and display only the lines that are visible - CalcListClipping() is a helper to compute this information. + // If your items are of variable size you may want to implement code similar to what CalcListClipping() does. Or split your data into fixed height items to allow random-seeking into your list. + ImGui::BeginChild("ScrollingRegion", ImVec2(0,-ImGui::GetTextLineHeightWithSpacing()*2)); + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(4,1)); // Tighten spacing + for (size_t i = 0; i < Items.size(); i++) + { + const char* item = Items[i]; + if (!filter.PassFilter(item)) + continue; + ImVec4 col(1,1,1,1); // A better implement may store a type per-item. For the sample let's just parse the text. + if (strstr(item, "[error]")) col = ImVec4(1.0f,0.4f,0.4f,1.0f); + else if (strncmp(item, "# ", 2) == 0) col = ImVec4(1.0f,0.8f,0.6f,1.0f); + ImGui::PushStyleColor(ImGuiCol_Text, col); + ImGui::TextUnformatted(item); + ImGui::PopStyleColor(); + } + if (ScrollToBottom) + ImGui::SetScrollPosHere(); + ScrollToBottom = false; + ImGui::PopStyleVar(); + ImGui::EndChild(); + ImGui::Separator(); + + // Command-line + if (ImGui::InputText("Input", InputBuf, IM_ARRAYSIZE(InputBuf), ImGuiInputTextFlags_EnterReturnsTrue|ImGuiInputTextFlags_CallbackCompletion|ImGuiInputTextFlags_CallbackHistory, &TextEditCallbackStub, (void*)this)) + { + char* input_end = InputBuf+strlen(InputBuf); + while (input_end > InputBuf && input_end[-1] == ' ') input_end--; *input_end = 0; + if (InputBuf[0]) + ExecCommand(InputBuf); + strcpy(InputBuf, ""); + } + + // Demonstrate keeping auto focus on the input box + if (ImGui::IsItemHovered() || (ImGui::IsRootWindowOrAnyChildFocused() && !ImGui::IsAnyItemActive() && !ImGui::IsMouseClicked(0))) + ImGui::SetKeyboardFocusHere(-1); // Auto focus + + ImGui::End(); + } + + void ExecCommand(const char* command_line) + { + AddLog("# %s\n", command_line); + + // Insert into history. First find match and delete it so it can be pushed to the back. This isn't trying to be smart or optimal. + HistoryPos = -1; + for (int i = (int)History.size()-1; i >= 0; i--) + if (ImStricmp(History[i], command_line) == 0) + { + ImGui::MemFree(History[i]); + History.erase(History.begin() + i); + break; + } + History.push_back(ImStrdup(command_line)); + + // Process command + if (ImStricmp(command_line, "CLEAR") == 0) + { + ClearLog(); + } + else if (ImStricmp(command_line, "HELP") == 0) + { + AddLog("Commands:"); + for (size_t i = 0; i < Commands.size(); i++) + AddLog("- %s", Commands[i]); + } + else if (ImStricmp(command_line, "HISTORY") == 0) + { + for (size_t i = History.size() >= 10 ? History.size() - 10 : 0; i < History.size(); i++) + AddLog("%3d: %s\n", i, History[i]); + } + else + { + AddLog("Unknown command: '%s'\n", command_line); + } + } + + static int TextEditCallbackStub(ImGuiTextEditCallbackData* data) + { + ExampleAppConsole* console = (ExampleAppConsole*)data->UserData; + return console->TextEditCallback(data); + } + + int TextEditCallback(ImGuiTextEditCallbackData* data) + { + //AddLog("cursor: %d, selection: %d-%d", data->CursorPos, data->SelectionStart, data->SelectionEnd); + switch (data->EventFlag) + { + case ImGuiInputTextFlags_CallbackCompletion: + { + // Example of TEXT COMPLETION + + // Locate beginning of current word + const char* word_end = data->Buf + data->CursorPos; + const char* word_start = word_end; + while (word_start > data->Buf) + { + const char c = word_start[-1]; + if (ImCharIsSpace(c) || c == ',' || c == ';') + break; + word_start--; + } + + // Build a list of candidates + ImVector candidates; + for (size_t i = 0; i < Commands.size(); i++) + if (ImStrnicmp(Commands[i], word_start, (int)(word_end-word_start)) == 0) + candidates.push_back(Commands[i]); + + if (candidates.size() == 0) + { + // No match + AddLog("No match for \"%.*s\"!\n", word_end-word_start, word_start); + } + else if (candidates.size() == 1) + { + // Single match. Delete the beginning of the word and replace it entirely so we've got nice casing + data->DeleteChars((int)(word_start-data->Buf), (int)(word_end-word_start)); + data->InsertChars(data->CursorPos, candidates[0]); + data->InsertChars(data->CursorPos, " "); + } + else + { + // Multiple matches. Complete as much as we can, so inputing "C" will complete to "CL" and display "CLEAR" and "CLASSIFY" + int match_len = (int)(word_end - word_start); + for (;;) + { + int c = 0; + bool all_candidates_matches = true; + for (size_t i = 0; i < candidates.size() && all_candidates_matches; i++) + if (i == 0) + c = toupper(candidates[i][match_len]); + else if (c != toupper(candidates[i][match_len])) + all_candidates_matches = false; + if (!all_candidates_matches) + break; + match_len++; + } + + if (match_len > 0) + { + data->DeleteChars((int)(word_start - data->Buf), (int)(word_end-word_start)); + data->InsertChars(data->CursorPos, candidates[0], candidates[0] + match_len); + } + + // List matches + AddLog("Possible matches:\n"); + for (size_t i = 0; i < candidates.size(); i++) + AddLog("- %s\n", candidates[i]); + } + + break; + } + case ImGuiInputTextFlags_CallbackHistory: + { + // Example of HISTORY + const int prev_history_pos = HistoryPos; + if (data->EventKey == ImGuiKey_UpArrow) + { + if (HistoryPos == -1) + HistoryPos = (int)(History.size() - 1); + else if (HistoryPos > 0) + HistoryPos--; + } + else if (data->EventKey == ImGuiKey_DownArrow) + { + if (HistoryPos != -1) + if (++HistoryPos >= (int)History.size()) + HistoryPos = -1; + } + + // A better implementation would preserve the data on the current input line along with cursor position. + if (prev_history_pos != HistoryPos) + { + ImFormatString(data->Buf, data->BufSize, "%s", (HistoryPos >= 0) ? History[HistoryPos] : ""); + data->BufDirty = true; + data->CursorPos = data->SelectionStart = data->SelectionEnd = (int)strlen(data->Buf); + } + } + } + return 0; + } +}; + +static void ShowExampleAppConsole(bool* opened) +{ + static ExampleAppConsole console; + console.Run("Example: Console", opened); +} + +static void ShowExampleAppLongText(bool* opened) +{ + ImGui::SetNextWindowSize(ImVec2(520,600), ImGuiSetCond_FirstUseEver); + if (!ImGui::Begin("Example: Long text display", opened)) + { + ImGui::End(); + return; + } + + static int test_type = 0; + static ImGuiTextBuffer log; + static int lines = 0; + ImGui::Text("Printing unusually long amount of text."); + ImGui::Combo("Test type", &test_type, "Single call to TextUnformatted()\0Multiple calls to Text(), clipped manually\0Multiple calls to Text(), not clipped"); + ImGui::Text("Buffer contents: %d lines, %d bytes", lines, log.size()); + if (ImGui::Button("Clear")) { log.clear(); lines = 0; } + ImGui::SameLine(); + if (ImGui::Button("Add 1000 lines")) + { + for (int i = 0; i < 1000; i++) + log.append("%i The quick brown fox jumps over the lazy dog\n", lines+i); + lines += 1000; + } + ImGui::BeginChild("Log"); + switch (test_type) + { + case 0: + // Single call to TextUnformatted() with a big buffer + ImGui::TextUnformatted(log.begin(), log.end()); + break; + case 1: + // Multiple calls to Text(), manually coarsely clipped - demonstrate how to use the CalcListClipping() helper. + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0,0)); + int display_start, display_end; + ImGui::CalcListClipping(lines, ImGui::GetTextLineHeight(), &display_start, &display_end); + ImGui::SetCursorPosY(ImGui::GetCursorPosY() + (display_start) * ImGui::GetTextLineHeight()); + for (int i = display_start; i < display_end; i++) + ImGui::Text("%i The quick brown fox jumps over the lazy dog\n", i); + ImGui::SetCursorPosY(ImGui::GetCursorPosY() + (lines - display_end) * ImGui::GetTextLineHeight()); + ImGui::PopStyleVar(); + break; + case 2: + // Multiple calls to Text(), not clipped + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0,0)); + for (int i = 0; i < lines; i++) + ImGui::Text("%i The quick brown fox jumps over the lazy dog\n", i); + ImGui::PopStyleVar(); + break; + } + ImGui::EndChild(); + ImGui::End(); +} + +// End of Sample code +#endif + +//----------------------------------------------------------------------------- +// FONT DATA +//----------------------------------------------------------------------------- +// Compressed with stb_compress() then converted to a C array. +// Use the program in extra_fonts/binary_to_compressed_c.cpp to create the array from a TTF file. +// Decompressor from stb.h (public domain) by Sean Barrett https://github.com/nothings/stb/blob/master/stb.h +//----------------------------------------------------------------------------- + +static unsigned int stb_decompress_length(unsigned char *input) +{ + return (input[8] << 24) + (input[9] << 16) + (input[10] << 8) + input[11]; +} + +static unsigned char *stb__barrier, *stb__barrier2, *stb__barrier3, *stb__barrier4; +static unsigned char *stb__dout; +static void stb__match(unsigned char *data, unsigned int length) +{ + // INVERSE of memmove... write each byte before copying the next... + IM_ASSERT (stb__dout + length <= stb__barrier); + if (stb__dout + length > stb__barrier) { stb__dout += length; return; } + if (data < stb__barrier4) { stb__dout = stb__barrier+1; return; } + while (length--) *stb__dout++ = *data++; +} + +static void stb__lit(unsigned char *data, unsigned int length) +{ + IM_ASSERT (stb__dout + length <= stb__barrier); + if (stb__dout + length > stb__barrier) { stb__dout += length; return; } + if (data < stb__barrier2) { stb__dout = stb__barrier+1; return; } + memcpy(stb__dout, data, length); + stb__dout += length; +} + +#define stb__in2(x) ((i[x] << 8) + i[(x)+1]) +#define stb__in3(x) ((i[x] << 16) + stb__in2((x)+1)) +#define stb__in4(x) ((i[x] << 24) + stb__in3((x)+1)) + +static unsigned char *stb_decompress_token(unsigned char *i) +{ + if (*i >= 0x20) { // use fewer if's for cases that expand small + if (*i >= 0x80) stb__match(stb__dout-i[1]-1, i[0] - 0x80 + 1), i += 2; + else if (*i >= 0x40) stb__match(stb__dout-(stb__in2(0) - 0x4000 + 1), i[2]+1), i += 3; + else /* *i >= 0x20 */ stb__lit(i+1, i[0] - 0x20 + 1), i += 1 + (i[0] - 0x20 + 1); + } else { // more ifs for cases that expand large, since overhead is amortized + if (*i >= 0x18) stb__match(stb__dout-(stb__in3(0) - 0x180000 + 1), i[3]+1), i += 4; + else if (*i >= 0x10) stb__match(stb__dout-(stb__in3(0) - 0x100000 + 1), stb__in2(3)+1), i += 5; + else if (*i >= 0x08) stb__lit(i+2, stb__in2(0) - 0x0800 + 1), i += 2 + (stb__in2(0) - 0x0800 + 1); + else if (*i == 0x07) stb__lit(i+3, stb__in2(1) + 1), i += 3 + (stb__in2(1) + 1); + else if (*i == 0x06) stb__match(stb__dout-(stb__in3(1)+1), i[4]+1), i += 5; + else if (*i == 0x04) stb__match(stb__dout-(stb__in3(1)+1), stb__in2(4)+1), i += 6; + } + return i; +} + +static unsigned int stb_adler32(unsigned int adler32, unsigned char *buffer, unsigned int buflen) +{ + const unsigned long ADLER_MOD = 65521; + unsigned long s1 = adler32 & 0xffff, s2 = adler32 >> 16; + unsigned long blocklen, i; + + blocklen = buflen % 5552; + while (buflen) { + for (i=0; i + 7 < blocklen; i += 8) { + s1 += buffer[0], s2 += s1; + s1 += buffer[1], s2 += s1; + s1 += buffer[2], s2 += s1; + s1 += buffer[3], s2 += s1; + s1 += buffer[4], s2 += s1; + s1 += buffer[5], s2 += s1; + s1 += buffer[6], s2 += s1; + s1 += buffer[7], s2 += s1; + + buffer += 8; + } + + for (; i < blocklen; ++i) + s1 += *buffer++, s2 += s1; + + s1 %= ADLER_MOD, s2 %= ADLER_MOD; + buflen -= blocklen; + blocklen = 5552; + } + return (unsigned int)(s2 << 16) + (unsigned int)s1; +} + +static unsigned int stb_decompress(unsigned char *output, unsigned char *i, unsigned int length) +{ + unsigned int olen; + if (stb__in4(0) != 0x57bC0000) return 0; + if (stb__in4(4) != 0) return 0; // error! stream is > 4GB + olen = stb_decompress_length(i); + stb__barrier2 = i; + stb__barrier3 = i+length; + stb__barrier = output + olen; + stb__barrier4 = output; + i += 16; + + stb__dout = output; + for (;;) { + unsigned char *old_i = i; + i = stb_decompress_token(i); + if (i == old_i) { + if (*i == 0x05 && i[1] == 0xfa) { + IM_ASSERT(stb__dout == output + olen); + if (stb__dout != output + olen) return 0; + if (stb_adler32(1, output, olen) != (unsigned int) stb__in4(2)) + return 0; + return olen; + } else { + IM_ASSERT(0); /* NOTREACHED */ + return 0; + } + } + IM_ASSERT(stb__dout <= output + olen); + if (stb__dout > output + olen) + return 0; + } +} + +//----------------------------------------------------------------------------- +// ProggyClean.ttf +// Copyright (c) 2004, 2005 Tristan Grimmer +// MIT license (see License.txt in http://www.upperbounds.net/download/ProggyClean.ttf.zip) +// Download and more information at http://upperbounds.net +//----------------------------------------------------------------------------- +static const unsigned int proggy_clean_ttf_compressed_size = 9583; +static const unsigned int proggy_clean_ttf_compressed_data[9584/4] = +{ + 0x0000bc57, 0x00000000, 0xf8a00000, 0x00000400, 0x00010037, 0x000c0000, 0x00030080, 0x2f534f40, 0x74eb8832, 0x01000090, 0x2c158248, 0x616d634e, + 0x23120270, 0x03000075, 0x241382a0, 0x74766352, 0x82178220, 0xfc042102, 0x02380482, 0x66796c67, 0x5689af12, 0x04070000, 0x80920000, 0x64616568, + 0xd36691d7, 0xcc201b82, 0x36210382, 0x27108268, 0xc3014208, 0x04010000, 0x243b0f82, 0x78746d68, 0x807e008a, 0x98010000, 0x06020000, 0x61636f6c, + 0xd8b0738c, 0x82050000, 0x0402291e, 0x7078616d, 0xda00ae01, 0x28201f82, 0x202c1082, 0x656d616e, 0x96bb5925, 0x84990000, 0x9e2c1382, 0x74736f70, + 0xef83aca6, 0x249b0000, 0xd22c3382, 0x70657270, 0x12010269, 0xf4040000, 0x08202f82, 0x012ecb84, 0x553c0000, 0x0f5fd5e9, 0x0300f53c, 0x00830008, + 0x7767b722, 0x002b3f82, 0xa692bd00, 0xfe0000d7, 0x83800380, 0x21f1826f, 0x00850002, 0x41820120, 0x40fec026, 0x80030000, 0x05821083, 0x07830120, + 0x0221038a, 0x24118200, 0x90000101, 0x82798200, 0x00022617, 0x00400008, 0x2009820a, 0x82098276, 0x82002006, 0x9001213b, 0x0223c883, 0x828a02bc, + 0x858f2010, 0xc5012507, 0x00023200, 0x04210083, 0x91058309, 0x6c412b03, 0x40007374, 0xac200000, 0x00830008, 0x01000523, 0x834d8380, 0x80032103, + 0x012101bf, 0x23b88280, 0x00800000, 0x0b830382, 0x07820120, 0x83800021, 0x88012001, 0x84002009, 0x2005870f, 0x870d8301, 0x2023901b, 0x83199501, + 0x82002015, 0x84802000, 0x84238267, 0x88002027, 0x8561882d, 0x21058211, 0x13880000, 0x01800022, 0x05850d85, 0x0f828020, 0x03208384, 0x03200582, + 0x47901b84, 0x1b850020, 0x1f821d82, 0x3f831d88, 0x3f410383, 0x84058405, 0x210982cd, 0x09830000, 0x03207789, 0xf38a1384, 0x01203782, 0x13872384, + 0x0b88c983, 0x0d898f84, 0x00202982, 0x23900383, 0x87008021, 0x83df8301, 0x86118d03, 0x863f880d, 0x8f35880f, 0x2160820f, 0x04830300, 0x1c220382, + 0x05820100, 0x4c000022, 0x09831182, 0x04001c24, 0x11823000, 0x0800082e, 0x00000200, 0xff007f00, 0xffffac20, 0x00220982, 0x09848100, 0xdf216682, + 0x843586d5, 0x06012116, 0x04400684, 0xa58120d7, 0x00b127d8, 0x01b88d01, 0x2d8685ff, 0xc100c621, 0xf4be0801, 0x9e011c01, 0x88021402, 0x1403fc02, + 0x9c035803, 0x1404de03, 0x50043204, 0xa2046204, 0x66051605, 0x1206bc05, 0xd6067406, 0x7e073807, 0x4e08ec07, 0x96086c08, 0x1009d008, 0x88094a09, + 0x800a160a, 0x560b040b, 0x2e0cc80b, 0xea0c820c, 0xa40d5e0d, 0x500eea0d, 0x280f960e, 0x1210b00f, 0xe0107410, 0xb6115211, 0x6e120412, 0x4c13c412, + 0xf613ac13, 0xae145814, 0x4015ea14, 0xa6158015, 0x1216b815, 0xc6167e16, 0x8e173417, 0x5618e017, 0xee18ba18, 0x96193619, 0x481ad419, 0xf01a9c1a, + 0xc81b5c1b, 0x4c1c041c, 0xea1c961c, 0x921d2a1d, 0x401ed21d, 0xe01e8e1e, 0x761f241f, 0xa61fa61f, 0x01821020, 0x8a202e34, 0xc820b220, 0x74211421, + 0xee219821, 0x86226222, 0x01820c23, 0x83238021, 0x23983c01, 0x24d823b0, 0x244a2400, 0x24902468, 0x250625ae, 0x25822560, 0x26f825f8, 0x82aa2658, + 0xd8be0801, 0x9a274027, 0x68280a28, 0x0e29a828, 0xb8292029, 0x362af829, 0x602a602a, 0x2a2b022b, 0xac2b5e2b, 0x202ce62b, 0x9a2c342c, 0x5c2d282d, + 0xaa2d782d, 0x262ee82d, 0x262fa62e, 0xf42fb62f, 0xc8305e30, 0xb4313e31, 0x9e321e32, 0x82331e33, 0x5c34ee33, 0x3a35ce34, 0xd4358635, 0x72362636, + 0x7637e636, 0x3a38d837, 0x1239a638, 0xae397439, 0x9a3a2e3a, 0x7c3b063b, 0x3a3ce83b, 0x223d963c, 0xec3d863d, 0xc63e563e, 0x9a3f2a3f, 0x6a401240, + 0x3641d040, 0x0842a241, 0x7a424042, 0xf042b842, 0xcc436243, 0x8a442a44, 0x5845ee44, 0xe245b645, 0xb4465446, 0x7a471447, 0x5448da47, 0x4049c648, + 0x15462400, 0x034d0808, 0x0b000700, 0x13000f00, 0x1b001700, 0x23001f00, 0x2b002700, 0x33002f00, 0x3b003700, 0x43003f00, 0x4b004700, 0x53004f00, + 0x5b005700, 0x63005f00, 0x6b006700, 0x73006f00, 0x7b007700, 0x83007f00, 0x8b008700, 0x00008f00, 0x15333511, 0x20039631, 0x20178205, 0xd3038221, + 0x20739707, 0x25008580, 0x028080fc, 0x05be8080, 0x04204a85, 0x05ce0685, 0x0107002a, 0x02000080, 0x00000400, 0x250d8b41, 0x33350100, 0x03920715, + 0x13820320, 0x858d0120, 0x0e8d0320, 0xff260d83, 0x00808000, 0x54820106, 0x04800223, 0x845b8c80, 0x41332059, 0x078b068f, 0x82000121, 0x82fe2039, + 0x84802003, 0x83042004, 0x23598a0e, 0x00180000, 0x03210082, 0x42ab9080, 0x73942137, 0x2013bb41, 0x8f978205, 0x2027a39b, 0x20b68801, 0x84b286fd, + 0x91c88407, 0x41032011, 0x11a51130, 0x15000027, 0x80ff8000, 0x11af4103, 0x841b0341, 0x8bd983fd, 0x9be99bc9, 0x8343831b, 0x21f1821f, 0xb58300ff, + 0x0f84e889, 0xf78a0484, 0x8000ff22, 0x0020eeb3, 0x14200082, 0x2130ef41, 0xeb431300, 0x4133200a, 0xd7410ecb, 0x9a07200b, 0x2027871b, 0x21238221, + 0xe7828080, 0xe784fd20, 0xe8848020, 0xfe808022, 0x08880d85, 0xba41fd20, 0x82248205, 0x85eab02a, 0x008022e7, 0x2cd74200, 0x44010021, 0xd34406eb, + 0x44312013, 0xcf8b0eef, 0x0d422f8b, 0x82332007, 0x0001212f, 0x8023cf82, 0x83000180, 0x820583de, 0x830682d4, 0x820020d4, 0x82dc850a, 0x20e282e9, + 0xb2ff85fe, 0x010327e9, 0x02000380, 0x0f440400, 0x0c634407, 0x68825982, 0x85048021, 0x260a825d, 0x010b0000, 0x4400ff00, 0x2746103f, 0x08d74209, + 0x4d440720, 0x0eaf4406, 0xc3441d20, 0x23078406, 0xff800002, 0x04845b83, 0x8d05b241, 0x1781436f, 0x6b8c87a5, 0x1521878e, 0x06474505, 0x01210783, + 0x84688c00, 0x8904828e, 0x441e8cf7, 0x0b270cff, 0x80008000, 0x45030003, 0xfb430fab, 0x080f4107, 0x410bf942, 0xd34307e5, 0x070d4207, 0x80800123, + 0x205d85fe, 0x849183fe, 0x20128404, 0x82809702, 0x00002217, 0x41839a09, 0x6b4408cf, 0x0733440f, 0x3b460720, 0x82798707, 0x97802052, 0x0000296f, + 0xff800004, 0x01800100, 0x0021ef89, 0x0a914625, 0x410a4d41, 0x00250ed4, 0x00050000, 0x056d4280, 0x210a7b46, 0x21481300, 0x46ed8512, 0x00210bd1, + 0x89718202, 0x21738877, 0x2b850001, 0x00220582, 0x87450a00, 0x0ddb4606, 0x41079b42, 0x9d420c09, 0x0b09420b, 0x8d820720, 0x9742fc84, 0x42098909, + 0x00241e0f, 0x00800014, 0x0b47da82, 0x0833442a, 0x49078d41, 0x2f450f13, 0x42278f17, 0x01200751, 0x22063742, 0x44808001, 0x20450519, 0x88068906, + 0x83fe2019, 0x4203202a, 0x1a941a58, 0x00820020, 0xe7a40e20, 0x420ce146, 0x854307e9, 0x0fcb4713, 0xff20a182, 0xfe209b82, 0x0c867f8b, 0x0021aea4, + 0x219fa40f, 0x7d41003b, 0x07194214, 0xbf440520, 0x071d4206, 0x6941a590, 0x80802309, 0x028900ff, 0xa9a4b685, 0xc5808021, 0x449b82ab, 0x152007eb, + 0x42134d46, 0x61440a15, 0x051e4208, 0x222b0442, 0x47001100, 0xfd412913, 0x17194714, 0x410f5b41, 0x02220773, 0x09428080, 0x21a98208, 0xd4420001, + 0x481c840d, 0x00232bc9, 0x42120000, 0xe74c261b, 0x149d4405, 0x07209d87, 0x410db944, 0x14421c81, 0x42fd2005, 0x80410bd2, 0x203d8531, 0x06874100, + 0x48256f4a, 0xcb420c95, 0x13934113, 0x44075d44, 0x044c0855, 0x00ff2105, 0xfe228185, 0x45448000, 0x22c5b508, 0x410c0000, 0x7b412087, 0x1bb74514, + 0x32429c85, 0x0a574805, 0x21208943, 0x8ba01300, 0x440dfb4e, 0x77431437, 0x245b4113, 0x200fb145, 0x41108ffe, 0x80203562, 0x00200082, 0x46362b42, + 0x1742178d, 0x4527830f, 0x0f830b2f, 0x4a138146, 0x802409a1, 0xfe8000ff, 0x94419982, 0x09294320, 0x04000022, 0x49050f4f, 0xcb470a63, 0x48032008, + 0x2b48067b, 0x85022008, 0x82638338, 0x00002209, 0x05af4806, 0x900e9f49, 0x84c5873f, 0x214285bd, 0x064900ff, 0x0c894607, 0x00000023, 0x4903820a, + 0x714319f3, 0x0749410c, 0x8a07a145, 0x02152507, 0xfe808000, 0x74490386, 0x8080211b, 0x0c276f82, 0x00018000, 0x48028003, 0x2b2315db, 0x43002f00, + 0x6f82142f, 0x44011521, 0x93510da7, 0x20e68508, 0x06494d80, 0x8e838020, 0x06821286, 0x124bff20, 0x25f3830c, 0x03800080, 0xe74a0380, 0x207b8715, + 0x876b861d, 0x4a152007, 0x07870775, 0xf6876086, 0x8417674a, 0x0a0021f2, 0x431c9743, 0x8d421485, 0x200b830b, 0x06474d03, 0x71828020, 0x04510120, + 0x42da8606, 0x1f831882, 0x001a0022, 0xff4d0082, 0x0b0f532c, 0x0d449b94, 0x4e312007, 0x074f12e7, 0x0bf3490b, 0xbb412120, 0x413f820a, 0xef490857, + 0x80002313, 0xe2830001, 0x6441fc20, 0x8b802006, 0x00012108, 0xfd201582, 0x492c9b48, 0x802014ff, 0x51084347, 0x0f4327f3, 0x17bf4a14, 0x201b7944, + 0x06964201, 0x134ffe20, 0x20d6830b, 0x25d78280, 0xfd800002, 0x05888000, 0x9318dc41, 0x21d282d4, 0xdb481800, 0x0dff542a, 0x45107743, 0xe14813f5, + 0x0f034113, 0x83135d45, 0x47b28437, 0xe4510e73, 0x21f58e06, 0x2b8400fd, 0x1041fcac, 0x08db4b0b, 0x421fdb41, 0xdf4b18df, 0x011d210a, 0x420af350, + 0x6e8308af, 0xac85cb86, 0x1e461082, 0x82b7a407, 0x411420a3, 0xa34130ab, 0x178f4124, 0x41139741, 0x86410d93, 0x82118511, 0x057243d8, 0x8941d9a4, + 0x3093480c, 0x4a13474f, 0xfb5016a9, 0x07ad4108, 0x4a0f9d42, 0xfe200fad, 0x4708aa41, 0x83482dba, 0x288f4d06, 0xb398c3bb, 0x44267b41, 0xb34439d7, + 0x0755410f, 0x200ebb45, 0x0f5f4215, 0x20191343, 0x06df5301, 0xf04c0220, 0x2ba64d07, 0x82050841, 0x430020ce, 0xa78f3627, 0x5213ff42, 0x2f970bc1, + 0x4305ab55, 0xa084111b, 0x450bac45, 0x5f4238b8, 0x010c2106, 0x0220ed82, 0x441bb344, 0x875010af, 0x0737480f, 0x490c5747, 0x0c840c03, 0x4c204b42, + 0x8ba905d7, 0x8b948793, 0x510c0c51, 0xfb4b24b9, 0x1b174107, 0x5709d74c, 0xd1410ca5, 0x079d480f, 0x201ff541, 0x06804780, 0x7d520120, 0x80002205, + 0x20a983fe, 0x47bb83fe, 0x1b8409b4, 0x81580220, 0x4e00202c, 0x4f41282f, 0x0eab4f17, 0x57471520, 0x0e0f4808, 0x8221e041, 0x3e1b4a8b, 0x4407175d, + 0x1b4b071f, 0x4a0f8b07, 0x174a0703, 0x0ba5411b, 0x430fb141, 0x0120057b, 0xfc20dd82, 0x4a056047, 0xf4850c0c, 0x01221982, 0x02828000, 0x1a5d088b, + 0x20094108, 0x8c0e3941, 0x4900200e, 0x7744434f, 0x200b870b, 0x0e4b5a33, 0x2b41f78b, 0x8b138307, 0x0b9f450b, 0x2406f741, 0xfd808001, 0x09475a00, + 0x84000121, 0x5980200e, 0x85450e5d, 0x832c8206, 0x4106831e, 0x00213814, 0x28b34810, 0x410c2f4b, 0x5f4a13d7, 0x0b2b4113, 0x6e43a883, 0x11174b05, + 0x4b066a45, 0xcc470541, 0x5000202b, 0xcb472f4b, 0x44b59f0f, 0xc5430b5b, 0x0d654907, 0x21065544, 0xd6828080, 0xfe201982, 0x8230ec4a, 0x120025c2, + 0x80ff8000, 0x4128d74d, 0x3320408b, 0x410a9f50, 0xdb822793, 0x822bd454, 0x61134b2e, 0x410b214a, 0xad4117c9, 0x0001211f, 0x4206854f, 0x4b430596, + 0x06bb5530, 0x2025cf46, 0x0ddd5747, 0x500ea349, 0x0f840fa7, 0x5213c153, 0x634e08d1, 0x0bbe4809, 0x59316e4d, 0x5b50053f, 0x203f6323, 0x5117eb46, + 0x94450a63, 0x246e410a, 0x63410020, 0x0bdb5f2f, 0x4233ab44, 0x39480757, 0x112d4a07, 0x7241118f, 0x000e2132, 0x9f286f41, 0x0f8762c3, 0x33350723, + 0x094e6415, 0x2010925f, 0x067252fe, 0xd0438020, 0x63a68225, 0x11203a4f, 0x480e6360, 0x5748131f, 0x079b521f, 0x200e2f43, 0x864b8315, 0x113348e7, + 0x85084e48, 0x06855008, 0x5880fd21, 0x7c420925, 0x0c414824, 0x37470c86, 0x1b8b422b, 0x5b0a8755, 0x23410c21, 0x0b83420b, 0x5a082047, 0xf482067f, + 0xa80b4c47, 0x0c0021cf, 0x20207b42, 0x0fb74100, 0x420b8744, 0xeb43076f, 0x0f6f420b, 0x4261fe20, 0x439aa00c, 0x215034e3, 0x0ff9570f, 0x4b1f2d5d, + 0x2d5d0c6f, 0x09634d0b, 0x1f51b8a0, 0x620f200c, 0xaf681e87, 0x24f94d07, 0x4e0f4945, 0xfe200c05, 0x22139742, 0x57048080, 0x23950c20, 0x97601585, + 0x4813201f, 0xad620523, 0x200f8f0f, 0x9e638f15, 0x00002181, 0x41342341, 0x0f930f0b, 0x210b4b62, 0x978f0001, 0xfe200f84, 0x8425c863, 0x2704822b, + 0x80000a00, 0x00038001, 0x610e9768, 0x834514bb, 0x0bc3430f, 0x2107e357, 0x80848080, 0x4400fe21, 0x2e410983, 0x00002a1a, 0x00000700, 0x800380ff, + 0x0fdf5800, 0x59150021, 0xd142163d, 0x0c02410c, 0x01020025, 0x65800300, 0x00240853, 0x1d333501, 0x15220382, 0x35420001, 0x44002008, 0x376406d7, + 0x096f6b19, 0x480bc142, 0x8f4908a7, 0x211f8b1f, 0x9e830001, 0x0584fe20, 0x4180fd21, 0x11850910, 0x8d198259, 0x000021d4, 0x5a08275d, 0x275d1983, + 0x06d9420e, 0x9f08b36a, 0x0f7d47b5, 0x8d8a2f8b, 0x4c0e0b57, 0xe7410e17, 0x42d18c1a, 0xb351087a, 0x1ac36505, 0x4b4a2f20, 0x0b9f450d, 0x430beb53, + 0xa7881015, 0xa5826a83, 0x80200f82, 0x86185a65, 0x4100208e, 0x176c3367, 0x0fe7650b, 0x4a17ad4b, 0x0f4217ed, 0x112e4206, 0x41113a42, 0xf7423169, + 0x0cb34737, 0x560f8b46, 0xa75407e5, 0x5f01200f, 0x31590c48, 0x80802106, 0x42268841, 0x0020091e, 0x4207ef64, 0x69461df7, 0x138d4114, 0x820f5145, + 0x53802090, 0xff200529, 0xb944b183, 0x417e8505, 0x00202561, 0x15210082, 0x42378200, 0x9b431cc3, 0x004f220d, 0x0dd54253, 0x4213f149, 0x7d41133b, + 0x42c9870b, 0x802010f9, 0x420b2c42, 0x8f441138, 0x267c4408, 0x600cb743, 0x8f4109d3, 0x05ab701d, 0x83440020, 0x3521223f, 0x0b794733, 0xfb62fe20, + 0x4afd2010, 0xaf410ae7, 0x25ce8525, 0x01080000, 0x7b6b0000, 0x0973710b, 0x82010021, 0x49038375, 0x33420767, 0x052c4212, 0x58464b85, 0x41fe2005, + 0x50440c27, 0x000c2209, 0x1cb36b80, 0x9b06df44, 0x0f93566f, 0x52830220, 0xfe216e8d, 0x200f8200, 0x0fb86704, 0xb057238d, 0x050b5305, 0x7217eb47, + 0xbd410b6b, 0x0f214610, 0x871f9956, 0x1e91567e, 0x2029b741, 0x20008200, 0x18b7410a, 0x27002322, 0x41095543, 0x0f8f0fb3, 0x41000121, 0x889d111c, + 0x14207b82, 0x00200382, 0x73188761, 0x475013a7, 0x6e33200c, 0x234e0ea3, 0x9b138313, 0x08e54d17, 0x9711094e, 0x2ee74311, 0x4908875e, 0xd75d1f1f, + 0x19ab5238, 0xa2084d48, 0x63a7a9b3, 0x55450b83, 0x0fd74213, 0x440d814c, 0x4f481673, 0x05714323, 0x13000022, 0x412e1f46, 0xdf493459, 0x21c7550f, + 0x8408215f, 0x201d49cb, 0xb1103043, 0x0f0d65d7, 0x452b8d41, 0x594b0f8d, 0x0b004605, 0xb215eb46, 0x000a24d7, 0x47000080, 0x002118cf, 0x06436413, + 0x420bd750, 0x2b500743, 0x076a470c, 0x4105c050, 0xd942053f, 0x0d00211a, 0x5f44779c, 0x0ce94805, 0x51558186, 0x14a54c0b, 0x49082b41, 0x0a4b0888, + 0x8080261f, 0x0d000000, 0x20048201, 0x1deb6a03, 0x420cb372, 0x07201783, 0x4306854d, 0x8b830c59, 0x59093c74, 0x0020250f, 0x67070f4a, 0x2341160b, + 0x00372105, 0x431c515d, 0x554e17ef, 0x0e5d6b05, 0x41115442, 0xb74a1ac1, 0x2243420a, 0x5b4f878f, 0x7507200f, 0x384b086f, 0x09d45409, 0x0020869a, + 0x12200082, 0xab460382, 0x10075329, 0x54138346, 0xaf540fbf, 0x1ea75413, 0x9a0c9e54, 0x0f6b44c1, 0x41000021, 0x47412a4f, 0x07374907, 0x5310bf76, + 0xff2009b4, 0x9a09a64c, 0x8200208d, 0x34c34500, 0x970fe141, 0x1fd74b0f, 0x440a3850, 0x206411f0, 0x27934609, 0x470c5d41, 0x555c2947, 0x1787540f, + 0x6e0f234e, 0x7d540a1b, 0x1d736b08, 0x0026a088, 0x80000e00, 0x9b5200ff, 0x08ef4318, 0x450bff77, 0x1d4d0b83, 0x081f7006, 0xcb691b86, 0x4b022008, + 0xc34b0b33, 0x1d0d4a0c, 0x8025a188, 0x0b000000, 0x52a38201, 0xbf7d0873, 0x0c234511, 0x8f0f894a, 0x4101200f, 0x0c880c9d, 0x2b418ea1, 0x06c74128, + 0x66181341, 0x7b4c0bb9, 0x0c06630b, 0xfe200c87, 0x9ba10882, 0x27091765, 0x01000008, 0x02800380, 0x48113f4e, 0x29430cf5, 0x09a75a0b, 0x31618020, + 0x6d802009, 0x61840e33, 0x8208bf51, 0x0c637d61, 0x7f092379, 0x4f470f4b, 0x1797510c, 0x46076157, 0xf5500fdf, 0x0f616910, 0x1171fe20, 0x82802006, + 0x08696908, 0x41127a4c, 0x3f4a15f3, 0x01042607, 0x0200ff00, 0x1cf77700, 0xff204185, 0x00235b8d, 0x43100000, 0x3b22243f, 0x3b4d3f00, 0x0b937709, + 0xad42f18f, 0x0b1f420f, 0x51084b43, 0x8020104a, 0xb557ff83, 0x052b7f2a, 0x0280ff22, 0x250beb78, 0x00170013, 0xbf6d2500, 0x07db760e, 0x410e2b7f, + 0x00230e4f, 0x49030000, 0x0582055b, 0x07000326, 0x00000b00, 0x580bcd46, 0x00200cdd, 0x57078749, 0x8749160f, 0x0f994f0a, 0x41134761, 0x01200b31, + 0xeb796883, 0x0b41500b, 0x0e90b38e, 0x202e7b51, 0x05d95801, 0x41080570, 0x1d530fc9, 0x0b937a0f, 0xaf8eb387, 0xf743b98f, 0x07c74227, 0x80000523, + 0x0fcb4503, 0x430ca37b, 0x7782077f, 0x8d0a9947, 0x08af4666, 0xeb798020, 0x6459881e, 0xc3740bbf, 0x0feb6f0b, 0x20072748, 0x052b6102, 0x435e0584, + 0x7d088308, 0x03200afd, 0x92109e41, 0x28aa8210, 0x80001500, 0x80030000, 0x0fdb5805, 0x209f4018, 0xa7418d87, 0x0aa3440f, 0x20314961, 0x073a52ff, + 0x6108505d, 0x43181051, 0x00223457, 0xe7820500, 0x50028021, 0x81410d33, 0x063d7108, 0xdb41af84, 0x4d888205, 0x00201198, 0x463d835f, 0x152106d7, + 0x0a355a33, 0x6917614e, 0x75411f4d, 0x184b8b07, 0x1809c344, 0x21091640, 0x0b828000, 0x42808021, 0x26790519, 0x86058605, 0x2428422d, 0x22123b42, + 0x42000080, 0xf587513b, 0x7813677b, 0xaf4d139f, 0x00ff210c, 0x5e0a1d57, 0x3b421546, 0x01032736, 0x02000380, 0x41180480, 0x2f420f07, 0x0c624807, + 0x00000025, 0x18000103, 0x83153741, 0x430120c3, 0x042106b2, 0x088d4d00, 0x2f830620, 0x1810434a, 0x18140345, 0x8507fb41, 0x5ee582ea, 0x0023116c, + 0x8d000600, 0x053b56af, 0xa6554fa2, 0x0d704608, 0x40180d20, 0x47181a43, 0xd37b07ff, 0x0b79500c, 0x420fd745, 0x47450bd9, 0x8471830a, 0x095a777e, + 0x84137542, 0x82002013, 0x2f401800, 0x0007213b, 0x4405e349, 0x0d550ff3, 0x16254c0c, 0x820ffe4a, 0x0400218a, 0x89066f41, 0x106b414f, 0xc84d0120, + 0x80802206, 0x0c9a4b03, 0x00100025, 0x68000200, 0x9d8c2473, 0x44134344, 0xf36a0f33, 0x4678860f, 0x1b440a25, 0x41988c0a, 0x80201879, 0x43079b5e, + 0x4a18080b, 0x0341190b, 0x1259530c, 0x43251552, 0x908205c8, 0x0cac4018, 0x86000421, 0x0e504aa2, 0x0020b891, 0xfb450082, 0x51132014, 0x8f5205f3, + 0x35052108, 0x8505cb59, 0x0f6d4f70, 0x82150021, 0x29af5047, 0x4f004b24, 0x75795300, 0x1b595709, 0x460b6742, 0xbf4b0f0d, 0x5743870b, 0xcb6d1461, + 0x08f64505, 0x4e05ab6c, 0x334126c3, 0x0bcb6b0d, 0x1811034d, 0x4111ef4b, 0x814f1ce5, 0x20af8227, 0x07fd7b80, 0x41188e84, 0xef410f33, 0x80802429, + 0x410d0000, 0xa34205ab, 0x76b7881c, 0xff500b89, 0x0741430f, 0x20086f4a, 0x209d8200, 0x234c18fd, 0x05d4670a, 0x4509af51, 0x9642078d, 0x189e831d, + 0x7c1cc74b, 0xcd4c07b9, 0x0e7c440f, 0x8b7b0320, 0x21108210, 0xc76c8080, 0x03002106, 0x6b23bf41, 0xc549060b, 0x7946180b, 0x0ff7530f, 0x17ad4618, + 0x200ecd45, 0x208c83fd, 0x5e0488fe, 0x032009c6, 0x420d044e, 0x0d8f0d7f, 0x00820020, 0x18001021, 0x6d273b45, 0xfd4c0c93, 0xcf451813, 0x0fe5450f, + 0x5a47c382, 0x820a8b0a, 0x282b4998, 0x410a8b5b, 0x4b232583, 0x54004f00, 0x978f0ce3, 0x500f1944, 0xa95f1709, 0x0280220b, 0x05ba7080, 0xa1530682, + 0x06324c13, 0x91412582, 0x05536e2c, 0x63431020, 0x0f434706, 0x8c11374c, 0x176143d7, 0x4d0f454c, 0xd3680bed, 0x0bee4d17, 0x212b9a41, 0x0f530a00, + 0x140d531c, 0x43139143, 0x95610e8d, 0x0f094415, 0x4205fb56, 0x1b4205cf, 0x17015225, 0x5e0c477f, 0xaf6e0aeb, 0x0ff36218, 0x04849a84, 0x0a454218, + 0x9c430420, 0x23c6822b, 0x04000102, 0x45091b4b, 0xf05f0955, 0x82802007, 0x421c2023, 0x5218282b, 0x7b53173f, 0x0fe7480c, 0x74173b7f, 0x47751317, + 0x634d1807, 0x0f6f430f, 0x24086547, 0xfc808002, 0x0b3c7f80, 0x10840120, 0x188d1282, 0x20096b43, 0x0fc24403, 0x00260faf, 0x0180000b, 0x3f500280, + 0x18002019, 0x450b4941, 0xf3530fb9, 0x18002010, 0x8208a551, 0x06234d56, 0xcb58a39b, 0xc3421805, 0x1313461e, 0x0f855018, 0xd34b0120, 0x6cfe2008, + 0x574f0885, 0x09204114, 0x07000029, 0x00008000, 0x44028002, 0x01420f57, 0x10c95c10, 0x11184c18, 0x80221185, 0x7f421e00, 0x00732240, 0x09cd4977, + 0x6d0b2b42, 0x4f180f8f, 0x8f5a0bcb, 0x9b0f830f, 0x0fb9411f, 0x230b5756, 0x00fd8080, 0x82060745, 0x000121d5, 0x8e0fb277, 0x4a8d4211, 0x24061c53, + 0x04000007, 0x12275280, 0x430c954c, 0x80201545, 0x200f764f, 0x20008200, 0x20ce8308, 0x09534f02, 0x660edf64, 0x73731771, 0xe7411807, 0x20a2820c, + 0x13b64404, 0x8f5d6682, 0x1d6b4508, 0x0cff4d18, 0x3348c58f, 0x0fc34c07, 0x31558b84, 0x8398820f, 0x17514712, 0x240b0e46, 0x80000a00, 0x093b4502, + 0x420f9759, 0xa54c0bf1, 0x0f2b470c, 0x410d314b, 0x2584170c, 0x73b30020, 0xb55fe782, 0x204d8410, 0x08e043fe, 0x4f147e41, 0x022008ab, 0x4b055159, + 0x2950068f, 0x00022208, 0x48511880, 0x82002009, 0x00112300, 0x634dff00, 0x24415f27, 0x180f6d43, 0x4d0b5d45, 0x4d5f05ef, 0x01802317, 0x56188000, + 0xa7840807, 0xc6450220, 0x21ca8229, 0x4b781a00, 0x3359182c, 0x0cf3470f, 0x180bef46, 0x420b0354, 0xff470b07, 0x4515200a, 0x9758239b, 0x4a80200c, + 0xd2410a26, 0x05fb4a08, 0x4b05e241, 0x03200dc9, 0x92290941, 0x00002829, 0x00010900, 0x5b020001, 0x23201363, 0x460d776a, 0xef530fdb, 0x209a890c, + 0x13fc4302, 0x00008024, 0xc4820104, 0x08820220, 0x20086b5b, 0x18518700, 0x8408d349, 0x0da449a1, 0x00080024, 0x7b690280, 0x4c438b1a, 0x01220f63, + 0x4c878000, 0x5c149c53, 0xfb430868, 0x2f56181e, 0x0ccf7b1b, 0x0f075618, 0x2008e347, 0x14144104, 0x00207f83, 0x00207b82, 0x201adf47, 0x16c35a13, + 0x540fdf47, 0x802006c8, 0x5418f185, 0x29430995, 0x00002419, 0x58001600, 0x5720316f, 0x4d051542, 0x4b7b1b03, 0x138f4707, 0xb747b787, 0x4aab8213, + 0x058305fc, 0x20115759, 0x82128401, 0x0a0b44e8, 0x46800121, 0xe64210d0, 0x82129312, 0x4bffdffe, 0x3b41171b, 0x9b27870f, 0x808022ff, 0x085c68fe, + 0x41800021, 0x01410b20, 0x001a213a, 0x47480082, 0x11374e12, 0x56130b4c, 0xdf4b0c65, 0x0b0f590b, 0x0f574c18, 0x830feb4b, 0x075f480f, 0x480b4755, + 0x40490b73, 0x80012206, 0x09d74280, 0x80fe8022, 0x80210e86, 0x056643ff, 0x10820020, 0x420b2646, 0x0b58391a, 0xd74c1808, 0x078b4e22, 0x2007f55f, + 0x4b491807, 0x83802017, 0x65aa82a7, 0x3152099e, 0x068b7616, 0x9b431220, 0x09bb742c, 0x500e376c, 0x8342179b, 0x0a4d5d0f, 0x8020a883, 0x180cd349, + 0x2016bb4b, 0x14476004, 0x84136c43, 0x08cf7813, 0x4f4c0520, 0x156f420f, 0x20085f42, 0x6fd3be03, 0xd4d30803, 0xa7411420, 0x004b222c, 0x0d3b614f, + 0x3f702120, 0x1393410a, 0x8f132745, 0x47421827, 0x41e08209, 0xb05e2bb9, 0x18b7410c, 0x18082647, 0x4107a748, 0xeb8826bf, 0x0ca76018, 0x733ecb41, + 0xd0410d83, 0x43ebaf2a, 0x0420067f, 0x721dab4c, 0x472005bb, 0x4105d341, 0x334844cb, 0x20dba408, 0x47d6ac00, 0x034e3aef, 0x0f8f421b, 0x930f134d, + 0x3521231f, 0xb7421533, 0x42f5ad0a, 0x1e961eaa, 0x17000022, 0x4c367b50, 0x7d491001, 0x0bf5520f, 0x4c18fda7, 0xb8460c55, 0x83fe2005, 0x00fe25b9, + 0x80000180, 0x9e751085, 0x261b5c12, 0x82110341, 0x001123fb, 0x4518fe80, 0xf38c2753, 0x6d134979, 0x295107a7, 0xaf5f180f, 0x0fe3660c, 0x180b6079, + 0x2007bd5f, 0x9aab9103, 0x2f4d1811, 0x05002109, 0x44254746, 0x1d200787, 0x450bab75, 0x4f180f57, 0x4f181361, 0x3b831795, 0xeb4b0120, 0x0b734805, + 0x84078f48, 0x2e1b47bc, 0x00203383, 0xaf065f45, 0x831520d7, 0x130f51a7, 0x1797bf97, 0x2b47d783, 0x18fe2005, 0x4a18a44f, 0xa64d086d, 0x1ab0410d, + 0x6205a258, 0xdbab069f, 0x4f06f778, 0xa963081d, 0x133b670a, 0x8323d141, 0x13195b23, 0x530f5e70, 0xe5ad0824, 0x58001421, 0x1f472b4b, 0x47bf410c, + 0x82000121, 0x83fe20cb, 0x07424404, 0x68068243, 0xd7ad0d3d, 0x00010d26, 0x80020000, 0x4a1c6f43, 0x23681081, 0x10a14f13, 0x8a070e57, 0x430a848f, + 0x7372243e, 0x4397a205, 0xb56c1021, 0x43978f0f, 0x64180505, 0x99aa0ff2, 0x0e000022, 0x20223341, 0x094b4f37, 0x074a3320, 0x2639410a, 0xfe208e84, + 0x8b0e0048, 0x508020a3, 0x9e4308fe, 0x073f4115, 0xe3480420, 0x0c9b5f1b, 0x7c137743, 0x9a95185b, 0x6122b148, 0x979b08df, 0x0fe36c18, 0x48109358, + 0x23441375, 0x0ffd5c0b, 0x180fc746, 0x2011d157, 0x07e95702, 0x58180120, 0x18770ac3, 0x51032008, 0x7d4118e3, 0x80802315, 0x3b4c1900, 0xbb5a1830, + 0x0ceb6109, 0x5b0b3d42, 0x4f181369, 0x4f180b8d, 0x4f180f75, 0x355a1b81, 0x200d820d, 0x18e483fd, 0x4528854f, 0x89420846, 0x1321411f, 0x44086b60, + 0x07421d77, 0x107d4405, 0x4113fd41, 0x5a181bf1, 0x4f180db3, 0x8021128f, 0x20f68280, 0x44a882fe, 0x334d249a, 0x052f6109, 0x1520c3a7, 0xef4eb783, + 0x4ec39b1b, 0xc4c90ee7, 0x20060b4d, 0x256f4905, 0x4d0cf761, 0xcf9b1f13, 0xa213d74e, 0x0e1145d4, 0x50135b42, 0xcb4e398f, 0x20d79f27, 0x08865d80, + 0x186d5018, 0xa90f7142, 0x067342d7, 0x3f450420, 0x65002021, 0xe3560771, 0x24d38f23, 0x15333531, 0x0eb94d01, 0x451c9f41, 0x384322fb, 0x00092108, + 0x19af6b18, 0x6e0c6f5a, 0xbd770bfb, 0x22bb7718, 0x20090f57, 0x25e74204, 0x4207275a, 0xdb5408ef, 0x1769450f, 0x1b1b5518, 0x210b1f57, 0x5e4c8001, + 0x55012006, 0x802107f1, 0x0a306a80, 0x45808021, 0x0d850b88, 0x31744f18, 0x1808ec54, 0x2009575b, 0x45ffa505, 0x1b420c73, 0x180f9f0f, 0x4a0cf748, + 0x501805b2, 0x00210f40, 0x4d118f80, 0xd6823359, 0x072b5118, 0x314ad7aa, 0x8fc79f08, 0x45d78b1f, 0xfe20058f, 0x23325118, 0x7b54d9b5, 0x9fc38f46, + 0x10bb410f, 0x41077b42, 0xc1410faf, 0x27cf441d, 0x46051b4f, 0x04200683, 0x2121d344, 0x8f530043, 0x8fcf9f0e, 0x21df8c1f, 0x50188000, 0x5d180e52, + 0xfd201710, 0x4405c341, 0xd68528e3, 0x20071f6b, 0x1b734305, 0x6b080957, 0x7d422b1f, 0x67002006, 0x7f8317b1, 0x2024cb48, 0x08676e00, 0x8749a39b, + 0x18132006, 0x410a6370, 0x8f490b47, 0x7e1f8f13, 0x551805c3, 0x4c180915, 0xfe200e2f, 0x244d5d18, 0x270bcf44, 0xff000019, 0x04800380, 0x5f253342, + 0xff520df7, 0x13274c18, 0x5542dd93, 0x0776181b, 0xf94a1808, 0x084a4c0c, 0x4308ea5b, 0xde831150, 0x7900fd21, 0x00492c1e, 0x060f4510, 0x17410020, + 0x0ce74526, 0x6206b341, 0x1f561083, 0x9d6c181b, 0x08a0500e, 0x112e4118, 0x60000421, 0xbf901202, 0x4408e241, 0xc7ab0513, 0xb40f0950, 0x055943c7, + 0x4f18ff20, 0xc9ae1cad, 0x32b34f18, 0x7a180120, 0x3d520a05, 0x53d1b40a, 0x80200813, 0x1b815018, 0x832bf86f, 0x67731847, 0x297f4308, 0x6418d54e, + 0x734213f7, 0x056b4b27, 0xdba5fe20, 0x1828aa4e, 0x2031a370, 0x06cb6101, 0x2040ad41, 0x07365300, 0x2558d985, 0x83fe200c, 0x0380211c, 0x542c4743, + 0x052006b7, 0x6021df45, 0x897b0707, 0x18d3c010, 0x20090e70, 0x1d5843ff, 0x540a0e44, 0x002126c5, 0x322f7416, 0x636a5720, 0x0f317409, 0x610fe159, + 0x294617e7, 0x08555213, 0x2006a75d, 0x6cec84fd, 0xfb5907be, 0x3a317405, 0x83808021, 0x180f20ea, 0x4626434a, 0x531818e3, 0xdb59172d, 0x0cbb460c, + 0x2013d859, 0x18b94502, 0x8f46188d, 0x77521842, 0x0a184e38, 0x9585fd20, 0x6a180684, 0xc64507e9, 0x51cbb230, 0xd3440cf3, 0x17ff6a0f, 0x450f5b42, + 0x276407c1, 0x4853180a, 0x21ccb010, 0xcf580013, 0x0c15442d, 0x410a1144, 0x1144359d, 0x5cfe2006, 0xa1410a43, 0x2bb64519, 0x2f5b7618, 0xb512b745, + 0x0cfd6fd1, 0x42089f59, 0xb8450c70, 0x0000232d, 0x50180900, 0xb9491ae3, 0x0fc37610, 0x01210f83, 0x0f3b4100, 0xa01b2742, 0x0ccd426f, 0x6e8f6f94, + 0x9c808021, 0xc7511870, 0x17c74b08, 0x9b147542, 0x44fe2079, 0xd5480c7e, 0x95ef861d, 0x101b597b, 0xf5417594, 0x9f471808, 0x86868d0e, 0x3733491c, + 0x690f4d6d, 0x43440b83, 0x1ba94c0b, 0x660cd16b, 0x802008ae, 0x74126448, 0xcb4f38a3, 0x2cb74b0b, 0x47137755, 0xe3971777, 0x1b5d0120, 0x057a4108, + 0x6e08664d, 0x17421478, 0x11af4208, 0x850c3f42, 0x08234f0c, 0x4321eb4a, 0xf3451095, 0x0f394e0f, 0x4310eb45, 0xc09707b1, 0x54431782, 0xaec08d1d, + 0x0f434dbb, 0x9f0c0b45, 0x0a3b4dbb, 0x4618bdc7, 0x536032eb, 0x17354213, 0x4d134169, 0xc7a30c2f, 0x4e254342, 0x174332cf, 0x43cdae17, 0x6b4706e4, + 0x0e16430d, 0x530b5542, 0x2f7c26bb, 0x13075f31, 0x43175342, 0x60181317, 0x6550114e, 0x28624710, 0x58070021, 0x59181683, 0x2d540cf5, 0x05d5660c, + 0x20090c7b, 0x0e157e02, 0x8000ff2b, 0x14000080, 0x80ff8000, 0x27137e03, 0x336a4b20, 0x0f817107, 0x13876e18, 0x730f2f7e, 0x2f450b75, 0x6d02200b, + 0x6d66094c, 0x4b802009, 0x15820a02, 0x2f45fe20, 0x5e032006, 0x00202fd9, 0x450af741, 0xeb412e0f, 0x0ff3411f, 0x420a8b65, 0xf7410eae, 0x1c664810, + 0x540e1145, 0xbfa509f3, 0x42302f58, 0x80200c35, 0xcb066c47, 0x4b1120c1, 0x41492abb, 0x34854110, 0xa7097b72, 0x251545c7, 0x4b2c7f56, 0xc5b40bab, + 0x940cd54e, 0x2e6151c8, 0x09f35f18, 0x4b420420, 0x09677121, 0x8f24f357, 0x1b5418e1, 0x08915a1f, 0x3143d894, 0x22541805, 0x1b9b4b0e, 0x8c0d3443, + 0x1400240d, 0x18ff8000, 0x582e6387, 0xf99b2b3b, 0x8807a550, 0x17a14790, 0x2184fd20, 0x5758fe20, 0x2354882c, 0x15000080, 0x5e056751, 0x334c2c2f, + 0x97c58f0c, 0x1fd7410f, 0x0d4d4018, 0x4114dc41, 0x04470ed6, 0x0dd54128, 0x00820020, 0x02011523, 0x22008700, 0x86480024, 0x0001240a, 0x8682001a, + 0x0002240b, 0x866c000e, 0x8a03200b, 0x8a042017, 0x0005220b, 0x22218614, 0x84060000, 0x86012017, 0x8212200f, 0x250b8519, 0x000d0001, 0x0b850031, + 0x07000224, 0x0b862600, 0x11000324, 0x0b862d00, 0x238a0420, 0x0a000524, 0x17863e00, 0x17840620, 0x01000324, 0x57820904, 0x0b85a783, 0x0b85a785, + 0x0b85a785, 0x22000325, 0x85007a00, 0x85a7850b, 0x85a7850b, 0x22a7850b, 0x82300032, 0x00342201, 0x0805862f, 0x35003131, 0x54207962, 0x74736972, + 0x47206e61, 0x6d6d6972, 0x65527265, 0x616c7567, 0x58545472, 0x6f725020, 0x43796767, 0x6e61656c, 0x30325454, 0x822f3430, 0x35313502, 0x79006200, + 0x54002000, 0x69007200, 0x74007300, 0x6e006100, 0x47200f82, 0x6d240f84, 0x65006d00, 0x52200982, 0x67240582, 0x6c007500, 0x72201d82, 0x54222b82, + 0x23825800, 0x19825020, 0x67006f22, 0x79220182, 0x1b824300, 0x3b846520, 0x1f825420, 0x41000021, 0x1422099b, 0x0b410000, 0x87088206, 0x01012102, + 0x78080982, 0x01020101, 0x01040103, 0x01060105, 0x01080107, 0x010a0109, 0x010c010b, 0x010e010d, 0x0110010f, 0x01120111, 0x01140113, 0x01160115, + 0x01180117, 0x011a0119, 0x011c011b, 0x011e011d, 0x0020011f, 0x00040003, 0x00060005, 0x00080007, 0x000a0009, 0x000c000b, 0x000e000d, 0x0010000f, + 0x00120011, 0x00140013, 0x00160015, 0x00180017, 0x001a0019, 0x001c001b, 0x001e001d, 0x08bb821f, 0x22002142, 0x24002300, 0x26002500, 0x28002700, + 0x2a002900, 0x2c002b00, 0x2e002d00, 0x30002f00, 0x32003100, 0x34003300, 0x36003500, 0x38003700, 0x3a003900, 0x3c003b00, 0x3e003d00, 0x40003f00, + 0x42004100, 0x4b09f382, 0x00450044, 0x00470046, 0x00490048, 0x004b004a, 0x004d004c, 0x004f004e, 0x00510050, 0x00530052, 0x00550054, 0x00570056, + 0x00590058, 0x005b005a, 0x005d005c, 0x005f005e, 0x01610060, 0x01220121, 0x01240123, 0x01260125, 0x01280127, 0x012a0129, 0x012c012b, 0x012e012d, + 0x0130012f, 0x01320131, 0x01340133, 0x01360135, 0x01380137, 0x013a0139, 0x013c013b, 0x013e013d, 0x0140013f, 0x00ac0041, 0x008400a3, 0x00bd0085, + 0x00e80096, 0x008e0086, 0x009d008b, 0x00a400a9, 0x008a00ef, 0x008300da, 0x00f20093, 0x008d00f3, 0x00880097, 0x00de00c3, 0x009e00f1, 0x00f500aa, + 0x00f600f4, 0x00ad00a2, 0x00c700c9, 0x006200ae, 0x00900063, 0x00cb0064, 0x00c80065, 0x00cf00ca, 0x00cd00cc, 0x00e900ce, 0x00d30066, 0x00d100d0, + 0x006700af, 0x009100f0, 0x00d400d6, 0x006800d5, 0x00ed00eb, 0x006a0089, 0x006b0069, 0x006c006d, 0x00a0006e, 0x0071006f, 0x00720070, 0x00750073, + 0x00760074, 0x00ea0077, 0x007a0078, 0x007b0079, 0x007c007d, 0x00a100b8, 0x007e007f, 0x00810080, 0x00ee00ec, 0x6e750eba, 0x646f6369, 0x78302365, + 0x31303030, 0x32200e8d, 0x33200e8d, 0x34200e8d, 0x35200e8d, 0x36200e8d, 0x37200e8d, 0x38200e8d, 0x39200e8d, 0x61200e8d, 0x62200e8d, 0x63200e8d, + 0x64200e8d, 0x65200e8d, 0x66200e8d, 0x31210e8c, 0x8d0e8d30, 0x8d3120ef, 0x8d3120ef, 0x8d3120ef, 0x8d3120ef, 0x8d3120ef, 0x8d3120ef, 0x8d3120ef, + 0x8d3120ef, 0x8d3120ef, 0x8d3120ef, 0x8d3120ef, 0x8d3120ef, 0x8d3120ef, 0x66312def, 0x6c656406, 0x04657465, 0x6f727545, 0x3820ec8c, 0x3820ec8d, + 0x3820ec8d, 0x3820ec8d, 0x3820ec8d, 0x3820ec8d, 0x3820ec8d, 0x3820ec8d, 0x3820ec8d, 0x3820ec8d, 0x3820ec8d, 0x3820ec8d, 0x3820ec8d, 0x3820ec8d, + 0x3820ec8d, 0x200ddc41, 0x0ddc4139, 0xef8d3920, 0xef8d3920, 0xef8d3920, 0xef8d3920, 0xef8d3920, 0xef8d3920, 0xef8d3920, 0xef8d3920, 0xef8d3920, + 0xef8d3920, 0xef8d3920, 0xef8d3920, 0xef8d3920, 0xef8d3920, 0x00663923, 0x48fa0500, 0x00f762f9, +}; + +static void GetDefaultCompressedFontDataTTF(const void** ttf_compressed_data, unsigned int* ttf_compressed_size) +{ + *ttf_compressed_data = proggy_clean_ttf_compressed_data; + *ttf_compressed_size = proggy_clean_ttf_compressed_size; +} + +//----------------------------------------------------------------------------- + +//---- Include imgui_user.inl at the end of imgui.cpp +//---- So you can include code that extends ImGui using its private data/functions. +#ifdef IMGUI_INCLUDE_IMGUI_USER_INL +#include "imgui_user.inl" +#endif + +//----------------------------------------------------------------------------- diff --git a/testbed/imgui/imgui.h b/testbed/imgui/imgui.h new file mode 100644 index 00000000..bb9af931 --- /dev/null +++ b/testbed/imgui/imgui.h @@ -0,0 +1,1048 @@ +// ImGui library v1.39 WIP +// See .cpp file for documentation. +// See ImGui::ShowTestWindow() for sample code. +// Read 'Programmer guide' in .cpp for notes on how to setup ImGui in your codebase. +// Get latest version at https://github.com/ocornut/imgui + +#pragma once + +#include "imconfig.h" // User-editable configuration file +#include // FLT_MAX +#include // va_list +#include // ptrdiff_t, NULL +#include // NULL, malloc, free, qsort, atoi +#include // memset, memmove, memcpy, strlen, strchr, strcpy, strcmp + +#define IMGUI_VERSION "1.39 WIP" + +// Define assertion handler. +#ifndef IM_ASSERT +#include +#define IM_ASSERT(_EXPR) assert(_EXPR) +#endif + +// Define attributes of all API symbols declarations, e.g. for DLL under Windows. +#ifndef IMGUI_API +#define IMGUI_API +#endif + +// Forward declarations +struct ImDrawCmd; +struct ImDrawList; +struct ImFont; +struct ImFontAtlas; +struct ImGuiIO; +struct ImGuiStorage; +struct ImGuiStyle; + +typedef unsigned int ImU32; +typedef unsigned short ImWchar; // character for display +typedef void* ImTextureID; // user data to refer to a texture (e.g. store your texture handle/id) +typedef ImU32 ImGuiID; // unique ID used by widgets (typically hashed from a stack of string) +typedef int ImGuiCol; // enum ImGuiCol_ +typedef int ImGuiStyleVar; // enum ImGuiStyleVar_ +typedef int ImGuiKey; // enum ImGuiKey_ +typedef int ImGuiColorEditMode; // enum ImGuiColorEditMode_ +typedef int ImGuiMouseCursor; // enum ImGuiMouseCursor_ +typedef int ImGuiWindowFlags; // enum ImGuiWindowFlags_ +typedef int ImGuiSetCond; // enum ImGuiSetCond_ +typedef int ImGuiInputTextFlags; // enum ImGuiInputTextFlags_ +struct ImGuiTextEditCallbackData; // for advanced uses of InputText() +typedef int (*ImGuiTextEditCallback)(ImGuiTextEditCallbackData *data); + +struct ImVec2 +{ + float x, y; + ImVec2() { x = y = 0.0f; } + ImVec2(float _x, float _y) { x = _x; y = _y; } + +#ifdef IM_VEC2_CLASS_EXTRA // Define constructor and implicit cast operators to convert back<>forth from your math types and ImVec2. + IM_VEC2_CLASS_EXTRA +#endif +}; + +struct ImVec4 +{ + float x, y, z, w; + ImVec4() { x = y = z = w = 0.0f; } + ImVec4(float _x, float _y, float _z, float _w) { x = _x; y = _y; z = _z; w = _w; } + +#ifdef IM_VEC4_CLASS_EXTRA // Define constructor and implicit cast operators to convert back<>forth from your math types and ImVec4. + IM_VEC4_CLASS_EXTRA +#endif +}; + +namespace ImGui +{ + // Proxy functions to access the MemAllocFn/MemFreeFn pointers in ImGui::GetIO(). The only reason they exist here is to allow ImVector<> to compile inline. + IMGUI_API void* MemAlloc(size_t sz); + IMGUI_API void MemFree(void* ptr); +} + +// std::vector<> like class to avoid dragging dependencies (also: windows implementation of STL with debug enabled is absurdly slow, so let's bypass it so our code runs fast in debug). +// Use '#define ImVector std::vector' if you want to use the STL type or your own type. +// Our implementation does NOT call c++ constructors! because the data types we use don't need them (but that could be added as well). Only provide the minimum functionalities we need. +#ifndef ImVector +template +class ImVector +{ +protected: + size_t Size; + size_t Capacity; + T* Data; + +public: + typedef T value_type; + typedef value_type* iterator; + typedef const value_type* const_iterator; + + ImVector() { Size = Capacity = 0; Data = NULL; } + ~ImVector() { if (Data) ImGui::MemFree(Data); } + + inline bool empty() const { return Size == 0; } + inline size_t size() const { return Size; } + inline size_t capacity() const { return Capacity; } + + inline value_type& at(size_t i) { IM_ASSERT(i < Size); return Data[i]; } + inline const value_type& at(size_t i) const { IM_ASSERT(i < Size); return Data[i]; } + inline value_type& operator[](size_t i) { IM_ASSERT(i < Size); return Data[i]; } + inline const value_type& operator[](size_t i) const { IM_ASSERT(i < Size); return Data[i]; } + + inline void clear() { if (Data) { Size = Capacity = 0; ImGui::MemFree(Data); Data = NULL; } } + inline iterator begin() { return Data; } + inline const_iterator begin() const { return Data; } + inline iterator end() { return Data + Size; } + inline const_iterator end() const { return Data + Size; } + inline value_type& front() { IM_ASSERT(Size > 0); return Data[0]; } + inline const value_type& front() const { IM_ASSERT(Size > 0); return Data[0]; } + inline value_type& back() { IM_ASSERT(Size > 0); return Data[Size-1]; } + inline const value_type& back() const { IM_ASSERT(Size > 0); return Data[Size-1]; } + inline void swap(ImVector& rhs) { const size_t rhs_size = rhs.Size; rhs.Size = Size; Size = rhs_size; const size_t rhs_cap = rhs.Capacity; rhs.Capacity = Capacity; Capacity = rhs_cap; value_type* rhs_data = rhs.Data; rhs.Data = Data; Data = rhs_data; } + + inline void resize(size_t new_size) { if (new_size > Capacity) reserve(new_size); Size = new_size; } + inline void reserve(size_t new_capacity) + { + if (new_capacity <= Capacity) return; + T* new_data = (value_type*)ImGui::MemAlloc(new_capacity * sizeof(value_type)); + memcpy(new_data, Data, Size * sizeof(value_type)); + ImGui::MemFree(Data); + Data = new_data; + Capacity = new_capacity; + } + + inline void push_back(const value_type& v) { if (Size == Capacity) reserve(Capacity ? Capacity * 2 : 4); Data[Size++] = v; } + inline void pop_back() { IM_ASSERT(Size > 0); Size--; } + + inline iterator erase(const_iterator it) { IM_ASSERT(it >= begin() && it < end()); const ptrdiff_t off = it - begin(); memmove(Data + off, Data + off + 1, (Size - (size_t)off - 1) * sizeof(value_type)); Size--; return Data + off; } + inline iterator insert(const_iterator it, const value_type& v) { IM_ASSERT(it >= begin() && it <= end()); const ptrdiff_t off = it - begin(); if (Size == Capacity) reserve(Capacity ? Capacity * 2 : 4); if (off < (int)Size) memmove(Data + off + 1, Data + off, (Size - (size_t)off) * sizeof(value_type)); Data[off] = v; Size++; return Data + off; } +}; +#endif // #ifndef ImVector + +// Helpers at bottom of the file: +// - IMGUI_ONCE_UPON_A_FRAME // Execute a block of code once per frame only (convenient for creating UI within deep-nested code that runs multiple times) +// - struct ImGuiTextFilter // Parse and apply text filters. In format "aaaaa[,bbbb][,ccccc]" +// - struct ImGuiTextBuffer // Text buffer for logging/accumulating text +// - struct ImGuiStorage // Custom key value storage (if you need to alter open/close states manually) +// - struct ImDrawList // Draw command list +// - struct ImFont // TTF font loader, bake glyphs into bitmap + +// ImGui end-user API +// In a namespace so that user can add extra functions in a separate file (e.g. Value() helpers for your vector or common types) +namespace ImGui +{ + // Main + IMGUI_API ImGuiIO& GetIO(); + IMGUI_API ImGuiStyle& GetStyle(); + IMGUI_API void NewFrame(); + IMGUI_API void Render(); + IMGUI_API void Shutdown(); + IMGUI_API void ShowUserGuide(); // help block + IMGUI_API void ShowStyleEditor(ImGuiStyle* ref = NULL); // style editor block + IMGUI_API void ShowTestWindow(bool* opened = NULL); // test window, demonstrate ImGui features + IMGUI_API void ShowMetricsWindow(bool* opened = NULL); // metrics window + + // Window + // See implementation in .cpp for details + IMGUI_API bool Begin(const char* name = "Debug", bool* p_opened = NULL, ImGuiWindowFlags flags = 0); // return false when window is collapsed, so you can early out in your code. 'bool* p_opened' creates a widget on the upper-right to close the window (which sets your bool to false). + IMGUI_API bool Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_use, float bg_alpha = -1.0f, ImGuiWindowFlags flags = 0); // this is the older/longer API. call SetNextWindowSize() instead if you want to set a window size. For regular windows, 'size_on_first_use' only applies to the first time EVER the window is created and probably not what you want! maybe obsolete this API eventually. + IMGUI_API void End(); + IMGUI_API bool BeginChild(const char* str_id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags extra_flags = 0); // size==0.0f: use remaining window size, size<0.0f: use remaining window size minus abs(size). on each axis. + IMGUI_API bool BeginChild(ImGuiID id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags extra_flags = 0); // " + IMGUI_API void EndChild(); + IMGUI_API ImVec2 GetContentRegionMax(); // window or current column boundaries, in windows coordinates + IMGUI_API ImVec2 GetWindowContentRegionMin(); // window boundaries, in windows coordinates + IMGUI_API ImVec2 GetWindowContentRegionMax(); + IMGUI_API ImDrawList* GetWindowDrawList(); // get rendering command-list if you want to append your own draw primitives + IMGUI_API ImFont* GetWindowFont(); + IMGUI_API float GetWindowFontSize(); // size (also height in pixels) of current font with current scale applied + IMGUI_API void SetWindowFontScale(float scale); // per-window font scale. Adjust IO.FontGlobalScale if you want to scale all windows + IMGUI_API ImVec2 GetWindowPos(); // you should rarely need/care about the window position, but it can be useful if you want to do your own drawing + IMGUI_API ImVec2 GetWindowSize(); // get current window position + IMGUI_API float GetWindowWidth(); + IMGUI_API bool GetWindowCollapsed(); + + IMGUI_API void SetNextWindowPos(const ImVec2& pos, ImGuiSetCond cond = 0); // set next window position - call before Begin() + IMGUI_API void SetNextWindowSize(const ImVec2& size, ImGuiSetCond cond = 0); // set next window size. set to ImVec2(0,0) to force an auto-fit + IMGUI_API void SetNextWindowCollapsed(bool collapsed, ImGuiSetCond cond = 0); // set next window collapsed state + IMGUI_API void SetNextWindowFocus(); // set next window to be focused / front-most + IMGUI_API void SetWindowPos(const ImVec2& pos, ImGuiSetCond cond = 0); // set current window position - call within Begin()/End(). may incur tearing + IMGUI_API void SetWindowSize(const ImVec2& size, ImGuiSetCond cond = 0); // set current window size. set to ImVec2(0,0) to force an auto-fit. may incur tearing + IMGUI_API void SetWindowCollapsed(bool collapsed, ImGuiSetCond cond = 0); // set current window collapsed state + IMGUI_API void SetWindowFocus(); // set current window to be focused / front-most + IMGUI_API void SetWindowPos(const char* name, const ImVec2& pos, ImGuiSetCond cond = 0); // set named window position - call within Begin()/End(). may incur tearing + IMGUI_API void SetWindowSize(const char* name, const ImVec2& size, ImGuiSetCond cond = 0); // set named window size. set to ImVec2(0,0) to force an auto-fit. may incur tearing + IMGUI_API void SetWindowCollapsed(const char* name, bool collapsed, ImGuiSetCond cond = 0); // set named window collapsed state + IMGUI_API void SetWindowFocus(const char* name); // set named window to be focused / front-most. use NULL to remove focus. + + IMGUI_API float GetScrollPosY(); // get scrolling position [0..GetScrollMaxY()] + IMGUI_API float GetScrollMaxY(); // get maximum scrolling position == ContentSize.Y - WindowSize.Y + IMGUI_API void SetScrollPosHere(); // adjust scrolling position to center into the current cursor position + IMGUI_API void SetKeyboardFocusHere(int offset = 0); // focus keyboard on the next widget. Use positive 'offset' to access sub components of a multiple component widget + IMGUI_API void SetStateStorage(ImGuiStorage* tree); // replace tree state storage with our own (if you want to manipulate it yourself, typically clear subsection of it) + IMGUI_API ImGuiStorage* GetStateStorage(); + + // Parameters stacks (shared) + IMGUI_API void PushFont(ImFont* font); // use NULL as a shortcut to push default font + IMGUI_API void PopFont(); + IMGUI_API void PushStyleColor(ImGuiCol idx, const ImVec4& col); + IMGUI_API void PopStyleColor(int count = 1); + IMGUI_API void PushStyleVar(ImGuiStyleVar idx, float val); + IMGUI_API void PushStyleVar(ImGuiStyleVar idx, const ImVec2& val); + IMGUI_API void PopStyleVar(int count = 1); + + // Parameters stacks (current window) + IMGUI_API void PushItemWidth(float item_width); // width of items for the common item+label case, pixels. 0.0f = default to ~2/3 of windows width, >0.0f: width in pixels, <0.0f align xx pixels to the right of window (so -0.01f always align width to the right side) + IMGUI_API void PopItemWidth(); + IMGUI_API float CalcItemWidth(); // width of item given pushed settings and current cursor position + IMGUI_API void PushAllowKeyboardFocus(bool v); // allow focusing using TAB/Shift-TAB, enabled by default but you can disable it for certain widgets + IMGUI_API void PopAllowKeyboardFocus(); + IMGUI_API void PushTextWrapPos(float wrap_pos_x = 0.0f); // word-wrapping for Text*() commands. < 0.0f: no wrapping; 0.0f: wrap to end of window (or column); > 0.0f: wrap at 'wrap_pos_x' position in window local space + IMGUI_API void PopTextWrapPos(); + + // Tooltip + IMGUI_API void SetTooltip(const char* fmt, ...); // set tooltip under mouse-cursor, typically use with ImGui::IsHovered(). last call wins + IMGUI_API void SetTooltipV(const char* fmt, va_list args); + IMGUI_API void BeginTooltip(); // use to create full-featured tooltip windows that aren't just text + IMGUI_API void EndTooltip(); + + // Popup + IMGUI_API void BeginPopup(bool* p_opened); + IMGUI_API void EndPopup(); + + // Layout + IMGUI_API void BeginGroup(); + IMGUI_API void EndGroup(); + IMGUI_API void Separator(); // horizontal line + IMGUI_API void SameLine(int column_x = 0, int spacing_w = -1); // call between widgets or groups to layout them horizontally + IMGUI_API void Spacing(); // add vertical spacing + IMGUI_API void Indent(); // move content position toward the right by style.IndentSpacing pixels + IMGUI_API void Unindent(); // move content position back to the left (cancel Indent) + IMGUI_API void Columns(int count = 1, const char* id = NULL, bool border=true); // setup number of columns + IMGUI_API void NextColumn(); // next column + IMGUI_API int GetColumnIndex(); // get current column index + IMGUI_API float GetColumnOffset(int column_index = -1); // get position of column line (in pixels, from the left side of the contents region). pass -1 to use current column, otherwise 0..GetcolumnsCount() inclusive. column 0 is usually 0.0f and not resizable unless you call this + IMGUI_API void SetColumnOffset(int column_index, float offset_x); // set position of column line (in pixels, from the left side of the contents region). pass -1 to use current column + IMGUI_API float GetColumnWidth(int column_index = -1); // column width (== GetColumnOffset(GetColumnIndex()+1) - GetColumnOffset(GetColumnOffset()) + IMGUI_API int GetColumnsCount(); // number of columns (what was passed to Columns()) + IMGUI_API ImVec2 GetCursorPos(); // cursor position is relative to window position + IMGUI_API float GetCursorPosX(); // " + IMGUI_API float GetCursorPosY(); // " + IMGUI_API void SetCursorPos(const ImVec2& pos); // " + IMGUI_API void SetCursorPosX(float x); // " + IMGUI_API void SetCursorPosY(float y); // " + IMGUI_API ImVec2 GetCursorScreenPos(); // cursor position in absolute screen coordinates [0..io.DisplaySize] + IMGUI_API void SetCursorScreenPos(const ImVec2& pos); // cursor position in absolute screen coordinates [0..io.DisplaySize] + IMGUI_API void AlignFirstTextHeightToWidgets(); // call once if the first item on the line is a Text() item and you want to vertically lower it to match subsequent (bigger) widgets + IMGUI_API float GetTextLineHeight(); // height of font == GetWindowFontSize() + IMGUI_API float GetTextLineHeightWithSpacing(); // spacing (in pixels) between 2 consecutive lines of text == GetWindowFontSize() + GetStyle().ItemSpacing.y + + // ID scopes + // If you are creating widgets in a loop you most likely want to push a unique identifier so ImGui can differentiate them + // You can also use "##extra" within your widget name to distinguish them from each others (see 'Programmer Guide') + IMGUI_API void PushID(const char* str_id); // push identifier into the ID stack. IDs are hash of the *entire* stack! + IMGUI_API void PushID(const char* str_id_begin, const char* str_id_end); + IMGUI_API void PushID(const void* ptr_id); + IMGUI_API void PushID(const int int_id); + IMGUI_API void PopID(); + IMGUI_API ImGuiID GetID(const char* str_id); // calculate unique ID (hash of whole ID stack + given parameter). useful if you want to query into ImGuiStorage yourself. otherwise rarely needed + IMGUI_API ImGuiID GetID(const char* str_id_begin, const char* str_id_end); + IMGUI_API ImGuiID GetID(const void* ptr_id); + + // Widgets + IMGUI_API void Text(const char* fmt, ...); + IMGUI_API void TextV(const char* fmt, va_list args); + IMGUI_API void TextColored(const ImVec4& col, const char* fmt, ...); // shortcut for PushStyleColor(ImGuiCol_Text, col); Text(fmt, ...); PopStyleColor(); + IMGUI_API void TextColoredV(const ImVec4& col, const char* fmt, va_list args); + IMGUI_API void TextWrapped(const char* fmt, ...); // shortcut for PushTextWrapPos(0.0f); Text(fmt, ...); PopTextWrapPos(); + IMGUI_API void TextWrappedV(const char* fmt, va_list args); + IMGUI_API void TextUnformatted(const char* text, const char* text_end = NULL); // doesn't require null terminated string if 'text_end' is specified. no copy done to any bounded stack buffer, recommended for long chunks of text + IMGUI_API void LabelText(const char* label, const char* fmt, ...); // display text+label aligned the same way as value+label widgets + IMGUI_API void LabelTextV(const char* label, const char* fmt, va_list args); + IMGUI_API void Bullet(); + IMGUI_API void BulletText(const char* fmt, ...); + IMGUI_API void BulletTextV(const char* fmt, va_list args); + IMGUI_API bool Button(const char* label, const ImVec2& size = ImVec2(0,0), bool repeat_when_held = false); + IMGUI_API bool SmallButton(const char* label); + IMGUI_API bool InvisibleButton(const char* str_id, const ImVec2& size); + IMGUI_API void Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0,0), const ImVec2& uv1 = ImVec2(1,1), const ImVec4& tint_col = ImVec4(1,1,1,1), const ImVec4& border_col = ImVec4(0,0,0,0)); + IMGUI_API bool ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0,0), const ImVec2& uv1 = ImVec2(1,1), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0,0,0,1), const ImVec4& tint_col = ImVec4(1,1,1,1)); // <0 frame_padding uses default frame padding settings. 0 for no padding + IMGUI_API bool CollapsingHeader(const char* label, const char* str_id = NULL, bool display_frame = true, bool default_open = false); + IMGUI_API bool Checkbox(const char* label, bool* v); + IMGUI_API bool CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value); + IMGUI_API bool RadioButton(const char* label, bool active); + IMGUI_API bool RadioButton(const char* label, int* v, int v_button); + IMGUI_API bool Combo(const char* label, int* current_item, const char** items, int items_count, int height_in_items = -1); + IMGUI_API bool Combo(const char* label, int* current_item, const char* items_separated_by_zeros, int height_in_items = -1); // separate items with \0, end item-list with \0\0 + IMGUI_API bool Combo(const char* label, int* current_item, bool (*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int height_in_items = -1); + IMGUI_API bool ColorButton(const ImVec4& col, bool small_height = false, bool outline_border = true); + IMGUI_API bool ColorEdit3(const char* label, float col[3]); + IMGUI_API bool ColorEdit4(const char* label, float col[4], bool show_alpha = true); + IMGUI_API void ColorEditMode(ImGuiColorEditMode mode); + IMGUI_API void PlotLines(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0), size_t stride = sizeof(float)); + IMGUI_API void PlotLines(const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0)); + IMGUI_API void PlotHistogram(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0), size_t stride = sizeof(float)); + IMGUI_API void PlotHistogram(const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0)); + + // Widgets: Sliders (tip: ctrl+click on a slider to input text) + IMGUI_API bool SliderFloat(const char* label, float* v, float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); // adjust display_format to decorate the value with a prefix or a suffix. Use power!=1.0 for logarithmic sliders + IMGUI_API bool SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); + IMGUI_API bool SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); + IMGUI_API bool SliderFloat4(const char* label, float v[4], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); + IMGUI_API bool SliderAngle(const char* label, float* v_rad, float v_degrees_min = -360.0f, float v_degrees_max = +360.0f); + IMGUI_API bool SliderInt(const char* label, int* v, int v_min, int v_max, const char* display_format = "%.0f"); + IMGUI_API bool SliderInt2(const char* label, int v[2], int v_min, int v_max, const char* display_format = "%.0f"); + IMGUI_API bool SliderInt3(const char* label, int v[3], int v_min, int v_max, const char* display_format = "%.0f"); + IMGUI_API bool SliderInt4(const char* label, int v[4], int v_min, int v_max, const char* display_format = "%.0f"); + IMGUI_API bool VSliderFloat(const char* label, const ImVec2& size, float* v, float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); + IMGUI_API bool VSliderInt(const char* label, const ImVec2& size, int* v, int v_min, int v_max, const char* display_format = "%.0f"); + + // Widgets: Drags (tip: ctrl+click on a drag box to input text) + IMGUI_API bool DragFloat(const char* label, float* v, float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f); // If v_max >= v_max we have no bound + IMGUI_API bool DragFloat2(const char* label, float v[2], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f); + IMGUI_API bool DragFloat3(const char* label, float v[3], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f); + IMGUI_API bool DragFloat4(const char* label, float v[4], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f); + IMGUI_API bool DragInt(const char* label, int* v, float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f"); // If v_max >= v_max we have no bound + IMGUI_API bool DragInt2(const char* label, int v[2], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f"); + IMGUI_API bool DragInt3(const char* label, int v[3], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f"); + IMGUI_API bool DragInt4(const char* label, int v[4], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f"); + + // Widgets: Input + IMGUI_API bool InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags = 0, ImGuiTextEditCallback callback = NULL, void* user_data = NULL); + IMGUI_API bool InputFloat(const char* label, float* v, float step = 0.0f, float step_fast = 0.0f, int decimal_precision = -1, ImGuiInputTextFlags extra_flags = 0); + IMGUI_API bool InputFloat2(const char* label, float v[2], int decimal_precision = -1); + IMGUI_API bool InputFloat3(const char* label, float v[3], int decimal_precision = -1); + IMGUI_API bool InputFloat4(const char* label, float v[4], int decimal_precision = -1); + IMGUI_API bool InputInt(const char* label, int* v, int step = 1, int step_fast = 100, ImGuiInputTextFlags extra_flags = 0); + IMGUI_API bool InputInt2(const char* label, int v[2]); + IMGUI_API bool InputInt3(const char* label, int v[3]); + IMGUI_API bool InputInt4(const char* label, int v[4]); + + // Widgets: Trees + IMGUI_API bool TreeNode(const char* str_label_id); // if returning 'true' the node is open and the user is responsible for calling TreePop + IMGUI_API bool TreeNode(const char* str_id, const char* fmt, ...); // " + IMGUI_API bool TreeNode(const void* ptr_id, const char* fmt, ...); // " + IMGUI_API bool TreeNodeV(const char* str_id, const char* fmt, va_list args); // " + IMGUI_API bool TreeNodeV(const void* ptr_id, const char* fmt, va_list args); // " + IMGUI_API void TreePush(const char* str_id = NULL); // already called by TreeNode(), but you can call Push/Pop yourself for layouting purpose + IMGUI_API void TreePush(const void* ptr_id = NULL); // " + IMGUI_API void TreePop(); + IMGUI_API void SetNextTreeNodeOpened(bool opened, ImGuiSetCond cond = 0); // set next tree node to be opened. + + // Widgets: Selectable / Lists + IMGUI_API bool Selectable(const char* label, bool selected = false, const ImVec2& size = ImVec2(0,0)); + IMGUI_API bool Selectable(const char* label, bool* p_selected, const ImVec2& size = ImVec2(0,0)); + IMGUI_API bool ListBox(const char* label, int* current_item, const char** items, int items_count, int height_in_items = -1); + IMGUI_API bool ListBox(const char* label, int* current_item, bool (*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int height_in_items = -1); + IMGUI_API bool ListBoxHeader(const char* label, const ImVec2& size = ImVec2(0,0)); // use if you want to reimplement ListBox() will custom data or interactions. make sure to call ListBoxFooter() afterwards. + IMGUI_API bool ListBoxHeader(const char* label, int items_count, int height_in_items = -1); // " + IMGUI_API void ListBoxFooter(); // terminate the scrolling region + + // Widgets: Value() Helpers. Output single value in "name: value" format (tip: freely declare your own within the ImGui namespace!) + IMGUI_API void Value(const char* prefix, bool b); + IMGUI_API void Value(const char* prefix, int v); + IMGUI_API void Value(const char* prefix, unsigned int v); + IMGUI_API void Value(const char* prefix, float v, const char* float_format = NULL); + IMGUI_API void Color(const char* prefix, const ImVec4& v); + IMGUI_API void Color(const char* prefix, unsigned int v); + + // Logging: all text output from interface is redirected to tty/file/clipboard. Tree nodes are automatically opened. + IMGUI_API void LogToTTY(int max_depth = -1); // start logging to tty + IMGUI_API void LogToFile(int max_depth = -1, const char* filename = NULL); // start logging to file + IMGUI_API void LogToClipboard(int max_depth = -1); // start logging to OS clipboard + IMGUI_API void LogFinish(); // stop logging (close file, etc.) + IMGUI_API void LogButtons(); // helper to display buttons for logging to tty/file/clipboard + IMGUI_API void LogText(const char* fmt, ...); // pass text data straight to log (without being displayed) + + // Utilities + IMGUI_API bool IsItemHovered(); // was the last item hovered by mouse? + IMGUI_API bool IsItemHoveredRect(); // was the last item hovered by mouse? even if another item is active while we are hovering this + IMGUI_API bool IsItemActive(); // was the last item active? (e.g. button being held, text field being edited- items that don't interact will always return false) + IMGUI_API bool IsAnyItemActive(); // + IMGUI_API bool IsItemVisible(); + IMGUI_API ImVec2 GetItemRectMin(); // get bounding rect of last item in screen space + IMGUI_API ImVec2 GetItemRectMax(); // " + IMGUI_API ImVec2 GetItemRectSize(); // " + IMGUI_API bool IsWindowFocused(); // is current window focused (differentiate child windows from each others) + IMGUI_API bool IsRootWindowFocused(); // is current root window focused + IMGUI_API bool IsRootWindowOrAnyChildFocused(); // is current root window or any of its child (including current window) focused + IMGUI_API bool IsRectClipped(const ImVec2& size); // test if rectangle of given size starting from cursor pos is out of clipping region. to perform coarse clipping on user's side (as an optimization) + IMGUI_API bool IsKeyPressed(int key_index, bool repeat = true); // key_index into the keys_down[512] array, imgui doesn't know the semantic of each entry + IMGUI_API bool IsMouseClicked(int button, bool repeat = false); + IMGUI_API bool IsMouseDoubleClicked(int button); + IMGUI_API bool IsMouseHoveringWindow(); // is mouse hovering current window ("window" in API names always refer to current window) + IMGUI_API bool IsMouseHoveringAnyWindow(); // is mouse hovering any active imgui window + IMGUI_API bool IsMouseHoveringRect(const ImVec2& rect_min, const ImVec2& rect_max);// is mouse hovering given bounding rect + IMGUI_API bool IsMouseDragging(int button = 0, float lock_threshold = -1.0f); // is mouse dragging. if lock_threshold < -1.0f uses io.MouseDraggingThreshold + IMGUI_API bool IsPosHoveringAnyWindow(const ImVec2& pos); // is given position hovering any active imgui window + IMGUI_API ImVec2 GetMousePos(); // shortcut to ImGui::GetIO().MousePos provided by user, to be consistent with other calls + IMGUI_API ImVec2 GetMouseDragDelta(int button = 0, float lock_threshold = -1.0f); // dragging amount since clicking, also see: GetItemActiveDragDelta(). if lock_threshold < -1.0f uses io.MouseDraggingThreshold + IMGUI_API void ResetMouseDragDelta(int button = 0); + IMGUI_API ImGuiMouseCursor GetMouseCursor(); // get desired cursor type, reset in ImGui::NewFrame(), this updated during the frame. valid before Render(). If you use software rendering by setting io.MouseDrawCursor ImGui will render those for you + IMGUI_API void SetMouseCursor(ImGuiMouseCursor type); // set desired cursor type + IMGUI_API float GetTime(); + IMGUI_API int GetFrameCount(); + IMGUI_API const char* GetStyleColName(ImGuiCol idx); + IMGUI_API ImVec2 CalcItemRectClosestPoint(const ImVec2& pos, bool on_edge = false, float outward = +0.0f); // utility to find the closest point the last item bounding rectangle edge. useful to visually link items + IMGUI_API ImVec2 CalcTextSize(const char* text, const char* text_end = NULL, bool hide_text_after_double_hash = false, float wrap_width = -1.0f); + IMGUI_API void CalcListClipping(int items_count, float items_height, int* out_items_display_start, int* out_items_display_end); // helper to manually clip large list of items. see comments in implementation + + IMGUI_API void BeginChildFrame(ImGuiID id, const ImVec2& size); // helper to create a child window / scrolling region that looks like a normal widget frame + IMGUI_API void EndChildFrame(); + + IMGUI_API ImU32 ColorConvertFloat4ToU32(const ImVec4& in); + IMGUI_API void ColorConvertRGBtoHSV(float r, float g, float b, float& out_h, float& out_s, float& out_v); + IMGUI_API void ColorConvertHSVtoRGB(float h, float s, float v, float& out_r, float& out_g, float& out_b); + + // Internal state access - if you want to share ImGui state between modules (e.g. DLL) or allocate it yourself + IMGUI_API const char* GetVersion(); + IMGUI_API void* GetInternalState(); + IMGUI_API size_t GetInternalStateSize(); + IMGUI_API void SetInternalState(void* state, bool construct = false); + + // Obsolete (will be removed) + IMGUI_API void GetDefaultFontData(const void** fnt_data, unsigned int* fnt_size, const void** png_data, unsigned int* png_size); // OBSOLETE + static inline void OpenNextNode(bool open) { ImGui::SetNextTreeNodeOpened(open, 0); } // OBSOLETE + static inline bool GetWindowIsFocused() { return ImGui::IsWindowFocused(); } // OBSOLETE + static inline ImVec2 GetItemBoxMin() { return GetItemRectMin(); } // OBSOLETE + static inline ImVec2 GetItemBoxMax() { return GetItemRectMax(); } // OBSOLETE + static inline bool IsClipped(const ImVec2& size) { return IsRectClipped(size); } // OBSOLETE + static inline bool IsMouseHoveringBox(const ImVec2& rect_min, const ImVec2& rect_max) { return IsMouseHoveringRect(rect_min, rect_max); } // OBSOLETE + +} // namespace ImGui + +// Flags for ImGui::Begin() +enum ImGuiWindowFlags_ +{ + // Default: 0 + ImGuiWindowFlags_NoTitleBar = 1 << 0, // Disable title-bar + ImGuiWindowFlags_NoResize = 1 << 1, // Disable user resizing with the lower-right grip + ImGuiWindowFlags_NoMove = 1 << 2, // Disable user moving the window + ImGuiWindowFlags_NoScrollbar = 1 << 3, // Disable scrollbar (window can still scroll with mouse or programatically) + ImGuiWindowFlags_NoScrollWithMouse = 1 << 4, // Disable user scrolling with mouse wheel + ImGuiWindowFlags_NoCollapse = 1 << 5, // Disable user collapsing window by double-clicking on it + ImGuiWindowFlags_AlwaysAutoResize = 1 << 6, // Resize every window to its content every frame + ImGuiWindowFlags_ShowBorders = 1 << 7, // Show borders around windows and items + ImGuiWindowFlags_NoSavedSettings = 1 << 8, // Never load/save settings in .ini file + // [Internal] + ImGuiWindowFlags_ChildWindow = 1 << 9, // For internal use by BeginChild() + ImGuiWindowFlags_ChildWindowAutoFitX = 1 << 10, // For internal use by BeginChild() + ImGuiWindowFlags_ChildWindowAutoFitY = 1 << 11, // For internal use by BeginChild() + ImGuiWindowFlags_ComboBox = 1 << 12, // For internal use by ComboBox() + ImGuiWindowFlags_Tooltip = 1 << 13, // For internal use by BeginTooltip() + ImGuiWindowFlags_Popup = 1 << 14 // For internal use by BeginPopup() +}; + +// Flags for ImGui::InputText() +enum ImGuiInputTextFlags_ +{ + // Default: 0 + ImGuiInputTextFlags_CharsDecimal = 1 << 0, // Allow 0123456789.+-*/ + ImGuiInputTextFlags_CharsHexadecimal = 1 << 1, // Allow 0123456789ABCDEFabcdef + ImGuiInputTextFlags_CharsUppercase = 1 << 2, // Turn a..z into A..Z + ImGuiInputTextFlags_CharsNoBlank = 1 << 3, // Filter out spaces, tabs + ImGuiInputTextFlags_AutoSelectAll = 1 << 4, // Select entire text when first taking mouse focus + ImGuiInputTextFlags_EnterReturnsTrue = 1 << 5, // Return 'true' when Enter is pressed (as opposed to when the value was modified) + ImGuiInputTextFlags_CallbackCompletion = 1 << 6, // Call user function on pressing TAB (for completion handling) + ImGuiInputTextFlags_CallbackHistory = 1 << 7, // Call user function on pressing Up/Down arrows (for history handling) + ImGuiInputTextFlags_CallbackAlways = 1 << 8, // Call user function every time + ImGuiInputTextFlags_CallbackCharFilter = 1 << 9 // Call user function to filter character. Modify data->EventChar to replace/filter input, or return 1 to discard character. +}; + +// User fill ImGuiIO.KeyMap[] array with indices into the ImGuiIO.KeysDown[512] array +enum ImGuiKey_ +{ + ImGuiKey_Tab, + ImGuiKey_LeftArrow, + ImGuiKey_RightArrow, + ImGuiKey_UpArrow, + ImGuiKey_DownArrow, + ImGuiKey_Home, + ImGuiKey_End, + ImGuiKey_Delete, + ImGuiKey_Backspace, + ImGuiKey_Enter, + ImGuiKey_Escape, + ImGuiKey_A, // for CTRL+A: select all + ImGuiKey_C, // for CTRL+C: copy + ImGuiKey_V, // for CTRL+V: paste + ImGuiKey_X, // for CTRL+X: cut + ImGuiKey_Y, // for CTRL+Y: redo + ImGuiKey_Z, // for CTRL+Z: undo + ImGuiKey_COUNT +}; + +// Enumeration for PushStyleColor() / PopStyleColor() +enum ImGuiCol_ +{ + ImGuiCol_Text, + ImGuiCol_WindowBg, + ImGuiCol_ChildWindowBg, + ImGuiCol_Border, + ImGuiCol_BorderShadow, + ImGuiCol_FrameBg, // Background of checkbox, radio button, plot, slider, text input + ImGuiCol_FrameBgHovered, + ImGuiCol_FrameBgActive, + ImGuiCol_TitleBg, + ImGuiCol_TitleBgCollapsed, + ImGuiCol_ScrollbarBg, + ImGuiCol_ScrollbarGrab, + ImGuiCol_ScrollbarGrabHovered, + ImGuiCol_ScrollbarGrabActive, + ImGuiCol_ComboBg, + ImGuiCol_CheckMark, + ImGuiCol_SliderGrab, + ImGuiCol_SliderGrabActive, + ImGuiCol_Button, + ImGuiCol_ButtonHovered, + ImGuiCol_ButtonActive, + ImGuiCol_Header, + ImGuiCol_HeaderHovered, + ImGuiCol_HeaderActive, + ImGuiCol_Column, + ImGuiCol_ColumnHovered, + ImGuiCol_ColumnActive, + ImGuiCol_ResizeGrip, + ImGuiCol_ResizeGripHovered, + ImGuiCol_ResizeGripActive, + ImGuiCol_CloseButton, + ImGuiCol_CloseButtonHovered, + ImGuiCol_CloseButtonActive, + ImGuiCol_PlotLines, + ImGuiCol_PlotLinesHovered, + ImGuiCol_PlotHistogram, + ImGuiCol_PlotHistogramHovered, + ImGuiCol_TextSelectedBg, + ImGuiCol_TooltipBg, + ImGuiCol_COUNT +}; + +// Enumeration for PushStyleVar() / PopStyleVar() +// NB: the enum only refers to fields of ImGuiStyle() which makes sense to be pushed/poped in UI code. Feel free to add others. +enum ImGuiStyleVar_ +{ + ImGuiStyleVar_Alpha, // float + ImGuiStyleVar_WindowPadding, // ImVec2 + ImGuiStyleVar_WindowRounding, // float + ImGuiStyleVar_ChildWindowRounding, // float + ImGuiStyleVar_FramePadding, // ImVec2 + ImGuiStyleVar_FrameRounding, // float + ImGuiStyleVar_ItemSpacing, // ImVec2 + ImGuiStyleVar_ItemInnerSpacing, // ImVec2 + ImGuiStyleVar_IndentSpacing, // float + ImGuiStyleVar_GrabMinSize // float +}; + +// Enumeration for ColorEditMode() +enum ImGuiColorEditMode_ +{ + ImGuiColorEditMode_UserSelect = -2, + ImGuiColorEditMode_UserSelectShowButton = -1, + ImGuiColorEditMode_RGB = 0, + ImGuiColorEditMode_HSV = 1, + ImGuiColorEditMode_HEX = 2 +}; + +// Enumeration for GetMouseCursor() +enum ImGuiMouseCursor_ +{ + ImGuiMouseCursor_Arrow = 0, + ImGuiMouseCursor_TextInput, // When hovering over InputText, etc. + ImGuiMouseCursor_Move, // Unused + ImGuiMouseCursor_ResizeNS, // Unused + ImGuiMouseCursor_ResizeEW, // When hovering over a column + ImGuiMouseCursor_ResizeNESW, // Unused + ImGuiMouseCursor_ResizeNWSE, // When hovering over the bottom-right corner of a window + ImGuiMouseCursor_Count_ +}; + +// Condition flags for ImGui::SetWindow***(), SetNextWindow***(), SetNextTreeNode***() functions +// All those functions treat 0 as a shortcut to ImGuiSetCond_Always +enum ImGuiSetCond_ +{ + ImGuiSetCond_Always = 1 << 0, // Set the variable + ImGuiSetCond_Once = 1 << 1, // Only set the variable on the first call per runtime session + ImGuiSetCond_FirstUseEver = 1 << 2 // Only set the variable if the window doesn't exist in the .ini file +}; + +struct ImGuiStyle +{ + float Alpha; // Global alpha applies to everything in ImGui + ImVec2 WindowPadding; // Padding within a window + ImVec2 WindowMinSize; // Minimum window size + float WindowRounding; // Radius of window corners rounding. Set to 0.0f to have rectangular windows + float ChildWindowRounding; // Radius of child window corners rounding. Set to 0.0f to have rectangular windows + ImVec2 FramePadding; // Padding within a framed rectangle (used by most widgets) + float FrameRounding; // Radius of frame corners rounding. Set to 0.0f to have rectangular frame (used by most widgets). + ImVec2 ItemSpacing; // Horizontal and vertical spacing between widgets/lines + ImVec2 ItemInnerSpacing; // Horizontal and vertical spacing between within elements of a composed widget (e.g. a slider and its label) + ImVec2 TouchExtraPadding; // Expand reactive bounding box for touch-based system where touch position is not accurate enough. Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget. So don't grow this too much! + ImVec2 AutoFitPadding; // Extra space after auto-fit (double-clicking on resize grip) + float WindowFillAlphaDefault; // Default alpha of window background, if not specified in ImGui::Begin() + float IndentSpacing; // Horizontal indentation when e.g. entering a tree node + float ColumnsMinSpacing; // Minimum horizontal spacing between two columns + float ScrollbarWidth; // Width of the vertical scrollbar + float GrabMinSize; // Minimum width/height of a slider or scrollbar grab + ImVec2 DisplaySafeAreaPadding; // Window positions are clamped to be visible within the display area. If you cannot see the edge of your screen (e.g. on a TV) increase the safe area padding. + ImVec4 Colors[ImGuiCol_COUNT]; + + IMGUI_API ImGuiStyle(); +}; + +// This is where your app communicate with ImGui. Call ImGui::GetIO() to access. +// Read 'Programmer guide' section in .cpp file for general usage. +struct ImGuiIO +{ + //------------------------------------------------------------------ + // Settings (fill once) // Default value: + //------------------------------------------------------------------ + + ImVec2 DisplaySize; // // Display size, in pixels. For clamping windows positions. + float DeltaTime; // = 1.0f/60.0f // Time elapsed since last frame, in seconds. + float IniSavingRate; // = 5.0f // Maximum time between saving positions/sizes to .ini file, in seconds. + const char* IniFilename; // = "imgui.ini" // Path to .ini file. NULL to disable .ini saving. + const char* LogFilename; // = "imgui_log.txt" // Path to .log file (default parameter to ImGui::LogToFile when no file is specified). + float MouseDoubleClickTime; // = 0.30f // Time for a double-click, in seconds. + float MouseDoubleClickMaxDist; // = 6.0f // Distance threshold to stay in to validate a double-click, in pixels. + float MouseDragThreshold; // = 6.0f // Distance threshold before considering we are dragging + int KeyMap[ImGuiKey_COUNT]; // // Map of indices into the KeysDown[512] entries array + void* UserData; // = NULL // Store your own data for retrieval by callbacks. + + ImFontAtlas* Fonts; // // Load and assemble one or more fonts into a single tightly packed texture. Output to Fonts array. + float FontGlobalScale; // = 1.0f // Global scale all fonts + bool FontAllowUserScaling; // = false // Allow user scaling text of individual window with CTRL+Wheel. + ImVec2 DisplayVisibleMin; // (0.0f,0.0f) // If you use DisplaySize as a virtual space larger than your screen, set DisplayVisibleMin/Max to the visible area. + ImVec2 DisplayVisibleMax; // (0.0f,0.0f) // If the values are the same, we defaults to Min=(0.0f) and Max=DisplaySize + + //------------------------------------------------------------------ + // User Functions + //------------------------------------------------------------------ + + // REQUIRED: rendering function. + // See example code if you are unsure of how to implement this. + void (*RenderDrawListsFn)(ImDrawList** const draw_lists, int count); + + // Optional: access OS clipboard + // (default to use native Win32 clipboard on Windows, otherwise uses a private clipboard. Override to access OS clipboard on other architectures) + const char* (*GetClipboardTextFn)(); + void (*SetClipboardTextFn)(const char* text); + + // Optional: override memory allocations. MemFreeFn() may be called with a NULL pointer. + // (default to posix malloc/free) + void* (*MemAllocFn)(size_t sz); + void (*MemFreeFn)(void* ptr); + + // Optional: notify OS Input Method Editor of the screen position of your cursor for text input position (e.g. when using Japanese/Chinese IME in Windows) + // (default to use native imm32 api on Windows) + void (*ImeSetInputScreenPosFn)(int x, int y); + void* ImeWindowHandle; // (Windows) Set this to your HWND to get automatic IME cursor positioning. + + //------------------------------------------------------------------ + // Input - Fill before calling NewFrame() + //------------------------------------------------------------------ + + ImVec2 MousePos; // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.) + bool MouseDown[5]; // Mouse buttons. ImGui itself only uses button 0 (left button). Others buttons allows to track if mouse is being used by your application + available to user as a convenience via IsMouse** API. + float MouseWheel; // Mouse wheel: 1 unit scrolls about 5 lines text. + bool MouseDrawCursor; // Request ImGui to draw a mouse cursor for you (if you are on a platform without a mouse cursor). + bool KeyCtrl; // Keyboard modifier pressed: Control + bool KeyShift; // Keyboard modifier pressed: Shift + bool KeyAlt; // Keyboard modifier pressed: Alt + bool KeysDown[512]; // Keyboard keys that are pressed (in whatever storage order you naturally have access to keyboard data) + ImWchar InputCharacters[16+1]; // List of characters input (translated by user from keypress+keyboard state). Fill using AddInputCharacter() helper. + + // Function + IMGUI_API void AddInputCharacter(ImWchar c); // Helper to add a new character into InputCharacters[] + + //------------------------------------------------------------------ + // Output - Retrieve after calling NewFrame(), you can use them to discard inputs or hide them from the rest of your application + //------------------------------------------------------------------ + + bool WantCaptureMouse; // Mouse is hovering a window or widget is active (= ImGui will use your mouse input) + bool WantCaptureKeyboard; // Widget is active (= ImGui will use your keyboard input) + float Framerate; // Framerate estimation, in frame per second. Rolling average estimation based on IO.DeltaTime over 120 frames + int MetricsRenderVertices; // Vertices processed during last call to Render() + + //------------------------------------------------------------------ + // [Internal] ImGui will maintain those fields for you + //------------------------------------------------------------------ + + ImVec2 MousePosPrev; // Previous mouse position + ImVec2 MouseDelta; // Mouse delta. Note that this is zero if either current or previous position are negative to allow mouse enabling/disabling. + bool MouseClicked[5]; // Mouse button went from !Down to Down + ImVec2 MouseClickedPos[5]; // Position at time of clicking + float MouseClickedTime[5]; // Time of last click (used to figure out double-click) + bool MouseDoubleClicked[5]; // Has mouse button been double-clicked? + bool MouseDownOwned[5]; // Track if button was clicked inside a window. We don't request mouse capture from the application if click started outside ImGui bounds. + float MouseDownTime[5]; // Time the mouse button has been down + float MouseDragMaxDistanceSqr[5]; // Squared maximum distance of how much mouse has traveled from the click point + float KeysDownTime[512]; // Time the keyboard key has been down + + IMGUI_API ImGuiIO(); +}; + +//----------------------------------------------------------------------------- +// Helpers +//----------------------------------------------------------------------------- + +// Helper: execute a block of code once a frame only +// Convenient if you want to quickly create an UI within deep-nested code that runs multiple times every frame. +// Usage: +// IMGUI_ONCE_UPON_A_FRAME +// { +// // code block will be executed one per frame +// } +// Attention! the macro expands into 2 statement so make sure you don't use it within e.g. an if() statement without curly braces. +#define IMGUI_ONCE_UPON_A_FRAME static ImGuiOnceUponAFrame imgui_oaf##__LINE__; if (imgui_oaf##__LINE__) +struct ImGuiOnceUponAFrame +{ + ImGuiOnceUponAFrame() { RefFrame = -1; } + mutable int RefFrame; + operator bool() const { const int current_frame = ImGui::GetFrameCount(); if (RefFrame == current_frame) return false; RefFrame = current_frame; return true; } +}; + +// Helper: Parse and apply text filters. In format "aaaaa[,bbbb][,ccccc]" +struct ImGuiTextFilter +{ + struct TextRange + { + const char* b; + const char* e; + + TextRange() { b = e = NULL; } + TextRange(const char* _b, const char* _e) { b = _b; e = _e; } + const char* begin() const { return b; } + const char* end() const { return e; } + bool empty() const { return b == e; } + char front() const { return *b; } + static bool isblank(char c) { return c == ' ' || c == '\t'; } + void trim_blanks() { while (b < e && isblank(*b)) b++; while (e > b && isblank(*(e-1))) e--; } + IMGUI_API void split(char separator, ImVector& out); + }; + + char InputBuf[256]; + ImVector Filters; + int CountGrep; + + ImGuiTextFilter(const char* default_filter = ""); + void Clear() { InputBuf[0] = 0; Build(); } + void Draw(const char* label = "Filter (inc,-exc)", float width = -1.0f); // Helper calling InputText+Build + bool PassFilter(const char* val) const; + bool IsActive() const { return !Filters.empty(); } + IMGUI_API void Build(); +}; + +// Helper: Text buffer for logging/accumulating text +struct ImGuiTextBuffer +{ + ImVector Buf; + + ImGuiTextBuffer() { Buf.push_back(0); } + const char* begin() const { return &Buf.front(); } + const char* end() const { return &Buf.back(); } // Buf is zero-terminated, so end() will point on the zero-terminator + size_t size() const { return Buf.size()-1; } + bool empty() { return size() >= 1; } + void clear() { Buf.clear(); Buf.push_back(0); } + IMGUI_API void append(const char* fmt, ...); + IMGUI_API void appendv(const char* fmt, va_list args); +}; + +// Helper: Key->value storage +// - Store collapse state for a tree (Int 0/1) +// - Store color edit options (Int using values in ImGuiColorEditMode enum). +// - Custom user storage for temporary values. +// Typically you don't have to worry about this since a storage is held within each Window. +// Declare your own storage if: +// - You want to manipulate the open/close state of a particular sub-tree in your interface (tree node uses Int 0/1 to store their state). +// - You want to store custom debug data easily without adding or editing structures in your code. +struct ImGuiStorage +{ + struct Pair + { + ImGuiID key; + union { int val_i; float val_f; void* val_p; }; + Pair(ImGuiID _key, int _val_i) { key = _key; val_i = _val_i; } + Pair(ImGuiID _key, float _val_f) { key = _key; val_f = _val_f; } + Pair(ImGuiID _key, void* _val_p) { key = _key; val_p = _val_p; } + }; + ImVector Data; + + // - Get***() functions find pair, never add/allocate. Pairs are sorted so a query is O(log N) + // - Set***() functions find pair, insertion on demand if missing. + // - Sorted insertion is costly but should amortize. A typical frame shouldn't need to insert any new pair. + IMGUI_API void Clear(); + IMGUI_API int GetInt(ImGuiID key, int default_val = 0) const; + IMGUI_API void SetInt(ImGuiID key, int val); + IMGUI_API float GetFloat(ImGuiID key, float default_val = 0.0f) const; + IMGUI_API void SetFloat(ImGuiID key, float val); + IMGUI_API void* GetVoidPtr(ImGuiID key) const; // default_val is NULL + IMGUI_API void SetVoidPtr(ImGuiID key, void* val); + + // - Get***Ref() functions finds pair, insert on demand if missing, return pointer. Useful if you intend to do Get+Set. + // - References are only valid until a new value is added to the storage. Calling a Set***() function or a Get***Ref() function invalidates the pointer. + // - A typical use case where this is convenient: + // float* pvar = ImGui::GetFloatRef(key); ImGui::SliderFloat("var", pvar, 0, 100.0f); some_var += *pvar; + // - You can also use this to quickly create temporary editable values during a session of using Edit&Continue, without restarting your application. + IMGUI_API int* GetIntRef(ImGuiID key, int default_val = 0); + IMGUI_API float* GetFloatRef(ImGuiID key, float default_val = 0); + IMGUI_API void** GetVoidPtrRef(ImGuiID key, void* default_val = NULL); + + // Use on your own storage if you know only integer are being stored (open/close all tree nodes) + IMGUI_API void SetAllInt(int val); +}; + +// Shared state of InputText(), passed to callback when a ImGuiInputTextFlags_Callback* flag is used. +struct ImGuiTextEditCallbackData +{ + ImGuiInputTextFlags EventFlag; // One of ImGuiInputTextFlags_Callback* // Read-only + ImGuiInputTextFlags Flags; // What user passed to InputText() // Read-only + void* UserData; // What user passed to InputText() // Read-only + + // CharFilter event: + ImWchar EventChar; // Character input // Read-write (replace character or set to zero) + + // Completion,History,Always events: + ImGuiKey EventKey; // Key pressed (Up/Down/TAB) // Read-only + char* Buf; // Current text // Read-write (pointed data only) + size_t BufSize; // // Read-only + bool BufDirty; // Set if you modify Buf directly // Write + int CursorPos; // // Read-write + int SelectionStart; // // Read-write (== to SelectionEnd when no selection) + int SelectionEnd; // // Read-write + + // NB: calling those function loses selection. + void DeleteChars(int pos, int bytes_count); + void InsertChars(int pos, const char* text, const char* text_end = NULL); +}; + +// ImColor() is just a helper that implicity converts to either ImU32 (packed 4x1 byte) or ImVec4 (4x1 float) +// None of the ImGui API are using ImColor directly but you can use it as a convenience to pass colors in either formats. +struct ImColor +{ + ImVec4 Value; + + ImColor(int r, int g, int b, int a = 255) { Value.x = (float)r / 255.0f; Value.y = (float)g / 255.0f; Value.z = (float)b / 255.0f; Value.w = (float)a / 255.0f; } + ImColor(float r, float g, float b, float a = 1.0f) { Value.x = r; Value.y = g; Value.z = b; Value.w = a; } + ImColor(const ImVec4& col) { Value = col; } + operator ImU32() const { return ImGui::ColorConvertFloat4ToU32(Value); } + operator ImVec4() const { return Value; } + + static ImColor HSV(float h, float s, float v, float a = 1.0f) { float r,g,b; ImGui::ColorConvertHSVtoRGB(h, s, v, r, g, b); return ImColor(r,g,b,a); } +}; + +//----------------------------------------------------------------------------- +// Draw List +// Hold a series of drawing commands. The user provides a renderer for ImDrawList. +//----------------------------------------------------------------------------- + +// Draw callbacks for advanced uses. +// NB- You most likely DO NOT need to care about draw callbacks just to create your own widget or customized UI rendering (you can poke into the draw list for that) +// Draw callback are useful for example if you want to render a complex 3D scene inside a UI element. +// The expected behavior from your rendering loop is: +// if (cmd.user_callback != NULL) +// cmd.user_callback(parent_list, cmd); +// else +// RenderTriangles() +// It is up to you to decide if your rendering loop or the callback should be responsible for backup/restoring rendering state. +typedef void (*ImDrawCallback)(const ImDrawList* parent_list, const ImDrawCmd* cmd); + +// Typically, 1 command = 1 gpu draw call (unless command is a callback) +struct ImDrawCmd +{ + unsigned int vtx_count; // Number of vertices (multiple of 3) to be drawn as triangles. The vertices are stored in the callee ImDrawList's vtx_buffer[] array. + ImVec4 clip_rect; // Clipping rectangle (x1, y1, x2, y2) + ImTextureID texture_id; // User-provided texture ID. Set by user in ImfontAtlas::SetTexID() for fonts or passed to Image*() functions. Ignore if never using images or multiple fonts atlas. + ImDrawCallback user_callback; // If != NULL, call the function instead of rendering the vertices. vtx_count will be 0. clip_rect and texture_id will be set normally. + void* user_callback_data; // The draw callback code can access this. +}; + +// Vertex layout +#ifndef IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT +struct ImDrawVert +{ + ImVec2 pos; + ImVec2 uv; + ImU32 col; +}; +#else +// You can change the vertex format layout by defining IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT in imconfig.h +// The code expect ImVec2 pos (8 bytes), ImVec2 uv (8 bytes), ImU32 col (4 bytes), but you can re-order them or add other fields as needed to simplify integration in your engine. +// The type has to be described by the #define (you can either declare the struct or use a typedef) +IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT; +#endif + +// Draw command list +// This is the low-level list of polygons that ImGui functions are filling. At the end of the frame, all command lists are passed to your ImGuiIO::RenderDrawListFn function for rendering. +// At the moment, each ImGui window contains its own ImDrawList but they could potentially be merged in the future. +// If you want to add custom rendering within a window, you can use ImGui::GetWindowDrawList() to access the current draw list and add your own primitives. +// You can interleave normal ImGui:: calls and adding primitives to the current draw list. +// All positions are in screen coordinates (0,0=top-left, 1 pixel per unit). Primitives are always added to the list and not culled (culling is done at render time and at a higher-level by ImGui:: functions). +// Note that this only gives you access to rendering polygons. If your intent is to create custom widgets and the publicly exposed functions/data aren't sufficient, you can add code in imgui_user.inl +struct ImDrawList +{ + // This is what you have to render + ImVector commands; // Commands. Typically 1 command = 1 gpu draw call. + ImVector vtx_buffer; // Vertex buffer. Each command consume ImDrawCmd::vtx_count of those + + // [Internal to ImGui] + ImVector clip_rect_stack; // [Internal] + ImVector texture_id_stack; // [Internal] + ImDrawVert* vtx_write; // [Internal] point within vtx_buffer after each add command (to avoid using the ImVector<> operators too much) + + ImDrawList() { Clear(); } + IMGUI_API void Clear(); + IMGUI_API void ClearFreeMemory(); + IMGUI_API void PushClipRect(const ImVec4& clip_rect); // Scissoring. The values are x1, y1, x2, y2. + IMGUI_API void PushClipRectFullScreen(); + IMGUI_API void PopClipRect(); + IMGUI_API void PushTextureID(const ImTextureID& texture_id); + IMGUI_API void PopTextureID(); + + // Primitives + IMGUI_API void AddLine(const ImVec2& a, const ImVec2& b, ImU32 col, float thickness = 1.0f); + IMGUI_API void AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners = 0x0F); + IMGUI_API void AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners = 0x0F); + IMGUI_API void AddTriangleFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col); + IMGUI_API void AddCircle(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12); + IMGUI_API void AddCircleFilled(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12); + IMGUI_API void AddArcFast(const ImVec2& center, float radius, ImU32 col, int a_min_12, int a_max_12, bool filled = false, const ImVec2& third_point_offset = ImVec2(0,0)); // Angles in 0..12 range + IMGUI_API void AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL, float wrap_width = 0.0f, const ImVec2* cpu_clip_max = NULL); + IMGUI_API void AddImage(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv0, const ImVec2& uv1, ImU32 col = 0xFFFFFFFF); + + // Advanced + IMGUI_API void AddCallback(ImDrawCallback callback, void* callback_data); // Your rendering function must check for 'user_callback' in ImDrawCmd and call the function instead of rendering triangles. + IMGUI_API void AddDrawCmd(); // This is useful if you need to forcefully create a new draw call (to allow for dependent rendering / blending). Otherwise primitives are merged into the same draw-call as much as possible + + // Internal helpers + IMGUI_API void PrimReserve(unsigned int vtx_count); + IMGUI_API void PrimTriangle(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col); + IMGUI_API void PrimRect(const ImVec2& a, const ImVec2& b, ImU32 col); + IMGUI_API void PrimRectUV(const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, ImU32 col); + IMGUI_API void PrimQuad(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, ImU32 col); + IMGUI_API void PrimLine(const ImVec2& a, const ImVec2& b, ImU32 col, float thickness = 1.0f); + IMGUI_API void UpdateClipRect(); + IMGUI_API void UpdateTextureID(); + IMGUI_API void PrimVtx(const ImVec2& pos, const ImVec2& uv, ImU32 col) { vtx_write->pos = pos; vtx_write->uv = uv; vtx_write->col = col; vtx_write++; } +}; + +// Load and rasterize multiple TTF fonts into a same texture. +// Sharing a texture for multiple fonts allows us to reduce the number of draw calls during rendering. +// We also add custom graphic data into the texture that serves for ImGui. +// 1. (Optional) Call AddFont*** functions. If you don't call any, the default font will be loaded for you. +// 2. Call GetTexDataAsAlpha8() or GetTexDataAsRGBA32() to build and retrieve pixels data. +// 3. Upload the pixels data into a texture within your graphics system. +// 4. Call SetTexID(my_tex_id); and pass the pointer/identifier to your texture. This value will be passed back to you during rendering to identify the texture. +// 5. Call ClearTexData() to free textures memory on the heap. +struct ImFontAtlas +{ + IMGUI_API ImFontAtlas(); + IMGUI_API ~ImFontAtlas(); + IMGUI_API ImFont* AddFontDefault(); + IMGUI_API ImFont* AddFontFromFileTTF(const char* filename, float size_pixels, const ImWchar* glyph_ranges = NULL, int font_no = 0); + IMGUI_API ImFont* AddFontFromMemoryTTF(void* in_ttf_data, unsigned int in_ttf_data_size, float size_pixels, const ImWchar* glyph_ranges = NULL, int font_no = 0); // Pass ownership of 'in_ttf_data' memory, will be deleted after build + IMGUI_API ImFont* AddFontFromMemoryCompressedTTF(const void* in_compressed_ttf_data, unsigned int in_compressed_ttf_data_size, float size_pixels, const ImWchar* glyph_ranges = NULL, int font_no = 0); // 'in_compressed_ttf_data' untouched and still owned by caller. compress with binary_to_compressed_c. + IMGUI_API void ClearTexData(); // Saves RAM once the texture has been copied to graphics memory. + IMGUI_API void Clear(); + + // Retrieve texture data + // User is in charge of copying the pixels into graphics memory, then call SetTextureUserID() + // After loading the texture into your graphic system, store your texture handle in 'TexID' (ignore if you aren't using multiple fonts nor images) + // RGBA32 format is provided for convenience and high compatibility, but note that all RGB pixels are white, so 75% of the memory is wasted. + // Pitch = Width * BytesPerPixels + IMGUI_API void GetTexDataAsAlpha8(unsigned char** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel = NULL); // 1 byte per-pixel + IMGUI_API void GetTexDataAsRGBA32(unsigned char** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel = NULL); // 4 bytes-per-pixel + IMGUI_API void SetTexID(void* id) { TexID = id; } + + // Helpers to retrieve list of common Unicode ranges (2 value per range, values are inclusive, zero-terminated list) + // (Those functions could be static but aren't so most users don't have to refer to the ImFontAtlas:: name ever if in their code; just using io.Fonts->) + IMGUI_API const ImWchar* GetGlyphRangesDefault(); // Basic Latin, Extended Latin + IMGUI_API const ImWchar* GetGlyphRangesJapanese(); // Default + Hiragana, Katakana, Half-Width, Selection of 1946 Ideographs + IMGUI_API const ImWchar* GetGlyphRangesChinese(); // Japanese + full set of about 21000 CJK Unified Ideographs + + // Members + // (Access texture data via GetTexData*() calls which will setup a default font for you.) + void* TexID; // User data to refer to the texture once it has been uploaded to user's graphic systems. It ia passed back to you during rendering. + unsigned char* TexPixelsAlpha8; // 1 component per pixel, each component is unsigned 8-bit. Total size = TexWidth * TexHeight + unsigned int* TexPixelsRGBA32; // 4 component per pixel, each component is unsigned 8-bit. Total size = TexWidth * TexHeight * 4 + int TexWidth; + int TexHeight; + ImVec2 TexUvWhitePixel; // Texture coordinates to a white pixel (part of the TexExtraData block) + ImVector Fonts; + + // Private + struct ImFontAtlasData; + ImVector InputData; // Internal data + IMGUI_API bool Build(); // Build pixels data. This is automatically for you by the GetTexData*** functions. + IMGUI_API void ClearInputData(); // Clear the input TTF data. + IMGUI_API void RenderCustomTexData(int pass, void* rects); +}; + +// TTF font loading and rendering +// ImFontAtlas automatically loads a default embedded font for you when you call GetTexDataAsAlpha8() or GetTexDataAsRGBA32(). +// Kerning isn't supported. At the moment some ImGui code does per-character CalcTextSize calls, need something more state-ful. +struct ImFont +{ + // Members: Settings + float FontSize; // // Height of characters, set during loading (don't change after loading) + float Scale; // = 1.0f // Base font scale, multiplied by the per-window font scale which you can adjust with SetFontScale() + ImVec2 DisplayOffset; // = (0.0f,0.0f) // Offset font rendering by xx pixels + ImWchar FallbackChar; // = '?' // Replacement glyph if one isn't found. Only set via SetFallbackChar() + + // Members: Runtime data + struct Glyph + { + ImWchar Codepoint; + signed short XAdvance; + signed short Width, Height; + signed short XOffset, YOffset; + float U0, V0, U1, V1; // Texture coordinates + }; + ImFontAtlas* ContainerAtlas; // What we has been loaded into + ImVector Glyphs; + const Glyph* FallbackGlyph; // == FindGlyph(FontFallbackChar) + float FallbackXAdvance; // + ImVector IndexXAdvance; // Glyphs->XAdvance directly indexable (for CalcTextSize functions which are often bottleneck in large UI) + ImVector IndexLookup; // Index glyphs by Unicode code-point + + // Methods + IMGUI_API ImFont(); + IMGUI_API ~ImFont(); + IMGUI_API void Clear(); + IMGUI_API void BuildLookupTable(); + IMGUI_API const Glyph* FindGlyph(unsigned short c) const; + IMGUI_API void SetFallbackChar(ImWchar c); + IMGUI_API bool IsLoaded() const { return ContainerAtlas != NULL; } + + // 'max_width' stops rendering after a certain width (could be turned into a 2d size). FLT_MAX to disable. + // 'wrap_width' enable automatic word-wrapping across multiple lines to fit into given width. 0.0f to disable. + IMGUI_API ImVec2 CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end = NULL, const char** remaining = NULL) const; // utf8 + IMGUI_API ImVec2 CalcTextSizeW(float size, float max_width, const ImWchar* text_begin, const ImWchar* text_end, const ImWchar** remaining = NULL) const; // wchar + IMGUI_API void RenderText(float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, ImDrawList* draw_list, float wrap_width = 0.0f, const ImVec2* cpu_clip_max = NULL) const; + IMGUI_API const char* CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) const; +}; + +//---- Include imgui_user.h at the end of imgui.h +//---- So you can include code that extends ImGui using any of the types declared above. +//---- (also convenient for user to only explicitly include vanilla imgui.h) +#ifdef IMGUI_INCLUDE_IMGUI_USER_H +#include "imgui_user.h" +#endif diff --git a/testbed/imgui/stb_rect_pack.h b/testbed/imgui/stb_rect_pack.h new file mode 100644 index 00000000..eb0ef2f2 --- /dev/null +++ b/testbed/imgui/stb_rect_pack.h @@ -0,0 +1,547 @@ +// stb_rect_pack.h - v0.05 - public domain - rectangle packing +// Sean Barrett 2014 +// +// Useful for e.g. packing rectangular textures into an atlas. +// Does not do rotation. +// +// Not necessarily the awesomest packing method, but better than +// the totally naive one in stb_truetype (which is primarily what +// this is meant to replace). +// +// Has only had a few tests run, may have issues. +// +// More docs to come. +// +// No memory allocations; uses qsort() and assert() from stdlib. +// +// This library currently uses the Skyline Bottom-Left algorithm. +// +// Please note: better rectangle packers are welcome! Please +// implement them to the same API, but with a different init +// function. +// +// Version history: +// +// 0.05: added STBRP_ASSERT to allow replacing assert +// 0.04: fixed minor bug in STBRP_LARGE_RECTS support +// 0.01: initial release + +////////////////////////////////////////////////////////////////////////////// +// +// INCLUDE SECTION +// + +#ifndef STB_INCLUDE_STB_RECT_PACK_H +#define STB_INCLUDE_STB_RECT_PACK_H + +#define STB_RECT_PACK_VERSION 1 + +#ifdef STBRP_STATIC +#define STBRP_DEF static +#else +#define STBRP_DEF extern +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct stbrp_context stbrp_context; +typedef struct stbrp_node stbrp_node; +typedef struct stbrp_rect stbrp_rect; + +#ifdef STBRP_LARGE_RECTS +typedef int stbrp_coord; +#else +typedef unsigned short stbrp_coord; +#endif + +STBRP_DEF void stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects); +// Assign packed locations to rectangles. The rectangles are of type +// 'stbrp_rect' defined below, stored in the array 'rects', and there +// are 'num_rects' many of them. +// +// Rectangles which are successfully packed have the 'was_packed' flag +// set to a non-zero value and 'x' and 'y' store the minimum location +// on each axis (i.e. bottom-left in cartesian coordinates, top-left +// if you imagine y increasing downwards). Rectangles which do not fit +// have the 'was_packed' flag set to 0. +// +// You should not try to access the 'rects' array from another thread +// while this function is running, as the function temporarily reorders +// the array while it executes. +// +// To pack into another rectangle, you need to call stbrp_init_target +// again. To continue packing into the same rectangle, you can call +// this function again. Calling this multiple times with multiple rect +// arrays will probably produce worse packing results than calling it +// a single time with the full rectangle array, but the option is +// available. + +struct stbrp_rect +{ + // reserved for your use: + int id; + + // input: + stbrp_coord w, h; + + // output: + stbrp_coord x, y; + int was_packed; // non-zero if valid packing + +}; // 16 bytes, nominally + + +STBRP_DEF void stbrp_init_target (stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes); +// Initialize a rectangle packer to: +// pack a rectangle that is 'width' by 'height' in dimensions +// using temporary storage provided by the array 'nodes', which is 'num_nodes' long +// +// You must call this function every time you start packing into a new target. +// +// There is no "shutdown" function. The 'nodes' memory must stay valid for +// the following stbrp_pack_rects() call (or calls), but can be freed after +// the call (or calls) finish. +// +// Note: to guarantee best results, either: +// 1. make sure 'num_nodes' >= 'width' +// or 2. call stbrp_allow_out_of_mem() defined below with 'allow_out_of_mem = 1' +// +// If you don't do either of the above things, widths will be quantized to multiples +// of small integers to guarantee the algorithm doesn't run out of temporary storage. +// +// If you do #2, then the non-quantized algorithm will be used, but the algorithm +// may run out of temporary storage and be unable to pack some rectangles. + +STBRP_DEF void stbrp_setup_allow_out_of_mem (stbrp_context *context, int allow_out_of_mem); +// Optionally call this function after init but before doing any packing to +// change the handling of the out-of-temp-memory scenario, described above. +// If you call init again, this will be reset to the default (false). + + +STBRP_DEF void stbrp_setup_heuristic (stbrp_context *context, int heuristic); +// Optionally select which packing heuristic the library should use. Different +// heuristics will produce better/worse results for different data sets. +// If you call init again, this will be reset to the default. + +enum +{ + STBRP_HEURISTIC_Skyline_default=0, + STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default, + STBRP_HEURISTIC_Skyline_BF_sortHeight +}; + + +////////////////////////////////////////////////////////////////////////////// +// +// the details of the following structures don't matter to you, but they must +// be visible so you can handle the memory allocations for them + +struct stbrp_node +{ + stbrp_coord x,y; + stbrp_node *next; +}; + +struct stbrp_context +{ + int width; + int height; + int align; + int init_mode; + int heuristic; + int num_nodes; + stbrp_node *active_head; + stbrp_node *free_head; + stbrp_node extra[2]; // we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2' +}; + +#ifdef __cplusplus +} +#endif + +#endif + +////////////////////////////////////////////////////////////////////////////// +// +// IMPLEMENTATION SECTION +// + +#ifdef STB_RECT_PACK_IMPLEMENTATION +#include + +#ifndef STBRP_ASSERT +#include +#define STBRP_ASSERT assert +#endif + +enum +{ + STBRP__INIT_skyline = 1 +}; + +STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic) +{ + switch (context->init_mode) { + case STBRP__INIT_skyline: + STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight); + context->heuristic = heuristic; + break; + default: + STBRP_ASSERT(0); + } +} + +STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_out_of_mem) +{ + if (allow_out_of_mem) + // if it's ok to run out of memory, then don't bother aligning them; + // this gives better packing, but may fail due to OOM (even though + // the rectangles easily fit). @TODO a smarter approach would be to only + // quantize once we've hit OOM, then we could get rid of this parameter. + context->align = 1; + else { + // if it's not ok to run out of memory, then quantize the widths + // so that num_nodes is always enough nodes. + // + // I.e. num_nodes * align >= width + // align >= width / num_nodes + // align = ceil(width/num_nodes) + + context->align = (context->width + context->num_nodes-1) / context->num_nodes; + } +} + +STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes) +{ + int i; +#ifndef STBRP_LARGE_RECTS + STBRP_ASSERT(width <= 0xffff && height <= 0xffff); +#endif + + for (i=0; i < num_nodes-1; ++i) + nodes[i].next = &nodes[i+1]; + nodes[i].next = NULL; + context->init_mode = STBRP__INIT_skyline; + context->heuristic = STBRP_HEURISTIC_Skyline_default; + context->free_head = &nodes[0]; + context->active_head = &context->extra[0]; + context->width = width; + context->height = height; + context->num_nodes = num_nodes; + stbrp_setup_allow_out_of_mem(context, 0); + + // node 0 is the full width, node 1 is the sentinel (lets us not store width explicitly) + context->extra[0].x = 0; + context->extra[0].y = 0; + context->extra[0].next = &context->extra[1]; + context->extra[1].x = (stbrp_coord) width; +#ifdef STBRP_LARGE_RECTS + context->extra[1].y = (1<<30); +#else + context->extra[1].y = 65535; +#endif + context->extra[1].next = NULL; +} + +// find minimum y position if it starts at x1 +static int stbrp__skyline_find_min_y(stbrp_context *c, stbrp_node *first, int x0, int width, int *pwaste) +{ + (void)c; + stbrp_node *node = first; + int x1 = x0 + width; + int min_y, visited_width, waste_area; + STBRP_ASSERT(first->x <= x0); + + #if 0 + // skip in case we're past the node + while (node->next->x <= x0) + ++node; + #else + STBRP_ASSERT(node->next->x > x0); // we ended up handling this in the caller for efficiency + #endif + + STBRP_ASSERT(node->x <= x0); + + min_y = 0; + waste_area = 0; + visited_width = 0; + while (node->x < x1) { + if (node->y > min_y) { + // raise min_y higher. + // we've accounted for all waste up to min_y, + // but we'll now add more waste for everything we've visted + waste_area += visited_width * (node->y - min_y); + min_y = node->y; + // the first time through, visited_width might be reduced + if (node->x < x0) + visited_width += node->next->x - x0; + else + visited_width += node->next->x - node->x; + } else { + // add waste area + int under_width = node->next->x - node->x; + if (under_width + visited_width > width) + under_width = width - visited_width; + waste_area += under_width * (min_y - node->y); + visited_width += under_width; + } + node = node->next; + } + + *pwaste = waste_area; + return min_y; +} + +typedef struct +{ + int x,y; + stbrp_node **prev_link; +} stbrp__findresult; + +static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int width, int height) +{ + int best_waste = (1<<30), best_x, best_y = (1 << 30); + stbrp__findresult fr; + stbrp_node **prev, *node, *tail, **best = NULL; + + // align to multiple of c->align + width = (width + c->align - 1); + width -= width % c->align; + STBRP_ASSERT(width % c->align == 0); + + node = c->active_head; + prev = &c->active_head; + while (node->x + width <= c->width) { + int y,waste; + y = stbrp__skyline_find_min_y(c, node, node->x, width, &waste); + if (c->heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight) { // actually just want to test BL + // bottom left + if (y < best_y) { + best_y = y; + best = prev; + } + } else { + // best-fit + if (y + height <= c->height) { + // can only use it if it first vertically + if (y < best_y || (y == best_y && waste < best_waste)) { + best_y = y; + best_waste = waste; + best = prev; + } + } + } + prev = &node->next; + node = node->next; + } + + best_x = (best == NULL) ? 0 : (*best)->x; + + // if doing best-fit (BF), we also have to try aligning right edge to each node position + // + // e.g, if fitting + // + // ____________________ + // |____________________| + // + // into + // + // | | + // | ____________| + // |____________| + // + // then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned + // + // This makes BF take about 2x the time + + if (c->heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight) { + tail = c->active_head; + node = c->active_head; + prev = &c->active_head; + // find first node that's admissible + while (tail->x < width) + tail = tail->next; + while (tail) { + int xpos = tail->x - width; + int y,waste; + STBRP_ASSERT(xpos >= 0); + // find the left position that matches this + while (node->next->x <= xpos) { + prev = &node->next; + node = node->next; + } + STBRP_ASSERT(node->next->x > xpos && node->x <= xpos); + y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste); + if (y + height < c->height) { + if (y <= best_y) { + if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) { + best_x = xpos; + STBRP_ASSERT(y <= best_y); + best_y = y; + best_waste = waste; + best = prev; + } + } + } + tail = tail->next; + } + } + + fr.prev_link = best; + fr.x = best_x; + fr.y = best_y; + return fr; +} + +static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, int width, int height) +{ + // find best position according to heuristic + stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height); + stbrp_node *node, *cur; + + // bail if: + // 1. it failed + // 2. the best node doesn't fit (we don't always check this) + // 3. we're out of memory + if (res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL) { + res.prev_link = NULL; + return res; + } + + // on success, create new node + node = context->free_head; + node->x = (stbrp_coord) res.x; + node->y = (stbrp_coord) (res.y + height); + + context->free_head = node->next; + + // insert the new node into the right starting point, and + // let 'cur' point to the remaining nodes needing to be + // stiched back in + + cur = *res.prev_link; + if (cur->x < res.x) { + // preserve the existing one, so start testing with the next one + stbrp_node *next = cur->next; + cur->next = node; + cur = next; + } else { + *res.prev_link = node; + } + + // from here, traverse cur and free the nodes, until we get to one + // that shouldn't be freed + while (cur->next && cur->next->x <= res.x + width) { + stbrp_node *next = cur->next; + // move the current node to the free list + cur->next = context->free_head; + context->free_head = cur; + cur = next; + } + + // stitch the list back in + node->next = cur; + + if (cur->x < res.x + width) + cur->x = (stbrp_coord) (res.x + width); + +#ifdef _DEBUG + cur = context->active_head; + while (cur->x < context->width) { + STBRP_ASSERT(cur->x < cur->next->x); + cur = cur->next; + } + STBRP_ASSERT(cur->next == NULL); + + { + stbrp_node *L1 = NULL, *L2 = NULL; + int count=0; + cur = context->active_head; + while (cur) { + L1 = cur; + cur = cur->next; + ++count; + } + cur = context->free_head; + while (cur) { + L2 = cur; + cur = cur->next; + ++count; + } + STBRP_ASSERT(count == context->num_nodes+2); + } +#endif + + return res; +} + +static int rect_height_compare(const void *a, const void *b) +{ + stbrp_rect *p = (stbrp_rect *) a; + stbrp_rect *q = (stbrp_rect *) b; + if (p->h > q->h) + return -1; + if (p->h < q->h) + return 1; + return (p->w > q->w) ? -1 : (p->w < q->w); +} + +static int rect_width_compare(const void *a, const void *b) +{ + stbrp_rect *p = (stbrp_rect *) a; + stbrp_rect *q = (stbrp_rect *) b; + if (p->w > q->w) + return -1; + if (p->w < q->w) + return 1; + return (p->h > q->h) ? -1 : (p->h < q->h); +} + +static int rect_original_order(const void *a, const void *b) +{ + stbrp_rect *p = (stbrp_rect *) a; + stbrp_rect *q = (stbrp_rect *) b; + return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed); +} + +#ifdef STBRP_LARGE_RECTS +#define STBRP__MAXVAL 0xffffffff +#else +#define STBRP__MAXVAL 0xffff +#endif + +STBRP_DEF void stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects) +{ + int i; + + // we use the 'was_packed' field internally to allow sorting/unsorting + for (i=0; i < num_rects; ++i) { + rects[i].was_packed = i; + #ifndef STBRP_LARGE_RECTS + STBRP_ASSERT(rects[i].w <= 0xffff && rects[i].h <= 0xffff); + #endif + } + + // sort according to heuristic + qsort(rects, num_rects, sizeof(rects[0]), rect_height_compare); + + for (i=0; i < num_rects; ++i) { + stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h); + if (fr.prev_link) { + rects[i].x = (stbrp_coord) fr.x; + rects[i].y = (stbrp_coord) fr.y; + } else { + rects[i].x = rects[i].y = STBRP__MAXVAL; + } + } + + // unsort + qsort(rects, num_rects, sizeof(rects[0]), rect_original_order); + + // set was_packed flags + for (i=0; i < num_rects; ++i) + rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL); +} +#endif diff --git a/testbed/imgui/stb_textedit.h b/testbed/imgui/stb_textedit.h new file mode 100644 index 00000000..5aa79f02 --- /dev/null +++ b/testbed/imgui/stb_textedit.h @@ -0,0 +1,1254 @@ +// stb_textedit.h - v1.4 - public domain - Sean Barrett +// Development of this library was sponsored by RAD Game Tools +// +// This C header file implements the guts of a multi-line text-editing +// widget; you implement display, word-wrapping, and low-level string +// insertion/deletion, and stb_textedit will map user inputs into +// insertions & deletions, plus updates to the cursor position, +// selection state, and undo state. +// +// It is intended for use in games and other systems that need to build +// their own custom widgets and which do not have heavy text-editing +// requirements (this library is not recommended for use for editing large +// texts, as its performance does not scale and it has limited undo). +// +// Non-trivial behaviors are modelled after Windows text controls. +// +// +// LICENSE +// +// This software has been placed in the public domain by its author. +// Where that dedication is not recognized, you are granted a perpetual, +// irrevocable license to copy and modify this file as you see fit. +// +// +// DEPENDENCIES +// +// Uses the C runtime function 'memmove'. Uses no other functions. +// Performs no runtime allocations. +// +// +// VERSION HISTORY +// +// 1.4 (2014-08-17) fix signed/unsigned warnings +// 1.3 (2014-06-19) fix mouse clicking to round to nearest char boundary +// 1.2 (2014-05-27) fix some RAD types that had crept into the new code +// 1.1 (2013-12-15) move-by-word (requires STB_TEXTEDIT_IS_SPACE ) +// 1.0 (2012-07-26) improve documentation, initial public release +// 0.3 (2012-02-24) bugfixes, single-line mode; insert mode +// 0.2 (2011-11-28) fixes to undo/redo +// 0.1 (2010-07-08) initial version +// +// ADDITIONAL CONTRIBUTORS +// +// Ulf Winklemann: move-by-word in 1.1 +// Scott Graham: mouse selection bugfix in 1.3 +// +// USAGE +// +// This file behaves differently depending on what symbols you define +// before including it. +// +// +// Header-file mode: +// +// If you do not define STB_TEXTEDIT_IMPLEMENTATION before including this, +// it will operate in "header file" mode. In this mode, it declares a +// single public symbol, STB_TexteditState, which encapsulates the current +// state of a text widget (except for the string, which you will store +// separately). +// +// To compile in this mode, you must define STB_TEXTEDIT_CHARTYPE to a +// primitive type that defines a single character (e.g. char, wchar_t, etc). +// +// To save space or increase undo-ability, you can optionally define the +// following things that are used by the undo system: +// +// STB_TEXTEDIT_POSITIONTYPE small int type encoding a valid cursor position +// STB_TEXTEDIT_UNDOSTATECOUNT the number of undo states to allow +// STB_TEXTEDIT_UNDOCHARCOUNT the number of characters to store in the undo buffer +// +// If you don't define these, they are set to permissive types and +// moderate sizes. The undo system does no memory allocations, so +// it grows STB_TexteditState by the worst-case storage which is (in bytes): +// +// [4 + sizeof(STB_TEXTEDIT_POSITIONTYPE)] * STB_TEXTEDIT_UNDOSTATE_COUNT +// + sizeof(STB_TEXTEDIT_CHARTYPE) * STB_TEXTEDIT_UNDOCHAR_COUNT +// +// +// Implementation mode: +// +// If you define STB_TEXTEDIT_IMPLEMENTATION before including this, it +// will compile the implementation of the text edit widget, depending +// on a large number of symbols which must be defined before the include. +// +// The implementation is defined only as static functions. You will then +// need to provide your own APIs in the same file which will access the +// static functions. +// +// The basic concept is that you provide a "string" object which +// behaves like an array of characters. stb_textedit uses indices to +// refer to positions in the string, implicitly representing positions +// in the displayed textedit. This is true for both plain text and +// rich text; even with rich text stb_truetype interacts with your +// code as if there was an array of all the displayed characters. +// +// Symbols that must be the same in header-file and implementation mode: +// +// STB_TEXTEDIT_CHARTYPE the character type +// STB_TEXTEDIT_POSITIONTYPE small type that a valid cursor position +// STB_TEXTEDIT_UNDOSTATECOUNT the number of undo states to allow +// STB_TEXTEDIT_UNDOCHARCOUNT the number of characters to store in the undo buffer +// +// Symbols you must define for implementation mode: +// +// STB_TEXTEDIT_STRING the type of object representing a string being edited, +// typically this is a wrapper object with other data you need +// +// STB_TEXTEDIT_STRINGLEN(obj) the length of the string (ideally O(1)) +// STB_TEXTEDIT_LAYOUTROW(&r,obj,n) returns the results of laying out a line of characters +// starting from character #n (see discussion below) +// STB_TEXTEDIT_GETWIDTH(obj,n,i) returns the pixel delta from the xpos of the i'th character +// to the xpos of the i+1'th char for a line of characters +// starting at character #n (i.e. accounts for kerning +// with previous char) +// STB_TEXTEDIT_KEYTOTEXT(k) maps a keyboard input to an insertable character +// (return type is int, -1 means not valid to insert) +// STB_TEXTEDIT_GETCHAR(obj,i) returns the i'th character of obj, 0-based +// STB_TEXTEDIT_NEWLINE the character returned by _GETCHAR() we recognize +// as manually wordwrapping for end-of-line positioning +// +// STB_TEXTEDIT_DELETECHARS(obj,i,n) delete n characters starting at i +// STB_TEXTEDIT_INSERTCHARS(obj,i,c*,n) insert n characters at i (pointed to by STB_TEXTEDIT_CHARTYPE*) +// +// STB_TEXTEDIT_K_SHIFT a power of two that is or'd in to a keyboard input to represent the shift key +// +// STB_TEXTEDIT_K_LEFT keyboard input to move cursor left +// STB_TEXTEDIT_K_RIGHT keyboard input to move cursor right +// STB_TEXTEDIT_K_UP keyboard input to move cursor up +// STB_TEXTEDIT_K_DOWN keyboard input to move cursor down +// STB_TEXTEDIT_K_LINESTART keyboard input to move cursor to start of line // e.g. HOME +// STB_TEXTEDIT_K_LINEEND keyboard input to move cursor to end of line // e.g. END +// STB_TEXTEDIT_K_TEXTSTART keyboard input to move cursor to start of text // e.g. ctrl-HOME +// STB_TEXTEDIT_K_TEXTEND keyboard input to move cursor to end of text // e.g. ctrl-END +// STB_TEXTEDIT_K_DELETE keyboard input to delete selection or character under cursor +// STB_TEXTEDIT_K_BACKSPACE keyboard input to delete selection or character left of cursor +// STB_TEXTEDIT_K_UNDO keyboard input to perform undo +// STB_TEXTEDIT_K_REDO keyboard input to perform redo +// +// Optional: +// STB_TEXTEDIT_K_INSERT keyboard input to toggle insert mode +// STB_TEXTEDIT_IS_SPACE(ch) true if character is whitespace (e.g. 'isspace'), +// required for WORDLEFT/WORDRIGHT +// STB_TEXTEDIT_K_WORDLEFT keyboard input to move cursor left one word // e.g. ctrl-LEFT +// STB_TEXTEDIT_K_WORDRIGHT keyboard input to move cursor right one word // e.g. ctrl-RIGHT +// +// Todo: +// STB_TEXTEDIT_K_PGUP keyboard input to move cursor up a page +// STB_TEXTEDIT_K_PGDOWN keyboard input to move cursor down a page +// +// Keyboard input must be encoded as a single integer value; e.g. a character code +// and some bitflags that represent shift states. to simplify the interface, SHIFT must +// be a bitflag, so we can test the shifted state of cursor movements to allow selection, +// i.e. (STB_TEXTED_K_RIGHT|STB_TEXTEDIT_K_SHIFT) should be shifted right-arrow. +// +// You can encode other things, such as CONTROL or ALT, in additional bits, and +// then test for their presence in e.g. STB_TEXTEDIT_K_WORDLEFT. For example, +// my Windows implementations add an additional CONTROL bit, and an additional KEYDOWN +// bit. Then all of the STB_TEXTEDIT_K_ values bitwise-or in the KEYDOWN bit, +// and I pass both WM_KEYDOWN and WM_CHAR events to the "key" function in the +// API below. The control keys will only match WM_KEYDOWN events because of the +// keydown bit I add, and STB_TEXTEDIT_KEYTOTEXT only tests for the KEYDOWN +// bit so it only decodes WM_CHAR events. +// +// STB_TEXTEDIT_LAYOUTROW returns information about the shape of one displayed +// row of characters assuming they start on the i'th character--the width and +// the height and the number of characters consumed. This allows this library +// to traverse the entire layout incrementally. You need to compute word-wrapping +// here. +// +// Each textfield keeps its own insert mode state, which is not how normal +// applications work. To keep an app-wide insert mode, update/copy the +// "insert_mode" field of STB_TexteditState before/after calling API functions. +// +// API +// +// void stb_textedit_initialize_state(STB_TexteditState *state, int is_single_line) +// +// void stb_textedit_click(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y) +// void stb_textedit_drag(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y) +// int stb_textedit_cut(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) +// int stb_textedit_paste(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE *text, int len) +// void stb_textedit_key(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int key) +// +// Each of these functions potentially updates the string and updates the +// state. +// +// initialize_state: +// set the textedit state to a known good default state when initially +// constructing the textedit. +// +// click: +// call this with the mouse x,y on a mouse down; it will update the cursor +// and reset the selection start/end to the cursor point. the x,y must +// be relative to the text widget, with (0,0) being the top left. +// +// drag: +// call this with the mouse x,y on a mouse drag/up; it will update the +// cursor and the selection end point +// +// cut: +// call this to delete the current selection; returns true if there was +// one. you should FIRST copy the current selection to the system paste buffer. +// (To copy, just copy the current selection out of the string yourself.) +// +// paste: +// call this to paste text at the current cursor point or over the current +// selection if there is one. +// +// key: +// call this for keyboard inputs sent to the textfield. you can use it +// for "key down" events or for "translated" key events. if you need to +// do both (as in Win32), or distinguish Unicode characters from control +// inputs, set a high bit to distinguish the two; then you can define the +// various definitions like STB_TEXTEDIT_K_LEFT have the is-key-event bit +// set, and make STB_TEXTEDIT_KEYTOCHAR check that the is-key-event bit is +// clear. +// +// When rendering, you can read the cursor position and selection state from +// the STB_TexteditState. +// +// +// Notes: +// +// This is designed to be usable in IMGUI, so it allows for the possibility of +// running in an IMGUI that has NOT cached the multi-line layout. For this +// reason, it provides an interface that is compatible with computing the +// layout incrementally--we try to make sure we make as few passes through +// as possible. (For example, to locate the mouse pointer in the text, we +// could define functions that return the X and Y positions of characters +// and binary search Y and then X, but if we're doing dynamic layout this +// will run the layout algorithm many times, so instead we manually search +// forward in one pass. Similar logic applies to e.g. up-arrow and +// down-arrow movement.) +// +// If it's run in a widget that *has* cached the layout, then this is less +// efficient, but it's not horrible on modern computers. But you wouldn't +// want to edit million-line files with it. + + +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//// +//// Header-file mode +//// +//// + +#ifndef INCLUDE_STB_TEXTEDIT_H +#define INCLUDE_STB_TEXTEDIT_H + +//////////////////////////////////////////////////////////////////////// +// +// STB_TexteditState +// +// Definition of STB_TexteditState which you should store +// per-textfield; it includes cursor position, selection state, +// and undo state. +// + +#ifndef STB_TEXTEDIT_UNDOSTATECOUNT +#define STB_TEXTEDIT_UNDOSTATECOUNT 99 +#endif +#ifndef STB_TEXTEDIT_UNDOCHARCOUNT +#define STB_TEXTEDIT_UNDOCHARCOUNT 999 +#endif +#ifndef STB_TEXTEDIT_CHARTYPE +#define STB_TEXTEDIT_CHARTYPE int +#endif +#ifndef STB_TEXTEDIT_POSITIONTYPE +#define STB_TEXTEDIT_POSITIONTYPE int +#endif + +typedef struct +{ + // private data + STB_TEXTEDIT_POSITIONTYPE where; + short insert_length; + short delete_length; + short char_storage; +} StbUndoRecord; + +typedef struct +{ + // private data + StbUndoRecord undo_rec [STB_TEXTEDIT_UNDOSTATECOUNT]; + STB_TEXTEDIT_CHARTYPE undo_char[STB_TEXTEDIT_UNDOCHARCOUNT]; + short undo_point, redo_point; + short undo_char_point, redo_char_point; +} StbUndoState; + +typedef struct +{ + ///////////////////// + // + // public data + // + + int cursor; + // position of the text cursor within the string + + int select_start; // selection start point + int select_end; + // selection start and end point in characters; if equal, no selection. + // note that start may be less than or greater than end (e.g. when + // dragging the mouse, start is where the initial click was, and you + // can drag in either direction) + + unsigned char insert_mode; + // each textfield keeps its own insert mode state. to keep an app-wide + // insert mode, copy this value in/out of the app state + + ///////////////////// + // + // private data + // + unsigned char cursor_at_end_of_line; // not implemented yet + unsigned char initialized; + unsigned char has_preferred_x; + unsigned char single_line; + unsigned char padding1, padding2, padding3; + float preferred_x; // this determines where the cursor up/down tries to seek to along x + StbUndoState undostate; +} STB_TexteditState; + + +//////////////////////////////////////////////////////////////////////// +// +// StbTexteditRow +// +// Result of layout query, used by stb_textedit to determine where +// the text in each row is. + +// result of layout query +typedef struct +{ + float x0,x1; // starting x location, end x location (allows for align=right, etc) + float baseline_y_delta; // position of baseline relative to previous row's baseline + float ymin,ymax; // height of row above and below baseline + int num_chars; +} StbTexteditRow; +#endif //INCLUDE_STB_TEXTEDIT_H + + +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//// +//// Implementation mode +//// +//// + + +// implementation isn't include-guarded, since it might have indirectly +// included just the "header" portion +#ifdef STB_TEXTEDIT_IMPLEMENTATION + +#include // memmove + + +///////////////////////////////////////////////////////////////////////////// +// +// Mouse input handling +// + +// traverse the layout to locate the nearest character to a display position +static int stb_text_locate_coord(STB_TEXTEDIT_STRING *str, float x, float y) +{ + StbTexteditRow r; + int n = STB_TEXTEDIT_STRINGLEN(str); + float base_y = 0, prev_x; + int i=0, k; + + if (y < 0) + return 0; + + r.x0 = r.x1 = 0; + r.ymin = r.ymax = 0; + r.num_chars = 0; + + // search rows to find one that straddles 'y' + while (i < n) { + STB_TEXTEDIT_LAYOUTROW(&r, str, i); + if (r.num_chars <= 0) + return n; + + if (y < base_y + r.ymax) + break; + + i += r.num_chars; + base_y += r.baseline_y_delta; + } + + // below all text, return 'after' last character + if (i >= n) + return n; + + // check if it's before the beginning of the line + if (x < r.x0) + return i; + + // check if it's before the end of the line + if (x < r.x1) { + // search characters in row for one that straddles 'x' + k = i; + prev_x = r.x0; + for (i=0; i < r.num_chars; ++i) { + float w = STB_TEXTEDIT_GETWIDTH(str, k, i); + if (x < prev_x+w) { + if (x < prev_x+w/2) + return k+i; + else + return k+i+1; + } + prev_x += w; + } + // shouldn't happen, but if it does, fall through to end-of-line case + } + + // if the last character is a newline, return that. otherwise return 'after' the last character + if (STB_TEXTEDIT_GETCHAR(str, i+r.num_chars-1) == STB_TEXTEDIT_NEWLINE) + return i+r.num_chars-1; + else + return i+r.num_chars; +} + +// API click: on mouse down, move the cursor to the clicked location, and reset the selection +static void stb_textedit_click(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y) +{ + state->cursor = stb_text_locate_coord(str, x, y); + state->select_start = state->cursor; + state->select_end = state->cursor; + state->has_preferred_x = 0; +} + +// API drag: on mouse drag, move the cursor and selection endpoint to the clicked location +static void stb_textedit_drag(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y) +{ + int p = stb_text_locate_coord(str, x, y); + state->cursor = state->select_end = p; +} + +///////////////////////////////////////////////////////////////////////////// +// +// Keyboard input handling +// + +// forward declarations +static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state); +static void stb_text_redo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state); +static void stb_text_makeundo_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length); +static void stb_text_makeundo_insert(STB_TexteditState *state, int where, int length); +static void stb_text_makeundo_replace(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length); + +typedef struct +{ + float x,y; // position of n'th character + float height; // height of line + int first_char, length; // first char of row, and length + int prev_first; // first char of previous row +} StbFindState; + +// find the x/y location of a character, and remember info about the previous row in +// case we get a move-up event (for page up, we'll have to rescan) +static void stb_textedit_find_charpos(StbFindState *find, STB_TEXTEDIT_STRING *str, int n, int single_line) +{ + StbTexteditRow r; + int prev_start = 0; + int z = STB_TEXTEDIT_STRINGLEN(str); + int i=0, first; + + if (n == z) { + // if it's at the end, then find the last line -- simpler than trying to + // explicitly handle this case in the regular code + if (single_line) { + STB_TEXTEDIT_LAYOUTROW(&r, str, 0); + find->y = 0; + find->first_char = 0; + find->length = z; + find->height = r.ymax - r.ymin; + find->x = r.x1; + } else { + find->y = 0; + find->x = 0; + find->height = 1; + while (i < z) { + STB_TEXTEDIT_LAYOUTROW(&r, str, i); + prev_start = i; + i += r.num_chars; + } + find->first_char = i; + find->length = 0; + find->prev_first = prev_start; + } + return; + } + + // search rows to find the one that straddles character n + find->y = 0; + + for(;;) { + STB_TEXTEDIT_LAYOUTROW(&r, str, i); + if (n < i + r.num_chars) + break; + prev_start = i; + i += r.num_chars; + find->y += r.baseline_y_delta; + } + + find->first_char = first = i; + find->length = r.num_chars; + find->height = r.ymax - r.ymin; + find->prev_first = prev_start; + + // now scan to find xpos + find->x = r.x0; + i = 0; + for (i=0; first+i < n; ++i) + find->x += STB_TEXTEDIT_GETWIDTH(str, first, i); +} + +#define STB_TEXT_HAS_SELECTION(s) ((s)->select_start != (s)->select_end) + +// make the selection/cursor state valid if client altered the string +static void stb_textedit_clamp(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) +{ + int n = STB_TEXTEDIT_STRINGLEN(str); + if (STB_TEXT_HAS_SELECTION(state)) { + if (state->select_start > n) state->select_start = n; + if (state->select_end > n) state->select_end = n; + // if clamping forced them to be equal, move the cursor to match + if (state->select_start == state->select_end) + state->cursor = state->select_start; + } + if (state->cursor > n) state->cursor = n; +} + +// delete characters while updating undo +static void stb_textedit_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int len) +{ + stb_text_makeundo_delete(str, state, where, len); + STB_TEXTEDIT_DELETECHARS(str, where, len); + state->has_preferred_x = 0; +} + +// delete the section +static void stb_textedit_delete_selection(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) +{ + stb_textedit_clamp(str, state); + if (STB_TEXT_HAS_SELECTION(state)) { + if (state->select_start < state->select_end) { + stb_textedit_delete(str, state, state->select_start, state->select_end - state->select_start); + state->select_end = state->cursor = state->select_start; + } else { + stb_textedit_delete(str, state, state->select_end, state->select_start - state->select_end); + state->select_start = state->cursor = state->select_end; + } + state->has_preferred_x = 0; + } +} + +// canoncialize the selection so start <= end +static void stb_textedit_sortselection(STB_TexteditState *state) +{ + if (state->select_end < state->select_start) { + int temp = state->select_end; + state->select_end = state->select_start; + state->select_start = temp; + } +} + +// move cursor to first character of selection +static void stb_textedit_move_to_first(STB_TexteditState *state) +{ + if (STB_TEXT_HAS_SELECTION(state)) { + stb_textedit_sortselection(state); + state->cursor = state->select_start; + state->select_end = state->select_start; + state->has_preferred_x = 0; + } +} + +// move cursor to last character of selection +static void stb_textedit_move_to_last(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) +{ + if (STB_TEXT_HAS_SELECTION(state)) { + stb_textedit_sortselection(state); + stb_textedit_clamp(str, state); + state->cursor = state->select_end; + state->select_start = state->select_end; + state->has_preferred_x = 0; + } +} + +#ifdef STB_TEXTEDIT_IS_SPACE +static int is_word_boundary( STB_TEXTEDIT_STRING *_str, int _idx ) +{ + return _idx > 0 ? (STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(_str,_idx-1) ) && !STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(_str, _idx) ) ) : 1; +} + +static int stb_textedit_move_to_word_previous( STB_TEXTEDIT_STRING *_str, STB_TexteditState *_state ) +{ + int c = _state->cursor - 1; + while( c >= 0 && !is_word_boundary( _str, c ) ) + --c; + + if( c < 0 ) + c = 0; + + return c; +} + +static int stb_textedit_move_to_word_next( STB_TEXTEDIT_STRING *_str, STB_TexteditState *_state ) +{ + const int len = STB_TEXTEDIT_STRINGLEN(_str); + int c = _state->cursor+1; + while( c < len && !is_word_boundary( _str, c ) ) + ++c; + + if( c > len ) + c = len; + + return c; +} +#endif + +// update selection and cursor to match each other +static void stb_textedit_prep_selection_at_cursor(STB_TexteditState *state) +{ + if (!STB_TEXT_HAS_SELECTION(state)) + state->select_start = state->select_end = state->cursor; + else + state->cursor = state->select_end; +} + +// API cut: delete selection +static int stb_textedit_cut(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) +{ + if (STB_TEXT_HAS_SELECTION(state)) { + stb_textedit_delete_selection(str,state); // implicity clamps + state->has_preferred_x = 0; + return 1; + } + return 0; +} + +// API paste: replace existing selection with passed-in text +static int stb_textedit_paste(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE const *ctext, int len) +{ + STB_TEXTEDIT_CHARTYPE *text = (STB_TEXTEDIT_CHARTYPE *) ctext; + // if there's a selection, the paste should delete it + stb_textedit_clamp(str, state); + stb_textedit_delete_selection(str,state); + // try to insert the characters + if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, text, len)) { + stb_text_makeundo_insert(state, state->cursor, len); + state->cursor += len; + state->has_preferred_x = 0; + return 1; + } + // remove the undo since we didn't actually insert the characters + if (state->undostate.undo_point) + --state->undostate.undo_point; + return 0; +} + +// API key: process a keyboard input +static void stb_textedit_key(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int key) +{ +retry: + switch (key) { + default: { + int c = STB_TEXTEDIT_KEYTOTEXT(key); + if (c > 0) { + STB_TEXTEDIT_CHARTYPE ch = (STB_TEXTEDIT_CHARTYPE) c; + + // can't add newline in single-line mode + if (c == '\n' && state->single_line) + break; + + if (state->insert_mode && !STB_TEXT_HAS_SELECTION(state) && state->cursor < STB_TEXTEDIT_STRINGLEN(str)) { + stb_text_makeundo_replace(str, state, state->cursor, 1, 1); + STB_TEXTEDIT_DELETECHARS(str, state->cursor, 1); + if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, &ch, 1)) { + ++state->cursor; + state->has_preferred_x = 0; + } + } else { + stb_textedit_delete_selection(str,state); // implicity clamps + if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, &ch, 1)) { + stb_text_makeundo_insert(state, state->cursor, 1); + ++state->cursor; + state->has_preferred_x = 0; + } + } + } + break; + } + +#ifdef STB_TEXTEDIT_K_INSERT + case STB_TEXTEDIT_K_INSERT: + state->insert_mode = !state->insert_mode; + break; +#endif + + case STB_TEXTEDIT_K_UNDO: + stb_text_undo(str, state); + state->has_preferred_x = 0; + break; + + case STB_TEXTEDIT_K_REDO: + stb_text_redo(str, state); + state->has_preferred_x = 0; + break; + + case STB_TEXTEDIT_K_LEFT: + // if currently there's a selection, move cursor to start of selection + if (STB_TEXT_HAS_SELECTION(state)) + stb_textedit_move_to_first(state); + else + if (state->cursor > 0) + --state->cursor; + state->has_preferred_x = 0; + break; + + case STB_TEXTEDIT_K_RIGHT: + // if currently there's a selection, move cursor to end of selection + if (STB_TEXT_HAS_SELECTION(state)) + stb_textedit_move_to_last(str, state); + else + ++state->cursor; + stb_textedit_clamp(str, state); + state->has_preferred_x = 0; + break; + + case STB_TEXTEDIT_K_LEFT | STB_TEXTEDIT_K_SHIFT: + stb_textedit_clamp(str, state); + stb_textedit_prep_selection_at_cursor(state); + // move selection left + if (state->select_end > 0) + --state->select_end; + state->cursor = state->select_end; + state->has_preferred_x = 0; + break; + +#ifdef STB_TEXTEDIT_IS_SPACE + case STB_TEXTEDIT_K_WORDLEFT: + if (STB_TEXT_HAS_SELECTION(state)) + stb_textedit_move_to_first(state); + else { + state->cursor = stb_textedit_move_to_word_previous(str, state); + stb_textedit_clamp( str, state ); + } + break; + + case STB_TEXTEDIT_K_WORDRIGHT: + if (STB_TEXT_HAS_SELECTION(state)) + stb_textedit_move_to_last(str, state); + else { + state->cursor = stb_textedit_move_to_word_next(str, state); + stb_textedit_clamp( str, state ); + } + break; + + case STB_TEXTEDIT_K_WORDLEFT | STB_TEXTEDIT_K_SHIFT: + if( !STB_TEXT_HAS_SELECTION( state ) ) + stb_textedit_prep_selection_at_cursor(state); + + state->cursor = stb_textedit_move_to_word_previous(str, state); + state->select_end = state->cursor; + + stb_textedit_clamp( str, state ); + break; + + case STB_TEXTEDIT_K_WORDRIGHT | STB_TEXTEDIT_K_SHIFT: + if( !STB_TEXT_HAS_SELECTION( state ) ) + stb_textedit_prep_selection_at_cursor(state); + + state->cursor = stb_textedit_move_to_word_next(str, state); + state->select_end = state->cursor; + + stb_textedit_clamp( str, state ); + break; +#endif + + case STB_TEXTEDIT_K_RIGHT | STB_TEXTEDIT_K_SHIFT: + stb_textedit_prep_selection_at_cursor(state); + // move selection right + ++state->select_end; + stb_textedit_clamp(str, state); + state->cursor = state->select_end; + state->has_preferred_x = 0; + break; + + case STB_TEXTEDIT_K_DOWN: + case STB_TEXTEDIT_K_DOWN | STB_TEXTEDIT_K_SHIFT: { + StbFindState find; + StbTexteditRow row; + int i, sel = (key & STB_TEXTEDIT_K_SHIFT) != 0; + + if (state->single_line) { + // on windows, up&down in single-line behave like left&right + key = STB_TEXTEDIT_K_RIGHT | (key & STB_TEXTEDIT_K_SHIFT); + goto retry; + } + + if (sel) + stb_textedit_prep_selection_at_cursor(state); + else if (STB_TEXT_HAS_SELECTION(state)) + stb_textedit_move_to_last(str,state); + + // compute current position of cursor point + stb_textedit_clamp(str, state); + stb_textedit_find_charpos(&find, str, state->cursor, state->single_line); + + // now find character position down a row + if (find.length) { + float goal_x = state->has_preferred_x ? state->preferred_x : find.x; + float x; + int start = find.first_char + find.length; + state->cursor = start; + STB_TEXTEDIT_LAYOUTROW(&row, str, state->cursor); + x = row.x0; + for (i=0; i < row.num_chars; ++i) { + float dx = STB_TEXTEDIT_GETWIDTH(str, start, i); + #ifdef STB_TEXTEDIT_GETWIDTH_NEWLINE + if (dx == STB_TEXTEDIT_GETWIDTH_NEWLINE) + break; + #endif + x += dx; + if (x > goal_x) + break; + ++state->cursor; + } + stb_textedit_clamp(str, state); + + state->has_preferred_x = 1; + state->preferred_x = goal_x; + + if (sel) + state->select_end = state->cursor; + } + break; + } + + case STB_TEXTEDIT_K_UP: + case STB_TEXTEDIT_K_UP | STB_TEXTEDIT_K_SHIFT: { + StbFindState find; + StbTexteditRow row; + int i, sel = (key & STB_TEXTEDIT_K_SHIFT) != 0; + + if (state->single_line) { + // on windows, up&down become left&right + key = STB_TEXTEDIT_K_LEFT | (key & STB_TEXTEDIT_K_SHIFT); + goto retry; + } + + if (sel) + stb_textedit_prep_selection_at_cursor(state); + else if (STB_TEXT_HAS_SELECTION(state)) + stb_textedit_move_to_first(state); + + // compute current position of cursor point + stb_textedit_clamp(str, state); + stb_textedit_find_charpos(&find, str, state->cursor, state->single_line); + + // can only go up if there's a previous row + if (find.prev_first != find.first_char) { + // now find character position up a row + float goal_x = state->has_preferred_x ? state->preferred_x : find.x; + float x; + state->cursor = find.prev_first; + STB_TEXTEDIT_LAYOUTROW(&row, str, state->cursor); + x = row.x0; + for (i=0; i < row.num_chars; ++i) { + float dx = STB_TEXTEDIT_GETWIDTH(str, find.prev_first, i); + #ifdef STB_TEXTEDIT_GETWIDTH_NEWLINE + if (dx == STB_TEXTEDIT_GETWIDTH_NEWLINE) + break; + #endif + x += dx; + if (x > goal_x) + break; + ++state->cursor; + } + stb_textedit_clamp(str, state); + + state->has_preferred_x = 1; + state->preferred_x = goal_x; + + if (sel) + state->select_end = state->cursor; + } + break; + } + + case STB_TEXTEDIT_K_DELETE: + case STB_TEXTEDIT_K_DELETE | STB_TEXTEDIT_K_SHIFT: + if (STB_TEXT_HAS_SELECTION(state)) + stb_textedit_delete_selection(str, state); + else { + int n = STB_TEXTEDIT_STRINGLEN(str); + if (state->cursor < n) + stb_textedit_delete(str, state, state->cursor, 1); + } + state->has_preferred_x = 0; + break; + + case STB_TEXTEDIT_K_BACKSPACE: + case STB_TEXTEDIT_K_BACKSPACE | STB_TEXTEDIT_K_SHIFT: + if (STB_TEXT_HAS_SELECTION(state)) + stb_textedit_delete_selection(str, state); + else { + stb_textedit_clamp(str, state); + if (state->cursor > 0) { + stb_textedit_delete(str, state, state->cursor-1, 1); + --state->cursor; + } + } + state->has_preferred_x = 0; + break; + + case STB_TEXTEDIT_K_TEXTSTART: + state->cursor = state->select_start = state->select_end = 0; + state->has_preferred_x = 0; + break; + + case STB_TEXTEDIT_K_TEXTEND: + state->cursor = STB_TEXTEDIT_STRINGLEN(str); + state->select_start = state->select_end = 0; + state->has_preferred_x = 0; + break; + + case STB_TEXTEDIT_K_TEXTSTART | STB_TEXTEDIT_K_SHIFT: + stb_textedit_prep_selection_at_cursor(state); + state->cursor = state->select_end = 0; + state->has_preferred_x = 0; + break; + + case STB_TEXTEDIT_K_TEXTEND | STB_TEXTEDIT_K_SHIFT: + stb_textedit_prep_selection_at_cursor(state); + state->cursor = state->select_end = STB_TEXTEDIT_STRINGLEN(str); + state->has_preferred_x = 0; + break; + + + case STB_TEXTEDIT_K_LINESTART: { + StbFindState find; + stb_textedit_clamp(str, state); + stb_textedit_move_to_first(state); + stb_textedit_find_charpos(&find, str, state->cursor, state->single_line); + state->cursor = find.first_char; + state->has_preferred_x = 0; + break; + } + + case STB_TEXTEDIT_K_LINEEND: { + StbFindState find; + stb_textedit_clamp(str, state); + stb_textedit_move_to_first(state); + stb_textedit_find_charpos(&find, str, state->cursor, state->single_line); + state->cursor = find.first_char + find.length; + state->has_preferred_x = 0; + break; + } + + case STB_TEXTEDIT_K_LINESTART | STB_TEXTEDIT_K_SHIFT: { + StbFindState find; + stb_textedit_clamp(str, state); + stb_textedit_prep_selection_at_cursor(state); + stb_textedit_find_charpos(&find, str, state->cursor, state->single_line); + state->cursor = state->select_end = find.first_char; + state->has_preferred_x = 0; + break; + } + + case STB_TEXTEDIT_K_LINEEND | STB_TEXTEDIT_K_SHIFT: { + StbFindState find; + stb_textedit_clamp(str, state); + stb_textedit_prep_selection_at_cursor(state); + stb_textedit_find_charpos(&find, str, state->cursor, state->single_line); + state->cursor = state->select_end = find.first_char + find.length; + state->has_preferred_x = 0; + break; + } + +// @TODO: +// STB_TEXTEDIT_K_PGUP - move cursor up a page +// STB_TEXTEDIT_K_PGDOWN - move cursor down a page + } +} + +///////////////////////////////////////////////////////////////////////////// +// +// Undo processing +// +// @OPTIMIZE: the undo/redo buffer should be circular + +static void stb_textedit_flush_redo(StbUndoState *state) +{ + state->redo_point = STB_TEXTEDIT_UNDOSTATECOUNT; + state->redo_char_point = STB_TEXTEDIT_UNDOCHARCOUNT; +} + +// discard the oldest entry in the undo list +static void stb_textedit_discard_undo(StbUndoState *state) +{ + if (state->undo_point > 0) { + // if the 0th undo state has characters, clean those up + if (state->undo_rec[0].char_storage >= 0) { + int n = state->undo_rec[0].insert_length, i; + // delete n characters from all other records + state->undo_char_point = state->undo_char_point - (short) n; // vsnet05 + memmove(state->undo_char, state->undo_char + n, (size_t) ((size_t)state->undo_char_point*sizeof(STB_TEXTEDIT_CHARTYPE))); + for (i=0; i < state->undo_point; ++i) + if (state->undo_rec[i].char_storage >= 0) + state->undo_rec[i].char_storage = state->undo_rec[i].char_storage - (short) n; // vsnet05 // @OPTIMIZE: get rid of char_storage and infer it + } + --state->undo_point; + memmove(state->undo_rec, state->undo_rec+1, (size_t) ((size_t)state->undo_point*sizeof(state->undo_rec[0]))); + } +} + +// discard the oldest entry in the redo list--it's bad if this +// ever happens, but because undo & redo have to store the actual +// characters in different cases, the redo character buffer can +// fill up even though the undo buffer didn't +static void stb_textedit_discard_redo(StbUndoState *state) +{ + int k = STB_TEXTEDIT_UNDOSTATECOUNT-1; + + if (state->redo_point <= k) { + // if the k'th undo state has characters, clean those up + if (state->undo_rec[k].char_storage >= 0) { + int n = state->undo_rec[k].insert_length, i; + // delete n characters from all other records + state->redo_char_point = state->redo_char_point + (short) n; // vsnet05 + memmove(state->undo_char + state->redo_char_point, state->undo_char + state->redo_char_point-n, (size_t) ((size_t)(STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_char_point)*sizeof(STB_TEXTEDIT_CHARTYPE))); + for (i=state->redo_point; i < k; ++i) + if (state->undo_rec[i].char_storage >= 0) + state->undo_rec[i].char_storage = state->undo_rec[i].char_storage + (short) n; // vsnet05 + } + ++state->redo_point; + memmove(state->undo_rec + state->redo_point-1, state->undo_rec + state->redo_point, (size_t) ((size_t)(STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point)*sizeof(state->undo_rec[0]))); + } +} + +static StbUndoRecord *stb_text_create_undo_record(StbUndoState *state, int numchars) +{ + // any time we create a new undo record, we discard redo + stb_textedit_flush_redo(state); + + // if we have no free records, we have to make room, by sliding the + // existing records down + if (state->undo_point == STB_TEXTEDIT_UNDOSTATECOUNT) + stb_textedit_discard_undo(state); + + // if the characters to store won't possibly fit in the buffer, we can't undo + if (numchars > STB_TEXTEDIT_UNDOCHARCOUNT) { + state->undo_point = 0; + state->undo_char_point = 0; + return NULL; + } + + // if we don't have enough free characters in the buffer, we have to make room + while (state->undo_char_point + numchars > STB_TEXTEDIT_UNDOCHARCOUNT) + stb_textedit_discard_undo(state); + + return &state->undo_rec[state->undo_point++]; +} + +static STB_TEXTEDIT_CHARTYPE *stb_text_createundo(StbUndoState *state, int pos, int insert_len, int delete_len) +{ + StbUndoRecord *r = stb_text_create_undo_record(state, insert_len); + if (r == NULL) + return NULL; + + r->where = pos; + r->insert_length = (short) insert_len; + r->delete_length = (short) delete_len; + + if (insert_len == 0) { + r->char_storage = -1; + return NULL; + } else { + r->char_storage = state->undo_char_point; + state->undo_char_point = state->undo_char_point + (short) insert_len; + return &state->undo_char[r->char_storage]; + } +} + +static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) +{ + StbUndoState *s = &state->undostate; + StbUndoRecord u, *r; + if (s->undo_point == 0) + return; + + // we need to do two things: apply the undo record, and create a redo record + u = s->undo_rec[s->undo_point-1]; + r = &s->undo_rec[s->redo_point-1]; + r->char_storage = -1; + + r->insert_length = u.delete_length; + r->delete_length = u.insert_length; + r->where = u.where; + + if (u.delete_length) { + // if the undo record says to delete characters, then the redo record will + // need to re-insert the characters that get deleted, so we need to store + // them. + + // there are three cases: + // there's enough room to store the characters + // characters stored for *redoing* don't leave room for redo + // characters stored for *undoing* don't leave room for redo + // if the last is true, we have to bail + + if (s->undo_char_point + u.delete_length >= STB_TEXTEDIT_UNDOCHARCOUNT) { + // the undo records take up too much character space; there's no space to store the redo characters + r->insert_length = 0; + } else { + int i; + + // there's definitely room to store the characters eventually + while (s->undo_char_point + u.delete_length > s->redo_char_point) { + // there's currently not enough room, so discard a redo record + stb_textedit_discard_redo(s); + // should never happen: + if (s->redo_point == STB_TEXTEDIT_UNDOSTATECOUNT) + return; + } + r = &s->undo_rec[s->redo_point-1]; + + r->char_storage = s->redo_char_point - u.delete_length; + s->redo_char_point = s->redo_char_point - (short) u.delete_length; + + // now save the characters + for (i=0; i < u.delete_length; ++i) + s->undo_char[r->char_storage + i] = STB_TEXTEDIT_GETCHAR(str, u.where + i); + } + + // now we can carry out the deletion + STB_TEXTEDIT_DELETECHARS(str, u.where, u.delete_length); + } + + // check type of recorded action: + if (u.insert_length) { + // easy case: was a deletion, so we need to insert n characters + STB_TEXTEDIT_INSERTCHARS(str, u.where, &s->undo_char[u.char_storage], u.insert_length); + s->undo_char_point -= u.insert_length; + } + + state->cursor = u.where + u.insert_length; + + s->undo_point--; + s->redo_point--; +} + +static void stb_text_redo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) +{ + StbUndoState *s = &state->undostate; + StbUndoRecord *u, r; + if (s->redo_point == STB_TEXTEDIT_UNDOSTATECOUNT) + return; + + // we need to do two things: apply the redo record, and create an undo record + u = &s->undo_rec[s->undo_point]; + r = s->undo_rec[s->redo_point]; + + // we KNOW there must be room for the undo record, because the redo record + // was derived from an undo record + + u->delete_length = r.insert_length; + u->insert_length = r.delete_length; + u->where = r.where; + u->char_storage = -1; + + if (r.delete_length) { + // the redo record requires us to delete characters, so the undo record + // needs to store the characters + + if (s->undo_char_point + u->insert_length > s->redo_char_point) { + u->insert_length = 0; + u->delete_length = 0; + } else { + int i; + u->char_storage = s->undo_char_point; + s->undo_char_point = s->undo_char_point + u->insert_length; + + // now save the characters + for (i=0; i < u->insert_length; ++i) + s->undo_char[u->char_storage + i] = STB_TEXTEDIT_GETCHAR(str, u->where + i); + } + + STB_TEXTEDIT_DELETECHARS(str, r.where, r.delete_length); + } + + if (r.insert_length) { + // easy case: need to insert n characters + STB_TEXTEDIT_INSERTCHARS(str, r.where, &s->undo_char[r.char_storage], r.insert_length); + } + + state->cursor = r.where + r.insert_length; + + s->undo_point++; + s->redo_point++; +} + +static void stb_text_makeundo_insert(STB_TexteditState *state, int where, int length) +{ + stb_text_createundo(&state->undostate, where, 0, length); +} + +static void stb_text_makeundo_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length) +{ + int i; + STB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, length, 0); + if (p) { + for (i=0; i < length; ++i) + p[i] = STB_TEXTEDIT_GETCHAR(str, where+i); + } +} + +static void stb_text_makeundo_replace(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length) +{ + int i; + STB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, old_length, new_length); + if (p) { + for (i=0; i < old_length; ++i) + p[i] = STB_TEXTEDIT_GETCHAR(str, where+i); + } +} + +// reset the state to default +static void stb_textedit_clear_state(STB_TexteditState *state, int is_single_line) +{ + state->undostate.undo_point = 0; + state->undostate.undo_char_point = 0; + state->undostate.redo_point = STB_TEXTEDIT_UNDOSTATECOUNT; + state->undostate.redo_char_point = STB_TEXTEDIT_UNDOCHARCOUNT; + state->select_end = state->select_start = 0; + state->cursor = 0; + state->has_preferred_x = 0; + state->preferred_x = 0; + state->cursor_at_end_of_line = 0; + state->initialized = 1; + state->single_line = (unsigned char) is_single_line; + state->insert_mode = 0; +} + +// API initialize +static void stb_textedit_initialize_state(STB_TexteditState *state, int is_single_line) +{ + stb_textedit_clear_state(state, is_single_line); +} +#endif//STB_TEXTEDIT_IMPLEMENTATION diff --git a/testbed/imgui/stb_truetype.h b/testbed/imgui/stb_truetype.h new file mode 100644 index 00000000..3c5d6f30 --- /dev/null +++ b/testbed/imgui/stb_truetype.h @@ -0,0 +1,2658 @@ +// [ImGui] this is a slightly modified version of stb_truetype.h 1.02 +// [ImGui] we added stbtt_PackFontRangesGatherRects() and stbtt_PackFontRangesRenderIntoRects() and modified stbtt_PackBegin() + +// stb_truetype.h - v1.02 - public domain +// authored from 2009-2014 by Sean Barrett / RAD Game Tools +// +// This library processes TrueType files: +// parse files +// extract glyph metrics +// extract glyph shapes +// render glyphs to one-channel bitmaps with antialiasing (box filter) +// +// Todo: +// non-MS cmaps +// crashproof on bad data +// hinting? (no longer patented) +// cleartype-style AA? +// optimize: use simple memory allocator for intermediates +// optimize: build edge-list directly from curves +// optimize: rasterize directly from curves? +// +// ADDITIONAL CONTRIBUTORS +// +// Mikko Mononen: compound shape support, more cmap formats +// Tor Andersson: kerning, subpixel rendering +// +// Bug/warning reports/fixes: +// "Zer" on mollyrocket (with fix) +// Cass Everitt +// stoiko (Haemimont Games) +// Brian Hook +// Walter van Niftrik +// David Gow +// David Given +// Ivan-Assen Ivanov +// Anthony Pesch +// Johan Duparc +// Hou Qiming +// Fabian "ryg" Giesen +// +// Misc other: +// Ryan Gordon +// +// VERSION HISTORY +// +// 1.02 (2014-12-10) fix various warnings & compile issues w/ stb_rect_pack, C++ +// 1.01 (2014-12-08) fix subpixel position when oversampling to exactly match +// non-oversampled; STBTT_POINT_SIZE for packed case only +// 1.00 (2014-12-06) add new PackBegin etc. API, w/ support for oversampling +// 0.99 (2014-09-18) fix multiple bugs with subpixel rendering (ryg) +// 0.9 (2014-08-07) support certain mac/iOS fonts without an MS platformID +// 0.8b (2014-07-07) fix a warning +// 0.8 (2014-05-25) fix a few more warnings +// 0.7 (2013-09-25) bugfix: subpixel glyph bug fixed in 0.5 had come back +// 0.6c (2012-07-24) improve documentation +// 0.6b (2012-07-20) fix a few more warnings +// 0.6 (2012-07-17) fix warnings; added stbtt_ScaleForMappingEmToPixels, +// stbtt_GetFontBoundingBox, stbtt_IsGlyphEmpty +// 0.5 (2011-12-09) bugfixes: +// subpixel glyph renderer computed wrong bounding box +// first vertex of shape can be off-curve (FreeSans) +// 0.4b (2011-12-03) fixed an error in the font baking example +// 0.4 (2011-12-01) kerning, subpixel rendering (tor) +// bugfixes for: +// codepoint-to-glyph conversion using table fmt=12 +// codepoint-to-glyph conversion using table fmt=4 +// stbtt_GetBakedQuad with non-square texture (Zer) +// updated Hello World! sample to use kerning and subpixel +// fixed some warnings +// 0.3 (2009-06-24) cmap fmt=12, compound shapes (MM) +// userdata, malloc-from-userdata, non-zero fill (stb) +// 0.2 (2009-03-11) Fix unsigned/signed char warnings +// 0.1 (2009-03-09) First public release +// +// LICENSE +// +// This software is in the public domain. Where that dedication is not +// recognized, you are granted a perpetual, irrevokable license to copy +// and modify this file as you see fit. +// +// USAGE +// +// Include this file in whatever places neeed to refer to it. In ONE C/C++ +// file, write: +// #define STB_TRUETYPE_IMPLEMENTATION +// before the #include of this file. This expands out the actual +// implementation into that C/C++ file. +// +// Simple 3D API (don't ship this, but it's fine for tools and quick start) +// stbtt_BakeFontBitmap() -- bake a font to a bitmap for use as texture +// stbtt_GetBakedQuad() -- compute quad to draw for a given char +// +// Improved 3D API (more shippable): +// #include "stb_rect_pack.h" -- optional, but you really want it +// stbtt_PackBegin() +// stbtt_PackSetOversample() -- for improved quality on small fonts +// stbtt_PackFontRanges() -- pack and renders +// stbtt_PackEnd() +// stbtt_GetPackedQuad() +// +// "Load" a font file from a memory buffer (you have to keep the buffer loaded) +// stbtt_InitFont() +// stbtt_GetFontOffsetForIndex() -- use for TTC font collections +// +// Render a unicode codepoint to a bitmap +// stbtt_GetCodepointBitmap() -- allocates and returns a bitmap +// stbtt_MakeCodepointBitmap() -- renders into bitmap you provide +// stbtt_GetCodepointBitmapBox() -- how big the bitmap must be +// +// Character advance/positioning +// stbtt_GetCodepointHMetrics() +// stbtt_GetFontVMetrics() +// stbtt_GetCodepointKernAdvance() +// +// ADDITIONAL DOCUMENTATION +// +// Immediately after this block comment are a series of sample programs. +// +// After the sample programs is the "header file" section. This section +// includes documentation for each API function. +// +// Some important concepts to understand to use this library: +// +// Codepoint +// Characters are defined by unicode codepoints, e.g. 65 is +// uppercase A, 231 is lowercase c with a cedilla, 0x7e30 is +// the hiragana for "ma". +// +// Glyph +// A visual character shape (every codepoint is rendered as +// some glyph) +// +// Glyph index +// A font-specific integer ID representing a glyph +// +// Baseline +// Glyph shapes are defined relative to a baseline, which is the +// bottom of uppercase characters. Characters extend both above +// and below the baseline. +// +// Current Point +// As you draw text to the screen, you keep track of a "current point" +// which is the origin of each character. The current point's vertical +// position is the baseline. Even "baked fonts" use this model. +// +// Vertical Font Metrics +// The vertical qualities of the font, used to vertically position +// and space the characters. See docs for stbtt_GetFontVMetrics. +// +// Font Size in Pixels or Points +// The preferred interface for specifying font sizes in stb_truetype +// is to specify how tall the font's vertical extent should be in pixels. +// If that sounds good enough, skip the next paragraph. +// +// Most font APIs instead use "points", which are a common typographic +// measurement for describing font size, defined as 72 points per inch. +// stb_truetype provides a point API for compatibility. However, true +// "per inch" conventions don't make much sense on computer displays +// since they different monitors have different number of pixels per +// inch. For example, Windows traditionally uses a convention that +// there are 96 pixels per inch, thus making 'inch' measurements have +// nothing to do with inches, and thus effectively defining a point to +// be 1.333 pixels. Additionally, the TrueType font data provides +// an explicit scale factor to scale a given font's glyphs to points, +// but the author has observed that this scale factor is often wrong +// for non-commercial fonts, thus making fonts scaled in points +// according to the TrueType spec incoherently sized in practice. +// +// ADVANCED USAGE +// +// Quality: +// +// - Use the functions with Subpixel at the end to allow your characters +// to have subpixel positioning. Since the font is anti-aliased, not +// hinted, this is very import for quality. (This is not possible with +// baked fonts.) +// +// - Kerning is now supported, and if you're supporting subpixel rendering +// then kerning is worth using to give your text a polished look. +// +// Performance: +// +// - Convert Unicode codepoints to glyph indexes and operate on the glyphs; +// if you don't do this, stb_truetype is forced to do the conversion on +// every call. +// +// - There are a lot of memory allocations. We should modify it to take +// a temp buffer and allocate from the temp buffer (without freeing), +// should help performance a lot. +// +// NOTES +// +// The system uses the raw data found in the .ttf file without changing it +// and without building auxiliary data structures. This is a bit inefficient +// on little-endian systems (the data is big-endian), but assuming you're +// caching the bitmaps or glyph shapes this shouldn't be a big deal. +// +// It appears to be very hard to programmatically determine what font a +// given file is in a general way. I provide an API for this, but I don't +// recommend it. +// +// +// SOURCE STATISTICS (based on v0.6c, 2050 LOC) +// +// Documentation & header file 520 LOC \___ 660 LOC documentation +// Sample code 140 LOC / +// Truetype parsing 620 LOC ---- 620 LOC TrueType +// Software rasterization 240 LOC \ . +// Curve tesselation 120 LOC \__ 550 LOC Bitmap creation +// Bitmap management 100 LOC / +// Baked bitmap interface 70 LOC / +// Font name matching & access 150 LOC ---- 150 +// C runtime library abstraction 60 LOC ---- 60 + + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +//// +//// SAMPLE PROGRAMS +//// +// +// Incomplete text-in-3d-api example, which draws quads properly aligned to be lossless +// +#if 0 +#define STB_TRUETYPE_IMPLEMENTATION // force following include to generate implementation +#include "stb_truetype.h" + +char ttf_buffer[1<<20]; +unsigned char temp_bitmap[512*512]; + +stbtt_bakedchar cdata[96]; // ASCII 32..126 is 95 glyphs +GLstbtt_uint ftex; + +void my_stbtt_initfont(void) +{ + fread(ttf_buffer, 1, 1<<20, fopen("c:/windows/fonts/times.ttf", "rb")); + stbtt_BakeFontBitmap(data,0, 32.0, temp_bitmap,512,512, 32,96, cdata); // no guarantee this fits! + // can free ttf_buffer at this point + glGenTextures(1, &ftex); + glBindTexture(GL_TEXTURE_2D, ftex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 512,512, 0, GL_ALPHA, GL_UNSIGNED_BYTE, temp_bitmap); + // can free temp_bitmap at this point + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); +} + +void my_stbtt_print(float x, float y, char *text) +{ + // assume orthographic projection with units = screen pixels, origin at top left + glBindTexture(GL_TEXTURE_2D, ftex); + glBegin(GL_QUADS); + while (*text) { + if (*text >= 32 && *text < 128) { + stbtt_aligned_quad q; + stbtt_GetBakedQuad(cdata, 512,512, *text-32, &x,&y,&q,1);//1=opengl & d3d10+,0=d3d9 + glTexCoord2f(q.s0,q.t1); glVertex2f(q.x0,q.y0); + glTexCoord2f(q.s1,q.t1); glVertex2f(q.x1,q.y0); + glTexCoord2f(q.s1,q.t0); glVertex2f(q.x1,q.y1); + glTexCoord2f(q.s0,q.t0); glVertex2f(q.x0,q.y1); + } + ++text; + } + glEnd(); +} +#endif +// +// +////////////////////////////////////////////////////////////////////////////// +// +// Complete program (this compiles): get a single bitmap, print as ASCII art +// +#if 0 +#include +#define STB_TRUETYPE_IMPLEMENTATION // force following include to generate implementation +#include "stb_truetype.h" + +char ttf_buffer[1<<25]; + +int main(int argc, char **argv) +{ + stbtt_fontinfo font; + unsigned char *bitmap; + int w,h,i,j,c = (argc > 1 ? atoi(argv[1]) : 'a'), s = (argc > 2 ? atoi(argv[2]) : 20); + + fread(ttf_buffer, 1, 1<<25, fopen(argc > 3 ? argv[3] : "c:/windows/fonts/arialbd.ttf", "rb")); + + stbtt_InitFont(&font, ttf_buffer, stbtt_GetFontOffsetForIndex(ttf_buffer,0)); + bitmap = stbtt_GetCodepointBitmap(&font, 0,stbtt_ScaleForPixelHeight(&font, s), c, &w, &h, 0,0); + + for (j=0; j < h; ++j) { + for (i=0; i < w; ++i) + putchar(" .:ioVM@"[bitmap[j*w+i]>>5]); + putchar('\n'); + } + return 0; +} +#endif +// +// Output: +// +// .ii. +// @@@@@@. +// V@Mio@@o +// :i. V@V +// :oM@@M +// :@@@MM@M +// @@o o@M +// :@@. M@M +// @@@o@@@@ +// :M@@V:@@. +// +////////////////////////////////////////////////////////////////////////////// +// +// Complete program: print "Hello World!" banner, with bugs +// +#if 0 +char buffer[24<<20]; +unsigned char screen[20][79]; + +int main(int arg, char **argv) +{ + stbtt_fontinfo font; + int i,j,ascent,baseline,ch=0; + float scale, xpos=2; // leave a little padding in case the character extends left + char *text = "Heljo World!"; + + fread(buffer, 1, 1000000, fopen("c:/windows/fonts/arialbd.ttf", "rb")); + stbtt_InitFont(&font, buffer, 0); + + scale = stbtt_ScaleForPixelHeight(&font, 15); + stbtt_GetFontVMetrics(&font, &ascent,0,0); + baseline = (int) (ascent*scale); + + while (text[ch]) { + int advance,lsb,x0,y0,x1,y1; + float x_shift = xpos - (float) floor(xpos); + stbtt_GetCodepointHMetrics(&font, text[ch], &advance, &lsb); + stbtt_GetCodepointBitmapBoxSubpixel(&font, text[ch], scale,scale,x_shift,0, &x0,&y0,&x1,&y1); + stbtt_MakeCodepointBitmapSubpixel(&font, &screen[baseline + y0][(int) xpos + x0], x1-x0,y1-y0, 79, scale,scale,x_shift,0, text[ch]); + // note that this stomps the old data, so where character boxes overlap (e.g. 'lj') it's wrong + // because this API is really for baking character bitmaps into textures. if you want to render + // a sequence of characters, you really need to render each bitmap to a temp buffer, then + // "alpha blend" that into the working buffer + xpos += (advance * scale); + if (text[ch+1]) + xpos += scale*stbtt_GetCodepointKernAdvance(&font, text[ch],text[ch+1]); + ++ch; + } + + for (j=0; j < 20; ++j) { + for (i=0; i < 78; ++i) + putchar(" .:ioVM@"[screen[j][i]>>5]); + putchar('\n'); + } + + return 0; +} +#endif + + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +//// +//// INTEGRATION WITH YOUR CODEBASE +//// +//// The following sections allow you to supply alternate definitions +//// of C library functions used by stb_truetype. + +#ifdef STB_TRUETYPE_IMPLEMENTATION + // #define your own (u)stbtt_int8/16/32 before including to override this + #ifndef stbtt_uint8 + typedef unsigned char stbtt_uint8; + typedef signed char stbtt_int8; + typedef unsigned short stbtt_uint16; + typedef signed short stbtt_int16; + typedef unsigned int stbtt_uint32; + typedef signed int stbtt_int32; + #endif + + typedef char stbtt__check_size32[sizeof(stbtt_int32)==4 ? 1 : -1]; + typedef char stbtt__check_size16[sizeof(stbtt_int16)==2 ? 1 : -1]; + + #ifdef STBTT_STATIC + #define STBTT_DEF static + #else + #define STBTT_DEF extern + #endif + + // #define your own STBTT_sort() to override this to avoid qsort + #ifndef STBTT_sort + #include + #define STBTT_sort(data,num_items,item_size,compare_func) qsort(data,num_items,item_size,compare_func) + #endif + + // #define your own STBTT_ifloor/STBTT_iceil() to avoid math.h + #ifndef STBTT_ifloor + #include + #define STBTT_ifloor(x) ((int) floor(x)) + #define STBTT_iceil(x) ((int) ceil(x)) + #endif + + #ifndef STBTT_sqrt + #include + #define STBTT_sqrt(x) sqrt(x) + #endif + + // #define your own functions "STBTT_malloc" / "STBTT_free" to avoid malloc.h + #ifndef STBTT_malloc + #include + #define STBTT_malloc(x,u) ((void)(u),malloc(x)) + #define STBTT_free(x,u) ((void)(u),free(x)) + #endif + + #ifndef STBTT_assert + #include + #define STBTT_assert(x) assert(x) + #endif + + #ifndef STBTT_strlen + #include + #define STBTT_strlen(x) strlen(x) + #endif + + #ifndef STBTT_memcpy + #include + #define STBTT_memcpy memcpy + #define STBTT_memset memset + #endif +#endif + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +//// +//// INTERFACE +//// +//// + +#ifndef __STB_INCLUDE_STB_TRUETYPE_H__ +#define __STB_INCLUDE_STB_TRUETYPE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +////////////////////////////////////////////////////////////////////////////// +// +// TEXTURE BAKING API +// +// If you use this API, you only have to call two functions ever. +// + +typedef struct +{ + unsigned short x0,y0,x1,y1; // coordinates of bbox in bitmap + float xoff,yoff,xadvance; +} stbtt_bakedchar; + +STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset, // font location (use offset=0 for plain .ttf) + float pixel_height, // height of font in pixels + unsigned char *pixels, int pw, int ph, // bitmap to be filled in + int first_char, int num_chars, // characters to bake + stbtt_bakedchar *chardata); // you allocate this, it's num_chars long +// if return is positive, the first unused row of the bitmap +// if return is negative, returns the negative of the number of characters that fit +// if return is 0, no characters fit and no rows were used +// This uses a very crappy packing. + +typedef struct +{ + float x0,y0,s0,t0; // top-left + float x1,y1,s1,t1; // bottom-right +} stbtt_aligned_quad; + +STBTT_DEF void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, // same data as above + int char_index, // character to display + float *xpos, float *ypos, // pointers to current position in screen pixel space + stbtt_aligned_quad *q, // output: quad to draw + int opengl_fillrule); // true if opengl fill rule; false if DX9 or earlier +// Call GetBakedQuad with char_index = 'character - first_char', and it +// creates the quad you need to draw and advances the current position. +// +// The coordinate system used assumes y increases downwards. +// +// Characters will extend both above and below the current position; +// see discussion of "BASELINE" above. +// +// It's inefficient; you might want to c&p it and optimize it. + + + +////////////////////////////////////////////////////////////////////////////// +// +// NEW TEXTURE BAKING API +// +// This provides options for packing multiple fonts into one atlas, not +// perfectly but better than nothing. + +typedef struct +{ + unsigned short x0,y0,x1,y1; // coordinates of bbox in bitmap + float xoff,yoff,xadvance; + float xoff2,yoff2; +} stbtt_packedchar; + +typedef struct stbtt_pack_context stbtt_pack_context; +typedef struct stbtt_fontinfo stbtt_fontinfo; +#ifndef STB_RECT_PACK_VERSION +typedef struct stbrp_rect stbrp_rect; +#endif + +STBTT_DEF int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, int width, int height, int stride_in_bytes, int padding, void *alloc_context); +// Initializes a packing context stored in the passed-in stbtt_pack_context. +// Future calls using this context will pack characters into the bitmap passed +// in here: a 1-channel bitmap that is weight x height. stride_in_bytes is +// the distance from one row to the next (or 0 to mean they are packed tightly +// together). "padding" is // the amount of padding to leave between each +// character (normally you want '1' for bitmaps you'll use as textures with +// bilinear filtering). +// +// Returns 0 on failure, 1 on success. + +STBTT_DEF void stbtt_PackEnd (stbtt_pack_context *spc); +// Cleans up the packing context and frees all memory. + +#define STBTT_POINT_SIZE(x) (-(x)) + +STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, float font_size, + int first_unicode_char_in_range, int num_chars_in_range, stbtt_packedchar *chardata_for_range); +// Creates character bitmaps from the font_index'th font found in fontdata (use +// font_index=0 if you don't know what that is). It creates num_chars_in_range +// bitmaps for characters with unicode values starting at first_unicode_char_in_range +// and increasing. Data for how to render them is stored in chardata_for_range; +// pass these to stbtt_GetPackedQuad to get back renderable quads. +// +// font_size is the full height of the character from ascender to descender, +// as computed by stbtt_ScaleForPixelHeight. To use a point size as computed +// by stbtt_ScaleForMappingEmToPixels, wrap the point size in STBTT_POINT_SIZE() +// and pass that result as 'font_size': +// ..., 20 , ... // font max minus min y is 20 pixels tall +// ..., STBTT_POINT_SIZE(20), ... // 'M' is 20 pixels tall + +typedef struct +{ + float font_size; + int first_unicode_char_in_range; + int num_chars_in_range; + stbtt_packedchar *chardata_for_range; // output +} stbtt_pack_range; + +STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges); +// Creates character bitmaps from multiple ranges of characters stored in +// ranges. This will usually create a better-packed bitmap than multiple +// calls to stbtt_PackFontRange. + +STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects); +STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects); +// Those functions are called by stbtt_PackFontRanges(). If you want to +// pack multiple fonts or custom data into a same texture, you may copy +// the contents of stbtt_PackFontRanges() and create a custom version +// using those functions. + +STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h_oversample, unsigned int v_oversample); +// Oversampling a font increases the quality by allowing higher-quality subpixel +// positioning, and is especially valuable at smaller text sizes. +// +// This function sets the amount of oversampling for all following calls to +// stbtt_PackFontRange(s). The default (no oversampling) is achieved by +// h_oversample=1, v_oversample=1. The total number of pixels required is +// h_oversample*v_oversample larger than the default; for example, 2x2 +// oversampling requires 4x the storage of 1x1. For best results, render +// oversampled textures with bilinear filtering. Look at the readme in +// stb/tests/oversample for information about oversampled fonts + +STBTT_DEF void stbtt_GetPackedQuad(stbtt_packedchar *chardata, int pw, int ph, // same data as above + int char_index, // character to display + float *xpos, float *ypos, // pointers to current position in screen pixel space + stbtt_aligned_quad *q, // output: quad to draw + int align_to_integer); + +// this is an opaque structure that you shouldn't mess with which holds +// all the context needed from PackBegin to PackEnd. +struct stbtt_pack_context { + void *user_allocator_context; + void *pack_info; + int width; + int height; + int stride_in_bytes; + int padding; + unsigned int h_oversample, v_oversample; + unsigned char *pixels; + void *nodes; +}; + +////////////////////////////////////////////////////////////////////////////// +// +// FONT LOADING +// +// + +STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index); +// Each .ttf/.ttc file may have more than one font. Each font has a sequential +// index number starting from 0. Call this function to get the font offset for +// a given index; it returns -1 if the index is out of range. A regular .ttf +// file will only define one font and it always be at offset 0, so it will +// return '0' for index 0, and -1 for all other indices. You can just skip +// this step if you know it's that kind of font. + + +// The following structure is defined publically so you can declare one on +// the stack or as a global or etc, but you should treat it as opaque. +typedef struct stbtt_fontinfo +{ + void * userdata; + unsigned char * data; // pointer to .ttf file + int fontstart; // offset of start of font + + int numGlyphs; // number of glyphs, needed for range checking + + int loca,head,glyf,hhea,hmtx,kern; // table locations as offset from start of .ttf + int index_map; // a cmap mapping for our chosen character encoding + int indexToLocFormat; // format needed to map from glyph index to glyph +} stbtt_fontinfo; + +STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data, int offset); +// Given an offset into the file that defines a font, this function builds +// the necessary cached info for the rest of the system. You must allocate +// the stbtt_fontinfo yourself, and stbtt_InitFont will fill it out. You don't +// need to do anything special to free it, because the contents are pure +// value data with no additional data structures. Returns 0 on failure. + + +////////////////////////////////////////////////////////////////////////////// +// +// CHARACTER TO GLYPH-INDEX CONVERSIOn + +STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codepoint); +// If you're going to perform multiple operations on the same character +// and you want a speed-up, call this function with the character you're +// going to process, then use glyph-based functions instead of the +// codepoint-based functions. + + +////////////////////////////////////////////////////////////////////////////// +// +// CHARACTER PROPERTIES +// + +STBTT_DEF float stbtt_ScaleForPixelHeight(const stbtt_fontinfo *info, float pixels); +// computes a scale factor to produce a font whose "height" is 'pixels' tall. +// Height is measured as the distance from the highest ascender to the lowest +// descender; in other words, it's equivalent to calling stbtt_GetFontVMetrics +// and computing: +// scale = pixels / (ascent - descent) +// so if you prefer to measure height by the ascent only, use a similar calculation. + +STBTT_DEF float stbtt_ScaleForMappingEmToPixels(const stbtt_fontinfo *info, float pixels); +// computes a scale factor to produce a font whose EM size is mapped to +// 'pixels' tall. This is probably what traditional APIs compute, but +// I'm not positive. + +STBTT_DEF void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, int *descent, int *lineGap); +// ascent is the coordinate above the baseline the font extends; descent +// is the coordinate below the baseline the font extends (i.e. it is typically negative) +// lineGap is the spacing between one row's descent and the next row's ascent... +// so you should advance the vertical position by "*ascent - *descent + *lineGap" +// these are expressed in unscaled coordinates, so you must multiply by +// the scale factor for a given size + +STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int *x0, int *y0, int *x1, int *y1); +// the bounding box around all possible characters + +STBTT_DEF void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, int codepoint, int *advanceWidth, int *leftSideBearing); +// leftSideBearing is the offset from the current horizontal position to the left edge of the character +// advanceWidth is the offset from the current horizontal position to the next horizontal position +// these are expressed in unscaled coordinates + +STBTT_DEF int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2); +// an additional amount to add to the 'advance' value between ch1 and ch2 + +STBTT_DEF int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, int *x0, int *y0, int *x1, int *y1); +// Gets the bounding box of the visible part of the glyph, in unscaled coordinates + +STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_index, int *advanceWidth, int *leftSideBearing); +STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2); +STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1); +// as above, but takes one or more glyph indices for greater efficiency + + +////////////////////////////////////////////////////////////////////////////// +// +// GLYPH SHAPES (you probably don't need these, but they have to go before +// the bitmaps for C declaration-order reasons) +// + +#ifndef STBTT_vmove // you can predefine these to use different values (but why?) + enum { + STBTT_vmove=1, + STBTT_vline, + STBTT_vcurve + }; +#endif + +#ifndef stbtt_vertex // you can predefine this to use different values + // (we share this with other code at RAD) + #define stbtt_vertex_type short // can't use stbtt_int16 because that's not visible in the header file + typedef struct + { + stbtt_vertex_type x,y,cx,cy; + unsigned char type,padding; + } stbtt_vertex; +#endif + +STBTT_DEF int stbtt_IsGlyphEmpty(const stbtt_fontinfo *info, int glyph_index); +// returns non-zero if nothing is drawn for this glyph + +STBTT_DEF int stbtt_GetCodepointShape(const stbtt_fontinfo *info, int unicode_codepoint, stbtt_vertex **vertices); +STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **vertices); +// returns # of vertices and fills *vertices with the pointer to them +// these are expressed in "unscaled" coordinates +// +// The shape is a series of countours. Each one starts with +// a STBTT_moveto, then consists of a series of mixed +// STBTT_lineto and STBTT_curveto segments. A lineto +// draws a line from previous endpoint to its x,y; a curveto +// draws a quadratic bezier from previous endpoint to +// its x,y, using cx,cy as the bezier control point. + +STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *vertices); +// frees the data allocated above + +////////////////////////////////////////////////////////////////////////////// +// +// BITMAP RENDERING +// + +STBTT_DEF void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata); +// frees the bitmap allocated below + +STBTT_DEF unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int codepoint, int *width, int *height, int *xoff, int *yoff); +// allocates a large-enough single-channel 8bpp bitmap and renders the +// specified character/glyph at the specified scale into it, with +// antialiasing. 0 is no coverage (transparent), 255 is fully covered (opaque). +// *width & *height are filled out with the width & height of the bitmap, +// which is stored left-to-right, top-to-bottom. +// +// xoff/yoff are the offset it pixel space from the glyph origin to the top-left of the bitmap + +STBTT_DEF unsigned char *stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint, int *width, int *height, int *xoff, int *yoff); +// the same as stbtt_GetCodepoitnBitmap, but you can specify a subpixel +// shift for the character + +STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int codepoint); +// the same as stbtt_GetCodepointBitmap, but you pass in storage for the bitmap +// in the form of 'output', with row spacing of 'out_stride' bytes. the bitmap +// is clipped to out_w/out_h bytes. Call stbtt_GetCodepointBitmapBox to get the +// width and height and positioning info for it first. + +STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint); +// same as stbtt_MakeCodepointBitmap, but you can specify a subpixel +// shift for the character + +STBTT_DEF void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1); +// get the bbox of the bitmap centered around the glyph origin; so the +// bitmap width is ix1-ix0, height is iy1-iy0, and location to place +// the bitmap top left is (leftSideBearing*scale,iy0). +// (Note that the bitmap uses y-increases-down, but the shape uses +// y-increases-up, so CodepointBitmapBox and CodepointBox are inverted.) + +STBTT_DEF void stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1); +// same as stbtt_GetCodepointBitmapBox, but you can specify a subpixel +// shift for the character + +// the following functions are equivalent to the above functions, but operate +// on glyph indices instead of Unicode codepoints (for efficiency) +STBTT_DEF unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int glyph, int *width, int *height, int *xoff, int *yoff); +STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int glyph, int *width, int *height, int *xoff, int *yoff); +STBTT_DEF void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int glyph); +STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int glyph); +STBTT_DEF void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1); +STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y,float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1); + + +// @TODO: don't expose this structure +typedef struct +{ + int w,h,stride; + unsigned char *pixels; +} stbtt__bitmap; + +STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result, float flatness_in_pixels, stbtt_vertex *vertices, int num_verts, float scale_x, float scale_y, float shift_x, float shift_y, int x_off, int y_off, int invert, void *userdata); + +////////////////////////////////////////////////////////////////////////////// +// +// Finding the right font... +// +// You should really just solve this offline, keep your own tables +// of what font is what, and don't try to get it out of the .ttf file. +// That's because getting it out of the .ttf file is really hard, because +// the names in the file can appear in many possible encodings, in many +// possible languages, and e.g. if you need a case-insensitive comparison, +// the details of that depend on the encoding & language in a complex way +// (actually underspecified in truetype, but also gigantic). +// +// But you can use the provided functions in two possible ways: +// stbtt_FindMatchingFont() will use *case-sensitive* comparisons on +// unicode-encoded names to try to find the font you want; +// you can run this before calling stbtt_InitFont() +// +// stbtt_GetFontNameString() lets you get any of the various strings +// from the file yourself and do your own comparisons on them. +// You have to have called stbtt_InitFont() first. + + +STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *fontdata, const char *name, int flags); +// returns the offset (not index) of the font that matches, or -1 if none +// if you use STBTT_MACSTYLE_DONTCARE, use a font name like "Arial Bold". +// if you use any other flag, use a font name like "Arial"; this checks +// the 'macStyle' header field; i don't know if fonts set this consistently +#define STBTT_MACSTYLE_DONTCARE 0 +#define STBTT_MACSTYLE_BOLD 1 +#define STBTT_MACSTYLE_ITALIC 2 +#define STBTT_MACSTYLE_UNDERSCORE 4 +#define STBTT_MACSTYLE_NONE 8 // <= not same as 0, this makes us check the bitfield is 0 + +STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2); +// returns 1/0 whether the first string interpreted as utf8 is identical to +// the second string interpreted as big-endian utf16... useful for strings from next func + +STBTT_DEF const char *stbtt_GetFontNameString(const stbtt_fontinfo *font, int *length, int platformID, int encodingID, int languageID, int nameID); +// returns the string (which may be big-endian double byte, e.g. for unicode) +// and puts the length in bytes in *length. +// +// some of the values for the IDs are below; for more see the truetype spec: +// http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6name.html +// http://www.microsoft.com/typography/otspec/name.htm + +enum { // platformID + STBTT_PLATFORM_ID_UNICODE =0, + STBTT_PLATFORM_ID_MAC =1, + STBTT_PLATFORM_ID_ISO =2, + STBTT_PLATFORM_ID_MICROSOFT =3 +}; + +enum { // encodingID for STBTT_PLATFORM_ID_UNICODE + STBTT_UNICODE_EID_UNICODE_1_0 =0, + STBTT_UNICODE_EID_UNICODE_1_1 =1, + STBTT_UNICODE_EID_ISO_10646 =2, + STBTT_UNICODE_EID_UNICODE_2_0_BMP=3, + STBTT_UNICODE_EID_UNICODE_2_0_FULL=4 +}; + +enum { // encodingID for STBTT_PLATFORM_ID_MICROSOFT + STBTT_MS_EID_SYMBOL =0, + STBTT_MS_EID_UNICODE_BMP =1, + STBTT_MS_EID_SHIFTJIS =2, + STBTT_MS_EID_UNICODE_FULL =10 +}; + +enum { // encodingID for STBTT_PLATFORM_ID_MAC; same as Script Manager codes + STBTT_MAC_EID_ROMAN =0, STBTT_MAC_EID_ARABIC =4, + STBTT_MAC_EID_JAPANESE =1, STBTT_MAC_EID_HEBREW =5, + STBTT_MAC_EID_CHINESE_TRAD =2, STBTT_MAC_EID_GREEK =6, + STBTT_MAC_EID_KOREAN =3, STBTT_MAC_EID_RUSSIAN =7 +}; + +enum { // languageID for STBTT_PLATFORM_ID_MICROSOFT; same as LCID... + // problematic because there are e.g. 16 english LCIDs and 16 arabic LCIDs + STBTT_MS_LANG_ENGLISH =0x0409, STBTT_MS_LANG_ITALIAN =0x0410, + STBTT_MS_LANG_CHINESE =0x0804, STBTT_MS_LANG_JAPANESE =0x0411, + STBTT_MS_LANG_DUTCH =0x0413, STBTT_MS_LANG_KOREAN =0x0412, + STBTT_MS_LANG_FRENCH =0x040c, STBTT_MS_LANG_RUSSIAN =0x0419, + STBTT_MS_LANG_GERMAN =0x0407, STBTT_MS_LANG_SPANISH =0x0409, + STBTT_MS_LANG_HEBREW =0x040d, STBTT_MS_LANG_SWEDISH =0x041D +}; + +enum { // languageID for STBTT_PLATFORM_ID_MAC + STBTT_MAC_LANG_ENGLISH =0 , STBTT_MAC_LANG_JAPANESE =11, + STBTT_MAC_LANG_ARABIC =12, STBTT_MAC_LANG_KOREAN =23, + STBTT_MAC_LANG_DUTCH =4 , STBTT_MAC_LANG_RUSSIAN =32, + STBTT_MAC_LANG_FRENCH =1 , STBTT_MAC_LANG_SPANISH =6 , + STBTT_MAC_LANG_GERMAN =2 , STBTT_MAC_LANG_SWEDISH =5 , + STBTT_MAC_LANG_HEBREW =10, STBTT_MAC_LANG_CHINESE_SIMPLIFIED =33, + STBTT_MAC_LANG_ITALIAN =3 , STBTT_MAC_LANG_CHINESE_TRAD =19 +}; + +#ifdef __cplusplus +} +#endif + +#endif // __STB_INCLUDE_STB_TRUETYPE_H__ + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +//// +//// IMPLEMENTATION +//// +//// + +#ifdef STB_TRUETYPE_IMPLEMENTATION + +#ifndef STBTT_MAX_OVERSAMPLE +#define STBTT_MAX_OVERSAMPLE 8 +#endif + +typedef int stbtt__test_oversample_pow2[(STBTT_MAX_OVERSAMPLE & (STBTT_MAX_OVERSAMPLE-1)) == 0 ? 1 : -1]; + +////////////////////////////////////////////////////////////////////////// +// +// accessors to parse data from file +// + +// on platforms that don't allow misaligned reads, if we want to allow +// truetype fonts that aren't padded to alignment, define ALLOW_UNALIGNED_TRUETYPE + +#define ttBYTE(p) (* (stbtt_uint8 *) (p)) +#define ttCHAR(p) (* (stbtt_int8 *) (p)) +#define ttFixed(p) ttLONG(p) + +#if defined(STB_TRUETYPE_BIGENDIAN) && !defined(ALLOW_UNALIGNED_TRUETYPE) + + #define ttUSHORT(p) (* (stbtt_uint16 *) (p)) + #define ttSHORT(p) (* (stbtt_int16 *) (p)) + #define ttULONG(p) (* (stbtt_uint32 *) (p)) + #define ttLONG(p) (* (stbtt_int32 *) (p)) + +#else + + static stbtt_uint16 ttUSHORT(const stbtt_uint8 *p) { return p[0]*256 + p[1]; } + static stbtt_int16 ttSHORT(const stbtt_uint8 *p) { return p[0]*256 + p[1]; } + static stbtt_uint32 ttULONG(const stbtt_uint8 *p) { return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; } + static stbtt_int32 ttLONG(const stbtt_uint8 *p) { return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; } + +#endif + +#define stbtt_tag4(p,c0,c1,c2,c3) ((p)[0] == (c0) && (p)[1] == (c1) && (p)[2] == (c2) && (p)[3] == (c3)) +#define stbtt_tag(p,str) stbtt_tag4(p,str[0],str[1],str[2],str[3]) + +static int stbtt__isfont(const stbtt_uint8 *font) +{ + // check the version number + if (stbtt_tag4(font, '1',0,0,0)) return 1; // TrueType 1 + if (stbtt_tag(font, "typ1")) return 1; // TrueType with type 1 font -- we don't support this! + if (stbtt_tag(font, "OTTO")) return 1; // OpenType with CFF + if (stbtt_tag4(font, 0,1,0,0)) return 1; // OpenType 1.0 + return 0; +} + +// @OPTIMIZE: binary search +static stbtt_uint32 stbtt__find_table(stbtt_uint8 *data, stbtt_uint32 fontstart, const char *tag) +{ + stbtt_int32 num_tables = ttUSHORT(data+fontstart+4); + stbtt_uint32 tabledir = fontstart + 12; + stbtt_int32 i; + for (i=0; i < num_tables; ++i) { + stbtt_uint32 loc = tabledir + 16*i; + if (stbtt_tag(data+loc+0, tag)) + return ttULONG(data+loc+8); + } + return 0; +} + +STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *font_collection, int index) +{ + // if it's just a font, there's only one valid index + if (stbtt__isfont(font_collection)) + return index == 0 ? 0 : -1; + + // check if it's a TTC + if (stbtt_tag(font_collection, "ttcf")) { + // version 1? + if (ttULONG(font_collection+4) == 0x00010000 || ttULONG(font_collection+4) == 0x00020000) { + stbtt_int32 n = ttLONG(font_collection+8); + if (index >= n) + return -1; + return ttULONG(font_collection+12+index*14); + } + } + return -1; +} + +STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data2, int fontstart) +{ + stbtt_uint8 *data = (stbtt_uint8 *) data2; + stbtt_uint32 cmap, t; + stbtt_int32 i,numTables; + + info->data = data; + info->fontstart = fontstart; + + cmap = stbtt__find_table(data, fontstart, "cmap"); // required + info->loca = stbtt__find_table(data, fontstart, "loca"); // required + info->head = stbtt__find_table(data, fontstart, "head"); // required + info->glyf = stbtt__find_table(data, fontstart, "glyf"); // required + info->hhea = stbtt__find_table(data, fontstart, "hhea"); // required + info->hmtx = stbtt__find_table(data, fontstart, "hmtx"); // required + info->kern = stbtt__find_table(data, fontstart, "kern"); // not required + if (!cmap || !info->loca || !info->head || !info->glyf || !info->hhea || !info->hmtx) + return 0; + + t = stbtt__find_table(data, fontstart, "maxp"); + if (t) + info->numGlyphs = ttUSHORT(data+t+4); + else + info->numGlyphs = 0xffff; + + // find a cmap encoding table we understand *now* to avoid searching + // later. (todo: could make this installable) + // the same regardless of glyph. + numTables = ttUSHORT(data + cmap + 2); + info->index_map = 0; + for (i=0; i < numTables; ++i) { + stbtt_uint32 encoding_record = cmap + 4 + 8 * i; + // find an encoding we understand: + switch(ttUSHORT(data+encoding_record)) { + case STBTT_PLATFORM_ID_MICROSOFT: + switch (ttUSHORT(data+encoding_record+2)) { + case STBTT_MS_EID_UNICODE_BMP: + case STBTT_MS_EID_UNICODE_FULL: + // MS/Unicode + info->index_map = cmap + ttULONG(data+encoding_record+4); + break; + } + break; + case STBTT_PLATFORM_ID_UNICODE: + // Mac/iOS has these + // all the encodingIDs are unicode, so we don't bother to check it + info->index_map = cmap + ttULONG(data+encoding_record+4); + break; + } + } + if (info->index_map == 0) + return 0; + + info->indexToLocFormat = ttUSHORT(data+info->head + 50); + return 1; +} + +STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codepoint) +{ + stbtt_uint8 *data = info->data; + stbtt_uint32 index_map = info->index_map; + + stbtt_uint16 format = ttUSHORT(data + index_map + 0); + if (format == 0) { // apple byte encoding + stbtt_int32 bytes = ttUSHORT(data + index_map + 2); + if (unicode_codepoint < bytes-6) + return ttBYTE(data + index_map + 6 + unicode_codepoint); + return 0; + } else if (format == 6) { + stbtt_uint32 first = ttUSHORT(data + index_map + 6); + stbtt_uint32 count = ttUSHORT(data + index_map + 8); + if ((stbtt_uint32) unicode_codepoint >= first && (stbtt_uint32) unicode_codepoint < first+count) + return ttUSHORT(data + index_map + 10 + (unicode_codepoint - first)*2); + return 0; + } else if (format == 2) { + STBTT_assert(0); // @TODO: high-byte mapping for japanese/chinese/korean + return 0; + } else if (format == 4) { // standard mapping for windows fonts: binary search collection of ranges + stbtt_uint16 segcount = ttUSHORT(data+index_map+6) >> 1; + stbtt_uint16 searchRange = ttUSHORT(data+index_map+8) >> 1; + stbtt_uint16 entrySelector = ttUSHORT(data+index_map+10); + stbtt_uint16 rangeShift = ttUSHORT(data+index_map+12) >> 1; + stbtt_uint16 item, offset, start, end; + + // do a binary search of the segments + stbtt_uint32 endCount = index_map + 14; + stbtt_uint32 search = endCount; + + if (unicode_codepoint > 0xffff) + return 0; + + // they lie from endCount .. endCount + segCount + // but searchRange is the nearest power of two, so... + if (unicode_codepoint >= ttUSHORT(data + search + rangeShift*2)) + search += rangeShift*2; + + // now decrement to bias correctly to find smallest + search -= 2; + while (entrySelector) { + searchRange >>= 1; + start = ttUSHORT(data + search + searchRange*2 + segcount*2 + 2); + end = ttUSHORT(data + search + searchRange*2); + if (unicode_codepoint > end) + search += searchRange*2; + --entrySelector; + } + search += 2; + + item = (stbtt_uint16) ((search - endCount) >> 1); + + STBTT_assert(unicode_codepoint <= ttUSHORT(data + endCount + 2*item)); + start = ttUSHORT(data + index_map + 14 + segcount*2 + 2 + 2*item); + end = ttUSHORT(data + index_map + 14 + 2 + 2*item); + if (unicode_codepoint < start) + return 0; + + offset = ttUSHORT(data + index_map + 14 + segcount*6 + 2 + 2*item); + if (offset == 0) + return (stbtt_uint16) (unicode_codepoint + ttSHORT(data + index_map + 14 + segcount*4 + 2 + 2*item)); + + return ttUSHORT(data + offset + (unicode_codepoint-start)*2 + index_map + 14 + segcount*6 + 2 + 2*item); + } else if (format == 12 || format == 13) { + stbtt_uint32 ngroups = ttULONG(data+index_map+12); + stbtt_int32 low,high; + low = 0; high = (stbtt_int32)ngroups; + // Binary search the right group. + while (low < high) { + stbtt_int32 mid = low + ((high-low) >> 1); // rounds down, so low <= mid < high + stbtt_uint32 start_char = ttULONG(data+index_map+16+mid*12); + stbtt_uint32 end_char = ttULONG(data+index_map+16+mid*12+4); + if ((stbtt_uint32) unicode_codepoint < start_char) + high = mid; + else if ((stbtt_uint32) unicode_codepoint > end_char) + low = mid+1; + else { + stbtt_uint32 start_glyph = ttULONG(data+index_map+16+mid*12+8); + if (format == 12) + return start_glyph + unicode_codepoint-start_char; + else // format == 13 + return start_glyph; + } + } + return 0; // not found + } + // @TODO + STBTT_assert(0); + return 0; +} + +STBTT_DEF int stbtt_GetCodepointShape(const stbtt_fontinfo *info, int unicode_codepoint, stbtt_vertex **vertices) +{ + return stbtt_GetGlyphShape(info, stbtt_FindGlyphIndex(info, unicode_codepoint), vertices); +} + +static void stbtt_setvertex(stbtt_vertex *v, stbtt_uint8 type, stbtt_int32 x, stbtt_int32 y, stbtt_int32 cx, stbtt_int32 cy) +{ + v->type = type; + v->x = (stbtt_int16) x; + v->y = (stbtt_int16) y; + v->cx = (stbtt_int16) cx; + v->cy = (stbtt_int16) cy; +} + +static int stbtt__GetGlyfOffset(const stbtt_fontinfo *info, int glyph_index) +{ + int g1,g2; + + if (glyph_index >= info->numGlyphs) return -1; // glyph index out of range + if (info->indexToLocFormat >= 2) return -1; // unknown index->glyph map format + + if (info->indexToLocFormat == 0) { + g1 = info->glyf + ttUSHORT(info->data + info->loca + glyph_index * 2) * 2; + g2 = info->glyf + ttUSHORT(info->data + info->loca + glyph_index * 2 + 2) * 2; + } else { + g1 = info->glyf + ttULONG (info->data + info->loca + glyph_index * 4); + g2 = info->glyf + ttULONG (info->data + info->loca + glyph_index * 4 + 4); + } + + return g1==g2 ? -1 : g1; // if length is 0, return -1 +} + +STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1) +{ + int g = stbtt__GetGlyfOffset(info, glyph_index); + if (g < 0) return 0; + + if (x0) *x0 = ttSHORT(info->data + g + 2); + if (y0) *y0 = ttSHORT(info->data + g + 4); + if (x1) *x1 = ttSHORT(info->data + g + 6); + if (y1) *y1 = ttSHORT(info->data + g + 8); + return 1; +} + +STBTT_DEF int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, int *x0, int *y0, int *x1, int *y1) +{ + return stbtt_GetGlyphBox(info, stbtt_FindGlyphIndex(info,codepoint), x0,y0,x1,y1); +} + +STBTT_DEF int stbtt_IsGlyphEmpty(const stbtt_fontinfo *info, int glyph_index) +{ + stbtt_int16 numberOfContours; + int g = stbtt__GetGlyfOffset(info, glyph_index); + if (g < 0) return 1; + numberOfContours = ttSHORT(info->data + g); + return numberOfContours == 0; +} + +static int stbtt__close_shape(stbtt_vertex *vertices, int num_vertices, int was_off, int start_off, + stbtt_int32 sx, stbtt_int32 sy, stbtt_int32 scx, stbtt_int32 scy, stbtt_int32 cx, stbtt_int32 cy) +{ + if (start_off) { + if (was_off) + stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, (cx+scx)>>1, (cy+scy)>>1, cx,cy); + stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, sx,sy,scx,scy); + } else { + if (was_off) + stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve,sx,sy,cx,cy); + else + stbtt_setvertex(&vertices[num_vertices++], STBTT_vline,sx,sy,0,0); + } + return num_vertices; +} + +STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **pvertices) +{ + stbtt_int16 numberOfContours; + stbtt_uint8 *endPtsOfContours; + stbtt_uint8 *data = info->data; + stbtt_vertex *vertices=0; + int num_vertices=0; + int g = stbtt__GetGlyfOffset(info, glyph_index); + + *pvertices = NULL; + + if (g < 0) return 0; + + numberOfContours = ttSHORT(data + g); + + if (numberOfContours > 0) { + stbtt_uint8 flags=0,flagcount; + stbtt_int32 ins, i,j=0,m,n, next_move, was_off=0, off, start_off=0; + stbtt_int32 x,y,cx,cy,sx,sy, scx,scy; + stbtt_uint8 *points; + endPtsOfContours = (data + g + 10); + ins = ttUSHORT(data + g + 10 + numberOfContours * 2); + points = data + g + 10 + numberOfContours * 2 + 2 + ins; + + n = 1+ttUSHORT(endPtsOfContours + numberOfContours*2-2); + + m = n + 2*numberOfContours; // a loose bound on how many vertices we might need + vertices = (stbtt_vertex *) STBTT_malloc(m * sizeof(vertices[0]), info->userdata); + if (vertices == 0) + return 0; + + next_move = 0; + flagcount=0; + + // in first pass, we load uninterpreted data into the allocated array + // above, shifted to the end of the array so we won't overwrite it when + // we create our final data starting from the front + + off = m - n; // starting offset for uninterpreted data, regardless of how m ends up being calculated + + // first load flags + + for (i=0; i < n; ++i) { + if (flagcount == 0) { + flags = *points++; + if (flags & 8) + flagcount = *points++; + } else + --flagcount; + vertices[off+i].type = flags; + } + + // now load x coordinates + x=0; + for (i=0; i < n; ++i) { + flags = vertices[off+i].type; + if (flags & 2) { + stbtt_int16 dx = *points++; + x += (flags & 16) ? dx : -dx; // ??? + } else { + if (!(flags & 16)) { + x = x + (stbtt_int16) (points[0]*256 + points[1]); + points += 2; + } + } + vertices[off+i].x = (stbtt_int16) x; + } + + // now load y coordinates + y=0; + for (i=0; i < n; ++i) { + flags = vertices[off+i].type; + if (flags & 4) { + stbtt_int16 dy = *points++; + y += (flags & 32) ? dy : -dy; // ??? + } else { + if (!(flags & 32)) { + y = y + (stbtt_int16) (points[0]*256 + points[1]); + points += 2; + } + } + vertices[off+i].y = (stbtt_int16) y; + } + + // now convert them to our format + num_vertices=0; + sx = sy = cx = cy = scx = scy = 0; + for (i=0; i < n; ++i) { + flags = vertices[off+i].type; + x = (stbtt_int16) vertices[off+i].x; + y = (stbtt_int16) vertices[off+i].y; + + if (next_move == i) { + if (i != 0) + num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy); + + // now start the new one + start_off = !(flags & 1); + if (start_off) { + // if we start off with an off-curve point, then when we need to find a point on the curve + // where we can start, and we need to save some state for when we wraparound. + scx = x; + scy = y; + if (!(vertices[off+i+1].type & 1)) { + // next point is also a curve point, so interpolate an on-point curve + sx = (x + (stbtt_int32) vertices[off+i+1].x) >> 1; + sy = (y + (stbtt_int32) vertices[off+i+1].y) >> 1; + } else { + // otherwise just use the next point as our start point + sx = (stbtt_int32) vertices[off+i+1].x; + sy = (stbtt_int32) vertices[off+i+1].y; + ++i; // we're using point i+1 as the starting point, so skip it + } + } else { + sx = x; + sy = y; + } + stbtt_setvertex(&vertices[num_vertices++], STBTT_vmove,sx,sy,0,0); + was_off = 0; + next_move = 1 + ttUSHORT(endPtsOfContours+j*2); + ++j; + } else { + if (!(flags & 1)) { // if it's a curve + if (was_off) // two off-curve control points in a row means interpolate an on-curve midpoint + stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, (cx+x)>>1, (cy+y)>>1, cx, cy); + cx = x; + cy = y; + was_off = 1; + } else { + if (was_off) + stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, x,y, cx, cy); + else + stbtt_setvertex(&vertices[num_vertices++], STBTT_vline, x,y,0,0); + was_off = 0; + } + } + } + num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy); + } else if (numberOfContours == -1) { + // Compound shapes. + int more = 1; + stbtt_uint8 *comp = data + g + 10; + num_vertices = 0; + vertices = 0; + while (more) { + stbtt_uint16 flags, gidx; + int comp_num_verts = 0, i; + stbtt_vertex *comp_verts = 0, *tmp = 0; + float mtx[6] = {1,0,0,1,0,0}, m, n; + + flags = ttSHORT(comp); comp+=2; + gidx = ttSHORT(comp); comp+=2; + + if (flags & 2) { // XY values + if (flags & 1) { // shorts + mtx[4] = ttSHORT(comp); comp+=2; + mtx[5] = ttSHORT(comp); comp+=2; + } else { + mtx[4] = ttCHAR(comp); comp+=1; + mtx[5] = ttCHAR(comp); comp+=1; + } + } + else { + // @TODO handle matching point + STBTT_assert(0); + } + if (flags & (1<<3)) { // WE_HAVE_A_SCALE + mtx[0] = mtx[3] = ttSHORT(comp)/16384.0f; comp+=2; + mtx[1] = mtx[2] = 0; + } else if (flags & (1<<6)) { // WE_HAVE_AN_X_AND_YSCALE + mtx[0] = ttSHORT(comp)/16384.0f; comp+=2; + mtx[1] = mtx[2] = 0; + mtx[3] = ttSHORT(comp)/16384.0f; comp+=2; + } else if (flags & (1<<7)) { // WE_HAVE_A_TWO_BY_TWO + mtx[0] = ttSHORT(comp)/16384.0f; comp+=2; + mtx[1] = ttSHORT(comp)/16384.0f; comp+=2; + mtx[2] = ttSHORT(comp)/16384.0f; comp+=2; + mtx[3] = ttSHORT(comp)/16384.0f; comp+=2; + } + + // Find transformation scales. + m = (float) STBTT_sqrt(mtx[0]*mtx[0] + mtx[1]*mtx[1]); + n = (float) STBTT_sqrt(mtx[2]*mtx[2] + mtx[3]*mtx[3]); + + // Get indexed glyph. + comp_num_verts = stbtt_GetGlyphShape(info, gidx, &comp_verts); + if (comp_num_verts > 0) { + // Transform vertices. + for (i = 0; i < comp_num_verts; ++i) { + stbtt_vertex* v = &comp_verts[i]; + stbtt_vertex_type x,y; + x=v->x; y=v->y; + v->x = (stbtt_vertex_type)(m * (mtx[0]*x + mtx[2]*y + mtx[4])); + v->y = (stbtt_vertex_type)(n * (mtx[1]*x + mtx[3]*y + mtx[5])); + x=v->cx; y=v->cy; + v->cx = (stbtt_vertex_type)(m * (mtx[0]*x + mtx[2]*y + mtx[4])); + v->cy = (stbtt_vertex_type)(n * (mtx[1]*x + mtx[3]*y + mtx[5])); + } + // Append vertices. + tmp = (stbtt_vertex*)STBTT_malloc((num_vertices+comp_num_verts)*sizeof(stbtt_vertex), info->userdata); + if (!tmp) { + if (vertices) STBTT_free(vertices, info->userdata); + if (comp_verts) STBTT_free(comp_verts, info->userdata); + return 0; + } + if (num_vertices > 0) STBTT_memcpy(tmp, vertices, num_vertices*sizeof(stbtt_vertex)); + STBTT_memcpy(tmp+num_vertices, comp_verts, comp_num_verts*sizeof(stbtt_vertex)); + if (vertices) STBTT_free(vertices, info->userdata); + vertices = tmp; + STBTT_free(comp_verts, info->userdata); + num_vertices += comp_num_verts; + } + // More components ? + more = flags & (1<<5); + } + } else if (numberOfContours < 0) { + // @TODO other compound variations? + STBTT_assert(0); + } else { + // numberOfCounters == 0, do nothing + } + + *pvertices = vertices; + return num_vertices; +} + +STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_index, int *advanceWidth, int *leftSideBearing) +{ + stbtt_uint16 numOfLongHorMetrics = ttUSHORT(info->data+info->hhea + 34); + if (glyph_index < numOfLongHorMetrics) { + if (advanceWidth) *advanceWidth = ttSHORT(info->data + info->hmtx + 4*glyph_index); + if (leftSideBearing) *leftSideBearing = ttSHORT(info->data + info->hmtx + 4*glyph_index + 2); + } else { + if (advanceWidth) *advanceWidth = ttSHORT(info->data + info->hmtx + 4*(numOfLongHorMetrics-1)); + if (leftSideBearing) *leftSideBearing = ttSHORT(info->data + info->hmtx + 4*numOfLongHorMetrics + 2*(glyph_index - numOfLongHorMetrics)); + } +} + +STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2) +{ + stbtt_uint8 *data = info->data + info->kern; + stbtt_uint32 needle, straw; + int l, r, m; + + // we only look at the first table. it must be 'horizontal' and format 0. + if (!info->kern) + return 0; + if (ttUSHORT(data+2) < 1) // number of tables, need at least 1 + return 0; + if (ttUSHORT(data+8) != 1) // horizontal flag must be set in format + return 0; + + l = 0; + r = ttUSHORT(data+10) - 1; + needle = glyph1 << 16 | glyph2; + while (l <= r) { + m = (l + r) >> 1; + straw = ttULONG(data+18+(m*6)); // note: unaligned read + if (needle < straw) + r = m - 1; + else if (needle > straw) + l = m + 1; + else + return ttSHORT(data+22+(m*6)); + } + return 0; +} + +STBTT_DEF int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2) +{ + if (!info->kern) // if no kerning table, don't waste time looking up both codepoint->glyphs + return 0; + return stbtt_GetGlyphKernAdvance(info, stbtt_FindGlyphIndex(info,ch1), stbtt_FindGlyphIndex(info,ch2)); +} + +STBTT_DEF void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, int codepoint, int *advanceWidth, int *leftSideBearing) +{ + stbtt_GetGlyphHMetrics(info, stbtt_FindGlyphIndex(info,codepoint), advanceWidth, leftSideBearing); +} + +STBTT_DEF void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, int *descent, int *lineGap) +{ + if (ascent ) *ascent = ttSHORT(info->data+info->hhea + 4); + if (descent) *descent = ttSHORT(info->data+info->hhea + 6); + if (lineGap) *lineGap = ttSHORT(info->data+info->hhea + 8); +} + +STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int *x0, int *y0, int *x1, int *y1) +{ + *x0 = ttSHORT(info->data + info->head + 36); + *y0 = ttSHORT(info->data + info->head + 38); + *x1 = ttSHORT(info->data + info->head + 40); + *y1 = ttSHORT(info->data + info->head + 42); +} + +STBTT_DEF float stbtt_ScaleForPixelHeight(const stbtt_fontinfo *info, float height) +{ + int fheight = ttSHORT(info->data + info->hhea + 4) - ttSHORT(info->data + info->hhea + 6); + return (float) height / fheight; +} + +STBTT_DEF float stbtt_ScaleForMappingEmToPixels(const stbtt_fontinfo *info, float pixels) +{ + int unitsPerEm = ttUSHORT(info->data + info->head + 18); + return pixels / unitsPerEm; +} + +STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *v) +{ + STBTT_free(v, info->userdata); +} + +////////////////////////////////////////////////////////////////////////////// +// +// antialiasing software rasterizer +// + +STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y,float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1) +{ + int x0,y0,x1,y1; + if (!stbtt_GetGlyphBox(font, glyph, &x0,&y0,&x1,&y1)) { + // e.g. space character + if (ix0) *ix0 = 0; + if (iy0) *iy0 = 0; + if (ix1) *ix1 = 0; + if (iy1) *iy1 = 0; + } else { + // move to integral bboxes (treating pixels as little squares, what pixels get touched)? + if (ix0) *ix0 = STBTT_ifloor( x0 * scale_x + shift_x); + if (iy0) *iy0 = STBTT_ifloor(-y1 * scale_y + shift_y); + if (ix1) *ix1 = STBTT_iceil ( x1 * scale_x + shift_x); + if (iy1) *iy1 = STBTT_iceil (-y0 * scale_y + shift_y); + } +} + +STBTT_DEF void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1) +{ + stbtt_GetGlyphBitmapBoxSubpixel(font, glyph, scale_x, scale_y,0.0f,0.0f, ix0, iy0, ix1, iy1); +} + +STBTT_DEF void stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1) +{ + stbtt_GetGlyphBitmapBoxSubpixel(font, stbtt_FindGlyphIndex(font,codepoint), scale_x, scale_y,shift_x,shift_y, ix0,iy0,ix1,iy1); +} + +STBTT_DEF void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1) +{ + stbtt_GetCodepointBitmapBoxSubpixel(font, codepoint, scale_x, scale_y,0.0f,0.0f, ix0,iy0,ix1,iy1); +} + +typedef struct stbtt__edge { + float x0,y0, x1,y1; + int invert; +} stbtt__edge; + +typedef struct stbtt__active_edge +{ + int x,dx; + float ey; + struct stbtt__active_edge *next; + int valid; +} stbtt__active_edge; + +#define FIXSHIFT 10 +#define FIX (1 << FIXSHIFT) +#define FIXMASK (FIX-1) + +static stbtt__active_edge *new_active(stbtt__edge *e, int off_x, float start_point, void *userdata) +{ + stbtt__active_edge *z = (stbtt__active_edge *) STBTT_malloc(sizeof(*z), userdata); // @TODO: make a pool of these!!! + float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0); + STBTT_assert(e->y0 <= start_point); + if (!z) return z; + // round dx down to avoid going too far + if (dxdy < 0) + z->dx = -STBTT_ifloor(FIX * -dxdy); + else + z->dx = STBTT_ifloor(FIX * dxdy); + z->x = STBTT_ifloor(FIX * (e->x0 + dxdy * (start_point - e->y0))); + z->x -= off_x * FIX; + z->ey = e->y1; + z->next = 0; + z->valid = e->invert ? 1 : -1; + return z; +} + +// note: this routine clips fills that extend off the edges... ideally this +// wouldn't happen, but it could happen if the truetype glyph bounding boxes +// are wrong, or if the user supplies a too-small bitmap +static void stbtt__fill_active_edges(unsigned char *scanline, int len, stbtt__active_edge *e, int max_weight) +{ + // non-zero winding fill + int x0=0, w=0; + + while (e) { + if (w == 0) { + // if we're currently at zero, we need to record the edge start point + x0 = e->x; w += e->valid; + } else { + int x1 = e->x; w += e->valid; + // if we went to zero, we need to draw + if (w == 0) { + int i = x0 >> FIXSHIFT; + int j = x1 >> FIXSHIFT; + + if (i < len && j >= 0) { + if (i == j) { + // x0,x1 are the same pixel, so compute combined coverage + scanline[i] = scanline[i] + (stbtt_uint8) ((x1 - x0) * max_weight >> FIXSHIFT); + } else { + if (i >= 0) // add antialiasing for x0 + scanline[i] = scanline[i] + (stbtt_uint8) (((FIX - (x0 & FIXMASK)) * max_weight) >> FIXSHIFT); + else + i = -1; // clip + + if (j < len) // add antialiasing for x1 + scanline[j] = scanline[j] + (stbtt_uint8) (((x1 & FIXMASK) * max_weight) >> FIXSHIFT); + else + j = len; // clip + + for (++i; i < j; ++i) // fill pixels between x0 and x1 + scanline[i] = scanline[i] + (stbtt_uint8) max_weight; + } + } + } + } + + e = e->next; + } +} + +static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata) +{ + stbtt__active_edge *active = NULL; + int y,j=0; + int max_weight = (255 / vsubsample); // weight per vertical scanline + int s; // vertical subsample index + unsigned char scanline_data[512], *scanline; + + if (result->w > 512) + scanline = (unsigned char *) STBTT_malloc(result->w, userdata); + else + scanline = scanline_data; + + y = off_y * vsubsample; + e[n].y0 = (off_y + result->h) * (float) vsubsample + 1; + + while (j < result->h) { + STBTT_memset(scanline, 0, result->w); + for (s=0; s < vsubsample; ++s) { + // find center of pixel for this scanline + float scan_y = y + 0.5f; + stbtt__active_edge **step = &active; + + // update all active edges; + // remove all active edges that terminate before the center of this scanline + while (*step) { + stbtt__active_edge * z = *step; + if (z->ey <= scan_y) { + *step = z->next; // delete from list + STBTT_assert(z->valid); + z->valid = 0; + STBTT_free(z, userdata); + } else { + z->x += z->dx; // advance to position for current scanline + step = &((*step)->next); // advance through list + } + } + + // resort the list if needed + for(;;) { + int changed=0; + step = &active; + while (*step && (*step)->next) { + if ((*step)->x > (*step)->next->x) { + stbtt__active_edge *t = *step; + stbtt__active_edge *q = t->next; + + t->next = q->next; + q->next = t; + *step = q; + changed = 1; + } + step = &(*step)->next; + } + if (!changed) break; + } + + // insert all edges that start before the center of this scanline -- omit ones that also end on this scanline + while (e->y0 <= scan_y) { + if (e->y1 > scan_y) { + stbtt__active_edge *z = new_active(e, off_x, scan_y, userdata); + // find insertion point + if (active == NULL) + active = z; + else if (z->x < active->x) { + // insert at front + z->next = active; + active = z; + } else { + // find thing to insert AFTER + stbtt__active_edge *p = active; + while (p->next && p->next->x < z->x) + p = p->next; + // at this point, p->next->x is NOT < z->x + z->next = p->next; + p->next = z; + } + } + ++e; + } + + // now process all active edges in XOR fashion + if (active) + stbtt__fill_active_edges(scanline, result->w, active, max_weight); + + ++y; + } + STBTT_memcpy(result->pixels + j * result->stride, scanline, result->w); + ++j; + } + + while (active) { + stbtt__active_edge *z = active; + active = active->next; + STBTT_free(z, userdata); + } + + if (scanline != scanline_data) + STBTT_free(scanline, userdata); +} + +static int stbtt__edge_compare(const void *p, const void *q) +{ + stbtt__edge *a = (stbtt__edge *) p; + stbtt__edge *b = (stbtt__edge *) q; + + if (a->y0 < b->y0) return -1; + if (a->y0 > b->y0) return 1; + return 0; +} + +typedef struct +{ + float x,y; +} stbtt__point; + +static void stbtt__rasterize(stbtt__bitmap *result, stbtt__point *pts, int *wcount, int windings, float scale_x, float scale_y, float shift_x, float shift_y, int off_x, int off_y, int invert, void *userdata) +{ + float y_scale_inv = invert ? -scale_y : scale_y; + stbtt__edge *e; + int n,i,j,k,m; + int vsubsample = result->h < 8 ? 15 : 5; + // vsubsample should divide 255 evenly; otherwise we won't reach full opacity + + // now we have to blow out the windings into explicit edge lists + n = 0; + for (i=0; i < windings; ++i) + n += wcount[i]; + + e = (stbtt__edge *) STBTT_malloc(sizeof(*e) * (n+1), userdata); // add an extra one as a sentinel + if (e == 0) return; + n = 0; + + m=0; + for (i=0; i < windings; ++i) { + stbtt__point *p = pts + m; + m += wcount[i]; + j = wcount[i]-1; + for (k=0; k < wcount[i]; j=k++) { + int a=k,b=j; + // skip the edge if horizontal + if (p[j].y == p[k].y) + continue; + // add edge from j to k to the list + e[n].invert = 0; + if (invert ? p[j].y > p[k].y : p[j].y < p[k].y) { + e[n].invert = 1; + a=j,b=k; + } + e[n].x0 = p[a].x * scale_x + shift_x; + e[n].y0 = (p[a].y * y_scale_inv + shift_y) * vsubsample; + e[n].x1 = p[b].x * scale_x + shift_x; + e[n].y1 = (p[b].y * y_scale_inv + shift_y) * vsubsample; + ++n; + } + } + + // now sort the edges by their highest point (should snap to integer, and then by x) + STBTT_sort(e, n, sizeof(e[0]), stbtt__edge_compare); + + // now, traverse the scanlines and find the intersections on each scanline, use xor winding rule + stbtt__rasterize_sorted_edges(result, e, n, vsubsample, off_x, off_y, userdata); + + STBTT_free(e, userdata); +} + +static void stbtt__add_point(stbtt__point *points, int n, float x, float y) +{ + if (!points) return; // during first pass, it's unallocated + points[n].x = x; + points[n].y = y; +} + +// tesselate until threshhold p is happy... @TODO warped to compensate for non-linear stretching +static int stbtt__tesselate_curve(stbtt__point *points, int *num_points, float x0, float y0, float x1, float y1, float x2, float y2, float objspace_flatness_squared, int n) +{ + // midpoint + float mx = (x0 + 2*x1 + x2)/4; + float my = (y0 + 2*y1 + y2)/4; + // versus directly drawn line + float dx = (x0+x2)/2 - mx; + float dy = (y0+y2)/2 - my; + if (n > 16) // 65536 segments on one curve better be enough! + return 1; + if (dx*dx+dy*dy > objspace_flatness_squared) { // half-pixel error allowed... need to be smaller if AA + stbtt__tesselate_curve(points, num_points, x0,y0, (x0+x1)/2.0f,(y0+y1)/2.0f, mx,my, objspace_flatness_squared,n+1); + stbtt__tesselate_curve(points, num_points, mx,my, (x1+x2)/2.0f,(y1+y2)/2.0f, x2,y2, objspace_flatness_squared,n+1); + } else { + stbtt__add_point(points, *num_points,x2,y2); + *num_points = *num_points+1; + } + return 1; +} + +// returns number of contours +static stbtt__point *stbtt_FlattenCurves(stbtt_vertex *vertices, int num_verts, float objspace_flatness, int **contour_lengths, int *num_contours, void *userdata) +{ + stbtt__point *points=0; + int num_points=0; + + float objspace_flatness_squared = objspace_flatness * objspace_flatness; + int i,n=0,start=0, pass; + + // count how many "moves" there are to get the contour count + for (i=0; i < num_verts; ++i) + if (vertices[i].type == STBTT_vmove) + ++n; + + *num_contours = n; + if (n == 0) return 0; + + *contour_lengths = (int *) STBTT_malloc(sizeof(**contour_lengths) * n, userdata); + + if (*contour_lengths == 0) { + *num_contours = 0; + return 0; + } + + // make two passes through the points so we don't need to realloc + for (pass=0; pass < 2; ++pass) { + float x=0,y=0; + if (pass == 1) { + points = (stbtt__point *) STBTT_malloc(num_points * sizeof(points[0]), userdata); + if (points == NULL) goto error; + } + num_points = 0; + n= -1; + for (i=0; i < num_verts; ++i) { + switch (vertices[i].type) { + case STBTT_vmove: + // start the next contour + if (n >= 0) + (*contour_lengths)[n] = num_points - start; + ++n; + start = num_points; + + x = vertices[i].x, y = vertices[i].y; + stbtt__add_point(points, num_points++, x,y); + break; + case STBTT_vline: + x = vertices[i].x, y = vertices[i].y; + stbtt__add_point(points, num_points++, x, y); + break; + case STBTT_vcurve: + stbtt__tesselate_curve(points, &num_points, x,y, + vertices[i].cx, vertices[i].cy, + vertices[i].x, vertices[i].y, + objspace_flatness_squared, 0); + x = vertices[i].x, y = vertices[i].y; + break; + } + } + (*contour_lengths)[n] = num_points - start; + } + + return points; +error: + STBTT_free(points, userdata); + STBTT_free(*contour_lengths, userdata); + *contour_lengths = 0; + *num_contours = 0; + return NULL; +} + +STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result, float flatness_in_pixels, stbtt_vertex *vertices, int num_verts, float scale_x, float scale_y, float shift_x, float shift_y, int x_off, int y_off, int invert, void *userdata) +{ + float scale = scale_x > scale_y ? scale_y : scale_x; + int winding_count, *winding_lengths; + stbtt__point *windings = stbtt_FlattenCurves(vertices, num_verts, flatness_in_pixels / scale, &winding_lengths, &winding_count, userdata); + if (windings) { + stbtt__rasterize(result, windings, winding_lengths, winding_count, scale_x, scale_y, shift_x, shift_y, x_off, y_off, invert, userdata); + STBTT_free(winding_lengths, userdata); + STBTT_free(windings, userdata); + } +} + +STBTT_DEF void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata) +{ + STBTT_free(bitmap, userdata); +} + +STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int glyph, int *width, int *height, int *xoff, int *yoff) +{ + int ix0,iy0,ix1,iy1; + stbtt__bitmap gbm; + stbtt_vertex *vertices; + int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices); + + if (scale_x == 0) scale_x = scale_y; + if (scale_y == 0) { + if (scale_x == 0) return NULL; + scale_y = scale_x; + } + + stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0,&iy0,&ix1,&iy1); + + // now we get the size + gbm.w = (ix1 - ix0); + gbm.h = (iy1 - iy0); + gbm.pixels = NULL; // in case we error + + if (width ) *width = gbm.w; + if (height) *height = gbm.h; + if (xoff ) *xoff = ix0; + if (yoff ) *yoff = iy0; + + if (gbm.w && gbm.h) { + gbm.pixels = (unsigned char *) STBTT_malloc(gbm.w * gbm.h, info->userdata); + if (gbm.pixels) { + gbm.stride = gbm.w; + + stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0, iy0, 1, info->userdata); + } + } + STBTT_free(vertices, info->userdata); + return gbm.pixels; +} + +STBTT_DEF unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int glyph, int *width, int *height, int *xoff, int *yoff) +{ + return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y, 0.0f, 0.0f, glyph, width, height, xoff, yoff); +} + +STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int glyph) +{ + int ix0,iy0; + stbtt_vertex *vertices; + int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices); + stbtt__bitmap gbm; + + stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0,&iy0,0,0); + gbm.pixels = output; + gbm.w = out_w; + gbm.h = out_h; + gbm.stride = out_stride; + + if (gbm.w && gbm.h) + stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0,iy0, 1, info->userdata); + + STBTT_free(vertices, info->userdata); +} + +STBTT_DEF void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int glyph) +{ + stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, 0.0f,0.0f, glyph); +} + +STBTT_DEF unsigned char *stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint, int *width, int *height, int *xoff, int *yoff) +{ + return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y,shift_x,shift_y, stbtt_FindGlyphIndex(info,codepoint), width,height,xoff,yoff); +} + +STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint) +{ + stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, shift_x, shift_y, stbtt_FindGlyphIndex(info,codepoint)); +} + +STBTT_DEF unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int codepoint, int *width, int *height, int *xoff, int *yoff) +{ + return stbtt_GetCodepointBitmapSubpixel(info, scale_x, scale_y, 0.0f,0.0f, codepoint, width,height,xoff,yoff); +} + +STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int codepoint) +{ + stbtt_MakeCodepointBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, 0.0f,0.0f, codepoint); +} + +////////////////////////////////////////////////////////////////////////////// +// +// bitmap baking +// +// This is SUPER-CRAPPY packing to keep source code small + +STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset, // font location (use offset=0 for plain .ttf) + float pixel_height, // height of font in pixels + unsigned char *pixels, int pw, int ph, // bitmap to be filled in + int first_char, int num_chars, // characters to bake + stbtt_bakedchar *chardata) +{ + float scale; + int x,y,bottom_y, i; + stbtt_fontinfo f; + if (!stbtt_InitFont(&f, data, offset)) + return -1; + STBTT_memset(pixels, 0, pw*ph); // background of 0 around pixels + x=y=1; + bottom_y = 1; + + scale = stbtt_ScaleForPixelHeight(&f, pixel_height); + + for (i=0; i < num_chars; ++i) { + int advance, lsb, x0,y0,x1,y1,gw,gh; + int g = stbtt_FindGlyphIndex(&f, first_char + i); + stbtt_GetGlyphHMetrics(&f, g, &advance, &lsb); + stbtt_GetGlyphBitmapBox(&f, g, scale,scale, &x0,&y0,&x1,&y1); + gw = x1-x0; + gh = y1-y0; + if (x + gw + 1 >= pw) + y = bottom_y, x = 1; // advance to next row + if (y + gh + 1 >= ph) // check if it fits vertically AFTER potentially moving to next row + return -i; + STBTT_assert(x+gw < pw); + STBTT_assert(y+gh < ph); + stbtt_MakeGlyphBitmap(&f, pixels+x+y*pw, gw,gh,pw, scale,scale, g); + chardata[i].x0 = (stbtt_int16) x; + chardata[i].y0 = (stbtt_int16) y; + chardata[i].x1 = (stbtt_int16) (x + gw); + chardata[i].y1 = (stbtt_int16) (y + gh); + chardata[i].xadvance = scale * advance; + chardata[i].xoff = (float) x0; + chardata[i].yoff = (float) y0; + x = x + gw + 1; + if (y+gh+1 > bottom_y) + bottom_y = y+gh+1; + } + return bottom_y; +} + +STBTT_DEF void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int opengl_fillrule) +{ + float d3d_bias = opengl_fillrule ? 0 : -0.5f; + float ipw = 1.0f / pw, iph = 1.0f / ph; + stbtt_bakedchar *b = chardata + char_index; + int round_x = STBTT_ifloor((*xpos + b->xoff) + 0.5); + int round_y = STBTT_ifloor((*ypos + b->yoff) + 0.5); + + q->x0 = round_x + d3d_bias; + q->y0 = round_y + d3d_bias; + q->x1 = round_x + b->x1 - b->x0 + d3d_bias; + q->y1 = round_y + b->y1 - b->y0 + d3d_bias; + + q->s0 = b->x0 * ipw; + q->t0 = b->y0 * iph; + q->s1 = b->x1 * ipw; + q->t1 = b->y1 * iph; + + *xpos += b->xadvance; +} + +////////////////////////////////////////////////////////////////////////////// +// +// rectangle packing replacement routines if you don't have stb_rect_pack.h +// + +#ifndef STB_RECT_PACK_VERSION +#ifdef _MSC_VER +#define STBTT__NOTUSED(v) (void)(v) +#else +#define STBTT__NOTUSED(v) (void)sizeof(v) +#endif + +typedef int stbrp_coord; + +//////////////////////////////////////////////////////////////////////////////////// +// // +// // +// COMPILER WARNING ?!?!? // +// // +// // +// if you get a compile warning due to these symbols being defined more than // +// once, move #include "stb_rect_pack.h" before #include "stb_truetype.h" // +// // +//////////////////////////////////////////////////////////////////////////////////// + +typedef struct +{ + int width,height; + int x,y,bottom_y; +} stbrp_context; + +typedef struct +{ + unsigned char x; +} stbrp_node; + +struct stbrp_rect +{ + stbrp_coord x,y; + int id,w,h,was_packed; +}; + +static void stbrp_init_target(stbrp_context *con, int pw, int ph, stbrp_node *nodes, int num_nodes) +{ + con->width = pw; + con->height = ph; + con->x = 0; + con->y = 0; + con->bottom_y = 0; + STBTT__NOTUSED(nodes); + STBTT__NOTUSED(num_nodes); +} + +static void stbrp_pack_rects(stbrp_context *con, stbrp_rect *rects, int num_rects) +{ + int i; + for (i=0; i < num_rects; ++i) { + if (con->x + rects[i].w > con->width) { + con->x = 0; + con->y = con->bottom_y; + } + if (con->y + rects[i].h > con->height) + break; + rects[i].x = con->x; + rects[i].y = con->y; + rects[i].was_packed = 1; + con->x += rects[i].w; + if (con->y + rects[i].h > con->bottom_y) + con->bottom_y = con->y + rects[i].h; + } + for ( ; i < num_rects; ++i) + rects[i].was_packed = 0; +} +#endif + +////////////////////////////////////////////////////////////////////////////// +// +// bitmap baking +// +// This is SUPER-AWESOME (tm Ryan Gordon) packing using stb_rect_pack.h. If +// stb_rect_pack.h isn't available, it uses the BakeFontBitmap strategy. + +STBTT_DEF int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, int pw, int ph, int stride_in_bytes, int padding, void *alloc_context) +{ + stbrp_context *context = (stbrp_context *) STBTT_malloc(sizeof(*context) ,alloc_context); + int num_nodes = pw - padding; + stbrp_node *nodes = (stbrp_node *) STBTT_malloc(sizeof(*nodes ) * num_nodes,alloc_context); + + if (context == NULL || nodes == NULL) { + if (context != NULL) STBTT_free(context, alloc_context); + if (nodes != NULL) STBTT_free(nodes , alloc_context); + return 0; + } + + spc->user_allocator_context = alloc_context; + spc->width = pw; + spc->height = ph; + spc->pixels = pixels; + spc->pack_info = context; + spc->nodes = nodes; + spc->padding = padding; + spc->stride_in_bytes = stride_in_bytes != 0 ? stride_in_bytes : pw; + spc->h_oversample = 1; + spc->v_oversample = 1; + + stbrp_init_target(context, pw-padding, ph-padding, nodes, num_nodes); + + if (pixels) + STBTT_memset(pixels, 0, pw*ph); // background of 0 around pixels + + return 1; +} + +STBTT_DEF void stbtt_PackEnd (stbtt_pack_context *spc) +{ + STBTT_free(spc->nodes , spc->user_allocator_context); + STBTT_free(spc->pack_info, spc->user_allocator_context); +} + +STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h_oversample, unsigned int v_oversample) +{ + STBTT_assert(h_oversample <= STBTT_MAX_OVERSAMPLE); + STBTT_assert(v_oversample <= STBTT_MAX_OVERSAMPLE); + if (h_oversample <= STBTT_MAX_OVERSAMPLE) + spc->h_oversample = h_oversample; + if (v_oversample <= STBTT_MAX_OVERSAMPLE) + spc->v_oversample = v_oversample; +} + +#define STBTT__OVER_MASK (STBTT_MAX_OVERSAMPLE-1) + +static void stbtt__h_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width) +{ + unsigned char buffer[STBTT_MAX_OVERSAMPLE]; + int safe_w = w - kernel_width; + int j; + for (j=0; j < h; ++j) { + int i; + unsigned int total; + memset(buffer, 0, kernel_width); + + total = 0; + + // make kernel_width a constant in common cases so compiler can optimize out the divide + switch (kernel_width) { + case 2: + for (i=0; i <= safe_w; ++i) { + total += pixels[i] - buffer[i & STBTT__OVER_MASK]; + buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i]; + pixels[i] = (unsigned char) (total / 2); + } + break; + case 3: + for (i=0; i <= safe_w; ++i) { + total += pixels[i] - buffer[i & STBTT__OVER_MASK]; + buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i]; + pixels[i] = (unsigned char) (total / 3); + } + break; + case 4: + for (i=0; i <= safe_w; ++i) { + total += pixels[i] - buffer[i & STBTT__OVER_MASK]; + buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i]; + pixels[i] = (unsigned char) (total / 4); + } + break; + default: + for (i=0; i <= safe_w; ++i) { + total += pixels[i] - buffer[i & STBTT__OVER_MASK]; + buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i]; + pixels[i] = (unsigned char) (total / kernel_width); + } + break; + } + + for (; i < w; ++i) { + STBTT_assert(pixels[i] == 0); + total -= buffer[i & STBTT__OVER_MASK]; + pixels[i] = (unsigned char) (total / kernel_width); + } + + pixels += stride_in_bytes; + } +} + +static void stbtt__v_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width) +{ + unsigned char buffer[STBTT_MAX_OVERSAMPLE]; + int safe_h = h - kernel_width; + int j; + for (j=0; j < w; ++j) { + int i; + unsigned int total; + memset(buffer, 0, kernel_width); + + total = 0; + + // make kernel_width a constant in common cases so compiler can optimize out the divide + switch (kernel_width) { + case 2: + for (i=0; i <= safe_h; ++i) { + total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; + buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes]; + pixels[i*stride_in_bytes] = (unsigned char) (total / 2); + } + break; + case 3: + for (i=0; i <= safe_h; ++i) { + total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; + buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes]; + pixels[i*stride_in_bytes] = (unsigned char) (total / 3); + } + break; + case 4: + for (i=0; i <= safe_h; ++i) { + total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; + buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes]; + pixels[i*stride_in_bytes] = (unsigned char) (total / 4); + } + break; + default: + for (i=0; i <= safe_h; ++i) { + total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; + buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes]; + pixels[i*stride_in_bytes] = (unsigned char) (total / kernel_width); + } + break; + } + + for (; i < h; ++i) { + STBTT_assert(pixels[i*stride_in_bytes] == 0); + total -= buffer[i & STBTT__OVER_MASK]; + pixels[i*stride_in_bytes] = (unsigned char) (total / kernel_width); + } + + pixels += 1; + } +} + +static float stbtt__oversample_shift(int oversample) +{ + if (!oversample) + return 0.0f; + + // The prefilter is a box filter of width "oversample", + // which shifts phase by (oversample - 1)/2 pixels in + // oversampled space. We want to shift in the opposite + // direction to counter this. + return (float)-(oversample - 1) / (2.0f * (float)oversample); +} + +// rects array must be big enough to accommodate all characters in the given ranges +STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects) +{ + int i,j,k; + + k=0; + for (i=0; i < num_ranges; ++i) { + float fh = ranges[i].font_size; + float scale = fh > 0 ? stbtt_ScaleForPixelHeight(info, fh) : stbtt_ScaleForMappingEmToPixels(info, -fh); + for (j=0; j < ranges[i].num_chars_in_range; ++j) { + int x0,y0,x1,y1; + int glyph = stbtt_FindGlyphIndex(info,ranges[i].first_unicode_char_in_range + j); + if (glyph) { + stbtt_GetGlyphBitmapBoxSubpixel(info,glyph, + scale * spc->h_oversample, + scale * spc->v_oversample, + 0,0, + &x0,&y0,&x1,&y1); + rects[k].w = (stbrp_coord) (x1-x0 + spc->padding + spc->h_oversample-1); + rects[k].h = (stbrp_coord) (y1-y0 + spc->padding + spc->v_oversample-1); + } else { + rects[k].w = rects[k].h = 1; + } + ++k; + } + } + + return k; +} + +// rects array must be big enough to accommodate all characters in the given ranges +STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects) +{ + float recip_h = 1.0f / spc->h_oversample; + float recip_v = 1.0f / spc->v_oversample; + float sub_x = stbtt__oversample_shift(spc->h_oversample); + float sub_y = stbtt__oversample_shift(spc->v_oversample); + int i,j,k, return_value = 1; + + k = 0; + for (i=0; i < num_ranges; ++i) { + float fh = ranges[i].font_size; + float scale = fh > 0 ? stbtt_ScaleForPixelHeight(info, fh) : stbtt_ScaleForMappingEmToPixels(info, -fh); + for (j=0; j < ranges[i].num_chars_in_range; ++j) { + stbrp_rect *r = &rects[k]; + if (r->was_packed) { + stbtt_packedchar *bc = &ranges[i].chardata_for_range[j]; + int advance, lsb, x0,y0,x1,y1; + int glyph = stbtt_FindGlyphIndex(info, ranges[i].first_unicode_char_in_range + j); + stbrp_coord pad = (stbrp_coord) spc->padding; + + // pad on left and top + r->x += pad; + r->y += pad; + r->w -= pad; + r->h -= pad; + stbtt_GetGlyphHMetrics(info, glyph, &advance, &lsb); + stbtt_GetGlyphBitmapBox(info, glyph, + scale * spc->h_oversample, + scale * spc->v_oversample, + &x0,&y0,&x1,&y1); + stbtt_MakeGlyphBitmapSubpixel(info, + spc->pixels + r->x + r->y*spc->stride_in_bytes, + r->w - spc->h_oversample+1, + r->h - spc->v_oversample+1, + spc->stride_in_bytes, + scale * spc->h_oversample, + scale * spc->v_oversample, + 0,0, + glyph); + + if (spc->h_oversample > 1) + stbtt__h_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes, + r->w, r->h, spc->stride_in_bytes, + spc->h_oversample); + + if (spc->v_oversample > 1) + stbtt__v_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes, + r->w, r->h, spc->stride_in_bytes, + spc->v_oversample); + + bc->x0 = (stbtt_int16) r->x; + bc->y0 = (stbtt_int16) r->y; + bc->x1 = (stbtt_int16) (r->x + r->w); + bc->y1 = (stbtt_int16) (r->y + r->h); + bc->xadvance = scale * advance; + bc->xoff = (float) x0 * recip_h + sub_x; + bc->yoff = (float) y0 * recip_v + sub_y; + bc->xoff2 = (x0 + r->w) * recip_h + sub_x; + bc->yoff2 = (y0 + r->h) * recip_v + sub_y; + } else { + return_value = 0; // if any fail, report failure + } + + ++k; + } + } + + return return_value; +} + +STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges) +{ + stbtt_fontinfo info; + int i,j,n, return_value = 1; + stbrp_context *context = (stbrp_context *) spc->pack_info; + stbrp_rect *rects; + + // flag all characters as NOT packed + for (i=0; i < num_ranges; ++i) + for (j=0; j < ranges[i].num_chars_in_range; ++j) + ranges[i].chardata_for_range[j].x0 = + ranges[i].chardata_for_range[j].y0 = + ranges[i].chardata_for_range[j].x1 = + ranges[i].chardata_for_range[j].y1 = 0; + + n = 0; + for (i=0; i < num_ranges; ++i) + n += ranges[i].num_chars_in_range; + + rects = (stbrp_rect *) STBTT_malloc(sizeof(*rects) * n, spc->user_allocator_context); + if (rects == NULL) + return 0; + + stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata,font_index)); + + n = stbtt_PackFontRangesGatherRects(spc, &info, ranges, num_ranges, rects); + + stbrp_pack_rects(context, rects, n); + + return_value = stbtt_PackFontRangesRenderIntoRects(spc, &info, ranges, num_ranges, rects); + + return return_value; +} + +STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, float font_size, + int first_unicode_char_in_range, int num_chars_in_range, stbtt_packedchar *chardata_for_range) +{ + stbtt_pack_range range; + range.first_unicode_char_in_range = first_unicode_char_in_range; + range.num_chars_in_range = num_chars_in_range; + range.chardata_for_range = chardata_for_range; + range.font_size = font_size; + return stbtt_PackFontRanges(spc, fontdata, font_index, &range, 1); +} + +STBTT_DEF void stbtt_GetPackedQuad(stbtt_packedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int align_to_integer) +{ + float ipw = 1.0f / pw, iph = 1.0f / ph; + stbtt_packedchar *b = chardata + char_index; + + if (align_to_integer) { + float x = (float) STBTT_ifloor((*xpos + b->xoff) + 0.5); + float y = (float) STBTT_ifloor((*ypos + b->yoff) + 0.5); + q->x0 = x; + q->y0 = y; + q->x1 = x + b->xoff2 - b->xoff; + q->y1 = y + b->yoff2 - b->yoff; + } else { + q->x0 = *xpos + b->xoff; + q->y0 = *ypos + b->yoff; + q->x1 = *xpos + b->xoff2; + q->y1 = *ypos + b->yoff2; + } + + q->s0 = b->x0 * ipw; + q->t0 = b->y0 * iph; + q->s1 = b->x1 * ipw; + q->t1 = b->y1 * iph; + + *xpos += b->xadvance; +} + + +////////////////////////////////////////////////////////////////////////////// +// +// font name matching -- recommended not to use this +// + +// check if a utf8 string contains a prefix which is the utf16 string; if so return length of matching utf8 string +static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(const stbtt_uint8 *s1, stbtt_int32 len1, const stbtt_uint8 *s2, stbtt_int32 len2) +{ + stbtt_int32 i=0; + + // convert utf16 to utf8 and compare the results while converting + while (len2) { + stbtt_uint16 ch = s2[0]*256 + s2[1]; + if (ch < 0x80) { + if (i >= len1) return -1; + if (s1[i++] != ch) return -1; + } else if (ch < 0x800) { + if (i+1 >= len1) return -1; + if (s1[i++] != 0xc0 + (ch >> 6)) return -1; + if (s1[i++] != 0x80 + (ch & 0x3f)) return -1; + } else if (ch >= 0xd800 && ch < 0xdc00) { + stbtt_uint32 c; + stbtt_uint16 ch2 = s2[2]*256 + s2[3]; + if (i+3 >= len1) return -1; + c = ((ch - 0xd800) << 10) + (ch2 - 0xdc00) + 0x10000; + if (s1[i++] != 0xf0 + (c >> 18)) return -1; + if (s1[i++] != 0x80 + ((c >> 12) & 0x3f)) return -1; + if (s1[i++] != 0x80 + ((c >> 6) & 0x3f)) return -1; + if (s1[i++] != 0x80 + ((c ) & 0x3f)) return -1; + s2 += 2; // plus another 2 below + len2 -= 2; + } else if (ch >= 0xdc00 && ch < 0xe000) { + return -1; + } else { + if (i+2 >= len1) return -1; + if (s1[i++] != 0xe0 + (ch >> 12)) return -1; + if (s1[i++] != 0x80 + ((ch >> 6) & 0x3f)) return -1; + if (s1[i++] != 0x80 + ((ch ) & 0x3f)) return -1; + } + s2 += 2; + len2 -= 2; + } + return i; +} + +STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2) +{ + return len1 == stbtt__CompareUTF8toUTF16_bigendian_prefix((const stbtt_uint8*) s1, len1, (const stbtt_uint8*) s2, len2); +} + +// returns results in whatever encoding you request... but note that 2-byte encodings +// will be BIG-ENDIAN... use stbtt_CompareUTF8toUTF16_bigendian() to compare +STBTT_DEF const char *stbtt_GetFontNameString(const stbtt_fontinfo *font, int *length, int platformID, int encodingID, int languageID, int nameID) +{ + stbtt_int32 i,count,stringOffset; + stbtt_uint8 *fc = font->data; + stbtt_uint32 offset = font->fontstart; + stbtt_uint32 nm = stbtt__find_table(fc, offset, "name"); + if (!nm) return NULL; + + count = ttUSHORT(fc+nm+2); + stringOffset = nm + ttUSHORT(fc+nm+4); + for (i=0; i < count; ++i) { + stbtt_uint32 loc = nm + 6 + 12 * i; + if (platformID == ttUSHORT(fc+loc+0) && encodingID == ttUSHORT(fc+loc+2) + && languageID == ttUSHORT(fc+loc+4) && nameID == ttUSHORT(fc+loc+6)) { + *length = ttUSHORT(fc+loc+8); + return (const char *) (fc+stringOffset+ttUSHORT(fc+loc+10)); + } + } + return NULL; +} + +static int stbtt__matchpair(stbtt_uint8 *fc, stbtt_uint32 nm, stbtt_uint8 *name, stbtt_int32 nlen, stbtt_int32 target_id, stbtt_int32 next_id) +{ + stbtt_int32 i; + stbtt_int32 count = ttUSHORT(fc+nm+2); + stbtt_int32 stringOffset = nm + ttUSHORT(fc+nm+4); + + for (i=0; i < count; ++i) { + stbtt_uint32 loc = nm + 6 + 12 * i; + stbtt_int32 id = ttUSHORT(fc+loc+6); + if (id == target_id) { + // find the encoding + stbtt_int32 platform = ttUSHORT(fc+loc+0), encoding = ttUSHORT(fc+loc+2), language = ttUSHORT(fc+loc+4); + + // is this a Unicode encoding? + if (platform == 0 || (platform == 3 && encoding == 1) || (platform == 3 && encoding == 10)) { + stbtt_int32 slen = ttUSHORT(fc+loc+8); + stbtt_int32 off = ttUSHORT(fc+loc+10); + + // check if there's a prefix match + stbtt_int32 matchlen = stbtt__CompareUTF8toUTF16_bigendian_prefix(name, nlen, fc+stringOffset+off,slen); + if (matchlen >= 0) { + // check for target_id+1 immediately following, with same encoding & language + if (i+1 < count && ttUSHORT(fc+loc+12+6) == next_id && ttUSHORT(fc+loc+12) == platform && ttUSHORT(fc+loc+12+2) == encoding && ttUSHORT(fc+loc+12+4) == language) { + slen = ttUSHORT(fc+loc+12+8); + off = ttUSHORT(fc+loc+12+10); + if (slen == 0) { + if (matchlen == nlen) + return 1; + } else if (matchlen < nlen && name[matchlen] == ' ') { + ++matchlen; + if (stbtt_CompareUTF8toUTF16_bigendian((char*) (name+matchlen), nlen-matchlen, (char*)(fc+stringOffset+off),slen)) + return 1; + } + } else { + // if nothing immediately following + if (matchlen == nlen) + return 1; + } + } + } + + // @TODO handle other encodings + } + } + return 0; +} + +static int stbtt__matches(stbtt_uint8 *fc, stbtt_uint32 offset, stbtt_uint8 *name, stbtt_int32 flags) +{ + stbtt_int32 nlen = (stbtt_int32) STBTT_strlen((char *) name); + stbtt_uint32 nm,hd; + if (!stbtt__isfont(fc+offset)) return 0; + + // check italics/bold/underline flags in macStyle... + if (flags) { + hd = stbtt__find_table(fc, offset, "head"); + if ((ttUSHORT(fc+hd+44) & 7) != (flags & 7)) return 0; + } + + nm = stbtt__find_table(fc, offset, "name"); + if (!nm) return 0; + + if (flags) { + // if we checked the macStyle flags, then just check the family and ignore the subfamily + if (stbtt__matchpair(fc, nm, name, nlen, 16, -1)) return 1; + if (stbtt__matchpair(fc, nm, name, nlen, 1, -1)) return 1; + if (stbtt__matchpair(fc, nm, name, nlen, 3, -1)) return 1; + } else { + if (stbtt__matchpair(fc, nm, name, nlen, 16, 17)) return 1; + if (stbtt__matchpair(fc, nm, name, nlen, 1, 2)) return 1; + if (stbtt__matchpair(fc, nm, name, nlen, 3, -1)) return 1; + } + + return 0; +} + +STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *font_collection, const char *name_utf8, stbtt_int32 flags) +{ + stbtt_int32 i; + for (i=0;;++i) { + stbtt_int32 off = stbtt_GetFontOffsetForIndex(font_collection, i); + if (off < 0) return off; + if (stbtt__matches((stbtt_uint8 *) font_collection, off, (stbtt_uint8*) name_utf8, flags)) + return off; + } +} + +#endif // STB_TRUETYPE_IMPLEMENTATION diff --git a/testbed/src/Gui.cpp b/testbed/src/Gui.cpp index e8c9552f..d826ae8b 100644 --- a/testbed/src/Gui.cpp +++ b/testbed/src/Gui.cpp @@ -25,18 +25,371 @@ // Libraries #include "Gui.h" +#include + +GLFWwindow* Gui::mWindow = NULL; +double Gui::g_Time = 0.0f; +bool Gui::g_MousePressed[3] = {false, false, false}; +float Gui::g_MouseWheel = 0.0f; +GLuint Gui::g_FontTexture = 0; +int Gui::g_ShaderHandle = 0; +int Gui::g_VertHandle = 0; +int Gui::g_FragHandle = 0; +int Gui::g_AttribLocationTex = 0; +int Gui::g_AttribLocationProjMtx = 0; +int Gui::g_AttribLocationPosition = 0; +int Gui::g_AttribLocationUV = 0; +int Gui::g_AttribLocationColor = 0; +size_t Gui::g_VboSize = 0; +unsigned int Gui::g_VboHandle = 0; +unsigned int Gui::g_VaoHandle = 0; // Constructor Gui::Gui() { - + g_Time = 0.0f; + g_MousePressed[0] = false; + g_MousePressed[1] = false; + g_MousePressed[2] = false; + g_MouseWheel = 0.0f; + g_FontTexture = 0; + g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; + g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; + g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; + g_VboSize = 0; + g_VboHandle = 0, g_VaoHandle = 0; } // Destructor Gui::~Gui() { + if (g_VaoHandle) glDeleteVertexArrays(1, &g_VaoHandle); + if (g_VboHandle) glDeleteBuffers(1, &g_VboHandle); + g_VaoHandle = 0; + g_VboHandle = 0; + + glDetachShader(g_ShaderHandle, g_VertHandle); + glDeleteShader(g_VertHandle); + g_VertHandle = 0; + + glDetachShader(g_ShaderHandle, g_FragHandle); + glDeleteShader(g_FragHandle); + g_FragHandle = 0; + + glDeleteProgram(g_ShaderHandle); + g_ShaderHandle = 0; + + if (g_FontTexture) + { + glDeleteTextures(1, &g_FontTexture); + ImGui::GetIO().Fonts->TexID = 0; + g_FontTexture = 0; + } + ImGui::Shutdown(); +} + +// Create and return the singleton instance of this class +Gui& Gui::getInstance() { + static Gui instance; + return instance; +} + +/// Initialize the GUI +void Gui::init() { + + ImGuiIO& io = ImGui::GetIO(); + io.KeyMap[ImGuiKey_Tab] = GLFW_KEY_TAB; + io.KeyMap[ImGuiKey_LeftArrow] = GLFW_KEY_LEFT; + io.KeyMap[ImGuiKey_RightArrow] = GLFW_KEY_RIGHT; + io.KeyMap[ImGuiKey_UpArrow] = GLFW_KEY_UP; + io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN; + io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; + io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; + io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; + io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; + io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; + io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; + io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; + io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; + io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; + io.KeyMap[ImGuiKey_X] = GLFW_KEY_X; + io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; + io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; + + io.RenderDrawListsFn = renderDrawLists; + io.SetClipboardTextFn = setClipboardText; + io.GetClipboardTextFn = getClipboardText; +} + +void Gui::createDeviceObjects() { + + const GLchar *vertex_shader = + "#version 330\n" + "uniform mat4 ProjMtx;\n" + "in vec2 Position;\n" + "in vec2 UV;\n" + "in vec4 Color;\n" + "out vec2 Frag_UV;\n" + "out vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_UV = UV;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + "}\n"; + + const GLchar* fragment_shader = + "#version 330\n" + "uniform sampler2D Texture;\n" + "in vec2 Frag_UV;\n" + "in vec4 Frag_Color;\n" + "out vec4 Out_Color;\n" + "void main()\n" + "{\n" + " Out_Color = Frag_Color * texture( Texture, Frag_UV.st);\n" + "}\n"; + + g_ShaderHandle = glCreateProgram(); + g_VertHandle = glCreateShader(GL_VERTEX_SHADER); + g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(g_VertHandle, 1, &vertex_shader, 0); + glShaderSource(g_FragHandle, 1, &fragment_shader, 0); + glCompileShader(g_VertHandle); + glCompileShader(g_FragHandle); + glAttachShader(g_ShaderHandle, g_VertHandle); + glAttachShader(g_ShaderHandle, g_FragHandle); + glLinkProgram(g_ShaderHandle); + + g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); + g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); + g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); + g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); + g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); + + glGenBuffers(1, &g_VboHandle); + + glGenVertexArrays(1, &g_VaoHandle); + glBindVertexArray(g_VaoHandle); + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glEnableVertexAttribArray(g_AttribLocationPosition); + glEnableVertexAttribArray(g_AttribLocationUV); + glEnableVertexAttribArray(g_AttribLocationColor); + + #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); + #undef OFFSETOF + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + createFontTextures(); } // Display the GUI -void Gui::display() { +void Gui::render() { + ImGuiIO& io = ImGui::GetIO(); + //glfwPollEvents(); + beginNewFrame(); + + bool show_test_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImColor(114, 144, 154); + + // 1. Show a simple window + // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug" + { + static float f = 0.0f; + ImGui::Text("Hello, world!"); + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); + ImGui::ColorEdit3("clear color", (float*)&clear_color); + if (ImGui::Button("Test Window")) int test = 1; + if (ImGui::Button("Another Window")) int test = 1; + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + } + + // 2. Show another simple window, this time using an explicit Begin/End pair + //if (show_another_window) + { + ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); + ImGui::Begin("Another Window", &show_another_window); + ImGui::Text("Hello"); + ImGui::End(); + } + + // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow() + //if (show_test_window) + { + ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); + ImGui::ShowTestWindow(&show_test_window); + } + + // Render the GUI + ImGui::Render(); +} + +void Gui::beginNewFrame() { + + if (!g_FontTexture) + createDeviceObjects(); + + ImGuiIO& io = ImGui::GetIO(); + + // Setup display size (every frame to accommodate for window resizing) + int w, h; + int display_w, display_h; + glfwGetWindowSize(mWindow, &w, &h); + glfwGetFramebufferSize(mWindow, &display_w, &display_h); + io.DisplaySize = ImVec2((float)display_w, (float)display_h); + + // Setup time step + double current_time = glfwGetTime(); + io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); + g_Time = current_time; + + // Setup inputs + // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) + if (glfwGetWindowAttrib(mWindow, GLFW_FOCUSED)) + { + double mouse_x, mouse_y; + glfwGetCursorPos(mWindow, &mouse_x, &mouse_y); + mouse_x *= (float)display_w / w; // Convert mouse coordinates to pixels + mouse_y *= (float)display_h / h; + io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.) + } + else + { + io.MousePos = ImVec2(-1,-1); + } + + for (int i = 0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(mWindow, i) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. + g_MousePressed[i] = false; + } + + io.MouseWheel = g_MouseWheel; + g_MouseWheel = 0.0f; + + // Hide/show hardware mouse cursor + glfwSetInputMode(mWindow, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); + + // Start the frame + ImGui::NewFrame(); +} + +void Gui::createFontTextures() +{ + ImGuiIO& io = ImGui::GetIO(); + + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader. + + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; +} + +// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) +// If text or lines are blurry when integrating ImGui in your engine: +// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) +void Gui::renderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count) +{ + if (cmd_lists_count == 0) + return; + + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled + GLint last_program, last_texture; + glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glActiveTexture(GL_TEXTURE0); + + // Setup orthographic projection matrix + const float width = ImGui::GetIO().DisplaySize.x; + const float height = ImGui::GetIO().DisplaySize.y; + const float ortho_projection[4][4] = + { + { 2.0f/width, 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f/-height, 0.0f, 0.0f }, + { 0.0f, 0.0f, -1.0f, 0.0f }, + { -1.0f, 1.0f, 0.0f, 1.0f }, + }; + glUseProgram(g_ShaderHandle); + glUniform1i(g_AttribLocationTex, 0); + glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); + + // Grow our buffer according to what we need + size_t total_vtx_count = 0; + for (int n = 0; n < cmd_lists_count; n++) + total_vtx_count += cmd_lists[n]->vtx_buffer.size(); + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + size_t needed_vtx_size = total_vtx_count * sizeof(ImDrawVert); + if (g_VboSize < needed_vtx_size) + { + g_VboSize = needed_vtx_size + 5000 * sizeof(ImDrawVert); // Grow buffer + glBufferData(GL_ARRAY_BUFFER, g_VboSize, NULL, GL_STREAM_DRAW); + } + + // Copy and convert all vertices into a single contiguous buffer + unsigned char* buffer_data = (unsigned char*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); + if (!buffer_data) + return; + for (int n = 0; n < cmd_lists_count; n++) + { + const ImDrawList* cmd_list = cmd_lists[n]; + memcpy(buffer_data, &cmd_list->vtx_buffer[0], cmd_list->vtx_buffer.size() * sizeof(ImDrawVert)); + buffer_data += cmd_list->vtx_buffer.size() * sizeof(ImDrawVert); + } + glUnmapBuffer(GL_ARRAY_BUFFER); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(g_VaoHandle); + + int cmd_offset = 0; + for (int n = 0; n < cmd_lists_count; n++) + { + const ImDrawList* cmd_list = cmd_lists[n]; + int vtx_offset = cmd_offset; + const ImDrawCmd* pcmd_end = cmd_list->commands.end(); + for (const ImDrawCmd* pcmd = cmd_list->commands.begin(); pcmd != pcmd_end; pcmd++) + { + if (pcmd->user_callback) + { + pcmd->user_callback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->texture_id); + glScissor((int)pcmd->clip_rect.x, (int)(height - pcmd->clip_rect.w), (int)(pcmd->clip_rect.z - pcmd->clip_rect.x), (int)(pcmd->clip_rect.w - pcmd->clip_rect.y)); + glDrawArrays(GL_TRIANGLES, vtx_offset, pcmd->vtx_count); + } + vtx_offset += pcmd->vtx_count; + } + cmd_offset = vtx_offset; + } + + // Restore modified state + glBindVertexArray(0); + glUseProgram(last_program); + glDisable(GL_SCISSOR_TEST); + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +const char* Gui::getClipboardText() { + return glfwGetClipboardString(mWindow); +} + +void Gui::setClipboardText(const char* text) { + glfwSetClipboardString(mWindow, text); } diff --git a/testbed/src/Gui.h b/testbed/src/Gui.h index b2853d0e..6ed1b152 100644 --- a/testbed/src/Gui.h +++ b/testbed/src/Gui.h @@ -27,21 +27,47 @@ #define GUI_H // Libraries - +#include +#include +#include // Class Gui class Gui { - private : + protected : // -------------------- Constants -------------------- // // -------------------- Attributes -------------------- // + // TODO : Delete this + static GLFWwindow* mWindow; + + static double g_Time; + static bool g_MousePressed[3]; + static float g_MouseWheel; + static GLuint g_FontTexture; + static int g_ShaderHandle, g_VertHandle, g_FragHandle; + static int g_AttribLocationTex, g_AttribLocationProjMtx; + static int g_AttribLocationPosition, g_AttribLocationUV, g_AttribLocationColor; + static size_t g_VboSize; + static unsigned int g_VboHandle, g_VaoHandle; + // -------------------- Methods -------------------- // + void createDeviceObjects(); + + void createFontTextures(); + + void beginNewFrame(); + + static void renderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count); + + static const char* getClipboardText(); + + static void setClipboardText(const char* text); public : @@ -53,11 +79,20 @@ class Gui { /// Destructor ~Gui(); + /// Create and return the singleton instance of this class + static Gui& getInstance(); + + /// Initialize the GUI + void init(); + /// Display the GUI - void display(); - - // -------------------- Methods -------------------- // + void render(); + static void setWindow(GLFWwindow* window); }; +inline void Gui::setWindow(GLFWwindow* window) { + mWindow = window; +} + #endif diff --git a/testbed/src/TestbedApplication.cpp b/testbed/src/TestbedApplication.cpp index 914a28a8..fc0721c4 100644 --- a/testbed/src/TestbedApplication.cpp +++ b/testbed/src/TestbedApplication.cpp @@ -103,6 +103,7 @@ void TestbedApplication::init() { glfwSwapInterval(0); // Initialize the GLEW library + glewExperimental = GL_TRUE; GLenum errorGLEW = glewInit(); if (errorGLEW != GLEW_OK) { @@ -127,6 +128,11 @@ void TestbedApplication::init() { // Create all the scenes createScenes(); + Gui::getInstance().setWindow(mWindow); + + // Init the GUI + Gui::getInstance().init(); + mTimer.start(); } @@ -214,7 +220,7 @@ void TestbedApplication::render() { mCurrentScene->render(); // Display the GUI - mGUI.display(); + Gui::getInstance().render(); // Check the OpenGL errors checkOpenGLErrors(); diff --git a/testbed/src/TestbedApplication.h b/testbed/src/TestbedApplication.h index f928f21e..f3b04a51 100644 --- a/testbed/src/TestbedApplication.h +++ b/testbed/src/TestbedApplication.h @@ -51,9 +51,6 @@ class TestbedApplication { /// GLFW window GLFWwindow* mWindow; - /// Graphical User Interface - Gui mGUI; - /// Timer Timer mTimer; From fadedbdb3097b01168a3a14e4bb7886006098ba3 Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Sun, 24 May 2015 17:23:55 +0200 Subject: [PATCH 09/36] Modify rendering to use OpenGL 3.3 --- testbed/common/Box.cpp | 90 ++++++++----- testbed/common/Box.h | 11 +- testbed/common/Capsule.cpp | 124 ++++++++++++++--- testbed/common/Capsule.h | 26 +++- testbed/common/Cone.cpp | 126 +++++++++++++++--- testbed/common/Cone.h | 26 +++- testbed/common/ConvexMesh.cpp | 124 ++++++++++++++--- testbed/common/ConvexMesh.h | 26 +++- testbed/common/Cylinder.cpp | 126 +++++++++++++++--- testbed/common/Cylinder.h | 27 +++- testbed/common/Dumbbell.cpp | 124 ++++++++++++++--- testbed/common/Dumbbell.h | 25 +++- testbed/common/Sphere.cpp | 123 ++++++++++++++--- testbed/common/Sphere.h | 27 +++- testbed/opengl-framework/CMakeLists.txt | 2 + testbed/opengl-framework/src/Shader.cpp | 4 +- testbed/opengl-framework/src/Shader.h | 30 ++++- .../src/VertexBufferObject.cpp | 6 - .../opengl-framework/src/openglframework.h | 1 + .../collisionshapes/CollisionShapesScene.cpp | 19 +-- .../collisionshapes/CollisionShapesScene.h | 8 +- testbed/scenes/cubes/CubesScene.cpp | 36 ++++- testbed/scenes/cubes/CubesScene.h | 3 + testbed/scenes/joints/JointsScene.cpp | 14 +- testbed/scenes/raycast/RaycastScene.cpp | 14 +- testbed/shaders/depth.frag | 2 +- testbed/shaders/depth.vert | 2 +- testbed/shaders/phong.frag | 21 +-- testbed/shaders/phong.vert | 23 ++-- testbed/src/Gui.cpp | 120 +++++------------ testbed/src/Gui.h | 7 +- testbed/src/TestbedApplication.cpp | 27 +++- 32 files changed, 1019 insertions(+), 325 deletions(-) diff --git a/testbed/common/Box.cpp b/testbed/common/Box.cpp index 68d213e7..29149488 100644 --- a/testbed/common/Box.cpp +++ b/testbed/common/Box.cpp @@ -32,6 +32,7 @@ // Initialize static variables openglframework::VertexBufferObject Box::mVBOVertices(GL_ARRAY_BUFFER); openglframework::VertexBufferObject Box::mVBOIndices(GL_ELEMENT_ARRAY_BUFFER); +openglframework::VertexArrayObject Box::mVAO; bool Box::areVBOsCreated = false; VertexData Box::mCubeVertices[8] = { {openglframework::Vector3(1,1,1),openglframework::Vector3(1,1,1),openglframework::Color(1,0,0,1)}, @@ -58,7 +59,7 @@ GLuint Box::mCubeIndices[36] = { 0, 1, 2, // Constructor Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &position, - reactphysics3d::CollisionWorld* world) + reactphysics3d::CollisionWorld* world, openglframework::Shader& shader) : openglframework::Object3D(), mColor(0.5f, 0.5f, 0.5f, 1.0f) { // Initialize the size of the box @@ -95,8 +96,9 @@ Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &p // If the Vertex Buffer object has not been created yet if (!areVBOsCreated) { + // Create the Vertex Buffer - createVBO(); + createVBOAndVAO(shader); } mTransformMatrix = mTransformMatrix * mScalingMatrix; @@ -104,7 +106,7 @@ Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &p // Constructor Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &position, - float mass, reactphysics3d::DynamicsWorld* world) + float mass, reactphysics3d::DynamicsWorld* world, openglframework::Shader& shader) : openglframework::Object3D(), mColor(0.5f, 0.5f, 0.5f, 1.0f) { // Initialize the size of the box @@ -142,7 +144,7 @@ Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &p // If the Vertex Buffer object has not been created yet if (!areVBOsCreated) { // Create the Vertex Buffer - createVBO(); + createVBOAndVAO(shader); } mTransformMatrix = mTransformMatrix * mScalingMatrix; @@ -151,6 +153,15 @@ Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &p // Destructor Box::~Box() { + if (areVBOsCreated) { + + // Destroy the VBOs and VAO + mVBOIndices.destroy(); + mVBOVertices.destroy(); + mVAO.destroy(); + + areVBOsCreated = false; + } } // Render the cube at the correct position and with the correct orientation @@ -174,33 +185,14 @@ void Box::render(openglframework::Shader& shader, openglframework::Vector4 color(mColor.r, mColor.g, mColor.b, mColor.a); shader.setVector4Uniform("vertexColor", color); - // Bind the vertices VBO - mVBOVertices.bind(); - - // Enable the vertex, normal and color arrays - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - - // Set the arrays pointers - glVertexPointer(3, GL_FLOAT, sizeof(VertexData), MEMBER_OFFSET(VertexData, position)); - glNormalPointer(GL_FLOAT, sizeof(VertexData), MEMBER_OFFSET(VertexData, normal)); - glColorPointer(3, GL_FLOAT, sizeof(VertexData), MEMBER_OFFSET(VertexData, color)); - - // Bind the indices VBO - mVBOIndices.bind(); + // Bind the VAO + mVAO.bind(); // Draw the geometry of the box glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, (char*)NULL); - // Unbind the VBOs - mVBOVertices.unbind(); - mVBOIndices.unbind(); - - // Disable the arrays - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); + // Unbind the VAO + mVAO.unbind(); // Unbind the shader shader.unbind(); @@ -233,15 +225,49 @@ void Box::updateTransform(float interpolationFactor) { // Create the Vertex Buffer Objects used to render to box with OpenGL. /// We create two VBOs (one for vertices and one for indices) to render all the boxes /// in the simulation. -void Box::createVBO() { +void Box::createVBOAndVAO(openglframework::Shader& shader) { - // Create the VBOs + // Bind the shader + shader.bind(); + + // Get the location of shader attribute variables + GLint vertexPositionLoc = shader.getAttribLocation("vertexPosition"); + GLint vertexNormalLoc = shader.getAttribLocation("vertexNormal"); + + // Create the VBO for the vertices data mVBOVertices.create(); - mVBOIndices.create(); - - // Copy the data into the VBOs + mVBOVertices.bind(); mVBOVertices.copyDataIntoVBO(sizeof(mCubeVertices), mCubeVertices, GL_STATIC_DRAW); + mVBOVertices.unbind(); + size_t test = sizeof(mCubeVertices); + + // Create th VBO for the indices data + mVBOIndices.create(); + mVBOIndices.bind(); mVBOIndices.copyDataIntoVBO(sizeof(mCubeIndices), mCubeIndices, GL_STATIC_DRAW); + mVBOIndices.unbind(); + + // Create the VAO for both VBOs + mVAO.create(); + mVAO.bind(); + + // Bind the VBO of vertices + mVBOVertices.bind(); + + glEnableVertexAttribArray(vertexPositionLoc); + glEnableVertexAttribArray(vertexNormalLoc); + + glVertexAttribPointer(vertexPositionLoc, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), MEMBER_OFFSET(VertexData, position)); + glVertexAttribPointer(vertexNormalLoc, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), MEMBER_OFFSET(VertexData, normal)); + + // Bind the VBO of indices + mVBOIndices.bind(); + + // Unbind the VAO + mVAO.unbind(); + + // Unbind the shader + shader.unbind(); areVBOsCreated = true; } diff --git a/testbed/common/Box.h b/testbed/common/Box.h index 97c86e5b..7d0b2721 100644 --- a/testbed/common/Box.h +++ b/testbed/common/Box.h @@ -68,6 +68,9 @@ class Box : public openglframework::Object3D { /// Vertex Buffer Object for the indices used to render the box with OpenGL static openglframework::VertexBufferObject mVBOIndices; + /// Vertex Array Object for the vertex data + static openglframework::VertexArrayObject mVAO; + /// Vertex data for each vertex of the cube (used to render the box) static VertexData mCubeVertices[8]; @@ -82,8 +85,8 @@ class Box : public openglframework::Object3D { // -------------------- Methods -------------------- // - /// Create a Vertex Buffer Object to render to box with OpenGL - static void createVBO(); + /// Create a the VAO and VBOs to render to box with OpenGL + static void createVBOAndVAO(openglframework::Shader &shader); public : @@ -91,11 +94,11 @@ class Box : public openglframework::Object3D { /// Constructor Box(const openglframework::Vector3& size, const openglframework::Vector3& position, - reactphysics3d::CollisionWorld* world); + reactphysics3d::CollisionWorld* world, openglframework::Shader &shader); /// Constructor Box(const openglframework::Vector3& size, const openglframework::Vector3& position, - float mass, reactphysics3d::DynamicsWorld *world); + float mass, reactphysics3d::DynamicsWorld *world, openglframework::Shader& shader); /// Destructor ~Box(); diff --git a/testbed/common/Capsule.cpp b/testbed/common/Capsule.cpp index 81b6fcbe..2a925a99 100644 --- a/testbed/common/Capsule.cpp +++ b/testbed/common/Capsule.cpp @@ -29,8 +29,10 @@ // Constructor Capsule::Capsule(float radius, float height, const openglframework::Vector3& position, reactphysics3d::CollisionWorld* world, - const std::string& meshFolderPath) - : openglframework::Mesh(), mRadius(radius), mHeight(height) { + const std::string& meshFolderPath, openglframework::Shader& shader) + : openglframework::Mesh(), mRadius(radius), mHeight(height), mVBOVertices(GL_ARRAY_BUFFER), + mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER), + mVBOIndices(GL_ELEMENT_ARRAY_BUFFER), mColor(1.0f, 0.5f, 0.5f, 1.0f) { // Load the mesh from a file openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "capsule.obj", *this); @@ -66,13 +68,19 @@ Capsule::Capsule(float radius, float height, const openglframework::Vector3& pos mRigidBody->addCollisionShape(collisionShape, rp3d::Transform::identity()); mTransformMatrix = mTransformMatrix * mScalingMatrix; + + // Create the VBOs and VAO + createVBOAndVAO(shader); } // Constructor Capsule::Capsule(float radius, float height, const openglframework::Vector3& position, float mass, reactphysics3d::DynamicsWorld* dynamicsWorld, - const std::string& meshFolderPath) - : openglframework::Mesh(), mRadius(radius), mHeight(height) { + const std::string& meshFolderPath, openglframework::Shader &shader) + : openglframework::Mesh(), mRadius(radius), mHeight(height), + mVBOVertices(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER), + mVBOTextureCoords(GL_ARRAY_BUFFER), mVBOIndices(GL_ELEMENT_ARRAY_BUFFER), + mColor(0.5f, 0.5f, 0.5f, 1.0f) { // Load the mesh from a file openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "capsule.obj", *this); @@ -108,6 +116,9 @@ Capsule::Capsule(float radius, float height, const openglframework::Vector3& pos mRigidBody = body; mTransformMatrix = mTransformMatrix * mScalingMatrix; + + // Create the VBOs and VAO + createVBOAndVAO(shader); } // Destructor @@ -115,6 +126,13 @@ Capsule::~Capsule() { // Destroy the mesh destroy(); + + // Destroy the VBOs and VAO + mVBOIndices.destroy(); + mVBOVertices.destroy(); + mVBONormals.destroy(); + mVBOTextureCoords.destroy(); + mVAO.destroy(); } // Render the sphere at the correct position and with the correct orientation @@ -134,29 +152,20 @@ void Capsule::render(openglframework::Shader& shader, localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose(); shader.setMatrix3x3Uniform("normalMatrix", normalMatrix); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - if (hasTexture()) { - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - } + // Set the vertex color + openglframework::Vector4 color(mColor.r, mColor.g, mColor.b, mColor.a); + shader.setVector4Uniform("vertexColor", color); - glVertexPointer(3, GL_FLOAT, 0, getVerticesPointer()); - glNormalPointer(GL_FLOAT, 0, getNormalsPointer()); - if(hasTexture()) { - glTexCoordPointer(2, GL_FLOAT, 0, getUVTextureCoordinatesPointer()); - } + // Bind the VAO + mVAO.bind(); // For each part of the mesh for (unsigned int i=0; iaddCollisionShape(collisionShape, rp3d::Transform::identity()); mTransformMatrix = mTransformMatrix * mScalingMatrix; + + // Create the VBOs and VAO + createVBOAndVAO(shader); } // Constructor Cone::Cone(float radius, float height, const openglframework::Vector3 &position, float mass, reactphysics3d::DynamicsWorld* dynamicsWorld, - const std::string& meshFolderPath) - : openglframework::Mesh(), mRadius(radius), mHeight(height) { + const std::string& meshFolderPath, openglframework::Shader &shader) + : openglframework::Mesh(), mRadius(radius), mHeight(height), + mVBOVertices(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER), + mVBOTextureCoords(GL_ARRAY_BUFFER), mVBOIndices(GL_ELEMENT_ARRAY_BUFFER), + mColor(0.5f, 0.5f, 0.5f, 1.0f) { // Load the mesh from a file openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "cone.obj", *this); @@ -108,6 +117,9 @@ Cone::Cone(float radius, float height, const openglframework::Vector3 &position, mRigidBody = body; mTransformMatrix = mTransformMatrix * mScalingMatrix; + + // Create the VBOs and VAO + createVBOAndVAO(shader); } // Destructor @@ -115,6 +127,13 @@ Cone::~Cone() { // Destroy the mesh destroy(); + + // Destroy the VBOs and VAO + mVBOIndices.destroy(); + mVBOVertices.destroy(); + mVBONormals.destroy(); + mVBOTextureCoords.destroy(); + mVAO.destroy(); } // Render the cone at the correct position and with the correct orientation @@ -134,29 +153,20 @@ void Cone::render(openglframework::Shader& shader, localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose(); shader.setMatrix3x3Uniform("normalMatrix", normalMatrix); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - if (hasTexture()) { - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - } + // Set the vertex color + openglframework::Vector4 color(mColor.r, mColor.g, mColor.b, mColor.a); + shader.setVector4Uniform("vertexColor", color); - glVertexPointer(3, GL_FLOAT, 0, getVerticesPointer()); - glNormalPointer(GL_FLOAT, 0, getNormalsPointer()); - if(hasTexture()) { - glTexCoordPointer(2, GL_FLOAT, 0, getUVTextureCoordinatesPointer()); - } + // Bind the VAO + mVAO.bind(); // For each part of the mesh for (unsigned int i=0; iaddCollisionShape(collisionShape, rp3d::Transform::identity()); + + // Create the VBOs and VAO + createVBOAndVAO(shader); } // Constructor ConvexMesh::ConvexMesh(const openglframework::Vector3 &position, float mass, reactphysics3d::DynamicsWorld* dynamicsWorld, - const std::string& meshFolderPath) - : openglframework::Mesh() { + const std::string& meshFolderPath, openglframework::Shader &shader) + : openglframework::Mesh(), mVBOVertices(GL_ARRAY_BUFFER), + mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER), + mVBOIndices(GL_ELEMENT_ARRAY_BUFFER), mColor(0.5f, 0.5f, 0.5f, 1.0f) { // Load the mesh from a file openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "convexmesh.obj", *this); @@ -147,6 +155,9 @@ ConvexMesh::ConvexMesh(const openglframework::Vector3 &position, float mass, body->addCollisionShape(collisionShape, rp3d::Transform::identity(), mass); mRigidBody = body; + + // Create the VBOs and VAO + createVBOAndVAO(shader); } // Destructor @@ -154,6 +165,13 @@ ConvexMesh::~ConvexMesh() { // Destroy the mesh destroy(); + + // Destroy the VBOs and VAO + mVBOIndices.destroy(); + mVBOVertices.destroy(); + mVBONormals.destroy(); + mVBOTextureCoords.destroy(); + mVAO.destroy(); } // Render the sphere at the correct position and with the correct orientation @@ -173,29 +191,20 @@ void ConvexMesh::render(openglframework::Shader& shader, localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose(); shader.setMatrix3x3Uniform("normalMatrix", normalMatrix); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - if (hasTexture()) { - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - } + // Set the vertex color + openglframework::Vector4 color(mColor.r, mColor.g, mColor.b, mColor.a); + shader.setVector4Uniform("vertexColor", color); - glVertexPointer(3, GL_FLOAT, 0, getVerticesPointer()); - glNormalPointer(GL_FLOAT, 0, getNormalsPointer()); - if(hasTexture()) { - glTexCoordPointer(2, GL_FLOAT, 0, getUVTextureCoordinatesPointer()); - } + // Bind the VAO + mVAO.bind(); // For each part of the mesh for (unsigned int i=0; iaddCollisionShape(collisionShape, rp3d::Transform::identity()); mTransformMatrix = mTransformMatrix * mScalingMatrix; + + // Create the VBOs and VAO + createVBOAndVAO(shader); } // Constructor Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& position, float mass, reactphysics3d::DynamicsWorld* dynamicsWorld, - const std::string& meshFolderPath) - : openglframework::Mesh(), mRadius(radius), mHeight(height) { + const std::string& meshFolderPath, openglframework::Shader& shader) + : openglframework::Mesh(), mRadius(radius), mHeight(height), + mVBOVertices(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER), + mVBOTextureCoords(GL_ARRAY_BUFFER), mVBOIndices(GL_ELEMENT_ARRAY_BUFFER), + mColor(0.5f, 0.5f, 0.5f, 1.0f) { // Load the mesh from a file openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "cylinder.obj", *this); @@ -108,6 +118,9 @@ Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& p mTransformMatrix = mTransformMatrix * mScalingMatrix; mRigidBody = body; + + // Create the VBOs and VAO + createVBOAndVAO(shader); } // Destructor @@ -115,6 +128,13 @@ Cylinder::~Cylinder() { // Destroy the mesh destroy(); + + // Destroy the VBOs and VAO + mVBOIndices.destroy(); + mVBOVertices.destroy(); + mVBONormals.destroy(); + mVBOTextureCoords.destroy(); + mVAO.destroy(); } // Render the cylinder at the correct position and with the correct orientation @@ -134,29 +154,20 @@ void Cylinder::render(openglframework::Shader& shader, localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose(); shader.setMatrix3x3Uniform("normalMatrix", normalMatrix); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - if (hasTexture()) { - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - } + // Set the vertex color + openglframework::Vector4 color(mColor.r, mColor.g, mColor.b, mColor.a); + shader.setVector4Uniform("vertexColor", color); - glVertexPointer(3, GL_FLOAT, 0, getVerticesPointer()); - glNormalPointer(GL_FLOAT, 0, getNormalsPointer()); - if(hasTexture()) { - glTexCoordPointer(2, GL_FLOAT, 0, getUVTextureCoordinatesPointer()); - } + // Bind the VAO + mVAO.bind(); // For each part of the mesh for (unsigned int i=0; iaddCollisionShape(cylinderCollisionShape, transformCylinderShape); mTransformMatrix = mTransformMatrix * mScalingMatrix; + + // Create the VBOs and VAO + createVBOAndVAO(shader); } // Destructor @@ -151,6 +163,13 @@ Dumbbell::~Dumbbell() { // Destroy the mesh destroy(); + + // Destroy the VBOs and VAO + mVBOIndices.destroy(); + mVBOVertices.destroy(); + mVBONormals.destroy(); + mVBOTextureCoords.destroy(); + mVAO.destroy(); } // Render the sphere at the correct position and with the correct orientation @@ -170,29 +189,20 @@ void Dumbbell::render(openglframework::Shader& shader, localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose(); shader.setMatrix3x3Uniform("normalMatrix", normalMatrix); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - if (hasTexture()) { - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - } + // Set the vertex color + openglframework::Vector4 color(mColor.r, mColor.g, mColor.b, mColor.a); + shader.setVector4Uniform("vertexColor", color); - glVertexPointer(3, GL_FLOAT, 0, getVerticesPointer()); - glNormalPointer(GL_FLOAT, 0, getNormalsPointer()); - if(hasTexture()) { - glTexCoordPointer(2, GL_FLOAT, 0, getUVTextureCoordinatesPointer()); - } + // Bind the VAO + mVAO.bind(); // For each part of the mesh for (unsigned int i=0; iaddCollisionShape(collisionShape, rp3d::Transform::identity()); mTransformMatrix = mTransformMatrix * mScalingMatrix; + + // Create the VBOs and VAO + createVBOAndVAO(shader); } // Constructor Sphere::Sphere(float radius, const openglframework::Vector3 &position, float mass, reactphysics3d::DynamicsWorld* world, - const std::string& meshFolderPath) - : openglframework::Mesh(), mRadius(radius) { + const std::string& meshFolderPath, openglframework::Shader& shader) + : openglframework::Mesh(), mRadius(radius), mVBOVertices(GL_ARRAY_BUFFER), + mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER), + mVBOIndices(GL_ELEMENT_ARRAY_BUFFER), mColor(0.5f, 0.5f, 0.5f, 1.0f) { // Load the mesh from a file openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "sphere.obj", *this); @@ -108,6 +115,9 @@ Sphere::Sphere(float radius, const openglframework::Vector3 &position, mRigidBody = body; mTransformMatrix = mTransformMatrix * mScalingMatrix; + + // Create the VBOs and VAO + createVBOAndVAO(shader); } // Destructor @@ -115,6 +125,13 @@ Sphere::~Sphere() { // Destroy the mesh destroy(); + + // Destroy the VBOs and VAO + mVBOIndices.destroy(); + mVBOVertices.destroy(); + mVBONormals.destroy(); + mVBOTextureCoords.destroy(); + mVAO.destroy(); } // Render the sphere at the correct position and with the correct orientation @@ -134,29 +151,20 @@ void Sphere::render(openglframework::Shader& shader, localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose(); shader.setMatrix3x3Uniform("normalMatrix", normalMatrix); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - if (hasTexture()) { - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - } + // Set the vertex color + openglframework::Vector4 color(mColor.r, mColor.g, mColor.b, mColor.a); + shader.setVector4Uniform("vertexColor", color); - glVertexPointer(3, GL_FLOAT, 0, getVerticesPointer()); - glNormalPointer(GL_FLOAT, 0, getNormalsPointer()); - if(hasTexture()) { - glTexCoordPointer(2, GL_FLOAT, 0, getUVTextureCoordinatesPointer()); - } + // Bind the VAO + mVAO.bind(); // For each part of the mesh for (unsigned int i=0; igetRigidBody()->getMaterial(); @@ -92,7 +93,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name) radius * sin(angle)); // Create a sphere and a corresponding rigid in the dynamics world - Box* box = new Box(BOX_SIZE, position , BOX_MASS, mDynamicsWorld); + Box* box = new Box(BOX_SIZE, position , BOX_MASS, mDynamicsWorld, mPhongShader); // Change the material properties of the rigid body rp3d::Material& material = box->getRigidBody()->getMaterial(); @@ -113,7 +114,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name) // Create a sphere and a corresponding rigid in the dynamics world Sphere* sphere = new Sphere(SPHERE_RADIUS, position , BOX_MASS, mDynamicsWorld, - meshFolderPath); + meshFolderPath, mPhongShader); // Change the material properties of the rigid body rp3d::Material& material = sphere->getRigidBody()->getMaterial(); @@ -134,7 +135,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name) // Create a cone and a corresponding rigid in the dynamics world Cone* cone = new Cone(CONE_RADIUS, CONE_HEIGHT, position, CONE_MASS, mDynamicsWorld, - meshFolderPath); + meshFolderPath, mPhongShader); // Change the material properties of the rigid body rp3d::Material& material = cone->getRigidBody()->getMaterial(); @@ -155,7 +156,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name) // Create a cylinder and a corresponding rigid in the dynamics world Cylinder* cylinder = new Cylinder(CYLINDER_RADIUS, CYLINDER_HEIGHT, position , - CYLINDER_MASS, mDynamicsWorld, meshFolderPath); + CYLINDER_MASS, mDynamicsWorld, meshFolderPath, mPhongShader); // Change the material properties of the rigid body rp3d::Material& material = cylinder->getRigidBody()->getMaterial(); @@ -176,7 +177,8 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name) // Create a cylinder and a corresponding rigid in the dynamics world Capsule* capsule = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, position , - CAPSULE_MASS, mDynamicsWorld, meshFolderPath); + CAPSULE_MASS, mDynamicsWorld, meshFolderPath, + mPhongShader); // Change the material properties of the rigid body rp3d::Material& material = capsule->getRigidBody()->getMaterial(); @@ -196,7 +198,8 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name) radius * sin(angle)); // Create a convex mesh and a corresponding rigid in the dynamics world - ConvexMesh* mesh = new ConvexMesh(position, MESH_MASS, mDynamicsWorld, meshFolderPath); + ConvexMesh* mesh = new ConvexMesh(position, MESH_MASS, mDynamicsWorld, meshFolderPath, + mPhongShader); // Change the material properties of the rigid body rp3d::Material& material = mesh->getRigidBody()->getMaterial(); @@ -208,7 +211,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name) // Create the floor openglframework::Vector3 floorPosition(0, 0, 0); - mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld); + mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld, mPhongShader); // The floor must be a static rigid body mFloor->getRigidBody()->setType(rp3d::STATIC); diff --git a/testbed/scenes/collisionshapes/CollisionShapesScene.h b/testbed/scenes/collisionshapes/CollisionShapesScene.h index 4a4e49b3..a12d3fa3 100644 --- a/testbed/scenes/collisionshapes/CollisionShapesScene.h +++ b/testbed/scenes/collisionshapes/CollisionShapesScene.h @@ -44,11 +44,11 @@ namespace collisionshapesscene { // Constants -const int NB_BOXES = 2; -const int NB_CUBES = 1; +const int NB_BOXES = 3; +const int NB_CUBES = 3; const int NB_CONES = 3; -const int NB_CYLINDERS = 2; -const int NB_CAPSULES = 1; +const int NB_CYLINDERS = 3; +const int NB_CAPSULES = 3; const int NB_MESHES = 2; const int NB_COMPOUND_SHAPES = 2; const openglframework::Vector3 BOX_SIZE(2, 2, 2); diff --git a/testbed/scenes/cubes/CubesScene.cpp b/testbed/scenes/cubes/CubesScene.cpp index e44d10e1..7e029977 100644 --- a/testbed/scenes/cubes/CubesScene.cpp +++ b/testbed/scenes/cubes/CubesScene.cpp @@ -69,7 +69,7 @@ CubesScene::CubesScene(const std::string& name) 0); // Create a cube and a corresponding rigid in the dynamics world - Box* cube = new Box(BOX_SIZE, position , BOX_MASS, mDynamicsWorld); + Box* cube = new Box(BOX_SIZE, position , BOX_MASS, mDynamicsWorld, mPhongShader); // Change the material properties of the rigid body rp3d::Material& material = cube->getRigidBody()->getMaterial(); @@ -81,7 +81,7 @@ CubesScene::CubesScene(const std::string& name) // Create the floor openglframework::Vector3 floorPosition(0, 0, 0); - mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld); + mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld, mPhongShader); // The floor must be a static rigid body mFloor->getRigidBody()->setType(rp3d::STATIC); @@ -150,6 +150,8 @@ void CubesScene::update() { // Render the scene void CubesScene::render() { + checkOpenGLErrors(); + glEnable(GL_DEPTH_TEST); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_CULL_FACE); @@ -170,19 +172,49 @@ void CubesScene::render() { mPhongShader.setVector3Uniform("light0SpecularColor", Vector3(specCol.r, specCol.g, specCol.b)); mPhongShader.setFloatUniform("shininess", 60.0f); + checkOpenGLErrors(); + // Render all the cubes of the scene for (std::vector::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { (*it)->render(mPhongShader, worldToCameraMatrix); } + checkOpenGLErrors(); + // Render the floor mFloor->render(mPhongShader, worldToCameraMatrix); // Unbind the shader mPhongShader.unbind(); + + checkOpenGLErrors(); } // Reset the scene void CubesScene::reset() { } + +// Check the OpenGL errors +void CubesScene::checkOpenGLErrors() { + GLenum glError; + + // Get the OpenGL errors + glError = glGetError(); + + // While there are errors + while (glError != GL_NO_ERROR) { + + // Get the error string + const GLubyte* stringError = gluErrorString(glError); + + // Display the error + if (stringError) + std::cerr << "OpenGL Error #" << glError << "(" << gluErrorString(glError) << ")" << std::endl; + else + std::cerr << "OpenGL Error #" << glError << " (no message available)" << std::endl; + + // Get the next error + glError = glGetError(); + } +} diff --git a/testbed/scenes/cubes/CubesScene.h b/testbed/scenes/cubes/CubesScene.h index 9acc5a62..50ebb001 100644 --- a/testbed/scenes/cubes/CubesScene.h +++ b/testbed/scenes/cubes/CubesScene.h @@ -85,6 +85,9 @@ class CubesScene : public Scene { /// Reset the scene virtual void reset(); + + // Check the OpenGL errors + static void checkOpenGLErrors(); }; } diff --git a/testbed/scenes/joints/JointsScene.cpp b/testbed/scenes/joints/JointsScene.cpp index fd3943df..a8688873 100644 --- a/testbed/scenes/joints/JointsScene.cpp +++ b/testbed/scenes/joints/JointsScene.cpp @@ -202,7 +202,7 @@ void JointsScene::createBallAndSocketJoints() { // Create a box and a corresponding rigid in the dynamics world mBallAndSocketJointChainBoxes[i] = new Box(boxDimension, positionBox , boxMass, - mDynamicsWorld); + mDynamicsWorld, mPhongShader); // The fist box cannot move (static body) if (i == 0) { @@ -247,7 +247,7 @@ void JointsScene::createSliderJoint() { // Create a box and a corresponding rigid in the dynamics world openglframework::Vector3 box1Dimension(2, 4, 2); - mSliderJointBottomBox = new Box(box1Dimension, positionBox1 , BOX_MASS, mDynamicsWorld); + mSliderJointBottomBox = new Box(box1Dimension, positionBox1 , BOX_MASS, mDynamicsWorld, mPhongShader); // The fist box cannot move mSliderJointBottomBox->getRigidBody()->setType(rp3d::STATIC); @@ -263,7 +263,7 @@ void JointsScene::createSliderJoint() { // Create a box and a corresponding rigid in the dynamics world openglframework::Vector3 box2Dimension(1.5f, 4, 1.5f); - mSliderJointTopBox = new Box(box2Dimension, positionBox2 , BOX_MASS, mDynamicsWorld); + mSliderJointTopBox = new Box(box2Dimension, positionBox2, BOX_MASS, mDynamicsWorld, mPhongShader); // Change the material properties of the rigid body rp3d::Material& material2 = mSliderJointTopBox->getRigidBody()->getMaterial(); @@ -299,7 +299,7 @@ void JointsScene::createPropellerHingeJoint() { // Create a box and a corresponding rigid in the dynamics world openglframework::Vector3 boxDimension(10, 1, 1); - mPropellerBox = new Box(boxDimension, positionBox1 , BOX_MASS, mDynamicsWorld); + mPropellerBox = new Box(boxDimension, positionBox1 , BOX_MASS, mDynamicsWorld, mPhongShader); // Change the material properties of the rigid body rp3d::Material& material = mPropellerBox->getRigidBody()->getMaterial(); @@ -334,7 +334,7 @@ void JointsScene::createFixedJoints() { // Create a box and a corresponding rigid in the dynamics world openglframework::Vector3 boxDimension(1.5, 1.5, 1.5); - mFixedJointBox1 = new Box(boxDimension, positionBox1 , BOX_MASS, mDynamicsWorld); + mFixedJointBox1 = new Box(boxDimension, positionBox1 , BOX_MASS, mDynamicsWorld, mPhongShader); // Change the material properties of the rigid body rp3d::Material& material1 = mFixedJointBox1->getRigidBody()->getMaterial(); @@ -346,7 +346,7 @@ void JointsScene::createFixedJoints() { openglframework::Vector3 positionBox2(-5, 7, 0); // Create a box and a corresponding rigid in the dynamics world - mFixedJointBox2 = new Box(boxDimension, positionBox2 , BOX_MASS, mDynamicsWorld); + mFixedJointBox2 = new Box(boxDimension, positionBox2 , BOX_MASS, mDynamicsWorld, mPhongShader); // Change the material properties of the rigid body rp3d::Material& material2 = mFixedJointBox2->getRigidBody()->getMaterial(); @@ -381,7 +381,7 @@ void JointsScene::createFloor() { // Create the floor openglframework::Vector3 floorPosition(0, 0, 0); - mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld); + mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld, mPhongShader); // The floor must be a static rigid body mFloor->getRigidBody()->setType(rp3d::STATIC); diff --git a/testbed/scenes/raycast/RaycastScene.cpp b/testbed/scenes/raycast/RaycastScene.cpp index d3d42eb4..fcf86c15 100644 --- a/testbed/scenes/raycast/RaycastScene.cpp +++ b/testbed/scenes/raycast/RaycastScene.cpp @@ -57,13 +57,13 @@ RaycastScene::RaycastScene(const std::string& name) openglframework::Vector3 position1(0, 0, 0); // Create a convex mesh and a corresponding collision body in the dynamics world - mDumbbell = new Dumbbell(position1, mCollisionWorld, meshFolderPath); + mDumbbell = new Dumbbell(position1, mCollisionWorld, meshFolderPath, mPhongShader); // ---------- Box ---------- // openglframework::Vector3 position2(0, 0, 0); // Create a box and a corresponding collision body in the dynamics world - mBox = new Box(BOX_SIZE, position2, mCollisionWorld); + mBox = new Box(BOX_SIZE, position2, mCollisionWorld, mPhongShader); mBox->getCollisionBody()->setIsActive(false); // ---------- Sphere ---------- // @@ -71,34 +71,34 @@ RaycastScene::RaycastScene(const std::string& name) // Create a sphere and a corresponding collision body in the dynamics world mSphere = new Sphere(SPHERE_RADIUS, position3, mCollisionWorld, - meshFolderPath); + meshFolderPath, mPhongShader); // ---------- Cone ---------- // openglframework::Vector3 position4(0, 0, 0); // Create a cone and a corresponding collision body in the dynamics world mCone = new Cone(CONE_RADIUS, CONE_HEIGHT, position4, mCollisionWorld, - meshFolderPath); + meshFolderPath, mPhongShader); // ---------- Cylinder ---------- // openglframework::Vector3 position5(0, 0, 0); // Create a cylinder and a corresponding collision body in the dynamics world mCylinder = new Cylinder(CYLINDER_RADIUS, CYLINDER_HEIGHT, position5, - mCollisionWorld, meshFolderPath); + mCollisionWorld, meshFolderPath, mPhongShader); // ---------- Capsule ---------- // openglframework::Vector3 position6(0, 0, 0); // Create a cylinder and a corresponding collision body in the dynamics world mCapsule = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, position6 , - mCollisionWorld, meshFolderPath); + mCollisionWorld, meshFolderPath, mPhongShader); // ---------- Convex Mesh ---------- // openglframework::Vector3 position7(0, 0, 0); // Create a convex mesh and a corresponding collision body in the dynamics world - mConvexMesh = new ConvexMesh(position7, mCollisionWorld, meshFolderPath); + mConvexMesh = new ConvexMesh(position7, mCollisionWorld, meshFolderPath, mPhongShader); // Create the lines that will be used for raycasting createLines(); diff --git a/testbed/shaders/depth.frag b/testbed/shaders/depth.frag index 4ef97b32..9b32019e 100644 --- a/testbed/shaders/depth.frag +++ b/testbed/shaders/depth.frag @@ -1,6 +1,6 @@ /******************************************************************************** * OpenGL-Framework * -* Copyright (c) 2013 Daniel Chappuis * +* Copyright (c) 2015 Daniel Chappuis * ********************************************************************************* * * * This software is provided 'as-is', without any express or implied warranty. * diff --git a/testbed/shaders/depth.vert b/testbed/shaders/depth.vert index f320cc72..09b9ff9a 100644 --- a/testbed/shaders/depth.vert +++ b/testbed/shaders/depth.vert @@ -1,6 +1,6 @@ /******************************************************************************** * OpenGL-Framework * -* Copyright (c) 2013 Daniel Chappuis * +* Copyright (c) 2015 Daniel Chappuis * ********************************************************************************* * * * This software is provided 'as-is', without any express or implied warranty. * diff --git a/testbed/shaders/phong.frag b/testbed/shaders/phong.frag index f09777da..2f5777f1 100644 --- a/testbed/shaders/phong.frag +++ b/testbed/shaders/phong.frag @@ -1,6 +1,8 @@ +#version 330 + /******************************************************************************** * OpenGL-Framework * -* Copyright (c) 2013 Daniel Chappuis * +* Copyright (c) 2015 Daniel Chappuis * ********************************************************************************* * * * This software is provided 'as-is', without any express or implied warranty. * @@ -29,14 +31,17 @@ uniform vec3 light0PosCameraSpace; // Camera-space position of the ligh uniform vec3 light0DiffuseColor; // Light 0 diffuse color uniform vec3 light0SpecularColor; // Light 0 specular color uniform float shininess; // Shininess -uniform sampler2D texture; // Texture +uniform sampler2D textureSampler; // Texture uniform bool isTexture; // True if we need to use the texture uniform vec4 vertexColor; // Vertex color -// Varying variables -varying vec3 vertexPosCameraSpace; // Camera-space position of the vertex -varying vec3 vertexNormalCameraSpace; // Vertex normal in camera-space -varying vec2 texCoords; // Texture coordinates +// In variables +in vec3 vertexPosCameraSpace; // Camera-space position of the vertex +in vec3 vertexNormalCameraSpace; // Vertex normal in camera-space +in vec2 texCoords; // Texture coordinates + +// Out variable +out vec4 color; // Output color void main() { @@ -45,7 +50,7 @@ void main() { // Get the texture color vec3 textureColor = vertexColor.rgb; - if (isTexture) textureColor = texture2D(texture, texCoords).rgb; + if (isTexture) textureColor = texture(textureSampler, texCoords).rgb; // Compute the surface normal vector vec3 N = normalize(vertexNormalCameraSpace); @@ -63,5 +68,5 @@ void main() { vec3 specular = light0SpecularColor * specularFactor; // Compute the final color - gl_FragColor = vec4(ambient + diffuse + specular, 1.0); + color = vec4(ambient + diffuse + specular, 1.0); } diff --git a/testbed/shaders/phong.vert b/testbed/shaders/phong.vert index 620344a9..3e9a5398 100644 --- a/testbed/shaders/phong.vert +++ b/testbed/shaders/phong.vert @@ -1,6 +1,8 @@ +#version 330 + /******************************************************************************** * OpenGL-Framework * -* Copyright (c) 2013 Daniel Chappuis * +* Copyright (c) 2015 Daniel Chappuis * ********************************************************************************* * * * This software is provided 'as-is', without any express or implied warranty. * @@ -28,22 +30,27 @@ uniform mat4 localToCameraMatrix; // Local-space to camera-space matrix uniform mat4 projectionMatrix; // Projection matrix uniform mat3 normalMatrix; // Normal matrix -// Varying variables -varying vec3 vertexPosCameraSpace; // Camera-space position of the vertex -varying vec3 vertexNormalCameraSpace; // Vertex normal in camera-space -varying vec2 texCoords; // Texture coordinates +// In variables +in vec4 vertexPosition; +in vec3 vertexNormal; +in vec2 textureCoords; + +// Out variables +out vec3 vertexPosCameraSpace; // Camera-space position of the vertex +out vec3 vertexNormalCameraSpace; // Vertex normal in camera-space +out vec2 texCoords; // Texture coordinates void main() { // Compute the vertex position - vec4 positionCameraSpace = localToCameraMatrix * gl_Vertex; + vec4 positionCameraSpace = localToCameraMatrix * vertexPosition; vertexPosCameraSpace = positionCameraSpace.xyz; // Compute the world surface normal - vertexNormalCameraSpace = normalMatrix * gl_Normal; + vertexNormalCameraSpace = normalMatrix * vertexNormal; // Get the texture coordinates - texCoords = gl_MultiTexCoord0.xy; + texCoords = textureCoords; // Compute the clip-space vertex coordinates gl_Position = projectionMatrix * positionCameraSpace; diff --git a/testbed/src/Gui.cpp b/testbed/src/Gui.cpp index d826ae8b..6c78006c 100644 --- a/testbed/src/Gui.cpp +++ b/testbed/src/Gui.cpp @@ -32,17 +32,12 @@ double Gui::g_Time = 0.0f; bool Gui::g_MousePressed[3] = {false, false, false}; float Gui::g_MouseWheel = 0.0f; GLuint Gui::g_FontTexture = 0; -int Gui::g_ShaderHandle = 0; -int Gui::g_VertHandle = 0; -int Gui::g_FragHandle = 0; -int Gui::g_AttribLocationTex = 0; -int Gui::g_AttribLocationProjMtx = 0; -int Gui::g_AttribLocationPosition = 0; -int Gui::g_AttribLocationUV = 0; -int Gui::g_AttribLocationColor = 0; size_t Gui::g_VboSize = 0; unsigned int Gui::g_VboHandle = 0; unsigned int Gui::g_VaoHandle = 0; +int Gui::g_AttribLocationTex = 0, Gui::g_AttribLocationProjMtx = 0; +int Gui::g_AttribLocationPosition = 0, Gui::g_AttribLocationUV = 0, Gui::g_AttribLocationColor = 0; +Shader Gui::mShader; // Constructor Gui::Gui() { @@ -52,9 +47,6 @@ Gui::Gui() { g_MousePressed[2] = false; g_MouseWheel = 0.0f; g_FontTexture = 0; - g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; - g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; - g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; g_VboSize = 0; g_VboHandle = 0, g_VaoHandle = 0; } @@ -67,16 +59,7 @@ Gui::~Gui() { g_VaoHandle = 0; g_VboHandle = 0; - glDetachShader(g_ShaderHandle, g_VertHandle); - glDeleteShader(g_VertHandle); - g_VertHandle = 0; - - glDetachShader(g_ShaderHandle, g_FragHandle); - glDeleteShader(g_FragHandle); - g_FragHandle = 0; - - glDeleteProgram(g_ShaderHandle); - g_ShaderHandle = 0; + mShader.destroy(); if (g_FontTexture) { @@ -122,48 +105,15 @@ void Gui::init() { void Gui::createDeviceObjects() { - const GLchar *vertex_shader = - "#version 330\n" - "uniform mat4 ProjMtx;\n" - "in vec2 Position;\n" - "in vec2 UV;\n" - "in vec4 Color;\n" - "out vec2 Frag_UV;\n" - "out vec4 Frag_Color;\n" - "void main()\n" - "{\n" - " Frag_UV = UV;\n" - " Frag_Color = Color;\n" - " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" - "}\n"; + /* + mShader.create("shaders/gui.vert", "shaders/gui.frag"); - const GLchar* fragment_shader = - "#version 330\n" - "uniform sampler2D Texture;\n" - "in vec2 Frag_UV;\n" - "in vec4 Frag_Color;\n" - "out vec4 Out_Color;\n" - "void main()\n" - "{\n" - " Out_Color = Frag_Color * texture( Texture, Frag_UV.st);\n" - "}\n"; - - g_ShaderHandle = glCreateProgram(); - g_VertHandle = glCreateShader(GL_VERTEX_SHADER); - g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(g_VertHandle, 1, &vertex_shader, 0); - glShaderSource(g_FragHandle, 1, &fragment_shader, 0); - glCompileShader(g_VertHandle); - glCompileShader(g_FragHandle); - glAttachShader(g_ShaderHandle, g_VertHandle); - glAttachShader(g_ShaderHandle, g_FragHandle); - glLinkProgram(g_ShaderHandle); - - g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); - g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); - g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); - g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); - g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); + GLuint shaderID = mShader.getProgramObjectId(); + g_AttribLocationTex = glGetUniformLocation(shaderID, "Texture"); + g_AttribLocationProjMtx = glGetUniformLocation(shaderID, "ProjMtx"); + g_AttribLocationPosition = glGetAttribLocation(shaderID, "Position"); + g_AttribLocationUV = glGetAttribLocation(shaderID, "UV"); + g_AttribLocationColor = glGetAttribLocation(shaderID, "Color"); glGenBuffers(1, &g_VboHandle); @@ -173,7 +123,6 @@ void Gui::createDeviceObjects() { glEnableVertexAttribArray(g_AttribLocationPosition); glEnableVertexAttribArray(g_AttribLocationUV); glEnableVertexAttribArray(g_AttribLocationColor); - #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); @@ -183,56 +132,41 @@ void Gui::createDeviceObjects() { glBindBuffer(GL_ARRAY_BUFFER, 0); createFontTextures(); + */ } // Display the GUI void Gui::render() { +/* ImGuiIO& io = ImGui::GetIO(); //glfwPollEvents(); beginNewFrame(); + bool show_test_window = true; bool show_another_window = false; - ImVec4 clear_color = ImColor(114, 144, 154); + ImVec4 clear_color = ImColor(255, 255, 255); // 1. Show a simple window // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug" { - static float f = 0.0f; ImGui::Text("Hello, world!"); - ImGui::SliderFloat("float", &f, 0.0f, 1.0f); - ImGui::ColorEdit3("clear color", (float*)&clear_color); - if (ImGui::Button("Test Window")) int test = 1; - if (ImGui::Button("Another Window")) int test = 1; - ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); } - // 2. Show another simple window, this time using an explicit Begin/End pair - //if (show_another_window) - { - ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); - ImGui::Begin("Another Window", &show_another_window); - ImGui::Text("Hello"); - ImGui::End(); - } - - // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow() - //if (show_test_window) - { - ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); - ImGui::ShowTestWindow(&show_test_window); - } // Render the GUI ImGui::Render(); + */ } void Gui::beginNewFrame() { + /* if (!g_FontTexture) createDeviceObjects(); + ImGuiIO& io = ImGui::GetIO(); // Setup display size (every frame to accommodate for window resizing) @@ -276,6 +210,7 @@ void Gui::beginNewFrame() { // Start the frame ImGui::NewFrame(); + */ } void Gui::createFontTextures() @@ -301,6 +236,7 @@ void Gui::createFontTextures() // - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) void Gui::renderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count) { + std::cout << "OpenGLVersion : " << glGetString(GL_VERSION) << std::endl; if (cmd_lists_count == 0) return; @@ -316,9 +252,14 @@ void Gui::renderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count) glEnable(GL_SCISSOR_TEST); glActiveTexture(GL_TEXTURE0); + /* // Setup orthographic projection matrix const float width = ImGui::GetIO().DisplaySize.x; const float height = ImGui::GetIO().DisplaySize.y; + Matrix4 orthoProj(2.0f / width, 0.0f, 0.0f, 0.0f, + 0.0f, 2.0/-height, 0.0f, 0.0f, + 0.0f, 0.0f, -1.0f, 0.0f, + -1.0f, 1.0f, 0.0f, 1.0f); const float ortho_projection[4][4] = { { 2.0f/width, 0.0f, 0.0f, 0.0f }, @@ -326,7 +267,11 @@ void Gui::renderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count) { 0.0f, 0.0f, -1.0f, 0.0f }, { -1.0f, 1.0f, 0.0f, 1.0f }, }; - glUseProgram(g_ShaderHandle); + + mShader.bind(); + //mShader.setIntUniform("Texture", 0); + //mShader.setMatrix4x4Uniform("ProjMtx", orthoProj); + ///glUseProgram(g_ShaderHandle); glUniform1i(g_AttribLocationTex, 0); glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); @@ -379,11 +324,14 @@ void Gui::renderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count) cmd_offset = vtx_offset; } + + // Restore modified state glBindVertexArray(0); glUseProgram(last_program); glDisable(GL_SCISSOR_TEST); glBindTexture(GL_TEXTURE_2D, last_texture); + */ } const char* Gui::getClipboardText() { diff --git a/testbed/src/Gui.h b/testbed/src/Gui.h index 6ed1b152..d61a6cdf 100644 --- a/testbed/src/Gui.h +++ b/testbed/src/Gui.h @@ -30,6 +30,9 @@ #include #include #include +#include "openglframework.h" + +using namespace openglframework; // Class Gui class Gui { @@ -44,11 +47,13 @@ class Gui { // TODO : Delete this static GLFWwindow* mWindow; + static Shader mShader; + static double g_Time; static bool g_MousePressed[3]; static float g_MouseWheel; static GLuint g_FontTexture; - static int g_ShaderHandle, g_VertHandle, g_FragHandle; + //static int g_ShaderHandle, g_VertHandle, g_FragHandle; static int g_AttribLocationTex, g_AttribLocationProjMtx; static int g_AttribLocationPosition, g_AttribLocationUV, g_AttribLocationColor; static size_t g_VboSize; diff --git a/testbed/src/TestbedApplication.cpp b/testbed/src/TestbedApplication.cpp index fc0721c4..c89da4f8 100644 --- a/testbed/src/TestbedApplication.cpp +++ b/testbed/src/TestbedApplication.cpp @@ -55,8 +55,8 @@ TestbedApplication::TestbedApplication() : mFPS(0), mNbFrames(0), mPreviousTime( mCurrentScene = NULL; mEngineSettings.timeStep = DEFAULT_TIMESTEP; mIsMultisamplingActive = true; - mWidth = 1000; - mHeight = 800; + mWidth = 1280; + mHeight = 720; } // Destructor @@ -85,6 +85,12 @@ void TestbedApplication::init() { std::exit(EXIT_FAILURE); } + // OpenGL version required + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); + // Active the multi-sampling by default if (mIsMultisamplingActive) { glfwWindowHint(GLFW_SAMPLES, 4); @@ -131,7 +137,7 @@ void TestbedApplication::init() { Gui::getInstance().setWindow(mWindow); // Init the GUI - Gui::getInstance().init(); + //Gui::getInstance().init(); mTimer.start(); } @@ -143,20 +149,24 @@ void TestbedApplication::createScenes() { CubesScene* cubeScene = new CubesScene("Cubes"); mScenes.push_back(cubeScene); + /* // Joints scene JointsScene* jointsScene = new JointsScene("Joints"); mScenes.push_back(jointsScene); + */ // Collision shapes scene CollisionShapesScene* collisionShapesScene = new CollisionShapesScene("Collision Shapes"); mScenes.push_back(collisionShapesScene); + /* // Raycast scene RaycastScene* raycastScene = new RaycastScene("Raycast"); mScenes.push_back(raycastScene); + */ assert(mScenes.size() > 0); - mCurrentScene = mScenes[0]; + mCurrentScene = mScenes[1]; } // Remove all the scenes @@ -201,7 +211,6 @@ void TestbedApplication::update() { // Compute the interpolation factor float factor = mTimer.computeInterpolationFactor(mEngineSettings.timeStep); assert(factor >= 0.0f && factor <= 1.0f); - std::cout << "Factor : " << factor << std::endl; // Notify the scene about the interpolation factor mCurrentScene->setInterpolationFactor(factor); @@ -220,7 +229,7 @@ void TestbedApplication::render() { mCurrentScene->render(); // Display the GUI - Gui::getInstance().render(); + //Gui::getInstance().render(); // Check the OpenGL errors checkOpenGLErrors(); @@ -251,6 +260,8 @@ void TestbedApplication::startMainLoop() { // Loop until the user closes the window while (!glfwWindowShouldClose(mWindow)) { + checkOpenGLErrors(); + // Reshape the viewport reshape(); @@ -265,6 +276,8 @@ void TestbedApplication::startMainLoop() { // Process events glfwPollEvents(); + + checkOpenGLErrors(); } } @@ -283,7 +296,7 @@ void TestbedApplication::checkOpenGLErrors() { // Display the error if (stringError) - std::cerr << "OpenGL Error #" << glError << "(" << gluErrorString(glError) << std::endl; + std::cerr << "OpenGL Error #" << glError << "(" << gluErrorString(glError) << ")" << std::endl; else std::cerr << "OpenGL Error #" << glError << " (no message available)" << std::endl; From 5ab2ee4df1427daea7c55357331e9d8a0078ff08 Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Mon, 1 Jun 2015 23:40:44 +0200 Subject: [PATCH 10/36] Continue to work on GUI for the testbed application --- testbed/common/Box.cpp | 4 +- testbed/common/Capsule.cpp | 2 +- .../src/VertexArrayObject.cpp | 70 +++++++ .../opengl-framework/src/VertexArrayObject.h | 99 +++++++++ testbed/shaders/gui.frag | 10 + testbed/shaders/gui.vert | 15 ++ testbed/src/Gui.cpp | 190 +++++++++++++----- testbed/src/Gui.h | 27 ++- testbed/src/Scene.h | 8 + testbed/src/TestbedApplication.cpp | 35 +++- testbed/src/TestbedApplication.h | 16 +- 11 files changed, 411 insertions(+), 65 deletions(-) create mode 100644 testbed/opengl-framework/src/VertexArrayObject.cpp create mode 100644 testbed/opengl-framework/src/VertexArrayObject.h create mode 100644 testbed/shaders/gui.frag create mode 100644 testbed/shaders/gui.vert diff --git a/testbed/common/Box.cpp b/testbed/common/Box.cpp index 29149488..4eefdf9e 100644 --- a/testbed/common/Box.cpp +++ b/testbed/common/Box.cpp @@ -60,7 +60,7 @@ GLuint Box::mCubeIndices[36] = { 0, 1, 2, // Constructor Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &position, reactphysics3d::CollisionWorld* world, openglframework::Shader& shader) - : openglframework::Object3D(), mColor(0.5f, 0.5f, 0.5f, 1.0f) { + : openglframework::Object3D(), mColor(0.01f, 0.62f, 0.39f, 1.0f) { // Initialize the size of the box mSize[0] = size.x * 0.5f; @@ -107,7 +107,7 @@ Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &p // Constructor Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &position, float mass, reactphysics3d::DynamicsWorld* world, openglframework::Shader& shader) - : openglframework::Object3D(), mColor(0.5f, 0.5f, 0.5f, 1.0f) { + : openglframework::Object3D(), mColor(0.01f, 0.62f, 0.39f, 1.0f) { // Initialize the size of the box mSize[0] = size.x * 0.5f; diff --git a/testbed/common/Capsule.cpp b/testbed/common/Capsule.cpp index 2a925a99..186970ff 100644 --- a/testbed/common/Capsule.cpp +++ b/testbed/common/Capsule.cpp @@ -32,7 +32,7 @@ Capsule::Capsule(float radius, float height, const openglframework::Vector3& pos const std::string& meshFolderPath, openglframework::Shader& shader) : openglframework::Mesh(), mRadius(radius), mHeight(height), mVBOVertices(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER), - mVBOIndices(GL_ELEMENT_ARRAY_BUFFER), mColor(1.0f, 0.5f, 0.5f, 1.0f) { + mVBOIndices(GL_ELEMENT_ARRAY_BUFFER), mColor(0.5f, 0.5f, 0.5f, 1.0f) { // Load the mesh from a file openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "capsule.obj", *this); diff --git a/testbed/opengl-framework/src/VertexArrayObject.cpp b/testbed/opengl-framework/src/VertexArrayObject.cpp new file mode 100644 index 00000000..2fb0d787 --- /dev/null +++ b/testbed/opengl-framework/src/VertexArrayObject.cpp @@ -0,0 +1,70 @@ +/******************************************************************************** +* OpenGL-Framework * +* Copyright (c) 2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Libraries +#include "VertexArrayObject.h" + +using namespace openglframework; + +// Constructor +VertexArrayObject::VertexArrayObject() : mVertexArrayID(0) { + +} + +// Destructor +VertexArrayObject::~VertexArrayObject() { + +} + +// Create the vertex buffer object +bool VertexArrayObject::create() { + + // Destroy the current VAO + destroy(); + + // Check that the needed OpenGL extensions are available + bool isExtensionOK = checkOpenGLExtensions(); + if (!isExtensionOK) { + std::cerr << "Error : Impossible to use Vertex Array Object on this platform" << std::endl; + assert(false); + return false; + } + + // Generate a new VAO + glGenVertexArrays(1, &mVertexArrayID); + assert(mVertexArrayID != 0); + + return true; +} + +// Destroy the VAO +void VertexArrayObject::destroy() { + + // Delete the vertex buffer object + if (mVertexArrayID) { + glDeleteVertexArrays(1, &mVertexArrayID); + mVertexArrayID = 0; + } +} diff --git a/testbed/opengl-framework/src/VertexArrayObject.h b/testbed/opengl-framework/src/VertexArrayObject.h new file mode 100644 index 00000000..2f7ed1b0 --- /dev/null +++ b/testbed/opengl-framework/src/VertexArrayObject.h @@ -0,0 +1,99 @@ +/******************************************************************************** +* OpenGL-Framework * +* Copyright (c) 2013 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +#ifndef VERTEX_ARRAY_OBJECT_H +#define VERTEX_ARRAY_OBJECT_H + +// Libraries +#include +#include +#include + +namespace openglframework { + + +// Class VertexArrayObject +class VertexArrayObject { + + private : + + // -------------------- Attributes -------------------- // + + /// ID of the Vertex Array Object + GLuint mVertexArrayID; + + public : + + // -------------------- Methods -------------------- // + + /// Constructor + VertexArrayObject(); + + /// Destructor + ~VertexArrayObject(); + + /// Create the vertex buffer object + bool create(); + + /// Bind the VAO + void bind() const; + + /// Unbind the VAO + void unbind() const; + + /// Return true if the needed OpenGL extensions are available for VAO + static bool checkOpenGLExtensions(); + + /// Destroy the VAO + void destroy(); +}; + +// Bind the VAO +inline void VertexArrayObject::bind() const { + assert(mVertexArrayID != 0); + + // Bind the VAO + glBindVertexArray(mVertexArrayID); +} + +// Unbind the VAO +inline void VertexArrayObject::unbind() const { + assert(mVertexArrayID != 0); + + // Unbind the VAO + glBindVertexArray(0); +} + +// Return true if the needed OpenGL extensions are available for VAO +inline bool VertexArrayObject::checkOpenGLExtensions() { + + // Check that OpenGL version is at least 3.0 or there the vertex array object extension exists + return (GLEW_VERSION_3_0 || GL_ARB_vertex_array_object); +} + +} + +#endif + diff --git a/testbed/shaders/gui.frag b/testbed/shaders/gui.frag new file mode 100644 index 00000000..a00d52bb --- /dev/null +++ b/testbed/shaders/gui.frag @@ -0,0 +1,10 @@ +#version 330 +uniform sampler2D Texture; +in vec2 Frag_UV; +in vec4 Frag_Color; +out vec4 Out_Color; + +void main() +{ + Out_Color = Frag_Color * texture( Texture, Frag_UV.st); +} diff --git a/testbed/shaders/gui.vert b/testbed/shaders/gui.vert new file mode 100644 index 00000000..18870a74 --- /dev/null +++ b/testbed/shaders/gui.vert @@ -0,0 +1,15 @@ +#version 330 + +uniform mat4 ProjMtx; +in vec2 Position; +in vec2 UV; +in vec4 Color; +out vec2 Frag_UV; +out vec4 Frag_Color; + +void main() +{ + Frag_UV = UV; + Frag_Color = Color; + gl_Position = ProjMtx * vec4(Position.xy,0,1); +} diff --git a/testbed/src/Gui.cpp b/testbed/src/Gui.cpp index 6c78006c..6d5ad0eb 100644 --- a/testbed/src/Gui.cpp +++ b/testbed/src/Gui.cpp @@ -26,6 +26,7 @@ // Libraries #include "Gui.h" #include +#include "TestbedApplication.h" GLFWwindow* Gui::mWindow = NULL; double Gui::g_Time = 0.0f; @@ -33,14 +34,16 @@ bool Gui::g_MousePressed[3] = {false, false, false}; float Gui::g_MouseWheel = 0.0f; GLuint Gui::g_FontTexture = 0; size_t Gui::g_VboSize = 0; -unsigned int Gui::g_VboHandle = 0; -unsigned int Gui::g_VaoHandle = 0; int Gui::g_AttribLocationTex = 0, Gui::g_AttribLocationProjMtx = 0; int Gui::g_AttribLocationPosition = 0, Gui::g_AttribLocationUV = 0, Gui::g_AttribLocationColor = 0; Shader Gui::mShader; +openglframework::VertexBufferObject Gui::mVBO(GL_ARRAY_BUFFER); +openglframework::VertexArrayObject Gui::mVAO; +Gui::LeftPane Gui::mLeftPane = SCENES; // Constructor Gui::Gui() { + g_Time = 0.0f; g_MousePressed[0] = false; g_MousePressed[1] = false; @@ -48,16 +51,13 @@ Gui::Gui() { g_MouseWheel = 0.0f; g_FontTexture = 0; g_VboSize = 0; - g_VboHandle = 0, g_VaoHandle = 0; } // Destructor Gui::~Gui() { - if (g_VaoHandle) glDeleteVertexArrays(1, &g_VaoHandle); - if (g_VboHandle) glDeleteBuffers(1, &g_VboHandle); - g_VaoHandle = 0; - g_VboHandle = 0; + mVAO.destroy(); + mVBO.destroy(); mShader.destroy(); @@ -101,72 +101,164 @@ void Gui::init() { io.RenderDrawListsFn = renderDrawLists; io.SetClipboardTextFn = setClipboardText; io.GetClipboardTextFn = getClipboardText; + + io.FontGlobalScale = GUI_SCALING; +} + +void Gui::displayHeader() { + + ImVec2 buttonSize(120, 40); + + int display_w, display_h; + glfwGetFramebufferSize(mWindow, &display_w, &display_h); + + ImGuiWindowFlags window_flags = 0; + window_flags |= ImGuiWindowFlags_NoTitleBar; + window_flags |= ImGuiWindowFlags_NoResize; + window_flags |= ImGuiWindowFlags_NoMove; + + ImGui::PushID("Header"); + ImGui::PushStyleColor(ImGuiCol_WindowBg, BACKGROUND_COLOR); + + ImGui::Begin("Header", NULL, ImVec2(display_w, HEADER_HEIGHT), 1.0f, window_flags); + ImGui::SetWindowPos(ImVec2(0, 0)); + ImGui::Button("Play", buttonSize); ImGui::SameLine(); + ImGui::Button("Pause", buttonSize); ImGui::SameLine(); + ImGui::Button("Step", buttonSize); ImGui::SameLine(); + ImGui::Button("Restart", buttonSize); ImGui::SameLine(); + ImGui::End(); + + ImGui::PopStyleColor(1); + ImGui::PopID(); +} + +void Gui::displayLeftPane() { + + const int nbButtonsHeader = 4; + ImVec2 buttonSize(LEFT_PANE_WIDTH / nbButtonsHeader - 9, LEFT_PANE_HEADER_HEIGHT); + + int display_w, display_h; + glfwGetFramebufferSize(mWindow, &display_w, &display_h); + + ImGuiWindowFlags window_flags = 0; + window_flags |= ImGuiWindowFlags_NoTitleBar; + window_flags |= ImGuiWindowFlags_NoResize; + window_flags |= ImGuiWindowFlags_NoMove; + + ImGui::PushID("LeftPane"); + ImGui::PushStyleColor(ImGuiCol_WindowBg, BACKGROUND_COLOR); + + ImGui::Begin("LeftPane", NULL, ImVec2(LEFT_PANE_WIDTH, display_h - HEADER_HEIGHT), 1.0f, window_flags); + ImGui::SetWindowPos(ImVec2(0, HEADER_HEIGHT)); + + // ----- Left Pane Header ----- // + ImGui::Button("Scenes", buttonSize); ImGui::SameLine(); + ImGui::Button("Physics", buttonSize); ImGui::SameLine(); + ImGui::Button("Rendering", buttonSize); ImGui::SameLine(); + ImGui::Button("Profiling", buttonSize); + + // Display the left pane content + switch(mLeftPane) { + case SCENES: displayScenesPane(); break; + case PHYSICS: displayPhysicsPane(); break; + case RENDERING: displayRenderingPane(); break; + case PROFILING: displayProfilingPane(); break; + } + + ImGui::End(); + + ImGui::PopStyleColor(1); + ImGui::PopID(); +} + +// Display the list of scenes +void Gui::displayScenesPane() { + + static int choice = 0; + int startChoice = choice; + TestbedApplication& app = TestbedApplication::getInstance(); + std::vector scenes = app.getScenes(); + + // For each scene + for (int i=0; igetName().c_str(), &choice, i); + } + + // If the user changed scene + if (choice != startChoice) { + app.switchScene(scenes[choice]); + } +} + +void Gui::displayPhysicsPane() { + +} + +void Gui::displayRenderingPane() { + +} + +void Gui::displayProfilingPane() { + } void Gui::createDeviceObjects() { - /* mShader.create("shaders/gui.vert", "shaders/gui.frag"); - GLuint shaderID = mShader.getProgramObjectId(); - g_AttribLocationTex = glGetUniformLocation(shaderID, "Texture"); - g_AttribLocationProjMtx = glGetUniformLocation(shaderID, "ProjMtx"); - g_AttribLocationPosition = glGetAttribLocation(shaderID, "Position"); - g_AttribLocationUV = glGetAttribLocation(shaderID, "UV"); - g_AttribLocationColor = glGetAttribLocation(shaderID, "Color"); + GLuint shaderID = mShader.getProgramObjectId(); + g_AttribLocationTex = glGetUniformLocation(shaderID, "Texture"); + g_AttribLocationProjMtx = glGetUniformLocation(shaderID, "ProjMtx"); + g_AttribLocationPosition = glGetAttribLocation(shaderID, "Position"); + g_AttribLocationUV = glGetAttribLocation(shaderID, "UV"); + g_AttribLocationColor = glGetAttribLocation(shaderID, "Color"); - glGenBuffers(1, &g_VboHandle); + mVBO.create(); - glGenVertexArrays(1, &g_VaoHandle); - glBindVertexArray(g_VaoHandle); - glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); - glEnableVertexAttribArray(g_AttribLocationPosition); - glEnableVertexAttribArray(g_AttribLocationUV); - glEnableVertexAttribArray(g_AttribLocationColor); - #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) - glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); - glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); - glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); - #undef OFFSETOF - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); + mVAO.create(); + mVAO.bind(); + mVBO.bind(); + glEnableVertexAttribArray(g_AttribLocationPosition); + glEnableVertexAttribArray(g_AttribLocationUV); + glEnableVertexAttribArray(g_AttribLocationColor); +#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); +#undef OFFSETOF + mVAO.unbind(); + mVBO.unbind(); - createFontTextures(); - */ + createFontTextures(); } // Display the GUI void Gui::render() { -/* ImGuiIO& io = ImGui::GetIO(); //glfwPollEvents(); beginNewFrame(); - bool show_test_window = true; bool show_another_window = false; ImVec4 clear_color = ImColor(255, 255, 255); - // 1. Show a simple window - // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug" - { - ImGui::Text("Hello, world!"); - } + displayHeader(); + displayLeftPane(); + ImGui::ShowTestWindow(); // Render the GUI ImGui::Render(); - */ } void Gui::beginNewFrame() { - /* if (!g_FontTexture) createDeviceObjects(); - ImGuiIO& io = ImGui::GetIO(); // Setup display size (every frame to accommodate for window resizing) @@ -210,7 +302,6 @@ void Gui::beginNewFrame() { // Start the frame ImGui::NewFrame(); - */ } void Gui::createFontTextures() @@ -236,7 +327,6 @@ void Gui::createFontTextures() // - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) void Gui::renderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count) { - std::cout << "OpenGLVersion : " << glGetString(GL_VERSION) << std::endl; if (cmd_lists_count == 0) return; @@ -252,7 +342,7 @@ void Gui::renderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count) glEnable(GL_SCISSOR_TEST); glActiveTexture(GL_TEXTURE0); - /* + // Setup orthographic projection matrix const float width = ImGui::GetIO().DisplaySize.x; const float height = ImGui::GetIO().DisplaySize.y; @@ -279,12 +369,13 @@ void Gui::renderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count) size_t total_vtx_count = 0; for (int n = 0; n < cmd_lists_count; n++) total_vtx_count += cmd_lists[n]->vtx_buffer.size(); - glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + mVBO.bind(); size_t needed_vtx_size = total_vtx_count * sizeof(ImDrawVert); if (g_VboSize < needed_vtx_size) { g_VboSize = needed_vtx_size + 5000 * sizeof(ImDrawVert); // Grow buffer - glBufferData(GL_ARRAY_BUFFER, g_VboSize, NULL, GL_STREAM_DRAW); + mVBO.copyDataIntoVBO(g_VboSize, NULL, GL_STREAM_DRAW); + //glBufferData(GL_ARRAY_BUFFER, g_VboSize, NULL, GL_STREAM_DRAW); } // Copy and convert all vertices into a single contiguous buffer @@ -298,8 +389,8 @@ void Gui::renderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count) buffer_data += cmd_list->vtx_buffer.size() * sizeof(ImDrawVert); } glUnmapBuffer(GL_ARRAY_BUFFER); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindVertexArray(g_VaoHandle); + mVBO.unbind(); + mVAO.bind(); int cmd_offset = 0; for (int n = 0; n < cmd_lists_count; n++) @@ -324,14 +415,11 @@ void Gui::renderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count) cmd_offset = vtx_offset; } - - // Restore modified state - glBindVertexArray(0); + mVAO.unbind(); glUseProgram(last_program); glDisable(GL_SCISSOR_TEST); glBindTexture(GL_TEXTURE_2D, last_texture); - */ } const char* Gui::getClipboardText() { diff --git a/testbed/src/Gui.h b/testbed/src/Gui.h index d61a6cdf..39b2aeb4 100644 --- a/testbed/src/Gui.h +++ b/testbed/src/Gui.h @@ -32,13 +32,25 @@ #include #include "openglframework.h" +// Constants +const float GUI_SCALING = 2.0f; +const int HEADER_HEIGHT = 80; +const int LEFT_PANE_WIDTH = 700; +const int LEFT_PANE_HEADER_HEIGHT = 60; +const ImColor BACKGROUND_COLOR = ImColor(41, 41, 41, 255); + using namespace openglframework; +// Declarations +class TestbedApplication; + // Class Gui class Gui { protected : + enum LeftPane {SCENES, PHYSICS, RENDERING, PROFILING}; + // -------------------- Constants -------------------- // @@ -48,7 +60,6 @@ class Gui { static GLFWwindow* mWindow; static Shader mShader; - static double g_Time; static bool g_MousePressed[3]; static float g_MouseWheel; @@ -57,7 +68,9 @@ class Gui { static int g_AttribLocationTex, g_AttribLocationProjMtx; static int g_AttribLocationPosition, g_AttribLocationUV, g_AttribLocationColor; static size_t g_VboSize; - static unsigned int g_VboHandle, g_VaoHandle; + static openglframework::VertexBufferObject mVBO; + static openglframework::VertexArrayObject mVAO; + static LeftPane mLeftPane; // -------------------- Methods -------------------- // @@ -74,6 +87,16 @@ class Gui { static void setClipboardText(const char* text); + static void displayHeader(); + static void displayLeftPane(); + + /// Display the list of scenes + static void displayScenesPane(); + + static void displayPhysicsPane(); + static void displayRenderingPane(); + static void displayProfilingPane(); + public : // -------------------- Methods -------------------- // diff --git a/testbed/src/Scene.h b/testbed/src/Scene.h index e37a9e20..2f269a36 100644 --- a/testbed/src/Scene.h +++ b/testbed/src/Scene.h @@ -152,6 +152,9 @@ class Scene { /// Set the interpolation factor void setInterpolationFactor(float interpolationFactor); + + /// Return the name of the scene + std::string getName() const; }; // Called when a keyboard event occurs @@ -185,4 +188,9 @@ inline void Scene::setInterpolationFactor(float interpolationFactor) { mInterpolationFactor = interpolationFactor; } +// Return the name of the scene +inline std::string Scene::getName() const { + return mName; +} + #endif diff --git a/testbed/src/TestbedApplication.cpp b/testbed/src/TestbedApplication.cpp index c89da4f8..d58150d0 100644 --- a/testbed/src/TestbedApplication.cpp +++ b/testbed/src/TestbedApplication.cpp @@ -137,7 +137,7 @@ void TestbedApplication::init() { Gui::getInstance().setWindow(mWindow); // Init the GUI - //Gui::getInstance().init(); + Gui::getInstance().init(); mTimer.start(); } @@ -149,21 +149,17 @@ void TestbedApplication::createScenes() { CubesScene* cubeScene = new CubesScene("Cubes"); mScenes.push_back(cubeScene); - /* // Joints scene JointsScene* jointsScene = new JointsScene("Joints"); mScenes.push_back(jointsScene); - */ // Collision shapes scene CollisionShapesScene* collisionShapesScene = new CollisionShapesScene("Collision Shapes"); mScenes.push_back(collisionShapesScene); - /* // Raycast scene RaycastScene* raycastScene = new RaycastScene("Raycast"); mScenes.push_back(raycastScene); - */ assert(mScenes.size() > 0); mCurrentScene = mScenes[1]; @@ -225,11 +221,22 @@ void TestbedApplication::update() { // Render void TestbedApplication::render() { + // Get the framebuffer dimension + int width, height; + glfwGetFramebufferSize(mWindow, &width, &height); + + // Resize the OpenGL viewport + glViewport(LEFT_PANE_WIDTH, HEADER_HEIGHT, + width - LEFT_PANE_WIDTH, height - HEADER_HEIGHT); + // Render the scene mCurrentScene->render(); + // Resize the OpenGL viewport + glViewport(0, 0, width, height); + // Display the GUI - //Gui::getInstance().render(); + Gui::getInstance().render(); // Check the OpenGL errors checkOpenGLErrors(); @@ -243,10 +250,11 @@ void TestbedApplication::reshape() { glfwGetFramebufferSize(mWindow, &width, &height); // Resize the camera viewport - mCurrentScene->reshape(width, height); + mCurrentScene->reshape(width - LEFT_PANE_WIDTH, height - HEADER_HEIGHT); // Resize the OpenGL viewport - glViewport(0, 0, width, height); + //glViewport(LEFT_PANE_WIDTH, HEADER_HEIGHT, + // width - LEFT_PANE_WIDTH, height - HEADER_HEIGHT); // Update the window size of the scene int windowWidth, windowHeight; @@ -281,6 +289,17 @@ void TestbedApplication::startMainLoop() { } } +// Change the current scene +void TestbedApplication::switchScene(Scene* newScene) { + + if (newScene == mCurrentScene) return; + + mCurrentScene = newScene; + + // Reset the scene + mCurrentScene->reset(); +} + // Check the OpenGL errors void TestbedApplication::checkOpenGLErrors() { GLenum glError; diff --git a/testbed/src/TestbedApplication.h b/testbed/src/TestbedApplication.h index f3b04a51..9843653c 100644 --- a/testbed/src/TestbedApplication.h +++ b/testbed/src/TestbedApplication.h @@ -135,7 +135,10 @@ class TestbedApplication { void createScenes(); /// Remove all the scenes - void destroyScenes() ; + void destroyScenes(); + + /// Return the list of the scenes + std::vector getScenes(); public : @@ -152,8 +155,19 @@ class TestbedApplication { /// Start the main loop where rendering occur void startMainLoop(); + + /// Change the current scene + void switchScene(Scene* newScene); + + // -------------------- Friendship -------------------- // + + friend class Gui; }; +// Return the list of the scenes +inline std::vector TestbedApplication::getScenes() { + return mScenes; +} #endif From 6279867964648c48221eee7edf5d252aa82fd099 Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Tue, 16 Jun 2015 22:46:43 +0200 Subject: [PATCH 11/36] Remove the use of the old transform variable in CollisionBody --- src/body/CollisionBody.cpp | 2 -- src/body/CollisionBody.h | 12 ------------ src/engine/DynamicsWorld.cpp | 3 --- 3 files changed, 17 deletions(-) diff --git a/src/body/CollisionBody.cpp b/src/body/CollisionBody.cpp index f9a4702d..779cc747 100644 --- a/src/body/CollisionBody.cpp +++ b/src/body/CollisionBody.cpp @@ -41,8 +41,6 @@ CollisionBody::CollisionBody(const Transform& transform, CollisionWorld& world, : Body(id), mType(DYNAMIC), mTransform(transform), mProxyCollisionShapes(NULL), mNbCollisionShapes(0), mContactManifoldsList(NULL), mWorld(world) { - // Initialize the old transform - mOldTransform = transform; } // Destructor diff --git a/src/body/CollisionBody.h b/src/body/CollisionBody.h index c75631a5..819584b5 100644 --- a/src/body/CollisionBody.h +++ b/src/body/CollisionBody.h @@ -73,9 +73,6 @@ class CollisionBody : public Body { /// Position and orientation of the body Transform mTransform; - /// Last position and orientation of the body - Transform mOldTransform; - /// First element of the linked list of proxy collision shapes of this body ProxyShape* mProxyCollisionShapes; @@ -102,9 +99,6 @@ class CollisionBody : public Body { /// Remove all the collision shapes void removeAllCollisionShapes(); - /// Update the old transform with the current one. - void updateOldTransform(); - /// Update the broad-phase state for this body (because it has moved for instance) virtual void updateBroadPhaseState() const; @@ -241,12 +235,6 @@ inline void CollisionBody::setTransform(const Transform& transform) { updateBroadPhaseState(); } -// Update the old transform with the current one. -/// This is used to compute the interpolated position and orientation of the body -inline void CollisionBody::updateOldTransform() { - mOldTransform = mTransform; -} - // Return the first element of the linked list of contact manifolds involving this body /** * @return A pointer to the first element of the linked-list with the contact diff --git a/src/engine/DynamicsWorld.cpp b/src/engine/DynamicsWorld.cpp index 242c8af9..97fcfcda 100644 --- a/src/engine/DynamicsWorld.cpp +++ b/src/engine/DynamicsWorld.cpp @@ -328,9 +328,6 @@ void DynamicsWorld::integrateRigidBodiesVelocities() { mConstrainedAngularVelocities[indexBody] *= clamp(angularDamping, decimal(0.0), decimal(1.0)); - // Update the old Transform of the body - bodies[b]->updateOldTransform(); - indexBody++; } } From f376e2043f0977e92856004b8a964a2ae3ece601 Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Thu, 25 Jun 2015 22:27:20 +0200 Subject: [PATCH 12/36] Modify the CollisionBody::setTransform() and Body::setIsSleeping() methods --- src/body/Body.h | 6 ++--- src/body/CollisionBody.h | 2 +- src/body/RigidBody.cpp | 58 ++++++++++++++++++++++++++++++++++++++++ src/body/RigidBody.h | 39 +++++---------------------- 4 files changed, 68 insertions(+), 37 deletions(-) diff --git a/src/body/Body.h b/src/body/Body.h index 946aa61f..e16a15c4 100644 --- a/src/body/Body.h +++ b/src/body/Body.h @@ -83,9 +83,6 @@ class Body { /// Private assignment operator Body& operator=(const Body& body); - /// Set the variable to know whether or not the body is sleeping - virtual void setIsSleeping(bool isSleeping); - public : // -------------------- Methods -------------------- // @@ -105,6 +102,9 @@ class Body { /// Set whether or not the body is allowed to go to sleep void setIsAllowedToSleep(bool isAllowedToSleep); + /// Set the variable to know whether or not the body is sleeping + virtual void setIsSleeping(bool isSleeping); + /// Return whether or not the body is sleeping bool isSleeping() const; diff --git a/src/body/CollisionBody.h b/src/body/CollisionBody.h index 819584b5..955a2130 100644 --- a/src/body/CollisionBody.h +++ b/src/body/CollisionBody.h @@ -132,7 +132,7 @@ class CollisionBody : public Body { const Transform& getTransform() const; /// Set the current position and orientation - void setTransform(const Transform& transform); + virtual void setTransform(const Transform& transform); /// Add a collision shape to the body. virtual ProxyShape* addCollisionShape(const CollisionShape& collisionShape, diff --git a/src/body/RigidBody.cpp b/src/body/RigidBody.cpp index ddf1ea83..32f540f8 100644 --- a/src/body/RigidBody.cpp +++ b/src/body/RigidBody.cpp @@ -265,6 +265,64 @@ void RigidBody::removeCollisionShape(const ProxyShape* proxyShape) { recomputeMassInformation(); } +// Set the linear velocity of the rigid body. +/** + * @param linearVelocity Linear velocity vector of the body + */ +void RigidBody::setLinearVelocity(const Vector3& linearVelocity) { + + // If it is a static body, we do nothing + if (mType == STATIC) return; + + // Update the linear velocity of the current body state + mLinearVelocity = linearVelocity; + + // If the linear velocity is not zero, awake the body + if (mLinearVelocity.lengthSquare() > decimal(0.0)) { + setIsSleeping(false); + } +} + +// Set the angular velocity. +/** +* @param angularVelocity The angular velocity vector of the body +*/ +void RigidBody::setAngularVelocity(const Vector3& angularVelocity) { + + // If it is a static body, we do nothing + if (mType == STATIC) return; + + // Set the angular velocity + mAngularVelocity = angularVelocity; + + // If the velocity is not zero, awake the body + if (mAngularVelocity.lengthSquare() > decimal(0.0)) { + setIsSleeping(false); + } +} + +// Set the current position and orientation +/** + * @param transform The transformation of the body that transforms the local-space + * of the body into world-space + */ +void RigidBody::setTransform(const Transform& transform) { + + // Update the transform of the body + mTransform = transform; + + const Vector3 oldCenterOfMass = mCenterOfMassWorld; + + // Compute the new center of mass in world-space coordinates + mCenterOfMassWorld = mTransform * mCenterOfMassLocal; + + // Update the linear velocity of the center of mass + mLinearVelocity += mAngularVelocity.cross(mCenterOfMassWorld - oldCenterOfMass); + + // Update the broad-phase state of the body + updateBroadPhaseState(); +} + // Recompute the center of mass, total mass and inertia tensor of the body using all // the collision shapes attached to the body. void RigidBody::recomputeMassInformation() { diff --git a/src/body/RigidBody.h b/src/body/RigidBody.h index 964fa286..e8cc573b 100644 --- a/src/body/RigidBody.h +++ b/src/body/RigidBody.h @@ -118,9 +118,6 @@ class RigidBody : public CollisionBody { /// Update the broad-phase state for this body (because it has moved for instance) virtual void updateBroadPhaseState() const; - /// Set the variable to know whether or not the body is sleeping - virtual void setIsSleeping(bool isSleeping); - public : // -------------------- Methods -------------------- // @@ -134,6 +131,9 @@ class RigidBody : public CollisionBody { /// Set the type of the body (static, kinematic or dynamic) void setType(BodyType type); + /// Set the current position and orientation + virtual void setTransform(const Transform& transform); + /// Return the mass of the body decimal getMass() const; @@ -149,6 +149,9 @@ class RigidBody : public CollisionBody { /// Set the angular velocity. void setAngularVelocity(const Vector3& angularVelocity); + /// Set the variable to know whether or not the body is sleeping + virtual void setIsSleeping(bool isSleeping); + /// Return the local inertia tensor of the body (in body coordinates) const Matrix3x3& getInertiaTensorLocal() const; @@ -252,20 +255,6 @@ inline Vector3 RigidBody::getAngularVelocity() const { return mAngularVelocity; } -// Set the angular velocity. -/// You should only call this method for a kinematic body. Otherwise, it -/// will do nothing. -/** -* @param angularVelocity The angular velocity vector of the body -*/ -inline void RigidBody::setAngularVelocity(const Vector3& angularVelocity) { - - // If it is a kinematic body - if (mType == KINEMATIC) { - mAngularVelocity = angularVelocity; - } -} - // Return the local inertia tensor of the body (in local-space coordinates) /** * @return The 3x3 inertia tensor matrix of the body (in local-space coordinates) @@ -310,22 +299,6 @@ inline Matrix3x3 RigidBody::getInertiaTensorInverseWorld() const { mTransform.getOrientation().getMatrix().getTranspose(); } -// Set the linear velocity of the rigid body. -/// You should only call this method for a kinematic body. Otherwise, it -/// will do nothing. -/** - * @param linearVelocity Linear velocity vector of the body - */ -inline void RigidBody::setLinearVelocity(const Vector3& linearVelocity) { - - // If it is a kinematic body - if (mType == KINEMATIC) { - - // Update the linear velocity of the current body state - mLinearVelocity = linearVelocity; - } -} - // Return true if the gravity needs to be applied to this rigid body /** * @return True if the gravity is applied to the body From 39ddabb6f54ce90a7572a8ba0708c4cd51749fb9 Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Thu, 25 Jun 2015 22:28:11 +0200 Subject: [PATCH 13/36] Make possible to witch between scenes and reset them --- testbed/common/Box.cpp | 38 +++-- testbed/common/Box.h | 7 +- testbed/common/Capsule.cpp | 64 +++++++-- testbed/common/Capsule.h | 16 ++- testbed/common/Cone.cpp | 61 ++++++-- testbed/common/Cone.h | 16 ++- testbed/common/ConvexMesh.cpp | 18 +++ testbed/common/ConvexMesh.h | 3 + testbed/common/Cylinder.cpp | 62 ++++++-- testbed/common/Cylinder.h | 16 ++- testbed/common/Dumbbell.cpp | 66 ++++++--- testbed/common/Dumbbell.h | 16 ++- testbed/common/Line.cpp | 4 + testbed/common/Sphere.cpp | 65 ++++++--- testbed/common/Sphere.h | 16 ++- testbed/common/VisualContactPoint.cpp | 133 +++++++++++++----- testbed/common/VisualContactPoint.h | 26 +++- .../collisionshapes/CollisionShapesScene.cpp | 129 ++++++++++++++++- testbed/scenes/cubes/CubesScene.cpp | 41 ++---- testbed/scenes/cubes/CubesScene.h | 5 +- testbed/scenes/joints/JointsScene.cpp | 66 +++++++++ testbed/scenes/raycast/RaycastScene.cpp | 122 ++++++++++++---- testbed/scenes/raycast/RaycastScene.h | 46 ++++-- testbed/src/TestbedApplication.cpp | 2 +- 24 files changed, 822 insertions(+), 216 deletions(-) diff --git a/testbed/common/Box.cpp b/testbed/common/Box.cpp index 4eefdf9e..3845644a 100644 --- a/testbed/common/Box.cpp +++ b/testbed/common/Box.cpp @@ -33,7 +33,7 @@ openglframework::VertexBufferObject Box::mVBOVertices(GL_ARRAY_BUFFER); openglframework::VertexBufferObject Box::mVBOIndices(GL_ELEMENT_ARRAY_BUFFER); openglframework::VertexArrayObject Box::mVAO; -bool Box::areVBOsCreated = false; +int Box::totalNbBoxes = 0; VertexData Box::mCubeVertices[8] = { {openglframework::Vector3(1,1,1),openglframework::Vector3(1,1,1),openglframework::Color(1,0,0,1)}, {openglframework::Vector3(-1,1,1),openglframework::Vector3(-1,1,1),openglframework::Color(1,0,0,1)}, @@ -95,12 +95,14 @@ Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &p mRigidBody->addCollisionShape(collisionShape, rp3d::Transform::identity()); // If the Vertex Buffer object has not been created yet - if (!areVBOsCreated) { + if (totalNbBoxes == 0) { // Create the Vertex Buffer createVBOAndVAO(shader); } + totalNbBoxes++; + mTransformMatrix = mTransformMatrix * mScalingMatrix; } @@ -142,26 +144,29 @@ Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &p mRigidBody = body; // If the Vertex Buffer object has not been created yet - if (!areVBOsCreated) { + if (totalNbBoxes == 0) { + // Create the Vertex Buffer createVBOAndVAO(shader); } + totalNbBoxes++; + mTransformMatrix = mTransformMatrix * mScalingMatrix; } // Destructor Box::~Box() { - if (areVBOsCreated) { + if (totalNbBoxes == 1) { // Destroy the VBOs and VAO mVBOIndices.destroy(); mVBOVertices.destroy(); mVAO.destroy(); - - areVBOsCreated = false; } + + totalNbBoxes--; } // Render the cube at the correct position and with the correct orientation @@ -239,7 +244,6 @@ void Box::createVBOAndVAO(openglframework::Shader& shader) { mVBOVertices.bind(); mVBOVertices.copyDataIntoVBO(sizeof(mCubeVertices), mCubeVertices, GL_STATIC_DRAW); mVBOVertices.unbind(); - size_t test = sizeof(mCubeVertices); // Create th VBO for the indices data mVBOIndices.create(); @@ -268,6 +272,22 @@ void Box::createVBOAndVAO(openglframework::Shader& shader) { // Unbind the shader shader.unbind(); - - areVBOsCreated = true; +} + +// Reset the transform +void Box::resetTransform(const rp3d::Transform& transform) { + + // Reset the transform + mRigidBody->setTransform(transform); + + mRigidBody->setIsSleeping(false); + + // Reset the velocity of the rigid body + rp3d::RigidBody* rigidBody = dynamic_cast(mRigidBody); + if (rigidBody != NULL) { + rigidBody->setLinearVelocity(rp3d::Vector3(0, 0, 0)); + rigidBody->setAngularVelocity(rp3d::Vector3(0, 0, 0)); + } + + updateTransform(1.0f); } diff --git a/testbed/common/Box.h b/testbed/common/Box.h index 7d0b2721..efacafb4 100644 --- a/testbed/common/Box.h +++ b/testbed/common/Box.h @@ -77,8 +77,8 @@ class Box : public openglframework::Object3D { /// Indices of the cube (used to render the box) static GLuint mCubeIndices[36]; - /// True if the VBOs have already been created - static bool areVBOsCreated; + /// Total number of boxes created + static int totalNbBoxes; /// Main color of the box openglframework::Color mColor; @@ -117,6 +117,9 @@ class Box : public openglframework::Object3D { /// Set the color of the box void setColor(const openglframework::Color& color); + + /// Set the position of the box + void resetTransform(const rp3d::Transform& transform); }; // Return a pointer to the collision body of the box diff --git a/testbed/common/Capsule.cpp b/testbed/common/Capsule.cpp index 186970ff..7a38838b 100644 --- a/testbed/common/Capsule.cpp +++ b/testbed/common/Capsule.cpp @@ -26,13 +26,18 @@ // Libraries #include "Capsule.h" +openglframework::VertexBufferObject Capsule::mVBOVertices(GL_ARRAY_BUFFER); +openglframework::VertexBufferObject Capsule::mVBONormals(GL_ARRAY_BUFFER); +openglframework::VertexBufferObject Capsule::mVBOTextureCoords(GL_ARRAY_BUFFER); +openglframework::VertexBufferObject Capsule::mVBOIndices(GL_ELEMENT_ARRAY_BUFFER); +openglframework::VertexArrayObject Capsule::mVAO; +int Capsule::totalNbCapsules = 0; + // Constructor Capsule::Capsule(float radius, float height, const openglframework::Vector3& position, reactphysics3d::CollisionWorld* world, const std::string& meshFolderPath, openglframework::Shader& shader) - : openglframework::Mesh(), mRadius(radius), mHeight(height), mVBOVertices(GL_ARRAY_BUFFER), - mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER), - mVBOIndices(GL_ELEMENT_ARRAY_BUFFER), mColor(0.5f, 0.5f, 0.5f, 1.0f) { + : openglframework::Mesh(), mRadius(radius), mHeight(height) { // Load the mesh from a file openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "capsule.obj", *this); @@ -70,7 +75,11 @@ Capsule::Capsule(float radius, float height, const openglframework::Vector3& pos mTransformMatrix = mTransformMatrix * mScalingMatrix; // Create the VBOs and VAO - createVBOAndVAO(shader); + if (totalNbCapsules == 0) { + createVBOAndVAO(shader); + } + + totalNbCapsules++; } // Constructor @@ -78,8 +87,6 @@ Capsule::Capsule(float radius, float height, const openglframework::Vector3& pos float mass, reactphysics3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath, openglframework::Shader &shader) : openglframework::Mesh(), mRadius(radius), mHeight(height), - mVBOVertices(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER), - mVBOTextureCoords(GL_ARRAY_BUFFER), mVBOIndices(GL_ELEMENT_ARRAY_BUFFER), mColor(0.5f, 0.5f, 0.5f, 1.0f) { // Load the mesh from a file @@ -118,21 +125,30 @@ Capsule::Capsule(float radius, float height, const openglframework::Vector3& pos mTransformMatrix = mTransformMatrix * mScalingMatrix; // Create the VBOs and VAO - createVBOAndVAO(shader); + if (totalNbCapsules == 0) { + createVBOAndVAO(shader); + } + + totalNbCapsules++; } // Destructor Capsule::~Capsule() { - // Destroy the mesh - destroy(); + if (totalNbCapsules == 1) { - // Destroy the VBOs and VAO - mVBOIndices.destroy(); - mVBOVertices.destroy(); - mVBONormals.destroy(); - mVBOTextureCoords.destroy(); - mVAO.destroy(); + // Destroy the mesh + destroy(); + + // Destroy the VBOs and VAO + mVBOIndices.destroy(); + mVBOVertices.destroy(); + mVBONormals.destroy(); + mVBOTextureCoords.destroy(); + mVAO.destroy(); + } + + totalNbCapsules--; } // Render the sphere at the correct position and with the correct orientation @@ -267,3 +283,21 @@ void Capsule::createVBOAndVAO(openglframework::Shader& shader) { // Unbind the shader shader.unbind(); } + +// Reset the transform +void Capsule::resetTransform(const rp3d::Transform& transform) { + + // Reset the transform + mRigidBody->setTransform(transform); + + mRigidBody->setIsSleeping(false); + + // Reset the velocity of the rigid body + rp3d::RigidBody* rigidBody = dynamic_cast(mRigidBody); + if (rigidBody != NULL) { + rigidBody->setLinearVelocity(rp3d::Vector3(0, 0, 0)); + rigidBody->setAngularVelocity(rp3d::Vector3(0, 0, 0)); + } + + updateTransform(1.0f); +} diff --git a/testbed/common/Capsule.h b/testbed/common/Capsule.h index 143c620d..94486834 100644 --- a/testbed/common/Capsule.h +++ b/testbed/common/Capsule.h @@ -53,19 +53,22 @@ class Capsule : public openglframework::Mesh { rp3d::Transform mPreviousTransform; /// Vertex Buffer Object for the vertices data - openglframework::VertexBufferObject mVBOVertices; + static openglframework::VertexBufferObject mVBOVertices; /// Vertex Buffer Object for the normals data - openglframework::VertexBufferObject mVBONormals; + static openglframework::VertexBufferObject mVBONormals; /// Vertex Buffer Object for the texture coords - openglframework::VertexBufferObject mVBOTextureCoords; + static openglframework::VertexBufferObject mVBOTextureCoords; /// Vertex Buffer Object for the indices - openglframework::VertexBufferObject mVBOIndices; + static openglframework::VertexBufferObject mVBOIndices; /// Vertex Array Object for the vertex data - openglframework::VertexArrayObject mVAO; + static openglframework::VertexArrayObject mVAO; + + // Total number of capsules created + static int totalNbCapsules; /// Color openglframework::Color mColor; @@ -104,6 +107,9 @@ class Capsule : public openglframework::Mesh { /// Render the sphere at the correct position and with the correct orientation void render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix); + + /// Set the position of the box + void resetTransform(const rp3d::Transform& transform); }; // Return a pointer to the collision body of the box diff --git a/testbed/common/Cone.cpp b/testbed/common/Cone.cpp index fbd2aadc..0e98211f 100644 --- a/testbed/common/Cone.cpp +++ b/testbed/common/Cone.cpp @@ -26,13 +26,18 @@ // Libraries #include "Cone.h" +openglframework::VertexBufferObject Cone::mVBOVertices(GL_ARRAY_BUFFER); +openglframework::VertexBufferObject Cone::mVBONormals(GL_ARRAY_BUFFER); +openglframework::VertexBufferObject Cone::mVBOTextureCoords(GL_ARRAY_BUFFER); +openglframework::VertexBufferObject Cone::mVBOIndices(GL_ELEMENT_ARRAY_BUFFER); +openglframework::VertexArrayObject Cone::mVAO; +int Cone::totalNbCones = 0; + // Constructor Cone::Cone(float radius, float height, const openglframework::Vector3 &position, reactphysics3d::CollisionWorld* world, const std::string& meshFolderPath, openglframework::Shader& shader) : openglframework::Mesh(), mRadius(radius), mHeight(height), - mVBOVertices(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER), - mVBOTextureCoords(GL_ARRAY_BUFFER), mVBOIndices(GL_ELEMENT_ARRAY_BUFFER), mColor(0.5f, 0.5f, 0.5f, 1.0f) { // Load the mesh from a file @@ -71,7 +76,11 @@ Cone::Cone(float radius, float height, const openglframework::Vector3 &position, mTransformMatrix = mTransformMatrix * mScalingMatrix; // Create the VBOs and VAO - createVBOAndVAO(shader); + if (totalNbCones == 0) { + createVBOAndVAO(shader); + } + + totalNbCones++; } // Constructor @@ -79,8 +88,6 @@ Cone::Cone(float radius, float height, const openglframework::Vector3 &position, float mass, reactphysics3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath, openglframework::Shader &shader) : openglframework::Mesh(), mRadius(radius), mHeight(height), - mVBOVertices(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER), - mVBOTextureCoords(GL_ARRAY_BUFFER), mVBOIndices(GL_ELEMENT_ARRAY_BUFFER), mColor(0.5f, 0.5f, 0.5f, 1.0f) { // Load the mesh from a file @@ -119,21 +126,29 @@ Cone::Cone(float radius, float height, const openglframework::Vector3 &position, mTransformMatrix = mTransformMatrix * mScalingMatrix; // Create the VBOs and VAO - createVBOAndVAO(shader); + if (totalNbCones == 0) { + createVBOAndVAO(shader); + } + + totalNbCones++; } // Destructor Cone::~Cone() { - // Destroy the mesh - destroy(); + if (totalNbCones == 1) { + // Destroy the mesh + destroy(); - // Destroy the VBOs and VAO - mVBOIndices.destroy(); - mVBOVertices.destroy(); - mVBONormals.destroy(); - mVBOTextureCoords.destroy(); - mVAO.destroy(); + // Destroy the VBOs and VAO + mVBOIndices.destroy(); + mVBOVertices.destroy(); + mVBONormals.destroy(); + mVBOTextureCoords.destroy(); + mVAO.destroy(); + } + + totalNbCones--; } // Render the cone at the correct position and with the correct orientation @@ -270,3 +285,21 @@ void Cone::createVBOAndVAO(openglframework::Shader& shader) { shader.unbind(); } +// Reset the transform +void Cone::resetTransform(const rp3d::Transform& transform) { + + // Reset the transform + mRigidBody->setTransform(transform); + + mRigidBody->setIsSleeping(false); + + // Reset the velocity of the rigid body + rp3d::RigidBody* rigidBody = dynamic_cast(mRigidBody); + if (rigidBody != NULL) { + rigidBody->setLinearVelocity(rp3d::Vector3(0, 0, 0)); + rigidBody->setAngularVelocity(rp3d::Vector3(0, 0, 0)); + } + + updateTransform(1.0f); +} + diff --git a/testbed/common/Cone.h b/testbed/common/Cone.h index d3121b53..7d3f17f8 100644 --- a/testbed/common/Cone.h +++ b/testbed/common/Cone.h @@ -53,19 +53,22 @@ class Cone : public openglframework::Mesh { rp3d::Transform mPreviousTransform; /// Vertex Buffer Object for the vertices data - openglframework::VertexBufferObject mVBOVertices; + static openglframework::VertexBufferObject mVBOVertices; /// Vertex Buffer Object for the normals data - openglframework::VertexBufferObject mVBONormals; + static openglframework::VertexBufferObject mVBONormals; /// Vertex Buffer Object for the texture coords - openglframework::VertexBufferObject mVBOTextureCoords; + static openglframework::VertexBufferObject mVBOTextureCoords; /// Vertex Buffer Object for the indices - openglframework::VertexBufferObject mVBOIndices; + static openglframework::VertexBufferObject mVBOIndices; /// Vertex Array Object for the vertex data - openglframework::VertexArrayObject mVAO; + static openglframework::VertexArrayObject mVAO; + + // Total number of cones created + static int totalNbCones; /// Color openglframework::Color mColor; @@ -103,6 +106,9 @@ class Cone : public openglframework::Mesh { /// Render the cone at the correct position and with the correct orientation void render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix); + + /// Set the position of the box + void resetTransform(const rp3d::Transform& transform); }; // Return a pointer to the collision body of the box diff --git a/testbed/common/ConvexMesh.cpp b/testbed/common/ConvexMesh.cpp index e55bad1f..25287c40 100644 --- a/testbed/common/ConvexMesh.cpp +++ b/testbed/common/ConvexMesh.cpp @@ -306,3 +306,21 @@ void ConvexMesh::createVBOAndVAO(openglframework::Shader& shader) { // Unbind the shader shader.unbind(); } + +// Reset the transform +void ConvexMesh::resetTransform(const rp3d::Transform& transform) { + + // Reset the transform + mRigidBody->setTransform(transform); + + mRigidBody->setIsSleeping(false); + + // Reset the velocity of the rigid body + rp3d::RigidBody* rigidBody = dynamic_cast(mRigidBody); + if (rigidBody != NULL) { + rigidBody->setLinearVelocity(rp3d::Vector3(0, 0, 0)); + rigidBody->setAngularVelocity(rp3d::Vector3(0, 0, 0)); + } + + updateTransform(1.0f); +} diff --git a/testbed/common/ConvexMesh.h b/testbed/common/ConvexMesh.h index bf680104..ac586dfb 100644 --- a/testbed/common/ConvexMesh.h +++ b/testbed/common/ConvexMesh.h @@ -94,6 +94,9 @@ class ConvexMesh : public openglframework::Mesh { /// Render the mesh at the correct position and with the correct orientation void render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix); + + /// Set the position of the box + void resetTransform(const rp3d::Transform& transform); }; // Return a pointer to the collision body of the box diff --git a/testbed/common/Cylinder.cpp b/testbed/common/Cylinder.cpp index 02ff1fba..e6e8eed8 100644 --- a/testbed/common/Cylinder.cpp +++ b/testbed/common/Cylinder.cpp @@ -26,14 +26,19 @@ // Libraries #include "Cylinder.h" +openglframework::VertexBufferObject Cylinder::mVBOVertices(GL_ARRAY_BUFFER); +openglframework::VertexBufferObject Cylinder::mVBONormals(GL_ARRAY_BUFFER); +openglframework::VertexBufferObject Cylinder::mVBOTextureCoords(GL_ARRAY_BUFFER); +openglframework::VertexBufferObject Cylinder::mVBOIndices(GL_ELEMENT_ARRAY_BUFFER); +openglframework::VertexArrayObject Cylinder::mVAO; +int Cylinder::totalNbCylinders = 0; + // Constructor Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& position, reactphysics3d::CollisionWorld* world, const std::string& meshFolderPath, openglframework::Shader& shader) : openglframework::Mesh(), mRadius(radius), mHeight(height), - mVBOVertices(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER), - mVBOTextureCoords(GL_ARRAY_BUFFER), mVBOIndices(GL_ELEMENT_ARRAY_BUFFER), mColor(0.5f, 0.5f, 0.5f, 1.0f) { // Load the mesh from a file @@ -72,7 +77,11 @@ Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& p mTransformMatrix = mTransformMatrix * mScalingMatrix; // Create the VBOs and VAO - createVBOAndVAO(shader); + if (totalNbCylinders == 0) { + createVBOAndVAO(shader); + } + + totalNbCylinders++; } // Constructor @@ -80,8 +89,6 @@ Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& p float mass, reactphysics3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath, openglframework::Shader& shader) : openglframework::Mesh(), mRadius(radius), mHeight(height), - mVBOVertices(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER), - mVBOTextureCoords(GL_ARRAY_BUFFER), mVBOIndices(GL_ELEMENT_ARRAY_BUFFER), mColor(0.5f, 0.5f, 0.5f, 1.0f) { // Load the mesh from a file @@ -120,21 +127,30 @@ Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& p mRigidBody = body; // Create the VBOs and VAO - createVBOAndVAO(shader); + if (totalNbCylinders == 0) { + createVBOAndVAO(shader); + } + + totalNbCylinders++; } // Destructor Cylinder::~Cylinder() { - // Destroy the mesh - destroy(); + if (totalNbCylinders == 1) { - // Destroy the VBOs and VAO - mVBOIndices.destroy(); - mVBOVertices.destroy(); - mVBONormals.destroy(); - mVBOTextureCoords.destroy(); - mVAO.destroy(); + // Destroy the mesh + destroy(); + + // Destroy the VBOs and VAO + mVBOIndices.destroy(); + mVBOVertices.destroy(); + mVBONormals.destroy(); + mVBOTextureCoords.destroy(); + mVAO.destroy(); + } + + totalNbCylinders--; } // Render the cylinder at the correct position and with the correct orientation @@ -269,3 +285,21 @@ void Cylinder::createVBOAndVAO(openglframework::Shader& shader) { // Unbind the shader shader.unbind(); } + +// Reset the transform +void Cylinder::resetTransform(const rp3d::Transform& transform) { + + // Reset the transform + mRigidBody->setTransform(transform); + + mRigidBody->setIsSleeping(false); + + // Reset the velocity of the rigid body + rp3d::RigidBody* rigidBody = dynamic_cast(mRigidBody); + if (rigidBody != NULL) { + rigidBody->setLinearVelocity(rp3d::Vector3(0, 0, 0)); + rigidBody->setAngularVelocity(rp3d::Vector3(0, 0, 0)); + } + + updateTransform(1.0f); +} diff --git a/testbed/common/Cylinder.h b/testbed/common/Cylinder.h index 021ef009..ab91ad43 100644 --- a/testbed/common/Cylinder.h +++ b/testbed/common/Cylinder.h @@ -53,19 +53,22 @@ class Cylinder : public openglframework::Mesh { rp3d::Transform mPreviousTransform; /// Vertex Buffer Object for the vertices data - openglframework::VertexBufferObject mVBOVertices; + static openglframework::VertexBufferObject mVBOVertices; /// Vertex Buffer Object for the normals data - openglframework::VertexBufferObject mVBONormals; + static openglframework::VertexBufferObject mVBONormals; /// Vertex Buffer Object for the texture coords - openglframework::VertexBufferObject mVBOTextureCoords; + static openglframework::VertexBufferObject mVBOTextureCoords; /// Vertex Buffer Object for the indices - openglframework::VertexBufferObject mVBOIndices; + static openglframework::VertexBufferObject mVBOIndices; /// Vertex Array Object for the vertex data - openglframework::VertexArrayObject mVAO; + static openglframework::VertexArrayObject mVAO; + + // Total number of capsules created + static int totalNbCylinders; /// Color openglframework::Color mColor; @@ -104,6 +107,9 @@ class Cylinder : public openglframework::Mesh { /// Render the cylinder at the correct position and with the correct orientation void render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix); + + /// Set the position of the box + void resetTransform(const rp3d::Transform& transform); }; // Return a pointer to the collision body of the box diff --git a/testbed/common/Dumbbell.cpp b/testbed/common/Dumbbell.cpp index f80a313b..66a9f3c1 100644 --- a/testbed/common/Dumbbell.cpp +++ b/testbed/common/Dumbbell.cpp @@ -26,13 +26,18 @@ // Libraries #include "Dumbbell.h" +openglframework::VertexBufferObject Dumbbell::mVBOVertices(GL_ARRAY_BUFFER); +openglframework::VertexBufferObject Dumbbell::mVBONormals(GL_ARRAY_BUFFER); +openglframework::VertexBufferObject Dumbbell::mVBOTextureCoords(GL_ARRAY_BUFFER); +openglframework::VertexBufferObject Dumbbell::mVBOIndices(GL_ELEMENT_ARRAY_BUFFER); +openglframework::VertexArrayObject Dumbbell::mVAO; +int Dumbbell::totalNbDumbbells = 0; + // Constructor Dumbbell::Dumbbell(const openglframework::Vector3 &position, reactphysics3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath, openglframework::Shader& shader) - : openglframework::Mesh(),mVBOVertices(GL_ARRAY_BUFFER), - mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER), - mVBOIndices(GL_ELEMENT_ARRAY_BUFFER), mColor(0.5f, 0.5f, 0.5f, 1.0f) { + : openglframework::Mesh(), mColor(0.5f, 0.5f, 0.5f, 1.0f) { // Load the mesh from a file openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "dumbbell.obj", *this); @@ -91,16 +96,18 @@ Dumbbell::Dumbbell(const openglframework::Vector3 &position, mTransformMatrix = mTransformMatrix * mScalingMatrix; // Create the VBOs and VAO - createVBOAndVAO(shader); + if (totalNbDumbbells == 0) { + createVBOAndVAO(shader); + } + + totalNbDumbbells++; } // Constructor Dumbbell::Dumbbell(const openglframework::Vector3 &position, reactphysics3d::CollisionWorld* world, const std::string& meshFolderPath, openglframework::Shader& shader) - : openglframework::Mesh(), mVBOVertices(GL_ARRAY_BUFFER), - mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER), - mVBOIndices(GL_ELEMENT_ARRAY_BUFFER), mColor(0.5f, 0.5f, 0.5f, 1.0f) { + : openglframework::Mesh(), mColor(0.5f, 0.5f, 0.5f, 1.0f) { // Load the mesh from a file openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "dumbbell.obj", *this); @@ -155,21 +162,30 @@ Dumbbell::Dumbbell(const openglframework::Vector3 &position, mTransformMatrix = mTransformMatrix * mScalingMatrix; // Create the VBOs and VAO - createVBOAndVAO(shader); + if (totalNbDumbbells == 0) { + createVBOAndVAO(shader); + } + + totalNbDumbbells++; } // Destructor Dumbbell::~Dumbbell() { - // Destroy the mesh - destroy(); + if (totalNbDumbbells == 1) { - // Destroy the VBOs and VAO - mVBOIndices.destroy(); - mVBOVertices.destroy(); - mVBONormals.destroy(); - mVBOTextureCoords.destroy(); - mVAO.destroy(); + // Destroy the mesh + destroy(); + + // Destroy the VBOs and VAO + mVBOIndices.destroy(); + mVBOVertices.destroy(); + mVBONormals.destroy(); + mVBOTextureCoords.destroy(); + mVAO.destroy(); + } + + totalNbDumbbells--; } // Render the sphere at the correct position and with the correct orientation @@ -304,3 +320,21 @@ void Dumbbell::createVBOAndVAO(openglframework::Shader& shader) { // Unbind the shader shader.unbind(); } + +// Reset the transform +void Dumbbell::resetTransform(const rp3d::Transform& transform) { + + // Reset the transform + mBody->setTransform(transform); + + mBody->setIsSleeping(false); + + // Reset the velocity of the rigid body + rp3d::RigidBody* rigidBody = dynamic_cast(mBody); + if (rigidBody != NULL) { + rigidBody->setLinearVelocity(rp3d::Vector3(0, 0, 0)); + rigidBody->setAngularVelocity(rp3d::Vector3(0, 0, 0)); + } + + updateTransform(1.0f); +} diff --git a/testbed/common/Dumbbell.h b/testbed/common/Dumbbell.h index 9bfe8b9e..01c4d15a 100644 --- a/testbed/common/Dumbbell.h +++ b/testbed/common/Dumbbell.h @@ -50,19 +50,22 @@ class Dumbbell : public openglframework::Mesh { rp3d::Transform mPreviousTransform; /// Vertex Buffer Object for the vertices data - openglframework::VertexBufferObject mVBOVertices; + static openglframework::VertexBufferObject mVBOVertices; /// Vertex Buffer Object for the normals data - openglframework::VertexBufferObject mVBONormals; + static openglframework::VertexBufferObject mVBONormals; /// Vertex Buffer Object for the texture coords - openglframework::VertexBufferObject mVBOTextureCoords; + static openglframework::VertexBufferObject mVBOTextureCoords; /// Vertex Buffer Object for the indices - openglframework::VertexBufferObject mVBOIndices; + static openglframework::VertexBufferObject mVBOIndices; /// Vertex Array Object for the vertex data - openglframework::VertexArrayObject mVAO; + static openglframework::VertexArrayObject mVAO; + + // Total number of capsules created + static int totalNbDumbbells; /// Color openglframework::Color mColor; @@ -100,6 +103,9 @@ class Dumbbell : public openglframework::Mesh { /// Render the sphere at the correct position and with the correct orientation void render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix); + + /// Set the position of the box + void resetTransform(const rp3d::Transform& transform); }; // Return a pointer to the rigid body of the sphere diff --git a/testbed/common/Line.cpp b/testbed/common/Line.cpp index 9263c1d6..56280e43 100644 --- a/testbed/common/Line.cpp +++ b/testbed/common/Line.cpp @@ -49,6 +49,10 @@ void Line::render(openglframework::Shader& shader, // Set the model to camera matrix shader.setMatrix4x4Uniform("localToCameraMatrix", worldToCameraMatrix); + // Set the vertex color + openglframework::Vector4 color(1, 0, 0, 1); + shader.setVector4Uniform("vertexColor", color); + glBegin(GL_LINES); glVertex3f(mWorldPoint1.x, mWorldPoint1.y, mWorldPoint1.z); glVertex3f(mWorldPoint2.x, mWorldPoint2.y, mWorldPoint2.z); diff --git a/testbed/common/Sphere.cpp b/testbed/common/Sphere.cpp index 0356ccbb..73ff71a5 100644 --- a/testbed/common/Sphere.cpp +++ b/testbed/common/Sphere.cpp @@ -26,13 +26,18 @@ // Libraries #include "Sphere.h" +openglframework::VertexBufferObject Sphere::mVBOVertices(GL_ARRAY_BUFFER); +openglframework::VertexBufferObject Sphere::mVBONormals(GL_ARRAY_BUFFER); +openglframework::VertexBufferObject Sphere::mVBOTextureCoords(GL_ARRAY_BUFFER); +openglframework::VertexBufferObject Sphere::mVBOIndices(GL_ELEMENT_ARRAY_BUFFER); +openglframework::VertexArrayObject Sphere::mVAO; +int Sphere::totalNbSpheres = 0; + // Constructor Sphere::Sphere(float radius, const openglframework::Vector3 &position, reactphysics3d::CollisionWorld* world, const std::string& meshFolderPath, openglframework::Shader& shader) - : openglframework::Mesh(), mRadius(radius), mVBOVertices(GL_ARRAY_BUFFER), - mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER), - mVBOIndices(GL_ELEMENT_ARRAY_BUFFER), mColor(0.5f, 0.5f, 0.5f, 1.0f) { + : openglframework::Mesh(), mRadius(radius), mColor(0.5f, 0.5f, 0.5f, 1.0f) { // Load the mesh from a file openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "sphere.obj", *this); @@ -70,16 +75,18 @@ Sphere::Sphere(float radius, const openglframework::Vector3 &position, mTransformMatrix = mTransformMatrix * mScalingMatrix; // Create the VBOs and VAO - createVBOAndVAO(shader); + if (totalNbSpheres == 0) { + createVBOAndVAO(shader); + } + + totalNbSpheres++; } // Constructor Sphere::Sphere(float radius, const openglframework::Vector3 &position, float mass, reactphysics3d::DynamicsWorld* world, const std::string& meshFolderPath, openglframework::Shader& shader) - : openglframework::Mesh(), mRadius(radius), mVBOVertices(GL_ARRAY_BUFFER), - mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER), - mVBOIndices(GL_ELEMENT_ARRAY_BUFFER), mColor(0.5f, 0.5f, 0.5f, 1.0f) { + : openglframework::Mesh(), mRadius(radius), mColor(0.5f, 0.5f, 0.5f, 1.0f) { // Load the mesh from a file openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "sphere.obj", *this); @@ -117,21 +124,29 @@ Sphere::Sphere(float radius, const openglframework::Vector3 &position, mTransformMatrix = mTransformMatrix * mScalingMatrix; // Create the VBOs and VAO - createVBOAndVAO(shader); + if (totalNbSpheres == 0) { + createVBOAndVAO(shader); + } + + totalNbSpheres++; } // Destructor Sphere::~Sphere() { - // Destroy the mesh - destroy(); + if (totalNbSpheres == 1) { + // Destroy the mesh + destroy(); - // Destroy the VBOs and VAO - mVBOIndices.destroy(); - mVBOVertices.destroy(); - mVBONormals.destroy(); - mVBOTextureCoords.destroy(); - mVAO.destroy(); + // Destroy the VBOs and VAO + mVBOIndices.destroy(); + mVBOVertices.destroy(); + mVBONormals.destroy(); + mVBOTextureCoords.destroy(); + mVAO.destroy(); + } + + totalNbSpheres--; } // Render the sphere at the correct position and with the correct orientation @@ -266,3 +281,21 @@ void Sphere::createVBOAndVAO(openglframework::Shader& shader) { // Unbind the shader shader.unbind(); } + +// Reset the transform +void Sphere::resetTransform(const rp3d::Transform& transform) { + + // Reset the transform + mRigidBody->setTransform(transform); + + mRigidBody->setIsSleeping(false); + + // Reset the velocity of the rigid body + rp3d::RigidBody* rigidBody = dynamic_cast(mRigidBody); + if (rigidBody != NULL) { + rigidBody->setLinearVelocity(rp3d::Vector3(0, 0, 0)); + rigidBody->setAngularVelocity(rp3d::Vector3(0, 0, 0)); + } + + updateTransform(1.0f); +} diff --git a/testbed/common/Sphere.h b/testbed/common/Sphere.h index 69813c98..7bef7196 100644 --- a/testbed/common/Sphere.h +++ b/testbed/common/Sphere.h @@ -50,19 +50,22 @@ class Sphere : public openglframework::Mesh { rp3d::Transform mPreviousTransform; /// Vertex Buffer Object for the vertices data - openglframework::VertexBufferObject mVBOVertices; + static openglframework::VertexBufferObject mVBOVertices; /// Vertex Buffer Object for the normals data - openglframework::VertexBufferObject mVBONormals; + static openglframework::VertexBufferObject mVBONormals; /// Vertex Buffer Object for the texture coords - openglframework::VertexBufferObject mVBOTextureCoords; + static openglframework::VertexBufferObject mVBOTextureCoords; /// Vertex Buffer Object for the indices - openglframework::VertexBufferObject mVBOIndices; + static openglframework::VertexBufferObject mVBOIndices; /// Vertex Array Object for the vertex data - openglframework::VertexArrayObject mVAO; + static openglframework::VertexArrayObject mVAO; + + // Total number of capsules created + static int totalNbSpheres; /// Color openglframework::Color mColor; @@ -101,6 +104,9 @@ class Sphere : public openglframework::Mesh { /// Render the sphere at the correct position and with the correct orientation void render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix); + + /// Set the position of the box + void resetTransform(const rp3d::Transform& transform); }; // Return a pointer to the collision body of the box diff --git a/testbed/common/VisualContactPoint.cpp b/testbed/common/VisualContactPoint.cpp index 77337192..df8f3bb0 100644 --- a/testbed/common/VisualContactPoint.cpp +++ b/testbed/common/VisualContactPoint.cpp @@ -27,46 +27,65 @@ #include "VisualContactPoint.h" // Initialization of static variables +openglframework::VertexBufferObject VisualContactPoint::mVBOVertices(GL_ARRAY_BUFFER); +openglframework::VertexBufferObject VisualContactPoint::mVBONormals(GL_ARRAY_BUFFER); +openglframework::VertexBufferObject VisualContactPoint::mVBOIndices(GL_ELEMENT_ARRAY_BUFFER); +openglframework::VertexArrayObject VisualContactPoint::mVAO; int VisualContactPoint::mNbTotalPoints = 0; -bool VisualContactPoint::mIsMeshInitialized = false; openglframework::Mesh VisualContactPoint::mMesh; +int VisualContactPoint::totalNbBoxes = 0; // Constructor -VisualContactPoint::VisualContactPoint(const openglframework::Vector3& position) { +VisualContactPoint::VisualContactPoint(const openglframework::Vector3& position, + openglframework::Shader& shader, + const std::string& meshFolderPath) + : mColor(1.0f, 0.0f, 0.0f, 1.0f) { - assert(mIsMeshInitialized); - - // Initialize the position where the sphere will be rendered + // Initialize the position where the mesh will be rendered translateWorld(position); + + // Create the VBOs and VAO + if (totalNbBoxes == 0) { + createStaticData(meshFolderPath); + createVBOAndVAO(shader); + } + + totalNbBoxes++; } // Destructor VisualContactPoint::~VisualContactPoint() { + if (totalNbBoxes == 1) { + + // Destroy the VBOs and VAO + mVBOIndices.destroy(); + mVBOVertices.destroy(); + mVBONormals.destroy(); + mVAO.destroy(); + + destroyStaticData(); + } + + totalNbBoxes--; } // Load and initialize the mesh for all the contact points void VisualContactPoint::createStaticData(const std::string& meshFolderPath) { - if (!mIsMeshInitialized) { + // Load the mesh from a file + openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "sphere.obj", mMesh); - // Load the mesh from a file - openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "sphere.obj", mMesh); + // Calculate the normals of the mesh + mMesh.calculateNormals(); - // Calculate the normals of the mesh - mMesh.calculateNormals(); - - mMesh.scaleVertices(VISUAL_CONTACT_POINT_RADIUS); - - mIsMeshInitialized = true; - } + mMesh.scaleVertices(VISUAL_CONTACT_POINT_RADIUS); } // Destroy the mesh for the contact points void VisualContactPoint::destroyStaticData() { mMesh.destroy(); - mIsMeshInitialized = false; } // Render the sphere at the correct position and with the correct orientation @@ -86,29 +105,77 @@ void VisualContactPoint::render(openglframework::Shader& shader, localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose(); shader.setMatrix3x3Uniform("normalMatrix", normalMatrix); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - if (mMesh.hasTexture()) { - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - } + // Set the vertex color + openglframework::Vector4 color(mColor.r, mColor.g, mColor.b, mColor.a); + shader.setVector4Uniform("vertexColor", color); - glVertexPointer(3, GL_FLOAT, 0, mMesh.getVerticesPointer()); - glNormalPointer(GL_FLOAT, 0, mMesh.getNormalsPointer()); - if(mMesh.hasTexture()) { - glTexCoordPointer(2, GL_FLOAT, 0, mMesh.getUVTextureCoordinatesPointer()); - } + // Bind the VAO + mVAO.bind(); // For each part of the mesh for (unsigned int i=0; isetNbIterationsVelocitySolver(15); - // Create the static data for the visual contact points - VisualContactPoint::createStaticData(meshFolderPath); - float radius = 3.0f; for (int i=0; iresetTransform(transform); + } + + // Create all the boxes of the scene + for (int i=0; iresetTransform(transform); + } + + // Create all the spheres of the scene + for (int i=0; iresetTransform(transform); + } + + // Create all the cones of the scene + for (int i=0; iresetTransform(transform); + } + + // Create all the cylinders of the scene + for (int i=0; iresetTransform(transform); + } + + // Create all the capsules of the scene + for (int i=0; iresetTransform(transform); + } + + // Create all the convex meshes of the scene + for (int i=0; iresetTransform(transform); + } } diff --git a/testbed/scenes/cubes/CubesScene.cpp b/testbed/scenes/cubes/CubesScene.cpp index 7e029977..4842dd34 100644 --- a/testbed/scenes/cubes/CubesScene.cpp +++ b/testbed/scenes/cubes/CubesScene.cpp @@ -65,7 +65,7 @@ CubesScene::CubesScene(const std::string& name) // Position of the cubes float angle = i * 30.0f; openglframework::Vector3 position(radius * cos(angle), - 10 + i * (BOX_SIZE.y + 0.3f), + 30 + i * (BOX_SIZE.y + 0.3f), 0); // Create a cube and a corresponding rigid in the dynamics world @@ -150,8 +150,6 @@ void CubesScene::update() { // Render the scene void CubesScene::render() { - checkOpenGLErrors(); - glEnable(GL_DEPTH_TEST); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_CULL_FACE); @@ -172,49 +170,36 @@ void CubesScene::render() { mPhongShader.setVector3Uniform("light0SpecularColor", Vector3(specCol.r, specCol.g, specCol.b)); mPhongShader.setFloatUniform("shininess", 60.0f); - checkOpenGLErrors(); - // Render all the cubes of the scene for (std::vector::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { (*it)->render(mPhongShader, worldToCameraMatrix); } - checkOpenGLErrors(); - // Render the floor mFloor->render(mPhongShader, worldToCameraMatrix); // Unbind the shader mPhongShader.unbind(); - - checkOpenGLErrors(); } // Reset the scene void CubesScene::reset() { -} + float radius = 2.0f; -// Check the OpenGL errors -void CubesScene::checkOpenGLErrors() { - GLenum glError; + for (int i=0; iresetTransform(transform); } } diff --git a/testbed/scenes/cubes/CubesScene.h b/testbed/scenes/cubes/CubesScene.h index 50ebb001..4c3df694 100644 --- a/testbed/scenes/cubes/CubesScene.h +++ b/testbed/scenes/cubes/CubesScene.h @@ -35,7 +35,7 @@ namespace cubesscene { // Constants -const int NB_CUBES = 200; // Number of boxes in the scene +const int NB_CUBES = 20; // Number of boxes in the scene const openglframework::Vector3 BOX_SIZE(2, 2, 2); // Box dimensions in meters const openglframework::Vector3 FLOOR_SIZE(50, 0.5f, 50); // Floor dimensions in meters const float BOX_MASS = 1.0f; // Box mass in kilograms @@ -85,9 +85,6 @@ class CubesScene : public Scene { /// Reset the scene virtual void reset(); - - // Check the OpenGL errors - static void checkOpenGLErrors(); }; } diff --git a/testbed/scenes/joints/JointsScene.cpp b/testbed/scenes/joints/JointsScene.cpp index a8688873..27c09e99 100644 --- a/testbed/scenes/joints/JointsScene.cpp +++ b/testbed/scenes/joints/JointsScene.cpp @@ -187,6 +187,72 @@ void JointsScene::render() { // Reset the scene void JointsScene::reset() { + openglframework::Vector3 positionBox(0, 15, 5); + openglframework::Vector3 boxDimension(1, 1, 1); + + for (int i=0; iresetTransform(transform); + + positionBox.y -= boxDimension.y + 0.5f; + } + + // --------------- Slider Joint --------------- // + + // Position of the box + openglframework::Vector3 positionBox1(0, 2.1f, 0); + rp3d::Vector3 initPosition(positionBox1.x, positionBox1.y, positionBox1.z); + rp3d::Quaternion initOrientation = rp3d::Quaternion::identity(); + rp3d::Transform transformBottomBox(initPosition, initOrientation); + + // Create a box and a corresponding rigid in the dynamics world + mSliderJointBottomBox->resetTransform(transformBottomBox); + + // Position of the box + openglframework::Vector3 positionBox2(0, 4.2f, 0); + initPosition = rp3d::Vector3(positionBox2.x, positionBox2.y, positionBox2.z); + initOrientation = rp3d::Quaternion::identity(); + rp3d::Transform transformTopBox(initPosition, initOrientation); + + // Create a box and a corresponding rigid in the dynamics world + mSliderJointTopBox->resetTransform(transformTopBox); + + // --------------- Propeller Hinge joint --------------- // + + // Position of the box + positionBox1 = openglframework::Vector3(0, 7, 0); + initPosition = rp3d::Vector3(positionBox1.x, positionBox1.y, positionBox1.z); + initOrientation = rp3d::Quaternion::identity(); + rp3d::Transform transformHingeBox(initPosition, initOrientation); + + // Create a box and a corresponding rigid in the dynamics world + mPropellerBox->resetTransform(transformHingeBox); + + // --------------- Fixed joint --------------- // + + // Position of the box + positionBox1 = openglframework::Vector3(5, 7, 0); + initPosition = rp3d::Vector3(positionBox1.x, positionBox1.y, positionBox1.z); + initOrientation = rp3d::Quaternion::identity(); + rp3d::Transform transformFixedBox1(initPosition, initOrientation); + + // Create a box and a corresponding rigid in the dynamics world + mFixedJointBox1->resetTransform(transformFixedBox1); + + // Position of the box + positionBox2 = openglframework::Vector3(-5, 7, 0); + initPosition = rp3d::Vector3(positionBox2.x, positionBox2.y, positionBox2.z); + initOrientation = rp3d::Quaternion::identity(); + rp3d::Transform transformFixedBox2(initPosition, initOrientation); + + // Create a box and a corresponding rigid in the dynamics world + mFixedJointBox2->resetTransform(transformFixedBox2); } // Create the boxes and joints for the Ball-and-Socket joint example diff --git a/testbed/scenes/raycast/RaycastScene.cpp b/testbed/scenes/raycast/RaycastScene.cpp index fcf86c15..774bb1bc 100644 --- a/testbed/scenes/raycast/RaycastScene.cpp +++ b/testbed/scenes/raycast/RaycastScene.cpp @@ -33,9 +33,9 @@ using namespace raycastscene; // Constructor RaycastScene::RaycastScene(const std::string& name) : Scene(name), mLight0(0), mCurrentBodyIndex(-1), mAreNormalsDisplayed(false), - mPhongShader("shaders/phong.vert", "shaders/phong.frag") { - - std::string meshFolderPath("meshes/"); + mPhongShader("shaders/phong.vert", "shaders/phong.frag"), + mMeshFolderPath("meshes/"), mRaycastManager(mPhongShader, mMeshFolderPath), + mVBOVertices(GL_ARRAY_BUFFER) { // Move the light 0 mLight0.translateWorld(Vector3(50, 50, 50)); @@ -50,14 +50,11 @@ RaycastScene::RaycastScene(const std::string& name) // Create the dynamics world for the physics simulation mCollisionWorld = new rp3d::CollisionWorld(); - // Create the static data for the visual contact points - VisualContactPoint::createStaticData(meshFolderPath); - // ---------- Dumbbell ---------- // openglframework::Vector3 position1(0, 0, 0); // Create a convex mesh and a corresponding collision body in the dynamics world - mDumbbell = new Dumbbell(position1, mCollisionWorld, meshFolderPath, mPhongShader); + mDumbbell = new Dumbbell(position1, mCollisionWorld, mMeshFolderPath, mPhongShader); // ---------- Box ---------- // openglframework::Vector3 position2(0, 0, 0); @@ -71,38 +68,41 @@ RaycastScene::RaycastScene(const std::string& name) // Create a sphere and a corresponding collision body in the dynamics world mSphere = new Sphere(SPHERE_RADIUS, position3, mCollisionWorld, - meshFolderPath, mPhongShader); + mMeshFolderPath, mPhongShader); // ---------- Cone ---------- // openglframework::Vector3 position4(0, 0, 0); // Create a cone and a corresponding collision body in the dynamics world mCone = new Cone(CONE_RADIUS, CONE_HEIGHT, position4, mCollisionWorld, - meshFolderPath, mPhongShader); + mMeshFolderPath, mPhongShader); // ---------- Cylinder ---------- // openglframework::Vector3 position5(0, 0, 0); // Create a cylinder and a corresponding collision body in the dynamics world mCylinder = new Cylinder(CYLINDER_RADIUS, CYLINDER_HEIGHT, position5, - mCollisionWorld, meshFolderPath, mPhongShader); + mCollisionWorld, mMeshFolderPath, mPhongShader); // ---------- Capsule ---------- // openglframework::Vector3 position6(0, 0, 0); // Create a cylinder and a corresponding collision body in the dynamics world mCapsule = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, position6 , - mCollisionWorld, meshFolderPath, mPhongShader); + mCollisionWorld, mMeshFolderPath, mPhongShader); // ---------- Convex Mesh ---------- // openglframework::Vector3 position7(0, 0, 0); // Create a convex mesh and a corresponding collision body in the dynamics world - mConvexMesh = new ConvexMesh(position7, mCollisionWorld, meshFolderPath, mPhongShader); + mConvexMesh = new ConvexMesh(position7, mCollisionWorld, mMeshFolderPath, mPhongShader); // Create the lines that will be used for raycasting createLines(); + // Create the VBO and VAO to render the lines + createVBOAndVAO(mPhongShader); + changeBody(); } @@ -128,6 +128,9 @@ void RaycastScene::createLines() { openglframework::Vector3 point2(0.0f, 0.0f, 0.0f); Line* line = new Line(point1, point2); mLines.push_back(line); + + mLinePoints.push_back(point1); + mLinePoints.push_back(point2); } } } @@ -225,6 +228,10 @@ RaycastScene::~RaycastScene() { ++it) { delete (*it); } + + // Destroy the VBOs and VAO + mVBOVertices.destroy(); + mVAO.destroy(); } // Update the physics world (take a simulation step) @@ -264,25 +271,48 @@ void RaycastScene::render() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_CULL_FACE); - // Get the world-space to camera-space matrix - const openglframework::Matrix4 worldToCameraMatrix = mCamera.getTransformMatrix().getInverse(); - // Bind the shader mPhongShader.bind(); - openglframework::Vector4 grey(0.7, 0.7, 0.7, 1); - mPhongShader.setVector4Uniform("vertexColor", grey); + // Get the world-space to camera-space matrix + const openglframework::Matrix4 worldToCameraMatrix = mCamera.getTransformMatrix().getInverse(); // Set the variables of the shader mPhongShader.setMatrix4x4Uniform("projectionMatrix", mCamera.getProjectionMatrix()); - mPhongShader.setVector3Uniform("light0PosCameraSpace", worldToCameraMatrix * mLight0.getOrigin()); + mPhongShader.setVector3Uniform("light0PosCameraSpace",worldToCameraMatrix * mLight0.getOrigin()); mPhongShader.setVector3Uniform("lightAmbientColor", Vector3(0.3f, 0.3f, 0.3f)); - const Color& diffColLight0 = mLight0.getDiffuseColor(); - const Color& specColLight0 = mLight0.getSpecularColor(); - mPhongShader.setVector3Uniform("light0DiffuseColor", Vector3(diffColLight0.r, diffColLight0.g, diffColLight0.b)); - mPhongShader.setVector3Uniform("light0SpecularColor", Vector3(specColLight0.r, specColLight0.g, specColLight0.b)); - mPhongShader.setFloatUniform("shininess", 200.0f); + const Color& diffCol = mLight0.getDiffuseColor(); + const Color& specCol = mLight0.getSpecularColor(); + mPhongShader.setVector3Uniform("light0DiffuseColor", Vector3(diffCol.r, diffCol.g, diffCol.b)); + mPhongShader.setVector3Uniform("light0SpecularColor", Vector3(specCol.r, specCol.g, specCol.b)); + mPhongShader.setFloatUniform("shininess", 60.0f); + // Set the model to camera matrix + const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix; + mPhongShader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix); + + // Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the + // model-view matrix) + const openglframework::Matrix3 normalMatrix = + localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose(); + mPhongShader.setMatrix3x3Uniform("normalMatrix", normalMatrix); + + // Set the vertex color + openglframework::Vector4 color(1, 0, 0, 1); + mPhongShader.setVector4Uniform("vertexColor", color); + + // Bind the VAO + mVAO.bind(); + + // Draw the lines + glDrawArrays(GL_LINES, 0, NB_RAYS); + + // Unbind the VAO + mVAO.unbind(); + + mPhongShader.unbind(); + + // Render the shapes if (mBox->getCollisionBody()->isActive()) mBox->render(mPhongShader, worldToCameraMatrix); if (mSphere->getCollisionBody()->isActive()) mSphere->render(mPhongShader, worldToCameraMatrix); if (mCone->getCollisionBody()->isActive()) mCone->render(mPhongShader, worldToCameraMatrix); @@ -291,7 +321,7 @@ void RaycastScene::render() { if (mConvexMesh->getCollisionBody()->isActive()) mConvexMesh->render(mPhongShader, worldToCameraMatrix); if (mDumbbell->getCollisionBody()->isActive()) mDumbbell->render(mPhongShader, worldToCameraMatrix); - mPhongShader.unbind(); + //mPhongShader.unbind(); mPhongShader.bind(); mPhongShader.setVector3Uniform("light0SpecularColor", Vector3(0, 0, 0)); @@ -299,7 +329,7 @@ void RaycastScene::render() { mPhongShader.setVector4Uniform("vertexColor", redColor); // Render all the raycast hit points - mRaycastManager.render(mPhongShader, worldToCameraMatrix, mAreNormalsDisplayed); + mRaycastManager.render(worldToCameraMatrix, mAreNormalsDisplayed); mPhongShader.unbind(); mPhongShader.bind(); @@ -316,3 +346,45 @@ void RaycastScene::render() { // Unbind the shader mPhongShader.unbind(); } + +// Create the Vertex Buffer Objects used to render with OpenGL. +/// We create two VBOs (one for vertices and one for indices) +void RaycastScene::createVBOAndVAO(openglframework::Shader& shader) { + + // Bind the shader + shader.bind(); + + // Get the location of shader attribute variables + GLint vertexPositionLoc = shader.getAttribLocation("vertexPosition"); + + // Create the VBO for the vertices data + mVBOVertices.create(); + mVBOVertices.bind(); + size_t sizeVertices = mLinePoints.size() * sizeof(openglframework::Vector3); + mVBOVertices.copyDataIntoVBO(sizeVertices, &mLinePoints[0], GL_STATIC_DRAW); + mVBOVertices.unbind(); + + // Create the VAO for both VBOs + mVAO.create(); + mVAO.bind(); + + // Bind the VBO of vertices + mVBOVertices.bind(); + glEnableVertexAttribArray(vertexPositionLoc); + glVertexAttribPointer(vertexPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL); + + // Unbind the VAO + mVAO.unbind(); + + // Unbind the shader + shader.unbind(); +} + +// Called when a keyboard event occurs +void RaycastScene::keyboardEvent(int key, int scancode, int action, int mods) { + + // If the space key has been pressed + if (key == GLFW_KEY_SPACE && action == GLFW_PRESS) { + changeBody(); + } +} diff --git a/testbed/scenes/raycast/RaycastScene.h b/testbed/scenes/raycast/RaycastScene.h index f3e6ed4d..79fa8c9d 100644 --- a/testbed/scenes/raycast/RaycastScene.h +++ b/testbed/scenes/raycast/RaycastScene.h @@ -70,12 +70,24 @@ class RaycastManager : public rp3d::RaycastCallback { /// All the normals at hit points std::vector mNormals; + /// Shader + openglframework::Shader& mShader; + + /// Contact point mesh folder path + std::string mMeshFolderPath; + public: + RaycastManager(openglframework::Shader& shader, + const std::string& meshFolderPath) + : mShader(shader), mMeshFolderPath(meshFolderPath) { + + } + virtual rp3d::decimal notifyRaycastHit(const rp3d::RaycastInfo& raycastInfo) { rp3d::Vector3 hitPos = raycastInfo.worldPoint; openglframework::Vector3 position(hitPos.x, hitPos.y, hitPos.z); - VisualContactPoint* point = new VisualContactPoint(position); + VisualContactPoint* point = new VisualContactPoint(position, mShader, mMeshFolderPath); mHitPoints.push_back(point); // Create a line to display the normal at hit point @@ -87,14 +99,13 @@ class RaycastManager : public rp3d::RaycastCallback { return raycastInfo.hitFraction; } - void render(openglframework::Shader& shader, - const openglframework::Matrix4& worldToCameraMatrix, + void render(const openglframework::Matrix4& worldToCameraMatrix, bool showNormals) { // Render all the raycast hit points for (std::vector::iterator it = mHitPoints.begin(); it != mHitPoints.end(); ++it) { - (*it)->render(shader, worldToCameraMatrix); + (*it)->render(mShader, worldToCameraMatrix); } if (showNormals) { @@ -102,7 +113,7 @@ class RaycastManager : public rp3d::RaycastCallback { // Render all the normals at hit points for (std::vector::iterator it = mNormals.begin(); it != mNormals.end(); ++it) { - (*it)->render(shader, worldToCameraMatrix); + (*it)->render(mShader, worldToCameraMatrix); } } } @@ -132,15 +143,18 @@ class RaycastScene : public Scene { // -------------------- Attributes -------------------- // - /// Raycast manager - RaycastManager mRaycastManager; - /// Light 0 openglframework::Light mLight0; /// Phong shader openglframework::Shader mPhongShader; + /// Contact point mesh folder path + std::string mMeshFolderPath; + + /// Raycast manager + RaycastManager mRaycastManager; + /// All the raycast lines std::vector mLines; @@ -164,9 +178,22 @@ class RaycastScene : public Scene { /// Collision world used for the physics simulation rp3d::CollisionWorld* mCollisionWorld; + /// All the points to render the lines + std::vector mLinePoints; + + /// Vertex Buffer Object for the vertices data + openglframework::VertexBufferObject mVBOVertices; + + /// Vertex Array Object for the vertex data + openglframework::VertexArrayObject mVAO; + /// Create the raycast lines void createLines(); + // Create the Vertex Buffer Objects used to render with OpenGL. + void createVBOAndVAO(openglframework::Shader& shader); + + public: // -------------------- Methods -------------------- // @@ -195,6 +222,9 @@ class RaycastScene : public Scene { /// Display or not the surface normals at hit points void showHideNormals(); + + /// Called when a keyboard event occurs + virtual void keyboardEvent(int key, int scancode, int action, int mods); }; // Display or not the surface normals at hit points diff --git a/testbed/src/TestbedApplication.cpp b/testbed/src/TestbedApplication.cpp index d58150d0..cdc31397 100644 --- a/testbed/src/TestbedApplication.cpp +++ b/testbed/src/TestbedApplication.cpp @@ -162,7 +162,7 @@ void TestbedApplication::createScenes() { mScenes.push_back(raycastScene); assert(mScenes.size() > 0); - mCurrentScene = mScenes[1]; + mCurrentScene = mScenes[0]; } // Remove all the scenes From 80cf65ccf2c25c2d710a891a2c448ded82c39254 Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Mon, 29 Jun 2015 23:35:50 +0200 Subject: [PATCH 14/36] Allow to change the gravity vector of the DynamicsWorld --- src/engine/DynamicsWorld.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/engine/DynamicsWorld.h b/src/engine/DynamicsWorld.h index 482bc66e..975bf661 100644 --- a/src/engine/DynamicsWorld.h +++ b/src/engine/DynamicsWorld.h @@ -220,6 +220,9 @@ class DynamicsWorld : public CollisionWorld { /// Return the gravity vector of the world Vector3 getGravity() const; + /// Set the gravity vector of the world + void setGravity(Vector3& gravity); + /// Return if the gravity is on bool isGravityEnabled() const; @@ -366,6 +369,14 @@ inline Vector3 DynamicsWorld::getGravity() const { return mGravity; } +// Set the gravity vector of the world +/** + * @param gravity The gravity vector (in meter per seconds squared) + */ +inline Vector3 DynamicsWorld::setGravity(Vector3& gravity) { + mGravity = gravity; +} + // Return if the gravity is enaled /** * @return True if the gravity is enabled in the world From 82f6bf2dbbb1483e9707f86e5b4e54759f98dbb4 Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Tue, 30 Jun 2015 19:50:17 +0200 Subject: [PATCH 15/36] Work on the GUI --- src/engine/DynamicsWorld.h | 2 +- testbed/src/Gui.cpp | 44 +++++++++++++++++++++++------- testbed/src/Scene.h | 12 ++++++-- testbed/src/TestbedApplication.cpp | 19 +++++++++++-- testbed/src/TestbedApplication.h | 44 ++++++++++++++++++++++++++++++ 5 files changed, 106 insertions(+), 15 deletions(-) diff --git a/src/engine/DynamicsWorld.h b/src/engine/DynamicsWorld.h index 975bf661..e9e6bae6 100644 --- a/src/engine/DynamicsWorld.h +++ b/src/engine/DynamicsWorld.h @@ -373,7 +373,7 @@ inline Vector3 DynamicsWorld::getGravity() const { /** * @param gravity The gravity vector (in meter per seconds squared) */ -inline Vector3 DynamicsWorld::setGravity(Vector3& gravity) { +inline void DynamicsWorld::setGravity(Vector3& gravity) { mGravity = gravity; } diff --git a/testbed/src/Gui.cpp b/testbed/src/Gui.cpp index 6d5ad0eb..7a1ac83f 100644 --- a/testbed/src/Gui.cpp +++ b/testbed/src/Gui.cpp @@ -107,6 +107,8 @@ void Gui::init() { void Gui::displayHeader() { + TestbedApplication& app = TestbedApplication::getInstance(); + ImVec2 buttonSize(120, 40); int display_w, display_h; @@ -122,10 +124,23 @@ void Gui::displayHeader() { ImGui::Begin("Header", NULL, ImVec2(display_w, HEADER_HEIGHT), 1.0f, window_flags); ImGui::SetWindowPos(ImVec2(0, 0)); - ImGui::Button("Play", buttonSize); ImGui::SameLine(); - ImGui::Button("Pause", buttonSize); ImGui::SameLine(); - ImGui::Button("Step", buttonSize); ImGui::SameLine(); - ImGui::Button("Restart", buttonSize); ImGui::SameLine(); + + bool isRunning = app.mTimer.isRunning(); + if (ImGui::Button(isRunning ? "Pause" : "Play", buttonSize)) { + app.togglePlayPauseSimulation(); + } + ImGui::SameLine(); + + if (ImGui::Button("Step", buttonSize)) { + app.toggleTakeSinglePhysicsStep(); + } + ImGui::SameLine(); + + if (ImGui::Button("Restart", buttonSize)) { + app.restartSimulation(); + } + ImGui::SameLine(); + ImGui::End(); ImGui::PopStyleColor(1); @@ -152,8 +167,16 @@ void Gui::displayLeftPane() { ImGui::SetWindowPos(ImVec2(0, HEADER_HEIGHT)); // ----- Left Pane Header ----- // - ImGui::Button("Scenes", buttonSize); ImGui::SameLine(); - ImGui::Button("Physics", buttonSize); ImGui::SameLine(); + if (ImGui::Button("Scenes", buttonSize)) { + mLeftPane = SCENES; + } + ImGui::SameLine(); + + if (ImGui::Button("Physics", buttonSize)) { + mLeftPane = PHYSICS; + } + ImGui::SameLine(); + ImGui::Button("Rendering", buttonSize); ImGui::SameLine(); ImGui::Button("Profiling", buttonSize); @@ -194,6 +217,11 @@ void Gui::displayScenesPane() { void Gui::displayPhysicsPane() { + TestbedApplication& app = TestbedApplication::getInstance(); + + // Physics time step + //float timestep = app.ge; + //ImGui::InputFloat("Timestep", ×tep, 0.01f, 1.0f); } void Gui::displayRenderingPane() { @@ -241,10 +269,6 @@ void Gui::render() { //glfwPollEvents(); beginNewFrame(); - bool show_test_window = true; - bool show_another_window = false; - ImVec4 clear_color = ImColor(255, 255, 255); - displayHeader(); displayLeftPane(); diff --git a/testbed/src/Scene.h b/testbed/src/Scene.h index 2f269a36..e6460805 100644 --- a/testbed/src/Scene.h +++ b/testbed/src/Scene.h @@ -35,8 +35,16 @@ struct EngineSettings { public: - float elapsedTime; // Elapsed time (in seconds) - float timeStep; // Current time step (in seconds) + float elapsedTime; // Elapsed time (in seconds) + float timeStep; // Current time step (in seconds) + int nbVelocitySolverIterations; // Nb of velocity solver iterations + int nbPositionSolverIterations; // Nb of position solver iterations + bool isSleepingEnabled; // True if sleeping technique is enabled + float timeBeforeSleep; // Time of inactivity before a body sleep + float sleepLinearVelocity; // Sleep linear velocity + float sleepAngularVelocity; // Sleep angular velocity + bool isGravityEnabled; // True if gravity is enabled + openglframework::Vector3 gravity; // Gravity vector /// Constructor EngineSettings() : elapsedTime(0.0f), timeStep(0.0f) { diff --git a/testbed/src/TestbedApplication.cpp b/testbed/src/TestbedApplication.cpp index cdc31397..d972aeb3 100644 --- a/testbed/src/TestbedApplication.cpp +++ b/testbed/src/TestbedApplication.cpp @@ -50,13 +50,15 @@ TestbedApplication& TestbedApplication::getInstance() { } // Constructor -TestbedApplication::TestbedApplication() : mFPS(0), mNbFrames(0), mPreviousTime(0){ +TestbedApplication::TestbedApplication() : mFPS(0), mNbFrames(0), mPreviousTime(0) { mCurrentScene = NULL; mEngineSettings.timeStep = DEFAULT_TIMESTEP; mIsMultisamplingActive = true; mWidth = 1280; mHeight = 720; + mSinglePhysicsStepEnabled = false; + mSinglePhysicsStepDone = false; } // Destructor @@ -175,6 +177,13 @@ void TestbedApplication::destroyScenes() { mCurrentScene = NULL; } +void TestbedApplication::updateSinglePhysicsStep() { + + assert(!mTimer.isRunning()); + + mCurrentScene->updatePhysics(); +} + // Update the physics of the current scene void TestbedApplication::updatePhysics() { @@ -202,7 +211,13 @@ void TestbedApplication::updatePhysics() { void TestbedApplication::update() { // Update the physics - updatePhysics(); + if (mSinglePhysicsStepEnabled && !mSinglePhysicsStepDone) { + updateSinglePhysicsStep(); + mSinglePhysicsStepDone = true; + } + else { + updatePhysics(); + } // Compute the interpolation factor float factor = mTimer.computeInterpolationFactor(mEngineSettings.timeStep); diff --git a/testbed/src/TestbedApplication.h b/testbed/src/TestbedApplication.h index 9843653c..eb5d2276 100644 --- a/testbed/src/TestbedApplication.h +++ b/testbed/src/TestbedApplication.h @@ -81,6 +81,12 @@ class TestbedApplication { /// Width and height of the window int mWidth, mHeight; + /// True if the next simulation update is a single physics step + bool mSinglePhysicsStepEnabled; + + /// True if the single physics step has been taken already + bool mSinglePhysicsStepDone; + // -------------------- Methods -------------------- // /// Private constructor (for the singleton class) @@ -98,6 +104,9 @@ class TestbedApplication { /// Update void update(); + /// Update the simulation by taking a single physics step + void updateSinglePhysicsStep(); + /// Called when the windows is reshaped void reshape(); @@ -140,6 +149,15 @@ class TestbedApplication { /// Return the list of the scenes std::vector getScenes(); + /// Start/stop the simulation + void togglePlayPauseSimulation(); + + /// Restart the simulation + void restartSimulation(); + + /// Set the variable to know if we need to take a single physics step + void toggleTakeSinglePhysicsStep(); + public : // -------------------- Methods -------------------- // @@ -169,5 +187,31 @@ inline std::vector TestbedApplication::getScenes() { return mScenes; } +// Start the simulation +inline void TestbedApplication::togglePlayPauseSimulation() { + + if (mTimer.isRunning()) { + mTimer.stop(); + } + else { + mTimer.start(); + } +} + +// Restart the simulation +inline void TestbedApplication::restartSimulation() { + mCurrentScene->reset(); + mTimer.start(); +} + +// Take a single step of simulation +inline void TestbedApplication::toggleTakeSinglePhysicsStep() { + mSinglePhysicsStepEnabled = true; + mSinglePhysicsStepDone = false; + + if (mTimer.isRunning()) { + mSinglePhysicsStepEnabled = false; + } +} #endif From 39b7883462fa20ed9abe61b10641d62081eeebd1 Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Sat, 11 Jul 2015 18:34:37 +0200 Subject: [PATCH 16/36] Add methods to query number of solver iterations in DynamicsWorld --- src/engine/DynamicsWorld.h | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/engine/DynamicsWorld.h b/src/engine/DynamicsWorld.h index e9e6bae6..6e39416a 100644 --- a/src/engine/DynamicsWorld.h +++ b/src/engine/DynamicsWorld.h @@ -189,9 +189,15 @@ class DynamicsWorld : public CollisionWorld { /// Update the physics simulation void update(decimal timeStep); + /// Get the number of iterations for the velocity constraint solver + uint getNbIterationsVelocitySolver() const; + /// Set the number of iterations for the velocity constraint solver void setNbIterationsVelocitySolver(uint nbIterations); + /// Get the number of iterations for the position constraint solver + uint getNbIterationsPositionSolver() const; + /// Set the number of iterations for the position constraint solver void setNbIterationsPositionSolver(uint nbIterations); @@ -305,7 +311,12 @@ inline void DynamicsWorld::resetBodiesForceAndTorque() { (*it)->mExternalForce.setToZero(); (*it)->mExternalTorque.setToZero(); } -} +} + +// Get the number of iterations for the velocity constraint solver +inline uint DynamicsWorld::getNbIterationsVelocitySolver() const { + return mNbVelocitySolverIterations; +} // Set the number of iterations for the velocity constraint solver /** @@ -315,6 +326,11 @@ inline void DynamicsWorld::setNbIterationsVelocitySolver(uint nbIterations) { mNbVelocitySolverIterations = nbIterations; } +// Get the number of iterations for the position constraint solver +inline uint DynamicsWorld::getNbIterationsPositionSolver() const { + return mNbPositionSolverIterations; +} + // Set the number of iterations for the position constraint solver /** * @param nbIterations Number of iterations for the position solver From be5d635e811eb9a0e5874c16c3968dd1d251084a Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Sat, 11 Jul 2015 18:35:58 +0200 Subject: [PATCH 17/36] Change imgui library and other modifications in testbed application --- testbed/CMakeLists.txt | 15 +- testbed/imgui/DroidSans.ttf | Bin 0 -> 190044 bytes testbed/imgui/LICENSE | 21 - testbed/imgui/imconfig.h | 58 - testbed/imgui/imgui.cpp | 12142 +--------------- testbed/imgui/imgui.h | 1111 +- testbed/imgui/imguiRenderGL2.cpp | 489 + testbed/imgui/imguiRenderGL2.h | 29 + testbed/imgui/imguiRenderGL3.cpp | 695 + testbed/imgui/imguiRenderGL3.h | 28 + testbed/imgui/stb_rect_pack.h | 547 - testbed/imgui/stb_textedit.h | 1254 -- testbed/imgui/stb_truetype.h | 821 +- .../collisionshapes/CollisionShapesScene.cpp | 23 + testbed/scenes/cubes/CubesScene.cpp | 24 + testbed/scenes/joints/JointsScene.cpp | 23 + testbed/scenes/raycast/RaycastScene.cpp | 1 + testbed/src/Gui.cpp | 487 +- testbed/src/Gui.h | 34 +- testbed/src/Scene.h | 8 + testbed/src/TestbedApplication.cpp | 38 +- testbed/src/TestbedApplication.h | 2 + 22 files changed, 2424 insertions(+), 15426 deletions(-) create mode 100644 testbed/imgui/DroidSans.ttf delete mode 100644 testbed/imgui/LICENSE delete mode 100644 testbed/imgui/imconfig.h create mode 100644 testbed/imgui/imguiRenderGL2.cpp create mode 100644 testbed/imgui/imguiRenderGL2.h create mode 100644 testbed/imgui/imguiRenderGL3.cpp create mode 100644 testbed/imgui/imguiRenderGL3.h delete mode 100644 testbed/imgui/stb_rect_pack.h delete mode 100644 testbed/imgui/stb_textedit.h diff --git a/testbed/CMakeLists.txt b/testbed/CMakeLists.txt index dd6faefc..4dc2511b 100644 --- a/testbed/CMakeLists.txt +++ b/testbed/CMakeLists.txt @@ -19,6 +19,14 @@ FILE(COPY "shaders/" DESTINATION "${EXECUTABLE_OUTPUT_PATH}/shaders/") # Copy the meshes used for the demo into the build directory FILE(COPY "meshes/" DESTINATION "${EXECUTABLE_OUTPUT_PATH}/meshes/") +# Copy the fonts used for the GUI into the build directory +FILE(COPY "imgui/DroidSans.ttf" DESTINATION "${EXECUTABLE_OUTPUT_PATH}") + +# Enable C++11 features +SET(CMAKE_CXX_FLAGS "-std=c++0x") + +#ADD_DEFINITIONS(-DGL3) + # Headers INCLUDE_DIRECTORIES("src/" "opengl-framework/src/" "glfw/include/" "common/" "scenes/" "imgui/") @@ -37,11 +45,10 @@ SET(TESTBED_SOURCES # IMGUI source files SET(IMGUI_SOURCES - imgui/imgui.h imgui/imgui.cpp - imgui/imconfig.h - imgui/stb_rect_pack.h - imgui/stb_textedit.h + imgui/imgui.h + imgui/imguiRenderGL3.h + imgui/imguiRenderGL3.cpp imgui/stb_truetype.h ) diff --git a/testbed/imgui/DroidSans.ttf b/testbed/imgui/DroidSans.ttf new file mode 100644 index 0000000000000000000000000000000000000000..767c63ad000e3eea20f3cb7a43ba9f4154ed7a5d GIT binary patch literal 190044 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%0D=-PBu&{ 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 type if you don't want to use the provided implementation defined in imgui.h -//#include -//#define ImVector std::vector -//#define ImVector MyVector - -//---- Define assertion handler. Defaults to calling assert(). -//#define IM_ASSERT(_EXPR) MyAssert(_EXPR) - -//---- Define attributes of all API symbols declarations, e.g. for DLL under Windows. -//#define IMGUI_API __declspec( dllexport ) -//#define IMGUI_API __declspec( dllimport ) - -//---- Include imgui_user.inl at the end of imgui.cpp so you can include code that extends ImGui using its private data/functions. -//#define IMGUI_INCLUDE_IMGUI_USER_INL - -//---- Include imgui_user.h at the end of imgui.h -//#define IMGUI_INCLUDE_IMGUI_USER_H - -//---- Don't implement default handlers for Windows (so as not to link with OpenClipboard() and others Win32 functions) -//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS -//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS - -//---- Don't implement help and test window functionality (ShowUserGuide()/ShowStyleEditor()/ShowTestWindow() methods will be empty) -//#define IMGUI_DISABLE_TEST_WINDOWS - -//---- Implement STB libraries in a namespace to avoid conflicts -//#define IMGUI_STB_NAMESPACE ImStb - -//---- Define constructor and implicit cast operators to convert back<>forth from your math types and ImVec2/ImVec4. -/* -#define IM_VEC2_CLASS_EXTRA \ - ImVec2(const MyVec2& f) { x = f.x; y = f.y; } \ - operator MyVec2() const { return MyVec2(x,y); } - -#define IM_VEC4_CLASS_EXTRA \ - ImVec4(const MyVec4& f) { x = f.x; y = f.y; z = f.z; w = f.w; } \ - operator MyVec4() const { return MyVec4(x,y,z,w); } -*/ - -//---- Freely implement extra functions within the ImGui:: namespace. -//---- Declare helpers or widgets implemented in imgui_user.inl or elsewhere, so end-user doesn't need to include multiple files. -//---- e.g. you can create variants of the ImGui::Value() helper for your low-level math types, or your own widgets/helpers. -/* -namespace ImGui -{ - void Value(const char* prefix, const MyVec2& v, const char* float_format = NULL); - void Value(const char* prefix, const MyVec4& v, const char* float_format = NULL); -} -*/ - diff --git a/testbed/imgui/imgui.cpp b/testbed/imgui/imgui.cpp index a0f0fe4a..77fdae25 100644 --- a/testbed/imgui/imgui.cpp +++ b/testbed/imgui/imgui.cpp @@ -1,11499 +1,683 @@ -// ImGui library v1.39 WIP -// See ImGui::ShowTestWindow() for sample code. -// Read 'Programmer guide' below for notes on how to setup ImGui in your codebase. -// Get latest version at https://github.com/ocornut/imgui -// Developed by Omar Cornut and ImGui contributors. +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. +// -/* - - Index - - MISSION STATEMENT - - END-USER GUIDE - - PROGRAMMER GUIDE (read me!) - - API BREAKING CHANGES (read me when you update!) - - FREQUENTLY ASKED QUESTIONS (FAQ), TIPS - - Can I have multiple widgets with the same label? (Yes) - - How do I update to a newer version of ImGui? - - Why is my text output blurry? - - How can I load a different font than the default? - - How can I load multiple fonts? - - How can I display and input Chinese, Japanese, Korean characters? - - ISSUES & TODO-LIST - - CODE - - SAMPLE CODE - - FONT DATA - - - MISSION STATEMENT - ================= - - - easy to use to create code-driven and data-driven tools - - easy to use to create ad hoc short-lived tools and long-lived, more elaborate tools - - easy to hack and improve - - minimize screen real-estate usage - - minimize setup and maintenance - - minimize state storage on user side - - portable, minimize dependencies, run on target (consoles, phones, etc.) - - efficient runtime (NB- we do allocate when "growing" content - creating a window / opening a tree node for the first time, etc. - but a typical frame won't allocate anything) - - read about immediate-mode gui principles @ http://mollyrocket.com/861, http://mollyrocket.com/forums/index.html - - Designed for developers and content-creators, not the typical end-user! Some of the weaknesses includes: - - doesn't look fancy, doesn't animate - - limited layout features, intricate layouts are typically crafted in code - - occasionally uses statically sized buffers for string manipulations - won't crash, but some very long pieces of text may be clipped. functions like ImGui::TextUnformatted() don't have such restriction. - - - END-USER GUIDE - ============== - - - double-click title bar to collapse window - - click upper right corner to close a window, available when 'bool* p_opened' is passed to ImGui::Begin() - - click and drag on lower right corner to resize window - - click and drag on any empty space to move window - - double-click/double-tap on lower right corner grip to auto-fit to content - - TAB/SHIFT+TAB to cycle through keyboard editable fields - - use mouse wheel to scroll - - use CTRL+mouse wheel to zoom window contents (if IO.FontAllowScaling is true) - - CTRL+Click on a slider to input value as text - - text editor: - - Hold SHIFT or use mouse to select text. - - CTRL+Left/Right to word jump - - CTRL+Shift+Left/Right to select words - - CTRL+A our Double-Click to select all - - CTRL+X,CTRL+C,CTRL+V to use OS clipboard - - CTRL+Z,CTRL+Y to undo/redo - - ESCAPE to revert text to its original value - - You can apply arithmetic operators +,*,/ on numerical values. Use +- to subtract (because - would set a negative value!) - - - PROGRAMMER GUIDE - ================ - - - read the FAQ below this section! - - your code creates the UI, if your code doesn't run the UI is gone! == very dynamic UI, no construction/destructions steps, less data retention on your side, no state duplication, less sync, less bugs. - - call and read ImGui::ShowTestWindow() for sample code demonstrating most features. - - see examples/ folder for standalone sample applications. e.g. examples/opengl_example/ - - customization: PushStyleColor()/PushStyleVar() or the style editor to tweak the look of the interface (e.g. if you want a more compact UI or a different color scheme). - - - getting started: - - initialisation: call ImGui::GetIO() to retrieve the ImGuiIO structure and fill the 'Settings' data. - - every frame: - 1/ in your mainloop or right after you got your keyboard/mouse info, call ImGui::GetIO() and fill the 'Input' data, then call ImGui::NewFrame(). - 2/ use any ImGui function you want between NewFrame() and Render() - 3/ ImGui::Render() to render all the accumulated command-lists. it will call your RenderDrawListFn handler that you set in the IO structure. - - all rendering information are stored into command-lists until ImGui::Render() is called. - - ImGui never touches or know about your GPU state. the only function that knows about GPU is the RenderDrawListFn handler that you must provide. - - effectively it means you can create widgets at any time in your code, regardless of "update" vs "render" considerations. - - refer to the examples applications in the examples/ folder for instruction on how to setup your code. - - a typical application skeleton may be: - - // Application init - ImGuiIO& io = ImGui::GetIO(); - io.DisplaySize.x = 1920.0f; - io.DisplaySize.y = 1280.0f; - io.DeltaTime = 1.0f/60.0f; - io.IniFilename = "imgui.ini"; - // TODO: Fill others settings of the io structure - - // Load texture - unsigned char* pixels; - int width, height, bytes_per_pixels; - io.Fonts->GetTexDataAsRGBA32(pixels, &width, &height, &bytes_per_pixels); - // TODO: copy texture to graphics memory. - // TODO: store your texture pointer/identifier in 'io.Fonts->TexID' - - // Application main loop - while (true) - { - // 1) get low-level input - // e.g. on Win32, GetKeyboardState(), or poll your events, etc. - - // 2) TODO: fill all fields of IO structure and call NewFrame - ImGuiIO& io = ImGui::GetIO(); - io.MousePos = mouse_pos; - io.MouseDown[0] = mouse_button_0; - io.KeysDown[i] = ... - ImGui::NewFrame(); - - // 3) most of your application code here - you can use any of ImGui::* functions at any point in the frame - ImGui::Begin("My window"); - ImGui::Text("Hello, world."); - ImGui::End(); - GameUpdate(); - GameRender(); - - // 4) render & swap video buffers - ImGui::Render(); - // swap video buffer, etc. - } - - - after calling ImGui::NewFrame() you can read back 'io.WantCaptureMouse' and 'io.WantCaptureKeyboard' to tell if ImGui - wants to use your inputs. if it does you can discard/hide the inputs from the rest of your application. - - API BREAKING CHANGES - ==================== - - Occasionally introducing changes that are breaking the API. The breakage are generally minor and easy to fix. - Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. - - - 2015/04/13 (1.38) - renamed IsClipped() to IsRectClipped(). Kept inline redirection function (will obsolete). - - 2015/04/09 (1.38) - renamed ImDrawList::AddArc() to ImDrawList::AddArcFast() for compatibility with future API - - 2015/04/03 (1.38) - removed ImGuiCol_CheckHovered, ImGuiCol_CheckActive, replaced with the more general ImGuiCol_FrameBgHovered, ImGuiCol_FrameBgActive. - - 2014/04/03 (1.38) - removed support for passing -FLT_MAX..+FLT_MAX as the range for a SliderFloat(). Use DragFloat() or Inputfloat() instead. - - 2015/03/17 (1.36) - renamed GetItemRectMin()/GetItemRectMax()/IsMouseHoveringBox() to GetItemRectMin()/GetItemRectMax()/IsMouseHoveringRect(). Kept inline redirection function (will obsolete). - - 2015/03/15 (1.36) - renamed style.TreeNodeSpacing to style.IndentSpacing, ImGuiStyleVar_TreeNodeSpacing to ImGuiStyleVar_IndentSpacing - - 2015/03/13 (1.36) - renamed GetWindowIsFocused() to IsWindowFocused(). Kept inline redirection function (will obsolete). - - 2015/03/08 (1.35) - renamed style.ScrollBarWidth to style.ScrollbarWidth - - 2015/02/27 (1.34) - renamed OpenNextNode(bool) to SetNextTreeNodeOpened(bool, ImGuiSetCond). Kept inline redirection function (will obsolete). - - 2015/02/27 (1.34) - renamed ImGuiSetCondition_*** to ImGuiSetCond_***, and _FirstUseThisSession becomes _Once. - - 2015/02/11 (1.32) - changed text input callback ImGuiTextEditCallback return type from void-->int. reserved for future use, return 0 for now. - - 2015/02/10 (1.32) - renamed GetItemWidth() to CalcItemWidth() to clarify its evolving behavior - - 2015/02/08 (1.31) - renamed GetTextLineSpacing() to GetTextLineHeightWithSpacing() - - 2015/02/01 (1.31) - removed IO.MemReallocFn (unused) - - 2015/01/19 (1.30) - renamed ImGuiStorage::GetIntPtr()/GetFloatPtr() to GetIntRef()/GetIntRef() because Ptr was conflicting with actual pointer storage functions. - - 2015/01/11 (1.30) - big font/image API change! now loads TTF file. allow for multiple fonts. no need for a PNG loader. - (1.30) - removed GetDefaultFontData(). uses io.Fonts->GetTextureData*() API to retrieve uncompressed pixels. - this sequence: - const void* png_data; - unsigned int png_size; - ImGui::GetDefaultFontData(NULL, NULL, &png_data, &png_size); - // - became: - unsigned char* pixels; - int width, height; - io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); - // - io.Fonts->TexID = (your_texture_identifier); - you now have much more flexibility to load multiple TTF fonts and manage the texture buffer for internal needs. - it is now recommended your sample the font texture with bilinear interpolation. - (1.30) - added texture identifier in ImDrawCmd passed to your render function (we can now render images). make sure to set io.Fonts->TexID. - (1.30) - removed IO.PixelCenterOffset (unnecessary, can be handled in user projection matrix) - (1.30) - removed ImGui::IsItemFocused() in favor of ImGui::IsItemActive() which handles all widgets - - 2014/12/10 (1.18) - removed SetNewWindowDefaultPos() in favor of new generic API SetNextWindowPos(pos, ImGuiSetCondition_FirstUseEver) - - 2014/11/28 (1.17) - moved IO.Font*** options to inside the IO.Font-> structure (FontYOffset, FontTexUvForWhite, FontBaseScale, FontFallbackGlyph) - - 2014/11/26 (1.17) - reworked syntax of IMGUI_ONCE_UPON_A_FRAME helper macro to increase compiler compatibility - - 2014/11/07 (1.15) - renamed IsHovered() to IsItemHovered() - - 2014/10/02 (1.14) - renamed IMGUI_INCLUDE_IMGUI_USER_CPP to IMGUI_INCLUDE_IMGUI_USER_INL and imgui_user.cpp to imgui_user.inl (more IDE friendly) - - 2014/09/25 (1.13) - removed 'text_end' parameter from IO.SetClipboardTextFn (the string is now always zero-terminated for simplicity) - - 2014/09/24 (1.12) - renamed SetFontScale() to SetWindowFontScale() - - 2014/09/24 (1.12) - moved IM_MALLOC/IM_REALLOC/IM_FREE preprocessor defines to IO.MemAllocFn/IO.MemReallocFn/IO.MemFreeFn - - 2014/08/30 (1.09) - removed IO.FontHeight (now computed automatically) - - 2014/08/30 (1.09) - moved IMGUI_FONT_TEX_UV_FOR_WHITE preprocessor define to IO.FontTexUvForWhite - - 2014/08/28 (1.09) - changed the behavior of IO.PixelCenterOffset following various rendering fixes - - - FREQUENTLY ASKED QUESTIONS (FAQ), TIPS - ====================================== - - Q: Can I have multiple widgets with the same label? - A: Yes. A primer on the use of labels/IDs in ImGui.. - - - Interactive widgets require state to be carried over multiple frames (most typically ImGui often needs to remember what is the "active" widget). - to do so they need an unique ID. unique ID are typically derived from a string label, an integer index or a pointer. - - Button("OK"); // Label = "OK", ID = hash of "OK" - Button("Cancel"); // Label = "Cancel", ID = hash of "Cancel" - - - Elements that are not clickable, such as Text() items don't need an ID. - - - ID are uniquely scoped within windows, tree nodes, etc. so no conflict can happen if you have two buttons called "OK" in two different windows - or in two different locations of a tree. - - - if you have a same ID twice in the same location, you'll have a conflict: - - Button("OK"); - Button("OK"); // ID collision! Both buttons will be treated as the same. - - Fear not! this is easy to solve and there are many ways to solve it! - - - when passing a label you can optionally specify extra unique ID information within string itself. This helps solving the simpler collision cases. - use "##" to pass a complement to the ID that won't be visible to the end-user: - - Button("Play##0"); // Label = "Play", ID = hash of "Play##0" - Button("Play##1"); // Label = "Play", ID = hash of "Play##1" (different from above) - - - occasionally (rarely) you might want change a label while preserving a constant ID. This allows you to animate labels. - use "###" to pass a label that isn't part of ID: - - Button("Hello###ID"; // Label = "Hello", ID = hash of "ID" - Button("World###ID"; // Label = "World", ID = hash of "ID" (same as above) - - - use PushID() / PopID() to create scopes and avoid ID conflicts within the same Window. - this is the most convenient way of distinguish ID if you are iterating and creating many UI elements. - you can push a pointer, a string or an integer value. remember that ID are formed from the addition of everything in the ID stack! - - for (int i = 0; i < 100; i++) - { - PushID(i); - Button("Click"); // Label = "Click", ID = hash of integer + "label" (unique) - PopID(); - } - - for (int i = 0; i < 100; i++) - { - MyObject* obj = Objects[i]; - PushID(obj); - Button("Click"); // Label = "Click", ID = hash of pointer + "label" (unique) - PopID(); - } - - for (int i = 0; i < 100; i++) - { - MyObject* obj = Objects[i]; - PushID(obj->Name); - Button("Click"); // Label = "Click", ID = hash of string + "label" (unique) - PopID(); - } - - - more example showing that you can stack multiple prefixes into the ID stack: - - Button("Click"); // Label = "Click", ID = hash of "Click" - PushID("node"); - Button("Click"); // Label = "Click", ID = hash of "node" + "Click" - PushID(my_ptr); - Button("Click"); // Label = "Click", ID = hash of "node" + ptr + "Click" - PopID(); - PopID(); - - - tree nodes implicitly creates a scope for you by calling PushID(). - - Button("Click"); // Label = "Click", ID = hash of "Click" - if (TreeNode("node")) - { - Button("Click"); // Label = "Click", ID = hash of "node" + "Click" - TreePop(); - } - - - when working with trees, ID are used to preserve the opened/closed state of each tree node. - depending on your use cases you may want to use strings, indices or pointers as ID. - e.g. when displaying a single object that may change over time (1-1 relationship), using a static string as ID will preserve your node open/closed state when the targeted object change. - e.g. when displaying a list of objects, using indices or pointers as ID will preserve the node open/closed state differently. experiment and see what makes more sense! - - Q: How do I update to a newer version of ImGui? - A: Overwrite the following files: - imgui.cpp - imgui.h - stb_rect_pack.h - stb_textedit.h - stb_truetype.h - Check the "API BREAKING CHANGES" sections for a list of occasional API breaking changes. - - Q: Why is my text output blurry? - A: In your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) - - Q: How can I load a different font than the default? (default is an embedded version of ProggyClean.ttf, rendered at size 13) - A: Use the font atlas to load the TTF file you want: - - io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels); - io.Fonts->GetTexDataAsRGBA32() or GetTexDataAsAlpha8() - - Q: How can I load multiple fonts? - A: Use the font atlas to pack them into a single texture: - - ImFont* font0 = io.Fonts->AddFontDefault(); - ImFont* font1 = io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels); - ImFont* font2 = io.Fonts->AddFontFromFileTTF("myfontfile2.ttf", size_in_pixels); - io.Fonts->GetTexDataAsRGBA32() or GetTexDataAsAlpha8() - // the first loaded font gets used by default - // use ImGui::PushFont()/ImGui::PopFont() to change the font at runtime - - Q: How can I render and input Chinese, Japanese, Korean characters? - A: When loading a font, pass custom Unicode ranges to specify the glyphs to load. ImGui will support UTF-8 encoding across the board. - Character input depends on you passing the right character code to io.AddInputCharacter(). The example applications do that. - - io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels, io.Fonts->GetGlyphRangesJapanese()); // Load Japanese characters - io.Fonts->GetTexDataAsRGBA32() or GetTexDataAsAlpha8() - io.ImeWindowHandle = MY_HWND; // To input using Microsoft IME, give ImGui the hwnd of your application - - - tip: the construct 'IMGUI_ONCE_UPON_A_FRAME { ... }' will run the block of code only once a frame. You can use it to quickly add custom UI in the middle of a deep nested inner loop in your code. - - tip: you can create widgets without a Begin()/End() block, they will go in an implicit window called "Debug" - - tip: you can call Begin() multiple times with the same name during the same frame, it will keep appending to the same window. - - tip: you can call Render() multiple times (e.g for VR renders). - - tip: call and read the ShowTestWindow() code for more example of how to use ImGui! - - - ISSUES & TODO-LIST - ================== - - - misc: merge or clarify ImVec4 vs ImRect? - - window: add horizontal scroll - - window: fix resize grip rendering scaling along with Rounding style setting - - window: autofit feedback loop when user relies on any dynamic layout (window width multiplier, column). maybe just clearly drop manual autofit? - - window: add a way for very transient windows (non-saved, temporary overlay over hundreds of objects) to "clean" up from the global window list. - - window: allow resizing of child windows (possibly given min/max for each axis?) - - window: background options for child windows, border option (disable rounding) - - window: resizing from any sides? + mouse cursor directives for app. - - widgets: display mode: widget-label, label-widget (aligned on column or using fixed size), label-newline-tab-widget etc. - - widgets: clean up widgets internal toward exposing everything. - - main: considering adding EndFrame()/Init(). some constructs are awkward in the implementation because of the lack of them. - - main: IsItemHovered() make it more consistent for various type of widgets, widgets with multiple components, etc. also effectively IsHovered() region sometimes differs from hot region, e.g tree nodes - - main: IsItemHovered() info stored in a stack? so that 'if TreeNode() { Text; TreePop; } if IsHovered' return the hover state of the TreeNode? -!- input number: large int not reliably supported because of int<>float conversions. - - input number: optional range min/max for Input*() functions - - input number: holding [-]/[+] buttons could increase the step speed non-linearly (or user-controlled) - - input number: use mouse wheel to step up/down - - input number: non-decimal input. - - text: proper alignment options - - layout: horizontal layout helper (github issue #97) - - layout: more generic alignment state (left/right/centered) for single items? - - layout: clean up the InputFloatN/SliderFloatN/ColorEdit4 layout code. item width should include frame padding. - - columns: separator function or parameter that works within the column (currently Separator() bypass all columns) (github issue #125) - - columns: declare column set (each column: fixed size, %, fill, distribute default size among fills) (github issue #125) - - columns: columns header to act as button (~sort op) and allow resize/reorder (github issue #125) - - columns: user specify columns size (github issue #125) - - popup: border options. richer api like BeginChild() perhaps? (github issue #197) - - combo: turn child handling code into pop up helper - - combo: contents should extends to fit label if combo widget is small - - listbox: multiple selection - - listbox: user may want to initial scroll to focus on the one selected value? - ! menubar, menus (github issue #126) - - tabs - - gauge: various forms of gauge/loading bars widgets - - color: better color editor. - - plot: make it easier for user to draw extra stuff into the graph (e.g: draw basis, highlight certain points, 2d plots, multiple plots) - - plot: "smooth" automatic scale over time, user give an input 0.0(full user scale) 1.0(full derived from value) - - plot: add a helper e.g. Plot(char* label, float value, float time_span=2.0f) that stores values and Plot them for you - probably another function name. and/or automatically allow to plot ANY displayed value (more reliance on stable ID) - - file selection widget -> build the tool in our codebase to improve model-dialog idioms - - slider: allow using the [-]/[+] buttons used by InputFloat()/InputInt() - - slider: initial absolute click is imprecise. change to relative movement slider (same as scrollbar). - - slider: add dragging-based widgets to edit values with mouse (on 2 axises), saving screen real-estate. - - text edit: clean up the mess caused by converting UTF-8 <> wchar. the code is rather inefficient right now. - - text edit: centered text for slider as input text so it matches typical positioning. - - text edit: flag to disable live update of the user buffer. - - text edit: field resize behavior - field could stretch when being edited? hover tooltip shows more text? - - text edit: add multi-line text edit - - tree: add treenode/treepush int variants? because (void*) cast from int warns on some platforms/settings - - settings: write more decent code to allow saving/loading new fields - - settings: api for per-tool simple persistent data (bool,int,float,columns sizes,etc.) in .ini file - ! style: store rounded corners in texture to use 1 quad per corner (filled and wireframe). so rounding have minor cost. - - style: checkbox: padding for "active" color should be a multiplier of the - - style: colorbox not always square? - - text: simple markup language for color change? - - log: LogButtons() options for specifying depth and/or hiding depth slider - - log: have more control over the log scope (e.g. stop logging when leaving current tree node scope) - - log: be able to log anything (e.g. right-click on a window/tree-node, shows context menu? log into tty/file/clipboard) - - log: let user copy any window content to clipboard easily (CTRL+C on windows? while moving it? context menu?). code is commented because it fails with multiple Begin/End pairs. - - filters: set a current filter that tree node can automatically query to hide themselves - - filters: handle wildcards (with implicit leading/trailing *), regexps - - shortcuts: add a shortcut api, e.g. parse "&Save" and/or "Save (CTRL+S)", pass in to widgets or provide simple ways to use (button=activate, input=focus) - ! keyboard: tooltip & combo boxes are messing up / not honoring keyboard tabbing - - keyboard: full keyboard navigation and focus. - - input: rework IO to be able to pass actual events to fix temporal aliasing issues. - - input: support track pad style scrolling & slider edit. - - tooltip: move to fit within screen (e.g. when mouse cursor is right of the screen). - - portability: big-endian test/support (github issue #81) - - misc: mark printf compiler attributes on relevant functions - - misc: provide a way to compile out the entire implementation while providing a dummy API (e.g. #define IMGUI_DUMMY_IMPL) - - misc: double-clicking on title bar to minimize isn't consistent, perhaps move to single-click on left-most collapse icon? - - style editor: have a more global HSV setter (e.g. alter hue on all elements). consider replacing active/hovered by offset in HSV space? - - style editor: color child window height expressed in multiple of line height. - - optimization/render: use indexed rendering to reduce vertex data cost (e.g. for remote/networked imgui) - - optimization/render: merge command-lists with same clip-rect into one even if they aren't sequential? (as long as in-between clip rectangle don't overlap)? - - optimization: turn some the various stack vectors into statically-sized arrays - - optimization: better clipping for multi-component widgets -*/ - -#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) -#define _CRT_SECURE_NO_WARNINGS -#endif +// Source altered and distributed from https://github.com/AdrienHerubel/imgui +#include +#include +#define _USE_MATH_DEFINES +#include #include "imgui.h" -#include // toupper, isprint -#include // sqrtf, fabsf, fmodf, powf, cosf, sinf, floorf, ceilf -#include // intptr_t -#include // vsnprintf, sscanf -#include // new (ptr) #ifdef _MSC_VER -#pragma warning (disable: 4505) // unreferenced local function has been removed (stb stuff) -#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen +# define snprintf _snprintf #endif -// Clang warnings with -Weverything -#ifdef __clang__ -#pragma clang diagnostic ignored "-Wold-style-cast" // warning : use of old-style cast // yes, they are more terse. -#pragma clang diagnostic ignored "-Wfloat-equal" // warning : comparing floating point with == or != is unsafe // storing and comparing against same constants ok. -#pragma clang diagnostic ignored "-Wformat-nonliteral" // warning : format string is not a string literal // passing non-literal to vsnformat(). yes, user passing incorrect format strings can crash the code. -#pragma clang diagnostic ignored "-Wexit-time-destructors" // warning : declaration requires an exit-time destructor // exit-time destruction order is undefined. if MemFree() leads to users code that has been disabled before exit it might cause problems. ImGui coding style welcomes static/globals. -#pragma clang diagnostic ignored "-Wglobal-constructors" // warning : declaration requires a global destructor // similar to above, not sure what the exact difference it. -#pragma clang diagnostic ignored "-Wsign-conversion" // warning : implicit conversion changes signedness // -#pragma clang diagnostic ignored "-Wmissing-noreturn" // warning : function xx could be declared with attribute 'noreturn' warning // GetDefaultFontData() asserts which some implementation makes it never return. -#endif -#ifdef __GNUC__ -#pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used -#endif +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//------------------------------------------------------------------------- -// STB libraries implementation -//------------------------------------------------------------------------- - -struct ImGuiTextEditState; - -//#define IMGUI_STB_NAMESPACE ImStb -//#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION -//#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION - -#ifdef IMGUI_STB_NAMESPACE -namespace IMGUI_STB_NAMESPACE -{ -#endif - -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunused-function" -#pragma clang diagnostic ignored "-Wmissing-prototypes" -#endif - -#define STBRP_ASSERT(x) IM_ASSERT(x) -#ifndef IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION -#define STBRP_STATIC -#define STB_RECT_PACK_IMPLEMENTATION -#endif -#include "stb_rect_pack.h" - -#define STBTT_malloc(x,u) ((void)(u), ImGui::MemAlloc(x)) -#define STBTT_free(x,u) ((void)(u), ImGui::MemFree(x)) -#define STBTT_assert(x) IM_ASSERT(x) -#ifndef IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION -#define STBTT_STATIC -#define STB_TRUETYPE_IMPLEMENTATION -#endif -#include "stb_truetype.h" - -#undef STB_TEXTEDIT_STRING -#undef STB_TEXTEDIT_CHARTYPE -#define STB_TEXTEDIT_STRING ImGuiTextEditState -#define STB_TEXTEDIT_CHARTYPE ImWchar -#include "stb_textedit.h" - -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - -#ifdef IMGUI_STB_NAMESPACE -} // namespace ImStb -using namespace IMGUI_STB_NAMESPACE; -#endif - -//------------------------------------------------------------------------- -// Forward Declarations -//------------------------------------------------------------------------- - -struct ImRect; -struct ImGuiColMod; -struct ImGuiStyleMod; -struct ImGuiDrawContext; -struct ImGuiTextEditState; -struct ImGuiIniData; -struct ImGuiState; -struct ImGuiWindow; - -static bool ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, bool allow_key_modifiers, bool repeat = false, bool pressed_on_click = false); -static void LogText(const ImVec2& ref_pos, const char* text, const char* text_end = NULL); - -static void RenderText(ImVec2 pos, const char* text, const char* text_end = NULL, bool hide_text_after_hash = true); -static void RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width); -static void RenderTextClipped(ImVec2 pos, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& clip_max); -static void RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border = true, float rounding = 0.0f); -static void RenderCollapseTriangle(ImVec2 p_min, bool opened, float scale = 1.0f, bool shadow = false); - -static void SetFont(ImFont* font); -static bool ItemAdd(const ImRect& bb, const ImGuiID* id); -static void ItemSize(ImVec2 size, float text_offset_y = 0.0f); -static void ItemSize(const ImRect& bb, float text_offset_y = 0.0f); -static void PushColumnClipRect(int column_index = -1); -static bool IsClippedEx(const ImRect& bb, const ImGuiID* id, bool clip_even_when_logged); - -static bool IsMouseHoveringRect(const ImRect& bb); -static bool IsKeyPressedMap(ImGuiKey key, bool repeat = true); - -static void Scrollbar(ImGuiWindow* window); -static bool CloseWindowButton(bool* p_opened = NULL); -static void FocusWindow(ImGuiWindow* window); -static ImGuiWindow* FindHoveredWindow(ImVec2 pos, bool excluding_childs); - -// Helpers: String -static int ImStricmp(const char* str1, const char* str2); -static int ImStrnicmp(const char* str1, const char* str2, int count); -static char* ImStrdup(const char *str); -static size_t ImStrlenW(const ImWchar* str); -static const char* ImStristr(const char* haystack, const char* needle, const char* needle_end); -static size_t ImFormatString(char* buf, size_t buf_size, const char* fmt, ...); -static size_t ImFormatStringV(char* buf, size_t buf_size, const char* fmt, va_list args); - -// Helpers: Misc -static ImU32 ImHash(const void* data, size_t data_size, ImU32 seed); -static bool ImLoadFileToMemory(const char* filename, const char* file_open_mode, void** out_file_data, size_t* out_file_size, size_t padding_bytes = 0); -static inline int ImUpperPowerOfTwo(int v) { v--; v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; v++; return v; } -static inline bool ImCharIsSpace(int c) { return c == ' ' || c == '\t' || c == 0x3000; } - -// Helpers: UTF-8 <> wchar -static int ImTextCharToUtf8(char* buf, size_t buf_size, unsigned int in_char); // return output UTF-8 bytes count -static ptrdiff_t ImTextStrToUtf8(char* buf, size_t buf_size, const ImWchar* in_text, const ImWchar* in_text_end); // return output UTF-8 bytes count -static int ImTextCharFromUtf8(unsigned int* out_char, const char* in_text, const char* in_text_end); // return input UTF-8 bytes count -static ptrdiff_t ImTextStrFromUtf8(ImWchar* buf, size_t buf_size, const char* in_text, const char* in_text_end, const char** in_remaining = NULL); // return input UTF-8 bytes count -static int ImTextCountCharsFromUtf8(const char* in_text, const char* in_text_end); // return number of UTF-8 code-points (NOT bytes count) -static int ImTextCountUtf8BytesFromStr(const ImWchar* in_text, const ImWchar* in_text_end); // return number of bytes to express string as UTF-8 code-points - -//----------------------------------------------------------------------------- -// Platform dependent default implementations -//----------------------------------------------------------------------------- - -static const char* GetClipboardTextFn_DefaultImpl(); -static void SetClipboardTextFn_DefaultImpl(const char* text); -static void ImeSetInputScreenPosFn_DefaultImpl(int x, int y); - -//----------------------------------------------------------------------------- -// User facing structures -//----------------------------------------------------------------------------- - -ImGuiStyle::ImGuiStyle() -{ - Alpha = 1.0f; // Global alpha applies to everything in ImGui - WindowPadding = ImVec2(8,8); // Padding within a window - WindowMinSize = ImVec2(32,32); // Minimum window size - WindowRounding = 9.0f; // Radius of window corners rounding. Set to 0.0f to have rectangular windows - ChildWindowRounding = 0.0f; // Radius of child window corners rounding. Set to 0.0f to have rectangular windows - FramePadding = ImVec2(4,3); // Padding within a framed rectangle (used by most widgets) - FrameRounding = 0.0f; // Radius of frame corners rounding. Set to 0.0f to have rectangular frames (used by most widgets). - ItemSpacing = ImVec2(8,4); // Horizontal and vertical spacing between widgets/lines - ItemInnerSpacing = ImVec2(4,4); // Horizontal and vertical spacing between within elements of a composed widget (e.g. a slider and its label) - TouchExtraPadding = ImVec2(0,0); // Expand reactive bounding box for touch-based system where touch position is not accurate enough. Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget. So don't grow this too much! - AutoFitPadding = ImVec2(8,8); // Extra space after auto-fit (double-clicking on resize grip) - WindowFillAlphaDefault = 0.70f; // Default alpha of window background, if not specified in ImGui::Begin() - IndentSpacing = 22.0f; // Horizontal spacing when e.g. entering a tree node - ColumnsMinSpacing = 6.0f; // Minimum horizontal spacing between two columns - ScrollbarWidth = 16.0f; // Width of the vertical scrollbar - GrabMinSize = 10.0f; // Minimum width/height of a slider or scrollbar grab - DisplaySafeAreaPadding = ImVec2(22,22); // Window positions are clamped to be visible within the display area. If you cannot see the edge of your screen (e.g. on a TV) increase the safe area padding - - Colors[ImGuiCol_Text] = ImVec4(0.90f, 0.90f, 0.90f, 1.00f); - Colors[ImGuiCol_WindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f); - Colors[ImGuiCol_ChildWindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); - Colors[ImGuiCol_Border] = ImVec4(0.70f, 0.70f, 0.70f, 1.00f); - Colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.60f); - Colors[ImGuiCol_FrameBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.30f); // Background of checkbox, radio button, plot, slider, text input - Colors[ImGuiCol_FrameBgHovered] = ImVec4(0.90f, 0.80f, 0.80f, 0.40f); - Colors[ImGuiCol_FrameBgActive] = ImVec4(0.90f, 0.65f, 0.65f, 0.45f); - Colors[ImGuiCol_TitleBg] = ImVec4(0.50f, 0.50f, 1.00f, 0.45f); - Colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.40f, 0.40f, 0.80f, 0.20f); - Colors[ImGuiCol_ScrollbarBg] = ImVec4(0.40f, 0.40f, 0.80f, 0.15f); - Colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.40f, 0.40f, 0.80f, 0.30f); - Colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.40f, 0.40f, 0.80f, 0.40f); - Colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.80f, 0.50f, 0.50f, 0.40f); - Colors[ImGuiCol_ComboBg] = ImVec4(0.20f, 0.20f, 0.20f, 0.99f); - Colors[ImGuiCol_CheckMark] = ImVec4(0.90f, 0.90f, 0.90f, 0.50f); - Colors[ImGuiCol_SliderGrab] = ImVec4(1.00f, 1.00f, 1.00f, 0.30f); - Colors[ImGuiCol_SliderGrabActive] = ImVec4(0.80f, 0.50f, 0.50f, 1.00f); - Colors[ImGuiCol_Button] = ImVec4(0.67f, 0.40f, 0.40f, 0.60f); - Colors[ImGuiCol_ButtonHovered] = ImVec4(0.67f, 0.40f, 0.40f, 1.00f); - Colors[ImGuiCol_ButtonActive] = ImVec4(0.80f, 0.50f, 0.50f, 1.00f); - Colors[ImGuiCol_Header] = ImVec4(0.40f, 0.40f, 0.90f, 0.45f); - Colors[ImGuiCol_HeaderHovered] = ImVec4(0.45f, 0.45f, 0.90f, 0.80f); - Colors[ImGuiCol_HeaderActive] = ImVec4(0.53f, 0.53f, 0.87f, 0.80f); - Colors[ImGuiCol_Column] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f); - Colors[ImGuiCol_ColumnHovered] = ImVec4(0.70f, 0.60f, 0.60f, 1.00f); - Colors[ImGuiCol_ColumnActive] = ImVec4(0.90f, 0.70f, 0.70f, 1.00f); - Colors[ImGuiCol_ResizeGrip] = ImVec4(1.00f, 1.00f, 1.00f, 0.30f); - Colors[ImGuiCol_ResizeGripHovered] = ImVec4(1.00f, 1.00f, 1.00f, 0.60f); - Colors[ImGuiCol_ResizeGripActive] = ImVec4(1.00f, 1.00f, 1.00f, 0.90f); - Colors[ImGuiCol_CloseButton] = ImVec4(0.50f, 0.50f, 0.90f, 0.50f); - Colors[ImGuiCol_CloseButtonHovered] = ImVec4(0.70f, 0.70f, 0.90f, 0.60f); - Colors[ImGuiCol_CloseButtonActive] = ImVec4(0.70f, 0.70f, 0.70f, 1.00f); - Colors[ImGuiCol_PlotLines] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); - Colors[ImGuiCol_PlotLinesHovered] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); - Colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); - Colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f); - Colors[ImGuiCol_TextSelectedBg] = ImVec4(0.00f, 0.00f, 1.00f, 0.35f); - Colors[ImGuiCol_TooltipBg] = ImVec4(0.05f, 0.05f, 0.10f, 0.90f); -} - -// Statically allocated font atlas. This is merely a maneuver to keep ImFontAtlas definition at the bottom of the .h file (otherwise it'd be inside ImGuiIO) -// Also we wouldn't be able to new() one at this point, before users may define IO.MemAllocFn. -static ImFontAtlas GDefaultFontAtlas; - -ImGuiIO::ImGuiIO() -{ - // Most fields are initialized with zero - memset(this, 0, sizeof(*this)); - - DisplaySize = ImVec2(-1.0f, -1.0f); - DeltaTime = 1.0f/60.0f; - IniSavingRate = 5.0f; - IniFilename = "imgui.ini"; - LogFilename = "imgui_log.txt"; - Fonts = &GDefaultFontAtlas; - FontGlobalScale = 1.0f; - MousePos = ImVec2(-1,-1); - MousePosPrev = ImVec2(-1,-1); - MouseDoubleClickTime = 0.30f; - MouseDoubleClickMaxDist = 6.0f; - MouseDragThreshold = 6.0f; - UserData = NULL; - - // User functions - RenderDrawListsFn = NULL; - MemAllocFn = malloc; - MemFreeFn = free; - GetClipboardTextFn = GetClipboardTextFn_DefaultImpl; // Platform dependent default implementations - SetClipboardTextFn = SetClipboardTextFn_DefaultImpl; - ImeSetInputScreenPosFn = ImeSetInputScreenPosFn_DefaultImpl; -} - -// Pass in translated ASCII characters for text input. -// - with glfw you can get those from the callback set in glfwSetCharCallback() -// - on Windows you can get those using ToAscii+keyboard state, or via the WM_CHAR message -void ImGuiIO::AddInputCharacter(ImWchar c) -{ - const size_t n = ImStrlenW(InputCharacters); - if (n + 1 < sizeof(InputCharacters) / sizeof(InputCharacters[0])) - { - InputCharacters[n] = c; - InputCharacters[n+1] = 0; - } -} - -//----------------------------------------------------------------------------- -// Helpers -//----------------------------------------------------------------------------- - -#define IM_ARRAYSIZE(_ARR) ((int)(sizeof(_ARR)/sizeof(*_ARR))) - -#undef PI -const float PI = 3.14159265358979323846f; - -#ifdef INT_MAX -#define IM_INT_MIN INT_MIN -#define IM_INT_MAX INT_MAX -#else -#define IM_INT_MIN (-2147483647-1) -#define IM_INT_MAX (2147483647) -#endif - -// Play it nice with Windows users. Notepad in 2015 still doesn't display text data with Unix-style \n. -#ifdef _MSC_VER -#define STR_NEWLINE "\r\n" -#else -#define STR_NEWLINE "\n" -#endif - -// Math bits -// We are keeping those static in the .cpp file so as not to leak them outside, in the case the user has implicit cast operators between ImVec2 and its own types. -static inline ImVec2 operator*(const ImVec2& lhs, const float rhs) { return ImVec2(lhs.x*rhs, lhs.y*rhs); } -//static inline ImVec2 operator/(const ImVec2& lhs, const float rhs) { return ImVec2(lhs.x/rhs, lhs.y/rhs); } -static inline ImVec2 operator+(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x+rhs.x, lhs.y+rhs.y); } -static inline ImVec2 operator-(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x-rhs.x, lhs.y-rhs.y); } -static inline ImVec2 operator*(const ImVec2& lhs, const ImVec2 rhs) { return ImVec2(lhs.x*rhs.x, lhs.y*rhs.y); } -static inline ImVec2 operator/(const ImVec2& lhs, const ImVec2 rhs) { return ImVec2(lhs.x/rhs.x, lhs.y/rhs.y); } -static inline ImVec2& operator+=(ImVec2& lhs, const ImVec2& rhs) { lhs.x += rhs.x; lhs.y += rhs.y; return lhs; } -static inline ImVec2& operator-=(ImVec2& lhs, const ImVec2& rhs) { lhs.x -= rhs.x; lhs.y -= rhs.y; return lhs; } -static inline ImVec2& operator*=(ImVec2& lhs, const float rhs) { lhs.x *= rhs; lhs.y *= rhs; return lhs; } -//static inline ImVec2& operator/=(ImVec2& lhs, const float rhs) { lhs.x /= rhs; lhs.y /= rhs; return lhs; } - -static inline int ImMin(int lhs, int rhs) { return lhs < rhs ? lhs : rhs; } -static inline int ImMax(int lhs, int rhs) { return lhs >= rhs ? lhs : rhs; } -static inline float ImMin(float lhs, float rhs) { return lhs < rhs ? lhs : rhs; } -static inline float ImMax(float lhs, float rhs) { return lhs >= rhs ? lhs : rhs; } -static inline ImVec2 ImMin(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(ImMin(lhs.x,rhs.x), ImMin(lhs.y,rhs.y)); } -static inline ImVec2 ImMax(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(ImMax(lhs.x,rhs.x), ImMax(lhs.y,rhs.y)); } -static inline int ImClamp(int v, int mn, int mx) { return (v < mn) ? mn : (v > mx) ? mx : v; } -static inline float ImClamp(float v, float mn, float mx) { return (v < mn) ? mn : (v > mx) ? mx : v; } -static inline ImVec2 ImClamp(const ImVec2& f, const ImVec2& mn, ImVec2 mx) { return ImVec2(ImClamp(f.x,mn.x,mx.x), ImClamp(f.y,mn.y,mx.y)); } -static inline float ImSaturate(float f) { return (f < 0.0f) ? 0.0f : (f > 1.0f) ? 1.0f : f; } -static inline float ImLerp(float a, float b, float t) { return a + (b - a) * t; } -static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, const ImVec2& t) { return ImVec2(a.x + (b.x - a.x) * t.x, a.y + (b.y - a.y) * t.y); } -static inline float ImLengthSqr(const ImVec2& lhs) { return lhs.x*lhs.x + lhs.y*lhs.y; } - -static int ImStricmp(const char* str1, const char* str2) -{ - int d; - while ((d = toupper(*str2) - toupper(*str1)) == 0 && *str1) { str1++; str2++; } - return d; -} - -static int ImStrnicmp(const char* str1, const char* str2, int count) -{ - int d = 0; - while (count > 0 && (d = toupper(*str2) - toupper(*str1)) == 0 && *str1) { str1++; str2++; count--; } - return d; -} - -static char* ImStrdup(const char *str) -{ - char *buff = (char*)ImGui::MemAlloc(strlen(str) + 1); - IM_ASSERT(buff); - strcpy(buff, str); - return buff; -} - -static size_t ImStrlenW(const ImWchar* str) -{ - size_t n = 0; - while (*str++) n++; - return n; -} - -static const char* ImStristr(const char* haystack, const char* needle, const char* needle_end) -{ - if (!needle_end) - needle_end = needle + strlen(needle); - - const char un0 = (char)toupper(*needle); - while (*haystack) - { - if (toupper(*haystack) == un0) - { - const char* b = needle + 1; - for (const char* a = haystack + 1; b < needle_end; a++, b++) - if (toupper(*a) != toupper(*b)) - break; - if (b == needle_end) - return haystack; - } - haystack++; - } - return NULL; -} - -// Pass data_size==0 for zero-terminated string -// Try to replace with FNV1a hash? -static ImU32 ImHash(const void* data, size_t data_size, ImU32 seed = 0) -{ - static ImU32 crc32_lut[256] = { 0 }; - if (!crc32_lut[1]) - { - const ImU32 polynomial = 0xEDB88320; - for (ImU32 i = 0; i < 256; i++) - { - ImU32 crc = i; - for (ImU32 j = 0; j < 8; j++) - crc = (crc >> 1) ^ (ImU32(-int(crc & 1)) & polynomial); - crc32_lut[i] = crc; - } - } - - seed = ~seed; - ImU32 crc = seed; - const unsigned char* current = (const unsigned char*)data; - - if (data_size > 0) - { - // Known size - while (data_size--) - crc = (crc >> 8) ^ crc32_lut[(crc & 0xFF) ^ *current++]; - } - else - { - // Zero-terminated string - while (unsigned char c = *current++) - { - // We support a syntax of "label###id" where only "###id" is included in the hash, and only "label" gets displayed. - // Because this syntax is rarely used we are optimizing for the common case. - // - If we reach ### in the string we discard the hash so far and reset to the seed. - // - We don't do 'current += 2; continue;' after handling ### to keep the code smaller. - if (c == '#' && current[0] == '#' && current[1] == '#') - crc = seed; - - crc = (crc >> 8) ^ crc32_lut[(crc & 0xFF) ^ c]; - } - } - return ~crc; -} - -static size_t ImFormatString(char* buf, size_t buf_size, const char* fmt, ...) -{ - va_list args; - va_start(args, fmt); - int w = vsnprintf(buf, buf_size, fmt, args); - va_end(args); - buf[buf_size-1] = 0; - return (w == -1) ? buf_size : (size_t)w; -} - -static size_t ImFormatStringV(char* buf, size_t buf_size, const char* fmt, va_list args) -{ - int w = vsnprintf(buf, buf_size, fmt, args); - buf[buf_size-1] = 0; - return (w == -1) ? buf_size : (size_t)w; -} - -ImU32 ImGui::ColorConvertFloat4ToU32(const ImVec4& in) -{ - ImU32 out = ((ImU32)(ImSaturate(in.x)*255.f)); - out |= ((ImU32)(ImSaturate(in.y)*255.f) << 8); - out |= ((ImU32)(ImSaturate(in.z)*255.f) << 16); - out |= ((ImU32)(ImSaturate(in.w)*255.f) << 24); - return out; -} - -// Convert rgb floats ([0-1],[0-1],[0-1]) to hsv floats ([0-1],[0-1],[0-1]), from Foley & van Dam p592 -// Optimized http://lolengine.net/blog/2013/01/13/fast-rgb-to-hsv -void ImGui::ColorConvertRGBtoHSV(float r, float g, float b, float& out_h, float& out_s, float& out_v) -{ - float K = 0.f; - if (g < b) - { - const float tmp = g; g = b; b = tmp; - K = -1.f; - } - if (r < g) - { - const float tmp = r; r = g; g = tmp; - K = -2.f / 6.f - K; - } - - const float chroma = r - (g < b ? g : b); - out_h = fabsf(K + (g - b) / (6.f * chroma + 1e-20f)); - out_s = chroma / (r + 1e-20f); - out_v = r; -} - -// Convert hsv floats ([0-1],[0-1],[0-1]) to rgb floats ([0-1],[0-1],[0-1]), from Foley & van Dam p593 -// also http://en.wikipedia.org/wiki/HSL_and_HSV -void ImGui::ColorConvertHSVtoRGB(float h, float s, float v, float& out_r, float& out_g, float& out_b) -{ - if (s == 0.0f) - { - // gray - out_r = out_g = out_b = v; - return; - } - - h = fmodf(h, 1.0f) / (60.0f/360.0f); - int i = (int)h; - float f = h - (float)i; - float p = v * (1.0f - s); - float q = v * (1.0f - s * f); - float t = v * (1.0f - s * (1.0f - f)); - - switch (i) - { - case 0: out_r = v; out_g = t; out_b = p; break; - case 1: out_r = q; out_g = v; out_b = p; break; - case 2: out_r = p; out_g = v; out_b = t; break; - case 3: out_r = p; out_g = q; out_b = v; break; - case 4: out_r = t; out_g = p; out_b = v; break; - case 5: default: out_r = v; out_g = p; out_b = q; break; - } -} - -// Load file content into memory -// Memory allocated with ImGui::MemAlloc(), must be freed by user using ImGui::MemFree() -static bool ImLoadFileToMemory(const char* filename, const char* file_open_mode, void** out_file_data, size_t* out_file_size, size_t padding_bytes) -{ - IM_ASSERT(filename && file_open_mode && out_file_data && out_file_size); - *out_file_data = NULL; - *out_file_size = 0; - - FILE* f; - if ((f = fopen(filename, file_open_mode)) == NULL) - return false; - - long file_size_signed; - if (fseek(f, 0, SEEK_END) || (file_size_signed = ftell(f)) == -1 || fseek(f, 0, SEEK_SET)) - { - fclose(f); - return false; - } - - size_t file_size = (size_t)file_size_signed; - void* file_data = ImGui::MemAlloc(file_size + padding_bytes); - if (file_data == NULL) - { - fclose(f); - return false; - } - if (fread(file_data, 1, file_size, f) != file_size) - { - fclose(f); - ImGui::MemFree(file_data); - return false; - } - if (padding_bytes > 0) - memset((void *)(((char*)file_data) + file_size), 0, padding_bytes); - - fclose(f); - *out_file_data = file_data; - *out_file_size = file_size; - - return true; -} - -//----------------------------------------------------------------------------- - -struct ImGuiColMod // Color modifier, backup of modified data so we can restore it -{ - ImGuiCol Col; - ImVec4 PreviousValue; -}; - -struct ImGuiStyleMod // Style modifier, backup of modified data so we can restore it -{ - ImGuiStyleVar Var; - ImVec2 PreviousValue; -}; - -struct ImRect // 2D axis aligned bounding-box -{ - ImVec2 Min; - ImVec2 Max; - - ImRect() { Min = ImVec2(FLT_MAX,FLT_MAX); Max = ImVec2(-FLT_MAX,-FLT_MAX); } - ImRect(const ImVec2& min, const ImVec2& max) { Min = min; Max = max; } - ImRect(const ImVec4& v) { Min.x = v.x; Min.y = v.y; Max.x = v.z; Max.y = v.w; } - ImRect(float x1, float y1, float x2, float y2) { Min.x = x1; Min.y = y1; Max.x = x2; Max.y = y2; } - - ImVec2 GetCenter() const { return Min + (Max-Min)*0.5f; } - ImVec2 GetSize() const { return Max-Min; } - float GetWidth() const { return (Max-Min).x; } - float GetHeight() const { return (Max-Min).y; } - ImVec2 GetTL() const { return Min; } - ImVec2 GetTR() const { return ImVec2(Max.x,Min.y); } - ImVec2 GetBL() const { return ImVec2(Min.x,Max.y); } - ImVec2 GetBR() const { return Max; } - bool Contains(const ImVec2& p) const { return p.x >= Min.x && p.y >= Min.y && p.x < Max.x && p.y < Max.y; } - bool Contains(const ImRect& r) const { return r.Min.x >= Min.x && r.Min.y >= Min.y && r.Max.x < Max.x && r.Max.y < Max.y; } - bool Overlaps(const ImRect& r) const { return r.Min.y < Max.y && r.Max.y > Min.y && r.Min.x < Max.x && r.Max.x > Min.x; } - void Add(const ImVec2& rhs) { Min.x = ImMin(Min.x, rhs.x); Min.y = ImMin(Min.y, rhs.y); Max.x = ImMax(Max.x, rhs.x); Max.y = ImMax(Max.x, rhs.x); } - void Add(const ImRect& rhs) { Min.x = ImMin(Min.x, rhs.Min.x); Min.y = ImMin(Min.y, rhs.Min.y); Max.x = ImMax(Max.x, rhs.Max.x); Max.y = ImMax(Max.y, rhs.Max.y); } - void Expand(const float amount) { Min.x -= amount; Min.y -= amount; Max.x += amount; Max.y += amount; } - void Expand(const ImVec2& amount) { Min -= amount; Max += amount; } - void Clip(const ImRect& clip) { Min.x = ImMax(Min.x, clip.Min.x); Min.y = ImMax(Min.y, clip.Min.y); Max.x = ImMin(Max.x, clip.Max.x); Max.y = ImMin(Max.y, clip.Max.y); } - ImVec2 GetClosestPoint(ImVec2 p, bool on_edge) const - { - if (!on_edge && Contains(p)) - return p; - if (p.x > Max.x) p.x = Max.x; - else if (p.x < Min.x) p.x = Min.x; - if (p.y > Max.y) p.y = Max.y; - else if (p.y < Min.y) p.y = Min.y; - return p; - } -}; -typedef ImRect ImGuiAabb; // FIXME-OBSOLETE - -struct ImGuiGroupData -{ - ImVec2 BackupCursorPos; - ImVec2 BackupCursorMaxPos; - float BackupColumnsStartX; - float BackupCurrentLineHeight; - float BackupCurrentLineTextBaseOffset; - float BackupLogLinePosY; -}; - -// Temporary per-window data, reset at the beginning of the frame -struct ImGuiDrawContext -{ - ImVec2 CursorPos; - ImVec2 CursorPosPrevLine; - ImVec2 CursorStartPos; - ImVec2 CursorMaxPos; // Implicitly calculate the size of our contents, always extending. Saved into window->SizeContents at the end of the frame - float CurrentLineHeight; - float CurrentLineTextBaseOffset; - float PrevLineHeight; - float PrevLineTextBaseOffset; - float LogLinePosY; - int TreeDepth; - ImGuiID LastItemID; - ImRect LastItemRect; - bool LastItemHoveredAndUsable; - bool LastItemHoveredRect; - ImVector ChildWindows; - ImVector AllowKeyboardFocus; - ImVector ItemWidth; // 0.0: default, >0.0: width in pixels, <0.0: align xx pixels to the right of window - ImVector TextWrapPos; - ImVector GroupStack; - ImGuiColorEditMode ColorEditMode; - ImGuiStorage* StateStorage; - - float ColumnsStartX; // Indentation / start position from left of window (increased by TreePush/TreePop, etc.) - float ColumnsOffsetX; // Offset to the current column (if ColumnsCurrent > 0). FIXME: This and the above should be a stack to allow use cases like Tree->Column->Tree. Need revamp columns API. - int ColumnsCurrent; - int ColumnsCount; - ImVec2 ColumnsStartPos; - float ColumnsCellMinY; - float ColumnsCellMaxY; - bool ColumnsShowBorders; - ImGuiID ColumnsSetID; - ImVector ColumnsOffsetsT; // Columns offset normalized 0.0 (far left) -> 1.0 (far right) - - ImGuiDrawContext() - { - CursorPos = CursorPosPrevLine = CursorStartPos = CursorMaxPos = ImVec2(0.0f, 0.0f); - CurrentLineHeight = PrevLineHeight = 0.0f; - CurrentLineTextBaseOffset = PrevLineTextBaseOffset = 0.0f; - LogLinePosY = -1.0f; - TreeDepth = 0; - LastItemID = 0; - LastItemRect = ImRect(0.0f,0.0f,0.0f,0.0f); - LastItemHoveredAndUsable = LastItemHoveredRect = false; - ColorEditMode = ImGuiColorEditMode_RGB; - StateStorage = NULL; - - ColumnsStartX = 0.0f; - ColumnsOffsetX = 0.0f; - ColumnsCurrent = 0; - ColumnsCount = 1; - ColumnsStartPos = ImVec2(0.0f, 0.0f); - ColumnsCellMinY = ColumnsCellMaxY = 0.0f; - ColumnsShowBorders = true; - ColumnsSetID = 0; - } -}; - -// Internal state of the currently focused/edited text input box -struct ImGuiTextEditState -{ - ImGuiID Id; // widget id owning the text state - ImWchar Text[1024]; // edit buffer, we need to persist but can't guarantee the persistence of the user-provided buffer. so we copy into own buffer. - char InitialText[1024*3+1]; // backup of end-user buffer at the time of focus (in UTF-8, unaltered) - size_t CurLenA, CurLenW; // we need to maintain our buffer length in both UTF-8 and wchar format. - size_t BufSizeA; // end-user buffer size, <= 1024 (or increase above) - float Width; // widget width - float ScrollX; - STB_TexteditState StbState; - float CursorAnim; - ImVec2 InputCursorScreenPos; // Cursor position in screen space to be used by IME callback. - bool SelectedAllMouseLock; - ImFont* Font; - float FontSize; - - ImGuiTextEditState() { memset(this, 0, sizeof(*this)); } - - void CursorAnimReset() { CursorAnim = -0.30f; } // After a user-input the cursor stays on for a while without blinking - bool CursorIsVisible() const { return CursorAnim <= 0.0f || fmodf(CursorAnim, 1.20f) <= 0.80f; } // Blinking - bool HasSelection() const { return StbState.select_start != StbState.select_end; } - void SelectAll() { StbState.select_start = 0; StbState.select_end = (int)ImStrlenW(Text); StbState.cursor = StbState.select_end; StbState.has_preferred_x = false; } - - void OnKeyPressed(int key); - void UpdateScrollOffset(); - ImVec2 CalcDisplayOffsetFromCharIdx(int i) const; - - // Static functions because they are used to render non-focused instances of a text input box - static const char* GetTextPointerClippedA(ImFont* font, float font_size, const char* text, float width, ImVec2* out_text_size = NULL); - static const ImWchar* GetTextPointerClippedW(ImFont* font, float font_size, const ImWchar* text, float width, ImVec2* out_text_size = NULL); - static void RenderTextScrolledClipped(ImFont* font, float font_size, const char* text, ImVec2 pos_base, float width, float scroll_x); -}; - -// Data saved in imgui.ini file -struct ImGuiIniData -{ - char* Name; - ImGuiID ID; - ImVec2 Pos; - ImVec2 Size; - bool Collapsed; - - ImGuiIniData() { memset(this, 0, sizeof(*this)); } - ~ImGuiIniData() { if (Name) { ImGui::MemFree(Name); Name = NULL; } } -}; - -struct ImGuiMouseCursorData -{ - ImGuiMouseCursor Type; - ImVec2 Offset; - ImVec2 Size; - ImVec2 TexUvMin[2]; - ImVec2 TexUvMax[2]; -}; - -// Main state for ImGui -struct ImGuiState -{ - bool Initialized; - ImGuiIO IO; - ImGuiStyle Style; - ImFont* Font; // (Shortcut) == FontStack.empty() ? IO.Font : FontStack.back() - float FontSize; // (Shortcut) == FontBaseSize * g.CurrentWindow->FontWindowScale == window->FontSize() - float FontBaseSize; // (Shortcut) == IO.FontGlobalScale * Font->Scale * Font->FontSize. Size of characters. - ImVec2 FontTexUvWhitePixel; // (Shortcut) == Font->TexUvForWhite - - float Time; - int FrameCount; - int FrameCountRendered; - ImVector Windows; - ImVector WindowsSortBuffer; - ImGuiWindow* CurrentWindow; // Being drawn into - ImVector CurrentWindowStack; - ImGuiWindow* FocusedWindow; // Will catch keyboard inputs - ImGuiWindow* HoveredWindow; // Will catch mouse inputs - ImGuiWindow* HoveredRootWindow; // Will catch mouse inputs (for focus/move only) - ImGuiID HoveredId; // Hovered widget - ImGuiID ActiveId; // Active widget - ImGuiID ActiveIdPreviousFrame; - bool ActiveIdIsAlive; - bool ActiveIdIsJustActivated; // Set when - bool ActiveIdIsFocusedOnly; // Set only by active widget. Denote focus but no active interaction. - ImGuiWindow* MovedWindow; // Track the child window we clicked on to move a window. Only valid if ActiveID is the "#MOVE" identifier of a window. - float SettingsDirtyTimer; - ImVector Settings; - int DisableHideTextAfterDoubleHash; - ImVector ColorModifiers; - ImVector StyleModifiers; - ImVector FontStack; - - ImVec2 SetNextWindowPosVal; - ImGuiSetCond SetNextWindowPosCond; - ImVec2 SetNextWindowSizeVal; - ImGuiSetCond SetNextWindowSizeCond; - bool SetNextWindowCollapsedVal; - ImGuiSetCond SetNextWindowCollapsedCond; - bool SetNextWindowFocus; - bool SetNextTreeNodeOpenedVal; - ImGuiSetCond SetNextTreeNodeOpenedCond; - - // Render - ImVector RenderDrawLists[3]; - - // Mouse cursor - ImGuiMouseCursor MouseCursor; - ImDrawList MouseCursorDrawList; // Optional software render of mouse cursors, if io.MouseDrawCursor is set - ImGuiMouseCursorData MouseCursorData[ImGuiMouseCursor_Count_]; - - // Widget state - ImGuiTextEditState InputTextState; - ImGuiID ScalarAsInputTextId; // Temporary text input when CTRL+clicking on a slider, etc. - ImGuiStorage ColorEditModeStorage; // for user selection - ImGuiID ActiveComboID; - ImVec2 ActiveClickDeltaToCenter; - float DragCurrentValue; // current dragged value, always float, not rounded by end-user precision settings - ImVec2 DragLastMouseDelta; - float DragSpeedDefaultRatio; // if speed == 0.0f, uses (max-min) * DragSpeedDefaultRatio - float DragSpeedScaleSlow; - float DragSpeedScaleFast; - float ScrollbarClickDeltaToGrabCenter; // distance between mouse and center of grab box, normalized in parent space - char Tooltip[1024]; - char* PrivateClipboard; // if no custom clipboard handler is defined - - // Logging - bool LogEnabled; - FILE* LogFile; - ImGuiTextBuffer* LogClipboard; // pointer so our GImGui static constructor doesn't call heap allocators. - int LogStartDepth; - int LogAutoExpandMaxDepth; - - // Misc - float FramerateSecPerFrame[120]; // calculate estimate of framerate for user - int FramerateSecPerFrameIdx; - float FramerateSecPerFrameAccum; - char TempBuffer[1024*3+1]; // temporary text buffer - - ImGuiState() - { - Initialized = false; - Font = NULL; - FontBaseSize = FontSize = 0.0f; - FontTexUvWhitePixel = ImVec2(0.0f, 0.0f); - - Time = 0.0f; - FrameCount = 0; - FrameCountRendered = -1; - CurrentWindow = NULL; - FocusedWindow = NULL; - HoveredWindow = NULL; - HoveredRootWindow = NULL; - HoveredId = 0; - ActiveId = 0; - ActiveIdPreviousFrame = 0; - ActiveIdIsAlive = false; - ActiveIdIsJustActivated = false; - ActiveIdIsFocusedOnly = false; - MovedWindow = NULL; - SettingsDirtyTimer = 0.0f; - DisableHideTextAfterDoubleHash = 0; - - SetNextWindowPosVal = ImVec2(0.0f, 0.0f); - SetNextWindowPosCond = 0; - SetNextWindowSizeVal = ImVec2(0.0f, 0.0f); - SetNextWindowSizeCond = 0; - SetNextWindowCollapsedVal = false; - SetNextWindowCollapsedCond = 0; - SetNextWindowFocus = false; - SetNextTreeNodeOpenedVal = false; - SetNextTreeNodeOpenedCond = 0; - - ScalarAsInputTextId = 0; - ActiveComboID = 0; - ActiveClickDeltaToCenter = ImVec2(0.0f, 0.0f); - DragCurrentValue = 0.0f; - DragLastMouseDelta = ImVec2(0.0f, 0.0f); - DragSpeedDefaultRatio = 0.01f; - DragSpeedScaleSlow = 0.01f; - DragSpeedScaleFast = 10.0f; - ScrollbarClickDeltaToGrabCenter = 0.0f; - memset(Tooltip, 0, sizeof(Tooltip)); - PrivateClipboard = NULL; - - MouseCursor = ImGuiMouseCursor_Arrow; - - LogEnabled = false; - LogFile = NULL; - LogClipboard = NULL; - LogStartDepth = 0; - LogAutoExpandMaxDepth = 2; - - memset(FramerateSecPerFrame, 0, sizeof(FramerateSecPerFrame)); - FramerateSecPerFrameIdx = 0; - FramerateSecPerFrameAccum = 0.0f; - } -}; - -static ImGuiState GImDefaultState; // Internal state storage -static ImGuiState* GImGui = &GImDefaultState; // We access everything through this pointer. NB: this pointer is always assumed to be != NULL - -struct ImGuiWindow -{ - char* Name; - ImGuiID ID; - ImGuiWindowFlags Flags; - ImVec2 PosFloat; - ImVec2 Pos; // Position rounded-up to nearest pixel - ImVec2 Size; // Current size (==SizeFull or collapsed title bar size) - ImVec2 SizeFull; // Size when non collapsed - ImVec2 SizeContents; // Size of contents (== extents reach of the drawing cursor) from previous frame - ImGuiID MoveID; // == window->GetID("#MOVE") - float ScrollY; - float NextScrollY; - bool ScrollbarY; - bool Visible; // Set to true on Begin() - bool WasVisible; - bool Accessed; // Set to true when any widget access the current window - bool Collapsed; // Set when collapsing window to become only title-bar - bool SkipItems; // == Visible && !Collapsed - int AutoFitFrames; - bool AutoFitOnlyGrows; - int SetWindowPosAllowFlags; // bit ImGuiSetCond_*** specify if SetWindowPos() call will succeed with this particular flag. - int SetWindowSizeAllowFlags; // bit ImGuiSetCond_*** specify if SetWindowSize() call will succeed with this particular flag. - int SetWindowCollapsedAllowFlags; // bit ImGuiSetCond_*** specify if SetWindowCollapsed() call will succeed with this particular flag. - - ImGuiDrawContext DC; // Temporary per-window data, reset at the beginning of the frame - ImVector IDStack; // ID stack. ID are hashes seeded with the value at the top of the stack - ImVector ClipRectStack; // Scissoring / clipping rectangle. x1, y1, x2, y2. - ImRect ClippedRect; // = ClipRectStack.front() after setup in Begin() - int LastFrameDrawn; - float ItemWidthDefault; - ImGuiStorage StateStorage; - float FontWindowScale; // Scale multiplier per-window - ImDrawList* DrawList; - ImGuiWindow* RootWindow; - - // Focus - int FocusIdxAllCounter; // Start at -1 and increase as assigned via FocusItemRegister() - int FocusIdxTabCounter; // (same, but only count widgets which you can Tab through) - int FocusIdxAllRequestCurrent; // Item being requested for focus - int FocusIdxTabRequestCurrent; // Tab-able item being requested for focus - int FocusIdxAllRequestNext; // Item being requested for focus, for next update (relies on layout to be stable between the frame pressing TAB and the next frame) - int FocusIdxTabRequestNext; // " - -public: - ImGuiWindow(const char* name); - ~ImGuiWindow(); - - ImGuiID GetID(const char* str, const char* str_end = NULL); - ImGuiID GetID(const void* ptr); - - bool FocusItemRegister(bool is_active, bool tab_stop = true); // Return true if focus is requested - void FocusItemUnregister(); - - ImRect Rect() const { return ImRect(Pos, Pos+Size); } - float CalcFontSize() const { return GImGui->FontBaseSize * FontWindowScale; } - float TitleBarHeight() const { return (Flags & ImGuiWindowFlags_NoTitleBar) ? 0 : CalcFontSize() + GImGui->Style.FramePadding.y * 2.0f; } - ImRect TitleBarRect() const { return ImRect(Pos, Pos + ImVec2(SizeFull.x, TitleBarHeight())); } - ImVec2 WindowPadding() const { return ((Flags & ImGuiWindowFlags_ChildWindow) && !(Flags & ImGuiWindowFlags_ShowBorders) && !(Flags & ImGuiWindowFlags_ComboBox)) ? ImVec2(0,0) : GImGui->Style.WindowPadding; } - ImU32 Color(ImGuiCol idx, float a=1.f) const { ImVec4 c = GImGui->Style.Colors[idx]; c.w *= GImGui->Style.Alpha * a; return ImGui::ColorConvertFloat4ToU32(c); } - ImU32 Color(const ImVec4& col) const { ImVec4 c = col; c.w *= GImGui->Style.Alpha; return ImGui::ColorConvertFloat4ToU32(c); } -}; - -static inline ImGuiWindow* GetCurrentWindow() -{ - // If this ever crash it probably means that ImGui::NewFrame() hasn't been called. We should always have a CurrentWindow in the stack (there is an implicit "Debug" window) - ImGuiState& g = *GImGui; - g.CurrentWindow->Accessed = true; - return g.CurrentWindow; -} - -static inline void SetCurrentWindow(ImGuiWindow* window) -{ - ImGuiState& g = *GImGui; - g.CurrentWindow = window; - if (window) - g.FontSize = window->CalcFontSize(); -} - -static inline ImGuiWindow* GetParentWindow() -{ - ImGuiState& g = *GImGui; - IM_ASSERT(g.CurrentWindowStack.size() >= 2); - return g.CurrentWindowStack[g.CurrentWindowStack.size() - 2]; -} - -static void SetActiveId(ImGuiID id) -{ - ImGuiState& g = *GImGui; - g.ActiveId = id; - g.ActiveIdIsFocusedOnly = false; - g.ActiveIdIsJustActivated = true; -} - -static void RegisterAliveId(ImGuiID id) -{ - ImGuiState& g = *GImGui; - if (g.ActiveId == id) - g.ActiveIdIsAlive = true; -} - -//----------------------------------------------------------------------------- - -// Helper: Key->value storage -void ImGuiStorage::Clear() -{ - Data.clear(); -} - -// std::lower_bound but without the bullshit -static ImVector::iterator LowerBound(ImVector& data, ImU32 key) -{ - ImVector::iterator first = data.begin(); - ImVector::iterator last = data.end(); - int count = (int)(last - first); - while (count > 0) - { - int count2 = count / 2; - ImVector::iterator mid = first + count2; - if (mid->key < key) - { - first = ++mid; - count -= count2 + 1; - } - else - { - count = count2; - } - } - return first; -} - -int ImGuiStorage::GetInt(ImU32 key, int default_val) const -{ - ImVector::iterator it = LowerBound(const_cast&>(Data), key); - if (it == Data.end() || it->key != key) - return default_val; - return it->val_i; -} - -float ImGuiStorage::GetFloat(ImU32 key, float default_val) const -{ - ImVector::iterator it = LowerBound(const_cast&>(Data), key); - if (it == Data.end() || it->key != key) - return default_val; - return it->val_f; -} - -void* ImGuiStorage::GetVoidPtr(ImGuiID key) const -{ - ImVector::iterator it = LowerBound(const_cast&>(Data), key); - if (it == Data.end() || it->key != key) - return NULL; - return it->val_p; -} - -// References are only valid until a new value is added to the storage. Calling a Set***() function or a Get***Ref() function invalidates the pointer. -int* ImGuiStorage::GetIntRef(ImGuiID key, int default_val) -{ - ImVector::iterator it = LowerBound(Data, key); - if (it == Data.end() || it->key != key) - it = Data.insert(it, Pair(key, default_val)); - return &it->val_i; -} - -float* ImGuiStorage::GetFloatRef(ImGuiID key, float default_val) -{ - ImVector::iterator it = LowerBound(Data, key); - if (it == Data.end() || it->key != key) - it = Data.insert(it, Pair(key, default_val)); - return &it->val_f; -} - -void** ImGuiStorage::GetVoidPtrRef(ImGuiID key, void* default_val) -{ - ImVector::iterator it = LowerBound(Data, key); - if (it == Data.end() || it->key != key) - it = Data.insert(it, Pair(key, default_val)); - return &it->val_p; -} - -// FIXME-OPT: Wasting CPU because all SetInt() are preceeded by GetInt() calls so we should have the result from lower_bound already in place. -// However we only use SetInt() on explicit user action (so that's maximum once a frame) so the optimisation isn't much needed. -void ImGuiStorage::SetInt(ImU32 key, int val) -{ - ImVector::iterator it = LowerBound(Data, key); - if (it == Data.end() || it->key != key) - { - Data.insert(it, Pair(key, val)); - return; - } - it->val_i = val; -} - -void ImGuiStorage::SetFloat(ImU32 key, float val) -{ - ImVector::iterator it = LowerBound(Data, key); - if (it == Data.end() || it->key != key) - { - Data.insert(it, Pair(key, val)); - return; - } - it->val_f = val; -} - -void ImGuiStorage::SetVoidPtr(ImU32 key, void* val) -{ - ImVector::iterator it = LowerBound(Data, key); - if (it == Data.end() || it->key != key) - { - Data.insert(it, Pair(key, val)); - return; - } - it->val_p = val; -} - -void ImGuiStorage::SetAllInt(int v) -{ - for (size_t i = 0; i < Data.size(); i++) - Data[i].val_i = v; -} - -//----------------------------------------------------------------------------- - -// Helper: Parse and apply text filters. In format "aaaaa[,bbbb][,ccccc]" -ImGuiTextFilter::ImGuiTextFilter(const char* default_filter) -{ - if (default_filter) - { - ImFormatString(InputBuf, IM_ARRAYSIZE(InputBuf), "%s", default_filter); - Build(); - } - else - { - InputBuf[0] = 0; - CountGrep = 0; - } -} - -void ImGuiTextFilter::Draw(const char* label, float width) -{ - if (width > 0.0f) - ImGui::PushItemWidth(width); - ImGui::InputText(label, InputBuf, IM_ARRAYSIZE(InputBuf)); - if (width > 0.0f) - ImGui::PopItemWidth(); - Build(); -} - -void ImGuiTextFilter::TextRange::split(char separator, ImVector& out) -{ - out.resize(0); - const char* wb = b; - const char* we = wb; - while (we < e) - { - if (*we == separator) - { - out.push_back(TextRange(wb, we)); - wb = we + 1; - } - we++; - } - if (wb != we) - out.push_back(TextRange(wb, we)); -} - -void ImGuiTextFilter::Build() -{ - Filters.resize(0); - TextRange input_range(InputBuf, InputBuf+strlen(InputBuf)); - input_range.split(',', Filters); - - CountGrep = 0; - for (size_t i = 0; i != Filters.size(); i++) - { - Filters[i].trim_blanks(); - if (Filters[i].empty()) - continue; - if (Filters[i].front() != '-') - CountGrep += 1; - } -} - -bool ImGuiTextFilter::PassFilter(const char* val) const -{ - if (Filters.empty()) - return true; - - if (val == NULL) - val = ""; - - for (size_t i = 0; i != Filters.size(); i++) - { - const TextRange& f = Filters[i]; - if (f.empty()) - continue; - if (f.front() == '-') - { - // Subtract - if (ImStristr(val, f.begin()+1, f.end()) != NULL) - return false; - } - else - { - // Grep - if (ImStristr(val, f.begin(), f.end()) != NULL) - return true; - } - } - - // Implicit * grep - if (CountGrep == 0) - return true; - - return false; -} - -//----------------------------------------------------------------------------- - -// On some platform vsnprintf() takes va_list by reference and modifies it. -// va_copy is the 'correct' way to copy a va_list but Visual Studio prior to 2013 doesn't have it. -#ifndef va_copy -#define va_copy(dest, src) (dest = src) -#endif - -// Helper: Text buffer for logging/accumulating text -void ImGuiTextBuffer::appendv(const char* fmt, va_list args) -{ - va_list args_copy; - va_copy(args_copy, args); - - int len = vsnprintf(NULL, 0, fmt, args); // FIXME-OPT: could do a first pass write attempt, likely successful on first pass. - if (len <= 0) - return; - - const size_t write_off = Buf.size(); - const size_t needed_sz = write_off + (size_t)len; - if (write_off + (size_t)len >= Buf.capacity()) - { - const size_t double_capacity = Buf.capacity() * 2; - Buf.reserve(needed_sz > double_capacity ? needed_sz : double_capacity); - } - - Buf.resize(needed_sz); - ImFormatStringV(&Buf[write_off] - 1, (size_t)len+1, fmt, args_copy); -} - -void ImGuiTextBuffer::append(const char* fmt, ...) -{ - va_list args; - va_start(args, fmt); - appendv(fmt, args); - va_end(args); -} - -//----------------------------------------------------------------------------- - -ImGuiWindow::ImGuiWindow(const char* name) -{ - Name = ImStrdup(name); - ID = ImHash(name, 0); - IDStack.push_back(ID); - MoveID = GetID("#MOVE"); - - Flags = 0; - PosFloat = Pos = ImVec2(0.0f, 0.0f); - Size = SizeFull = ImVec2(0.0f, 0.0f); - SizeContents = ImVec2(0.0f, 0.0f); - ScrollY = 0.0f; - NextScrollY = 0.0f; - ScrollbarY = false; - Visible = WasVisible = false; - Accessed = false; - Collapsed = false; - SkipItems = false; - AutoFitFrames = -1; - AutoFitOnlyGrows = false; - SetWindowPosAllowFlags = SetWindowSizeAllowFlags = SetWindowCollapsedAllowFlags = ImGuiSetCond_Always | ImGuiSetCond_Once | ImGuiSetCond_FirstUseEver; - - LastFrameDrawn = -1; - ItemWidthDefault = 0.0f; - FontWindowScale = 1.0f; - - DrawList = (ImDrawList*)ImGui::MemAlloc(sizeof(ImDrawList)); - new(DrawList) ImDrawList(); - RootWindow = NULL; - - FocusIdxAllCounter = FocusIdxTabCounter = -1; - FocusIdxAllRequestCurrent = FocusIdxTabRequestCurrent = IM_INT_MAX; - FocusIdxAllRequestNext = FocusIdxTabRequestNext = IM_INT_MAX; -} - -ImGuiWindow::~ImGuiWindow() -{ - DrawList->~ImDrawList(); - ImGui::MemFree(DrawList); - DrawList = NULL; - ImGui::MemFree(Name); - Name = NULL; -} - -ImGuiID ImGuiWindow::GetID(const char* str, const char* str_end) -{ - ImGuiID seed = IDStack.back(); - const ImGuiID id = ImHash(str, str_end ? str_end - str : 0, seed); - RegisterAliveId(id); - return id; -} - -ImGuiID ImGuiWindow::GetID(const void* ptr) -{ - ImGuiID seed = IDStack.back(); - const ImGuiID id = ImHash(&ptr, sizeof(void*), seed); - RegisterAliveId(id); - return id; -} - -bool ImGuiWindow::FocusItemRegister(bool is_active, bool tab_stop) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - - const bool allow_keyboard_focus = window->DC.AllowKeyboardFocus.back(); - FocusIdxAllCounter++; - if (allow_keyboard_focus) - FocusIdxTabCounter++; - - // Process keyboard input at this point: TAB, Shift-TAB switch focus - // We can always TAB out of a widget that doesn't allow tabbing in. - if (tab_stop && FocusIdxAllRequestNext == IM_INT_MAX && FocusIdxTabRequestNext == IM_INT_MAX && is_active && IsKeyPressedMap(ImGuiKey_Tab)) - { - // Modulo on index will be applied at the end of frame once we've got the total counter of items. - FocusIdxTabRequestNext = FocusIdxTabCounter + (g.IO.KeyShift ? (allow_keyboard_focus ? -1 : 0) : +1); - } - - if (FocusIdxAllCounter == FocusIdxAllRequestCurrent) - return true; - - if (allow_keyboard_focus) - if (FocusIdxTabCounter == FocusIdxTabRequestCurrent) - return true; - - return false; -} - -void ImGuiWindow::FocusItemUnregister() -{ - FocusIdxAllCounter--; - FocusIdxTabCounter--; -} - -static inline void AddDrawListToRenderList(ImVector& out_render_list, ImDrawList* draw_list) -{ - if (!draw_list->commands.empty() && !draw_list->vtx_buffer.empty()) - { - if (draw_list->commands.back().vtx_count == 0) - draw_list->commands.pop_back(); - out_render_list.push_back(draw_list); - GImGui->IO.MetricsRenderVertices += (int)draw_list->vtx_buffer.size(); - } -} - -static void AddWindowToRenderList(ImVector& out_render_list, ImGuiWindow* window) -{ - AddDrawListToRenderList(out_render_list, window->DrawList); - for (size_t i = 0; i < window->DC.ChildWindows.size(); i++) - { - ImGuiWindow* child = window->DC.ChildWindows[i]; - if (child->Visible) // clipped children may have been marked not Visible - AddWindowToRenderList(out_render_list, child); - } -} - -//----------------------------------------------------------------------------- - -void* ImGui::MemAlloc(size_t sz) -{ - return GImGui->IO.MemAllocFn(sz); -} - -void ImGui::MemFree(void* ptr) -{ - return GImGui->IO.MemFreeFn(ptr); -} - -static ImGuiIniData* FindWindowSettings(const char* name) -{ - ImGuiState& g = *GImGui; - ImGuiID id = ImHash(name, 0); - for (size_t i = 0; i != g.Settings.size(); i++) - { - ImGuiIniData* ini = g.Settings[i]; - if (ini->ID == id) - return ini; - } - return NULL; -} - -static ImGuiIniData* AddWindowSettings(const char* name) -{ - ImGuiIniData* ini = (ImGuiIniData*)ImGui::MemAlloc(sizeof(ImGuiIniData)); - new(ini) ImGuiIniData(); - ini->Name = ImStrdup(name); - ini->ID = ImHash(name, 0); - ini->Collapsed = false; - ini->Pos = ImVec2(FLT_MAX,FLT_MAX); - ini->Size = ImVec2(0,0); - GImGui->Settings.push_back(ini); - return ini; -} - -// Zero-tolerance, poor-man .ini parsing -// FIXME: Write something less rubbish -static void LoadSettings() -{ - ImGuiState& g = *GImGui; - const char* filename = g.IO.IniFilename; - if (!filename) - return; - - char* file_data; - size_t file_size; - if (!ImLoadFileToMemory(filename, "rb", (void**)&file_data, &file_size, 1)) - return; - - ImGuiIniData* settings = NULL; - const char* buf_end = file_data + file_size; - for (const char* line_start = file_data; line_start < buf_end; ) - { - const char* line_end = line_start; - while (line_end < buf_end && *line_end != '\n' && *line_end != '\r') - line_end++; - - if (line_start[0] == '[' && line_end > line_start && line_end[-1] == ']') - { - char name[64]; - ImFormatString(name, IM_ARRAYSIZE(name), "%.*s", line_end-line_start-2, line_start+1); - settings = FindWindowSettings(name); - if (!settings) - settings = AddWindowSettings(name); - } - else if (settings) - { - float x, y; - int i; - if (sscanf(line_start, "Pos=%f,%f", &x, &y) == 2) - settings->Pos = ImVec2(x, y); - else if (sscanf(line_start, "Size=%f,%f", &x, &y) == 2) - settings->Size = ImMax(ImVec2(x, y), g.Style.WindowMinSize); - else if (sscanf(line_start, "Collapsed=%d", &i) == 1) - settings->Collapsed = (i != 0); - } - - line_start = line_end+1; - } - - ImGui::MemFree(file_data); -} - -static void SaveSettings() -{ - ImGuiState& g = *GImGui; - const char* filename = g.IO.IniFilename; - if (!filename) - return; - - // Gather data from windows that were active during this session - for (size_t i = 0; i != g.Windows.size(); i++) - { - ImGuiWindow* window = g.Windows[i]; - if (window->Flags & ImGuiWindowFlags_NoSavedSettings) - continue; - ImGuiIniData* settings = FindWindowSettings(window->Name); - settings->Pos = window->Pos; - settings->Size = window->SizeFull; - settings->Collapsed = window->Collapsed; - } - - // Write .ini file - // If a window wasn't opened in this session we preserve its settings - FILE* f = fopen(filename, "wt"); - if (!f) - return; - for (size_t i = 0; i != g.Settings.size(); i++) - { - const ImGuiIniData* settings = g.Settings[i]; - if (settings->Pos.x == FLT_MAX) - continue; - const char* name = settings->Name; - if (const char* p = strstr(name, "###")) // Skip to the "###" marker if any. We don't skip past to match the behavior of GetID() - name = p; - fprintf(f, "[%s]\n", name); - fprintf(f, "Pos=%d,%d\n", (int)settings->Pos.x, (int)settings->Pos.y); - fprintf(f, "Size=%d,%d\n", (int)settings->Size.x, (int)settings->Size.y); - fprintf(f, "Collapsed=%d\n", settings->Collapsed); - fprintf(f, "\n"); - } - - fclose(f); -} - -static void MarkSettingsDirty() -{ - ImGuiState& g = *GImGui; - - if (g.SettingsDirtyTimer <= 0.0f) - g.SettingsDirtyTimer = g.IO.IniSavingRate; -} - -const char* ImGui::GetVersion() -{ - return IMGUI_VERSION; -} - -// Internal state access - if you want to share ImGui state between modules (e.g. DLL) or allocate it yourself -// Note that we still point to some static data and members (such as GFontAtlas), so the state instance you end up using will point to the static data within its module -void* ImGui::GetInternalState() -{ - return GImGui; -} - -size_t ImGui::GetInternalStateSize() -{ - return sizeof(ImGuiState); -} - -void ImGui::SetInternalState(void* state, bool construct) -{ - if (construct) - new (state) ImGuiState(); - - GImGui = (ImGuiState*)state; -} - -ImGuiIO& ImGui::GetIO() -{ - return GImGui->IO; -} - -ImGuiStyle& ImGui::GetStyle() -{ - return GImGui->Style; -} - -void ImGui::NewFrame() -{ - ImGuiState& g = *GImGui; - - // Check user data - IM_ASSERT(g.IO.DeltaTime > 0.0f); - IM_ASSERT(g.IO.DisplaySize.x >= 0.0f && g.IO.DisplaySize.y >= 0.0f); - IM_ASSERT(g.IO.RenderDrawListsFn != NULL); // Must be implemented - IM_ASSERT(g.IO.Fonts->Fonts.size() > 0); // Font Atlas not created. Did you call io.Fonts->GetTexDataAsRGBA32 / GetTexDataAsAlpha8 ? - IM_ASSERT(g.IO.Fonts->Fonts[0]->IsLoaded()); // Font Atlas not created. Did you call io.Fonts->GetTexDataAsRGBA32 / GetTexDataAsAlpha8 ? - - if (!g.Initialized) - { - // Initialize on first frame - g.LogClipboard = (ImGuiTextBuffer*)ImGui::MemAlloc(sizeof(ImGuiTextBuffer)); - new(g.LogClipboard) ImGuiTextBuffer(); - - IM_ASSERT(g.Settings.empty()); - LoadSettings(); - g.Initialized = true; - } - - SetFont(g.IO.Fonts->Fonts[0]); - - g.Time += g.IO.DeltaTime; - g.FrameCount += 1; - g.Tooltip[0] = '\0'; - - // Update inputs state - if (g.IO.MousePos.x < 0 && g.IO.MousePos.y < 0) - g.IO.MousePos = ImVec2(-9999.0f, -9999.0f); - if ((g.IO.MousePos.x < 0 && g.IO.MousePos.y < 0) || (g.IO.MousePosPrev.x < 0 && g.IO.MousePosPrev.y < 0)) // if mouse just appeared or disappeared (negative coordinate) we cancel out movement in MouseDelta - g.IO.MouseDelta = ImVec2(0.0f, 0.0f); - else - g.IO.MouseDelta = g.IO.MousePos - g.IO.MousePosPrev; - g.IO.MousePosPrev = g.IO.MousePos; - for (size_t i = 0; i < IM_ARRAYSIZE(g.IO.MouseDown); i++) - { - g.IO.MouseDownTime[i] = g.IO.MouseDown[i] ? (g.IO.MouseDownTime[i] < 0.0f ? 0.0f : g.IO.MouseDownTime[i] + g.IO.DeltaTime) : -1.0f; - g.IO.MouseClicked[i] = (g.IO.MouseDownTime[i] == 0.0f); - g.IO.MouseDoubleClicked[i] = false; - if (g.IO.MouseClicked[i]) - { - if (g.Time - g.IO.MouseClickedTime[i] < g.IO.MouseDoubleClickTime) - { - if (ImLengthSqr(g.IO.MousePos - g.IO.MouseClickedPos[i]) < g.IO.MouseDoubleClickMaxDist * g.IO.MouseDoubleClickMaxDist) - g.IO.MouseDoubleClicked[i] = true; - g.IO.MouseClickedTime[i] = -FLT_MAX; // so the third click isn't turned into a double-click - } - else - { - g.IO.MouseClickedTime[i] = g.Time; - } - g.IO.MouseClickedPos[i] = g.IO.MousePos; - g.IO.MouseDragMaxDistanceSqr[i] = 0.0f; - } - else if (g.IO.MouseDown[i]) - { - g.IO.MouseDragMaxDistanceSqr[i] = ImMax(g.IO.MouseDragMaxDistanceSqr[i], ImLengthSqr(g.IO.MousePos - g.IO.MouseClickedPos[i])); - } - } - for (size_t i = 0; i < IM_ARRAYSIZE(g.IO.KeysDown); i++) - g.IO.KeysDownTime[i] = g.IO.KeysDown[i] ? (g.IO.KeysDownTime[i] < 0.0f ? 0.0f : g.IO.KeysDownTime[i] + g.IO.DeltaTime) : -1.0f; - - // Calculate frame-rate for the user, as a purely luxurious feature - g.FramerateSecPerFrameAccum += g.IO.DeltaTime - g.FramerateSecPerFrame[g.FramerateSecPerFrameIdx]; - g.FramerateSecPerFrame[g.FramerateSecPerFrameIdx] = g.IO.DeltaTime; - g.FramerateSecPerFrameIdx = (g.FramerateSecPerFrameIdx + 1) % IM_ARRAYSIZE(g.FramerateSecPerFrame); - g.IO.Framerate = 1.0f / (g.FramerateSecPerFrameAccum / (float)IM_ARRAYSIZE(g.FramerateSecPerFrame)); - - // Clear reference to active widget if the widget isn't alive anymore - g.HoveredId = 0; - if (!g.ActiveIdIsAlive && g.ActiveIdPreviousFrame == g.ActiveId && g.ActiveId != 0) - SetActiveId(0); - g.ActiveIdPreviousFrame = g.ActiveId; - g.ActiveIdIsAlive = false; - g.ActiveIdIsJustActivated = false; - if (!g.ActiveId) - g.MovedWindow = NULL; - - // Delay saving settings so we don't spam disk too much - if (g.SettingsDirtyTimer > 0.0f) - { - g.SettingsDirtyTimer -= g.IO.DeltaTime; - if (g.SettingsDirtyTimer <= 0.0f) - SaveSettings(); - } - - // Find the window we are hovering. Child windows can extend beyond the limit of their parent so we need to derive HoveredRootWindow from HoveredWindow - g.HoveredWindow = FindHoveredWindow(g.IO.MousePos, false); - if (g.HoveredWindow && (g.HoveredWindow->Flags & ImGuiWindowFlags_ChildWindow)) - g.HoveredRootWindow = g.HoveredWindow->RootWindow; - else - g.HoveredRootWindow = FindHoveredWindow(g.IO.MousePos, true); - - // Are we using inputs? Tell user so they can capture/discard the inputs away from the rest of their application. - // When clicking outside of a window we assume the click is owned by the application and won't request capture. - int mouse_earliest_button_down = -1; - for (int i = 0; i < IM_ARRAYSIZE(g.IO.MouseDown); i++) - { - if (g.IO.MouseClicked[i]) - g.IO.MouseDownOwned[i] = (g.HoveredWindow != NULL); - if (g.IO.MouseDown[i]) - if (mouse_earliest_button_down == -1 || g.IO.MouseClickedTime[mouse_earliest_button_down] > g.IO.MouseClickedTime[i]) - mouse_earliest_button_down = i; - } - bool mouse_owned_by_application = mouse_earliest_button_down != -1 && !g.IO.MouseDownOwned[mouse_earliest_button_down]; - g.IO.WantCaptureMouse = (!mouse_owned_by_application && g.HoveredWindow != NULL) || (g.ActiveId != 0); - g.IO.WantCaptureKeyboard = (g.ActiveId != 0); - g.MouseCursor = ImGuiMouseCursor_Arrow; - - // If mouse was first clicked outside of ImGui bounds we also cancel out hovering. - if (mouse_owned_by_application) - g.HoveredWindow = g.HoveredRootWindow = NULL; - - // Scale & Scrolling - if (g.HoveredWindow && g.IO.MouseWheel != 0.0f) - { - ImGuiWindow* window = g.HoveredWindow; - if (g.IO.KeyCtrl) - { - if (g.IO.FontAllowUserScaling) - { - // Zoom / Scale window - float new_font_scale = ImClamp(window->FontWindowScale + g.IO.MouseWheel * 0.10f, 0.50f, 2.50f); - float scale = new_font_scale / window->FontWindowScale; - window->FontWindowScale = new_font_scale; - - const ImVec2 offset = window->Size * (1.0f - scale) * (g.IO.MousePos - window->Pos) / window->Size; - window->Pos += offset; - window->PosFloat += offset; - window->Size *= scale; - window->SizeFull *= scale; - } - } - else - { - // Scroll - if (!(window->Flags & ImGuiWindowFlags_NoScrollWithMouse)) - { - const int scroll_lines = (window->Flags & ImGuiWindowFlags_ComboBox) ? 3 : 5; - window->NextScrollY -= g.IO.MouseWheel * window->CalcFontSize() * scroll_lines; - } - } - } - - // Pressing TAB activate widget focus - // NB: Don't discard FocusedWindow if it isn't active, so that a window that go on/off programatically won't lose its keyboard focus. - if (g.ActiveId == 0 && g.FocusedWindow != NULL && g.FocusedWindow->Visible && IsKeyPressedMap(ImGuiKey_Tab, false)) - { - g.FocusedWindow->FocusIdxTabRequestNext = 0; - } - - // Mark all windows as not visible - for (size_t i = 0; i != g.Windows.size(); i++) - { - ImGuiWindow* window = g.Windows[i]; - window->WasVisible = window->Visible; - window->Visible = false; - window->Accessed = false; - } - - // No window should be open at the beginning of the frame. - // But in order to allow the user to call NewFrame() multiple times without calling Render(), we are doing an explicit clear. - g.CurrentWindowStack.resize(0); - - // Create implicit window - we will only render it if the user has added something to it. - ImGui::SetNextWindowSize(ImVec2(400,400), ImGuiSetCond_FirstUseEver); - ImGui::Begin("Debug"); -} - -// NB: behavior of ImGui after Shutdown() is not tested/guaranteed at the moment. This function is merely here to free heap allocations. -void ImGui::Shutdown() -{ - ImGuiState& g = *GImGui; - if (!g.Initialized) - return; - - SaveSettings(); - - for (size_t i = 0; i < g.Windows.size(); i++) - { - g.Windows[i]->~ImGuiWindow(); - ImGui::MemFree(g.Windows[i]); - } - g.Windows.clear(); - g.WindowsSortBuffer.clear(); - g.CurrentWindowStack.clear(); - g.FocusedWindow = NULL; - g.HoveredWindow = NULL; - g.HoveredRootWindow = NULL; - for (size_t i = 0; i < g.Settings.size(); i++) - { - g.Settings[i]->~ImGuiIniData(); - ImGui::MemFree(g.Settings[i]); - } - g.Settings.clear(); - g.ColorModifiers.clear(); - g.StyleModifiers.clear(); - g.FontStack.clear(); - for (size_t i = 0; i < IM_ARRAYSIZE(g.RenderDrawLists); i++) - g.RenderDrawLists[i].clear(); - g.MouseCursorDrawList.ClearFreeMemory(); - g.ColorEditModeStorage.Clear(); - if (g.PrivateClipboard) - { - ImGui::MemFree(g.PrivateClipboard); - g.PrivateClipboard = NULL; - } - - if (g.LogFile && g.LogFile != stdout) - { - fclose(g.LogFile); - g.LogFile = NULL; - } - if (g.LogClipboard) - { - g.LogClipboard->~ImGuiTextBuffer(); - ImGui::MemFree(g.LogClipboard); - } - - g.IO.Fonts->Clear(); - - g.Initialized = false; -} - -// FIXME: Add a more explicit sort order in the window structure. -static int ChildWindowComparer(const void* lhs, const void* rhs) -{ - const ImGuiWindow* a = *(const ImGuiWindow**)lhs; - const ImGuiWindow* b = *(const ImGuiWindow**)rhs; - if (int d = (a->Flags & ImGuiWindowFlags_Popup) - (b->Flags & ImGuiWindowFlags_Popup)) - return d; - if (int d = (a->Flags & ImGuiWindowFlags_Tooltip) - (b->Flags & ImGuiWindowFlags_Tooltip)) - return d; - if (int d = (a->Flags & ImGuiWindowFlags_ComboBox) - (b->Flags & ImGuiWindowFlags_ComboBox)) - return d; - return 0; -} - -static void AddWindowToSortedBuffer(ImVector& out_sorted_windows, ImGuiWindow* window) -{ - out_sorted_windows.push_back(window); - if (window->Visible) - { - const size_t count = window->DC.ChildWindows.size(); - if (count > 1) - qsort(window->DC.ChildWindows.begin(), count, sizeof(ImGuiWindow*), ChildWindowComparer); - for (size_t i = 0; i < count; i++) - { - ImGuiWindow* child = window->DC.ChildWindows[i]; - if (child->Visible) - AddWindowToSortedBuffer(out_sorted_windows, child); - } - } -} - -static void PushClipRect(const ImVec4& clip_rect, bool clipped = true) -{ - ImGuiWindow* window = GetCurrentWindow(); - - ImVec4 cr = clip_rect; - if (clipped && !window->ClipRectStack.empty()) - { - // Clip with existing clip rect - const ImVec4 cur_cr = window->ClipRectStack.back(); - cr = ImVec4(ImMax(cr.x, cur_cr.x), ImMax(cr.y, cur_cr.y), ImMin(cr.z, cur_cr.z), ImMin(cr.w, cur_cr.w)); - } - cr.z = ImMax(cr.x, cr.z); - cr.w = ImMax(cr.y, cr.w); - - IM_ASSERT(cr.x <= cr.z && cr.y <= cr.w); - window->ClipRectStack.push_back(cr); - window->DrawList->PushClipRect(cr); -} - -static void PopClipRect() -{ - ImGuiWindow* window = GetCurrentWindow(); - window->ClipRectStack.pop_back(); - window->DrawList->PopClipRect(); -} - -void ImGui::Render() -{ - ImGuiState& g = *GImGui; - IM_ASSERT(g.Initialized); // Forgot to call ImGui::NewFrame() - - const bool first_render_of_the_frame = (g.FrameCountRendered != g.FrameCount); - g.FrameCountRendered = g.FrameCount; - - if (first_render_of_the_frame) - { - // Hide implicit window if it hasn't been used - IM_ASSERT(g.CurrentWindowStack.size() == 1); // Mismatched Begin/End - if (g.CurrentWindow && !g.CurrentWindow->Accessed) - g.CurrentWindow->Visible = false; - ImGui::End(); - - if (g.ActiveId == 0 && g.HoveredId == 0 && g.IO.MouseClicked[0]) - { - if (g.HoveredRootWindow != NULL) - { - // Select window for move/focus when we're done with all our widgets (we use the root window ID here) - IM_ASSERT(g.MovedWindow == NULL); - g.MovedWindow = g.HoveredWindow; - SetActiveId(g.HoveredRootWindow->MoveID); - } - else if (g.FocusedWindow != NULL) - { - // Clicking on void disable focus - FocusWindow(NULL); - } - } - - // Sort the window list so that all child windows are after their parent - // We cannot do that on FocusWindow() because childs may not exist yet - g.WindowsSortBuffer.resize(0); - g.WindowsSortBuffer.reserve(g.Windows.size()); - for (size_t i = 0; i != g.Windows.size(); i++) - { - ImGuiWindow* window = g.Windows[i]; - if (window->Flags & ImGuiWindowFlags_ChildWindow) // if a child is visible its parent will add it - if (window->Visible) - continue; - AddWindowToSortedBuffer(g.WindowsSortBuffer, window); - } - IM_ASSERT(g.Windows.size() == g.WindowsSortBuffer.size()); // we done something wrong - g.Windows.swap(g.WindowsSortBuffer); - - // Clear data for next frame - g.IO.MouseWheel = 0.0f; - memset(g.IO.InputCharacters, 0, sizeof(g.IO.InputCharacters)); - } - - // Skip render altogether if alpha is 0.0 - // Note that vertex buffers have been created, so it is best practice that you don't call Begin/End in the first place. - if (g.Style.Alpha > 0.0f) - { - // Render tooltip - if (g.Tooltip[0]) - { - // Use a dummy window to render the tooltip - ImGui::BeginTooltip(); - ImGui::TextUnformatted(g.Tooltip); - ImGui::EndTooltip(); - } - - // Gather windows to render - g.IO.MetricsRenderVertices = 0; - for (size_t i = 0; i < IM_ARRAYSIZE(g.RenderDrawLists); i++) - g.RenderDrawLists[i].resize(0); - for (size_t i = 0; i != g.Windows.size(); i++) - { - ImGuiWindow* window = g.Windows[i]; - if (window->Visible && (window->Flags & (ImGuiWindowFlags_ChildWindow)) == 0) - { - // FIXME: Generalize this with a proper layering system so we can stack. - if (window->Flags & ImGuiWindowFlags_Popup) - AddWindowToRenderList(g.RenderDrawLists[1], window); - else if (window->Flags & ImGuiWindowFlags_Tooltip) - AddWindowToRenderList(g.RenderDrawLists[2], window); - else - AddWindowToRenderList(g.RenderDrawLists[0], window); - } - } - - // Flatten layers - size_t n = g.RenderDrawLists[0].size(); - size_t flattened_size = n; - for (size_t i = 1; i < IM_ARRAYSIZE(g.RenderDrawLists); i++) - flattened_size += g.RenderDrawLists[i].size(); - g.RenderDrawLists[0].resize(flattened_size); - for (size_t i = 1; i < IM_ARRAYSIZE(g.RenderDrawLists); i++) - { - ImVector& layer = g.RenderDrawLists[i]; - if (!layer.empty()) - { - memcpy(&g.RenderDrawLists[0][n], &layer[0], layer.size() * sizeof(ImDrawList*)); - n += layer.size(); - } - } - - if (g.IO.MouseDrawCursor) - { - const ImGuiMouseCursorData& cursor_data = g.MouseCursorData[g.MouseCursor]; - const ImVec2 pos = g.IO.MousePos - cursor_data.Offset; - const ImVec2 size = cursor_data.Size; - const ImTextureID tex_id = g.IO.Fonts->TexID; - g.MouseCursorDrawList.Clear(); - g.MouseCursorDrawList.PushTextureID(tex_id); - g.MouseCursorDrawList.AddImage(tex_id, pos+ImVec2(1,0), pos+ImVec2(1,0) + size, cursor_data.TexUvMin[1], cursor_data.TexUvMax[1], 0x30000000); // Shadow - g.MouseCursorDrawList.AddImage(tex_id, pos+ImVec2(2,0), pos+ImVec2(2,0) + size, cursor_data.TexUvMin[1], cursor_data.TexUvMax[1], 0x30000000); // Shadow - g.MouseCursorDrawList.AddImage(tex_id, pos, pos + size, cursor_data.TexUvMin[1], cursor_data.TexUvMax[1], 0xFF000000); // Black border - g.MouseCursorDrawList.AddImage(tex_id, pos, pos + size, cursor_data.TexUvMin[0], cursor_data.TexUvMax[0], 0xFFFFFFFF); // White fill - g.MouseCursorDrawList.PopTextureID(); - AddDrawListToRenderList(g.RenderDrawLists[0], &g.MouseCursorDrawList); - } - - // Render - if (!g.RenderDrawLists[0].empty()) - g.IO.RenderDrawListsFn(&g.RenderDrawLists[0][0], (int)g.RenderDrawLists[0].size()); - } -} - -// Find the optional ## from which we stop displaying text. -static const char* FindTextDisplayEnd(const char* text, const char* text_end = NULL) -{ - const char* text_display_end = text; - if (!text_end) - text_end = (const char*)-1; - - ImGuiState& g = *GImGui; - if (g.DisableHideTextAfterDoubleHash > 0) - { - while (text_display_end < text_end && *text_display_end != '\0') - text_display_end++; - } - else - { - while (text_display_end < text_end && *text_display_end != '\0' && (text_display_end[0] != '#' || text_display_end[1] != '#')) - text_display_end++; - } - return text_display_end; -} - -// Pass text data straight to log (without being displayed) -void ImGui::LogText(const char* fmt, ...) -{ - ImGuiState& g = *GImGui; - if (!g.LogEnabled) - return; - - va_list args; - va_start(args, fmt); - if (g.LogFile) - { - vfprintf(g.LogFile, fmt, args); - } - else - { - g.LogClipboard->appendv(fmt, args); - } - va_end(args); -} - -// Internal version that takes a position to decide on newline placement and pad items according to their depth. -// We split text into individual lines to add current tree level padding -static void LogText(const ImVec2& ref_pos, const char* text, const char* text_end) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - - if (!text_end) - text_end = FindTextDisplayEnd(text, text_end); - - const bool log_new_line = ref_pos.y > window->DC.LogLinePosY+1; - window->DC.LogLinePosY = ref_pos.y; - - const char* text_remaining = text; - if (g.LogStartDepth > window->DC.TreeDepth) // Re-adjust padding if we have popped out of our starting depth - g.LogStartDepth = window->DC.TreeDepth; - const int tree_depth = (window->DC.TreeDepth - g.LogStartDepth); - for (;;) - { - // Split the string. Each new line (after a '\n') is followed by spacing corresponding to the current depth of our log entry. - const char* line_end = text_remaining; - while (line_end < text_end) - if (*line_end == '\n') - break; - else - line_end++; - if (line_end >= text_end) - line_end = NULL; - - const bool is_first_line = (text == text_remaining); - bool is_last_line = false; - if (line_end == NULL) - { - is_last_line = true; - line_end = text_end; - } - if (line_end != NULL && !(is_last_line && (line_end - text_remaining)==0)) - { - const int char_count = (int)(line_end - text_remaining); - if (log_new_line || !is_first_line) - ImGui::LogText(STR_NEWLINE "%*s%.*s", tree_depth*4, "", char_count, text_remaining); - else - ImGui::LogText(" %.*s", char_count, text_remaining); - } - - if (is_last_line) - break; - text_remaining = line_end + 1; - } -} - -static float CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x) -{ - if (wrap_pos_x < 0.0f) - return 0.0f; - - ImGuiWindow* window = GetCurrentWindow(); - if (wrap_pos_x == 0.0f) - wrap_pos_x = ImGui::GetContentRegionMax().x; - if (wrap_pos_x > 0.0f) - wrap_pos_x += window->Pos.x; // wrap_pos_x is provided is window local space - - const float wrap_width = wrap_pos_x > 0.0f ? ImMax(wrap_pos_x - pos.x, 0.00001f) : 0.0f; - return wrap_width; -} - -// Internal ImGui functions to render text -// RenderText***() functions calls ImDrawList::AddText() calls ImBitmapFont::RenderText() -static void RenderText(ImVec2 pos, const char* text, const char* text_end, bool hide_text_after_hash) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - - // Hide anything after a '##' string - const char* text_display_end; - if (hide_text_after_hash) - { - text_display_end = FindTextDisplayEnd(text, text_end); - } - else - { - if (!text_end) - text_end = text + strlen(text); // FIXME-OPT - text_display_end = text_end; - } - - const int text_len = (int)(text_display_end - text); - if (text_len > 0) - { - // Render - window->DrawList->AddText(g.Font, g.FontSize, pos, window->Color(ImGuiCol_Text), text, text_display_end); - - // Log as text - if (g.LogEnabled) - LogText(pos, text, text_display_end); - } -} - -static void RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - - if (!text_end) - text_end = text + strlen(text); // FIXME-OPT - - const int text_len = (int)(text_end - text); - if (text_len > 0) - { - // Render - window->DrawList->AddText(g.Font, g.FontSize, pos, window->Color(ImGuiCol_Text), text, text_end, wrap_width); - - // Log as text - if (g.LogEnabled) - LogText(pos, text, text_end); - } -} - -static void RenderTextClipped(ImVec2 pos, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& clip_max) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - - // Hide anything after a '##' string - const char* text_display_end = FindTextDisplayEnd(text, text_end); - const int text_len = (int)(text_display_end - text); - if (text_len > 0) - { - const ImVec2 text_size = text_size_if_known ? *text_size_if_known : ImGui::CalcTextSize(text, text_display_end, false, 0.0f); - - // Perform CPU side clipping for single clipped element to avoid using scissor state - const bool need_clipping = (pos.x + text_size.x >= clip_max.x) || (pos.y + text_size.y >= clip_max.y); - - // Render - window->DrawList->AddText(g.Font, g.FontSize, pos, window->Color(ImGuiCol_Text), text, text_display_end, 0.0f, need_clipping ? &clip_max : NULL); - - // Log as text - if (g.LogEnabled) - LogText(pos, text, text_display_end); - } -} - -// Render a rectangle shaped with optional rounding and borders -static void RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border, float rounding) -{ - ImGuiWindow* window = GetCurrentWindow(); - - window->DrawList->AddRectFilled(p_min, p_max, fill_col, rounding); - if (border && (window->Flags & ImGuiWindowFlags_ShowBorders)) - { - // FIXME: This is the best I've found that works on multiple renderer/back ends. Bit dodgy. - window->DrawList->AddRect(p_min+ImVec2(1.5f,1.5f), p_max+ImVec2(1,1), window->Color(ImGuiCol_BorderShadow), rounding); - window->DrawList->AddRect(p_min+ImVec2(0.5f,0.5f), p_max+ImVec2(0,0), window->Color(ImGuiCol_Border), rounding); - } -} - -// Render a triangle to denote expanded/collapsed state -static void RenderCollapseTriangle(ImVec2 p_min, bool opened, float scale, bool shadow) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - - const float h = g.FontSize * 1.00f; - const float r = h * 0.40f * scale; - ImVec2 center = p_min + ImVec2(h*0.50f, h*0.50f*scale); - - ImVec2 a, b, c; - if (opened) - { - center.y -= r*0.25f; - a = center + ImVec2(0,1)*r; - b = center + ImVec2(-0.866f,-0.5f)*r; - c = center + ImVec2(0.866f,-0.5f)*r; - } - else - { - a = center + ImVec2(1,0)*r; - b = center + ImVec2(-0.500f,0.866f)*r; - c = center + ImVec2(-0.500f,-0.866f)*r; - } - - if (shadow && (window->Flags & ImGuiWindowFlags_ShowBorders) != 0) - window->DrawList->AddTriangleFilled(a+ImVec2(2,2), b+ImVec2(2,2), c+ImVec2(2,2), window->Color(ImGuiCol_BorderShadow)); - window->DrawList->AddTriangleFilled(a, b, c, window->Color(ImGuiCol_Text)); -} - -// Calculate text size. Text can be multi-line. Optionally ignore text after a ## marker. -// CalcTextSize("") should return ImVec2(0.0f, GImGui->FontSize) -ImVec2 ImGui::CalcTextSize(const char* text, const char* text_end, bool hide_text_after_double_hash, float wrap_width) -{ - ImGuiState& g = *GImGui; - - const char* text_display_end; - if (hide_text_after_double_hash) - text_display_end = FindTextDisplayEnd(text, text_end); // Hide anything after a '##' string - else - text_display_end = text_end; - - ImFont* font = g.Font; - const float font_size = g.FontSize; - ImVec2 text_size = font->CalcTextSizeA(font_size, FLT_MAX, wrap_width, text, text_display_end, NULL); - - // Cancel out character spacing for the last character of a line (it is baked into glyph->XAdvance field) - const float font_scale = font_size / font->FontSize; - const float character_spacing_x = 1.0f * font_scale; - if (text_size.x > 0.0f) - text_size.x -= character_spacing_x; - - return text_size; -} - -// Helper to calculate coarse clipping of large list of evenly sized items. -// If you are displaying thousands of items and you have a random access to the list, you can perform clipping yourself to save on CPU. -// { -// float item_height = ImGui::GetTextLineHeightWithSpacing(); -// int display_start, display_end; -// ImGui::CalcListClipping(count, item_height, &display_start, &display_end); // calculate how many to clip/display -// ImGui::SetCursorPosY(ImGui::GetCursorPosY() + (display_start) * item_height); // advance cursor -// for (int i = display_start; i < display_end; i++) // display only visible items -// // TODO: display visible item -// ImGui::SetCursorPosY(ImGui::GetCursorPosY() + (count - display_end) * item_height); // advance cursor -// } -void ImGui::CalcListClipping(int items_count, float items_height, int* out_items_display_start, int* out_items_display_end) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - - if (g.LogEnabled) - { - // If logging is active, do not perform any clipping - *out_items_display_start = 0; - *out_items_display_end = items_count; - return; - } - - const ImVec2 pos = window->DC.CursorPos; - const ImVec4 clip_rect = window->ClipRectStack.back(); - const float clip_y1 = clip_rect.y; - const float clip_y2 = clip_rect.w; - - int start = (int)((clip_y1 - pos.y) / items_height); - int end = (int)((clip_y2 - pos.y) / items_height); - start = ImClamp(start, 0, items_count); - end = ImClamp(end + 1, start, items_count); - - *out_items_display_start = start; - *out_items_display_end = end; -} - -// Find window given position, search front-to-back -static ImGuiWindow* FindHoveredWindow(ImVec2 pos, bool excluding_childs) -{ - ImGuiState& g = *GImGui; - for (int i = (int)g.Windows.size()-1; i >= 0; i--) - { - ImGuiWindow* window = g.Windows[(size_t)i]; - if (!window->Visible) - continue; - if (excluding_childs && (window->Flags & ImGuiWindowFlags_ChildWindow) != 0) - continue; - - // Using the clipped AABB so a child window will typically be clipped by its parent. - ImRect bb(window->ClippedRect.Min - g.Style.TouchExtraPadding, window->ClippedRect.Max + g.Style.TouchExtraPadding); - if (bb.Contains(pos)) - return window; - } - return NULL; -} - -// Test if mouse cursor is hovering given rectangle -// NB- Rectangle is clipped by our current clip setting -// NB- Expand the rectangle to be generous on imprecise inputs systems (g.Style.TouchExtraPadding) -static bool IsMouseHoveringRect(const ImRect& rect) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - - // Clip - ImRect rect_clipped = rect; - if (!window->ClipRectStack.empty()) - { - const ImVec4 clip_rect = window->ClipRectStack.back(); - rect_clipped.Clip(ImRect(ImVec2(clip_rect.x, clip_rect.y), ImVec2(clip_rect.z, clip_rect.w))); - } - - // Expand for touch input - const ImRect rect_for_touch(rect_clipped.Min - g.Style.TouchExtraPadding, rect_clipped.Max + g.Style.TouchExtraPadding); - return rect_for_touch.Contains(g.IO.MousePos); -} - -bool ImGui::IsMouseHoveringRect(const ImVec2& rect_min, const ImVec2& rect_max) -{ - return IsMouseHoveringRect(ImRect(rect_min, rect_max)); -} - -bool ImGui::IsMouseHoveringWindow() -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - return g.HoveredWindow == window; -} - -bool ImGui::IsMouseHoveringAnyWindow() -{ - ImGuiState& g = *GImGui; - return g.HoveredWindow != NULL; -} - -bool ImGui::IsPosHoveringAnyWindow(const ImVec2& pos) -{ - return FindHoveredWindow(pos, false) != NULL; -} - -static bool IsKeyPressedMap(ImGuiKey key, bool repeat) -{ - ImGuiState& g = *GImGui; - const int key_index = g.IO.KeyMap[key]; - return ImGui::IsKeyPressed(key_index, repeat); -} - -bool ImGui::IsKeyPressed(int key_index, bool repeat) -{ - ImGuiState& g = *GImGui; - IM_ASSERT(key_index >= 0 && key_index < IM_ARRAYSIZE(g.IO.KeysDown)); - const float t = g.IO.KeysDownTime[key_index]; - if (t == 0.0f) - return true; - - // FIXME: Repeat rate should be provided elsewhere? - const float KEY_REPEAT_DELAY = 0.250f; - const float KEY_REPEAT_RATE = 0.020f; - if (repeat && t > KEY_REPEAT_DELAY) - if ((fmodf(t - KEY_REPEAT_DELAY, KEY_REPEAT_RATE) > KEY_REPEAT_RATE*0.5f) != (fmodf(t - KEY_REPEAT_DELAY - g.IO.DeltaTime, KEY_REPEAT_RATE) > KEY_REPEAT_RATE*0.5f)) - return true; - - return false; -} - -bool ImGui::IsMouseClicked(int button, bool repeat) -{ - ImGuiState& g = *GImGui; - IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); - const float t = g.IO.MouseDownTime[button]; - if (t == 0.0f) - return true; - - // FIXME: Repeat rate should be provided elsewhere? - const float MOUSE_REPEAT_DELAY = 0.250f; - const float MOUSE_REPEAT_RATE = 0.020f; - if (repeat && t > MOUSE_REPEAT_DELAY) - if ((fmodf(t - MOUSE_REPEAT_DELAY, MOUSE_REPEAT_RATE) > MOUSE_REPEAT_RATE*0.5f) != (fmodf(t - MOUSE_REPEAT_DELAY - g.IO.DeltaTime, MOUSE_REPEAT_RATE) > MOUSE_REPEAT_RATE*0.5f)) - return true; - - return false; -} - -bool ImGui::IsMouseDoubleClicked(int button) -{ - ImGuiState& g = *GImGui; - IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); - return g.IO.MouseDoubleClicked[button]; -} - -bool ImGui::IsMouseDragging(int button, float lock_threshold) -{ - ImGuiState& g = *GImGui; - IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); - if (lock_threshold < 0.0f) - lock_threshold = g.IO.MouseDragThreshold; - return g.IO.MouseDragMaxDistanceSqr[button] >= lock_threshold * lock_threshold; -} - -ImVec2 ImGui::GetMousePos() -{ - return GImGui->IO.MousePos; -} - -ImVec2 ImGui::GetMouseDragDelta(int button, float lock_threshold) -{ - ImGuiState& g = *GImGui; - IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); - if (lock_threshold < 0.0f) - lock_threshold = g.IO.MouseDragThreshold; - if (g.IO.MouseDown[button]) - if (g.IO.MouseDragMaxDistanceSqr[button] >= lock_threshold * lock_threshold) - return g.IO.MousePos - g.IO.MouseClickedPos[button]; // Assume we can only get active with left-mouse button (at the moment). - return ImVec2(0.0f, 0.0f); -} - -void ImGui::ResetMouseDragDelta(int button) -{ - ImGuiState& g = *GImGui; - IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); - // NB: We don't need to reset g.IO.MouseDragMaxDistanceSqr - g.IO.MouseClickedPos[button] = g.IO.MousePos; -} - -ImGuiMouseCursor ImGui::GetMouseCursor() -{ - return GImGui->MouseCursor; -} - -void ImGui::SetMouseCursor(ImGuiMouseCursor cursor_type) -{ - GImGui->MouseCursor = cursor_type; -} - -bool ImGui::IsItemHovered() -{ - ImGuiWindow* window = GetCurrentWindow(); - return window->DC.LastItemHoveredAndUsable; -} - -bool ImGui::IsItemHoveredRect() -{ - ImGuiWindow* window = GetCurrentWindow(); - return window->DC.LastItemHoveredRect; -} - -bool ImGui::IsItemActive() -{ - ImGuiState& g = *GImGui; - if (g.ActiveId) - { - ImGuiWindow* window = GetCurrentWindow(); - return g.ActiveId == window->DC.LastItemID; - } - return false; -} - -bool ImGui::IsAnyItemActive() -{ - ImGuiState& g = *GImGui; - return g.ActiveId != 0; -} - -bool ImGui::IsItemVisible() -{ - ImGuiWindow* window = GetCurrentWindow(); - ImRect r(window->ClipRectStack.back()); - return r.Overlaps(window->DC.LastItemRect); -} - -ImVec2 ImGui::GetItemRectMin() -{ - ImGuiWindow* window = GetCurrentWindow(); - return window->DC.LastItemRect.Min; -} - -ImVec2 ImGui::GetItemRectMax() -{ - ImGuiWindow* window = GetCurrentWindow(); - return window->DC.LastItemRect.Max; -} - -ImVec2 ImGui::GetItemRectSize() -{ - ImGuiWindow* window = GetCurrentWindow(); - return window->DC.LastItemRect.GetSize(); -} - -ImVec2 ImGui::CalcItemRectClosestPoint(const ImVec2& pos, bool on_edge, float outward) -{ - ImGuiWindow* window = GetCurrentWindow(); - ImRect rect = window->DC.LastItemRect; - rect.Expand(outward); - return rect.GetClosestPoint(pos, on_edge); -} - -// Tooltip is stored and turned into a BeginTooltip()/EndTooltip() sequence at the end of the frame. Each call override previous value. -void ImGui::SetTooltipV(const char* fmt, va_list args) -{ - ImGuiState& g = *GImGui; - ImFormatStringV(g.Tooltip, IM_ARRAYSIZE(g.Tooltip), fmt, args); -} - -void ImGui::SetTooltip(const char* fmt, ...) -{ - va_list args; - va_start(args, fmt); - SetTooltipV(fmt, args); - va_end(args); -} - -float ImGui::GetTime() -{ - return GImGui->Time; -} - -int ImGui::GetFrameCount() -{ - return GImGui->FrameCount; -} - -void ImGui::BeginTooltip() -{ - ImGuiState& g = *GImGui; - ImGuiWindowFlags flags = ImGuiWindowFlags_Tooltip|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_AlwaysAutoResize; - ImGui::Begin("##Tooltip", NULL, ImVec2(0,0), g.Style.Colors[ImGuiCol_TooltipBg].w, flags); -} - -void ImGui::EndTooltip() -{ - IM_ASSERT(GetCurrentWindow()->Flags & ImGuiWindowFlags_Tooltip); - ImGui::End(); -} - -void ImGui::BeginPopup(bool* p_opened) -{ - IM_ASSERT(p_opened != NULL); // Must provide a bool at the moment - - ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); - ImGuiWindowFlags flags = ImGuiWindowFlags_Popup|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_AlwaysAutoResize; - ImGui::Begin("##Popup", p_opened, flags); -} - -void ImGui::EndPopup() -{ - IM_ASSERT(GetCurrentWindow()->Flags & ImGuiWindowFlags_Popup); - ImGui::End(); - ImGui::PopStyleVar(); -} - -bool ImGui::BeginChild(const char* str_id, const ImVec2& size_arg, bool border, ImGuiWindowFlags extra_flags) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - - ImGuiWindowFlags flags = ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_ChildWindow; - - const ImVec2 content_max = window->Pos + ImGui::GetContentRegionMax(); - const ImVec2 cursor_pos = window->Pos + ImGui::GetCursorPos(); - ImVec2 size = size_arg; - if (size.x <= 0.0f) - { - if (size.x == 0.0f) - flags |= ImGuiWindowFlags_ChildWindowAutoFitX; - size.x = ImMax(content_max.x - cursor_pos.x, g.Style.WindowMinSize.x) - fabsf(size.x); - } - if (size.y <= 0.0f) - { - if (size.y == 0.0f) - flags |= ImGuiWindowFlags_ChildWindowAutoFitY; - size.y = ImMax(content_max.y - cursor_pos.y, g.Style.WindowMinSize.y) - fabsf(size.y); - } - if (border) - flags |= ImGuiWindowFlags_ShowBorders; - flags |= extra_flags; - - char title[256]; - ImFormatString(title, IM_ARRAYSIZE(title), "%s.%s", window->Name, str_id); - - const float alpha = 1.0f; - bool ret = ImGui::Begin(title, NULL, size, alpha, flags); - - if (!(window->Flags & ImGuiWindowFlags_ShowBorders)) - g.CurrentWindow->Flags &= ~ImGuiWindowFlags_ShowBorders; - - return ret; -} - -bool ImGui::BeginChild(ImGuiID id, const ImVec2& size, bool border, ImGuiWindowFlags extra_flags) -{ - char str_id[32]; - ImFormatString(str_id, IM_ARRAYSIZE(str_id), "child_%x", id); - bool ret = ImGui::BeginChild(str_id, size, border, extra_flags); - return ret; -} - -void ImGui::EndChild() -{ - ImGuiWindow* window = GetCurrentWindow(); - - IM_ASSERT(window->Flags & ImGuiWindowFlags_ChildWindow); - if (window->Flags & ImGuiWindowFlags_ComboBox) - { - ImGui::End(); - } - else - { - // When using auto-filling child window, we don't provide full width/height to ItemSize so that it doesn't feed back into automatic size-fitting. - ImGuiState& g = *GImGui; - ImVec2 sz = ImGui::GetWindowSize(); - if (window->Flags & ImGuiWindowFlags_ChildWindowAutoFitX) - sz.x = ImMax(g.Style.WindowMinSize.x, sz.x - g.Style.AutoFitPadding.x); - if (window->Flags & ImGuiWindowFlags_ChildWindowAutoFitY) - sz.y = ImMax(g.Style.WindowMinSize.y, sz.y - g.Style.AutoFitPadding.y); - - ImGui::End(); - - window = GetCurrentWindow(); - ImRect bb(window->DC.CursorPos, window->DC.CursorPos + sz); - ItemSize(sz); - ItemAdd(bb, NULL); - } -} - -// Helper to create a child window / scrolling region that looks like a normal widget frame. -void ImGui::BeginChildFrame(ImGuiID id, const ImVec2& size) -{ - ImGuiState& g = *GImGui; - const ImGuiStyle& style = g.Style; - ImGui::PushStyleColor(ImGuiCol_ChildWindowBg, style.Colors[ImGuiCol_FrameBg]); - ImGui::PushStyleVar(ImGuiStyleVar_ChildWindowRounding, style.FrameRounding); - ImGui::BeginChild(id, size); -} - -void ImGui::EndChildFrame() -{ - ImGui::EndChild(); - ImGui::PopStyleVar(); - ImGui::PopStyleColor(); -} - -static ImGuiWindow* FindWindowByName(const char* name) -{ - // FIXME-OPT: Store sorted hashes -> pointers. - ImGuiState& g = *GImGui; - ImGuiID id = ImHash(name, 0); - for (size_t i = 0; i < g.Windows.size(); i++) - if (g.Windows[i]->ID == id) - return g.Windows[i]; - return NULL; -} - -static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFlags flags) -{ - ImGuiState& g = *GImGui; - - // Create window the first time - ImGuiWindow* window = (ImGuiWindow*)ImGui::MemAlloc(sizeof(ImGuiWindow)); - new(window) ImGuiWindow(name); - window->Flags = flags; - - if (flags & ImGuiWindowFlags_NoSavedSettings) - { - // User can disable loading and saving of settings. Tooltip and child windows also don't store settings. - window->Size = window->SizeFull = size; - } - else - { - // Retrieve settings from .ini file - // Use SetWindowPos() or SetNextWindowPos() with the appropriate condition flag to change the initial position of a window. - window->PosFloat = ImVec2(60, 60); - window->Pos = ImVec2((float)(int)window->PosFloat.x, (float)(int)window->PosFloat.y); - - ImGuiIniData* settings = FindWindowSettings(name); - if (!settings) - { - settings = AddWindowSettings(name); - } - else - { - window->SetWindowPosAllowFlags &= ~ImGuiSetCond_FirstUseEver; - window->SetWindowSizeAllowFlags &= ~ImGuiSetCond_FirstUseEver; - window->SetWindowCollapsedAllowFlags &= ~ImGuiSetCond_FirstUseEver; - } - - if (settings->Pos.x != FLT_MAX) - { - window->PosFloat = settings->Pos; - window->Pos = ImVec2((float)(int)window->PosFloat.x, (float)(int)window->PosFloat.y); - window->Collapsed = settings->Collapsed; - } - - if (ImLengthSqr(settings->Size) > 0.00001f && !(flags & ImGuiWindowFlags_NoResize)) - size = settings->Size; - window->Size = window->SizeFull = size; - } - - if ((flags & ImGuiWindowFlags_AlwaysAutoResize) != 0) - { - window->AutoFitFrames = 2; - window->AutoFitOnlyGrows = false; - } - else if (ImLengthSqr(window->Size) < 0.00001f) - { - window->AutoFitFrames = 2; - window->AutoFitOnlyGrows = true; - } - - g.Windows.push_back(window); - return window; -} - -// Push a new ImGui window to add widgets to. -// - 'size' for a regular window denote the initial size for first-time creation (no saved data) and isn't that useful. Use SetNextWindowSize() prior to calling Begin() for more flexible window manipulation. -// - A default window called "Debug" is automatically stacked at the beginning of every frame so you can use widgets without explicitly calling a Begin/End pair. -// - Begin/End can be called multiple times during the frame with the same window name to append content. -// - The window name is used as a unique identifier to preserve window information across frames (and save rudimentary information to the .ini file). -// You can use the "##" or "###" markers to use the same label with different id, or same id with different label. See documentation at the top of this file. -// - Return false when window is collapsed, so you can early out in your code. You always need to call ImGui::End() even if false is returned. -// - Passing 'bool* p_opened' displays a Close button on the upper-right corner of the window, the pointed value will be set to false when the button is pressed. -// - Passing non-zero 'size' is roughly equivalent to calling SetNextWindowSize(size, ImGuiSetCond_FirstUseEver) prior to calling Begin(). -bool ImGui::Begin(const char* name, bool* p_opened, ImGuiWindowFlags flags) -{ - return ImGui::Begin(name, p_opened, ImVec2(0.f, 0.f), -1.0f, flags); -} - -bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_use, float bg_alpha, ImGuiWindowFlags flags) -{ - ImGuiState& g = *GImGui; - const ImGuiStyle& style = g.Style; - IM_ASSERT(g.Initialized); // Forgot to call ImGui::NewFrame() - IM_ASSERT(name != NULL); // Must pass a name - - // Find or create - bool window_is_new = false; - ImGuiWindow* window = FindWindowByName(name); - if (!window) - { - window = CreateNewWindow(name, size_on_first_use, flags); - window_is_new = true; - } - window->Flags = (ImGuiWindowFlags)flags; - - // Add to stack - g.CurrentWindowStack.push_back(window); - SetCurrentWindow(window); - - // Process SetNextWindow***() calls - bool window_pos_set_by_api = false; - if (g.SetNextWindowPosCond) - { - const ImVec2 backup_cursor_pos = window->DC.CursorPos; // FIXME: not sure of the exact reason of this anymore :( need to look into that. - ImGui::SetWindowPos(g.SetNextWindowPosVal, g.SetNextWindowPosCond); - window->DC.CursorPos = backup_cursor_pos; - window_pos_set_by_api = true; - g.SetNextWindowPosCond = 0; - } - if (g.SetNextWindowSizeCond) - { - ImGui::SetWindowSize(g.SetNextWindowSizeVal, g.SetNextWindowSizeCond); - g.SetNextWindowSizeCond = 0; - } - if (g.SetNextWindowCollapsedCond) - { - ImGui::SetWindowCollapsed(g.SetNextWindowCollapsedVal, g.SetNextWindowCollapsedCond); - g.SetNextWindowCollapsedCond = 0; - } - if (g.SetNextWindowFocus) - { - ImGui::SetWindowFocus(); - g.SetNextWindowFocus = false; - } - - // Find parent - ImGuiWindow* parent_window = (flags & ImGuiWindowFlags_ChildWindow) != 0 ? g.CurrentWindowStack[g.CurrentWindowStack.size()-2] : NULL; - - // Update known root window (if we are a child window, otherwise window == window->RootWindow) - size_t root_idx = g.CurrentWindowStack.size() - 1; - while (root_idx > 0) - { - if ((g.CurrentWindowStack[root_idx]->Flags & ImGuiWindowFlags_ChildWindow) == 0) - break; - root_idx--; - } - window->RootWindow = g.CurrentWindowStack[root_idx]; - - // Default alpha - if (bg_alpha < 0.0f) - bg_alpha = style.WindowFillAlphaDefault; - - // When reusing window again multiple times a frame, just append content (don't need to setup again) - const int current_frame = ImGui::GetFrameCount(); - const bool first_begin_of_the_frame = (window->LastFrameDrawn != current_frame); - if (first_begin_of_the_frame) - { - window->DrawList->Clear(); - window->Visible = true; - - // New windows appears in front - if (!(flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Tooltip)) - { - if (window->LastFrameDrawn < current_frame - 1) - { - FocusWindow(window); - - // Popup position themselves when they first appear - if (flags & ImGuiWindowFlags_Popup) - { - if (!window_pos_set_by_api) - window->PosFloat = g.IO.MousePos; - } - } - } - - window->LastFrameDrawn = current_frame; - window->ClipRectStack.resize(0); - - // Reset contents size for auto-fitting - window->SizeContents = window_is_new ? ImVec2(0.0f, 0.0f) : window->DC.CursorMaxPos - window->Pos; - window->SizeContents.y += window->ScrollY; - - if (flags & ImGuiWindowFlags_ChildWindow) - { - parent_window->DC.ChildWindows.push_back(window); - window->Pos = window->PosFloat = parent_window->DC.CursorPos; - window->SizeFull = size_on_first_use; - } - } - - // Setup texture - window->DrawList->PushTextureID(g.Font->ContainerAtlas->TexID); - - // Setup outer clipping rectangle - if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_ComboBox)) - PushClipRect(parent_window->ClipRectStack.back()); - else if (g.IO.DisplayVisibleMin.x != g.IO.DisplayVisibleMax.x && g.IO.DisplayVisibleMin.y != g.IO.DisplayVisibleMax.y) - PushClipRect(ImVec4(g.IO.DisplayVisibleMin.x, g.IO.DisplayVisibleMin.y, g.IO.DisplayVisibleMax.x, g.IO.DisplayVisibleMax.y)); - else - PushClipRect(ImVec4(0.0f, 0.0f, g.IO.DisplaySize.x, g.IO.DisplaySize.y)); - - // Setup and draw window - if (first_begin_of_the_frame) - { - // Reset ID stack - window->IDStack.resize(1); - - // Move window (at the beginning of the frame to avoid input lag or sheering). Only valid for root windows. - RegisterAliveId(window->MoveID); - if (g.ActiveId == window->MoveID) - { - if (g.IO.MouseDown[0]) - { - if (!(window->Flags & ImGuiWindowFlags_NoMove)) - { - window->PosFloat += g.IO.MouseDelta; - if (!(window->Flags & ImGuiWindowFlags_NoSavedSettings)) - MarkSettingsDirty(); - } - IM_ASSERT(g.MovedWindow != NULL); - FocusWindow(g.MovedWindow); - } - else - { - SetActiveId(0); - g.MovedWindow = NULL; // Not strictly necessary but doing it for sanity. - } - } - - // Tooltips always follows mouse - if (!window_pos_set_by_api && (window->Flags & ImGuiWindowFlags_Tooltip) != 0) - { - window->PosFloat = g.IO.MousePos + ImVec2(32,16) - style.FramePadding*2; - } - - // Clamp into view - if (!(window->Flags & ImGuiWindowFlags_ChildWindow) && !(window->Flags & ImGuiWindowFlags_Tooltip)) - { - if (window->AutoFitFrames <= 0 && g.IO.DisplaySize.x > 0.0f && g.IO.DisplaySize.y > 0.0f) // Ignore zero-sized display explicitly to avoid losing positions if a window manager reports zero-sized window when initializing or minimizing. - { - ImVec2 clip_min = style.DisplaySafeAreaPadding; - ImVec2 clip_max = g.IO.DisplaySize - style.DisplaySafeAreaPadding; - window->PosFloat = ImMax(window->PosFloat + window->Size, clip_min) - window->Size; - window->PosFloat = ImMin(window->PosFloat, clip_max); - } - window->SizeFull = ImMax(window->SizeFull, style.WindowMinSize); - } - window->Pos = ImVec2((float)(int)window->PosFloat.x, (float)(int)window->PosFloat.y); - - // Default item width. Make it proportional to window size if window manually resizes - if (window->Size.x > 0.0f && !(window->Flags & ImGuiWindowFlags_Tooltip) && !(window->Flags & ImGuiWindowFlags_AlwaysAutoResize)) - window->ItemWidthDefault = (float)(int)(window->Size.x * 0.65f); - else - window->ItemWidthDefault = 200.0f; - - // Prepare for focus requests - if (window->FocusIdxAllRequestNext == IM_INT_MAX || window->FocusIdxAllCounter == -1) - window->FocusIdxAllRequestCurrent = IM_INT_MAX; - else - window->FocusIdxAllRequestCurrent = (window->FocusIdxAllRequestNext + (window->FocusIdxAllCounter+1)) % (window->FocusIdxAllCounter+1); - if (window->FocusIdxTabRequestNext == IM_INT_MAX || window->FocusIdxTabCounter == -1) - window->FocusIdxTabRequestCurrent = IM_INT_MAX; - else - window->FocusIdxTabRequestCurrent = (window->FocusIdxTabRequestNext + (window->FocusIdxTabCounter+1)) % (window->FocusIdxTabCounter+1); - window->FocusIdxAllCounter = window->FocusIdxTabCounter = -1; - window->FocusIdxAllRequestNext = window->FocusIdxTabRequestNext = IM_INT_MAX; - - ImRect title_bar_rect = window->TitleBarRect(); - - // Apply and ImClamp scrolling - window->ScrollY = window->NextScrollY; - window->ScrollY = ImMax(window->ScrollY, 0.0f); - if (!window->Collapsed && !window->SkipItems) - window->ScrollY = ImMin(window->ScrollY, ImMax(0.0f, window->SizeContents.y - window->SizeFull.y)); - window->NextScrollY = window->ScrollY; - - // At this point we don't have a clipping rectangle setup yet, so we can test and draw in title bar - // Collapse window by double-clicking on title bar - if (!(window->Flags & ImGuiWindowFlags_NoTitleBar)) - { - if (!(window->Flags & ImGuiWindowFlags_NoCollapse) && g.HoveredWindow == window && IsMouseHoveringRect(title_bar_rect) && g.IO.MouseDoubleClicked[0]) - { - window->Collapsed = !window->Collapsed; - if (!(window->Flags & ImGuiWindowFlags_NoSavedSettings)) - MarkSettingsDirty(); - FocusWindow(window); - } - } - else - { - window->Collapsed = false; - } - - // Calculate auto-fit size - ImVec2 size_auto_fit; - if ((window->Flags & ImGuiWindowFlags_Tooltip) != 0) - { - // Tooltip always resize. We keep the spacing symmetric on both axises for aesthetic purpose. - size_auto_fit = window->SizeContents + style.WindowPadding - ImVec2(0.0f, style.ItemSpacing.y); - } - else - { - size_auto_fit = ImClamp(window->SizeContents + style.AutoFitPadding, style.WindowMinSize, ImMax(style.WindowMinSize, g.IO.DisplaySize - style.AutoFitPadding)); - if (size_auto_fit.y < window->SizeContents.y + style.AutoFitPadding.y) - size_auto_fit.x += style.ScrollbarWidth; - } - - const float window_rounding = (window->Flags & ImGuiWindowFlags_ChildWindow) ? style.ChildWindowRounding : style.WindowRounding; - if (window->Collapsed) - { - // We still process initial auto-fit on collapsed windows to get a window width - // But otherwise we don't honor ImGuiWindowFlags_AlwaysAutoResize when collapsed. - if (window->AutoFitFrames > 0) - { - window->SizeFull = window->AutoFitOnlyGrows ? ImMax(window->SizeFull, size_auto_fit) : size_auto_fit; - title_bar_rect = window->TitleBarRect(); - } - - // Draw title bar only - window->Size = title_bar_rect.GetSize(); - window->DrawList->AddRectFilled(title_bar_rect.GetTL(), title_bar_rect.GetBR(), window->Color(ImGuiCol_TitleBgCollapsed), window_rounding); - if (window->Flags & ImGuiWindowFlags_ShowBorders) - { - window->DrawList->AddRect(title_bar_rect.GetTL()+ImVec2(1,1), title_bar_rect.GetBR()+ImVec2(1,1), window->Color(ImGuiCol_BorderShadow), window_rounding); - window->DrawList->AddRect(title_bar_rect.GetTL(), title_bar_rect.GetBR(), window->Color(ImGuiCol_Border), window_rounding); - } - } - else - { - ImU32 resize_col = 0; - if ((window->Flags & ImGuiWindowFlags_Tooltip) != 0) - { - window->Size = window->SizeFull = size_auto_fit; - } - else - { - if ((window->Flags & ImGuiWindowFlags_AlwaysAutoResize) != 0) - { - // Don't continuously mark settings as dirty, the size of the window doesn't need to be stored. - window->SizeFull = size_auto_fit; - } - else if (window->AutoFitFrames > 0) - { - // Auto-fit only grows during the first few frames - window->SizeFull = window->AutoFitOnlyGrows ? ImMax(window->SizeFull, size_auto_fit) : size_auto_fit; - if (!(window->Flags & ImGuiWindowFlags_NoSavedSettings)) - MarkSettingsDirty(); - } - else if (!(window->Flags & ImGuiWindowFlags_NoResize)) - { - // Manual resize grip - const ImRect resize_rect(window->Rect().GetBR()-ImVec2(14,14), window->Rect().GetBR()); - const ImGuiID resize_id = window->GetID("#RESIZE"); - bool hovered, held; - ButtonBehavior(resize_rect, resize_id, &hovered, &held, true); - resize_col = window->Color(held ? ImGuiCol_ResizeGripActive : hovered ? ImGuiCol_ResizeGripHovered : ImGuiCol_ResizeGrip); - - if (hovered || held) - g.MouseCursor = ImGuiMouseCursor_ResizeNWSE; - - if (g.HoveredWindow == window && held && g.IO.MouseDoubleClicked[0]) - { - // Manual auto-fit when double-clicking - window->SizeFull = size_auto_fit; - if (!(window->Flags & ImGuiWindowFlags_NoSavedSettings)) - MarkSettingsDirty(); - SetActiveId(0); - } - else if (held) - { - // Resize - window->SizeFull = ImMax(window->SizeFull + g.IO.MouseDelta, style.WindowMinSize); - if (!(window->Flags & ImGuiWindowFlags_NoSavedSettings)) - MarkSettingsDirty(); - } - } - - // Update rectangle immediately so that rendering right below us isn't one frame late - window->Size = window->SizeFull; - title_bar_rect = window->TitleBarRect(); - } - - // Scrollbar - window->ScrollbarY = (window->SizeContents.y > window->Size.y) && !(window->Flags & ImGuiWindowFlags_NoScrollbar); - - // Window background - if (bg_alpha > 0.0f) - { - if ((window->Flags & ImGuiWindowFlags_ComboBox) != 0) - window->DrawList->AddRectFilled(window->Pos, window->Pos+window->Size, window->Color(ImGuiCol_ComboBg, bg_alpha), window_rounding); - else if ((window->Flags & ImGuiWindowFlags_Tooltip) != 0) - window->DrawList->AddRectFilled(window->Pos, window->Pos+window->Size, window->Color(ImGuiCol_TooltipBg, bg_alpha), window_rounding); - else if ((window->Flags & ImGuiWindowFlags_ChildWindow) != 0) - window->DrawList->AddRectFilled(window->Pos, window->Pos+window->Size-ImVec2(window->ScrollbarY?style.ScrollbarWidth:0.0f,0.0f), window->Color(ImGuiCol_ChildWindowBg, bg_alpha), window_rounding, window->ScrollbarY ? (1|8) : (0xF)); - else - window->DrawList->AddRectFilled(window->Pos, window->Pos+window->Size, window->Color(ImGuiCol_WindowBg, bg_alpha), window_rounding); - } - - // Title bar - if (!(window->Flags & ImGuiWindowFlags_NoTitleBar)) - window->DrawList->AddRectFilled(title_bar_rect.GetTL(), title_bar_rect.GetBR(), window->Color(ImGuiCol_TitleBg), window_rounding, 1|2); - - // Borders - if (window->Flags & ImGuiWindowFlags_ShowBorders) - { - window->DrawList->AddRect(window->Pos+ImVec2(1,1), window->Pos+window->Size+ImVec2(1,1), window->Color(ImGuiCol_BorderShadow), window_rounding); - window->DrawList->AddRect(window->Pos, window->Pos+window->Size, window->Color(ImGuiCol_Border), window_rounding); - if (!(window->Flags & ImGuiWindowFlags_NoTitleBar)) - window->DrawList->AddLine(title_bar_rect.GetBL(), title_bar_rect.GetBR(), window->Color(ImGuiCol_Border)); - } - - // Scrollbar - if (window->ScrollbarY) - Scrollbar(window); - - // Render resize grip - // (after the input handling so we don't have a frame of latency) - if (!(window->Flags & ImGuiWindowFlags_NoResize)) - { - const float r = window_rounding; - const ImVec2 br = window->Rect().GetBR(); - if (r == 0.0f) - { - window->DrawList->AddTriangleFilled(br, br-ImVec2(0,14), br-ImVec2(14,0), resize_col); - } - else - { - // FIXME: We should draw 4 triangles and decide on a size that's not dependent on the rounding size (previously used 18) - window->DrawList->AddArcFast(br - ImVec2(r,r), r, resize_col, 6, 9, true); - window->DrawList->AddTriangleFilled(br+ImVec2(0,-2*r),br+ImVec2(0,-r),br+ImVec2(-r,-r), resize_col); - window->DrawList->AddTriangleFilled(br+ImVec2(-r,-r), br+ImVec2(-r,0),br+ImVec2(-2*r,0), resize_col); - } - } - } - - // Setup drawing context - window->DC.ColumnsStartX = window->WindowPadding().x; - window->DC.ColumnsOffsetX = 0.0f; - window->DC.CursorStartPos = window->Pos + ImVec2(window->DC.ColumnsStartX + window->DC.ColumnsOffsetX, window->TitleBarHeight() + window->WindowPadding().y) - ImVec2(0.0f, window->ScrollY); - window->DC.CursorPos = window->DC.CursorStartPos; - window->DC.CursorPosPrevLine = window->DC.CursorPos; - window->DC.CursorMaxPos = window->DC.CursorStartPos; - window->DC.CurrentLineHeight = window->DC.PrevLineHeight = 0.0f; - window->DC.CurrentLineTextBaseOffset = window->DC.PrevLineTextBaseOffset = 0.0f; - window->DC.LogLinePosY = window->DC.CursorPos.y - 9999.0f; - window->DC.ChildWindows.resize(0); - window->DC.ItemWidth.resize(0); - window->DC.ItemWidth.push_back(window->ItemWidthDefault); - window->DC.AllowKeyboardFocus.resize(0); - window->DC.AllowKeyboardFocus.push_back(true); - window->DC.TextWrapPos.resize(0); - window->DC.TextWrapPos.push_back(-1.0f); // disabled - window->DC.ColorEditMode = ImGuiColorEditMode_UserSelect; - window->DC.ColumnsCurrent = 0; - window->DC.ColumnsCount = 1; - window->DC.ColumnsStartPos = window->DC.CursorPos; - window->DC.ColumnsCellMinY = window->DC.ColumnsCellMaxY = window->DC.ColumnsStartPos.y; - window->DC.TreeDepth = 0; - window->DC.StateStorage = &window->StateStorage; - window->DC.GroupStack.resize(0); - - if (window->AutoFitFrames > 0) - window->AutoFitFrames--; - - // Title bar - if (!(window->Flags & ImGuiWindowFlags_NoTitleBar)) - { - if (p_opened != NULL) - CloseWindowButton(p_opened); - - ImVec2 text_min = window->Pos + style.FramePadding; - if (!(window->Flags & ImGuiWindowFlags_NoCollapse)) - { - RenderCollapseTriangle(window->Pos + style.FramePadding, !window->Collapsed, 1.0f, true); - text_min.x += g.FontSize + style.ItemInnerSpacing.x; - } - - const ImVec2 text_size = CalcTextSize(name, NULL, true); - const ImVec2 text_max = window->Pos + ImVec2(window->Size.x - (p_opened ? (title_bar_rect.GetHeight()-3) : style.FramePadding.x), style.FramePadding.y*2 + text_size.y); - RenderTextClipped(text_min, name, NULL, &text_size, text_max); - } - if (window->Flags & ImGuiWindowFlags_Popup) - { - if (p_opened) - { - if (g.IO.MouseClicked[0] && (!g.HoveredWindow || g.HoveredWindow->RootWindow != window)) - *p_opened = false; - else if (!g.FocusedWindow) - *p_opened = false; - else if (g.FocusedWindow->RootWindow != window)// && !(g.FocusedWindow->RootWindow->Flags & ImGuiWindowFlags_Tooltip)) - *p_opened = false; - } - } - - // Save clipped aabb so we can access it in constant-time in FindHoveredWindow() - window->ClippedRect = window->Rect(); - window->ClippedRect.Clip(window->ClipRectStack.front()); - - // Pressing CTRL+C while holding on a window copy its content to the clipboard - // This works but 1. doesn't handle multiple Begin/End pairs, 2. recursing into another Begin/End pair - so we need to work that out and add better logging scope. - // Maybe we can support CTRL+C on every element? - /* - if (g.ActiveId == move_id) - if (g.IO.KeyCtrl && IsKeyPressedMap(ImGuiKey_C)) - ImGui::LogToClipboard(); - */ - } - - // Inner clipping rectangle - // We set this up after processing the resize grip so that our clip rectangle doesn't lag by a frame - // Note that if our window is collapsed we will end up with a null clipping rectangle which is the correct behavior. - const ImRect title_bar_rect = window->TitleBarRect(); - ImVec4 clip_rect(title_bar_rect.Min.x+0.5f+window->WindowPadding().x*0.5f, title_bar_rect.Max.y+0.5f, window->Rect().Max.x+0.5f-window->WindowPadding().x*0.5f, window->Rect().Max.y-1.5f); - if (window->ScrollbarY) - clip_rect.z -= style.ScrollbarWidth; - PushClipRect(clip_rect); - - // Clear 'accessed' flag last thing - if (first_begin_of_the_frame) - window->Accessed = false; - - // Child window can be out of sight and have "negative" clip windows. - // Mark them as collapsed so commands are skipped earlier (we can't manually collapse because they have no title bar). - if (flags & ImGuiWindowFlags_ChildWindow) - { - IM_ASSERT((flags & ImGuiWindowFlags_NoTitleBar) != 0); - window->Collapsed = parent_window && parent_window->Collapsed; - - const ImVec4 clip_rect_t = window->ClipRectStack.back(); - window->Collapsed |= (clip_rect_t.x >= clip_rect_t.z || clip_rect_t.y >= clip_rect_t.w); - - // We also hide the window from rendering because we've already added its border to the command list. - // (we could perform the check earlier in the function but it is simpler at this point) - if (window->Collapsed) - window->Visible = false; - } - if (style.Alpha <= 0.0f) - window->Visible = false; - - // Return false if we don't intend to display anything to allow user to perform an early out optimization - window->SkipItems = (window->Collapsed || !window->Visible) && window->AutoFitFrames <= 0; - return !window->SkipItems; -} - -void ImGui::End() -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; - - ImGui::Columns(1, "#CloseColumns"); - PopClipRect(); // inner window clip rectangle - PopClipRect(); // outer window clip rectangle - window->DrawList->PopTextureID(); - - // Stop logging - if (!(window->Flags & ImGuiWindowFlags_ChildWindow)) // FIXME: add more options for scope of logging - ImGui::LogFinish(); - - // Pop - // NB: we don't clear 'window->RootWindow'. The pointer is allowed to live until the next call to Begin(). - g.CurrentWindowStack.pop_back(); - SetCurrentWindow(g.CurrentWindowStack.empty() ? NULL : g.CurrentWindowStack.back()); -} - -// Vertical scrollbar -// The entire piece of code below is rather confusing because: -// - We handle absolute seeking (when first clicking outside the grab) and relative manipulation (afterward or when clicking inside the grab) -// - We store values as ratio and in a form that allows the window content to change while we are holding on a scrollbar -static void Scrollbar(ImGuiWindow* window) -{ - ImGuiState& g = *GImGui; - const ImGuiStyle& style = g.Style; - const ImGuiID id = window->GetID("#SCROLLY"); - - // Render background - ImRect bb(window->Rect().Max.x - style.ScrollbarWidth, window->Pos.y + window->TitleBarHeight()+1, window->Rect().Max.x, window->Rect().Max.y-1); - window->DrawList->AddRectFilled(bb.Min, bb.Max, window->Color(ImGuiCol_ScrollbarBg)); - bb.Expand(-3.0f); - const float scrollbar_height = bb.GetHeight(); - - // The grabable box size generally represent the amount visible (vs the total scrollable amount) - // But we maintain a minimum size in pixel to allow for the user to still aim inside. - const float grab_h_pixels = ImMin(ImMax(scrollbar_height * ImSaturate(window->Size.y / ImMax(window->SizeContents.y, window->Size.y)), style.GrabMinSize), scrollbar_height); - const float grab_h_norm = grab_h_pixels / scrollbar_height; - - // Handle input right away. None of the code of Begin() is relying on scrolling position before calling Scrollbar(). - bool held = false; - bool hovered = false; - const bool previously_held = (g.ActiveId == id); - ButtonBehavior(bb, id, &hovered, &held, true); - - const float scroll_max = ImMax(1.0f, window->SizeContents.y - window->Size.y); - float scroll_ratio = ImSaturate(window->ScrollY / scroll_max); - float grab_y_norm = scroll_ratio * (scrollbar_height - grab_h_pixels) / scrollbar_height; - if (held) - { - const float clicked_y_norm = ImSaturate((g.IO.MousePos.y - bb.Min.y) / scrollbar_height); // Click position in scrollbar space (0.0f->1.0f) - g.HoveredId = id; - - bool seek_absolute = false; - if (!previously_held) - { - // On initial click calculate the distance between mouse and the center of the grab - if (clicked_y_norm >= grab_y_norm && clicked_y_norm <= grab_y_norm + grab_h_norm) - { - g.ScrollbarClickDeltaToGrabCenter = clicked_y_norm - grab_y_norm - grab_h_norm*0.5f; - } - else - { - seek_absolute = true; - g.ScrollbarClickDeltaToGrabCenter = 0; - } - } - - // Apply scroll - const float scroll_y_norm = ImSaturate((clicked_y_norm - g.ScrollbarClickDeltaToGrabCenter - grab_h_norm*0.5f) / (1.0f - grab_h_norm)); - window->ScrollY = (float)(int)(0.5f + scroll_y_norm * (window->SizeContents.y - window->Size.y)); - window->NextScrollY = window->ScrollY; - - // Update values for rendering - scroll_ratio = ImSaturate(window->ScrollY / scroll_max); - grab_y_norm = scroll_ratio * (scrollbar_height - grab_h_pixels) / scrollbar_height; - - // Update distance to grab now that we have seeked and saturated - if (seek_absolute) - g.ScrollbarClickDeltaToGrabCenter = clicked_y_norm - grab_y_norm - grab_h_norm*0.5f; - } - - // Render - const ImU32 grab_col = window->Color(held ? ImGuiCol_ScrollbarGrabActive : hovered ? ImGuiCol_ScrollbarGrabHovered : ImGuiCol_ScrollbarGrab); - window->DrawList->AddRectFilled(ImVec2(bb.Min.x, ImLerp(bb.Min.y, bb.Max.y, grab_y_norm)), ImVec2(bb.Max.x, ImLerp(bb.Min.y, bb.Max.y, grab_y_norm) + grab_h_pixels), grab_col); -} - -// Moving window to front of display (which happens to be back of our sorted list) -static void FocusWindow(ImGuiWindow* window) -{ - ImGuiState& g = *GImGui; - - // Always mark the window we passed as focused. This is used for keyboard interactions such as tabbing. - g.FocusedWindow = window; - - // Passing NULL allow to disable keyboard focus - if (!window) - return; - - // And move its root window to the top of the pile - if (window->RootWindow) - window = window->RootWindow; - - if (g.Windows.back() == window) - return; - - for (size_t i = 0; i < g.Windows.size(); i++) - if (g.Windows[i] == window) - { - g.Windows.erase(g.Windows.begin() + i); - break; - } - g.Windows.push_back(window); -} - -void ImGui::PushItemWidth(float item_width) -{ - ImGuiWindow* window = GetCurrentWindow(); - window->DC.ItemWidth.push_back(item_width == 0.0f ? window->ItemWidthDefault : item_width); -} - -void ImGui::PopItemWidth() -{ - ImGuiWindow* window = GetCurrentWindow(); - window->DC.ItemWidth.pop_back(); -} - -float ImGui::CalcItemWidth() -{ - ImGuiWindow* window = GetCurrentWindow(); - float w = window->DC.ItemWidth.back(); - if (w < 0.0f) - { - // Align to a right-side limit. We include 1 frame padding in the calculation because this is how the width is always used (we add 2 frame padding to it), but we could move that responsibility to the widget as well. - ImGuiState& g = *GImGui; - w = -w; - float width_to_right_edge = window->Pos.x + ImGui::GetContentRegionMax().x - window->DC.CursorPos.x; - w = ImMax(1.0f, width_to_right_edge - w - g.Style.FramePadding.x * 2.0f); - } - w = (float)(int)w; - return w; -} - -static void SetFont(ImFont* font) -{ - ImGuiState& g = *GImGui; - - IM_ASSERT(font && font->IsLoaded()); - IM_ASSERT(font->Scale > 0.0f); - g.Font = font; - g.FontBaseSize = g.IO.FontGlobalScale * g.Font->FontSize * g.Font->Scale; - g.FontSize = g.CurrentWindow ? g.CurrentWindow->CalcFontSize() : 0.0f; - g.FontTexUvWhitePixel = g.Font->ContainerAtlas->TexUvWhitePixel; -} - -void ImGui::PushFont(ImFont* font) -{ - ImGuiState& g = *GImGui; - - if (!font) - font = g.IO.Fonts->Fonts[0]; - - SetFont(font); - g.FontStack.push_back(font); - g.CurrentWindow->DrawList->PushTextureID(font->ContainerAtlas->TexID); -} - -void ImGui::PopFont() -{ - ImGuiState& g = *GImGui; - - g.CurrentWindow->DrawList->PopTextureID(); - g.FontStack.pop_back(); - SetFont(g.FontStack.empty() ? g.IO.Fonts->Fonts[0] : g.FontStack.back()); -} - -void ImGui::PushAllowKeyboardFocus(bool allow_keyboard_focus) -{ - ImGuiWindow* window = GetCurrentWindow(); - window->DC.AllowKeyboardFocus.push_back(allow_keyboard_focus); -} - -void ImGui::PopAllowKeyboardFocus() -{ - ImGuiWindow* window = GetCurrentWindow(); - window->DC.AllowKeyboardFocus.pop_back(); -} - -void ImGui::PushTextWrapPos(float wrap_x) -{ - ImGuiWindow* window = GetCurrentWindow(); - window->DC.TextWrapPos.push_back(wrap_x); -} - -void ImGui::PopTextWrapPos() -{ - ImGuiWindow* window = GetCurrentWindow(); - window->DC.TextWrapPos.pop_back(); -} - -void ImGui::PushStyleColor(ImGuiCol idx, const ImVec4& col) -{ - ImGuiState& g = *GImGui; - - ImGuiColMod backup; - backup.Col = idx; - backup.PreviousValue = g.Style.Colors[idx]; - g.ColorModifiers.push_back(backup); - g.Style.Colors[idx] = col; -} - -void ImGui::PopStyleColor(int count) -{ - ImGuiState& g = *GImGui; - - while (count > 0) - { - ImGuiColMod& backup = g.ColorModifiers.back(); - g.Style.Colors[backup.Col] = backup.PreviousValue; - g.ColorModifiers.pop_back(); - count--; - } -} - -static float* GetStyleVarFloatAddr(ImGuiStyleVar idx) -{ - ImGuiState& g = *GImGui; - switch (idx) - { - case ImGuiStyleVar_Alpha: return &g.Style.Alpha; - case ImGuiStyleVar_WindowRounding: return &g.Style.WindowRounding; - case ImGuiStyleVar_ChildWindowRounding: return &g.Style.ChildWindowRounding; - case ImGuiStyleVar_FrameRounding: return &g.Style.FrameRounding; - case ImGuiStyleVar_IndentSpacing: return &g.Style.IndentSpacing; - case ImGuiStyleVar_GrabMinSize: return &g.Style.GrabMinSize; - } - return NULL; -} - -static ImVec2* GetStyleVarVec2Addr(ImGuiStyleVar idx) -{ - ImGuiState& g = *GImGui; - switch (idx) - { - case ImGuiStyleVar_WindowPadding: return &g.Style.WindowPadding; - case ImGuiStyleVar_FramePadding: return &g.Style.FramePadding; - case ImGuiStyleVar_ItemSpacing: return &g.Style.ItemSpacing; - case ImGuiStyleVar_ItemInnerSpacing: return &g.Style.ItemInnerSpacing; - } - return NULL; -} - -void ImGui::PushStyleVar(ImGuiStyleVar idx, float val) -{ - ImGuiState& g = *GImGui; - - float* pvar = GetStyleVarFloatAddr(idx); - IM_ASSERT(pvar != NULL); // Called function with wrong-type? Variable is not a float. - ImGuiStyleMod backup; - backup.Var = idx; - backup.PreviousValue = ImVec2(*pvar, 0.0f); - g.StyleModifiers.push_back(backup); - *pvar = val; -} - - -void ImGui::PushStyleVar(ImGuiStyleVar idx, const ImVec2& val) -{ - ImGuiState& g = *GImGui; - - ImVec2* pvar = GetStyleVarVec2Addr(idx); - IM_ASSERT(pvar != NULL); // Called function with wrong-type? Variable is not a ImVec2. - ImGuiStyleMod backup; - backup.Var = idx; - backup.PreviousValue = *pvar; - g.StyleModifiers.push_back(backup); - *pvar = val; -} - -void ImGui::PopStyleVar(int count) -{ - ImGuiState& g = *GImGui; - - while (count > 0) - { - ImGuiStyleMod& backup = g.StyleModifiers.back(); - if (float* pvar_f = GetStyleVarFloatAddr(backup.Var)) - *pvar_f = backup.PreviousValue.x; - else if (ImVec2* pvar_v = GetStyleVarVec2Addr(backup.Var)) - *pvar_v = backup.PreviousValue; - g.StyleModifiers.pop_back(); - count--; - } -} - -const char* ImGui::GetStyleColName(ImGuiCol idx) -{ - // Create switch-case from enum with regexp: ImGuiCol_{.*}, --> case ImGuiCol_\1: return "\1"; - switch (idx) - { - case ImGuiCol_Text: return "Text"; - case ImGuiCol_WindowBg: return "WindowBg"; - case ImGuiCol_ChildWindowBg: return "ChildWindowBg"; - case ImGuiCol_Border: return "Border"; - case ImGuiCol_BorderShadow: return "BorderShadow"; - case ImGuiCol_FrameBg: return "FrameBg"; - case ImGuiCol_FrameBgHovered: return "FrameBgHovered"; - case ImGuiCol_FrameBgActive: return "FrameBgActive"; - case ImGuiCol_TitleBg: return "TitleBg"; - case ImGuiCol_TitleBgCollapsed: return "TitleBgCollapsed"; - case ImGuiCol_ScrollbarBg: return "ScrollbarBg"; - case ImGuiCol_ScrollbarGrab: return "ScrollbarGrab"; - case ImGuiCol_ScrollbarGrabHovered: return "ScrollbarGrabHovered"; - case ImGuiCol_ScrollbarGrabActive: return "ScrollbarGrabActive"; - case ImGuiCol_ComboBg: return "ComboBg"; - case ImGuiCol_CheckMark: return "CheckMark"; - case ImGuiCol_SliderGrab: return "SliderGrab"; - case ImGuiCol_SliderGrabActive: return "SliderGrabActive"; - case ImGuiCol_Button: return "Button"; - case ImGuiCol_ButtonHovered: return "ButtonHovered"; - case ImGuiCol_ButtonActive: return "ButtonActive"; - case ImGuiCol_Header: return "Header"; - case ImGuiCol_HeaderHovered: return "HeaderHovered"; - case ImGuiCol_HeaderActive: return "HeaderActive"; - case ImGuiCol_Column: return "Column"; - case ImGuiCol_ColumnHovered: return "ColumnHovered"; - case ImGuiCol_ColumnActive: return "ColumnActive"; - case ImGuiCol_ResizeGrip: return "ResizeGrip"; - case ImGuiCol_ResizeGripHovered: return "ResizeGripHovered"; - case ImGuiCol_ResizeGripActive: return "ResizeGripActive"; - case ImGuiCol_CloseButton: return "CloseButton"; - case ImGuiCol_CloseButtonHovered: return "CloseButtonHovered"; - case ImGuiCol_CloseButtonActive: return "CloseButtonActive"; - case ImGuiCol_PlotLines: return "PlotLines"; - case ImGuiCol_PlotLinesHovered: return "PlotLinesHovered"; - case ImGuiCol_PlotHistogram: return "PlotHistogram"; - case ImGuiCol_PlotHistogramHovered: return "PlotHistogramHovered"; - case ImGuiCol_TextSelectedBg: return "TextSelectedBg"; - case ImGuiCol_TooltipBg: return "TooltipBg"; - } - IM_ASSERT(0); - return "Unknown"; -} - -bool ImGui::IsWindowFocused() -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - return g.FocusedWindow == window; -} - -bool ImGui::IsRootWindowFocused() -{ - ImGuiState& g = *GImGui; - ImGuiWindow* root_window = GetCurrentWindow()->RootWindow; - return g.FocusedWindow == root_window; -} - -bool ImGui::IsRootWindowOrAnyChildFocused() -{ - ImGuiState& g = *GImGui; - ImGuiWindow* root_window = GetCurrentWindow()->RootWindow; - return g.FocusedWindow && g.FocusedWindow->RootWindow == root_window; -} - -float ImGui::GetWindowWidth() -{ - ImGuiWindow* window = GetCurrentWindow(); - return window->Size.x; -} - -ImVec2 ImGui::GetWindowPos() -{ - ImGuiWindow* window = GetCurrentWindow(); - return window->Pos; -} - -static void SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiSetCond cond) -{ - // Test condition (NB: bit 0 is always true) and clear flags for next time - if (cond && (window->SetWindowPosAllowFlags & cond) == 0) - return; - window->SetWindowPosAllowFlags &= ~(ImGuiSetCond_Once | ImGuiSetCond_FirstUseEver); - - // Set - const ImVec2 old_pos = window->Pos; - window->PosFloat = pos; - window->Pos = ImVec2((float)(int)window->PosFloat.x, (float)(int)window->PosFloat.y); - window->DC.CursorPos += (window->Pos - old_pos); // As we happen to move the window while it is being appended to (which is a bad idea - will smear) let's at least offset the cursor - window->DC.CursorMaxPos += (window->Pos - old_pos); // And more importantly we need to adjust this so size calculation doesn't get affected. -} - -void ImGui::SetWindowPos(const ImVec2& pos, ImGuiSetCond cond) -{ - ImGuiWindow* window = GetCurrentWindow(); - SetWindowPos(window, pos, cond); -} - -void ImGui::SetWindowPos(const char* name, const ImVec2& pos, ImGuiSetCond cond) -{ - ImGuiWindow* window = FindWindowByName(name); - if (window) - SetWindowPos(window, pos, cond); -} - -ImVec2 ImGui::GetWindowSize() -{ - ImGuiWindow* window = GetCurrentWindow(); - return window->Size; -} - -static void SetWindowSize(ImGuiWindow* window, const ImVec2& size, ImGuiSetCond cond) -{ - // Test condition (NB: bit 0 is always true) and clear flags for next time - if (cond && (window->SetWindowSizeAllowFlags & cond) == 0) - return; - window->SetWindowSizeAllowFlags &= ~(ImGuiSetCond_Once | ImGuiSetCond_FirstUseEver); - - // Set - if (ImLengthSqr(size) > 0.00001f) - { - window->SizeFull = size; - window->AutoFitFrames = 0; - } - else - { - // Autofit - window->AutoFitFrames = 2; - window->AutoFitOnlyGrows = false; - } -} - -void ImGui::SetWindowSize(const ImVec2& size, ImGuiSetCond cond) -{ - ImGuiWindow* window = GetCurrentWindow(); - SetWindowSize(window, size, cond); -} - -void ImGui::SetWindowSize(const char* name, const ImVec2& size, ImGuiSetCond cond) -{ - ImGuiWindow* window = FindWindowByName(name); - if (window) - SetWindowSize(window, size, cond); -} - -static void SetWindowCollapsed(ImGuiWindow* window, bool collapsed, ImGuiSetCond cond) -{ - // Test condition (NB: bit 0 is always true) and clear flags for next time - if (cond && (window->SetWindowCollapsedAllowFlags & cond) == 0) - return; - window->SetWindowCollapsedAllowFlags &= ~(ImGuiSetCond_Once | ImGuiSetCond_FirstUseEver); - - // Set - window->Collapsed = collapsed; -} - -void ImGui::SetWindowCollapsed(bool collapsed, ImGuiSetCond cond) -{ - ImGuiWindow* window = GetCurrentWindow(); - SetWindowCollapsed(window, collapsed, cond); -} - -bool ImGui::GetWindowCollapsed() -{ - ImGuiWindow* window = GetCurrentWindow(); - return window->Collapsed; -} - -void ImGui::SetWindowCollapsed(const char* name, bool collapsed, ImGuiSetCond cond) -{ - ImGuiWindow* window = FindWindowByName(name); - if (window) - SetWindowCollapsed(window, collapsed, cond); -} - -void ImGui::SetWindowFocus() -{ - ImGuiWindow* window = GetCurrentWindow(); - FocusWindow(window); -} - -void ImGui::SetWindowFocus(const char* name) -{ - if (name) - { - ImGuiWindow* window = FindWindowByName(name); - if (window) - FocusWindow(window); - } - else - { - FocusWindow(NULL); - } -} - -void ImGui::SetNextWindowPos(const ImVec2& pos, ImGuiSetCond cond) -{ - ImGuiState& g = *GImGui; - g.SetNextWindowPosVal = pos; - g.SetNextWindowPosCond = cond ? cond : ImGuiSetCond_Always; -} - -void ImGui::SetNextWindowSize(const ImVec2& size, ImGuiSetCond cond) -{ - ImGuiState& g = *GImGui; - g.SetNextWindowSizeVal = size; - g.SetNextWindowSizeCond = cond ? cond : ImGuiSetCond_Always; -} - -void ImGui::SetNextWindowCollapsed(bool collapsed, ImGuiSetCond cond) -{ - ImGuiState& g = *GImGui; - g.SetNextWindowCollapsedVal = collapsed; - g.SetNextWindowCollapsedCond = cond ? cond : ImGuiSetCond_Always; -} - -void ImGui::SetNextWindowFocus() -{ - ImGuiState& g = *GImGui; - g.SetNextWindowFocus = true; -} - -ImVec2 ImGui::GetContentRegionMax() -{ - ImGuiWindow* window = GetCurrentWindow(); - ImVec2 window_padding = window->WindowPadding(); - ImVec2 mx = window->Size - window_padding; - if (window->DC.ColumnsCount != 1) - { - mx.x = ImGui::GetColumnOffset(window->DC.ColumnsCurrent + 1); - mx.x -= window_padding.x; - } - else - { - if (window->ScrollbarY) - mx.x -= GImGui->Style.ScrollbarWidth; - } - return mx; -} - -ImVec2 ImGui::GetWindowContentRegionMin() -{ - ImGuiWindow* window = GetCurrentWindow(); - return ImVec2(0, window->TitleBarHeight()) + window->WindowPadding(); -} - -ImVec2 ImGui::GetWindowContentRegionMax() -{ - ImGuiWindow* window = GetCurrentWindow(); - ImVec2 m = window->Size - window->WindowPadding(); - if (window->ScrollbarY) - m.x -= GImGui->Style.ScrollbarWidth; - return m; -} - -float ImGui::GetTextLineHeight() -{ - ImGuiState& g = *GImGui; - return g.FontSize; -} - -float ImGui::GetTextLineHeightWithSpacing() -{ - ImGuiState& g = *GImGui; - return g.FontSize + g.Style.ItemSpacing.y; -} - -ImDrawList* ImGui::GetWindowDrawList() -{ - ImGuiWindow* window = GetCurrentWindow(); - return window->DrawList; -} - -ImFont* ImGui::GetWindowFont() -{ - ImGuiState& g = *GImGui; - return g.Font; -} - -float ImGui::GetWindowFontSize() -{ - ImGuiState& g = *GImGui; - return g.FontSize; -} - -void ImGui::SetWindowFontScale(float scale) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - window->FontWindowScale = scale; - g.FontSize = window->CalcFontSize(); -} - -// NB: internally we store CursorPos in absolute screen coordinates because it is more convenient. -// Conversion happens as we pass the value to user, but it makes our naming convention dodgy. May want to rename 'DC.CursorPos'. -ImVec2 ImGui::GetCursorPos() -{ - ImGuiWindow* window = GetCurrentWindow(); - return window->DC.CursorPos - window->Pos; -} - -float ImGui::GetCursorPosX() -{ - return ImGui::GetCursorPos().x; -} - -float ImGui::GetCursorPosY() -{ - return ImGui::GetCursorPos().y; -} - -void ImGui::SetCursorPos(const ImVec2& pos) -{ - ImGuiWindow* window = GetCurrentWindow(); - window->DC.CursorPos = window->Pos + pos; - window->DC.CursorMaxPos = ImMax(window->DC.CursorMaxPos, window->DC.CursorPos); -} - -void ImGui::SetCursorPosX(float x) -{ - ImGuiWindow* window = GetCurrentWindow(); - window->DC.CursorPos.x = window->Pos.x + x; - window->DC.CursorMaxPos.x = ImMax(window->DC.CursorMaxPos.x, window->DC.CursorPos.x); -} - -void ImGui::SetCursorPosY(float y) -{ - ImGuiWindow* window = GetCurrentWindow(); - window->DC.CursorPos.y = window->Pos.y + y; - window->DC.CursorMaxPos.y = ImMax(window->DC.CursorMaxPos.y, window->DC.CursorPos.y); -} - -ImVec2 ImGui::GetCursorScreenPos() -{ - ImGuiWindow* window = GetCurrentWindow(); - return window->DC.CursorPos; -} - -void ImGui::SetCursorScreenPos(const ImVec2& screen_pos) -{ - ImGuiWindow* window = GetCurrentWindow(); - window->DC.CursorPos = screen_pos; -} - -float ImGui::GetScrollPosY() -{ - ImGuiWindow* window = GetCurrentWindow(); - return window->ScrollY; -} - -float ImGui::GetScrollMaxY() -{ - ImGuiWindow* window = GetCurrentWindow(); - return window->SizeContents.y - window->SizeFull.y; -} - -void ImGui::SetScrollPosHere() -{ - ImGuiWindow* window = GetCurrentWindow(); - window->NextScrollY = (window->DC.CursorPos.y + window->ScrollY) - (window->Pos.y + window->SizeFull.y * 0.5f) - (window->TitleBarHeight() + window->WindowPadding().y); -} - -void ImGui::SetKeyboardFocusHere(int offset) -{ - ImGuiWindow* window = GetCurrentWindow(); - window->FocusIdxAllRequestNext = window->FocusIdxAllCounter + 1 + offset; - window->FocusIdxTabRequestNext = IM_INT_MAX; -} - -void ImGui::SetStateStorage(ImGuiStorage* tree) -{ - ImGuiWindow* window = GetCurrentWindow(); - window->DC.StateStorage = tree ? tree : &window->StateStorage; -} - -ImGuiStorage* ImGui::GetStateStorage() -{ - ImGuiWindow* window = GetCurrentWindow(); - return window->DC.StateStorage; -} - -void ImGui::TextV(const char* fmt, va_list args) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return; - - const char* text_end = g.TempBuffer + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args); - TextUnformatted(g.TempBuffer, text_end); -} - -void ImGui::Text(const char* fmt, ...) -{ - va_list args; - va_start(args, fmt); - TextV(fmt, args); - va_end(args); -} - -void ImGui::TextColoredV(const ImVec4& col, const char* fmt, va_list args) -{ - ImGui::PushStyleColor(ImGuiCol_Text, col); - TextV(fmt, args); - ImGui::PopStyleColor(); -} - -void ImGui::TextColored(const ImVec4& col, const char* fmt, ...) -{ - va_list args; - va_start(args, fmt); - TextColoredV(col, fmt, args); - va_end(args); -} - -void ImGui::TextWrappedV(const char* fmt, va_list args) -{ - ImGui::PushTextWrapPos(0.0f); - TextV(fmt, args); - ImGui::PopTextWrapPos(); -} - -void ImGui::TextWrapped(const char* fmt, ...) -{ - va_list args; - va_start(args, fmt); - TextWrappedV(fmt, args); - va_end(args); -} - -void ImGui::TextUnformatted(const char* text, const char* text_end) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return; - - IM_ASSERT(text != NULL); - const char* text_begin = text; - if (text_end == NULL) - text_end = text + strlen(text); // FIXME-OPT - - const float wrap_pos_x = window->DC.TextWrapPos.back(); - const bool wrap_enabled = wrap_pos_x >= 0.0f; - if (text_end - text > 2000 && !wrap_enabled) - { - // Long text! - // Perform manual coarse clipping to optimize for long multi-line text - // From this point we will only compute the width of lines that are visible. Optimization only available when word-wrapping is disabled. - // We also don't vertically center the text within the line full height, which is unlikely to matter because we are likely the biggest and only item on the line. - const char* line = text; - const float line_height = ImGui::GetTextLineHeight(); - const ImVec2 text_pos = window->DC.CursorPos + ImVec2(0.0f, window->DC.CurrentLineTextBaseOffset); - const ImVec4 clip_rect = window->ClipRectStack.back(); - ImVec2 text_size(0,0); - - if (text_pos.y <= clip_rect.w) - { - ImVec2 pos = text_pos; - - // Lines to skip (can't skip when logging text) - if (!g.LogEnabled) - { - int lines_skippable = (int)((clip_rect.y - text_pos.y) / line_height) - 1; - if (lines_skippable > 0) - { - int lines_skipped = 0; - while (line < text_end && lines_skipped <= lines_skippable) - { - const char* line_end = strchr(line, '\n'); - line = line_end + 1; - lines_skipped++; - } - pos.y += lines_skipped * line_height; - } - } - - // Lines to render - if (line < text_end) - { - ImRect line_rect(pos, pos + ImVec2(ImGui::GetWindowWidth(), line_height)); - while (line < text_end) - { - const char* line_end = strchr(line, '\n'); - if (IsClippedEx(line_rect, NULL, false)) - break; - - const ImVec2 line_size = CalcTextSize(line, line_end, false); - text_size.x = ImMax(text_size.x, line_size.x); - RenderText(pos, line, line_end, false); - if (!line_end) - line_end = text_end; - line = line_end + 1; - line_rect.Min.y += line_height; - line_rect.Max.y += line_height; - pos.y += line_height; - } - - // Count remaining lines - int lines_skipped = 0; - while (line < text_end) - { - const char* line_end = strchr(line, '\n'); - if (!line_end) - line_end = text_end; - line = line_end + 1; - lines_skipped++; - } - pos.y += lines_skipped * line_height; - } - - text_size.y += (pos - text_pos).y; - } - - ImRect bb(text_pos, text_pos + text_size); - ItemSize(bb); - ItemAdd(bb, NULL); - } - else - { - const float wrap_width = wrap_enabled ? CalcWrapWidthForPos(window->DC.CursorPos, wrap_pos_x) : 0.0f; - const ImVec2 text_size = CalcTextSize(text_begin, text_end, false, wrap_width); - - // Account of baseline offset - ImVec2 text_pos = window->DC.CursorPos; - text_pos.y += window->DC.CurrentLineTextBaseOffset; - - ImRect bb(text_pos, text_pos + text_size); - ItemSize(bb.GetSize()); - if (!ItemAdd(bb, NULL)) - return; - - // Render (we don't hide text after ## in this end-user function) - RenderTextWrapped(bb.Min, text_begin, text_end, wrap_width); - } -} - -void ImGui::AlignFirstTextHeightToWidgets() -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return; - - // Declare a dummy item size to that upcoming items that are smaller will center-align on the newly expanded line height. - ItemSize(ImVec2(0, g.FontSize + g.Style.FramePadding.y*2), g.Style.FramePadding.y); - ImGui::SameLine(0, 0); -} - -// Add a label+text combo aligned to other label+value widgets -void ImGui::LabelTextV(const char* label, const char* fmt, va_list args) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return; - - const ImGuiStyle& style = g.Style; - const float w = ImGui::CalcItemWidth(); - - const char* value_text_begin = &g.TempBuffer[0]; - const char* value_text_end = value_text_begin + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args); - - const ImVec2 label_size = CalcTextSize(label, NULL, true); - const ImRect value_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w + style.FramePadding.x*2, label_size.y + style.FramePadding.y*2)); - const ImRect total_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w + style.FramePadding.x*2 + (label_size.x > 0.0f ? style.ItemInnerSpacing.x : 0.0f), style.FramePadding.y*2) + label_size); - ItemSize(total_bb, style.FramePadding.y); - if (!ItemAdd(total_bb, NULL)) - return; - - // Render - RenderTextClipped(ImVec2(value_bb.Min.x, value_bb.Min.y + style.FramePadding.y), value_text_begin, value_text_end, NULL, value_bb.Max); - RenderText(ImVec2(value_bb.Max.x + style.ItemInnerSpacing.x, value_bb.Min.y + style.FramePadding.y), label); -} - -void ImGui::LabelText(const char* label, const char* fmt, ...) -{ - va_list args; - va_start(args, fmt); - LabelTextV(label, fmt, args); - va_end(args); -} - -static inline bool IsWindowContentHoverable(ImGuiWindow* window) -{ - ImGuiState& g = *GImGui; - - // An active popup disable hovering on other windows (apart from its own children) - if (ImGuiWindow* focused_window = g.FocusedWindow) - if (ImGuiWindow* focused_root_window = focused_window->RootWindow) - if ((focused_root_window->Flags & ImGuiWindowFlags_Popup) != 0 && focused_root_window->WasVisible && focused_root_window != window->RootWindow) - return false; - - return true; -} - -static bool IsHovered(const ImRect& bb, ImGuiID id) -{ - ImGuiState& g = *GImGui; - if (g.HoveredId == 0) - { - ImGuiWindow* window = GetCurrentWindow(); - if (g.HoveredRootWindow == window->RootWindow) - if ((g.ActiveId == 0 || g.ActiveId == id || g.ActiveIdIsFocusedOnly) && IsMouseHoveringRect(bb)) - if (IsWindowContentHoverable(g.HoveredRootWindow)) - return true; - } - return false; -} - -static bool ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, bool allow_key_modifiers, bool repeat, bool pressed_on_click) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - - const bool hovered = IsHovered(bb, id); - bool pressed = false; - if (hovered) - { - g.HoveredId = id; - if (allow_key_modifiers || (!g.IO.KeyCtrl && !g.IO.KeyShift && !g.IO.KeyAlt)) - { - if (g.IO.MouseClicked[0]) - { - if (pressed_on_click) - { - pressed = true; - SetActiveId(0); - } - else - { - SetActiveId(id); - } - FocusWindow(window); - } - else if (repeat && g.ActiveId && ImGui::IsMouseClicked(0, true)) - { - pressed = true; - } - } - } - - bool held = false; - if (g.ActiveId == id) - { - if (g.IO.MouseDown[0]) - { - held = true; - } - else - { - if (hovered) - pressed = true; - SetActiveId(0); - } - } - - if (out_hovered) *out_hovered = hovered; - if (out_held) *out_held = held; - - return pressed; -} - -bool ImGui::Button(const char* label, const ImVec2& size_arg, bool repeat_when_held) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; - - const ImGuiStyle& style = g.Style; - const ImGuiID id = window->GetID(label); - const ImVec2 label_size = CalcTextSize(label, NULL, true); - - const ImVec2 size(size_arg.x != 0.0f ? size_arg.x : (label_size.x + style.FramePadding.x*2), size_arg.y != 0.0f ? size_arg.y : (label_size.y + style.FramePadding.y*2)); - const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); - ItemSize(bb, style.FramePadding.y); - if (!ItemAdd(bb, &id)) - return false; - - bool hovered, held; - bool pressed = ButtonBehavior(bb, id, &hovered, &held, true, repeat_when_held); - - // Render - const ImU32 col = window->Color((hovered && held) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button); - RenderFrame(bb.Min, bb.Max, col, true, style.FrameRounding); - - const ImVec2 off = ImVec2(ImMax(0.0f, size.x - label_size.x) * 0.5f, ImMax(0.0f, size.y - label_size.y) * 0.5f); // Center (only applies if we explicitly gave a size bigger than the text size, which isn't the common path) - RenderTextClipped(bb.Min + off, label, NULL, &label_size, bb.Max); // Render clip (only applies if we explicitly gave a size smaller than the text size, which isn't the commmon path) - - return pressed; -} - -// Small buttons fits within text without additional spacing. -bool ImGui::SmallButton(const char* label) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; - - const ImGuiStyle& style = g.Style; - const ImGuiID id = window->GetID(label); - const ImVec2 label_size = CalcTextSize(label, NULL, true); - - ImVec2 text_pos = window->DC.CursorPos; - text_pos.y += window->DC.CurrentLineTextBaseOffset; - ImRect bb(text_pos, text_pos + label_size + ImVec2(style.FramePadding.x*2,0)); - ItemSize(bb); - if (!ItemAdd(bb, &id)) - return false; - - bool hovered, held; - bool pressed = ButtonBehavior(bb, id, &hovered, &held, true); - - // Render - const ImU32 col = window->Color((hovered && held) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button); - RenderFrame(bb.Min, bb.Max, col); - RenderText(bb.Min + ImVec2(style.FramePadding.x,0), label); - - return pressed; -} - -// Tip: use ImGui::PushID()/PopID() to push indices or pointers in the ID stack. -// Then you can keep 'str_id' empty or the same for all your buttons (instead of creating a string based on a non-string id) -bool ImGui::InvisibleButton(const char* str_id, const ImVec2& size) -{ - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; - - const ImGuiID id = window->GetID(str_id); - const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); - ItemSize(bb); - if (!ItemAdd(bb, &id)) - return false; - - bool hovered, held; - bool pressed = ButtonBehavior(bb, id, &hovered, &held, true); - - return pressed; -} - -// Upper-right button to close a window. -static bool CloseWindowButton(bool* p_opened) -{ - ImGuiWindow* window = GetCurrentWindow(); - - const ImGuiID id = window->GetID("#CLOSE"); - const float size = window->TitleBarHeight() - 4.0f; - const ImRect bb(window->Rect().GetTR() + ImVec2(-3.0f-size,2.0f), window->Rect().GetTR() + ImVec2(-3.0f,2.0f+size)); - - bool hovered, held; - bool pressed = ButtonBehavior(bb, id, &hovered, &held, true); - - // Render - const ImU32 col = window->Color((held && hovered) ? ImGuiCol_CloseButtonActive : hovered ? ImGuiCol_CloseButtonHovered : ImGuiCol_CloseButton); - const ImVec2 center = bb.GetCenter(); - window->DrawList->AddCircleFilled(center, ImMax(2.0f,size*0.5f), col, 16); - - const float cross_extent = (size * 0.5f * 0.7071f) - 1.0f; - if (hovered) - { - window->DrawList->AddLine(center + ImVec2(+cross_extent,+cross_extent), center + ImVec2(-cross_extent,-cross_extent), window->Color(ImGuiCol_Text)); - window->DrawList->AddLine(center + ImVec2(+cross_extent,-cross_extent), center + ImVec2(-cross_extent,+cross_extent), window->Color(ImGuiCol_Text)); - } - - if (p_opened != NULL && pressed) - *p_opened = !*p_opened; - - return pressed; -} - -void ImGui::Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& tint_col, const ImVec4& border_col) -{ - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return; - - ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); - if (border_col.w > 0.0f) - bb.Max += ImVec2(2,2); - ItemSize(bb); - if (!ItemAdd(bb, NULL)) - return; - - if (border_col.w > 0.0f) - { - window->DrawList->AddRect(bb.Min, bb.Max, window->Color(border_col), 0.0f); - window->DrawList->AddImage(user_texture_id, bb.Min+ImVec2(1,1), bb.Max-ImVec2(1,1), uv0, uv1, window->Color(tint_col)); - } - else - { - window->DrawList->AddImage(user_texture_id, bb.Min, bb.Max, uv0, uv1, window->Color(tint_col)); - } -} - -// frame_padding < 0: uses FramePadding from style (default) -// frame_padding = 0: no framing -// frame_padding > 0: set framing size -// The color used are the button colors. -bool ImGui::ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, int frame_padding, const ImVec4& bg_col, const ImVec4& tint_col) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; - - const ImGuiStyle& style = g.Style; - - // Default to using texture ID as ID. User can still push string/integer prefixes. - // We could hash the size/uv to create a unique ID but that would prevent the user from animating buttons. - ImGui::PushID((void *)user_texture_id); - const ImGuiID id = window->GetID("#image"); - ImGui::PopID(); - - const ImVec2 padding = (frame_padding >= 0) ? ImVec2((float)frame_padding, (float)frame_padding) : style.FramePadding; - const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size + padding*2); - const ImRect image_bb(window->DC.CursorPos + padding, window->DC.CursorPos + padding + size); - ItemSize(bb); - if (!ItemAdd(bb, &id)) - return false; - - bool hovered, held; - bool pressed = ButtonBehavior(bb, id, &hovered, &held, true); - - // Render - const ImU32 col = window->Color((hovered && held) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button); - if (padding.x > 0.0f || padding.y > 0.0f) - RenderFrame(bb.Min, bb.Max, col); - if (bg_col.w > 0.0f) - window->DrawList->AddRectFilled(image_bb.Min, image_bb.Max, window->Color(bg_col)); - window->DrawList->AddImage(user_texture_id, image_bb.Min, image_bb.Max, uv0, uv1, window->Color(tint_col)); - - return pressed; -} - -// Start logging ImGui output to TTY -void ImGui::LogToTTY(int max_depth) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - if (g.LogEnabled) - return; - - g.LogEnabled = true; - g.LogFile = stdout; - g.LogStartDepth = window->DC.TreeDepth; - if (max_depth >= 0) - g.LogAutoExpandMaxDepth = max_depth; -} - -// Start logging ImGui output to given file -void ImGui::LogToFile(int max_depth, const char* filename) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - if (g.LogEnabled) - return; - if (!filename) - { - filename = g.IO.LogFilename; - if (!filename) - return; - } - - g.LogFile = fopen(filename, "ab"); - if (!g.LogFile) - { - IM_ASSERT(g.LogFile != NULL); // Consider this an error - return; - } - g.LogEnabled = true; - g.LogStartDepth = window->DC.TreeDepth; - if (max_depth >= 0) - g.LogAutoExpandMaxDepth = max_depth; -} - -// Start logging ImGui output to clipboard -void ImGui::LogToClipboard(int max_depth) -{ - ImGuiWindow* window = GetCurrentWindow(); - ImGuiState& g = *GImGui; - if (g.LogEnabled) - return; - - g.LogEnabled = true; - g.LogFile = NULL; - g.LogStartDepth = window->DC.TreeDepth; - if (max_depth >= 0) - g.LogAutoExpandMaxDepth = max_depth; -} - -void ImGui::LogFinish() -{ - ImGuiState& g = *GImGui; - if (!g.LogEnabled) - return; - - ImGui::LogText(STR_NEWLINE); - g.LogEnabled = false; - if (g.LogFile != NULL) - { - if (g.LogFile == stdout) - fflush(g.LogFile); - else - fclose(g.LogFile); - g.LogFile = NULL; - } - if (g.LogClipboard->size() > 1) - { - if (g.IO.SetClipboardTextFn) - g.IO.SetClipboardTextFn(g.LogClipboard->begin()); - g.LogClipboard->clear(); - } -} - -// Helper to display logging buttons -void ImGui::LogButtons() -{ - ImGuiState& g = *GImGui; - - ImGui::PushID("LogButtons"); - const bool log_to_tty = ImGui::Button("Log To TTY"); - ImGui::SameLine(); - const bool log_to_file = ImGui::Button("Log To File"); - ImGui::SameLine(); - const bool log_to_clipboard = ImGui::Button("Log To Clipboard"); - ImGui::SameLine(); - - ImGui::PushItemWidth(80.0f); - ImGui::PushAllowKeyboardFocus(false); - ImGui::SliderInt("Depth", &g.LogAutoExpandMaxDepth, 0, 9, NULL); - ImGui::PopAllowKeyboardFocus(); - ImGui::PopItemWidth(); - ImGui::PopID(); - - // Start logging at the end of the function so that the buttons don't appear in the log - if (log_to_tty) - LogToTTY(g.LogAutoExpandMaxDepth); - if (log_to_file) - LogToFile(g.LogAutoExpandMaxDepth, g.IO.LogFilename); - if (log_to_clipboard) - LogToClipboard(g.LogAutoExpandMaxDepth); -} - -bool ImGui::CollapsingHeader(const char* label, const char* str_id, bool display_frame, bool default_open) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; - - const ImGuiStyle& style = g.Style; - - IM_ASSERT(str_id != NULL || label != NULL); - if (str_id == NULL) - str_id = label; - if (label == NULL) - label = str_id; - const ImGuiID id = window->GetID(str_id); - - // We only write to the tree storage if the user clicks (or explicitely use SetNextTreeNode*** functions) - ImGuiStorage* storage = window->DC.StateStorage; - bool opened; - if (g.SetNextTreeNodeOpenedCond != 0) - { - if (g.SetNextTreeNodeOpenedCond & ImGuiSetCond_Always) - { - opened = g.SetNextTreeNodeOpenedVal; - storage->SetInt(id, opened); - } - else - { - // We treat ImGuiSetCondition_Once and ImGuiSetCondition_FirstUseEver the same because tree node state are not saved persistently. - const int stored_value = storage->GetInt(id, -1); - if (stored_value == -1) - { - opened = g.SetNextTreeNodeOpenedVal; - storage->SetInt(id, opened); - } - else - { - opened = stored_value != 0; - } - } - g.SetNextTreeNodeOpenedCond = 0; - } - else - { - opened = storage->GetInt(id, default_open) != 0; - } - - // Framed header expand a little outside the default padding - const ImVec2 window_padding = window->WindowPadding(); - const ImVec2 label_size = CalcTextSize(label, NULL, true); - const ImVec2 pos_min = window->DC.CursorPos; - const ImVec2 pos_max = window->Pos + GetContentRegionMax(); - ImRect bb = ImRect(pos_min, ImVec2(pos_max.x, pos_min.y + label_size.y)); - if (display_frame) - { - bb.Min.x -= window_padding.x*0.5f - 1; - bb.Max.x += window_padding.x*0.5f - 1; - bb.Max.y += style.FramePadding.y * 2; - } - - // FIXME: we don't provide our width so that it doesn't get feed back into AutoFit. Should manage that better so we can still hover without extending ContentsSize - const ImRect text_bb(bb.Min, bb.Min + ImVec2(g.FontSize + style.FramePadding.x*2*2,0) + label_size); - ItemSize(ImVec2(text_bb.GetSize().x, bb.GetSize().y), display_frame ? style.FramePadding.y : 0.0f); - - // When logging is enabled, if automatically expand tree nodes (but *NOT* collapsing headers.. seems like sensible behavior). - // NB- If we are above max depth we still allow manually opened nodes to be logged. - if (g.LogEnabled && !display_frame && window->DC.TreeDepth < g.LogAutoExpandMaxDepth) - opened = true; - - if (!ItemAdd(bb, &id)) - return opened; - - bool hovered, held; - bool pressed = ButtonBehavior(display_frame ? bb : text_bb, id, &hovered, &held, false); - if (pressed) - { - opened = !opened; - storage->SetInt(id, opened); - } - - // Render - const ImU32 col = window->Color((held && hovered) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header); - if (display_frame) - { - // Framed type - RenderFrame(bb.Min, bb.Max, col, true, style.FrameRounding); - RenderCollapseTriangle(bb.Min + style.FramePadding, opened, 1.0f, true); - if (g.LogEnabled) - { - // NB: '##' is normally used to hide text (as a library-wide feature), so we need to specify the text range to make sure the ## aren't stripped out here. - const char log_prefix[] = "\n##"; - LogText(bb.Min + style.FramePadding, log_prefix, log_prefix+3); - } - RenderText(bb.Min + style.FramePadding + ImVec2(g.FontSize + style.FramePadding.x*2,0), label); - if (g.LogEnabled) - { - const char log_suffix[] = "##"; - LogText(bb.Min + style.FramePadding, log_suffix, log_suffix+2); - } - } - else - { - // Unframed typed for tree nodes - if ((held && hovered) || hovered) - RenderFrame(bb.Min, bb.Max, col, false); - RenderCollapseTriangle(bb.Min + ImVec2(style.FramePadding.x, g.FontSize*0.15f), opened, 0.70f, false); - if (g.LogEnabled) - LogText(bb.Min, ">"); - RenderText(bb.Min + ImVec2(g.FontSize + style.FramePadding.x*2,0), label); - } - - return opened; -} - -void ImGui::Bullet() -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return; - - const ImGuiStyle& style = g.Style; - const float line_height = g.FontSize; - const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(line_height, line_height)); - ItemSize(bb); - if (!ItemAdd(bb, NULL)) - return; - - // Render - const float bullet_size = line_height*0.15f; - window->DrawList->AddCircleFilled(bb.Min + ImVec2(style.FramePadding.x + line_height*0.5f, line_height*0.5f), bullet_size, window->Color(ImGuiCol_Text)); - - // Stay on same line - ImGui::SameLine(0, -1); -} - -// Text with a little bullet aligned to the typical tree node. -void ImGui::BulletTextV(const char* fmt, va_list args) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return; - - const char* text_begin = g.TempBuffer; - const char* text_end = text_begin + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args); - - const ImGuiStyle& style = g.Style; - const float line_height = g.FontSize; - const ImVec2 label_size = CalcTextSize(text_begin, text_end, true); - const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(line_height + (label_size.x > 0.0f ? (style.FramePadding.x*2) : 0.0f),0) + label_size); // Empty text doesn't add padding - ItemSize(bb); - if (!ItemAdd(bb, NULL)) - return; - - // Render - const float bullet_size = line_height*0.15f; - window->DrawList->AddCircleFilled(bb.Min + ImVec2(style.FramePadding.x + line_height*0.5f, line_height*0.5f), bullet_size, window->Color(ImGuiCol_Text)); - RenderText(bb.Min+ImVec2(g.FontSize + style.FramePadding.x*2,0), text_begin, text_end); -} - -void ImGui::BulletText(const char* fmt, ...) -{ - va_list args; - va_start(args, fmt); - BulletTextV(fmt, args); - va_end(args); -} - -// If returning 'true' the node is open and the user is responsible for calling TreePop -bool ImGui::TreeNodeV(const char* str_id, const char* fmt, va_list args) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; - - ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args); - - if (!str_id || !str_id[0]) - str_id = fmt; - - ImGui::PushID(str_id); - const bool opened = ImGui::CollapsingHeader(g.TempBuffer, "", false); - ImGui::PopID(); - - if (opened) - ImGui::TreePush(str_id); - - return opened; -} - -bool ImGui::TreeNode(const char* str_id, const char* fmt, ...) -{ - va_list args; - va_start(args, fmt); - bool s = TreeNodeV(str_id, fmt, args); - va_end(args); - return s; -} - -// If returning 'true' the node is open and the user is responsible for calling TreePop -bool ImGui::TreeNodeV(const void* ptr_id, const char* fmt, va_list args) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; - - ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args); - - if (!ptr_id) - ptr_id = fmt; - - ImGui::PushID(ptr_id); - const bool opened = ImGui::CollapsingHeader(g.TempBuffer, "", false); - ImGui::PopID(); - - if (opened) - ImGui::TreePush(ptr_id); - - return opened; -} - -bool ImGui::TreeNode(const void* ptr_id, const char* fmt, ...) -{ - va_list args; - va_start(args, fmt); - bool s = TreeNodeV(ptr_id, fmt, args); - va_end(args); - return s; -} - -bool ImGui::TreeNode(const char* str_label_id) -{ - return TreeNode(str_label_id, "%s", str_label_id); -} - -void ImGui::SetNextTreeNodeOpened(bool opened, ImGuiSetCond cond) -{ - ImGuiState& g = *GImGui; - g.SetNextTreeNodeOpenedVal = opened; - g.SetNextTreeNodeOpenedCond = cond ? cond : ImGuiSetCond_Always; -} - -void ImGui::PushID(const char* str_id) -{ - ImGuiWindow* window = GetCurrentWindow(); - window->IDStack.push_back(window->GetID(str_id)); -} - -void ImGui::PushID(const char* str_id_begin, const char* str_id_end) -{ - ImGuiWindow* window = GetCurrentWindow(); - window->IDStack.push_back(window->GetID(str_id_begin, str_id_end)); -} - -void ImGui::PushID(const void* ptr_id) -{ - ImGuiWindow* window = GetCurrentWindow(); - window->IDStack.push_back(window->GetID(ptr_id)); -} - -void ImGui::PushID(const int int_id) -{ - const void* ptr_id = (void*)(intptr_t)int_id; - ImGuiWindow* window = GetCurrentWindow(); - window->IDStack.push_back(window->GetID(ptr_id)); -} - -void ImGui::PopID() -{ - ImGuiWindow* window = GetCurrentWindow(); - window->IDStack.pop_back(); -} - -ImGuiID ImGui::GetID(const char* str_id) -{ - ImGuiWindow* window = GetCurrentWindow(); - return window->GetID(str_id); -} - -ImGuiID ImGui::GetID(const char* str_id_begin, const char* str_id_end) -{ - ImGuiWindow* window = GetCurrentWindow(); - return window->GetID(str_id_begin, str_id_end); -} - -ImGuiID ImGui::GetID(const void* ptr_id) -{ - ImGuiWindow* window = GetCurrentWindow(); - return window->GetID(ptr_id); -} - -// User can input math operators (e.g. +100) to edit a numerical values. -// NB: only call right after InputText because we are using its InitialValue storage -static void ApplyNumericalTextInput(const char* buf, float *v) -{ - while (ImCharIsSpace(*buf)) - buf++; - - // We don't support '-' op because it would conflict with inputing negative value. - // Instead you can use +-100 to subtract from an existing value - char op = buf[0]; - if (op == '+' || op == '*' || op == '/') - { - buf++; - while (ImCharIsSpace(*buf)) - buf++; - } - else - { - op = 0; - } - if (!buf[0]) - return; - - float ref_v = *v; - if (op) - if (sscanf(GImGui->InputTextState.InitialText, "%f", &ref_v) < 1) - return; - - float op_v = 0.0f; - if (sscanf(buf, "%f", &op_v) < 1) - return; - - if (op == '+') - *v = ref_v + op_v; - else if (op == '*') - *v = ref_v * op_v; - else if (op == '/') - { - if (op_v == 0.0f) - return; - *v = ref_v / op_v; - } - else - *v = op_v; -} - -// Create text input in place of a slider (when CTRL+Clicking on slider) -static bool SliderFloatAsInputText(const char* label, float* v, ImGuiID id, int decimal_precision) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - - char text_buf[64]; - ImFormatString(text_buf, IM_ARRAYSIZE(text_buf), "%.*f", decimal_precision, *v); - - SetActiveId(g.ScalarAsInputTextId); - g.HoveredId = 0; - - // Our replacement widget will override the focus ID (registered previously to allow for a TAB focus to happen) - window->FocusItemUnregister(); - - bool value_changed = ImGui::InputText(label, text_buf, IM_ARRAYSIZE(text_buf), ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_AutoSelectAll); - if (g.ScalarAsInputTextId == 0) - { - // First frame - IM_ASSERT(g.ActiveId == id); // InputText ID expected to match the Slider ID (else we'd need to store them both, which is also possible) - g.ScalarAsInputTextId = g.ActiveId; - g.HoveredId = id; - } - else if (g.ActiveId != g.ScalarAsInputTextId) - { - // Release - g.ScalarAsInputTextId = 0; - } - if (value_changed) - { - ApplyNumericalTextInput(text_buf, v); - } - return value_changed; -} - -// Parse display precision back from the display format string -static inline void ParseFormat(const char* fmt, int& decimal_precision) -{ - while ((fmt = strchr(fmt, '%')) != NULL) - { - fmt++; - if (fmt[0] == '%') { fmt++; continue; } // Ignore "%%" - while (*fmt >= '0' && *fmt <= '9') - fmt++; - if (*fmt == '.') - { - decimal_precision = atoi(fmt + 1); - if (decimal_precision < 0 || decimal_precision > 10) - decimal_precision = 3; - } - break; - } -} - -static inline float RoundScalar(float value, int decimal_precision) -{ - // Round past decimal precision - // 0: 1, 1: 0.1, 2: 0.01, etc. - // So when our value is 1.99999 with a precision of 0.001 we'll end up rounding to 2.0 - // FIXME: Investigate better rounding methods - const float min_step = 1.0f / powf(10.0f, (float)decimal_precision); - const float remainder = fmodf(value, min_step); - if (remainder <= min_step*0.5f) - value -= remainder; - else - value += (min_step - remainder); - return value; -} - -static bool SliderScalarBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_min, float v_max, float power, int decimal_precision, bool horizontal) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - const ImGuiStyle& style = g.Style; - - // Draw frame - RenderFrame(frame_bb.Min, frame_bb.Max, window->Color(ImGuiCol_FrameBg), true, style.FrameRounding); - - const bool is_non_linear = fabsf(power - 1.0f) > 0.0001f; - - const float padding = horizontal ? style.FramePadding.x : style.FramePadding.y; - const float slider_sz = horizontal ? (frame_bb.GetWidth() - padding * 2.0f) : (frame_bb.GetHeight() - padding * 2.0f); - float grab_sz; - if (decimal_precision > 0) - grab_sz = ImMin(style.GrabMinSize, slider_sz); - else - grab_sz = ImMin(ImMax(1.0f * (slider_sz / (v_max-v_min+1.0f)), style.GrabMinSize), slider_sz); // Integer sliders, if possible have the grab size represent 1 unit - const float slider_usable_sz = slider_sz - grab_sz; - const float slider_usable_pos_min = (horizontal ? frame_bb.Min.x : frame_bb.Min.y) + padding + grab_sz*0.5f; - const float slider_usable_pos_max = (horizontal ? frame_bb.Max.x : frame_bb.Max.y) - padding - grab_sz*0.5f; - - bool value_changed = false; - - // For logarithmic sliders that cross over sign boundary we want the exponential increase to be symmetric around 0.0f - float linear_zero_pos = 0.0f; // 0.0->1.0f - if (v_min * v_max < 0.0f) - { - // Different sign - const float linear_dist_min_to_0 = powf(fabsf(0.0f - v_min), 1.0f/power); - const float linear_dist_max_to_0 = powf(fabsf(v_max - 0.0f), 1.0f/power); - linear_zero_pos = linear_dist_min_to_0 / (linear_dist_min_to_0+linear_dist_max_to_0); - } - else - { - // Same sign - linear_zero_pos = v_min < 0.0f ? 1.0f : 0.0f; - } - - // Process clicking on the slider - if (g.ActiveId == id) - { - if (g.IO.MouseDown[0]) - { - const float mouse_abs_pos = horizontal ? g.IO.MousePos.x : g.IO.MousePos.y; - float normalized_pos = ImClamp((mouse_abs_pos - slider_usable_pos_min) / slider_usable_sz, 0.0f, 1.0f); - if (!horizontal) - normalized_pos = 1.0f - normalized_pos; - - float new_value; - if (is_non_linear) - { - // Account for logarithmic scale on both sides of the zero - if (normalized_pos < linear_zero_pos) - { - // Negative: rescale to the negative range before powering - float a = 1.0f - (normalized_pos / linear_zero_pos); - a = powf(a, power); - new_value = ImLerp(ImMin(v_max,0.0f), v_min, a); - } - else - { - // Positive: rescale to the positive range before powering - float a; - if (fabsf(linear_zero_pos - 1.0f) > 1.e-6) - a = (normalized_pos - linear_zero_pos) / (1.0f - linear_zero_pos); - else - a = normalized_pos; - a = powf(a, power); - new_value = ImLerp(ImMax(v_min,0.0f), v_max, a); - } - } - else - { - // Linear slider - new_value = ImLerp(v_min, v_max, normalized_pos); - } - - // Round past decimal precision - new_value = RoundScalar(new_value, decimal_precision); - - if (*v != new_value) - { - *v = new_value; - value_changed = true; - } - } - else - { - SetActiveId(0); - } - } - - // Calculate slider grab positioning - float grab_t; - if (is_non_linear) - { - float v_clamped = ImClamp(*v, v_min, v_max); - if (v_clamped < 0.0f) - { - const float f = 1.0f - (v_clamped - v_min) / (ImMin(0.0f,v_max) - v_min); - grab_t = (1.0f - powf(f, 1.0f/power)) * linear_zero_pos; - } - else - { - const float f = (v_clamped - ImMax(0.0f,v_min)) / (v_max - ImMax(0.0f,v_min)); - grab_t = linear_zero_pos + powf(f, 1.0f/power) * (1.0f - linear_zero_pos); - } - } - else - { - // Linear slider - grab_t = (ImClamp(*v, v_min, v_max) - v_min) / (v_max - v_min); - } - - // Draw - if (!horizontal) - grab_t = 1.0f - grab_t; - const float grab_pos = ImLerp(slider_usable_pos_min, slider_usable_pos_max, grab_t); - ImRect grab_bb; - if (horizontal) - grab_bb = ImRect(ImVec2(grab_pos - grab_sz*0.5f, frame_bb.Min.y + 2.0f), ImVec2(grab_pos + grab_sz*0.5f, frame_bb.Max.y - 2.0f)); - else - grab_bb = ImRect(ImVec2(frame_bb.Min.x + 2.0f, grab_pos - grab_sz*0.5f), ImVec2(frame_bb.Max.x - 2.0f, grab_pos + grab_sz*0.5f)); - window->DrawList->AddRectFilled(grab_bb.Min, grab_bb.Max, window->Color(g.ActiveId == id ? ImGuiCol_SliderGrabActive : ImGuiCol_SliderGrab)); - - return value_changed; -} - -// Use power!=1.0 for logarithmic sliders. -// Adjust display_format to decorate the value with a prefix or a suffix. -// "%.3f" 1.234 -// "%5.2f secs" 01.23 secs -// "Gold: %.0f" Gold: 1 -bool ImGui::SliderFloat(const char* label, float* v, float v_min, float v_max, const char* display_format, float power) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; - - const ImGuiStyle& style = g.Style; - const ImGuiID id = window->GetID(label); - const float w = ImGui::CalcItemWidth(); - - const ImVec2 label_size = CalcTextSize(label, NULL, true); - const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y) + style.FramePadding*2.0f); - const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f)); - - // NB- we don't call ItemSize() yet because we may turn into a text edit box below - if (!ItemAdd(total_bb, &id)) - { - ItemSize(total_bb, style.FramePadding.y); - return false; - } - - const bool hovered = IsHovered(frame_bb, id); - if (hovered) - g.HoveredId = id; - - if (!display_format) - display_format = "%.3f"; - int decimal_precision = 3; - ParseFormat(display_format, decimal_precision); - - // Tabbing or CTRL-clicking on Slider turns it into an input box - bool start_text_input = false; - const bool tab_focus_requested = window->FocusItemRegister(g.ActiveId == id); - if (tab_focus_requested || (hovered && g.IO.MouseClicked[0])) - { - SetActiveId(id); - FocusWindow(window); - - const bool is_ctrl_down = g.IO.KeyCtrl; - if (tab_focus_requested || is_ctrl_down) - { - start_text_input = true; - g.ScalarAsInputTextId = 0; - } - } - if (start_text_input || (g.ActiveId == id && g.ScalarAsInputTextId == id)) - return SliderFloatAsInputText(label, v, id, decimal_precision); - - ItemSize(total_bb, style.FramePadding.y); - - // Actual slider behavior + render grab - const bool value_changed = SliderScalarBehavior(frame_bb, id, v, v_min, v_max, power, decimal_precision, true); - - // Display value using user-provided display format so user can add prefix/suffix/decorations to the value. - char value_buf[64]; - const char* value_buf_end = value_buf + ImFormatString(value_buf, IM_ARRAYSIZE(value_buf), display_format, *v); - const ImVec2 value_text_size = CalcTextSize(value_buf, value_buf_end, true); - RenderTextClipped(ImVec2(ImMax(frame_bb.Min.x + style.FramePadding.x, frame_bb.GetCenter().x - value_text_size.x*0.5f), frame_bb.Min.y + style.FramePadding.y), value_buf, value_buf_end, &value_text_size, frame_bb.Max); - - if (label_size.x > 0.0f) - RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); - - return value_changed; -} - -bool ImGui::VSliderFloat(const char* label, const ImVec2& size, float* v, float v_min, float v_max, const char* display_format, float power) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; - - const ImGuiStyle& style = g.Style; - const ImGuiID id = window->GetID(label); - - const ImVec2 label_size = CalcTextSize(label, NULL, true); - const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + size); - const ImRect bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f)); - - ItemSize(bb, style.FramePadding.y); - if (!ItemAdd(frame_bb, &id)) - return false; - - const bool hovered = IsHovered(frame_bb, id); - if (hovered) - g.HoveredId = id; - - if (!display_format) - display_format = "%.3f"; - int decimal_precision = 3; - ParseFormat(display_format, decimal_precision); - - if (hovered && g.IO.MouseClicked[0]) - { - SetActiveId(id); - FocusWindow(window); - } - - // Actual slider behavior + render grab - bool value_changed = SliderScalarBehavior(frame_bb, id, v, v_min, v_max, power, decimal_precision, false); - - // Display value using user-provided display format so user can add prefix/suffix/decorations to the value. - // For the vertical slider we allow centered text to overlap the frame padding - char value_buf[64]; - char* value_buf_end = value_buf + ImFormatString(value_buf, IM_ARRAYSIZE(value_buf), display_format, *v); - const ImVec2 value_text_size = CalcTextSize(value_buf, value_buf_end, true); - RenderTextClipped(ImVec2(ImMax(frame_bb.Min.x, frame_bb.GetCenter().x - value_text_size.x*0.5f), frame_bb.Min.y + style.FramePadding.y), value_buf, value_buf_end, &value_text_size, frame_bb.Max); - - if (label_size.x > 0.0f) - RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); - - return value_changed; -} - -bool ImGui::SliderAngle(const char* label, float* v_rad, float v_degrees_min, float v_degrees_max) -{ - float v_deg = (*v_rad) * 360.0f / (2*PI); - bool value_changed = ImGui::SliderFloat(label, &v_deg, v_degrees_min, v_degrees_max, "%.0f deg", 1.0f); - *v_rad = v_deg * (2*PI) / 360.0f; - return value_changed; -} - -bool ImGui::SliderInt(const char* label, int* v, int v_min, int v_max, const char* display_format) -{ - if (!display_format) - display_format = "%.0f"; - float v_f = (float)*v; - bool value_changed = ImGui::SliderFloat(label, &v_f, (float)v_min, (float)v_max, display_format, 1.0f); - *v = (int)v_f; - return value_changed; -} - -bool ImGui::VSliderInt(const char* label, const ImVec2& size, int* v, int v_min, int v_max, const char* display_format) -{ - if (!display_format) - display_format = "%.0f"; - float v_f = (float)*v; - bool value_changed = ImGui::VSliderFloat(label, size, &v_f, (float)v_min, (float)v_max, display_format, 1.0f); - *v = (int)v_f; - return value_changed; -} - -// Add multiple sliders on 1 line for compact edition of multiple components -static bool SliderFloatN(const char* label, float* v, int components, float v_min, float v_max, const char* display_format, float power) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; - - const ImGuiStyle& style = g.Style; - const float w_full = ImGui::CalcItemWidth(); - const float w_item_one = ImMax(1.0f, (float)(int)((w_full - (style.FramePadding.x*2.0f + style.ItemInnerSpacing.x)*(components-1)) / (float)components)); - const float w_item_last = ImMax(1.0f, (float)(int)(w_full - (w_item_one + style.FramePadding.x*2.0f + style.ItemInnerSpacing.x)*(components-1))); - - bool value_changed = false; - ImGui::BeginGroup(); - ImGui::PushID(label); - ImGui::PushItemWidth(w_item_one); - for (int i = 0; i < components; i++) - { - ImGui::PushID(i); - if (i + 1 == components) - { - ImGui::PopItemWidth(); - ImGui::PushItemWidth(w_item_last); - } - value_changed |= ImGui::SliderFloat("##v", &v[i], v_min, v_max, display_format, power); - ImGui::SameLine(0, (int)style.ItemInnerSpacing.x); - ImGui::PopID(); - } - ImGui::PopItemWidth(); - ImGui::PopID(); - - ImGui::TextUnformatted(label, FindTextDisplayEnd(label)); - ImGui::EndGroup(); - - return value_changed; -} - -bool ImGui::SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* display_format, float power) -{ - return SliderFloatN(label, v, 2, v_min, v_max, display_format, power); -} - -bool ImGui::SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* display_format, float power) -{ - return SliderFloatN(label, v, 3, v_min, v_max, display_format, power); -} - -bool ImGui::SliderFloat4(const char* label, float v[4], float v_min, float v_max, const char* display_format, float power) -{ - return SliderFloatN(label, v, 4, v_min, v_max, display_format, power); -} - -static bool SliderIntN(const char* label, int* v, int components, int v_min, int v_max, const char* display_format) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; - - const ImGuiStyle& style = g.Style; - const float w_full = ImGui::CalcItemWidth(); - const float w_item_one = ImMax(1.0f, (float)(int)((w_full - (style.FramePadding.x*2.0f + style.ItemInnerSpacing.x)*(components-1)) / (float)components)); - const float w_item_last = ImMax(1.0f, (float)(int)(w_full - (w_item_one + style.FramePadding.x*2.0f + style.ItemInnerSpacing.x)*(components-1))); - - bool value_changed = false; - ImGui::BeginGroup(); - ImGui::PushID(label); - ImGui::PushItemWidth(w_item_one); - for (int i = 0; i < components; i++) - { - ImGui::PushID(i); - if (i + 1 == components) - { - ImGui::PopItemWidth(); - ImGui::PushItemWidth(w_item_last); - } - value_changed |= ImGui::SliderInt("##v", &v[i], v_min, v_max, display_format); - ImGui::SameLine(0, (int)style.ItemInnerSpacing.x); - ImGui::PopID(); - } - ImGui::PopItemWidth(); - ImGui::PopID(); - - ImGui::TextUnformatted(label, FindTextDisplayEnd(label)); - ImGui::EndGroup(); - - return value_changed; -} - -bool ImGui::SliderInt2(const char* label, int v[2], int v_min, int v_max, const char* display_format) -{ - return SliderIntN(label, v, 2, v_min, v_max, display_format); -} - -bool ImGui::SliderInt3(const char* label, int v[3], int v_min, int v_max, const char* display_format) -{ - return SliderIntN(label, v, 3, v_min, v_max, display_format); -} - -bool ImGui::SliderInt4(const char* label, int v[4], int v_min, int v_max, const char* display_format) -{ - return SliderIntN(label, v, 4, v_min, v_max, display_format); -} - -// FIXME-WIP: Work in progress. May change API / behavior. -static bool DragScalarBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_speed, float v_min, float v_max, int decimal_precision, float power) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - const ImGuiStyle& style = g.Style; - - // Draw frame - const ImU32 frame_col = window->Color(g.ActiveId == id ? ImGuiCol_FrameBgActive : g.HoveredId == id ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg); - RenderFrame(frame_bb.Min, frame_bb.Max, frame_col, true, style.FrameRounding); - - bool value_changed = false; - - // Process clicking on the drag - if (g.ActiveId == id) - { - if (g.IO.MouseDown[0]) - { - if (g.ActiveIdIsJustActivated) - { - // Lock current value on click - g.DragCurrentValue = *v; - g.DragLastMouseDelta = ImVec2(0.f, 0.f); - } - - const ImVec2 mouse_drag_delta = ImGui::GetMouseDragDelta(0, 1.0f); - if (fabsf(mouse_drag_delta.x - g.DragLastMouseDelta.x) > 0.0f) - { - float speed = v_speed; - if (speed == 0.0f && (v_max - v_min) != 0.0f && (v_max - v_min) < FLT_MAX) - speed = (v_max - v_min) * g.DragSpeedDefaultRatio; - if (g.IO.KeyShift && g.DragSpeedScaleFast >= 0.0f) - speed = speed * g.DragSpeedScaleFast; - if (g.IO.KeyAlt && g.DragSpeedScaleSlow >= 0.0f) - speed = speed * g.DragSpeedScaleSlow; - - float v_cur = g.DragCurrentValue; - float delta = (mouse_drag_delta.x - g.DragLastMouseDelta.x) * speed; - if (fabsf(power - 1.0f) > 0.001f) - { - // Logarithmic curve on both side of 0.0 - float v0_abs = v_cur >= 0.0f ? v_cur : -v_cur; - float v0_sign = v_cur >= 0.0f ? 1.0f : -1.0f; - float v1 = powf(v0_abs, 1.0f / power) + (delta * v0_sign); - float v1_abs = v1 >= 0.0f ? v1 : -v1; - float v1_sign = v1 >= 0.0f ? 1.0f : -1.0f; // Crossed sign line - v_cur = powf(v1_abs, power) * v0_sign * v1_sign; // Reapply sign - } - else - { - v_cur += delta; - } - g.DragLastMouseDelta.x = mouse_drag_delta.x; - - // Clamp - if (v_min < v_max) - v_cur = ImClamp(v_cur, v_min, v_max); - g.DragCurrentValue = v_cur; - - // Round to user desired precision, then apply - v_cur = RoundScalar(v_cur, decimal_precision); - if (*v != v_cur) - { - *v = v_cur; - value_changed = true; - } - } - } - else - { - SetActiveId(0); - } - } - - return value_changed; -} - -bool ImGui::DragFloat(const char* label, float *v, float v_speed, float v_min, float v_max, const char* display_format, float power) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; - - const ImGuiStyle& style = g.Style; - const ImGuiID id = window->GetID(label); - const float w = ImGui::CalcItemWidth(); - - const ImVec2 label_size = CalcTextSize(label, NULL, true); - const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y) + style.FramePadding*2.0f); - const ImRect inner_bb(frame_bb.Min + style.FramePadding, frame_bb.Max - style.FramePadding); - const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f)); - - // NB- we don't call ItemSize() yet because we may turn into a text edit box below - if (!ItemAdd(total_bb, &id)) - { - ItemSize(total_bb, style.FramePadding.y); - return false; - } - - const bool hovered = IsHovered(frame_bb, id); - if (hovered) - g.HoveredId = id; - - if (!display_format) - display_format = "%.3f"; - int decimal_precision = 3; - ParseFormat(display_format, decimal_precision); - - // Tabbing or CTRL-clicking on Drag turns it into an input box - bool start_text_input = false; - const bool tab_focus_requested = window->FocusItemRegister(g.ActiveId == id); - if (tab_focus_requested || (hovered && (g.IO.MouseClicked[0] | g.IO.MouseDoubleClicked[0]))) - { - SetActiveId(id); - FocusWindow(window); - - if (tab_focus_requested || g.IO.KeyCtrl || g.IO.MouseDoubleClicked[0]) - { - start_text_input = true; - g.ScalarAsInputTextId = 0; - } - } - if (start_text_input || (g.ActiveId == id && g.ScalarAsInputTextId == id)) - return SliderFloatAsInputText(label, v, id, decimal_precision); - - ItemSize(total_bb, style.FramePadding.y); - - // Actual drag behavior - const bool value_changed = DragScalarBehavior(frame_bb, id, v, v_speed, v_min, v_max, decimal_precision, power); - - // Display value using user-provided display format so user can add prefix/suffix/decorations to the value. - char value_buf[64]; - const char* value_buf_end = value_buf + ImFormatString(value_buf, IM_ARRAYSIZE(value_buf), display_format, *v); - const ImVec2 value_text_size = CalcTextSize(value_buf, value_buf_end, true); - RenderTextClipped(ImVec2(ImMax(frame_bb.Min.x + style.FramePadding.x, inner_bb.GetCenter().x - value_text_size.x*0.5f), frame_bb.Min.y + style.FramePadding.y), value_buf, value_buf_end, &value_text_size, frame_bb.Max); - - if (label_size.x > 0.0f) - RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, inner_bb.Min.y), label); - - return value_changed; -} - -static bool DragFloatN(const char* label, float* v, int components, float v_speed, float v_min, float v_max, const char* display_format, float power) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; - - const ImGuiStyle& style = g.Style; - const float w_full = ImGui::CalcItemWidth(); - const float w_item_one = ImMax(1.0f, (float)(int)((w_full - (style.FramePadding.x*2.0f + style.ItemInnerSpacing.x)*(components-1)) / (float)components)); - const float w_item_last = ImMax(1.0f, (float)(int)(w_full - (w_item_one + style.FramePadding.x*2.0f + style.ItemInnerSpacing.x)*(components-1))); - - bool value_changed = false; - ImGui::BeginGroup(); - ImGui::PushID(label); - ImGui::PushItemWidth(w_item_one); - for (int i = 0; i < components; i++) - { - ImGui::PushID(i); - if (i + 1 == components) - { - ImGui::PopItemWidth(); - ImGui::PushItemWidth(w_item_last); - } - value_changed |= ImGui::DragFloat("##v", &v[i], v_speed, v_min, v_max, display_format, power); - ImGui::SameLine(0, (int)style.ItemInnerSpacing.x); - ImGui::PopID(); - } - ImGui::PopItemWidth(); - ImGui::PopID(); - - ImGui::TextUnformatted(label, FindTextDisplayEnd(label)); - ImGui::EndGroup(); - - return value_changed; -} - -bool ImGui::DragFloat2(const char* label, float v[2], float v_speed, float v_min, float v_max, const char* display_format, float power) -{ - return DragFloatN(label, v, 2, v_speed, v_min, v_max, display_format, power); -} - -bool ImGui::DragFloat3(const char* label, float v[2], float v_speed, float v_min, float v_max, const char* display_format, float power) -{ - return DragFloatN(label, v, 3, v_speed, v_min, v_max, display_format, power); -} - -bool ImGui::DragFloat4(const char* label, float v[2], float v_speed, float v_min, float v_max, const char* display_format, float power) -{ - return DragFloatN(label, v, 4, v_speed, v_min, v_max, display_format, power); -} - -// NB: v_speed is float to allow adjusting the drag speed with more precision -bool ImGui::DragInt(const char* label, int* v, float v_speed, int v_min, int v_max, const char* display_format) -{ - if (!display_format) - display_format = "%.0f"; - float v_f = (float)*v; - bool value_changed = ImGui::DragFloat(label, &v_f, v_speed, (float)v_min, (float)v_max, display_format); - *v = (int)v_f; - return value_changed; -} - -static bool DragIntN(const char* label, int* v, int components, float v_speed, int v_min, int v_max, const char* display_format) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; - - const ImGuiStyle& style = g.Style; - const float w_full = ImGui::CalcItemWidth(); - const float w_item_one = ImMax(1.0f, (float)(int)((w_full - (style.FramePadding.x*2.0f + style.ItemInnerSpacing.x)*(components-1)) / (float)components)); - const float w_item_last = ImMax(1.0f, (float)(int)(w_full - (w_item_one + style.FramePadding.x*2.0f + style.ItemInnerSpacing.x)*(components-1))); - - bool value_changed = false; - ImGui::BeginGroup(); - ImGui::PushID(label); - ImGui::PushItemWidth(w_item_one); - for (int i = 0; i < components; i++) - { - ImGui::PushID(i); - if (i + 1 == components) - { - ImGui::PopItemWidth(); - ImGui::PushItemWidth(w_item_last); - } - value_changed |= ImGui::DragInt("##v", &v[i], v_speed, v_min, v_max, display_format); - ImGui::SameLine(0, (int)style.ItemInnerSpacing.x); - ImGui::PopID(); - } - ImGui::PopItemWidth(); - ImGui::PopID(); - - ImGui::TextUnformatted(label, FindTextDisplayEnd(label)); - ImGui::EndGroup(); - - return value_changed; -} - -bool ImGui::DragInt2(const char* label, int v[2], float v_speed, int v_min, int v_max, const char* display_format) -{ - return DragIntN(label, v, 2, v_speed, v_min, v_max, display_format); -} - -bool ImGui::DragInt3(const char* label, int v[3], float v_speed, int v_min, int v_max, const char* display_format) -{ - return DragIntN(label, v, 3, v_speed, v_min, v_max, display_format); -} - -bool ImGui::DragInt4(const char* label, int v[4], float v_speed, int v_min, int v_max, const char* display_format) -{ - return DragIntN(label, v, 4, v_speed, v_min, v_max, display_format); -} - -enum ImGuiPlotType -{ - ImGuiPlotType_Lines, - ImGuiPlotType_Histogram -}; - -static void Plot(ImGuiPlotType plot_type, const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return; - - const ImGuiStyle& style = g.Style; - - const ImVec2 label_size = ImGui::CalcTextSize(label, NULL, true); - if (graph_size.x == 0.0f) - graph_size.x = ImGui::CalcItemWidth() + (style.FramePadding.x * 2); - if (graph_size.y == 0.0f) - graph_size.y = label_size.y + (style.FramePadding.y * 2); - - const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(graph_size.x, graph_size.y)); - const ImRect inner_bb(frame_bb.Min + style.FramePadding, frame_bb.Max - style.FramePadding); - const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0)); - ItemSize(total_bb, style.FramePadding.y); - if (!ItemAdd(total_bb, NULL)) - return; - - // Determine scale from values if not specified - if (scale_min == FLT_MAX || scale_max == FLT_MAX) - { - float v_min = FLT_MAX; - float v_max = -FLT_MAX; - for (int i = 0; i < values_count; i++) - { - const float v = values_getter(data, i); - v_min = ImMin(v_min, v); - v_max = ImMax(v_max, v); - } - if (scale_min == FLT_MAX) - scale_min = v_min; - if (scale_max == FLT_MAX) - scale_max = v_max; - } - - RenderFrame(frame_bb.Min, frame_bb.Max, window->Color(ImGuiCol_FrameBg), true, style.FrameRounding); - - int res_w = ImMin((int)graph_size.x, values_count); - if (plot_type == ImGuiPlotType_Lines) - res_w -= 1; - - // Tooltip on hover - int v_hovered = -1; - if (IsMouseHoveringRect(inner_bb)) - { - const float t = ImClamp((g.IO.MousePos.x - inner_bb.Min.x) / (inner_bb.Max.x - inner_bb.Min.x), 0.0f, 0.9999f); - const int v_idx = (int)(t * (values_count + ((plot_type == ImGuiPlotType_Lines) ? -1 : 0))); - IM_ASSERT(v_idx >= 0 && v_idx < values_count); - - const float v0 = values_getter(data, (v_idx + values_offset) % values_count); - const float v1 = values_getter(data, (v_idx + 1 + values_offset) % values_count); - if (plot_type == ImGuiPlotType_Lines) - ImGui::SetTooltip("%d: %8.4g\n%d: %8.4g", v_idx, v0, v_idx+1, v1); - else if (plot_type == ImGuiPlotType_Histogram) - ImGui::SetTooltip("%d: %8.4g", v_idx, v0); - v_hovered = v_idx; - } - - const float t_step = 1.0f / (float)res_w; - - float v0 = values_getter(data, (0 + values_offset) % values_count); - float t0 = 0.0f; - ImVec2 p0 = ImVec2( t0, 1.0f - ImSaturate((v0 - scale_min) / (scale_max - scale_min)) ); - - const ImU32 col_base = window->Color((plot_type == ImGuiPlotType_Lines) ? ImGuiCol_PlotLines : ImGuiCol_PlotHistogram); - const ImU32 col_hovered = window->Color((plot_type == ImGuiPlotType_Lines) ? ImGuiCol_PlotLinesHovered : ImGuiCol_PlotHistogramHovered); - - for (int n = 0; n < res_w; n++) - { - const float t1 = t0 + t_step; - const int v_idx = (int)(t0 * values_count); - IM_ASSERT(v_idx >= 0 && v_idx < values_count); - const float v1 = values_getter(data, (v_idx + values_offset + 1) % values_count); - const ImVec2 p1 = ImVec2( t1, 1.0f - ImSaturate((v1 - scale_min) / (scale_max - scale_min)) ); - - // NB- Draw calls are merged together by the DrawList system. - if (plot_type == ImGuiPlotType_Lines) - window->DrawList->AddLine(ImLerp(inner_bb.Min, inner_bb.Max, p0), ImLerp(inner_bb.Min, inner_bb.Max, p1), v_hovered == v_idx ? col_hovered : col_base); - else if (plot_type == ImGuiPlotType_Histogram) - window->DrawList->AddRectFilled(ImLerp(inner_bb.Min, inner_bb.Max, p0), ImLerp(inner_bb.Min, inner_bb.Max, ImVec2(p1.x, 1.0f))+ImVec2(-1,0), v_hovered == v_idx ? col_hovered : col_base); - - t0 = t1; - p0 = p1; - } - - // Text overlay - if (overlay_text) - RenderText(ImVec2(inner_bb.GetCenter().x - ImGui::CalcTextSize(overlay_text, NULL, true).x*0.5f, frame_bb.Min.y + style.FramePadding.y), overlay_text); - - RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, inner_bb.Min.y), label); -} - -struct ImGuiPlotArrayGetterData -{ - const float* Values; - size_t Stride; - - ImGuiPlotArrayGetterData(const float* values, size_t stride) { Values = values; Stride = stride; } -}; - -static float Plot_ArrayGetter(void* data, int idx) -{ - ImGuiPlotArrayGetterData* plot_data = (ImGuiPlotArrayGetterData*)data; - const float v = *(float*)(void*)((unsigned char*)plot_data->Values + (size_t)idx * plot_data->Stride); - return v; -} - -void ImGui::PlotLines(const char* label, const float* values, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size, size_t stride) -{ - ImGuiPlotArrayGetterData data(values, stride); - Plot(ImGuiPlotType_Lines, label, &Plot_ArrayGetter, (void*)&data, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size); -} - -void ImGui::PlotLines(const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size) -{ - Plot(ImGuiPlotType_Lines, label, values_getter, data, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size); -} - -void ImGui::PlotHistogram(const char* label, const float* values, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size, size_t stride) -{ - ImGuiPlotArrayGetterData data(values, stride); - Plot(ImGuiPlotType_Histogram, label, &Plot_ArrayGetter, (void*)&data, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size); -} - -void ImGui::PlotHistogram(const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size) -{ - Plot(ImGuiPlotType_Histogram, label, values_getter, data, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size); -} - -bool ImGui::Checkbox(const char* label, bool* v) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; - - const ImGuiStyle& style = g.Style; - const ImGuiID id = window->GetID(label); - const ImVec2 label_size = CalcTextSize(label, NULL, true); - - const ImRect check_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(label_size.y + style.FramePadding.y*2, label_size.y + style.FramePadding.y*2)); - ItemSize(check_bb, style.FramePadding.y); - - ImRect total_bb = check_bb; - if (label_size.x > 0) - SameLine(0, (int)style.ItemInnerSpacing.x); - const ImRect text_bb(window->DC.CursorPos + ImVec2(0,style.FramePadding.y), window->DC.CursorPos + ImVec2(0,style.FramePadding.y) + label_size); - if (label_size.x > 0) - { - ItemSize(ImVec2(text_bb.GetWidth(), check_bb.GetHeight()), style.FramePadding.y); - total_bb = ImRect(ImMin(check_bb.Min, text_bb.Min), ImMax(check_bb.Max, text_bb.Max)); - } - - if (!ItemAdd(total_bb, &id)) - return false; - - bool hovered, held; - bool pressed = ButtonBehavior(total_bb, id, &hovered, &held, true); - if (pressed) - *v = !(*v); - - RenderFrame(check_bb.Min, check_bb.Max, window->Color((held && hovered) ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg), true, style.FrameRounding); - if (*v) - { - const float check_sz = ImMin(check_bb.GetWidth(), check_bb.GetHeight()); - const float pad = check_sz < 8.0f ? 1.0f : check_sz < 13.0f ? 2.0f : 3.0f; - window->DrawList->AddRectFilled(check_bb.Min+ImVec2(pad,pad), check_bb.Max-ImVec2(pad,pad), window->Color(ImGuiCol_CheckMark), style.FrameRounding); - } - - if (g.LogEnabled) - LogText(text_bb.GetTL(), *v ? "[x]" : "[ ]"); - RenderText(text_bb.GetTL(), label); - - return pressed; -} - -bool ImGui::CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value) -{ - bool v = (*flags & flags_value) ? true : false; - bool pressed = ImGui::Checkbox(label, &v); - if (v) - *flags |= flags_value; - else - *flags &= ~flags_value; - return pressed; -} - -bool ImGui::RadioButton(const char* label, bool active) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; - - const ImGuiStyle& style = g.Style; - const ImGuiID id = window->GetID(label); - const ImVec2 label_size = CalcTextSize(label, NULL, true); - - const ImRect check_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(label_size.y + style.FramePadding.y*2-1, label_size.y + style.FramePadding.y*2-1)); - ItemSize(check_bb, style.FramePadding.y); - - ImRect total_bb = check_bb; - if (label_size.x > 0) - SameLine(0, (int)style.ItemInnerSpacing.x); - const ImRect text_bb(window->DC.CursorPos + ImVec2(0, style.FramePadding.y), window->DC.CursorPos + ImVec2(0, style.FramePadding.y) + label_size); - if (label_size.x > 0) - { - ItemSize(ImVec2(text_bb.GetWidth(), check_bb.GetHeight()), style.FramePadding.y); - total_bb.Add(text_bb); - } - - if (!ItemAdd(total_bb, &id)) - return false; - - ImVec2 center = check_bb.GetCenter(); - center.x = (float)(int)center.x + 0.5f; - center.y = (float)(int)center.y + 0.5f; - const float radius = check_bb.GetHeight() * 0.5f; - - bool hovered, held; - bool pressed = ButtonBehavior(total_bb, id, &hovered, &held, true); - - window->DrawList->AddCircleFilled(center, radius, window->Color((held && hovered) ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg), 16); - if (active) - { - const float check_sz = ImMin(check_bb.GetWidth(), check_bb.GetHeight()); - const float pad = check_sz < 8.0f ? 1.0f : check_sz < 13.0f ? 2.0f : 3.0f; - window->DrawList->AddCircleFilled(center, radius-pad, window->Color(ImGuiCol_CheckMark), 16); - } - - if (window->Flags & ImGuiWindowFlags_ShowBorders) - { - window->DrawList->AddCircle(center+ImVec2(1,1), radius, window->Color(ImGuiCol_BorderShadow), 16); - window->DrawList->AddCircle(center, radius, window->Color(ImGuiCol_Border), 16); - } - - if (g.LogEnabled) - LogText(text_bb.GetTL(), active ? "(x)" : "( )"); - RenderText(text_bb.GetTL(), label); - - return pressed; -} - -bool ImGui::RadioButton(const char* label, int* v, int v_button) -{ - const bool pressed = ImGui::RadioButton(label, *v == v_button); - if (pressed) - { - *v = v_button; - } - return pressed; -} - -// Wrapper for stb_textedit.h to edit text (our wrapper is for: statically sized buffer, single-line, wchar characters. InputText converts between UTF-8 and wchar) -static int STB_TEXTEDIT_STRINGLEN(const STB_TEXTEDIT_STRING* obj) { return (int)ImStrlenW(obj->Text); } -static ImWchar STB_TEXTEDIT_GETCHAR(const STB_TEXTEDIT_STRING* obj, int idx) { return obj->Text[idx]; } -static float STB_TEXTEDIT_GETWIDTH(STB_TEXTEDIT_STRING* obj, int line_start_idx, int char_idx) { (void)line_start_idx; return obj->Font->CalcTextSizeW(obj->FontSize, FLT_MAX, &obj->Text[char_idx], &obj->Text[char_idx]+1, NULL).x; } -static int STB_TEXTEDIT_KEYTOTEXT(int key) { return key >= 0x10000 ? 0 : key; } -static ImWchar STB_TEXTEDIT_NEWLINE = '\n'; -static void STB_TEXTEDIT_LAYOUTROW(StbTexteditRow* r, STB_TEXTEDIT_STRING* obj, int line_start_idx) -{ - const ImWchar* text_remaining = NULL; - const ImVec2 size = obj->Font->CalcTextSizeW(obj->FontSize, FLT_MAX, obj->Text + line_start_idx, NULL, &text_remaining); - r->x0 = 0.0f; - r->x1 = size.x; - r->baseline_y_delta = size.y; - r->ymin = 0.0f; - r->ymax = size.y; - r->num_chars = (int)(text_remaining - (obj->Text + line_start_idx)); -} - -static bool is_separator(unsigned int c) { return c==',' || c==';' || c=='(' || c==')' || c=='{' || c=='}' || c=='[' || c==']' || c=='|'; } -#define STB_TEXTEDIT_IS_SPACE(CH) ( ImCharIsSpace((unsigned int)CH) || is_separator((unsigned int)CH) ) -static void STB_TEXTEDIT_DELETECHARS(STB_TEXTEDIT_STRING* obj, int pos, int n) -{ - ImWchar* dst = obj->Text + pos; - - // We maintain our buffer length in both UTF-8 and wchar formats - obj->CurLenA -= ImTextCountUtf8BytesFromStr(dst, dst + n); - obj->CurLenW -= n; - - // Offset remaining text - const ImWchar* src = obj->Text + pos + n; - while (ImWchar c = *src++) - *dst++ = c; - *dst = '\0'; -} - -static bool STB_TEXTEDIT_INSERTCHARS(STB_TEXTEDIT_STRING* obj, int pos, const ImWchar* new_text, int new_text_len) -{ - const size_t text_len = obj->CurLenW; - if ((size_t)new_text_len + text_len + 1 > IM_ARRAYSIZE(obj->Text)) - return false; - - const int new_text_len_utf8 = ImTextCountUtf8BytesFromStr(new_text, new_text + new_text_len); - if ((size_t)new_text_len_utf8 + obj->CurLenA + 1 > obj->BufSizeA) - return false; - - if (pos != (int)text_len) - memmove(obj->Text + (size_t)pos + new_text_len, obj->Text + (size_t)pos, (text_len - (size_t)pos) * sizeof(ImWchar)); - memcpy(obj->Text + (size_t)pos, new_text, (size_t)new_text_len * sizeof(ImWchar)); - - obj->CurLenW += new_text_len; - obj->CurLenA += new_text_len_utf8; - obj->Text[obj->CurLenW] = '\0'; - - return true; -} - -// We don't use an enum so we can build even with conflicting symbols (if another user of stb_textedit.h leak their STB_TEXTEDIT_K_* symbols) -#define STB_TEXTEDIT_K_LEFT 0x10000 // keyboard input to move cursor left -#define STB_TEXTEDIT_K_RIGHT 0x10001 // keyboard input to move cursor right -#define STB_TEXTEDIT_K_UP 0x10002 // keyboard input to move cursor up -#define STB_TEXTEDIT_K_DOWN 0x10003 // keyboard input to move cursor down -#define STB_TEXTEDIT_K_LINESTART 0x10004 // keyboard input to move cursor to start of line -#define STB_TEXTEDIT_K_LINEEND 0x10005 // keyboard input to move cursor to end of line -#define STB_TEXTEDIT_K_TEXTSTART 0x10006 // keyboard input to move cursor to start of text -#define STB_TEXTEDIT_K_TEXTEND 0x10007 // keyboard input to move cursor to end of text -#define STB_TEXTEDIT_K_DELETE 0x10008 // keyboard input to delete selection or character under cursor -#define STB_TEXTEDIT_K_BACKSPACE 0x10009 // keyboard input to delete selection or character left of cursor -#define STB_TEXTEDIT_K_UNDO 0x1000A // keyboard input to perform undo -#define STB_TEXTEDIT_K_REDO 0x1000B // keyboard input to perform redo -#define STB_TEXTEDIT_K_WORDLEFT 0x1000C // keyboard input to move cursor left one word -#define STB_TEXTEDIT_K_WORDRIGHT 0x1000D // keyboard input to move cursor right one word -#define STB_TEXTEDIT_K_SHIFT 0x20000 - -#ifdef IMGUI_STB_NAMESPACE -namespace IMGUI_STB_NAMESPACE -{ -#endif -#define STB_TEXTEDIT_IMPLEMENTATION -#include "stb_textedit.h" -#ifdef IMGUI_STB_NAMESPACE -} -#endif - -void ImGuiTextEditState::OnKeyPressed(int key) -{ - stb_textedit_key(this, &StbState, key); - CursorAnimReset(); -} - -void ImGuiTextEditState::UpdateScrollOffset() -{ - // Scroll in chunks of quarter width - const float scroll_x_increment = Width * 0.25f; - const float cursor_offset_x = Font->CalcTextSizeW(FontSize, FLT_MAX, Text, Text+StbState.cursor, NULL).x; - - // If widget became bigger than text (because of a resize), reset horizontal scrolling - if (ScrollX > 0.0f) - { - const float text_width = cursor_offset_x + Font->CalcTextSizeW(FontSize, FLT_MAX, Text+StbState.cursor, NULL, NULL).x; - if (text_width < Width) - { - ScrollX = 0.0f; - return; - } - } - - if (cursor_offset_x < ScrollX) - ScrollX = ImMax(0.0f, cursor_offset_x - scroll_x_increment); - else if (cursor_offset_x - Width >= ScrollX) - ScrollX = cursor_offset_x - Width + scroll_x_increment; -} - -ImVec2 ImGuiTextEditState::CalcDisplayOffsetFromCharIdx(int i) const -{ - const ImWchar* text_start = GetTextPointerClippedW(Font, FontSize, Text, ScrollX, NULL); - const ImWchar* text_end = (Text+i >= text_start) ? Text+i : text_start; // Clip if requested character is outside of display - IM_ASSERT(text_end >= text_start); - - const ImVec2 offset = Font->CalcTextSizeW(FontSize, Width+1, text_start, text_end, NULL); - return offset; -} - -// [Static] -const char* ImGuiTextEditState::GetTextPointerClippedA(ImFont* font, float font_size, const char* text, float width, ImVec2* out_text_size) -{ - if (width <= 0.0f) - return text; - - const char* text_clipped_end = NULL; - const ImVec2 text_size = font->CalcTextSizeA(font_size, width, 0.0f, text, NULL, &text_clipped_end); - if (out_text_size) - *out_text_size = text_size; - return text_clipped_end; -} - -// [Static] -const ImWchar* ImGuiTextEditState::GetTextPointerClippedW(ImFont* font, float font_size, const ImWchar* text, float width, ImVec2* out_text_size) -{ - if (width <= 0.0f) - return text; - - const ImWchar* text_clipped_end = NULL; - const ImVec2 text_size = font->CalcTextSizeW(font_size, width, text, NULL, &text_clipped_end); - if (out_text_size) - *out_text_size = text_size; - return text_clipped_end; -} - -// [Static] -void ImGuiTextEditState::RenderTextScrolledClipped(ImFont* font, float font_size, const char* buf, ImVec2 pos, float width, float scroll_x) -{ - ImGuiWindow* window = GetCurrentWindow(); - const ImU32 font_color = window->Color(ImGuiCol_Text); - //window->DrawList->AddLine(pos, pos+ImVec2(width,0), 0xFF00FFFF); - - // Determine start and end of visible string - // FIXME-OPT: This is pretty slow for what it does. - const char* text_start = scroll_x <= 0.0f ? buf : GetTextPointerClippedA(font, font_size, buf, scroll_x, NULL); - const char* text_end = GetTextPointerClippedA(font, font_size, text_start, width + 1, NULL); // +1 to allow character spacing to fit outside the allowed width - window->DrawList->AddText(font, font_size, pos, font_color, text_start, text_end); - - // Log as text - if (GImGui->LogEnabled) - LogText(pos, buf, NULL); -} - -bool ImGui::InputFloat(const char* label, float *v, float step, float step_fast, int decimal_precision, ImGuiInputTextFlags extra_flags) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; - - const ImGuiStyle& style = g.Style; - const float w = ImGui::CalcItemWidth(); - const ImVec2 label_size = CalcTextSize(label, NULL, true); - const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y) + style.FramePadding*2.0f); - - ImGui::BeginGroup(); - ImGui::PushID(label); - const ImVec2 button_sz = ImVec2(g.FontSize, g.FontSize) + style.FramePadding * 2; - if (step > 0.0f) - ImGui::PushItemWidth(ImMax(1.0f, w - (button_sz.x + style.ItemInnerSpacing.x)*2)); - - char buf[64]; - if (decimal_precision < 0) - ImFormatString(buf, IM_ARRAYSIZE(buf), "%f", *v); // Ideally we'd have a minimum decimal precision of 1 to visually denote that it is a float, while hiding non-significant digits? - else - ImFormatString(buf, IM_ARRAYSIZE(buf), "%.*f", decimal_precision, *v); - bool value_changed = false; - const ImGuiInputTextFlags flags = extra_flags | (ImGuiInputTextFlags_CharsDecimal|ImGuiInputTextFlags_AutoSelectAll); - if (ImGui::InputText("", buf, IM_ARRAYSIZE(buf), flags)) - { - ApplyNumericalTextInput(buf, v); - value_changed = true; - } - - // Step buttons - if (step > 0.0f) - { - ImGui::PopItemWidth(); - ImGui::SameLine(0, (int)style.ItemInnerSpacing.x); - if (ImGui::Button("-", button_sz, true)) - { - *v -= g.IO.KeyCtrl && step_fast > 0.0f ? step_fast : step; - value_changed = true; - } - ImGui::SameLine(0, (int)style.ItemInnerSpacing.x); - if (ImGui::Button("+", button_sz, true)) - { - *v += g.IO.KeyCtrl && step_fast > 0.0f ? step_fast : step; - value_changed = true; - } - } - - ImGui::PopID(); - - if (label_size.x > 0) - { - ImGui::SameLine(0, (int)style.ItemInnerSpacing.x); - RenderText(ImVec2(window->DC.CursorPos.x, window->DC.CursorPos.y + style.FramePadding.y), label); - ItemSize(label_size, style.FramePadding.y); - } - - ImGui::EndGroup(); - - return value_changed; -} - -bool ImGui::InputInt(const char* label, int *v, int step, int step_fast, ImGuiInputTextFlags extra_flags) -{ - float f = (float)*v; - const bool value_changed = ImGui::InputFloat(label, &f, (float)step, (float)step_fast, 0, extra_flags); - if (value_changed) - *v = (int)f; - return value_changed; -} - -// Public API to manipulate UTF-8 text -// We expose UTF-8 to the user (unlike the STB_TEXTEDIT_* functions which are manipulating wchar) -void ImGuiTextEditCallbackData::DeleteChars(int pos, int bytes_count) -{ - char* dst = Buf + pos; - const char* src = Buf + pos + bytes_count; - while (char c = *src++) - *dst++ = c; - *dst = '\0'; - - BufDirty = true; - if (CursorPos + bytes_count >= pos) - CursorPos -= bytes_count; - else if (CursorPos >= pos) - CursorPos = pos; - SelectionStart = SelectionEnd = CursorPos; -} - -void ImGuiTextEditCallbackData::InsertChars(int pos, const char* new_text, const char* new_text_end) -{ - const size_t text_len = strlen(Buf); - if (!new_text_end) - new_text_end = new_text + strlen(new_text); - const size_t new_text_len = (size_t)(new_text_end - new_text); - - if (new_text_len + text_len + 1 >= BufSize) - return; - - size_t upos = (size_t)pos; - if (text_len != upos) - memmove(Buf + upos + new_text_len, Buf + upos, text_len - upos); - memcpy(Buf + upos, new_text, new_text_len * sizeof(char)); - Buf[text_len + new_text_len] = '\0'; - - BufDirty = true; - if (CursorPos >= pos) - CursorPos += (int)new_text_len; - SelectionStart = SelectionEnd = CursorPos; -} - -// Return false to discard a character. -static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags flags, ImGuiTextEditCallback callback, void* user_data) -{ - unsigned int c = *p_char; - - if (c < 128 && c != ' ' && !isprint((int)(c & 0xFF))) - return false; - - if (c >= 0xE000 && c <= 0xF8FF) // Filter private Unicode range. I don't imagine anybody would want to input them. GLFW on OSX seems to send private characters for special keys like arrow keys. - return false; - - if (flags & (ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase | ImGuiInputTextFlags_CharsNoBlank)) - { - if (flags & ImGuiInputTextFlags_CharsDecimal) - if (!(c >= '0' && c <= '9') && (c != '.') && (c != '-') && (c != '+') && (c != '*') && (c != '/')) - return false; - - if (flags & ImGuiInputTextFlags_CharsHexadecimal) - if (!(c >= '0' && c <= '9') && !(c >= 'a' && c <= 'f') && !(c >= 'A' && c <= 'F')) - return false; - - if (flags & ImGuiInputTextFlags_CharsUppercase) - if (c >= 'a' && c <= 'z') - *p_char = (c += (unsigned int)('A'-'a')); - - if (flags & ImGuiInputTextFlags_CharsNoBlank) - if (ImCharIsSpace(c)) - return false; - } - - if (flags & ImGuiInputTextFlags_CallbackCharFilter) - { - ImGuiTextEditCallbackData callback_data; - memset(&callback_data, 0, sizeof(ImGuiTextEditCallbackData)); - callback_data.EventFlag = ImGuiInputTextFlags_CallbackCharFilter; - callback_data.EventChar = (ImWchar)c; - callback_data.Flags = flags; - callback_data.UserData = user_data; - if (callback(&callback_data) != 0) - return false; - *p_char = callback_data.EventChar; - if (!callback_data.EventChar) - return false; - } - - return true; -} - -// Edit a string of text -bool ImGui::InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags, ImGuiTextEditCallback callback, void* user_data) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; - - const ImGuiIO& io = g.IO; - const ImGuiStyle& style = g.Style; - - const ImGuiID id = window->GetID(label); - const float w = ImGui::CalcItemWidth(); - - const ImVec2 label_size = CalcTextSize(label, NULL, true); - const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y) + style.FramePadding*2.0f); - const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? (style.ItemInnerSpacing.x + label_size.x) : 0.0f, 0.0f)); - ItemSize(total_bb, style.FramePadding.y); - if (!ItemAdd(total_bb, &id)) - return false; - - // NB: we are only allowed to access 'edit_state' if we are the active widget. - ImGuiTextEditState& edit_state = g.InputTextState; - - const bool is_ctrl_down = io.KeyCtrl; - const bool is_shift_down = io.KeyShift; - const bool focus_requested = window->FocusItemRegister(g.ActiveId == id, (flags & ImGuiInputTextFlags_CallbackCompletion) == 0); // Using completion callback disable keyboard tabbing - const bool focus_requested_by_code = focus_requested && (window->FocusIdxAllCounter == window->FocusIdxAllRequestCurrent); - const bool focus_requested_by_tab = focus_requested && !focus_requested_by_code; - - const bool hovered = IsHovered(frame_bb, id); - if (hovered) - { - g.HoveredId = id; - g.MouseCursor = ImGuiMouseCursor_TextInput; - } - const bool user_clicked = hovered && io.MouseClicked[0]; - - bool select_all = (g.ActiveId != id) && (flags & ImGuiInputTextFlags_AutoSelectAll) != 0; - if (focus_requested || user_clicked) - { - if (g.ActiveId != id) - { - // Start edition - // Take a copy of the initial buffer value (both in original UTF-8 format and converted to wchar) - // From the moment we focused we are ignoring the content of 'buf' - ImFormatString(edit_state.InitialText, IM_ARRAYSIZE(edit_state.InitialText), "%s", buf); - const char* buf_end = NULL; - edit_state.CurLenW = ImTextStrFromUtf8(edit_state.Text, IM_ARRAYSIZE(edit_state.Text), buf, NULL, &buf_end); - edit_state.CurLenA = buf_end - buf; // We can't get the result from ImFormatString() above because it is not UTF-8 aware. Here we'll cut off malformed UTF-8. - edit_state.Width = w + style.FramePadding.x; - edit_state.InputCursorScreenPos = ImVec2(-1.f,-1.f); - edit_state.CursorAnimReset(); - - if (edit_state.Id != id) - { - edit_state.Id = id; - edit_state.ScrollX = 0.0f; - stb_textedit_initialize_state(&edit_state.StbState, true); - if (focus_requested_by_code) - select_all = true; - } - else - { - // Recycle existing cursor/selection/undo stack but clamp position - // Note a single mouse click will override the cursor/position immediately by calling stb_textedit_click handler. - edit_state.StbState.cursor = ImMin(edit_state.StbState.cursor, (int)edit_state.CurLenW); - edit_state.StbState.select_start = ImMin(edit_state.StbState.select_start, (int)edit_state.CurLenW); - edit_state.StbState.select_end = ImMin(edit_state.StbState.select_end, (int)edit_state.CurLenW); - } - if (focus_requested_by_tab || (user_clicked && is_ctrl_down)) - select_all = true; - } - SetActiveId(id); - FocusWindow(window); - } - else if (io.MouseClicked[0]) - { - // Release focus when we click outside - if (g.ActiveId == id) - { - SetActiveId(0); - } - } - - // Although we are active we don't prevent mouse from hovering other elements unless we are interacting right now with the widget. - // Down the line we should have a cleaner concept of focused vs active in the library. - if (g.ActiveId == id) - g.ActiveIdIsFocusedOnly = !io.MouseDown[0]; - - bool value_changed = false; - bool cancel_edit = false; - bool enter_pressed = false; - if (g.ActiveId == id) - //if (edit_state.Id == id) // Works, but double-click to select-all sets cursors to end which in turn tends to scroll toward the right when shrinking widget. - { - // Update some data if we are active or last active - edit_state.Width = w + style.FramePadding.x; - edit_state.BufSizeA = buf_size; - edit_state.Font = g.Font; - edit_state.FontSize = g.FontSize; - edit_state.UpdateScrollOffset(); - } - if (g.ActiveId == id) - { - // Edit in progress - const float mx = g.IO.MousePos.x - frame_bb.Min.x - style.FramePadding.x; - const float my = g.FontSize*0.5f; // Flatten mouse because we are doing a single-line edit - - if (select_all || (hovered && io.MouseDoubleClicked[0])) - { - edit_state.SelectAll(); - edit_state.SelectedAllMouseLock = true; - } - else if (io.MouseClicked[0] && !edit_state.SelectedAllMouseLock) - { - stb_textedit_click(&edit_state, &edit_state.StbState, mx + edit_state.ScrollX, my); - edit_state.CursorAnimReset(); - } - else if (io.MouseDown[0] && !edit_state.SelectedAllMouseLock) - { - stb_textedit_drag(&edit_state, &edit_state.StbState, mx + edit_state.ScrollX, my); - edit_state.CursorAnimReset(); - } - if (edit_state.SelectedAllMouseLock && !io.MouseDown[0]) - edit_state.SelectedAllMouseLock = false; - - if (g.IO.InputCharacters[0]) - { - // Process text input (before we check for Return because using some IME will effectively send a Return?) - for (int n = 0; n < IM_ARRAYSIZE(g.IO.InputCharacters) && g.IO.InputCharacters[n]; n++) - { - unsigned int c = (unsigned int)g.IO.InputCharacters[n]; - if (c) - { - // Insert character if they pass filtering - if (!InputTextFilterCharacter(&c, flags, callback, user_data)) - continue; - edit_state.OnKeyPressed((int)c); - } - } - - // Consume characters - memset(g.IO.InputCharacters, 0, sizeof(g.IO.InputCharacters)); - } - - const int k_mask = (is_shift_down ? STB_TEXTEDIT_K_SHIFT : 0); - if (IsKeyPressedMap(ImGuiKey_LeftArrow)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_WORDLEFT | k_mask : STB_TEXTEDIT_K_LEFT | k_mask); } - else if (IsKeyPressedMap(ImGuiKey_RightArrow)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_WORDRIGHT | k_mask : STB_TEXTEDIT_K_RIGHT | k_mask); } - else if (IsKeyPressedMap(ImGuiKey_Home)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_TEXTSTART | k_mask : STB_TEXTEDIT_K_LINESTART | k_mask); } - else if (IsKeyPressedMap(ImGuiKey_End)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_TEXTEND | k_mask : STB_TEXTEDIT_K_LINEEND | k_mask); } - else if (IsKeyPressedMap(ImGuiKey_Delete)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_DELETE | k_mask); } - else if (IsKeyPressedMap(ImGuiKey_Backspace)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_BACKSPACE | k_mask); } - else if (IsKeyPressedMap(ImGuiKey_Enter)) { SetActiveId(0); enter_pressed = true; } - else if (IsKeyPressedMap(ImGuiKey_Escape)) { SetActiveId(0); cancel_edit = true; } - else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_Z)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_UNDO); } - else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_Y)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_REDO); } - else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_A)) { edit_state.SelectAll(); } - else if (is_ctrl_down && (IsKeyPressedMap(ImGuiKey_X) || IsKeyPressedMap(ImGuiKey_C))) - { - // Cut, Copy - const bool cut = IsKeyPressedMap(ImGuiKey_X); - if (cut && !edit_state.HasSelection()) - edit_state.SelectAll(); - - if (g.IO.SetClipboardTextFn) - { - const int ib = edit_state.HasSelection() ? ImMin(edit_state.StbState.select_start, edit_state.StbState.select_end) : 0; - const int ie = edit_state.HasSelection() ? ImMax(edit_state.StbState.select_start, edit_state.StbState.select_end) : (int)edit_state.CurLenW; - ImTextStrToUtf8(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), edit_state.Text+ib, edit_state.Text+ie); - g.IO.SetClipboardTextFn(g.TempBuffer); - } - - if (cut) - stb_textedit_cut(&edit_state, &edit_state.StbState); - } - else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_V)) - { - // Paste - if (g.IO.GetClipboardTextFn) - { - if (const char* clipboard = g.IO.GetClipboardTextFn()) - { - // Remove new-line from pasted buffer - const size_t clipboard_len = strlen(clipboard); - ImWchar* clipboard_filtered = (ImWchar*)ImGui::MemAlloc((clipboard_len+1) * sizeof(ImWchar)); - int clipboard_filtered_len = 0; - for (const char* s = clipboard; *s; ) - { - unsigned int c; - s += ImTextCharFromUtf8(&c, s, NULL); - if (c == 0) - break; - if (c >= 0x10000) - continue; - if (!InputTextFilterCharacter(&c, flags, callback, user_data)) - continue; - clipboard_filtered[clipboard_filtered_len++] = (ImWchar)c; - } - clipboard_filtered[clipboard_filtered_len] = 0; - if (clipboard_filtered_len > 0) // If everything was filtered, ignore the pasting operation - stb_textedit_paste(&edit_state, &edit_state.StbState, clipboard_filtered, clipboard_filtered_len); - ImGui::MemFree(clipboard_filtered); - } - } - } - - edit_state.CursorAnim += g.IO.DeltaTime; - edit_state.UpdateScrollOffset(); - - if (cancel_edit) - { - // Restore initial value - ImFormatString(buf, buf_size, "%s", edit_state.InitialText); - value_changed = true; - } - else - { - // Apply new value immediately - copy modified buffer back - // Note that as soon as we can focus into the input box, the in-widget value gets priority over any underlying modification of the input buffer - // FIXME: We actually always render 'buf' in RenderTextScrolledClipped - // FIXME-OPT: CPU waste to do this every time the widget is active, should mark dirty state from the stb_textedit callbacks - ImTextStrToUtf8(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), edit_state.Text, NULL); - - // User callback - if ((flags & (ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_CallbackHistory | ImGuiInputTextFlags_CallbackAlways)) != 0) - { - IM_ASSERT(callback != NULL); - - // The reason we specify the usage semantic (Completion/History) is that Completion needs to disable keyboard TABBING at the moment. - ImGuiInputTextFlags event_flag = 0; - ImGuiKey event_key = ImGuiKey_COUNT; - if ((flags & ImGuiInputTextFlags_CallbackCompletion) != 0 && IsKeyPressedMap(ImGuiKey_Tab)) - { - event_flag = ImGuiInputTextFlags_CallbackCompletion; - event_key = ImGuiKey_Tab; - } - else if ((flags & ImGuiInputTextFlags_CallbackHistory) != 0 && IsKeyPressedMap(ImGuiKey_UpArrow)) - { - event_flag = ImGuiInputTextFlags_CallbackHistory; - event_key = ImGuiKey_UpArrow; - } - else if ((flags & ImGuiInputTextFlags_CallbackHistory) != 0 && IsKeyPressedMap(ImGuiKey_DownArrow)) - { - event_flag = ImGuiInputTextFlags_CallbackHistory; - event_key = ImGuiKey_DownArrow; - } - - if (event_key != ImGuiKey_COUNT || (flags & ImGuiInputTextFlags_CallbackAlways) != 0) - { - ImGuiTextEditCallbackData callback_data; - callback_data.EventFlag = event_flag; - callback_data.EventKey = event_key; - callback_data.Buf = g.TempBuffer; - callback_data.BufSize = edit_state.BufSizeA; - callback_data.BufDirty = false; - callback_data.Flags = flags; - callback_data.UserData = user_data; - - // We have to convert from position from wchar to UTF-8 positions - const int utf8_cursor_pos = callback_data.CursorPos = ImTextCountUtf8BytesFromStr(edit_state.Text, edit_state.Text + edit_state.StbState.cursor); - const int utf8_selection_start = callback_data.SelectionStart = ImTextCountUtf8BytesFromStr(edit_state.Text, edit_state.Text + edit_state.StbState.select_start); - const int utf8_selection_end = callback_data.SelectionEnd = ImTextCountUtf8BytesFromStr(edit_state.Text, edit_state.Text + edit_state.StbState.select_end); - - // Call user code - callback(&callback_data); - - // Read back what user may have modified - IM_ASSERT(callback_data.Buf == g.TempBuffer); // Invalid to modify those fields - IM_ASSERT(callback_data.BufSize == edit_state.BufSizeA); - IM_ASSERT(callback_data.Flags == flags); - if (callback_data.CursorPos != utf8_cursor_pos) edit_state.StbState.cursor = ImTextCountCharsFromUtf8(callback_data.Buf, callback_data.Buf + callback_data.CursorPos); - if (callback_data.SelectionStart != utf8_selection_start) edit_state.StbState.select_start = ImTextCountCharsFromUtf8(callback_data.Buf, callback_data.Buf + callback_data.SelectionStart); - if (callback_data.SelectionEnd != utf8_selection_end) edit_state.StbState.select_end = ImTextCountCharsFromUtf8(callback_data.Buf, callback_data.Buf + callback_data.SelectionEnd); - if (callback_data.BufDirty) - { - ImTextStrFromUtf8(edit_state.Text, IM_ARRAYSIZE(edit_state.Text), g.TempBuffer, NULL); - edit_state.CursorAnimReset(); - } - } - } - - if (strcmp(g.TempBuffer, buf) != 0) - { - ImFormatString(buf, buf_size, "%s", g.TempBuffer); - value_changed = true; - } - } - } - - RenderFrame(frame_bb.Min, frame_bb.Max, window->Color(ImGuiCol_FrameBg), true, style.FrameRounding); - - const ImVec2 font_off_up = ImVec2(0.0f, g.FontSize+1.0f); // FIXME: those offsets are part of the style or font API - const ImVec2 font_off_dn = ImVec2(0.0f, 2.0f); - - if (g.ActiveId == id) - { - // Draw selection - const int select_begin_idx = edit_state.StbState.select_start; - const int select_end_idx = edit_state.StbState.select_end; - if (select_begin_idx != select_end_idx) - { - const ImVec2 select_begin_pos = frame_bb.Min + style.FramePadding + edit_state.CalcDisplayOffsetFromCharIdx(ImMin(select_begin_idx,select_end_idx)); - const ImVec2 select_end_pos = frame_bb.Min + style.FramePadding + edit_state.CalcDisplayOffsetFromCharIdx(ImMax(select_begin_idx,select_end_idx)); - window->DrawList->AddRectFilled(select_begin_pos - font_off_up, select_end_pos + font_off_dn, window->Color(ImGuiCol_TextSelectedBg)); - } - } - - //const float render_scroll_x = (g.ActiveId == id) ? edit_state.ScrollX : 0.0f; - const float render_scroll_x = (edit_state.Id == id) ? edit_state.ScrollX : 0.0f; - ImGuiTextEditState::RenderTextScrolledClipped(g.Font, g.FontSize, buf, frame_bb.Min + style.FramePadding, w + style.FramePadding.x, render_scroll_x); - - if (g.ActiveId == id) - { - const ImVec2 cursor_pos = frame_bb.Min + style.FramePadding + edit_state.CalcDisplayOffsetFromCharIdx(edit_state.StbState.cursor); - - // Draw blinking cursor - if (g.InputTextState.CursorIsVisible()) - window->DrawList->AddRect(cursor_pos - font_off_up + ImVec2(0,2), cursor_pos + font_off_dn - ImVec2(0,3), window->Color(ImGuiCol_Text)); - - // Notify OS of text input position for advanced IME - if (io.ImeSetInputScreenPosFn && ImLengthSqr(edit_state.InputCursorScreenPos - cursor_pos) > 0.0001f) - io.ImeSetInputScreenPosFn((int)cursor_pos.x - 1, (int)(cursor_pos.y - g.FontSize)); // -1 x offset so that Windows IME can cover our cursor. Bit of an extra nicety. - - edit_state.InputCursorScreenPos = cursor_pos; - } - - if (label_size.x > 0) - RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); - - if ((flags & ImGuiInputTextFlags_EnterReturnsTrue) != 0) - return enter_pressed; - else - return value_changed; -} - -static bool InputFloatN(const char* label, float* v, int components, int decimal_precision) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; - - const ImGuiStyle& style = g.Style; - const float w_full = ImGui::CalcItemWidth(); - const float w_item_one = ImMax(1.0f, (float)(int)((w_full - (style.FramePadding.x*2.0f + style.ItemInnerSpacing.x) * (components-1)) / (float)components)); - const float w_item_last = ImMax(1.0f, (float)(int)(w_full - (w_item_one + style.FramePadding.x*2.0f + style.ItemInnerSpacing.x) * (components-1))); - - bool value_changed = false; - ImGui::BeginGroup(); - ImGui::PushID(label); - ImGui::PushItemWidth(w_item_one); - for (int i = 0; i < components; i++) - { - ImGui::PushID(i); - if (i + 1 == components) - { - ImGui::PopItemWidth(); - ImGui::PushItemWidth(w_item_last); - } - value_changed |= ImGui::InputFloat("##v", &v[i], 0, 0, decimal_precision); - ImGui::SameLine(0, (int)style.ItemInnerSpacing.x); - ImGui::PopID(); - } - ImGui::PopItemWidth(); - ImGui::PopID(); - - window->DC.CurrentLineTextBaseOffset = ImMax(window->DC.CurrentLineTextBaseOffset, style.FramePadding.y); - ImGui::TextUnformatted(label, FindTextDisplayEnd(label)); - ImGui::EndGroup(); - - return value_changed; -} - -bool ImGui::InputFloat2(const char* label, float v[2], int decimal_precision) -{ - return InputFloatN(label, v, 2, decimal_precision); -} - -bool ImGui::InputFloat3(const char* label, float v[3], int decimal_precision) -{ - return InputFloatN(label, v, 3, decimal_precision); -} - -bool ImGui::InputFloat4(const char* label, float v[4], int decimal_precision) -{ - return InputFloatN(label, v, 4, decimal_precision); -} - -static bool InputIntN(const char* label, int* v, int components) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; - - const ImGuiStyle& style = g.Style; - const float w_full = ImGui::CalcItemWidth(); - const float w_item_one = ImMax(1.0f, (float)(int)((w_full - (style.FramePadding.x*2.0f + style.ItemInnerSpacing.x) * (components-1)) / (float)components)); - const float w_item_last = ImMax(1.0f, (float)(int)(w_full - (w_item_one + style.FramePadding.x*2.0f + style.ItemInnerSpacing.x) * (components-1))); - - bool value_changed = false; - ImGui::BeginGroup(); - ImGui::PushID(label); - ImGui::PushItemWidth(w_item_one); - for (int i = 0; i < components; i++) - { - ImGui::PushID(i); - if (i + 1 == components) - { - ImGui::PopItemWidth(); - ImGui::PushItemWidth(w_item_last); - } - value_changed |= ImGui::InputInt("##v", &v[i], 0, 0); - ImGui::SameLine(0, (int)style.ItemInnerSpacing.x); - ImGui::PopID(); - } - ImGui::PopItemWidth(); - ImGui::PopID(); - - window->DC.CurrentLineTextBaseOffset = ImMax(window->DC.CurrentLineTextBaseOffset, style.FramePadding.y); - ImGui::TextUnformatted(label, FindTextDisplayEnd(label)); - ImGui::EndGroup(); - - return value_changed; -} - -bool ImGui::InputInt2(const char* label, int v[2]) -{ - return InputIntN(label, v, 2); -} - -bool ImGui::InputInt3(const char* label, int v[3]) -{ - return InputIntN(label, v, 3); -} - -bool ImGui::InputInt4(const char* label, int v[4]) -{ - return InputIntN(label, v, 4); -} - -static bool Items_ArrayGetter(void* data, int idx, const char** out_text) -{ - const char** items = (const char**)data; - if (out_text) - *out_text = items[idx]; - return true; -} - -static bool Items_SingleStringGetter(void* data, int idx, const char** out_text) -{ - // FIXME-OPT: we could pre-compute the indices to fasten this. But only 1 active combo means the waste is limited. - const char* items_separated_by_zeros = (const char*)data; - int items_count = 0; - const char* p = items_separated_by_zeros; - while (*p) - { - if (idx == items_count) - break; - p += strlen(p) + 1; - items_count++; - } - if (!*p) - return false; - if (out_text) - *out_text = p; - return true; -} - -// Combo box helper allowing to pass an array of strings. -bool ImGui::Combo(const char* label, int* current_item, const char** items, int items_count, int height_in_items) -{ - const bool value_changed = Combo(label, current_item, Items_ArrayGetter, (void*)items, items_count, height_in_items); - return value_changed; -} - -// Combo box helper allowing to pass all items in a single string. -bool ImGui::Combo(const char* label, int* current_item, const char* items_separated_by_zeros, int height_in_items) -{ - int items_count = 0; - const char* p = items_separated_by_zeros; // FIXME-OPT: Avoid computing this - while (*p) - { - p += strlen(p) + 1; - items_count++; - } - bool value_changed = Combo(label, current_item, Items_SingleStringGetter, (void*)items_separated_by_zeros, items_count, height_in_items); - return value_changed; -} - -// Combo box function. -bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(void*, int, const char**), void* data, int items_count, int height_in_items) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; - - const ImGuiStyle& style = g.Style; - const ImGuiID id = window->GetID(label); - const float w = ImGui::CalcItemWidth(); - - const ImVec2 label_size = CalcTextSize(label, NULL, true); - const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y) + style.FramePadding*2.0f); - const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(style.ItemInnerSpacing.x + label_size.x,0)); - ItemSize(total_bb, style.FramePadding.y); - if (!ItemAdd(total_bb, &id)) - return false; - - const float arrow_size = (g.FontSize + style.FramePadding.x * 2.0f); - const bool hovered = IsHovered(frame_bb, id); - - bool value_changed = false; - const ImRect value_bb(frame_bb.Min, frame_bb.Max - ImVec2(arrow_size, 0.0f)); - RenderFrame(frame_bb.Min, frame_bb.Max, window->Color(ImGuiCol_FrameBg), true, style.FrameRounding); - RenderFrame(ImVec2(frame_bb.Max.x-arrow_size, frame_bb.Min.y), frame_bb.Max, window->Color(hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button), true, style.FrameRounding); // FIXME-ROUNDING - RenderCollapseTriangle(ImVec2(frame_bb.Max.x-arrow_size, frame_bb.Min.y) + style.FramePadding, true); - - if (*current_item >= 0 && *current_item < items_count) - { - const char* item_text; - if (items_getter(data, *current_item, &item_text)) - RenderTextClipped(frame_bb.Min + style.FramePadding, item_text, NULL, NULL, value_bb.Max); - } - - if (label_size.x > 0) - RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); - - ImGui::PushID((int)id); - bool menu_toggled = false; - if (hovered) - { - g.HoveredId = id; - if (g.IO.MouseClicked[0]) - { - menu_toggled = true; - g.ActiveComboID = (g.ActiveComboID == id) ? 0 : id; - if (g.ActiveComboID) - FocusWindow(window); - } - } - - if (g.ActiveComboID == id) - { - // Size default to hold ~7 items - if (height_in_items < 0) - height_in_items = 7; - - const ImVec2 backup_pos = ImGui::GetCursorPos(); - const float popup_off_x = 0.0f;//style.ItemInnerSpacing.x; - const float popup_height = (label_size.y + style.ItemSpacing.y) * ImMin(items_count, height_in_items) + (style.FramePadding.y * 3); - const ImRect popup_rect(ImVec2(frame_bb.Min.x+popup_off_x, frame_bb.Max.y), ImVec2(frame_bb.Max.x+popup_off_x, frame_bb.Max.y + popup_height)); - ImGui::SetCursorPos(popup_rect.Min - window->Pos); - - const ImGuiWindowFlags flags = ImGuiWindowFlags_ComboBox | ((window->Flags & ImGuiWindowFlags_ShowBorders) ? ImGuiWindowFlags_ShowBorders : 0); - ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, style.FramePadding); - ImGui::BeginChild("#ComboBox", popup_rect.GetSize(), false, flags); - ImGui::Spacing(); - - bool combo_item_active = false; - combo_item_active |= (g.ActiveId == GetCurrentWindow()->GetID("#SCROLLY")); - - // Display items - for (int i = 0; i < items_count; i++) - { - ImGui::PushID((void*)(intptr_t)i); - const bool item_selected = (i == *current_item); - const char* item_text; - if (!items_getter(data, i, &item_text)) - item_text = "*Unknown item*"; - if (ImGui::Selectable(item_text, item_selected)) - { - SetActiveId(0); - g.ActiveComboID = 0; - value_changed = true; - *current_item = i; - } - if (item_selected && menu_toggled) - ImGui::SetScrollPosHere(); - combo_item_active |= ImGui::IsItemActive(); - ImGui::PopID(); - } - ImGui::EndChild(); - ImGui::PopStyleVar(); - ImGui::SetCursorPos(backup_pos); - - if (!combo_item_active && g.ActiveId != 0) - g.ActiveComboID = 0; - } - - ImGui::PopID(); - - return value_changed; -} - -// Tip: pass an empty label (e.g. "##dummy") then you can use the space to draw other text or image. -// But you need to make sure the ID is unique, e.g. enclose calls in PushID/PopID. -bool ImGui::Selectable(const char* label, bool selected, const ImVec2& size_arg) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; - - const ImGuiStyle& style = g.Style; - const ImGuiID id = window->GetID(label); - const ImVec2 label_size = CalcTextSize(label, NULL, true); - - const float w = ImMax(label_size.x, window->Pos.x + ImGui::GetContentRegionMax().x - style.AutoFitPadding.x - window->DC.CursorPos.x); - const ImVec2 size(size_arg.x != 0.0f ? size_arg.x : w, size_arg.y != 0.0f ? size_arg.y : label_size.y); - ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); - ItemSize(bb); - if (size_arg.x == 0.0f) - bb.Max.x += style.AutoFitPadding.x; - - // Selectables are meant to be tightly packed together. So for both rendering and collision we extend to compensate for spacing. - ImRect bb_with_spacing = bb; - const float spacing_L = (float)(int)(style.ItemSpacing.x * 0.5f); - const float spacing_U = (float)(int)(style.ItemSpacing.y * 0.5f); - const float spacing_R = style.ItemSpacing.x - spacing_L; - const float spacing_D = style.ItemSpacing.y - spacing_U; - bb_with_spacing.Min.x -= spacing_L; - bb_with_spacing.Min.y -= spacing_U; - bb_with_spacing.Max.x += spacing_R; - bb_with_spacing.Max.y += spacing_D; - if (!ItemAdd(bb_with_spacing, &id)) - return false; - - bool hovered, held; - bool pressed = ButtonBehavior(bb_with_spacing, id, &hovered, &held, true, false, false); - - // Render - if (hovered || selected) - { - const ImU32 col = window->Color((held && hovered) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header); - RenderFrame(bb_with_spacing.Min, bb_with_spacing.Max, col, false, style.FrameRounding); - } - - //const ImVec2 off = ImVec2(ImMax(0.0f, size.x - text_size.x) * 0.5f, ImMax(0.0f, size.y - text_size.y) * 0.5f); - RenderTextClipped(bb.Min, label, NULL, &label_size, bb_with_spacing.Max); - - return pressed; -} - -bool ImGui::Selectable(const char* label, bool* p_selected, const ImVec2& size_arg) -{ - if (ImGui::Selectable(label, *p_selected, size_arg)) - { - *p_selected = !*p_selected; - return true; - } - return false; -} - -// Helper to calculate the size of a listbox and display a label on the right. -// Tip: To have a list filling the entire window width, PushItemWidth(-1) and pass an empty label "##empty" -bool ImGui::ListBoxHeader(const char* label, const ImVec2& size_arg) -{ - ImGuiWindow* window = GetCurrentWindow(); - - const ImGuiStyle& style = ImGui::GetStyle(); - const ImGuiID id = ImGui::GetID(label); - const ImVec2 label_size = ImGui::CalcTextSize(label, NULL, true); - - // Size default to hold ~7 items. Fractional number of items helps seeing that we can scroll down/up without looking at scrollbar. - ImVec2 size; - size.x = (size_arg.x != 0.0f) ? (size_arg.x) : ImGui::CalcItemWidth() + style.FramePadding.x * 2.0f; - size.y = (size_arg.y != 0.0f) ? (size_arg.y) : ImGui::GetTextLineHeightWithSpacing() * 7.4f + style.ItemSpacing.y; - const ImVec2 frame_size = ImVec2(size.x, ImMax(size.y, label_size.y)); - const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + frame_size); - const ImRect bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f)); - window->DC.LastItemRect = bb; - - ImGui::BeginGroup(); - if (label_size.x > 0) - RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); - - ImGui::BeginChildFrame(id, frame_bb.GetSize()); - return true; -} - -bool ImGui::ListBoxHeader(const char* label, int items_count, int height_in_items) -{ - // Size default to hold ~7 items. Fractional number of items helps seeing that we can scroll down/up without looking at scrollbar. - // However we don't add +0.40f if items_count <= height_in_items. It is slightly dodgy, because it means a dynamic list of items will make the widget resize occasionally when it crosses that size. - // I am expecting that someone will come and complain about this behavior in a remote future, then we can advise on a better solution. - if (height_in_items < 0) - height_in_items = ImMin(items_count, 7); - float height_in_items_f = height_in_items < items_count ? (height_in_items + 0.40f) : (height_in_items + 0.00f); - - // We include ItemSpacing.y so that a list sized for the exact number of items doesn't make a scrollbar appears. We could also enforce that by passing a flag to BeginChild(). - ImVec2 size; - size.x = 0.0f; - size.y = ImGui::GetTextLineHeightWithSpacing() * height_in_items_f + ImGui::GetStyle().ItemSpacing.y; - return ImGui::ListBoxHeader(label, size); -} - -void ImGui::ListBoxFooter() -{ - ImGuiWindow* parent_window = GetParentWindow(); - const ImRect bb = parent_window->DC.LastItemRect; - const ImGuiStyle& style = ImGui::GetStyle(); - - ImGui::EndChildFrame(); - - // Redeclare item size so that it includes the label (we have stored the full size in LastItemRect) - // We call SameLine() to restore DC.CurrentLine* data - ImGui::SameLine(); - parent_window->DC.CursorPos = bb.Min; - ItemSize(bb, style.FramePadding.y); - ImGui::EndGroup(); -} - -bool ImGui::ListBox(const char* label, int* current_item, const char** items, int items_count, int height_items) -{ - const bool value_changed = ListBox(label, current_item, Items_ArrayGetter, (void*)items, items_count, height_items); - return value_changed; -} - -bool ImGui::ListBox(const char* label, int* current_item, bool (*items_getter)(void*, int, const char**), void* data, int items_count, int height_in_items) -{ - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; - - if (!ImGui::ListBoxHeader(label, items_count, height_in_items)) - return false; - - bool value_changed = false; - for (int i = 0; i < items_count; i++) - { - const bool item_selected = (i == *current_item); - const char* item_text; - if (!items_getter(data, i, &item_text)) - item_text = "*Unknown item*"; - - ImGui::PushID(i); - if (ImGui::Selectable(item_text, item_selected)) - { - *current_item = i; - value_changed = true; - } - ImGui::PopID(); - } - - ImGui::ListBoxFooter(); - return value_changed; -} - -// A little colored square. Return true when clicked. -bool ImGui::ColorButton(const ImVec4& col, bool small_height, bool outline_border) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; - - const ImGuiStyle& style = g.Style; - const ImGuiID id = window->GetID("#colorbutton"); - const float square_size = g.FontSize; - const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(square_size + style.FramePadding.x*2, square_size + (small_height ? 0 : style.FramePadding.y*2))); - ItemSize(bb, small_height ? 0.0f : style.FramePadding.y); - if (!ItemAdd(bb, &id)) - return false; - - bool hovered, held; - bool pressed = ButtonBehavior(bb, id, &hovered, &held, true); - RenderFrame(bb.Min, bb.Max, window->Color(col), outline_border, style.FrameRounding); - - if (hovered) - { - int ix = (int)(col.x * 255.0f + 0.5f); - int iy = (int)(col.y * 255.0f + 0.5f); - int iz = (int)(col.z * 255.0f + 0.5f); - int iw = (int)(col.w * 255.0f + 0.5f); - ImGui::SetTooltip("Color:\n(%.2f,%.2f,%.2f,%.2f)\n#%02X%02X%02X%02X", col.x, col.y, col.z, col.w, ix, iy, iz, iw); - } - - return pressed; -} - -bool ImGui::ColorEdit3(const char* label, float col[3]) -{ - float col4[4]; - col4[0] = col[0]; - col4[1] = col[1]; - col4[2] = col[2]; - col4[3] = 1.0f; - const bool value_changed = ImGui::ColorEdit4(label, col4, false); - col[0] = col4[0]; - col[1] = col4[1]; - col[2] = col4[2]; - return value_changed; -} - -// Edit colors components (each component in 0.0f..1.0f range -// Use CTRL-Click to input value and TAB to go to next item. -bool ImGui::ColorEdit4(const char* label, float col[4], bool alpha) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; - - const ImGuiStyle& style = g.Style; - const ImGuiID id = window->GetID(label); - const float w_full = ImGui::CalcItemWidth(); - const float square_sz = (g.FontSize + style.FramePadding.x * 2.0f); - - ImGuiColorEditMode edit_mode = window->DC.ColorEditMode; - if (edit_mode == ImGuiColorEditMode_UserSelect || edit_mode == ImGuiColorEditMode_UserSelectShowButton) - edit_mode = g.ColorEditModeStorage.GetInt(id, 0) % 3; - - float f[4] = { col[0], col[1], col[2], col[3] }; - - if (edit_mode == ImGuiColorEditMode_HSV) - ImGui::ColorConvertRGBtoHSV(f[0], f[1], f[2], f[0], f[1], f[2]); - - int i[4] = { (int)(f[0] * 255.0f + 0.5f), (int)(f[1] * 255.0f + 0.5f), (int)(f[2] * 255.0f + 0.5f), (int)(f[3] * 255.0f + 0.5f) }; - - int components = alpha ? 4 : 3; - bool value_changed = false; - - ImGui::BeginGroup(); - ImGui::PushID(label); - - const bool hsv = (edit_mode == 1); - switch (edit_mode) - { - case ImGuiColorEditMode_RGB: - case ImGuiColorEditMode_HSV: - { - // RGB/HSV 0..255 Sliders - const float w_items_all = w_full - (square_sz + style.ItemInnerSpacing.x); - const float w_item_one = ImMax(1.0f, (float)(int)((w_items_all - (style.FramePadding.x*2.0f + style.ItemInnerSpacing.x) * (components-1)) / (float)components)); - const float w_item_last = ImMax(1.0f, (float)(int)(w_items_all - (w_item_one + style.FramePadding.x*2.0f + style.ItemInnerSpacing.x) * (components-1))); - - const bool hide_prefix = (w_item_one <= CalcTextSize("M:999").x); - const char* ids[4] = { "##X", "##Y", "##Z", "##W" }; - const char* fmt_table[3][4] = - { - { "%3.0f", "%3.0f", "%3.0f", "%3.0f" }, - { "R:%3.0f", "G:%3.0f", "B:%3.0f", "A:%3.0f" }, - { "H:%3.0f", "S:%3.0f", "V:%3.0f", "A:%3.0f" } - }; - const char** fmt = hide_prefix ? fmt_table[0] : hsv ? fmt_table[2] : fmt_table[1]; - - ImGui::PushItemWidth(w_item_one); - for (int n = 0; n < components; n++) - { - if (n > 0) - ImGui::SameLine(0, (int)style.ItemInnerSpacing.x); - if (n + 1 == components) - ImGui::PushItemWidth(w_item_last); - value_changed |= ImGui::DragInt(ids[n], &i[n], 1.0f, 0, 255, fmt[n]); - } - ImGui::PopItemWidth(); - ImGui::PopItemWidth(); - } - break; - case ImGuiColorEditMode_HEX: - { - // RGB Hexadecimal Input - const float w_slider_all = w_full - square_sz; - char buf[64]; - if (alpha) - ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X%02X", i[0], i[1], i[2], i[3]); - else - ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X", i[0], i[1], i[2]); - ImGui::PushItemWidth(w_slider_all - style.ItemInnerSpacing.x); - value_changed |= ImGui::InputText("##Text", buf, IM_ARRAYSIZE(buf), ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase); - ImGui::PopItemWidth(); - char* p = buf; - while (*p == '#' || ImCharIsSpace(*p)) - p++; - - // Treat at unsigned (%X is unsigned) - i[0] = i[1] = i[2] = i[3] = 0; - if (alpha) - sscanf(p, "%02X%02X%02X%02X", (unsigned int*)&i[0], (unsigned int*)&i[1], (unsigned int*)&i[2], (unsigned int*)&i[3]); - else - sscanf(p, "%02X%02X%02X", (unsigned int*)&i[0], (unsigned int*)&i[1], (unsigned int*)&i[2]); - } - break; - } - - ImGui::SameLine(0, (int)style.ItemInnerSpacing.x); - - const ImVec4 col_display(col[0], col[1], col[2], 1.0f); - if (ImGui::ColorButton(col_display)) - g.ColorEditModeStorage.SetInt(id, (edit_mode + 1) % 3); // Don't set local copy of 'edit_mode' right away! - - if (window->DC.ColorEditMode == ImGuiColorEditMode_UserSelectShowButton) - { - ImGui::SameLine(0, (int)style.ItemInnerSpacing.x); - const char* button_titles[3] = { "RGB", "HSV", "HEX" }; - if (ImGui::Button(button_titles[edit_mode])) - g.ColorEditModeStorage.SetInt(id, (edit_mode + 1) % 3); // Don't set local copy of 'edit_mode' right away! - ImGui::SameLine(); - } - else - { - ImGui::SameLine(0, (int)style.ItemInnerSpacing.x); - } - - ImGui::TextUnformatted(label, FindTextDisplayEnd(label)); - - // Convert back - for (int n = 0; n < 4; n++) - f[n] = i[n] / 255.0f; - if (edit_mode == 1) - ImGui::ColorConvertHSVtoRGB(f[0], f[1], f[2], f[0], f[1], f[2]); - - if (value_changed) - { - col[0] = f[0]; - col[1] = f[1]; - col[2] = f[2]; - if (alpha) - col[3] = f[3]; - } - - ImGui::PopID(); - ImGui::EndGroup(); - - return value_changed; -} - -void ImGui::ColorEditMode(ImGuiColorEditMode mode) -{ - ImGuiWindow* window = GetCurrentWindow(); - window->DC.ColorEditMode = mode; -} - -// Horizontal separating line. -void ImGui::Separator() -{ - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return; - - if (window->DC.ColumnsCount > 1) - PopClipRect(); - - const ImRect bb(ImVec2(window->Pos.x, window->DC.CursorPos.y), ImVec2(window->Pos.x + window->Size.x, window->DC.CursorPos.y)); - ItemSize(ImVec2(0.0f, bb.GetSize().y)); // NB: we don't provide our width so that it doesn't get feed back into AutoFit - if (!ItemAdd(bb, NULL)) - { - if (window->DC.ColumnsCount > 1) - PushColumnClipRect(); - return; - } - - window->DrawList->AddLine(bb.Min, bb.Max, window->Color(ImGuiCol_Border)); - - ImGuiState& g = *GImGui; - if (g.LogEnabled) - ImGui::LogText(STR_NEWLINE "--------------------------------"); - - if (window->DC.ColumnsCount > 1) - { - PushColumnClipRect(); - window->DC.ColumnsCellMinY = window->DC.CursorPos.y; - } -} - -// A little vertical spacing. -void ImGui::Spacing() -{ - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return; - - ItemSize(ImVec2(0,0)); -} - -// Advance cursor given item size. -static void ItemSize(ImVec2 size, float text_offset_y) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return; - - // Always align ourselves on pixel boundaries - const float line_height = ImMax(window->DC.CurrentLineHeight, size.y); - const float text_base_offset = ImMax(window->DC.CurrentLineTextBaseOffset, text_offset_y); - window->DC.CursorPosPrevLine = ImVec2(window->DC.CursorPos.x + size.x, window->DC.CursorPos.y); - window->DC.CursorPos = ImVec2((float)(int)(window->Pos.x + window->DC.ColumnsStartX + window->DC.ColumnsOffsetX), (float)(int)(window->DC.CursorPos.y + line_height + g.Style.ItemSpacing.y)); - window->DC.CursorMaxPos.x = ImMax(window->DC.CursorMaxPos.x, window->DC.CursorPosPrevLine.x); - window->DC.CursorMaxPos.y = ImMax(window->DC.CursorMaxPos.y, window->DC.CursorPos.y); - - //window->DrawList->AddCircle(window->DC.CursorMaxPos, 3.0f, 0xFF0000FF, 4); // Debug - - window->DC.PrevLineHeight = line_height; - window->DC.PrevLineTextBaseOffset = text_base_offset; - window->DC.CurrentLineHeight = window->DC.CurrentLineTextBaseOffset = 0.0f; -} - -static inline void ItemSize(const ImRect& bb, float text_offset_y) -{ - ItemSize(bb.GetSize(), text_offset_y); -} - -static bool IsClippedEx(const ImRect& bb, const ImGuiID* id, bool clip_even_when_logged) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - - if (!bb.Overlaps(ImRect(window->ClipRectStack.back()))) - { - if (!id || *id != GImGui->ActiveId) - if (clip_even_when_logged || !g.LogEnabled) - return true; - } - return false; -} - -bool ImGui::IsRectClipped(const ImVec2& size) -{ - ImGuiWindow* window = GetCurrentWindow(); - return IsClippedEx(ImRect(window->DC.CursorPos, window->DC.CursorPos + size), NULL, true); -} - -static bool ItemAdd(const ImRect& bb, const ImGuiID* id) -{ - ImGuiWindow* window = GetCurrentWindow(); - window->DC.LastItemID = id ? *id : 0; - window->DC.LastItemRect = bb; - if (IsClippedEx(bb, id, false)) - { - window->DC.LastItemHoveredAndUsable = window->DC.LastItemHoveredRect = false; - return false; - } - - // This is a sensible default, but widgets are free to override it after calling ItemAdd() - ImGuiState& g = *GImGui; - if (IsMouseHoveringRect(bb)) - { - // Matching the behavior of IsHovered() but ignore if ActiveId==window->MoveID (we clicked on the window background) - // So that clicking on items with no active id such as Text() still returns true with IsItemHovered() - window->DC.LastItemHoveredRect = true; - window->DC.LastItemHoveredAndUsable = false; - if (g.HoveredRootWindow == window->RootWindow) - if (g.ActiveId == 0 || (id && g.ActiveId == *id) || g.ActiveIdIsFocusedOnly || (g.ActiveId == window->MoveID)) - if (IsWindowContentHoverable(window)) - window->DC.LastItemHoveredAndUsable = true; - } - else - { - window->DC.LastItemHoveredAndUsable = window->DC.LastItemHoveredRect = false; - } - - return true; -} - -void ImGui::BeginGroup() -{ - ImGuiWindow* window = GetCurrentWindow(); - - window->DC.GroupStack.resize(window->DC.GroupStack.size() + 1); - ImGuiGroupData& group_data = window->DC.GroupStack.back(); - group_data.BackupCursorPos = window->DC.CursorPos; - group_data.BackupCursorMaxPos = window->DC.CursorMaxPos; - group_data.BackupColumnsStartX = window->DC.ColumnsStartX; - group_data.BackupCurrentLineHeight = window->DC.CurrentLineHeight; - group_data.BackupCurrentLineTextBaseOffset = window->DC.CurrentLineTextBaseOffset; - group_data.BackupLogLinePosY = window->DC.LogLinePosY; - - window->DC.ColumnsStartX = window->DC.CursorPos.x - window->Pos.x; - window->DC.CursorMaxPos = window->DC.CursorPos; - window->DC.CurrentLineHeight = 0.0f; - window->DC.LogLinePosY = window->DC.CursorPos.y - 9999.0f; -} - -void ImGui::EndGroup() -{ - ImGuiWindow* window = GetCurrentWindow(); - ImGuiStyle& style = ImGui::GetStyle(); - - IM_ASSERT(!window->DC.GroupStack.empty()); - - ImGuiGroupData& group_data = window->DC.GroupStack.back(); - - ImRect group_bb(group_data.BackupCursorPos, window->DC.CursorMaxPos); - group_bb.Max.y -= style.ItemSpacing.y; // Cancel out last vertical spacing because we are adding one ourselves. - group_bb.Max = ImMax(group_bb.Min, group_bb.Max); - - window->DC.CursorPos = group_data.BackupCursorPos; - window->DC.CursorMaxPos = ImMax(group_data.BackupCursorMaxPos, window->DC.CursorMaxPos); - window->DC.CurrentLineHeight = group_data.BackupCurrentLineHeight; - window->DC.CurrentLineTextBaseOffset = group_data.BackupCurrentLineTextBaseOffset; // FIXME: Ideally we'll grab the base offset from the first line of the group. - window->DC.ColumnsStartX = group_data.BackupColumnsStartX; - window->DC.LogLinePosY = window->DC.CursorPos.y - 9999.0f; - - ItemSize(group_bb.GetSize(), group_data.BackupCurrentLineTextBaseOffset); - ItemAdd(group_bb, NULL); - - window->DC.GroupStack.pop_back(); - - //window->DrawList->AddRect(group_bb.Min, group_bb.Max, 0xFFFF00FF); // Debug -} - -// Gets back to previous line and continue with horizontal layout -// column_x == 0 : follow on previous item -// columm_x != 0 : align to specified column -// spacing_w < 0 : use default spacing if column_x==0, no spacing if column_x!=0 -// spacing_w >= 0 : enforce spacing -void ImGui::SameLine(int column_x, int spacing_w) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return; - - float x, y; - if (column_x != 0) - { - if (spacing_w < 0) spacing_w = 0; - x = window->Pos.x + (float)column_x + (float)spacing_w; - y = window->DC.CursorPosPrevLine.y; - } - else - { - if (spacing_w < 0) spacing_w = (int)g.Style.ItemSpacing.x; - x = window->DC.CursorPosPrevLine.x + (float)spacing_w; - y = window->DC.CursorPosPrevLine.y; - } - window->DC.CurrentLineHeight = window->DC.PrevLineHeight; - window->DC.CurrentLineTextBaseOffset = window->DC.PrevLineTextBaseOffset; - window->DC.CursorPos = ImVec2(x, y); -} - -void ImGui::NextColumn() -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return; - - if (window->DC.ColumnsCount > 1) - { - ImGui::PopItemWidth(); - PopClipRect(); - - window->DC.ColumnsCellMaxY = ImMax(window->DC.ColumnsCellMaxY, window->DC.CursorPos.y); - if (++window->DC.ColumnsCurrent < window->DC.ColumnsCount) - { - window->DC.ColumnsOffsetX = ImGui::GetColumnOffset(window->DC.ColumnsCurrent) - window->DC.ColumnsStartX + g.Style.ItemSpacing.x; - } - else - { - window->DC.ColumnsCurrent = 0; - window->DC.ColumnsOffsetX = 0.0f; - window->DC.ColumnsCellMinY = window->DC.ColumnsCellMaxY; - } - window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.ColumnsStartX + window->DC.ColumnsOffsetX); - window->DC.CursorPos.y = window->DC.ColumnsCellMinY; - window->DC.CurrentLineHeight = 0.0f; - window->DC.CurrentLineTextBaseOffset = 0.0f; - - PushColumnClipRect(); - ImGui::PushItemWidth(ImGui::GetColumnWidth() * 0.65f); // FIXME - } -} - -int ImGui::GetColumnIndex() -{ - ImGuiWindow* window = GetCurrentWindow(); - return window->DC.ColumnsCurrent; -} - -int ImGui::GetColumnsCount() -{ - ImGuiWindow* window = GetCurrentWindow(); - return window->DC.ColumnsCount; -} - -static float GetDraggedColumnOffset(int column_index) -{ - // Active (dragged) column always follow mouse. The reason we need this is that dragging a column to the right edge of an auto-resizing - // window creates a feedback loop because we store normalized positions/ So while dragging we enforce absolute positioning - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - IM_ASSERT(g.ActiveId == window->DC.ColumnsSetID + ImGuiID(column_index)); - - float x = g.IO.MousePos.x + g.ActiveClickDeltaToCenter.x; - x -= window->Pos.x; - x = ImClamp(x, ImGui::GetColumnOffset(column_index-1)+g.Style.ColumnsMinSpacing, ImGui::GetColumnOffset(column_index+1)-g.Style.ColumnsMinSpacing); - - return x; -} - -float ImGui::GetColumnOffset(int column_index) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - if (column_index < 0) - column_index = window->DC.ColumnsCurrent; - - if (g.ActiveId) - { - const ImGuiID column_id = window->DC.ColumnsSetID + ImGuiID(column_index); - if (g.ActiveId == column_id) - return GetDraggedColumnOffset(column_index); - } - - // Read from cache - IM_ASSERT(column_index < (int)window->DC.ColumnsOffsetsT.size()); - const float t = window->DC.ColumnsOffsetsT[column_index]; - - const float min_x = window->DC.ColumnsStartX; - const float max_x = window->Size.x - (g.Style.ScrollbarWidth);// - window->WindowPadding().x; - const float offset = min_x + t * (max_x - min_x); - return offset; -} - -void ImGui::SetColumnOffset(int column_index, float offset) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - if (column_index < 0) - column_index = window->DC.ColumnsCurrent; - - IM_ASSERT(column_index < (int)window->DC.ColumnsOffsetsT.size()); - const ImGuiID column_id = window->DC.ColumnsSetID + ImGuiID(column_index); - - const float min_x = window->DC.ColumnsStartX; - const float max_x = window->Size.x - (g.Style.ScrollbarWidth);// - window->WindowPadding().x; - const float t = (offset - min_x) / (max_x - min_x); - window->DC.StateStorage->SetFloat(column_id, t); - window->DC.ColumnsOffsetsT[column_index] = t; -} - -float ImGui::GetColumnWidth(int column_index) -{ - ImGuiWindow* window = GetCurrentWindow(); - if (column_index < 0) - column_index = window->DC.ColumnsCurrent; - - const float w = GetColumnOffset(column_index+1) - GetColumnOffset(column_index); - return w; -} - -static void PushColumnClipRect(int column_index) -{ - ImGuiWindow* window = GetCurrentWindow(); - if (column_index < 0) - column_index = window->DC.ColumnsCurrent; - - const float x1 = window->Pos.x + ImGui::GetColumnOffset(column_index) - 1; - const float x2 = window->Pos.x + ImGui::GetColumnOffset(column_index+1) - 1; - PushClipRect(ImVec4(x1,-FLT_MAX,x2,+FLT_MAX)); -} - -void ImGui::Columns(int columns_count, const char* id, bool border) -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - - if (window->DC.ColumnsCount != 1) - { - if (window->DC.ColumnsCurrent != 0) - ItemSize(ImVec2(0,0)); // Advance to column 0 - ImGui::PopItemWidth(); - PopClipRect(); - - window->DC.ColumnsCellMaxY = ImMax(window->DC.ColumnsCellMaxY, window->DC.CursorPos.y); - window->DC.CursorPos.y = window->DC.ColumnsCellMaxY; - } - - // Draw columns borders and handle resize at the time of "closing" a columns set - if (window->DC.ColumnsCount != columns_count && window->DC.ColumnsCount != 1 && window->DC.ColumnsShowBorders && !window->SkipItems) - { - const float y1 = window->DC.ColumnsStartPos.y; - const float y2 = window->DC.CursorPos.y; - for (int i = 1; i < window->DC.ColumnsCount; i++) - { - float x = window->Pos.x + GetColumnOffset(i); - - const ImGuiID column_id = window->DC.ColumnsSetID + ImGuiID(i); - const ImRect column_rect(ImVec2(x-4,y1),ImVec2(x+4,y2)); - - if (IsClippedEx(column_rect, &column_id, false)) - continue; - - bool hovered, held; - ButtonBehavior(column_rect, column_id, &hovered, &held, true); - if (hovered || held) - g.MouseCursor = ImGuiMouseCursor_ResizeEW; - - // Draw before resize so our items positioning are in sync with the line being drawn - const ImU32 col = window->Color(held ? ImGuiCol_ColumnActive : hovered ? ImGuiCol_ColumnHovered : ImGuiCol_Column); - const float xi = (float)(int)x; - window->DrawList->AddLine(ImVec2(xi, y1), ImVec2(xi, y2), col); - - if (held) - { - if (g.ActiveIdIsJustActivated) - g.ActiveClickDeltaToCenter.x = x - g.IO.MousePos.x; - - x = GetDraggedColumnOffset(i); - SetColumnOffset(i, x); - } - } - } - - // Set state for first column - window->DC.ColumnsSetID = window->GetID(id ? id : ""); - window->DC.ColumnsCurrent = 0; - window->DC.ColumnsCount = columns_count; - window->DC.ColumnsShowBorders = border; - window->DC.ColumnsStartPos = window->DC.CursorPos; - window->DC.ColumnsCellMinY = window->DC.ColumnsCellMaxY = window->DC.CursorPos.y; - window->DC.ColumnsOffsetX = 0.0f; - window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.ColumnsStartX + window->DC.ColumnsOffsetX); - - if (window->DC.ColumnsCount != 1) - { - // Cache column offsets - window->DC.ColumnsOffsetsT.resize((size_t)columns_count + 1); - for (int column_index = 0; column_index < columns_count + 1; column_index++) - { - const ImGuiID column_id = window->DC.ColumnsSetID + ImGuiID(column_index); - RegisterAliveId(column_id); - const float default_t = column_index / (float)window->DC.ColumnsCount; - const float t = window->DC.StateStorage->GetFloat(column_id, default_t); // Cheaply store our floating point value inside the integer (could store an union into the map?) - window->DC.ColumnsOffsetsT[column_index] = t; - } - - PushColumnClipRect(); - ImGui::PushItemWidth(ImGui::GetColumnWidth() * 0.65f); - } - else - { - window->DC.ColumnsOffsetsT.resize(2); - window->DC.ColumnsOffsetsT[0] = 0.0f; - window->DC.ColumnsOffsetsT[1] = 1.0f; - } -} - - -inline void ImGui::Indent() -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - window->DC.ColumnsStartX += g.Style.IndentSpacing; - window->DC.CursorPos.x = window->Pos.x + window->DC.ColumnsStartX + window->DC.ColumnsOffsetX; -} - -inline void ImGui::Unindent() -{ - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - window->DC.ColumnsStartX -= g.Style.IndentSpacing; - window->DC.CursorPos.x = window->Pos.x + window->DC.ColumnsStartX + window->DC.ColumnsOffsetX; -} - -void ImGui::TreePush(const char* str_id) -{ - ImGuiWindow* window = GetCurrentWindow(); - ImGui::Indent(); - window->DC.TreeDepth++; - PushID(str_id ? str_id : "#TreePush"); -} - -void ImGui::TreePush(const void* ptr_id) -{ - ImGuiWindow* window = GetCurrentWindow(); - ImGui::Indent(); - window->DC.TreeDepth++; - PushID(ptr_id ? ptr_id : (const void*)"#TreePush"); -} - -void ImGui::TreePop() -{ - ImGuiWindow* window = GetCurrentWindow(); - ImGui::Unindent(); - window->DC.TreeDepth--; - PopID(); -} - -void ImGui::Value(const char* prefix, bool b) -{ - ImGui::Text("%s: %s", prefix, (b ? "true" : "false")); -} - -void ImGui::Value(const char* prefix, int v) -{ - ImGui::Text("%s: %d", prefix, v); -} - -void ImGui::Value(const char* prefix, unsigned int v) -{ - ImGui::Text("%s: %d", prefix, v); -} - -void ImGui::Value(const char* prefix, float v, const char* float_format) -{ - if (float_format) - { - char fmt[64]; - ImFormatString(fmt, IM_ARRAYSIZE(fmt), "%%s: %s", float_format); - ImGui::Text(fmt, prefix, v); - } - else - { - ImGui::Text("%s: %.3f", prefix, v); - } -} - -void ImGui::Color(const char* prefix, const ImVec4& v) -{ - ImGui::Text("%s: (%.2f,%.2f,%.2f,%.2f)", prefix, v.x, v.y, v.z, v.w); - ImGui::SameLine(); - ImGui::ColorButton(v, true); -} - -void ImGui::Color(const char* prefix, unsigned int v) -{ - ImGui::Text("%s: %08X", prefix, v); - ImGui::SameLine(); - - ImVec4 col; - col.x = (float)((v >> 0) & 0xFF) / 255.0f; - col.y = (float)((v >> 8) & 0xFF) / 255.0f; - col.z = (float)((v >> 16) & 0xFF) / 255.0f; - col.w = (float)((v >> 24) & 0xFF) / 255.0f; - ImGui::ColorButton(col, true); -} - -//----------------------------------------------------------------------------- -// ImDrawList -//----------------------------------------------------------------------------- - -static ImVec4 GNullClipRect(-9999.0f,-9999.0f, +9999.0f, +9999.0f); - -void ImDrawList::Clear() -{ - commands.resize(0); - vtx_buffer.resize(0); - vtx_write = NULL; - clip_rect_stack.resize(0); - texture_id_stack.resize(0); -} - -void ImDrawList::ClearFreeMemory() -{ - commands.clear(); - vtx_buffer.clear(); - vtx_write = NULL; - clip_rect_stack.clear(); - texture_id_stack.clear(); -} - -void ImDrawList::AddDrawCmd() -{ - ImDrawCmd draw_cmd; - draw_cmd.vtx_count = 0; - draw_cmd.clip_rect = clip_rect_stack.empty() ? GNullClipRect : clip_rect_stack.back(); - draw_cmd.texture_id = texture_id_stack.empty() ? NULL : texture_id_stack.back(); - draw_cmd.user_callback = NULL; - draw_cmd.user_callback_data = NULL; - - IM_ASSERT(draw_cmd.clip_rect.x <= draw_cmd.clip_rect.z && draw_cmd.clip_rect.y <= draw_cmd.clip_rect.w); - commands.push_back(draw_cmd); -} - -void ImDrawList::AddCallback(ImDrawCallback callback, void* callback_data) -{ - ImDrawCmd* current_cmd = commands.empty() ? NULL : &commands.back(); - if (!current_cmd || current_cmd->vtx_count != 0 || current_cmd->user_callback != NULL) - { - AddDrawCmd(); - current_cmd = &commands.back(); - } - current_cmd->user_callback = callback; - current_cmd->user_callback_data = callback_data; - - // Force a new command after us - // We function this way so that the most common calls (AddLine, AddRect..) always have a command to add to without doing any check. - AddDrawCmd(); -} - -void ImDrawList::UpdateClipRect() -{ - ImDrawCmd* current_cmd = commands.empty() ? NULL : &commands.back(); - if (!current_cmd || (current_cmd->vtx_count != 0) || current_cmd->user_callback != NULL) - { - AddDrawCmd(); - } - else - { - current_cmd->clip_rect = clip_rect_stack.empty() ? GNullClipRect : clip_rect_stack.back(); - } -} - -// Scissoring. The values in clip_rect are x1, y1, x2, y2. -void ImDrawList::PushClipRect(const ImVec4& clip_rect) -{ - clip_rect_stack.push_back(clip_rect); - UpdateClipRect(); -} - -void ImDrawList::PushClipRectFullScreen() -{ - PushClipRect(GNullClipRect); - - // This would be more correct but we're not supposed to access ImGuiState from here? - //ImGuiState& g = *GImGui; - //if (g.IO.DisplayVisibleMin.x != g.IO.DisplayVisibleMax.x && g.IO.DisplayVisibleMin.y != g.IO.DisplayVisibleMax.y) - // PushClipRect(ImVec4(g.IO.DisplayVisibleMin.x, g.IO.DisplayVisibleMin.y, g.IO.DisplayVisibleMax.x, g.IO.DisplayVisibleMax.y)); - //else - // PushClipRect(ImVec4(0.0f, 0.0f, g.IO.DisplaySize.x, g.IO.DisplaySize.y)); -} - -void ImDrawList::PopClipRect() -{ - IM_ASSERT(clip_rect_stack.size() > 0); - clip_rect_stack.pop_back(); - UpdateClipRect(); -} - -void ImDrawList::UpdateTextureID() -{ - ImDrawCmd* current_cmd = commands.empty() ? NULL : &commands.back(); - const ImTextureID texture_id = texture_id_stack.empty() ? NULL : texture_id_stack.back(); - if (!current_cmd || (current_cmd->vtx_count != 0 && current_cmd->texture_id != texture_id) || current_cmd->user_callback != NULL) - { - AddDrawCmd(); - } - else - { - current_cmd->texture_id = texture_id; - } -} - -void ImDrawList::PushTextureID(const ImTextureID& texture_id) -{ - texture_id_stack.push_back(texture_id); - UpdateTextureID(); -} - -void ImDrawList::PopTextureID() -{ - IM_ASSERT(texture_id_stack.size() > 0); - texture_id_stack.pop_back(); - UpdateTextureID(); -} - -void ImDrawList::PrimReserve(unsigned int vtx_count) -{ - ImDrawCmd& draw_cmd = commands.back(); - draw_cmd.vtx_count += vtx_count; - - size_t vtx_buffer_size = vtx_buffer.size(); - vtx_buffer.resize(vtx_buffer_size + vtx_count); - vtx_write = &vtx_buffer[vtx_buffer_size]; -} - -void ImDrawList::PrimTriangle(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col) -{ - const ImVec2 uv = GImGui->FontTexUvWhitePixel; - vtx_write[0].pos = a; vtx_write[0].uv = uv; vtx_write[0].col = col; - vtx_write[1].pos = b; vtx_write[1].uv = uv; vtx_write[1].col = col; - vtx_write[2].pos = c; vtx_write[2].uv = uv; vtx_write[2].col = col; - vtx_write += 3; -} - -void ImDrawList::PrimRect(const ImVec2& a, const ImVec2& c, ImU32 col) -{ - const ImVec2 uv = GImGui->FontTexUvWhitePixel; - const ImVec2 b(c.x, a.y); - const ImVec2 d(a.x, c.y); - vtx_write[0].pos = a; vtx_write[0].uv = uv; vtx_write[0].col = col; - vtx_write[1].pos = b; vtx_write[1].uv = uv; vtx_write[1].col = col; - vtx_write[2].pos = c; vtx_write[2].uv = uv; vtx_write[2].col = col; - vtx_write[3].pos = a; vtx_write[3].uv = uv; vtx_write[3].col = col; - vtx_write[4].pos = c; vtx_write[4].uv = uv; vtx_write[4].col = col; - vtx_write[5].pos = d; vtx_write[5].uv = uv; vtx_write[5].col = col; - vtx_write += 6; -} - -void ImDrawList::PrimRectUV(const ImVec2& a, const ImVec2& c, const ImVec2& uv_a, const ImVec2& uv_c, ImU32 col) -{ - const ImVec2 b(c.x, a.y); - const ImVec2 d(a.x, c.y); - const ImVec2 uv_b(uv_c.x, uv_a.y); - const ImVec2 uv_d(uv_a.x, uv_c.y); - vtx_write[0].pos = a; vtx_write[0].uv = uv_a; vtx_write[0].col = col; - vtx_write[1].pos = b; vtx_write[1].uv = uv_b; vtx_write[1].col = col; - vtx_write[2].pos = c; vtx_write[2].uv = uv_c; vtx_write[2].col = col; - vtx_write[3].pos = a; vtx_write[3].uv = uv_a; vtx_write[3].col = col; - vtx_write[4].pos = c; vtx_write[4].uv = uv_c; vtx_write[4].col = col; - vtx_write[5].pos = d; vtx_write[5].uv = uv_d; vtx_write[5].col = col; - vtx_write += 6; -} - -void ImDrawList::PrimQuad(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, ImU32 col) -{ - const ImVec2 uv = GImGui->FontTexUvWhitePixel; - vtx_write[0].pos = a; vtx_write[0].uv = uv; vtx_write[0].col = col; - vtx_write[1].pos = b; vtx_write[1].uv = uv; vtx_write[1].col = col; - vtx_write[2].pos = c; vtx_write[2].uv = uv; vtx_write[2].col = col; - vtx_write[3].pos = a; vtx_write[3].uv = uv; vtx_write[3].col = col; - vtx_write[4].pos = c; vtx_write[4].uv = uv; vtx_write[4].col = col; - vtx_write[5].pos = d; vtx_write[5].uv = uv; vtx_write[5].col = col; - vtx_write += 6; -} - -// FIXME-OPT: In many instances the caller could provide a normal. -void ImDrawList::PrimLine(const ImVec2& a, const ImVec2& b, ImU32 col, float thickness) -{ - const float inv_length = 1.0f / sqrtf(ImLengthSqr(b - a)); - const float dx = (b.x - a.x) * (thickness * 0.5f * inv_length); // line direction, halved - const float dy = (b.y - a.y) * (thickness * 0.5f * inv_length); // line direction, halved - - const ImVec2 pa(a.x + dy, a.y - dx); - const ImVec2 pb(b.x + dy, b.y - dx); - const ImVec2 pc(b.x - dy, b.y + dx); - const ImVec2 pd(a.x - dy, a.y + dx); - PrimQuad(pa, pb, pc, pd, col); -} - -void ImDrawList::AddLine(const ImVec2& a, const ImVec2& b, ImU32 col, float thickness) -{ - if ((col >> 24) == 0) - return; - - PrimReserve(6); - PrimLine(a, b, col, thickness); -} - -void ImDrawList::AddArcFast(const ImVec2& center, float radius, ImU32 col, int a_min, int a_max, bool filled, const ImVec2& third_point_offset) -{ - if ((col >> 24) == 0) - return; - - const int SAMPLES = 12; - static ImVec2 circle_vtx[SAMPLES]; - static bool circle_vtx_builds = false; - if (!circle_vtx_builds) - { - for (int i = 0; i < SAMPLES; i++) - { - const float a = ((float)i / (float)SAMPLES) * 2*PI; - circle_vtx[i].x = cosf(a + PI); - circle_vtx[i].y = sinf(a + PI); - } - circle_vtx_builds = true; - } - - const ImVec2 uv = GImGui->FontTexUvWhitePixel; - if (filled) - { - PrimReserve((unsigned int)(a_max-a_min) * 3); - for (int a0 = a_min; a0 < a_max; a0++) - { - int a1 = (a0 + 1 == SAMPLES) ? 0 : a0 + 1; - PrimVtx(center + circle_vtx[a0] * radius, uv, col); - PrimVtx(center + circle_vtx[a1] * radius, uv, col); - PrimVtx(center + third_point_offset, uv, col); - } - } - else - { - PrimReserve((unsigned int)(a_max-a_min) * 6); - for (int a0 = a_min; a0 < a_max; a0++) - { - int a1 = (a0 + 1 == SAMPLES) ? 0 : a0 + 1; - PrimLine(center + circle_vtx[a0] * radius, center + circle_vtx[a1] * radius, col); - } - } -} - -void ImDrawList::AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding, int rounding_corners) -{ - if ((col >> 24) == 0) - return; - - float r = rounding; - r = ImMin(r, fabsf(b.x-a.x) * ( ((rounding_corners&(1|2))==(1|2)) || ((rounding_corners&(4|8))==(4|8)) ? 0.5f : 1.0f )); - r = ImMin(r, fabsf(b.y-a.y) * ( ((rounding_corners&(1|8))==(1|8)) || ((rounding_corners&(2|4))==(2|4)) ? 0.5f : 1.0f )); - - if (r == 0.0f || rounding_corners == 0) - { - PrimReserve(4*6); - PrimLine(ImVec2(a.x,a.y), ImVec2(b.x,a.y), col); - PrimLine(ImVec2(b.x,a.y), ImVec2(b.x,b.y), col); - PrimLine(ImVec2(b.x,b.y), ImVec2(a.x,b.y), col); - PrimLine(ImVec2(a.x,b.y), ImVec2(a.x,a.y), col); - } - else - { - PrimReserve(4*6); - PrimLine(ImVec2(a.x + ((rounding_corners & 1)?r:0), a.y), ImVec2(b.x - ((rounding_corners & 2)?r:0), a.y), col); - PrimLine(ImVec2(b.x, a.y + ((rounding_corners & 2)?r:0)), ImVec2(b.x, b.y - ((rounding_corners & 4)?r:0)), col); - PrimLine(ImVec2(b.x - ((rounding_corners & 4)?r:0), b.y), ImVec2(a.x + ((rounding_corners & 8)?r:0), b.y), col); - PrimLine(ImVec2(a.x, b.y - ((rounding_corners & 8)?r:0)), ImVec2(a.x, a.y + ((rounding_corners & 1)?r:0)), col); - - if (rounding_corners & 1) AddArcFast(ImVec2(a.x+r,a.y+r), r, col, 0, 3); - if (rounding_corners & 2) AddArcFast(ImVec2(b.x-r,a.y+r), r, col, 3, 6); - if (rounding_corners & 4) AddArcFast(ImVec2(b.x-r,b.y-r), r, col, 6, 9); - if (rounding_corners & 8) AddArcFast(ImVec2(a.x+r,b.y-r), r, col, 9, 12); - } -} - -void ImDrawList::AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding, int rounding_corners) -{ - if ((col >> 24) == 0) - return; - - float r = rounding; - r = ImMin(r, fabsf(b.x-a.x) * ( ((rounding_corners&(1|2))==(1|2)) || ((rounding_corners&(4|8))==(4|8)) ? 0.5f : 1.0f )); - r = ImMin(r, fabsf(b.y-a.y) * ( ((rounding_corners&(1|8))==(1|8)) || ((rounding_corners&(2|4))==(2|4)) ? 0.5f : 1.0f )); - - if (r == 0.0f || rounding_corners == 0) - { - // Use triangle so we can merge more draw calls together (at the cost of extra vertices) - PrimReserve(6); - PrimRect(a, b, col); - } - else - { - PrimReserve(6+6*2); - PrimRect(ImVec2(a.x+r,a.y), ImVec2(b.x-r,b.y), col); - - float top_y = (rounding_corners & 1) ? a.y+r : a.y; - float bot_y = (rounding_corners & 8) ? b.y-r : b.y; - PrimRect(ImVec2(a.x,top_y), ImVec2(a.x+r,bot_y), col); - - top_y = (rounding_corners & 2) ? a.y+r : a.y; - bot_y = (rounding_corners & 4) ? b.y-r : b.y; - PrimRect(ImVec2(b.x-r,top_y), ImVec2(b.x,bot_y), col); - - if (rounding_corners & 1) AddArcFast(ImVec2(a.x+r,a.y+r), r, col, 0, 3, true); - if (rounding_corners & 2) AddArcFast(ImVec2(b.x-r,a.y+r), r, col, 3, 6, true); - if (rounding_corners & 4) AddArcFast(ImVec2(b.x-r,b.y-r), r, col, 6, 9, true); - if (rounding_corners & 8) AddArcFast(ImVec2(a.x+r,b.y-r), r, col, 9, 12, true); - } -} - -void ImDrawList::AddTriangleFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col) -{ - if ((col >> 24) == 0) - return; - - PrimReserve(3); - PrimTriangle(a, b, c, col); -} - -void ImDrawList::AddCircle(const ImVec2& centre, float radius, ImU32 col, int num_segments) -{ - if ((col >> 24) == 0) - return; - - PrimReserve((unsigned int)num_segments*6); - const float a_step = 2*PI/(float)num_segments; - float a0 = 0.0f; - for (int i = 0; i < num_segments; i++) - { - const float a1 = (i + 1) == num_segments ? 0.0f : a0 + a_step; - PrimLine(centre + ImVec2(cosf(a0), sinf(a0))*radius, centre + ImVec2(cosf(a1), sinf(a1))*radius, col); - a0 = a1; - } -} - -void ImDrawList::AddCircleFilled(const ImVec2& centre, float radius, ImU32 col, int num_segments) -{ - if ((col >> 24) == 0) - return; - - const ImVec2 uv = GImGui->FontTexUvWhitePixel; - PrimReserve((unsigned int)num_segments*3); - const float a_step = 2*PI/(float)num_segments; - float a0 = 0.0f; - for (int i = 0; i < num_segments; i++) - { - const float a1 = (i + 1) == num_segments ? 0.0f : a0 + a_step; - PrimVtx(centre + ImVec2(cosf(a0), sinf(a0))*radius, uv, col); - PrimVtx(centre + ImVec2(cosf(a1), sinf(a1))*radius, uv, col); - PrimVtx(centre, uv, col); - a0 = a1; - } -} - -void ImDrawList::AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end, float wrap_width, const ImVec2* cpu_clip_max) -{ - if ((col >> 24) == 0) - return; - - if (text_end == NULL) - text_end = text_begin + strlen(text_begin); - if (text_begin == text_end) - return; - - IM_ASSERT(font->ContainerAtlas->TexID == texture_id_stack.back()); // Use high-level ImGui::PushFont() or low-level ImDrawList::PushTextureId() to change font. - - // reserve vertices for worse case - const unsigned int char_count = (unsigned int)(text_end - text_begin); - const unsigned int vtx_count_max = char_count * 6; - const size_t vtx_begin = vtx_buffer.size(); - PrimReserve(vtx_count_max); - - font->RenderText(font_size, pos, col, clip_rect_stack.back(), text_begin, text_end, this, wrap_width, cpu_clip_max); - - // give back unused vertices - vtx_buffer.resize((size_t)(vtx_write - &vtx_buffer.front())); - const size_t vtx_count = vtx_buffer.size() - vtx_begin; - commands.back().vtx_count -= (unsigned int)(vtx_count_max - vtx_count); - vtx_write -= (vtx_count_max - vtx_count); -} - -void ImDrawList::AddImage(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv0, const ImVec2& uv1, ImU32 col) -{ - if ((col >> 24) == 0) - return; - - // FIXME-OPT: This is wasting draw calls. - const bool push_texture_id = texture_id_stack.empty() || user_texture_id != texture_id_stack.back(); - if (push_texture_id) - PushTextureID(user_texture_id); - - PrimReserve(6); - PrimRectUV(a, b, uv0, uv1, col); - - if (push_texture_id) - PopTextureID(); -} - -//----------------------------------------------------------------------------- -// ImFontAtlias -//----------------------------------------------------------------------------- - -struct ImFontAtlas::ImFontAtlasData -{ - // Input - ImFont* OutFont; // Load into this font - void* TTFData; // TTF data, we own the memory - size_t TTFDataSize; // TTF data size, in bytes - float SizePixels; // Desired output size, in pixels - const ImWchar* GlyphRanges; // List of Unicode range (2 value per range, values are inclusive, zero-terminated list) - int FontNo; // Index of font within .TTF file (0) - - // Temporary Build Data - stbtt_fontinfo FontInfo; - stbrp_rect* Rects; - stbtt_pack_range* Ranges; - int RangesCount; -}; - -ImFontAtlas::ImFontAtlas() -{ - TexID = NULL; - TexPixelsAlpha8 = NULL; - TexPixelsRGBA32 = NULL; - TexWidth = TexHeight = 0; - TexUvWhitePixel = ImVec2(0, 0); -} - -ImFontAtlas::~ImFontAtlas() -{ - Clear(); -} - -void ImFontAtlas::ClearInputData() -{ - for (size_t i = 0; i < InputData.size(); i++) - { - if (InputData[i]->TTFData) - ImGui::MemFree(InputData[i]->TTFData); - ImGui::MemFree(InputData[i]); - } - InputData.clear(); -} - -void ImFontAtlas::ClearTexData() -{ - if (TexPixelsAlpha8) - ImGui::MemFree(TexPixelsAlpha8); - if (TexPixelsRGBA32) - ImGui::MemFree(TexPixelsRGBA32); - TexPixelsAlpha8 = NULL; - TexPixelsRGBA32 = NULL; -} - -void ImFontAtlas::Clear() -{ - ClearInputData(); - ClearTexData(); - for (size_t i = 0; i < Fonts.size(); i++) - { - Fonts[i]->~ImFont(); - ImGui::MemFree(Fonts[i]); - } - Fonts.clear(); -} - -void ImGui::GetDefaultFontData(const void** fnt_data, unsigned int* fnt_size, const void** png_data, unsigned int* png_size) -{ - printf("GetDefaultFontData() is obsoleted in ImGui 1.30.\n"); - printf("Please use ImGui::GetIO().Fonts->GetTexDataAsRGBA32() or GetTexDataAsAlpha8() functions to retrieve uncompressed texture data.\n"); - if (fnt_data) *fnt_data = NULL; - if (fnt_size) *fnt_size = 0; - if (png_data) *png_data = NULL; - if (png_size) *png_size = 0; - IM_ASSERT(false); -} - -void ImFontAtlas::GetTexDataAsAlpha8(unsigned char** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel) -{ - // Lazily build - if (TexPixelsAlpha8 == NULL) - { - if (InputData.empty()) - AddFontDefault(); - Build(); - } - - *out_pixels = TexPixelsAlpha8; - if (out_width) *out_width = TexWidth; - if (out_height) *out_height = TexHeight; - if (out_bytes_per_pixel) *out_bytes_per_pixel = 1; -} - -void ImFontAtlas::GetTexDataAsRGBA32(unsigned char** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel) -{ - // Lazily convert to RGBA32 format - // Although it is likely to be the most commonly used format, our font rendering is 8 bpp - if (!TexPixelsRGBA32) - { - unsigned char* pixels; - GetTexDataAsAlpha8(&pixels, NULL, NULL); - TexPixelsRGBA32 = (unsigned int*)ImGui::MemAlloc((size_t)(TexWidth * TexHeight * 4)); - const unsigned char* src = pixels; - unsigned int* dst = TexPixelsRGBA32; - for (int n = TexWidth * TexHeight; n > 0; n--) - *dst++ = ((unsigned int)(*src++) << 24) | 0x00FFFFFF; - } - - *out_pixels = (unsigned char*)TexPixelsRGBA32; - if (out_width) *out_width = TexWidth; - if (out_height) *out_height = TexHeight; - if (out_bytes_per_pixel) *out_bytes_per_pixel = 4; -} - -static void GetDefaultCompressedFontDataTTF(const void** ttf_compressed_data, unsigned int* ttf_compressed_size); -static unsigned int stb_decompress_length(unsigned char *input); -static unsigned int stb_decompress(unsigned char *output, unsigned char *i, unsigned int length); - -// Load embedded ProggyClean.ttf at size 13 -ImFont* ImFontAtlas::AddFontDefault() -{ - unsigned int ttf_compressed_size; - const void* ttf_compressed; - GetDefaultCompressedFontDataTTF(&ttf_compressed, &ttf_compressed_size); - ImFont* font = AddFontFromMemoryCompressedTTF(ttf_compressed, ttf_compressed_size, 13.0f, GetGlyphRangesDefault(), 0); - font->DisplayOffset.y += 1; - return font; -} - -ImFont* ImFontAtlas::AddFontFromFileTTF(const char* filename, float size_pixels, const ImWchar* glyph_ranges, int font_no) -{ - void* data = NULL; - size_t data_size = 0; - if (!ImLoadFileToMemory(filename, "rb", (void**)&data, &data_size)) - { - IM_ASSERT(0); // Could not load file. - return NULL; - } - - ImFont* font = AddFontFromMemoryTTF(data, (unsigned int)data_size, size_pixels, glyph_ranges, font_no); - return font; -} - -// NB: ownership of 'data' is given to ImFontAtlas which will clear it. -ImFont* ImFontAtlas::AddFontFromMemoryTTF(void* in_ttf_data, unsigned int in_ttf_data_size, float size_pixels, const ImWchar* glyph_ranges, int font_no) -{ - // Create new font - ImFont* font = (ImFont*)ImGui::MemAlloc(sizeof(ImFont)); - new (font) ImFont(); - Fonts.push_back(font); - - // Add to build list - ImFontAtlasData* data = (ImFontAtlasData*)ImGui::MemAlloc(sizeof(ImFontAtlasData)); - memset(data, 0, sizeof(ImFontAtlasData)); - data->OutFont = font; - data->TTFData = in_ttf_data; - data->TTFDataSize = in_ttf_data_size; - data->SizePixels = size_pixels; - data->GlyphRanges = glyph_ranges; - data->FontNo = font_no; - InputData.push_back(data); - - // Invalidate texture - ClearTexData(); - - return font; -} - -ImFont* ImFontAtlas::AddFontFromMemoryCompressedTTF(const void* in_compressed_ttf_data, unsigned int in_compressed_ttf_data_size, float size_pixels, const ImWchar* glyph_ranges, int font_no) -{ - // Decompress - const size_t buf_decompressed_size = stb_decompress_length((unsigned char*)in_compressed_ttf_data); - unsigned char* buf_decompressed = (unsigned char *)ImGui::MemAlloc(buf_decompressed_size); - stb_decompress(buf_decompressed, (unsigned char*)in_compressed_ttf_data, in_compressed_ttf_data_size); - - // Add - ImFont* font = AddFontFromMemoryTTF(buf_decompressed, (unsigned int)buf_decompressed_size, size_pixels, glyph_ranges, font_no); - return font; -} - -bool ImFontAtlas::Build() -{ - IM_ASSERT(InputData.size() > 0); - - TexID = NULL; - TexWidth = TexHeight = 0; - TexUvWhitePixel = ImVec2(0, 0); - ClearTexData(); - - // Initialize font information early (so we can error without any cleanup) + count glyphs - int total_glyph_count = 0; - int total_glyph_range_count = 0; - for (size_t input_i = 0; input_i < InputData.size(); input_i++) - { - ImFontAtlasData& data = *InputData[input_i]; - IM_ASSERT(data.OutFont && !data.OutFont->IsLoaded()); - const int font_offset = stbtt_GetFontOffsetForIndex((unsigned char*)data.TTFData, data.FontNo); - IM_ASSERT(font_offset >= 0); - if (!stbtt_InitFont(&data.FontInfo, (unsigned char*)data.TTFData, font_offset)) - return false; - - if (!data.GlyphRanges) - data.GlyphRanges = GetGlyphRangesDefault(); - for (const ImWchar* in_range = data.GlyphRanges; in_range[0] && in_range[1]; in_range += 2) - { - total_glyph_count += (in_range[1] - in_range[0]) + 1; - total_glyph_range_count++; - } - } - - // Start packing - TexWidth = (total_glyph_count > 1000) ? 1024 : 512; // Width doesn't actually matters. - TexHeight = 0; - const int max_tex_height = 1024*32; - stbtt_pack_context spc; - int ret = stbtt_PackBegin(&spc, NULL, TexWidth, max_tex_height, 0, 1, NULL); - IM_ASSERT(ret); - stbtt_PackSetOversampling(&spc, 1, 1); - - // Pack our extra data rectangles first, so it will be on the upper-left corner of our texture (UV will have small values). - ImVector extra_rects; - RenderCustomTexData(0, &extra_rects); - stbrp_pack_rects((stbrp_context*)spc.pack_info, &extra_rects[0], (int)extra_rects.size()); - for (size_t i = 0; i < extra_rects.size(); i++) - if (extra_rects[i].was_packed) - TexHeight = ImMax(TexHeight, extra_rects[i].y + extra_rects[i].h); - - // Allocate packing character data and flag packed characters buffer as non-packed (x0=y0=x1=y1=0) - int buf_packedchars_n = 0, buf_rects_n = 0, buf_ranges_n = 0; - stbtt_packedchar* buf_packedchars = (stbtt_packedchar*)ImGui::MemAlloc(total_glyph_count * sizeof(stbtt_packedchar)); - stbrp_rect* buf_rects = (stbrp_rect*)ImGui::MemAlloc(total_glyph_count * sizeof(stbrp_rect)); - stbtt_pack_range* buf_ranges = (stbtt_pack_range*)ImGui::MemAlloc(total_glyph_range_count * sizeof(stbtt_pack_range)); - memset(buf_packedchars, 0, total_glyph_count * sizeof(stbtt_packedchar)); - memset(buf_rects, 0, total_glyph_count * sizeof(stbrp_rect)); // Unnecessary but let's clear this for the sake of sanity. - memset(buf_ranges, 0, total_glyph_range_count * sizeof(stbtt_pack_range)); - - // First font pass: pack all glyphs (no rendering at this point, we are working with glyph sizes only) - for (size_t input_i = 0; input_i < InputData.size(); input_i++) - { - ImFontAtlasData& data = *InputData[input_i]; - - // Setup ranges - int glyph_count = 0; - int glyph_ranges_count = 0; - for (const ImWchar* in_range = data.GlyphRanges; in_range[0] && in_range[1]; in_range += 2) - { - glyph_count += (in_range[1] - in_range[0]) + 1; - glyph_ranges_count++; - } - data.Ranges = buf_ranges + buf_ranges_n; - data.RangesCount = glyph_ranges_count; - buf_ranges_n += glyph_ranges_count; - for (int i = 0; i < glyph_ranges_count; i++) - { - const ImWchar* in_range = &data.GlyphRanges[i * 2]; - stbtt_pack_range& range = data.Ranges[i]; - range.font_size = data.SizePixels; - range.first_unicode_char_in_range = in_range[0]; - range.num_chars_in_range = (in_range[1] - in_range[0]) + 1; - range.chardata_for_range = buf_packedchars + buf_packedchars_n; - buf_packedchars_n += range.num_chars_in_range; - } - - // Pack - data.Rects = buf_rects + buf_rects_n; - buf_rects_n += glyph_count; - const int n = stbtt_PackFontRangesGatherRects(&spc, &data.FontInfo, data.Ranges, data.RangesCount, data.Rects); - stbrp_pack_rects((stbrp_context*)spc.pack_info, data.Rects, n); - - // Extend texture height - for (int i = 0; i < n; i++) - if (data.Rects[i].was_packed) - TexHeight = ImMax(TexHeight, data.Rects[i].y + data.Rects[i].h); - } - IM_ASSERT(buf_rects_n == total_glyph_count); - IM_ASSERT(buf_packedchars_n == total_glyph_count); - IM_ASSERT(buf_ranges_n == total_glyph_range_count); - - // Create texture - TexHeight = ImUpperPowerOfTwo(TexHeight); - TexPixelsAlpha8 = (unsigned char*)ImGui::MemAlloc(TexWidth * TexHeight); - memset(TexPixelsAlpha8, 0, TexWidth * TexHeight); - spc.pixels = TexPixelsAlpha8; - spc.height = TexHeight; - - // Second pass: render characters - for (size_t input_i = 0; input_i < InputData.size(); input_i++) - { - ImFontAtlasData& data = *InputData[input_i]; - ret = stbtt_PackFontRangesRenderIntoRects(&spc, &data.FontInfo, data.Ranges, data.RangesCount, data.Rects); - data.Rects = NULL; - } - - // End packing - stbtt_PackEnd(&spc); - ImGui::MemFree(buf_rects); - buf_rects = NULL; - - // Third pass: setup ImFont and glyphs for runtime - for (size_t input_i = 0; input_i < InputData.size(); input_i++) - { - ImFontAtlasData& data = *InputData[input_i]; - data.OutFont->ContainerAtlas = this; - data.OutFont->FontSize = data.SizePixels; - - const float font_scale = stbtt_ScaleForPixelHeight(&data.FontInfo, data.SizePixels); - int font_ascent, font_descent, font_line_gap; - stbtt_GetFontVMetrics(&data.FontInfo, &font_ascent, &font_descent, &font_line_gap); - - const float uv_scale_x = 1.0f / TexWidth; - const float uv_scale_y = 1.0f / TexHeight; - const int character_spacing_x = 1; - for (int i = 0; i < data.RangesCount; i++) - { - stbtt_pack_range& range = data.Ranges[i]; - for (int char_idx = 0; char_idx < range.num_chars_in_range; char_idx += 1) - { - const int codepoint = range.first_unicode_char_in_range + char_idx; - const stbtt_packedchar& pc = range.chardata_for_range[char_idx]; - if (!pc.x0 && !pc.x1 && !pc.y0 && !pc.y1) - continue; - - data.OutFont->Glyphs.resize(data.OutFont->Glyphs.size() + 1); - ImFont::Glyph& glyph = data.OutFont->Glyphs.back(); - glyph.Codepoint = (ImWchar)codepoint; - glyph.Width = (signed short)pc.x1 - pc.x0 + 1; - glyph.Height = (signed short)pc.y1 - pc.y0 + 1; - glyph.XOffset = (signed short)(pc.xoff); - glyph.YOffset = (signed short)(pc.yoff + (int)(font_ascent * font_scale)); - glyph.XAdvance = (signed short)(pc.xadvance + character_spacing_x); // Bake spacing into XAdvance - glyph.U0 = ((float)pc.x0 - 0.5f) * uv_scale_x; - glyph.V0 = ((float)pc.y0 - 0.5f) * uv_scale_y; - glyph.U1 = ((float)pc.x0 - 0.5f + glyph.Width) * uv_scale_x; - glyph.V1 = ((float)pc.y0 - 0.5f + glyph.Height) * uv_scale_y; - } - } - - data.OutFont->BuildLookupTable(); - } - - // Cleanup temporaries - ImGui::MemFree(buf_packedchars); - ImGui::MemFree(buf_ranges); - buf_packedchars = NULL; - buf_ranges = NULL; - ClearInputData(); - - // Render into our custom data block - RenderCustomTexData(1, &extra_rects); - - return true; -} - -void ImFontAtlas::RenderCustomTexData(int pass, void* p_rects) -{ - // . = white layer, X = black layer, others are blank - const int TEX_DATA_W = 90; - const int TEX_DATA_H = 27; - const char texture_data[TEX_DATA_W*TEX_DATA_H+1] = - { - "..- -XXXXXXX- X - X -XXXXXXX - XXXXXXX" - "..- -X.....X- X.X - X.X -X.....X - X.....X" - "--- -XXX.XXX- X...X - X...X -X....X - X....X" - "X - X.X - X.....X - X.....X -X...X - X...X" - "XX - X.X -X.......X- X.......X -X..X.X - X.X..X" - "X.X - X.X -XXXX.XXXX- XXXX.XXXX -X.X X.X - X.X X.X" - "X..X - X.X - X.X - X.X -XX X.X - X.X XX" - "X...X - X.X - X.X - XX X.X XX - X.X - X.X " - "X....X - X.X - X.X - X.X X.X X.X - X.X - X.X " - "X.....X - X.X - X.X - X..X X.X X..X - X.X - X.X " - "X......X - X.X - X.X - X...XXXXXX.XXXXXX...X - X.X XX-XX X.X " - "X.......X - X.X - X.X -X.....................X- X.X X.X-X.X X.X " - "X........X - X.X - X.X - X...XXXXXX.XXXXXX...X - X.X..X-X..X.X " - "X.........X -XXX.XXX- X.X - X..X X.X X..X - X...X-X...X " - "X..........X-X.....X- X.X - X.X X.X X.X - X....X-X....X " - "X......XXXXX-XXXXXXX- X.X - XX X.X XX - X.....X-X.....X " - "X...X..X --------- X.X - X.X - XXXXXXX-XXXXXXX " - "X..X X..X - -XXXX.XXXX- XXXX.XXXX ------------------------------------" - "X.X X..X - -X.......X- X.......X - XX XX - " - "XX X..X - - X.....X - X.....X - X.X X.X - " - " X..X - X...X - X...X - X..X X..X - " - " XX - X.X - X.X - X...XXXXXXXXXXXXX...X - " - "------------ - X - X -X.....................X- " - " ----------------------------------- X...XXXXXXXXXXXXX...X - " - " - X..X X..X - " - " - X.X X.X - " - " - XX XX - " - }; - - ImVector& rects = *(ImVector*)p_rects; - if (pass == 0) - { - stbrp_rect r; - memset(&r, 0, sizeof(r)); - r.w = (TEX_DATA_W*2)+1; - r.h = TEX_DATA_H+1; - rects.push_back(r); - } - else if (pass == 1) - { - // Copy pixels - const stbrp_rect& r = rects[0]; - for (int y = 0, n = 0; y < TEX_DATA_H; y++) - for (int x = 0; x < TEX_DATA_W; x++, n++) - { - const int offset0 = (int)(r.x + x) + (int)(r.y + y) * TexWidth; - const int offset1 = offset0 + 1 + TEX_DATA_W; - TexPixelsAlpha8[offset0] = texture_data[n] == '.' ? 0xFF : 0x00; - TexPixelsAlpha8[offset1] = texture_data[n] == 'X' ? 0xFF : 0x00; - } - const ImVec2 tex_uv_scale(1.0f / TexWidth, 1.0f / TexHeight); - TexUvWhitePixel = ImVec2(r.x + 0.5f, r.y + 0.5f) * tex_uv_scale; - - const ImVec2 cursor_datas[ImGuiMouseCursor_Count_][3] = - { - // Pos ........ Size ......... Offset ...... - { ImVec2(0,3), ImVec2(12,19), ImVec2( 0, 0) }, // ImGuiMouseCursor_Arrow - { ImVec2(13,0), ImVec2(7,16), ImVec2( 4, 8) }, // ImGuiMouseCursor_TextInput - { ImVec2(31,0), ImVec2(23,23), ImVec2(11,11) }, // ImGuiMouseCursor_Move - { ImVec2(21,0), ImVec2( 9,23), ImVec2( 5,11) }, // ImGuiMouseCursor_ResizeNS - { ImVec2(55,18),ImVec2(23, 9), ImVec2(11, 5) }, // ImGuiMouseCursor_ResizeEW - { ImVec2(73,0), ImVec2(17,17), ImVec2( 9, 9) }, // ImGuiMouseCursor_ResizeNESW - { ImVec2(55,0), ImVec2(17,17), ImVec2( 9, 9) }, // ImGuiMouseCursor_ResizeNWSE - }; - - for (int type = 0; type < ImGuiMouseCursor_Count_; type++) - { - ImGuiMouseCursorData& cursor_data = GImGui->MouseCursorData[type]; - ImVec2 pos = cursor_datas[type][0] + ImVec2((float)r.x, (float)r.y); - const ImVec2 size = cursor_datas[type][1]; - cursor_data.Type = type; - cursor_data.Size = size; - cursor_data.Offset = cursor_datas[type][2]; - cursor_data.TexUvMin[0] = (pos) * tex_uv_scale; - cursor_data.TexUvMax[0] = (pos + size) * tex_uv_scale; - pos.x += TEX_DATA_W+1; - cursor_data.TexUvMin[1] = (pos) * tex_uv_scale; - cursor_data.TexUvMax[1] = (pos + size) * tex_uv_scale; - } - } -} - -//----------------------------------------------------------------------------- -// ImFont -//----------------------------------------------------------------------------- - -ImFont::ImFont() -{ - Scale = 1.0f; - FallbackChar = (ImWchar)'?'; - Clear(); -} - -ImFont::~ImFont() -{ - // Invalidate active font so that the user gets a clear crash instead of a dangling pointer. - // If you want to delete fonts you need to do it between Render() and NewFrame(). - ImGuiState& g = *GImGui; - if (g.Font == this) - g.Font = NULL; - Clear(); -} - -void ImFont::Clear() -{ - FontSize = 0.0f; - DisplayOffset = ImVec2(-0.5f, 0.5f); - ContainerAtlas = NULL; - Glyphs.clear(); - FallbackGlyph = NULL; - FallbackXAdvance = 0.0f; - IndexXAdvance.clear(); - IndexLookup.clear(); -} - -// Retrieve list of range (2 int per range, values are inclusive) -const ImWchar* ImFontAtlas::GetGlyphRangesDefault() -{ - static const ImWchar ranges[] = - { - 0x0020, 0x00FF, // Basic Latin + Latin Supplement - 0, - }; - return &ranges[0]; -} - -const ImWchar* ImFontAtlas::GetGlyphRangesChinese() -{ - static const ImWchar ranges[] = - { - 0x0020, 0x00FF, // Basic Latin + Latin Supplement - 0x3000, 0x30FF, // Punctuations, Hiragana, Katakana - 0x31F0, 0x31FF, // Katakana Phonetic Extensions - 0xFF00, 0xFFEF, // Half-width characters - 0x4e00, 0x9FAF, // CJK Ideograms - 0, - }; - return &ranges[0]; -} - -const ImWchar* ImFontAtlas::GetGlyphRangesJapanese() -{ - // Store the 1946 ideograms code points as successive offsets from the initial unicode codepoint 0x4E00. Each offset has an implicit +1. - // This encoding helps us reduce the source code size. - static const short offsets_from_0x4E00[] = - { - -1,0,1,3,0,0,0,0,1,0,5,1,1,0,7,4,6,10,0,1,9,9,7,1,3,19,1,10,7,1,0,1,0,5,1,0,6,4,2,6,0,0,12,6,8,0,3,5,0,1,0,9,0,0,8,1,1,3,4,5,13,0,0,8,2,17, - 4,3,1,1,9,6,0,0,0,2,1,3,2,22,1,9,11,1,13,1,3,12,0,5,9,2,0,6,12,5,3,12,4,1,2,16,1,1,4,6,5,3,0,6,13,15,5,12,8,14,0,0,6,15,3,6,0,18,8,1,6,14,1, - 5,4,12,24,3,13,12,10,24,0,0,0,1,0,1,1,2,9,10,2,2,0,0,3,3,1,0,3,8,0,3,2,4,4,1,6,11,10,14,6,15,3,4,15,1,0,0,5,2,2,0,0,1,6,5,5,6,0,3,6,5,0,0,1,0, - 11,2,2,8,4,7,0,10,0,1,2,17,19,3,0,2,5,0,6,2,4,4,6,1,1,11,2,0,3,1,2,1,2,10,7,6,3,16,0,8,24,0,0,3,1,1,3,0,1,6,0,0,0,2,0,1,5,15,0,1,0,0,2,11,19, - 1,4,19,7,6,5,1,0,0,0,0,5,1,0,1,9,0,0,5,0,2,0,1,0,3,0,11,3,0,2,0,0,0,0,0,9,3,6,4,12,0,14,0,0,29,10,8,0,14,37,13,0,31,16,19,0,8,30,1,20,8,3,48, - 21,1,0,12,0,10,44,34,42,54,11,18,82,0,2,1,2,12,1,0,6,2,17,2,12,7,0,7,17,4,2,6,24,23,8,23,39,2,16,23,1,0,5,1,2,15,14,5,6,2,11,0,8,6,2,2,2,14, - 20,4,15,3,4,11,10,10,2,5,2,1,30,2,1,0,0,22,5,5,0,3,1,5,4,1,0,0,2,2,21,1,5,1,2,16,2,1,3,4,0,8,4,0,0,5,14,11,2,16,1,13,1,7,0,22,15,3,1,22,7,14, - 22,19,11,24,18,46,10,20,64,45,3,2,0,4,5,0,1,4,25,1,0,0,2,10,0,0,0,1,0,1,2,0,0,9,1,2,0,0,0,2,5,2,1,1,5,5,8,1,1,1,5,1,4,9,1,3,0,1,0,1,1,2,0,0, - 2,0,1,8,22,8,1,0,0,0,0,4,2,1,0,9,8,5,0,9,1,30,24,2,6,4,39,0,14,5,16,6,26,179,0,2,1,1,0,0,0,5,2,9,6,0,2,5,16,7,5,1,1,0,2,4,4,7,15,13,14,0,0, - 3,0,1,0,0,0,2,1,6,4,5,1,4,9,0,3,1,8,0,0,10,5,0,43,0,2,6,8,4,0,2,0,0,9,6,0,9,3,1,6,20,14,6,1,4,0,7,2,3,0,2,0,5,0,3,1,0,3,9,7,0,3,4,0,4,9,1,6,0, - 9,0,0,2,3,10,9,28,3,6,2,4,1,2,32,4,1,18,2,0,3,1,5,30,10,0,2,2,2,0,7,9,8,11,10,11,7,2,13,7,5,10,0,3,40,2,0,1,6,12,0,4,5,1,5,11,11,21,4,8,3,7, - 8,8,33,5,23,0,0,19,8,8,2,3,0,6,1,1,1,5,1,27,4,2,5,0,3,5,6,3,1,0,3,1,12,5,3,3,2,0,7,7,2,1,0,4,0,1,1,2,0,10,10,6,2,5,9,7,5,15,15,21,6,11,5,20, - 4,3,5,5,2,5,0,2,1,0,1,7,28,0,9,0,5,12,5,5,18,30,0,12,3,3,21,16,25,32,9,3,14,11,24,5,66,9,1,2,0,5,9,1,5,1,8,0,8,3,3,0,1,15,1,4,8,1,2,7,0,7,2, - 8,3,7,5,3,7,10,2,1,0,0,2,25,0,6,4,0,10,0,4,2,4,1,12,5,38,4,0,4,1,10,5,9,4,0,14,4,2,5,18,20,21,1,3,0,5,0,7,0,3,7,1,3,1,1,8,1,0,0,0,3,2,5,2,11, - 6,0,13,1,3,9,1,12,0,16,6,2,1,0,2,1,12,6,13,11,2,0,28,1,7,8,14,13,8,13,0,2,0,5,4,8,10,2,37,42,19,6,6,7,4,14,11,18,14,80,7,6,0,4,72,12,36,27, - 7,7,0,14,17,19,164,27,0,5,10,7,3,13,6,14,0,2,2,5,3,0,6,13,0,0,10,29,0,4,0,3,13,0,3,1,6,51,1,5,28,2,0,8,0,20,2,4,0,25,2,10,13,10,0,16,4,0,1,0, - 2,1,7,0,1,8,11,0,0,1,2,7,2,23,11,6,6,4,16,2,2,2,0,22,9,3,3,5,2,0,15,16,21,2,9,20,15,15,5,3,9,1,0,0,1,7,7,5,4,2,2,2,38,24,14,0,0,15,5,6,24,14, - 5,5,11,0,21,12,0,3,8,4,11,1,8,0,11,27,7,2,4,9,21,59,0,1,39,3,60,62,3,0,12,11,0,3,30,11,0,13,88,4,15,5,28,13,1,4,48,17,17,4,28,32,46,0,16,0, - 18,11,1,8,6,38,11,2,6,11,38,2,0,45,3,11,2,7,8,4,30,14,17,2,1,1,65,18,12,16,4,2,45,123,12,56,33,1,4,3,4,7,0,0,0,3,2,0,16,4,2,4,2,0,7,4,5,2,26, - 2,25,6,11,6,1,16,2,6,17,77,15,3,35,0,1,0,5,1,0,38,16,6,3,12,3,3,3,0,9,3,1,3,5,2,9,0,18,0,25,1,3,32,1,72,46,6,2,7,1,3,14,17,0,28,1,40,13,0,20, - 15,40,6,38,24,12,43,1,1,9,0,12,6,0,6,2,4,19,3,7,1,48,0,9,5,0,5,6,9,6,10,15,2,11,19,3,9,2,0,1,10,1,27,8,1,3,6,1,14,0,26,0,27,16,3,4,9,6,2,23, - 9,10,5,25,2,1,6,1,1,48,15,9,15,14,3,4,26,60,29,13,37,21,1,6,4,0,2,11,22,23,16,16,2,2,1,3,0,5,1,6,4,0,0,4,0,0,8,3,0,2,5,0,7,1,7,3,13,2,4,10, - 3,0,2,31,0,18,3,0,12,10,4,1,0,7,5,7,0,5,4,12,2,22,10,4,2,15,2,8,9,0,23,2,197,51,3,1,1,4,13,4,3,21,4,19,3,10,5,40,0,4,1,1,10,4,1,27,34,7,21, - 2,17,2,9,6,4,2,3,0,4,2,7,8,2,5,1,15,21,3,4,4,2,2,17,22,1,5,22,4,26,7,0,32,1,11,42,15,4,1,2,5,0,19,3,1,8,6,0,10,1,9,2,13,30,8,2,24,17,19,1,4, - 4,25,13,0,10,16,11,39,18,8,5,30,82,1,6,8,18,77,11,13,20,75,11,112,78,33,3,0,0,60,17,84,9,1,1,12,30,10,49,5,32,158,178,5,5,6,3,3,1,3,1,4,7,6, - 19,31,21,0,2,9,5,6,27,4,9,8,1,76,18,12,1,4,0,3,3,6,3,12,2,8,30,16,2,25,1,5,5,4,3,0,6,10,2,3,1,0,5,1,19,3,0,8,1,5,2,6,0,0,0,19,1,2,0,5,1,2,5, - 1,3,7,0,4,12,7,3,10,22,0,9,5,1,0,2,20,1,1,3,23,30,3,9,9,1,4,191,14,3,15,6,8,50,0,1,0,0,4,0,0,1,0,2,4,2,0,2,3,0,2,0,2,2,8,7,0,1,1,1,3,3,17,11, - 91,1,9,3,2,13,4,24,15,41,3,13,3,1,20,4,125,29,30,1,0,4,12,2,21,4,5,5,19,11,0,13,11,86,2,18,0,7,1,8,8,2,2,22,1,2,6,5,2,0,1,2,8,0,2,0,5,2,1,0, - 2,10,2,0,5,9,2,1,2,0,1,0,4,0,0,10,2,5,3,0,6,1,0,1,4,4,33,3,13,17,3,18,6,4,7,1,5,78,0,4,1,13,7,1,8,1,0,35,27,15,3,0,0,0,1,11,5,41,38,15,22,6, - 14,14,2,1,11,6,20,63,5,8,27,7,11,2,2,40,58,23,50,54,56,293,8,8,1,5,1,14,0,1,12,37,89,8,8,8,2,10,6,0,0,0,4,5,2,1,0,1,1,2,7,0,3,3,0,4,6,0,3,2, - 19,3,8,0,0,0,4,4,16,0,4,1,5,1,3,0,3,4,6,2,17,10,10,31,6,4,3,6,10,126,7,3,2,2,0,9,0,0,5,20,13,0,15,0,6,0,2,5,8,64,50,3,2,12,2,9,0,0,11,8,20, - 109,2,18,23,0,0,9,61,3,0,28,41,77,27,19,17,81,5,2,14,5,83,57,252,14,154,263,14,20,8,13,6,57,39,38, - }; - static int ranges_unpacked = false; - static ImWchar ranges[8 + IM_ARRAYSIZE(offsets_from_0x4E00)*2 + 1] = - { - 0x0020, 0x00FF, // Basic Latin + Latin Supplement - 0x3000, 0x30FF, // Punctuations, Hiragana, Katakana - 0x31F0, 0x31FF, // Katakana Phonetic Extensions - 0xFF00, 0xFFEF, // Half-width characters - }; - if (!ranges_unpacked) - { - // Unpack - int codepoint = 0x4e00; - ImWchar* dst = &ranges[8]; - for (int n = 0; n < IM_ARRAYSIZE(offsets_from_0x4E00); n++, dst += 2) - dst[0] = dst[1] = (ImWchar)(codepoint += (offsets_from_0x4E00[n] + 1)); - dst[0] = 0; - ranges_unpacked = true; - } - return &ranges[0]; -} - -void ImFont::BuildLookupTable() -{ - int max_codepoint = 0; - for (size_t i = 0; i != Glyphs.size(); i++) - max_codepoint = ImMax(max_codepoint, (int)Glyphs[i].Codepoint); - - IndexXAdvance.clear(); - IndexXAdvance.resize((size_t)max_codepoint + 1); - IndexLookup.clear(); - IndexLookup.resize((size_t)max_codepoint + 1); - for (size_t i = 0; i < (size_t)max_codepoint + 1; i++) - { - IndexXAdvance[i] = -1.0f; - IndexLookup[i] = -1; - } - for (size_t i = 0; i < Glyphs.size(); i++) - { - const size_t codepoint = (int)Glyphs[i].Codepoint; - IndexXAdvance[codepoint] = Glyphs[i].XAdvance; - IndexLookup[codepoint] = (int)i; - } - - // Create a glyph to handle TAB - // FIXME: Needs proper TAB handling but it needs to be contextualized (can arbitrary say that each string starts at "column 0" - if (FindGlyph((unsigned short)' ')) - { - if (Glyphs.back().Codepoint != '\t') // So we can call this function multiple times - Glyphs.resize(Glyphs.size() + 1); - ImFont::Glyph& tab_glyph = Glyphs.back(); - tab_glyph = *FindGlyph((unsigned short)' '); - tab_glyph.Codepoint = '\t'; - tab_glyph.XAdvance *= 4; - IndexXAdvance[(size_t)tab_glyph.Codepoint] = (float)tab_glyph.XAdvance; - IndexLookup[(size_t)tab_glyph.Codepoint] = (int)(Glyphs.size()-1); - } - - FallbackGlyph = NULL; - FallbackGlyph = FindGlyph(FallbackChar); - FallbackXAdvance = FallbackGlyph ? FallbackGlyph->XAdvance : 0.0f; - for (size_t i = 0; i < (size_t)max_codepoint + 1; i++) - if (IndexXAdvance[i] < 0.0f) - IndexXAdvance[i] = FallbackXAdvance; -} - -void ImFont::SetFallbackChar(ImWchar c) -{ - FallbackChar = c; - BuildLookupTable(); -} - -const ImFont::Glyph* ImFont::FindGlyph(unsigned short c) const -{ - if (c < (int)IndexLookup.size()) - { - const int i = IndexLookup[c]; - if (i != -1) - return &Glyphs[i]; - } - return FallbackGlyph; -} - -// Convert UTF-8 to 32-bits character, process single character input. -// Based on stb_from_utf8() from github.com/nothings/stb/ -// We handle UTF-8 decoding error by skipping forward. -static int ImTextCharFromUtf8(unsigned int* out_char, const char* in_text, const char* in_text_end) -{ - unsigned int c = (unsigned int)-1; - const unsigned char* str = (const unsigned char*)in_text; - if (!(*str & 0x80)) - { - c = (unsigned int)(*str++); - *out_char = c; - return 1; - } - if ((*str & 0xe0) == 0xc0) - { - *out_char = 0; - if (in_text_end && in_text_end - (const char*)str < 2) return 0; - if (*str < 0xc2) return 0; - c = (unsigned int)((*str++ & 0x1f) << 6); - if ((*str & 0xc0) != 0x80) return 0; - c += (*str++ & 0x3f); - *out_char = c; - return 2; - } - if ((*str & 0xf0) == 0xe0) - { - *out_char = 0; - if (in_text_end && in_text_end - (const char*)str < 3) return 0; - if (*str == 0xe0 && (str[1] < 0xa0 || str[1] > 0xbf)) return 0; - if (*str == 0xed && str[1] > 0x9f) return 0; // str[1] < 0x80 is checked below - c = (unsigned int)((*str++ & 0x0f) << 12); - if ((*str & 0xc0) != 0x80) return 0; - c += (unsigned int)((*str++ & 0x3f) << 6); - if ((*str & 0xc0) != 0x80) return 0; - c += (*str++ & 0x3f); - *out_char = c; - return 3; - } - if ((*str & 0xf8) == 0xf0) - { - *out_char = 0; - if (in_text_end && in_text_end - (const char*)str < 4) return 0; - if (*str > 0xf4) return 0; - if (*str == 0xf0 && (str[1] < 0x90 || str[1] > 0xbf)) return 0; - if (*str == 0xf4 && str[1] > 0x8f) return 0; // str[1] < 0x80 is checked below - c = (unsigned int)((*str++ & 0x07) << 18); - if ((*str & 0xc0) != 0x80) return 0; - c += (unsigned int)((*str++ & 0x3f) << 12); - if ((*str & 0xc0) != 0x80) return 0; - c += (unsigned int)((*str++ & 0x3f) << 6); - if ((*str & 0xc0) != 0x80) return 0; - c += (*str++ & 0x3f); - // utf-8 encodings of values used in surrogate pairs are invalid - if ((c & 0xFFFFF800) == 0xD800) return 0; - *out_char = c; - return 4; - } - *out_char = 0; - return 0; -} - -static ptrdiff_t ImTextStrFromUtf8(ImWchar* buf, size_t buf_size, const char* in_text, const char* in_text_end, const char** in_text_remaining) -{ - ImWchar* buf_out = buf; - ImWchar* buf_end = buf + buf_size; - while (buf_out < buf_end-1 && (!in_text_end || in_text < in_text_end) && *in_text) - { - unsigned int c; - in_text += ImTextCharFromUtf8(&c, in_text, in_text_end); - if (c == 0) - break; - if (c < 0x10000) // FIXME: Losing characters that don't fit in 2 bytes - *buf_out++ = (ImWchar)c; - } - *buf_out = 0; - if (in_text_remaining) - *in_text_remaining = in_text; - return buf_out - buf; -} - -static int ImTextCountCharsFromUtf8(const char* in_text, const char* in_text_end) -{ - int char_count = 0; - while ((!in_text_end || in_text < in_text_end) && *in_text) - { - unsigned int c; - in_text += ImTextCharFromUtf8(&c, in_text, in_text_end); - if (c == 0) - break; - if (c < 0x10000) - char_count++; - } - return char_count; -} - -// Based on stb_to_utf8() from github.com/nothings/stb/ -static int ImTextCharToUtf8(char* buf, size_t buf_size, unsigned int c) -{ - if (c) - { - size_t i = 0; - size_t n = buf_size; - if (c < 0x80) - { - if (i+1 > n) return 0; - buf[i++] = (char)c; - return 1; - } - else if (c < 0x800) - { - if (i+2 > n) return 0; - buf[i++] = (char)(0xc0 + (c >> 6)); - buf[i++] = (char)(0x80 + (c & 0x3f)); - return 2; - } - else if (c >= 0xdc00 && c < 0xe000) - { - return 0; - } - else if (c >= 0xd800 && c < 0xdc00) - { - if (i+4 > n) return 0; - buf[i++] = (char)(0xf0 + (c >> 18)); - buf[i++] = (char)(0x80 + ((c >> 12) & 0x3f)); - buf[i++] = (char)(0x80 + ((c >> 6) & 0x3f)); - buf[i++] = (char)(0x80 + ((c ) & 0x3f)); - return 4; - } - //else if (c < 0x10000) - { - if (i+3 > n) return 0; - buf[i++] = (char)(0xe0 + (c >> 12)); - buf[i++] = (char)(0x80 + ((c>> 6) & 0x3f)); - buf[i++] = (char)(0x80 + ((c ) & 0x3f)); - return 3; - } - } - return 0; -} - -static ptrdiff_t ImTextStrToUtf8(char* buf, size_t buf_size, const ImWchar* in_text, const ImWchar* in_text_end) -{ - char* buf_out = buf; - const char* buf_end = buf + buf_size; - while (buf_out < buf_end-1 && (!in_text_end || in_text < in_text_end) && *in_text) - { - buf_out += ImTextCharToUtf8(buf_out, (uintptr_t)(buf_end-buf_out-1), (unsigned int)*in_text); - in_text++; - } - *buf_out = 0; - return buf_out - buf; -} - -static int ImTextCountUtf8BytesFromStr(const ImWchar* in_text, const ImWchar* in_text_end) -{ - int bytes_count = 0; - while ((!in_text_end || in_text < in_text_end) && *in_text) - { - char dummy[5]; // FIXME-OPT - bytes_count += ImTextCharToUtf8(dummy, 5, (unsigned int)*in_text); - in_text++; - } - return bytes_count; -} - -const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) const -{ - // Simple word-wrapping for English, not full-featured. Please submit failing cases! - // FIXME: Much possible improvements (don't cut things like "word !", "word!!!" but cut within "word,,,,", more sensible support for punctuations, support for Unicode punctuations, etc.) - - // For references, possible wrap point marked with ^ - // "aaa bbb, ccc,ddd. eee fff. ggg!" - // ^ ^ ^ ^ ^__ ^ ^ - - // List of hardcoded separators: .,;!?'" - - // Skip extra blanks after a line returns (that includes not counting them in width computation) - // e.g. "Hello world" --> "Hello" "World" - - // Cut words that cannot possibly fit within one line. - // e.g.: "The tropical fish" with ~5 characters worth of width --> "The tr" "opical" "fish" - - float line_width = 0.0f; - float word_width = 0.0f; - float blank_width = 0.0f; - - const char* word_end = text; - const char* prev_word_end = NULL; - bool inside_word = true; - - const char* s = text; - while (s < text_end) - { - unsigned int c = (unsigned int)*s; - const char* next_s; - if (c < 0x80) - next_s = s + 1; - else - next_s = s + ImTextCharFromUtf8(&c, s, text_end); - if (c == 0) - break; - - if (c == '\n') - { - line_width = word_width = blank_width = 0.0f; - inside_word = true; - s = next_s; - continue; - } - - const float char_width = ((size_t)c < IndexXAdvance.size()) ? IndexXAdvance[(size_t)c] * scale : FallbackXAdvance; - if (ImCharIsSpace(c)) - { - if (inside_word) - { - line_width += blank_width; - blank_width = 0.0f; - } - blank_width += char_width; - inside_word = false; - } - else - { - word_width += char_width; - if (inside_word) - { - word_end = next_s; - } - else - { - prev_word_end = word_end; - line_width += word_width + blank_width; - word_width = blank_width = 0.0f; - } - - // Allow wrapping after punctuation. - inside_word = !(c == '.' || c == ',' || c == ';' || c == '!' || c == '?' || c == '\"'); - } - - // We ignore blank width at the end of the line (they can be skipped) - if (line_width + word_width >= wrap_width) - { - // Words that cannot possibly fit within an entire line will be cut anywhere. - if (word_width < wrap_width) - s = prev_word_end ? prev_word_end : word_end; - break; - } - - s = next_s; - } - - return s; -} - -ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end, const char** remaining) const -{ - if (!text_end) - text_end = text_begin + strlen(text_begin); // FIXME-OPT: Need to avoid this. - - const float scale = size / FontSize; - const float line_height = FontSize * scale; - - ImVec2 text_size = ImVec2(0,0); - float line_width = 0.0f; - - const bool word_wrap_enabled = (wrap_width > 0.0f); - const char* word_wrap_eol = NULL; - - const char* s = text_begin; - while (s < text_end) - { - if (word_wrap_enabled) - { - // Calculate how far we can render. Requires two passes on the string data but keeps the code simple and not intrusive for what's essentially an uncommon feature. - if (!word_wrap_eol) - { - word_wrap_eol = CalcWordWrapPositionA(scale, s, text_end, wrap_width - line_width); - if (word_wrap_eol == s) // Wrap_width is too small to fit anything. Force displaying 1 character to minimize the height discontinuity. - word_wrap_eol++; // +1 may not be a character start point in UTF-8 but it's ok because we use s >= word_wrap_eol below - } - - if (s >= word_wrap_eol) - { - if (text_size.x < line_width) - text_size.x = line_width; - text_size.y += line_height; - line_width = 0.0f; - word_wrap_eol = NULL; - - // Wrapping skips upcoming blanks - while (s < text_end) - { - const char c = *s; - if (ImCharIsSpace(c)) { s++; } else if (c == '\n') { s++; break; } else { break; } - } - continue; - } - } - - // Decode and advance source (handle unlikely UTF-8 decoding failure by skipping to the next byte) - const char* prev_s = s; - unsigned int c = (unsigned int)*s; - if (c < 0x80) - { - s += 1; - } - else - { - s += ImTextCharFromUtf8(&c, s, text_end); - if (c == 0) - break; - } - - if (c == '\n') - { - text_size.x = ImMax(text_size.x, line_width); - text_size.y += line_height; - line_width = 0.0f; - continue; - } - - const float char_width = ((size_t)c < IndexXAdvance.size()) ? IndexXAdvance[(size_t)c] * scale : FallbackXAdvance; - if (line_width + char_width >= max_width) - { - s = prev_s; - break; - } - - line_width += char_width; - } - - if (line_width > 0 || text_size.y == 0.0f) - { - if (text_size.x < line_width) - text_size.x = line_width; - text_size.y += line_height; - } - - if (remaining) - *remaining = s; - - return text_size; -} - -ImVec2 ImFont::CalcTextSizeW(float size, float max_width, const ImWchar* text_begin, const ImWchar* text_end, const ImWchar** remaining) const -{ - if (!text_end) - text_end = text_begin + ImStrlenW(text_begin); - - const float scale = size / FontSize; - const float line_height = FontSize * scale; - - ImVec2 text_size = ImVec2(0,0); - float line_width = 0.0f; - - const ImWchar* s = text_begin; - while (s < text_end) - { - const unsigned int c = (unsigned int)(*s++); - - if (c == '\n') - { - text_size.x = ImMax(text_size.x, line_width); - text_size.y += line_height; - line_width = 0.0f; - continue; - } - - const float char_width = ((size_t)c < IndexXAdvance.size()) ? IndexXAdvance[(size_t)c] * scale : FallbackXAdvance; - if (line_width + char_width >= max_width) - { - s--; - break; - } - - line_width += char_width; - } - - if (line_width > 0 || text_size.y == 0.0f) - { - if (text_size.x < line_width) - text_size.x = line_width; - text_size.y += line_height; - } - - if (remaining) - *remaining = s; - - return text_size; -} - -void ImFont::RenderText(float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect_ref, const char* text_begin, const char* text_end, ImDrawList* draw_list, float wrap_width, const ImVec2* cpu_clip_max) const -{ - if (!text_end) - text_end = text_begin + strlen(text_begin); - - const float scale = size / FontSize; - const float line_height = FontSize * scale; - - // Align to be pixel perfect - pos.x = (float)(int)pos.x + DisplayOffset.x; - pos.y = (float)(int)pos.y + DisplayOffset.y; - - const bool word_wrap_enabled = (wrap_width > 0.0f); - const char* word_wrap_eol = NULL; - - ImVec4 clip_rect = clip_rect_ref; - if (cpu_clip_max) - { - clip_rect.z = ImMin(clip_rect.z, cpu_clip_max->x); - clip_rect.w = ImMin(clip_rect.w, cpu_clip_max->y); - } - float x = pos.x; - float y = pos.y; - - ImDrawVert* out_vertices = draw_list->vtx_write; - - const char* s = text_begin; - while (s < text_end) - { - if (word_wrap_enabled) - { - // Calculate how far we can render. Requires two passes on the string data but keeps the code simple and not intrusive for what's essentially an uncommon feature. - if (!word_wrap_eol) - { - word_wrap_eol = CalcWordWrapPositionA(scale, s, text_end, wrap_width - (x - pos.x)); - if (word_wrap_eol == s) // Wrap_width is too small to fit anything. Force displaying 1 character to minimize the height discontinuity. - word_wrap_eol++; // +1 may not be a character start point in UTF-8 but it's ok because we use s >= word_wrap_eol below - } - - if (s >= word_wrap_eol) - { - x = pos.x; - y += line_height; - word_wrap_eol = NULL; - - // Wrapping skips upcoming blanks - while (s < text_end) - { - const char c = *s; - if (ImCharIsSpace(c)) { s++; } else if (c == '\n') { s++; break; } else { break; } - } - continue; - } - } - - // Decode and advance source (handle unlikely UTF-8 decoding failure by skipping to the next byte) - unsigned int c = (unsigned int)*s; - if (c < 0x80) - { - s += 1; - } - else - { - s += ImTextCharFromUtf8(&c, s, text_end); - if (c == 0) - break; - } - - if (c == '\n') - { - x = pos.x; - y += line_height; - continue; - } - - float char_width = 0.0f; - if (const Glyph* glyph = FindGlyph((unsigned short)c)) - { - char_width = glyph->XAdvance * scale; - if (c != ' ' && c != '\t') - { - // Clipping on Y is more likely - float y1 = (float)(y + glyph->YOffset * scale); - float y2 = (float)(y1 + glyph->Height * scale); - if (y1 <= clip_rect.w && y2 >= clip_rect.y) - { - float x1 = (float)(x + glyph->XOffset * scale); - float x2 = (float)(x1 + glyph->Width * scale); - if (x1 <= clip_rect.z && x2 >= clip_rect.x) - { - // Render a character - float u1 = glyph->U0; - float v1 = glyph->V0; - float u2 = glyph->U1; - float v2 = glyph->V1; - - // CPU side clipping used to fit text in their frame when the frame is too small. Only does clipping for axis aligned quad and in the "max" direction (bottom-right) - if (cpu_clip_max) - { - if (x2 > cpu_clip_max->x) - { - const float clip_tx = (cpu_clip_max->x - x1) / (x2 - x1); - x2 = cpu_clip_max->x; - u2 = u1 + clip_tx * (u2 - u1); - } - if (y2 > cpu_clip_max->y) - { - const float clip_ty = (cpu_clip_max->y - y1) / (y2 - y1); - y2 = cpu_clip_max->y; - v2 = v1 + clip_ty * (v2 - v1); - } - } - - // NB: we are not calling PrimRectUV() here because non-inlined causes too much overhead in a debug build. - out_vertices[0].pos = ImVec2(x1, y1); - out_vertices[0].uv = ImVec2(u1, v1); - out_vertices[0].col = col; - - out_vertices[1].pos = ImVec2(x2, y1); - out_vertices[1].uv = ImVec2(u2, v1); - out_vertices[1].col = col; - - out_vertices[2].pos = ImVec2(x2, y2); - out_vertices[2].uv = ImVec2(u2, v2); - out_vertices[2].col = col; - - out_vertices[3] = out_vertices[0]; - out_vertices[4] = out_vertices[2]; - - out_vertices[5].pos = ImVec2(x1, y2); - out_vertices[5].uv = ImVec2(u1, v2); - out_vertices[5].col = col; - - out_vertices += 6; - } - } - } - } - - x += char_width; - } - - draw_list->vtx_write = out_vertices; -} - -//----------------------------------------------------------------------------- -// PLATFORM DEPENDANT HELPERS -//----------------------------------------------------------------------------- - -#if defined(_MSC_VER) && !defined(IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS) - -#ifndef _WINDOWS_ -#define WIN32_LEAN_AND_MEAN -#include -#endif - -// Win32 API clipboard implementation -static const char* GetClipboardTextFn_DefaultImpl() -{ - static char* buf_local = NULL; - if (buf_local) - { - ImGui::MemFree(buf_local); - buf_local = NULL; - } - if (!OpenClipboard(NULL)) - return NULL; - HANDLE wbuf_handle = GetClipboardData(CF_UNICODETEXT); - if (wbuf_handle == NULL) - return NULL; - if (ImWchar* wbuf_global = (ImWchar*)GlobalLock(wbuf_handle)) - { - int buf_len = ImTextCountUtf8BytesFromStr(wbuf_global, NULL) + 1; - buf_local = (char*)ImGui::MemAlloc(buf_len * sizeof(char)); - ImTextStrToUtf8(buf_local, buf_len, wbuf_global, NULL); - } - GlobalUnlock(wbuf_handle); - CloseClipboard(); - return buf_local; -} - -// Win32 API clipboard implementation -static void SetClipboardTextFn_DefaultImpl(const char* text) -{ - if (!OpenClipboard(NULL)) - return; - - const int wbuf_length = ImTextCountCharsFromUtf8(text, NULL) + 1; - HGLOBAL wbuf_handle = GlobalAlloc(GMEM_MOVEABLE, (SIZE_T)wbuf_length * sizeof(ImWchar)); - if (wbuf_handle == NULL) - return; - ImWchar* wbuf_global = (ImWchar*)GlobalLock(wbuf_handle); - ImTextStrFromUtf8(wbuf_global, wbuf_length, text, NULL); - GlobalUnlock(wbuf_handle); - EmptyClipboard(); - SetClipboardData(CF_UNICODETEXT, wbuf_handle); - CloseClipboard(); -} - -#else - -// Local ImGui-only clipboard implementation, if user hasn't defined better clipboard handlers -static const char* GetClipboardTextFn_DefaultImpl() -{ - return GImGui->PrivateClipboard; -} - -// Local ImGui-only clipboard implementation, if user hasn't defined better clipboard handlers -static void SetClipboardTextFn_DefaultImpl(const char* text) -{ - ImGuiState& g = *GImGui; - if (g.PrivateClipboard) - { - ImGui::MemFree(g.PrivateClipboard); - g.PrivateClipboard = NULL; - } - const char* text_end = text + strlen(text); - g.PrivateClipboard = (char*)ImGui::MemAlloc((size_t)(text_end - text) + 1); - memcpy(g.PrivateClipboard, text, (size_t)(text_end - text)); - g.PrivateClipboard[(size_t)(text_end - text)] = 0; -} - -#endif - -#if defined(_MSC_VER) && !defined(IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS) - -#ifndef _WINDOWS_ -#define WIN32_LEAN_AND_MEAN -#include -#endif -#include -#pragma comment(lib, "imm32") - -static void ImeSetInputScreenPosFn_DefaultImpl(int x, int y) -{ - // Notify OS Input Method Editor of text input position - if (HWND hwnd = (HWND)GImGui->IO.ImeWindowHandle) - if (HIMC himc = ImmGetContext(hwnd)) - { - COMPOSITIONFORM cf; - cf.ptCurrentPos.x = x; - cf.ptCurrentPos.y = y; - cf.dwStyle = CFS_FORCE_POSITION; - ImmSetCompositionWindow(himc, &cf); - } -} - -#else - -static void ImeSetInputScreenPosFn_DefaultImpl(int, int) -{ -} - -#endif - -#ifdef IMGUI_DISABLE_TEST_WINDOWS - -void ImGui::ShowUserGuide() {} -void ImGui::ShowStyleEditor(ImGuiStyle*) {} -void ImGui::ShowTestWindow(bool*) {} -void ImGui::ShowMetricsWindow(bool*) {} - -#else - -//----------------------------------------------------------------------------- -// HELP -//----------------------------------------------------------------------------- - -void ImGui::ShowUserGuide() -{ - ImGuiState& g = *GImGui; - - ImGui::BulletText("Double-click on title bar to collapse window."); - ImGui::BulletText("Click and drag on lower right corner to resize window."); - ImGui::BulletText("Click and drag on any empty space to move window."); - ImGui::BulletText("Mouse Wheel to scroll."); - if (g.IO.FontAllowUserScaling) - ImGui::BulletText("CTRL+Mouse Wheel to zoom window contents."); - ImGui::BulletText("TAB/SHIFT+TAB to cycle through keyboard editable fields."); - ImGui::BulletText("CTRL+Click on a slider to input text."); - ImGui::BulletText( - "While editing text:\n" - "- Hold SHIFT or use mouse to select text\n" - "- CTRL+Left/Right to word jump\n" - "- CTRL+A select all\n" - "- CTRL+X,CTRL+C,CTRL+V clipboard\n" - "- CTRL+Z,CTRL+Y undo/redo\n" - "- ESCAPE to revert\n" - "- You can apply arithmetic operators +,*,/ on numerical values.\n" - " Use +- to subtract.\n"); -} - -void ImGui::ShowStyleEditor(ImGuiStyle* ref) -{ - ImGuiState& g = *GImGui; - ImGuiStyle& style = g.Style; - - const ImGuiStyle def; // Default style - - if (ImGui::Button("Revert Style")) - g.Style = ref ? *ref : def; - if (ref) - { - ImGui::SameLine(); - if (ImGui::Button("Save Style")) - *ref = g.Style; - } - - ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.55f); - - if (ImGui::TreeNode("Sizes")) - { - ImGui::SliderFloat("Alpha", &style.Alpha, 0.20f, 1.0f, "%.2f"); // Not exposing zero here so user doesn't "lose" the UI. But application code could have a toggle to switch between zero and non-zero. - ImGui::SliderFloat2("WindowPadding", (float*)&style.WindowPadding, 0.0f, 20.0f, "%.0f"); - ImGui::SliderFloat("WindowRounding", &style.WindowRounding, 0.0f, 16.0f, "%.0f"); - ImGui::SliderFloat("ChildWindowRounding", &style.ChildWindowRounding, 0.0f, 16.0f, "%.0f"); - ImGui::SliderFloat2("FramePadding", (float*)&style.FramePadding, 0.0f, 20.0f, "%.0f"); - ImGui::SliderFloat("FrameRounding", &style.FrameRounding, 0.0f, 16.0f, "%.0f"); - ImGui::SliderFloat2("ItemSpacing", (float*)&style.ItemSpacing, 0.0f, 20.0f, "%.0f"); - ImGui::SliderFloat2("ItemInnerSpacing", (float*)&style.ItemInnerSpacing, 0.0f, 20.0f, "%.0f"); - ImGui::SliderFloat2("TouchExtraPadding", (float*)&style.TouchExtraPadding, 0.0f, 10.0f, "%.0f"); - ImGui::SliderFloat("IndentSpacing", &style.IndentSpacing, 0.0f, 20.0f, "%.0f"); - ImGui::SliderFloat("ScrollBarWidth", &style.ScrollbarWidth, 1.0f, 20.0f, "%.0f"); - ImGui::SliderFloat("GrabMinSize", &style.GrabMinSize, 1.0f, 20.0f, "%.0f"); - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Colors")) - { - static int output_dest = 0; - static bool output_only_modified = false; - if (ImGui::Button("Output Colors")) - { - if (output_dest == 0) - ImGui::LogToClipboard(); - else - ImGui::LogToTTY(); - ImGui::LogText("ImGuiStyle& style = ImGui::GetStyle();" STR_NEWLINE); - for (int i = 0; i < ImGuiCol_COUNT; i++) - { - const ImVec4& col = style.Colors[i]; - const char* name = ImGui::GetStyleColName(i); - if (!output_only_modified || memcmp(&col, (ref ? &ref->Colors[i] : &def.Colors[i]), sizeof(ImVec4)) != 0) - ImGui::LogText("style.Colors[ImGuiCol_%s]%*s= ImVec4(%.2ff, %.2ff, %.2ff, %.2ff);" STR_NEWLINE, name, 22 - strlen(name), "", col.x, col.y, col.z, col.w); - } - ImGui::LogFinish(); - } - ImGui::SameLine(); ImGui::PushItemWidth(150); ImGui::Combo("##output_type", &output_dest, "To Clipboard\0To TTY"); ImGui::PopItemWidth(); - ImGui::SameLine(); ImGui::Checkbox("Only Modified Fields", &output_only_modified); - - static ImGuiColorEditMode edit_mode = ImGuiColorEditMode_RGB; - ImGui::RadioButton("RGB", &edit_mode, ImGuiColorEditMode_RGB); - ImGui::SameLine(); - ImGui::RadioButton("HSV", &edit_mode, ImGuiColorEditMode_HSV); - ImGui::SameLine(); - ImGui::RadioButton("HEX", &edit_mode, ImGuiColorEditMode_HEX); - //ImGui::Text("Tip: Click on colored square to change edit mode."); - - static ImGuiTextFilter filter; - filter.Draw("Filter colors", 200); - - ImGui::BeginChild("#colors", ImVec2(0, 300), true); - - ImGui::ColorEditMode(edit_mode); - for (int i = 0; i < ImGuiCol_COUNT; i++) - { - const char* name = ImGui::GetStyleColName(i); - if (!filter.PassFilter(name)) - continue; - ImGui::PushID(i); - ImGui::ColorEdit4(name, (float*)&style.Colors[i], true); - if (memcmp(&style.Colors[i], (ref ? &ref->Colors[i] : &def.Colors[i]), sizeof(ImVec4)) != 0) - { - ImGui::SameLine(); if (ImGui::Button("Revert")) style.Colors[i] = ref ? ref->Colors[i] : def.Colors[i]; - if (ref) { ImGui::SameLine(); if (ImGui::Button("Save")) ref->Colors[i] = style.Colors[i]; } - } - ImGui::PopID(); - } - ImGui::EndChild(); - - ImGui::TreePop(); - } - - ImGui::PopItemWidth(); -} - -//----------------------------------------------------------------------------- -// SAMPLE CODE -//----------------------------------------------------------------------------- - -static void ShowExampleAppConsole(bool* opened); -static void ShowExampleAppLongText(bool* opened); -static void ShowExampleAppAutoResize(bool* opened); -static void ShowExampleAppFixedOverlay(bool* opened); -static void ShowExampleAppManipulatingWindowTitle(bool* opened); -static void ShowExampleAppCustomRendering(bool* opened); - -// Demonstrate ImGui features (unfortunately this makes this function a little bloated!) -void ImGui::ShowTestWindow(bool* opened) -{ - // Examples apps - static bool show_app_metrics = false; - static bool show_app_console = false; - static bool show_app_long_text = false; - static bool show_app_auto_resize = false; - static bool show_app_fixed_overlay = false; - static bool show_app_custom_rendering = false; - static bool show_app_manipulating_window_title = false; - if (show_app_metrics) - ImGui::ShowMetricsWindow(&show_app_metrics); - if (show_app_console) - ShowExampleAppConsole(&show_app_console); - if (show_app_long_text) - ShowExampleAppLongText(&show_app_long_text); - if (show_app_auto_resize) - ShowExampleAppAutoResize(&show_app_auto_resize); - if (show_app_fixed_overlay) - ShowExampleAppFixedOverlay(&show_app_fixed_overlay); - if (show_app_manipulating_window_title) - ShowExampleAppManipulatingWindowTitle(&show_app_manipulating_window_title); - if (show_app_custom_rendering) - ShowExampleAppCustomRendering(&show_app_custom_rendering); - - static bool no_titlebar = false; - static bool no_border = true; - static bool no_resize = false; - static bool no_move = false; - static bool no_scrollbar = false; - static bool no_collapse = false; - static float bg_alpha = 0.65f; - - // Demonstrate the various window flags. Typically you would just use the default. - ImGuiWindowFlags window_flags = 0; - if (no_titlebar) window_flags |= ImGuiWindowFlags_NoTitleBar; - if (!no_border) window_flags |= ImGuiWindowFlags_ShowBorders; - if (no_resize) window_flags |= ImGuiWindowFlags_NoResize; - if (no_move) window_flags |= ImGuiWindowFlags_NoMove; - if (no_scrollbar) window_flags |= ImGuiWindowFlags_NoScrollbar; - if (no_collapse) window_flags |= ImGuiWindowFlags_NoCollapse; - if (!ImGui::Begin("ImGui Test", opened, ImVec2(550,680), bg_alpha, window_flags)) - { - // Early out if the window is collapsed, as an optimization. - ImGui::End(); - return; - } - - //ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.65f); // 2/3 of the space for widget and 1/3 for labels - ImGui::PushItemWidth(-140); // Right align, keep 140 pixels for labels - - ImGui::Text("ImGui says hello."); - //ImGui::Text("MousePos (%g, %g)", ImGui::GetIO().MousePos.x, ImGui::GetIO().MousePos.y); - //ImGui::Text("MouseWheel %d", ImGui::GetIO().MouseWheel); - //ImGui::Text("KeyMods %s%s%s", ImGui::GetIO().KeyCtrl ? "CTRL" : "", ImGui::GetIO().KeyShift ? "SHIFT" : "", ImGui::GetIO().KeyAlt? "ALT" : ""); - //ImGui::Text("WantCaptureMouse: %d", ImGui::GetIO().WantCaptureMouse); - //ImGui::Text("WantCaptureKeyboard: %d", ImGui::GetIO().WantCaptureKeyboard); - - ImGui::Spacing(); - if (ImGui::CollapsingHeader("Help")) - { - ImGui::TextWrapped("This window is being created by the ShowTestWindow() function. Please refer to the code for programming reference.\n\nUser Guide:"); - ImGui::ShowUserGuide(); - } - - if (ImGui::CollapsingHeader("Window options")) - { - ImGui::Checkbox("no titlebar", &no_titlebar); ImGui::SameLine(150); - ImGui::Checkbox("no border", &no_border); ImGui::SameLine(300); - ImGui::Checkbox("no resize", &no_resize); - ImGui::Checkbox("no move", &no_move); ImGui::SameLine(150); - ImGui::Checkbox("no scrollbar", &no_scrollbar); ImGui::SameLine(300); - ImGui::Checkbox("no collapse", &no_collapse); - ImGui::SliderFloat("bg alpha", &bg_alpha, 0.0f, 1.0f); - - if (ImGui::TreeNode("Style")) - { - ImGui::ShowStyleEditor(); - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Fonts")) - { - ImGui::TextWrapped("Tip: Load fonts with GetIO().Fonts->AddFontFromFileTTF()."); - for (size_t i = 0; i < ImGui::GetIO().Fonts->Fonts.size(); i++) - { - ImFont* font = ImGui::GetIO().Fonts->Fonts[i]; - ImGui::BulletText("Font %d: %.2f pixels, %d glyphs", i, font->FontSize, font->Glyphs.size()); - ImGui::TreePush((void*)i); - ImGui::PushFont(font); - ImGui::Text("The quick brown fox jumps over the lazy dog"); - ImGui::PopFont(); - if (i > 0 && ImGui::Button("Set as default")) - { - ImGui::GetIO().Fonts->Fonts[i] = ImGui::GetIO().Fonts->Fonts[0]; - ImGui::GetIO().Fonts->Fonts[0] = font; - } - ImGui::SliderFloat("font scale", &font->Scale, 0.3f, 2.0f, "%.1f"); // scale only this font - ImGui::TreePop(); - } - static float window_scale = 1.0f; - ImGui::SliderFloat("this window scale", &window_scale, 0.3f, 2.0f, "%.1f"); // scale only this window - ImGui::SliderFloat("global scale", &ImGui::GetIO().FontGlobalScale, 0.3f, 2.0f, "%.1f"); // scale everything - ImGui::SetWindowFontScale(window_scale); - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Logging")) - { - ImGui::LogButtons(); - ImGui::TreePop(); - } - } - - if (ImGui::CollapsingHeader("Widgets")) - { - static bool a=false; - if (ImGui::Button("Button")) { printf("Clicked\n"); a ^= 1; } - if (a) - { - ImGui::SameLine(); - ImGui::Text("Thanks for clicking me!"); - } - - if (ImGui::TreeNode("Tree")) - { - for (size_t i = 0; i < 5; i++) - { - if (ImGui::TreeNode((void*)i, "Child %d", i)) - { - ImGui::Text("blah blah"); - ImGui::SameLine(); - if (ImGui::SmallButton("print")) - printf("Child %d pressed", (int)i); - ImGui::TreePop(); - } - } - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Bullets")) - { - ImGui::BulletText("Bullet point 1"); - ImGui::BulletText("Bullet point 2\nOn multiple lines"); - ImGui::Bullet(); ImGui::Text("Bullet point 3 (two calls)"); - ImGui::Bullet(); ImGui::SmallButton("Button 1"); - ImGui::Bullet(); ImGui::SmallButton("Button 2"); - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Colored Text")) - { - // Using shortcut. You can use PushStyleColor()/PopStyleColor() for more flexibility. - ImGui::TextColored(ImVec4(1.0f,0.0f,1.0f,1.0f), "Pink"); - ImGui::TextColored(ImVec4(1.0f,1.0f,0.0f,1.0f), "Yellow"); - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Word Wrapping")) - { - // Using shortcut. You can use PushTextWrapPos()/PopTextWrapPos() for more flexibility. - ImGui::TextWrapped("This text should automatically wrap on the edge of the window. The current implementation for text wrapping follows simple rules that works for English and possibly other languages."); - ImGui::Spacing(); - - static float wrap_width = 200.0f; - ImGui::SliderFloat("Wrap width", &wrap_width, -20, 600, "%.0f"); - - ImGui::Text("Test paragraph 1:"); - ImGui::GetWindowDrawList()->AddRectFilled(ImGui::GetCursorScreenPos() + ImVec2(wrap_width, 0.0f), ImGui::GetCursorScreenPos() + ImVec2(wrap_width+10, ImGui::GetTextLineHeight()), 0xFFFF00FF); - ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + wrap_width); - ImGui::Text("lazy dog. This paragraph is made to fit within %.0f pixels. The quick brown fox jumps over the lazy dog.", wrap_width); - ImGui::GetWindowDrawList()->AddRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), 0xFF00FFFF); - ImGui::PopTextWrapPos(); - - ImGui::Text("Test paragraph 2:"); - ImGui::GetWindowDrawList()->AddRectFilled(ImGui::GetCursorScreenPos() + ImVec2(wrap_width, 0.0f), ImGui::GetCursorScreenPos() + ImVec2(wrap_width+10, ImGui::GetTextLineHeight()), 0xFFFF00FF); - ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + wrap_width); - ImGui::Text("aaaaaaaa bbbbbbbb, cccccccc,dddddddd. eeeeeeee ffffffff. gggggggg!hhhhhhhh"); - ImGui::GetWindowDrawList()->AddRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), 0xFF00FFFF); - ImGui::PopTextWrapPos(); - - ImGui::TreePop(); - } - - if (ImGui::TreeNode("UTF-8 Text")) - { - // UTF-8 test with Japanese characters - // (needs a suitable font, try Arial Unicode or M+ fonts http://mplus-fonts.sourceforge.jp/mplus-outline-fonts/index-en.html) - // Most compiler appears to support UTF-8 in source code (with Visual Studio you need to save your file as 'UTF-8 without signature') - // However for the sake for maximum portability here we are *not* including raw UTF-8 character in this source file, instead we encode the string with hexadecimal constants. - // In your own application be reasonable and use UTF-8 in source or retrieve the data from file system! - // Note that characters values are preserved even if the font cannot be displayed, so you can safely copy & paste garbled characters into another application. - ImGui::TextWrapped("CJK text will only appears if the font was loaded with the appropriate CJK character ranges. Call io.Font->LoadFromFileTTF() manually to load extra character ranges."); - ImGui::Text("Hiragana: \xe3\x81\x8b\xe3\x81\x8d\xe3\x81\x8f\xe3\x81\x91\xe3\x81\x93 (kakikukeko)"); - ImGui::Text("Kanjis: \xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e (nihongo)"); - static char buf[32] = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e"; - ImGui::InputText("UTF-8 input", buf, IM_ARRAYSIZE(buf)); - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Clipping")) - { - static ImVec2 size(80, 20); - ImGui::TextWrapped("On a per-widget basis we are occasionally clipping text if it won't fit in its frame."); - ImGui::SliderFloat2("size", (float*)&size, 5.0f, 200.0f); - ImGui::Button("Line 1 hello\nLine 2 clip me!", size); - ImGui::TextWrapped("Otherwise we are doing coarser clipping + passing a scissor rectangle to the renderer. The system is designed to try minimizing both execution and rendering cost."); - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Images")) - { - ImGui::TextWrapped("Below we are displaying the font texture (which is the only texture we have access to in this demo). Use the 'ImTextureID' type as storage to pass pointers or identifier to your own texture data. Hover the texture for a zoomed view!"); - ImVec2 tex_screen_pos = ImGui::GetCursorScreenPos(); - float tex_w = (float)ImGui::GetIO().Fonts->TexWidth; - float tex_h = (float)ImGui::GetIO().Fonts->TexHeight; - ImTextureID tex_id = ImGui::GetIO().Fonts->TexID; - ImGui::Image(tex_id, ImVec2(tex_w, tex_h), ImVec2(0,0), ImVec2(1,1), ImColor(255,255,255,255), ImColor(255,255,255,128)); - if (ImGui::IsItemHovered()) - { - ImGui::BeginTooltip(); - float focus_sz = 32.0f; - float focus_x = ImClamp(ImGui::GetMousePos().x - tex_screen_pos.x - focus_sz * 0.5f, 0.0f, tex_w - focus_sz); - float focus_y = ImClamp(ImGui::GetMousePos().y - tex_screen_pos.y - focus_sz * 0.5f, 0.0f, tex_h - focus_sz); - ImGui::Text("Min: (%.2f, %.2f)", focus_x, focus_y); - ImGui::Text("Max: (%.2f, %.2f)", focus_x + focus_sz, focus_y + focus_sz); - ImVec2 uv0 = ImVec2((focus_x) / tex_w, (focus_y) / tex_h); - ImVec2 uv1 = ImVec2((focus_x + focus_sz) / tex_w, (focus_y + focus_sz) / tex_h); - ImGui::Image(tex_id, ImVec2(128,128), uv0, uv1, ImColor(255,255,255,255), ImColor(255,255,255,128)); - ImGui::EndTooltip(); - } - ImGui::TextWrapped("And now some textured buttons.."); - static int pressed_count = 0; - for (int i = 0; i < 8; i++) - { - if (i > 0) - ImGui::SameLine(); - ImGui::PushID(i); - int frame_padding = -1 + i; // -1 padding uses default padding - if (ImGui::ImageButton(tex_id, ImVec2(32,32), ImVec2(0,0), ImVec2(32.0f/tex_w,32/tex_h), frame_padding)) - pressed_count += 1; - ImGui::PopID(); - } - ImGui::Text("Pressed %d times.", pressed_count); - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Selectables")) - { - if (ImGui::TreeNode("Basic")) - { - static bool selected[3] = { false, true, false }; - ImGui::Selectable("1. I am selectable", &selected[0]); - ImGui::Selectable("2. I am selectable", &selected[1]); - ImGui::Text("3. I am not selectable"); - ImGui::Selectable("4. I am selectable", &selected[2]); - ImGui::TreePop(); - } - if (ImGui::TreeNode("Rendering more text into the same block")) - { - static bool selected[3] = { false, false, false }; - ImGui::Selectable("main.c", &selected[0]); ImGui::SameLine(300); ImGui::Text(" 2,345 bytes"); - ImGui::Selectable("Hello.cpp", &selected[1]); ImGui::SameLine(300); ImGui::Text("12,345 bytes"); - ImGui::Selectable("Hello.h", &selected[2]); ImGui::SameLine(300); ImGui::Text(" 2,345 bytes"); - ImGui::TreePop(); - } - if (ImGui::TreeNode("Grid")) - { - static bool selected[16] = { true, false, false, false, false, true, false, false, false, false, true, false, false, false, false, true }; - for (int i = 0; i < 16; i++) - { - ImGui::PushID(i); - if (ImGui::Selectable("Me", &selected[i], ImVec2(50,50))) - { - int x = i % 4, y = i / 4; - if (x > 0) selected[i - 1] ^= 1; - if (x < 3) selected[i + 1] ^= 1; - if (y > 0) selected[i - 4] ^= 1; - if (y < 3) selected[i + 4] ^= 1; - } - if ((i % 4) < 3) ImGui::SameLine(); - ImGui::PopID(); - } - ImGui::TreePop(); - } - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Popup")) - { - static bool popup_open = false; - static int selected_fish = -1; - const char* fishes[] = { "Bream", "Haddock", "Mackerel", "Pollock", "Tilefish" }; - if (ImGui::Button("Select..")) - popup_open = true; - ImGui::SameLine(); - ImGui::Text(selected_fish == -1 ? "" : fishes[selected_fish]); - if (popup_open) - { - ImGui::BeginPopup(&popup_open); - ImGui::Text("Aquarium"); - ImGui::Separator(); - for (int i = 0; i < IM_ARRAYSIZE(fishes); i++) - { - if (ImGui::Selectable(fishes[i], false)) - { - selected_fish = i; - popup_open = false; - } - } - ImGui::EndPopup(); - } - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Filtered Text Input")) - { - static char buf1[64] = ""; ImGui::InputText("default", buf1, 64); - static char buf2[64] = ""; ImGui::InputText("decimal", buf2, 64, ImGuiInputTextFlags_CharsDecimal); - static char buf3[64] = ""; ImGui::InputText("hexadecimal", buf3, 64, ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase); - static char buf4[64] = ""; ImGui::InputText("uppercase", buf4, 64, ImGuiInputTextFlags_CharsUppercase); - static char buf5[64] = ""; ImGui::InputText("no blank", buf5, 64, ImGuiInputTextFlags_CharsNoBlank); - struct TextFilters { static int FilterImGuiLetters(ImGuiTextEditCallbackData* data) { if (data->EventChar < 256 && strchr("imgui", (char)data->EventChar)) return 0; return 1; } }; - static char buf6[64] = ""; ImGui::InputText("\"imgui\" letters", buf6, 64, ImGuiInputTextFlags_CallbackCharFilter, TextFilters::FilterImGuiLetters); - ImGui::TreePop(); - } - - static bool check = true; - ImGui::Checkbox("checkbox", &check); - - static int e = 0; - ImGui::RadioButton("radio a", &e, 0); ImGui::SameLine(); - ImGui::RadioButton("radio b", &e, 1); ImGui::SameLine(); - ImGui::RadioButton("radio c", &e, 2); - - // Color buttons, demonstrate using PushID() to add unique identifier in the ID stack, and changing style. - for (int i = 0; i < 7; i++) - { - if (i > 0) ImGui::SameLine(); - ImGui::PushID(i); - ImGui::PushStyleColor(ImGuiCol_Button, ImColor::HSV(i/7.0f, 0.6f, 0.6f)); - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImColor::HSV(i/7.0f, 0.7f, 0.7f)); - ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImColor::HSV(i/7.0f, 0.8f, 0.8f)); - ImGui::Button("Click"); - ImGui::PopStyleColor(3); - ImGui::PopID(); - } - - ImGui::Text("Hover over me"); - if (ImGui::IsItemHovered()) - ImGui::SetTooltip("I am a tooltip"); - - ImGui::SameLine(); - ImGui::Text("- or me"); - if (ImGui::IsItemHovered()) - { - ImGui::BeginTooltip(); - ImGui::Text("I am a fancy tooltip"); - static float arr[] = { 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f }; - ImGui::PlotLines("Curve", arr, IM_ARRAYSIZE(arr)); - ImGui::EndTooltip(); - } - - // Testing IMGUI_ONCE_UPON_A_FRAME macro - //for (int i = 0; i < 5; i++) - //{ - // IMGUI_ONCE_UPON_A_FRAME - // { - // ImGui::Text("This will be displayed only once."); - // } - //} - - ImGui::Separator(); - - ImGui::LabelText("label", "Value"); - - static int item = 1; - ImGui::Combo("combo", &item, "aaaa\0bbbb\0cccc\0dddd\0eeee\0\0"); - - const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK" }; - static int item2 = -1; - ImGui::Combo("combo scroll", &item2, items, IM_ARRAYSIZE(items)); - - { - static char str0[128] = "Hello, world!"; - static int i0=123; - static float f0=0.001f; - ImGui::InputText("input text", str0, IM_ARRAYSIZE(str0)); - ImGui::InputInt("input int", &i0); - ImGui::InputFloat("input float", &f0, 0.01f, 1.0f); - - static float vec4a[4] = { 0.10f, 0.20f, 0.30f, 0.44f }; - ImGui::InputFloat3("input float3", vec4a); - } - - { - static int i1=50; - static int i2=42; - ImGui::DragInt("drag int", &i1, 1); - ImGui::SameLine(); - ImGui::TextColored(ImColor(170,170,170,255), "(?)"); - if (ImGui::IsItemHovered()) - ImGui::SetTooltip("Click and drag to edit value.\nHold SHIFT/ALT for faster/slower edit.\nDouble-click or CTRL+click to input text"); - - ImGui::DragInt("drag int 0..100", &i2, 1, 0, 100, "%.0f%%"); - - static float f1=1.00f; - static float f2=0.0067f; - ImGui::DragFloat("drag float", &f1, 1.0f); - ImGui::DragFloat("drag small float", &f2, 0.0001f, 0.0f, 0.0f, "%.06f ns"); - } - - { - static int i1=0; - //static int i2=42; - ImGui::SliderInt("slider int 0..3", &i1, 0, 3); - //ImGui::SliderInt("slider int -100..100", &i2, -100, 100); - - static float f1=0.123f; - static float f2=0.0f; - ImGui::SliderFloat("slider float", &f1, 0.0f, 1.0f, "ratio = %.3f"); - ImGui::SliderFloat("slider log float", &f2, -10.0f, 10.0f, "%.4f", 3.0f); - static float angle = 0.0f; - ImGui::SliderAngle("slider angle", &angle); - } - - static float col1[3] = { 1.0f,0.0f,0.2f }; - static float col2[4] = { 0.4f,0.7f,0.0f,0.5f }; - ImGui::ColorEdit3("color 1", col1); - ImGui::ColorEdit4("color 2", col2); - - const char* listbox_items[] = { "Apple", "Banana", "Cherry", "Kiwi", "Mango", "Orange", "Pineapple", "Strawberry", "Watermelon" }; - static int listbox_item_current = 1; - ImGui::ListBox("listbox\n(single select)", &listbox_item_current, listbox_items, IM_ARRAYSIZE(listbox_items), 4); - - //static int listbox_item_current2 = 2; - //ImGui::PushItemWidth(-1); - //ImGui::ListBox("##listbox2", &listbox_item_current2, listbox_items, IM_ARRAYSIZE(listbox_items), 4); - //ImGui::PopItemWidth(); - - if (ImGui::TreeNode("Multi-component Widgets")) - { - ImGui::Unindent(); - - static float vec4f[4] = { 0.10f, 0.20f, 0.30f, 0.44f }; - static int vec4i[4] = { 1, 5, 100, 255 }; - - ImGui::InputFloat2("input float2", vec4f); - ImGui::DragFloat2("drag float2", vec4f, 0.01f, 0.0f, 1.0f); - ImGui::SliderFloat2("slider float2", vec4f, 0.0f, 1.0f); - ImGui::DragInt2("drag int2", vec4i, 1, 0, 255); - ImGui::InputInt2("input int2", vec4i); - ImGui::SliderInt2("slider int2", vec4i, 0, 255); - - ImGui::InputFloat3("input float3", vec4f); - ImGui::DragFloat3("drag float3", vec4f, 0.01f, 0.0f, 1.0f); - ImGui::SliderFloat3("slider float3", vec4f, 0.0f, 1.0f); - ImGui::DragInt3("drag int3", vec4i, 1, 0, 255); - ImGui::InputInt3("input int3", vec4i); - ImGui::SliderInt3("slider int3", vec4i, 0, 255); - - ImGui::InputFloat4("input float4", vec4f); - ImGui::DragFloat4("drag float4", vec4f, 0.01f, 0.0f, 1.0f); - ImGui::SliderFloat4("slider float4", vec4f, 0.0f, 1.0f); - ImGui::InputInt4("input int4", vec4i); - ImGui::DragInt4("drag int4", vec4i, 1, 0, 255); - ImGui::SliderInt4("slider int4", vec4i, 0, 255); - - ImGui::Indent(); - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Vertical Sliders")) - { - ImGui::Unindent(); - const float spacing = 4; - ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(spacing, spacing)); - - static int int_value = 0; - ImGui::VSliderInt("##int", ImVec2(18,160), &int_value, 0, 5); - ImGui::SameLine(); - - static float values[7] = { 0.0f, 0.60f, 0.35f, 0.9f, 0.70f, 0.20f, 0.0f }; - ImGui::PushID("set1"); - for (int i = 0; i < 7; i++) - { - if (i > 0) ImGui::SameLine(); - ImGui::PushID(i); - ImGui::PushStyleColor(ImGuiCol_FrameBg, ImColor::HSV(i/7.0f, 0.5f, 0.5f)); - ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, ImColor::HSV(i/7.0f, 0.6f, 0.5f)); - ImGui::PushStyleColor(ImGuiCol_FrameBgActive, ImColor::HSV(i/7.0f, 0.7f, 0.5f)); - ImGui::PushStyleColor(ImGuiCol_SliderGrab, ImColor::HSV(i/7.0f, 0.9f, 0.9f)); - ImGui::VSliderFloat("##v", ImVec2(18,160), &values[i], 0.0f, 1.0f, ""); - if (ImGui::IsItemActive() || ImGui::IsItemHovered()) - ImGui::SetTooltip("%.3f", values[i]); - ImGui::PopStyleColor(4); - ImGui::PopID(); - } - ImGui::PopID(); - - ImGui::SameLine(); - ImGui::PushID("set2"); - static float values2[4] = { 0.20f, 0.80f, 0.40f, 0.25f }; - const int rows = 3; - const ImVec2 small_slider_size(18, (160.0f-(rows-1)*spacing)/rows); - for (int nx = 0; nx < 4; nx++) - { - if (nx > 0) ImGui::SameLine(); - ImGui::BeginGroup(); - for (int ny = 0; ny < rows; ny++) - { - ImGui::PushID(nx*rows+ny); - ImGui::VSliderFloat("##v", small_slider_size, &values2[nx], 0.0f, 1.0f, ""); - if (ImGui::IsItemActive() || ImGui::IsItemHovered()) - ImGui::SetTooltip("%.3f", values2[nx]); - ImGui::PopID(); - } - ImGui::EndGroup(); - } - ImGui::PopID(); - - ImGui::SameLine(); - ImGui::PushID("set3"); - for (int i = 0; i < 4; i++) - { - if (i > 0) ImGui::SameLine(); - ImGui::PushID(i); - ImGui::PushStyleVar(ImGuiStyleVar_GrabMinSize, 40); - ImGui::VSliderFloat("##v", ImVec2(40,160), &values[i], 0.0f, 1.0f, "%.2f"); - ImGui::PopStyleVar(); - ImGui::PopID(); - } - ImGui::PopID(); - - ImGui::Indent(); - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Dragging")) - { - // You can use ImGui::GetItemActiveDragDelta() to query for the dragged amount on any widget. - static ImVec2 value_raw(0.0f, 0.0f); - static ImVec2 value_with_lock_threshold(0.0f, 0.0f); - ImGui::Button("Drag Me"); - if (ImGui::IsItemActive()) - { - value_raw = ImGui::GetMouseDragDelta(0, 0.0f); - value_with_lock_threshold = ImGui::GetMouseDragDelta(0); - //ImGui::SetTooltip("Delta: %.1f, %.1f", value.x, value.y); - - // Draw a line between the button and the mouse cursor - ImDrawList* draw_list = ImGui::GetWindowDrawList(); - draw_list->PushClipRectFullScreen(); - draw_list->AddLine(ImGui::CalcItemRectClosestPoint(ImGui::GetIO().MousePos, true, -2.0f), ImGui::GetIO().MousePos, ImColor(ImGui::GetStyle().Colors[ImGuiCol_Button]), 4.0f); - draw_list->PopClipRect(); - } - ImGui::SameLine(); ImGui::Text("Raw (%.1f, %.1f), WithLockThresold (%.1f, %.1f)", value_raw.x, value_raw.y, value_with_lock_threshold.x, value_with_lock_threshold.y); - ImGui::TreePop(); - } - } - - if (ImGui::CollapsingHeader("Graphs widgets")) - { - static float arr[] = { 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f }; - ImGui::PlotLines("Frame Times", arr, IM_ARRAYSIZE(arr)); - - static bool pause; - static ImVector values; if (values.empty()) { values.resize(90); memset(&values.front(), 0, values.size()*sizeof(float)); } - static size_t values_offset = 0; - if (!pause) - { - // create dummy data at fixed 60 hz rate - static float refresh_time = -1.0f; - if (ImGui::GetTime() > refresh_time + 1.0f/60.0f) - { - refresh_time = ImGui::GetTime(); - static float phase = 0.0f; - values[values_offset] = cosf(phase); - values_offset = (values_offset+1)%values.size(); - phase += 0.10f*values_offset; - } - } - ImGui::PlotLines("##Graph", &values.front(), (int)values.size(), (int)values_offset, "avg 0.0", -1.0f, 1.0f, ImVec2(0,80)); - ImGui::SameLine(0, (int)ImGui::GetStyle().ItemInnerSpacing.x); - ImGui::BeginGroup(); - ImGui::Text("Graph"); - ImGui::Checkbox("pause", &pause); - ImGui::EndGroup(); - ImGui::PlotHistogram("Histogram", arr, IM_ARRAYSIZE(arr), 0, NULL, 0.0f, 1.0f, ImVec2(0,80)); - } - - if (ImGui::CollapsingHeader("Layout")) - { - if (ImGui::TreeNode("Widgets Alignment")) - { - static float f = 0.0f; - ImGui::Text("Fixed: 100 pixels"); - ImGui::PushItemWidth(100); - ImGui::InputFloat("float##1", &f); - ImGui::PopItemWidth(); - - ImGui::Text("Proportional: 50%% of window width"); - ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.5f); - ImGui::InputFloat("float##2", &f); - ImGui::PopItemWidth(); - - ImGui::Text("Right-aligned: Leave 100 pixels for label"); - ImGui::PushItemWidth(-100); - ImGui::InputFloat("float##3", &f); - ImGui::PopItemWidth(); - - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Basic Horizontal Layout")) - { - ImGui::TextWrapped("(Use ImGui::SameLine() to keep adding items to the right of the preceeding item)"); - - // Text - ImGui::Text("Two items: Hello"); - ImGui::SameLine(); - ImGui::TextColored(ImVec4(1,1,0,1), "World"); - - // Adjust spacing - ImGui::Text("More spacing: Hello"); - ImGui::SameLine(0, 20); - ImGui::TextColored(ImVec4(1,1,0,1), "World"); - - // Button - ImGui::AlignFirstTextHeightToWidgets(); - ImGui::Text("Normal buttons"); ImGui::SameLine(); - ImGui::Button("Banana"); ImGui::SameLine(); - ImGui::Button("Apple"); ImGui::SameLine(); - ImGui::Button("Corniflower"); - - // Button - ImGui::Text("Small buttons"); ImGui::SameLine(); - ImGui::SmallButton("Like this one"); ImGui::SameLine(); - ImGui::Text("can fit within a text block."); - - // Aligned to arbitrary position. Easy/cheap column. - ImGui::Text("Aligned"); - ImGui::SameLine(150); ImGui::Text("x=150"); - ImGui::SameLine(300); ImGui::Text("x=300"); - ImGui::Text("Aligned"); - ImGui::SameLine(150); ImGui::SmallButton("x=150"); - ImGui::SameLine(300); ImGui::SmallButton("x=300"); - - // Checkbox - static bool c1=false,c2=false,c3=false,c4=false; - ImGui::Checkbox("My", &c1); ImGui::SameLine(); - ImGui::Checkbox("Tailor", &c2); ImGui::SameLine(); - ImGui::Checkbox("Is", &c3); ImGui::SameLine(); - ImGui::Checkbox("Rich", &c4); - - // Various - static float f0=1.0f, f1=2.0f, f2=3.0f; - ImGui::PushItemWidth(80); - const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD" }; - static int item = -1; - ImGui::Combo("Combo", &item, items, IM_ARRAYSIZE(items)); ImGui::SameLine(); - ImGui::SliderFloat("X", &f0, 0.0f,5.0f); ImGui::SameLine(); - ImGui::SliderFloat("Y", &f1, 0.0f,5.0f); ImGui::SameLine(); - ImGui::SliderFloat("Z", &f2, 0.0f,5.0f); - ImGui::PopItemWidth(); - - ImGui::PushItemWidth(80); - ImGui::Text("Lists:"); - static int selection[4] = { 0, 1, 2, 3 }; - for (int i = 0; i < 4; i++) - { - if (i > 0) ImGui::SameLine(); - ImGui::PushID(i); - ImGui::ListBox("", &selection[i], items, IM_ARRAYSIZE(items)); - ImGui::PopID(); - //if (ImGui::IsItemHovered()) ImGui::SetTooltip("ListBox %d hovered", i); - } - ImGui::PopItemWidth(); - - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Groups")) - { - ImGui::TextWrapped("(Using ImGui::BeginGroup()/EndGroup() to layout items)"); - - ImVec2 size; - ImGui::BeginGroup(); - { - ImGui::BeginGroup(); - ImGui::Button("AAA"); - ImGui::SameLine(); - ImGui::Button("BBB"); - ImGui::SameLine(); - ImGui::BeginGroup(); - ImGui::Button("CCC"); - ImGui::Button("DDD"); - ImGui::EndGroup(); - if (ImGui::IsItemHovered()) - ImGui::SetTooltip("Group hovered"); - ImGui::SameLine(); - ImGui::Button("EEE"); - ImGui::EndGroup(); - - // Capture the group size and create widgets using the same size - size = ImGui::GetItemRectSize(); - const float values[5] = { 0.5f, 0.20f, 0.80f, 0.60f, 0.25f }; - ImGui::PlotHistogram("##values", values, IM_ARRAYSIZE(values), 0, NULL, 0.0f, 1.0f, size); - } - ImGui::Button("ACTION", ImVec2((size.x - ImGui::GetStyle().ItemSpacing.x)*0.5f,size.y)); - ImGui::SameLine(); - ImGui::Button("REACTION", ImVec2((size.x - ImGui::GetStyle().ItemSpacing.x)*0.5f,size.y)); - ImGui::EndGroup(); - ImGui::SameLine(); - - ImGui::Button("LEVERAGE\nBUZZWORD", size); - ImGui::SameLine(); - - ImGui::ListBoxHeader("List", size); - ImGui::Selectable("Selected", true); - ImGui::Selectable("Not Selected", false); - ImGui::ListBoxFooter(); - - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Text Baseline Alignment")) - { - ImGui::TextWrapped("(This is testing the vertical alignment that occurs on text to keep it at the same baseline as widgets. Lines only composed of text or \"small\" widgets fit in less vertical spaces than lines with normal widgets)"); - - ImGui::Text("One\nTwo\nThree"); ImGui::SameLine(); - ImGui::Text("Hello\nWorld"); ImGui::SameLine(); - ImGui::Text("Banana"); - - ImGui::Text("Banana"); ImGui::SameLine(); - ImGui::Text("Hello\nWorld"); ImGui::SameLine(); - ImGui::Text("One\nTwo\nThree"); - - ImGui::Button("HOP"); ImGui::SameLine(); - ImGui::Text("Banana"); ImGui::SameLine(); - ImGui::Text("Hello\nWorld"); ImGui::SameLine(); - ImGui::Text("Banana"); - - ImGui::Button("HOP"); ImGui::SameLine(); - ImGui::Text("Hello\nWorld"); ImGui::SameLine(); - ImGui::Text("Banana"); - - ImGui::Button("TEST"); ImGui::SameLine(); - ImGui::Text("TEST"); ImGui::SameLine(); - ImGui::SmallButton("TEST"); - - ImGui::AlignFirstTextHeightToWidgets(); // If your line starts with text, call this to align it to upcoming widgets. - ImGui::Text("Text aligned to Widget"); ImGui::SameLine(); - ImGui::Button("Widget"); ImGui::SameLine(); - ImGui::Text("Widget"); ImGui::SameLine(); - ImGui::SmallButton("Widget"); - - ImGui::TreePop(); - } - } - - if (ImGui::CollapsingHeader("Child regions")) - { - ImGui::Text("Without border"); - static int line = 50; - bool goto_line = ImGui::Button("Goto"); - ImGui::SameLine(); - ImGui::PushItemWidth(100); - goto_line |= ImGui::InputInt("##Line", &line, 0, 0, ImGuiInputTextFlags_EnterReturnsTrue); - ImGui::PopItemWidth(); - ImGui::BeginChild("Sub1", ImVec2(ImGui::GetWindowWidth() * 0.5f,300)); - for (int i = 0; i < 100; i++) - { - ImGui::Text("%04d: scrollable region", i); - if (goto_line && line == i) - ImGui::SetScrollPosHere(); - } - if (goto_line && line >= 100) - ImGui::SetScrollPosHere(); - ImGui::EndChild(); - - ImGui::SameLine(); - - ImGui::PushStyleVar(ImGuiStyleVar_ChildWindowRounding, 5.0f); - ImGui::BeginChild("Sub2", ImVec2(0,300), true); - ImGui::Text("With border"); - ImGui::Columns(2); - for (int i = 0; i < 100; i++) - { - if (i == 50) - ImGui::NextColumn(); - char buf[32]; - ImFormatString(buf, IM_ARRAYSIZE(buf), "%08x", i*5731); - ImGui::Button(buf); - } - ImGui::EndChild(); - ImGui::PopStyleVar(); - } - - if (ImGui::CollapsingHeader("Columns")) - { - // Basic columns - ImGui::Text("Basic:"); - ImGui::Columns(4, "mycolumns"); - ImGui::Separator(); - ImGui::Text("ID"); ImGui::NextColumn(); - ImGui::Text("Name"); ImGui::NextColumn(); - ImGui::Text("Path"); ImGui::NextColumn(); - ImGui::Text("Flags"); ImGui::NextColumn(); - ImGui::Separator(); - const char* names[3] = { "Robert", "Stephanie", "C64" }; - const char* paths[3] = { "/path/robert", "/path/stephanie", "/path/computer" }; - for (int i = 0; i < 3; i++) - { - ImGui::Text("%04d", i); ImGui::NextColumn(); - ImGui::Text(names[i]); ImGui::NextColumn(); - ImGui::Text(paths[i]); ImGui::NextColumn(); - ImGui::Text("...."); ImGui::NextColumn(); - } - ImGui::Columns(1); - - ImGui::Separator(); - ImGui::Spacing(); - - // Scrolling columns - /* - ImGui::Text("Scrolling:"); - ImGui::BeginChild("##header", ImVec2(0, ImGui::GetTextLineHeightWithSpacing()+ImGui::GetStyle().ItemSpacing.y)); - ImGui::Columns(3); - ImGui::Text("ID"); ImGui::NextColumn(); - ImGui::Text("Name"); ImGui::NextColumn(); - ImGui::Text("Path"); ImGui::NextColumn(); - ImGui::Columns(1); - ImGui::Separator(); - ImGui::EndChild(); - ImGui::BeginChild("##scrollingregion", ImVec2(0, 60)); - ImGui::Columns(3); - for (int i = 0; i < 10; i++) - { - ImGui::Text("%04d", i); ImGui::NextColumn(); - ImGui::Text("Foobar"); ImGui::NextColumn(); - ImGui::Text("/path/foobar/%04d/", i); ImGui::NextColumn(); - } - ImGui::Columns(1); - ImGui::EndChild(); - - ImGui::Separator(); - ImGui::Spacing(); - */ - - // Create multiple items in a same cell before switching to next column - ImGui::Text("Mixed items:"); - ImGui::Columns(3, "mixed"); - ImGui::Separator(); - - static int e = 0; - ImGui::Text("Hello"); - ImGui::Button("Banana"); - ImGui::RadioButton("radio a", &e, 0); - ImGui::NextColumn(); - - ImGui::Text("ImGui"); - ImGui::Button("Apple"); - ImGui::RadioButton("radio b", &e, 1); - static float foo = 1.0f; - ImGui::InputFloat("red", &foo, 0.05f, 0, 3); - ImGui::Text("An extra line here."); - ImGui::NextColumn(); - - ImGui::Text("World!"); - ImGui::Button("Corniflower"); - ImGui::RadioButton("radio c", &e, 2); - static float bar = 1.0f; - ImGui::InputFloat("blue", &bar, 0.05f, 0, 3); - ImGui::NextColumn(); - - if (ImGui::CollapsingHeader("Category A")) ImGui::Text("Blah blah blah"); ImGui::NextColumn(); - if (ImGui::CollapsingHeader("Category B")) ImGui::Text("Blah blah blah"); ImGui::NextColumn(); - if (ImGui::CollapsingHeader("Category C")) ImGui::Text("Blah blah blah"); ImGui::NextColumn(); - ImGui::Columns(1); - - ImGui::Separator(); - ImGui::Spacing(); - - // Tree items - ImGui::Text("Tree items:"); - ImGui::Columns(2, "tree items"); - ImGui::Separator(); - if (ImGui::TreeNode("Hello")) { ImGui::BulletText("World"); ImGui::TreePop(); } ImGui::NextColumn(); - if (ImGui::TreeNode("Bonjour")) { ImGui::BulletText("Monde"); ImGui::TreePop(); } ImGui::NextColumn(); - ImGui::Columns(1); - - ImGui::Separator(); - ImGui::Spacing(); - - // Word-wrapping - ImGui::Text("Word-wrapping:"); - ImGui::Columns(2, "word-wrapping"); - ImGui::Separator(); - ImGui::TextWrapped("The quick brown fox jumps over the lazy dog."); - ImGui::Text("Hello Left"); - ImGui::NextColumn(); - ImGui::TextWrapped("The quick brown fox jumps over the lazy dog."); - ImGui::Text("Hello Right"); - ImGui::Columns(1); - - ImGui::Separator(); - ImGui::Spacing(); - - if (ImGui::TreeNode("Inside a tree..")) - { - if (ImGui::TreeNode("node 1 (with borders)")) - { - ImGui::Columns(4); - for (int i = 0; i < 8; i++) - { - ImGui::Text("%c%c%c", 'a'+i, 'a'+i, 'a'+i); - ImGui::NextColumn(); - } - ImGui::Columns(1); - ImGui::TreePop(); - } - if (ImGui::TreeNode("node 2 (without borders)")) - { - ImGui::Columns(4, NULL, false); - for (int i = 0; i < 8; i++) - { - ImGui::Text("%c%c%c", 'a'+i, 'a'+i, 'a'+i); - ImGui::NextColumn(); - } - ImGui::Columns(1); - ImGui::TreePop(); - } - ImGui::TreePop(); - } - } - - if (ImGui::CollapsingHeader("Filtering")) - { - static ImGuiTextFilter filter; - ImGui::Text("Filter usage:\n" - " \"\" display all lines\n" - " \"xxx\" display lines containing \"xxx\"\n" - " \"xxx,yyy\" display lines containing \"xxx\" or \"yyy\"\n" - " \"-xxx\" hide lines containing \"xxx\""); - filter.Draw(); - const char* lines[] = { "aaa1.c", "bbb1.c", "ccc1.c", "aaa2.cpp", "bbb2.cpp", "ccc2.cpp", "abc.h", "hello, world" }; - for (size_t i = 0; i < IM_ARRAYSIZE(lines); i++) - if (filter.PassFilter(lines[i])) - ImGui::BulletText("%s", lines[i]); - } - - if (ImGui::CollapsingHeader("Keyboard, Mouse & Focus")) - { - if (ImGui::TreeNode("Tabbing")) - { - ImGui::Text("Use TAB/SHIFT+TAB to cycle thru keyboard editable fields."); - static char buf[32] = "dummy"; - ImGui::InputText("1", buf, IM_ARRAYSIZE(buf)); - ImGui::InputText("2", buf, IM_ARRAYSIZE(buf)); - ImGui::InputText("3", buf, IM_ARRAYSIZE(buf)); - ImGui::PushAllowKeyboardFocus(false); - ImGui::InputText("4 (tab skip)", buf, IM_ARRAYSIZE(buf)); - //ImGui::SameLine(); ImGui::Text("(?)"); if (ImGui::IsHovered()) ImGui::SetTooltip("Use ImGui::PushAllowKeyboardFocus(bool)\nto disable tabbing through certain widgets."); - ImGui::PopAllowKeyboardFocus(); - ImGui::InputText("5", buf, IM_ARRAYSIZE(buf)); - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Focus from code")) - { - bool focus_1 = ImGui::Button("Focus on 1"); ImGui::SameLine(); - bool focus_2 = ImGui::Button("Focus on 2"); ImGui::SameLine(); - bool focus_3 = ImGui::Button("Focus on 3"); - int has_focus = 0; - static char buf[128] = "click on a button to set focus"; - - if (focus_1) ImGui::SetKeyboardFocusHere(); - ImGui::InputText("1", buf, IM_ARRAYSIZE(buf)); - if (ImGui::IsItemActive()) has_focus = 1; - - if (focus_2) ImGui::SetKeyboardFocusHere(); - ImGui::InputText("2", buf, IM_ARRAYSIZE(buf)); - if (ImGui::IsItemActive()) has_focus = 2; - - ImGui::PushAllowKeyboardFocus(false); - if (focus_3) ImGui::SetKeyboardFocusHere(); - ImGui::InputText("3 (tab skip)", buf, IM_ARRAYSIZE(buf)); - if (ImGui::IsItemActive()) has_focus = 3; - ImGui::PopAllowKeyboardFocus(); - if (has_focus) - ImGui::Text("Item with focus: %d", has_focus); - else - ImGui::Text("Item with focus: "); - ImGui::TextWrapped("Cursor & selection are preserved when refocusing last used item in code."); - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Mouse cursors")) - { - ImGui::TextWrapped("(Your application can render a different mouse cursor based on what ImGui::GetMouseCursor() returns. You can also set io.MouseDrawCursor to ask ImGui to render the cursor for you in software)"); - ImGui::Checkbox("io.MouseDrawCursor", &ImGui::GetIO().MouseDrawCursor); - ImGui::Text("Hover to see mouse cursors:"); - for (int i = 0; i < ImGuiMouseCursor_Count_; i++) - { - char label[32]; - sprintf(label, "Mouse cursor %d", i); - ImGui::Bullet(); ImGui::Selectable(label, false); - if (ImGui::IsItemHovered()) - ImGui::SetMouseCursor(i); - } - ImGui::TreePop(); - } - } - - if (ImGui::CollapsingHeader("App Examples")) - { - ImGui::Checkbox("Metrics", &show_app_metrics); - ImGui::Checkbox("Console", &show_app_console); - ImGui::Checkbox("Long text display", &show_app_long_text); - ImGui::Checkbox("Auto-resizing window", &show_app_auto_resize); - ImGui::Checkbox("Simple overlay", &show_app_fixed_overlay); - ImGui::Checkbox("Manipulating window title", &show_app_manipulating_window_title); - ImGui::Checkbox("Custom rendering", &show_app_custom_rendering); - } - - ImGui::End(); -} - -void ImGui::ShowMetricsWindow(bool* opened) -{ - if (ImGui::Begin("ImGui Metrics", opened)) - { - ImGui::Text("ImGui %s", ImGui::GetVersion()); - ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); - ImGui::Text("%d vertices", ImGui::GetIO().MetricsRenderVertices); - ImGui::Separator(); - - struct Funcs - { - static void NodeDrawList(ImDrawList* draw_list, const char* label) - { - bool node_opened = ImGui::TreeNode(draw_list, "%s: %d vtx, %d cmds", label, draw_list->vtx_buffer.size(), draw_list->commands.size()); - if (draw_list == ImGui::GetWindowDrawList()) - { - ImGui::SameLine(); - ImGui::TextColored(ImColor(255,100,100), "CURRENTLY APPENDING"); // Can't display stats for active draw list! (we don't have the data double-buffered) - } - if (!node_opened) - return; - for (const ImDrawCmd* pcmd = draw_list->commands.begin(); pcmd < draw_list->commands.end(); pcmd++) - if (pcmd->user_callback) - ImGui::BulletText("Callback %p, user_data %p", pcmd->user_callback, pcmd->user_callback_data); - else - ImGui::BulletText("Draw %d vtx, tex = %p", pcmd->vtx_count, pcmd->texture_id); - ImGui::TreePop(); - } - - static void NodeWindows(ImVector& windows, const char* label) - { - if (!ImGui::TreeNode(label, "%s (%d)", label, (int)windows.size())) - return; - for (int i = 0; i < (int)windows.size(); i++) - Funcs::NodeWindow(windows[i], "Window"); - ImGui::TreePop(); - } - - static void NodeWindow(ImGuiWindow* window, const char* label) - { - if (!ImGui::TreeNode(window, "%s '%s', %d @ 0x%p", label, window->Name, window->Visible, window)) - return; - NodeDrawList(window->DrawList, "DrawList"); - if (window->RootWindow != window) NodeWindow(window->RootWindow, "RootWindow"); - if (window->DC.ChildWindows.size() > 0) NodeWindows(window->DC.ChildWindows, "ChildWindows"); - ImGui::TreePop(); - } - }; - - ImGuiState& g = *GImGui; // Access private state - g.DisableHideTextAfterDoubleHash++; // Not exposed (yet). Disable processing that hides text after '##' markers. - Funcs::NodeWindows(g.Windows, "Windows"); - if (ImGui::TreeNode("DrawList", "Active DrawLists (%d)", (int)g.RenderDrawLists[0].size())) - { - for (int i = 0; i < (int)g.RenderDrawLists[0].size(); i++) - Funcs::NodeDrawList(g.RenderDrawLists[0][i], "DrawList"); - ImGui::TreePop(); - } - g.DisableHideTextAfterDoubleHash--; - } - ImGui::End(); -} - -static void ShowExampleAppAutoResize(bool* opened) -{ - if (!ImGui::Begin("Example: Auto-Resizing Window", opened, ImGuiWindowFlags_AlwaysAutoResize)) - { - ImGui::End(); - return; - } - - static int lines = 10; - ImGui::TextWrapped("Window will resize every-frame to the size of its content. Note that you don't want to query the window size to output your content because that would create a feedback loop."); - ImGui::SliderInt("Number of lines", &lines, 1, 20); - for (int i = 0; i < lines; i++) - ImGui::Text("%*sThis is line %d", i*4, "", i); // Pad with space to extend size horizontally - - ImGui::End(); -} - -static void ShowExampleAppFixedOverlay(bool* opened) -{ - ImGui::SetNextWindowPos(ImVec2(10,10)); - if (!ImGui::Begin("Example: Fixed Overlay", opened, ImVec2(0,0), 0.3f, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoSavedSettings)) - { - ImGui::End(); - return; - } - - ImGui::Text("Simple overlay\non the top-left side of the screen."); - ImGui::Separator(); - ImGui::Text("Mouse Position: (%.1f,%.1f)", ImGui::GetIO().MousePos.x, ImGui::GetIO().MousePos.y); - - ImGui::End(); -} - -static void ShowExampleAppManipulatingWindowTitle(bool* opened) -{ - (void)opened; - - // By default, Windows are uniquely identified by their title. - // You can use the "##" and "###" markers to manipulate the display/ID. Read FAQ at the top of this file! - - // Using "##" to display same title but have unique identifier. - ImGui::SetNextWindowPos(ImVec2(100,100), ImGuiSetCond_FirstUseEver); - ImGui::Begin("Same title as another window##1"); - ImGui::Text("This is window 1.\nMy title is the same as window 2, but my identifier is unique."); - ImGui::End(); - - ImGui::SetNextWindowPos(ImVec2(100,200), ImGuiSetCond_FirstUseEver); - ImGui::Begin("Same title as another window##2"); - ImGui::Text("This is window 2.\nMy title is the same as window 1, but my identifier is unique."); - ImGui::End(); - - // Using "###" to display a changing title but keep a static identifier "AnimatedTitle" - char buf[128]; - ImFormatString(buf, IM_ARRAYSIZE(buf), "Animated title %c %d###AnimatedTitle", "|/-\\"[(int)(ImGui::GetTime()/0.25f)&3], rand()); - ImGui::SetNextWindowPos(ImVec2(100,300), ImGuiSetCond_FirstUseEver); - ImGui::Begin(buf); - ImGui::Text("This window has a changing title."); - ImGui::End(); -} - -static void ShowExampleAppCustomRendering(bool* opened) -{ - ImGui::SetNextWindowSize(ImVec2(300,350), ImGuiSetCond_FirstUseEver); - if (!ImGui::Begin("Example: Custom Rendering", opened)) - { - ImGui::End(); - return; - } - - // Tip: If you do a lot of custom rendering, you probably want to use your own geometrical types and benefit of overloaded operators, etc. - // Define IM_VEC2_CLASS_EXTRA in imconfig.h to create implicit conversions between your types and ImVec2/ImVec4. - // ImGui defines overloaded operators but they are internal to imgui.cpp and not exposed outside (to avoid messing with your types) - // In this example we aren't using the operators. - - static ImVector points; - static bool adding_line = false; - if (ImGui::Button("Clear")) points.clear(); - if (points.size() >= 2) { ImGui::SameLine(); if (ImGui::Button("Undo")) { points.pop_back(); points.pop_back(); } } - ImGui::Text("Left-click and drag to add lines"); - ImGui::Text("Right-click to undo"); - - ImDrawList* draw_list = ImGui::GetWindowDrawList(); - - // Here we are using InvisibleButton() as a convenience to 1) advance the cursor and 2) allows us to use IsItemHovered() - // However you can draw directly and poll mouse/keyboard by yourself. You can manipulate the cursor using GetCursorPos() and SetCursorPos(). - // If you only use the ImDrawList API, you can notify the owner window of its extends by using SetCursorPos(max). - ImVec2 canvas_pos = ImGui::GetCursorScreenPos(); // ImDrawList API uses screen coordinates! - ImVec2 canvas_size = ImVec2(ImMax(50.0f,ImGui::GetWindowContentRegionMax().x-ImGui::GetCursorPos().x), ImMax(50.0f,ImGui::GetWindowContentRegionMax().y-ImGui::GetCursorPos().y)); // Resize canvas what's available - draw_list->AddRect(canvas_pos, ImVec2(canvas_pos.x + canvas_size.x, canvas_pos.y + canvas_size.y), 0xFFFFFFFF); - bool adding_preview = false; - ImGui::InvisibleButton("canvas", canvas_size); - if (ImGui::IsItemHovered()) - { - ImVec2 mouse_pos_in_canvas = ImVec2(ImGui::GetIO().MousePos.x - canvas_pos.x, ImGui::GetIO().MousePos.y - canvas_pos.y); - if (!adding_line && ImGui::GetIO().MouseClicked[0]) - { - points.push_back(mouse_pos_in_canvas); - adding_line = true; - } - if (adding_line) - { - adding_preview = true; - points.push_back(mouse_pos_in_canvas); - if (!ImGui::GetIO().MouseDown[0]) - adding_line = adding_preview = false; - } - if (ImGui::GetIO().MouseClicked[1] && !points.empty()) - { - adding_line = false; - points.pop_back(); - points.pop_back(); - } - } - draw_list->PushClipRect(ImVec4(canvas_pos.x, canvas_pos.y, canvas_pos.x+canvas_size.x, canvas_pos.y+canvas_size.y)); // clip lines within the canvas (if we resize it, etc.) - for (int i = 0; i < (int)points.size() - 1; i += 2) - draw_list->AddLine(ImVec2(canvas_pos.x + points[i].x, canvas_pos.y + points[i].y), ImVec2(canvas_pos.x + points[i+1].x, canvas_pos.y + points[i+1].y), 0xFF00FFFF); - draw_list->PopClipRect(); - if (adding_preview) - points.pop_back(); - ImGui::End(); -} - -struct ExampleAppConsole -{ - char InputBuf[256]; - ImVector Items; - bool ScrollToBottom; - ImVector History; - int HistoryPos; // -1: new line, 0..History.size()-1 browsing history. - ImVector Commands; - - ExampleAppConsole() - { - ClearLog(); - HistoryPos = -1; - Commands.push_back("HELP"); - Commands.push_back("HISTORY"); - Commands.push_back("CLEAR"); - Commands.push_back("CLASSIFY"); // "classify" is here to provide an example of "C"+[tab] completing to "CL" and displaying matches. - } - ~ExampleAppConsole() - { - ClearLog(); - for (size_t i = 0; i < Items.size(); i++) - ImGui::MemFree(History[i]); - } - - void ClearLog() - { - for (size_t i = 0; i < Items.size(); i++) - ImGui::MemFree(Items[i]); - Items.clear(); - ScrollToBottom = true; - } - - void AddLog(const char* fmt, ...) - { - char buf[1024]; - va_list args; - va_start(args, fmt); - ImFormatStringV(buf, IM_ARRAYSIZE(buf), fmt, args); - va_end(args); - Items.push_back(ImStrdup(buf)); - ScrollToBottom = true; - } - - void Run(const char* title, bool* opened) - { - ImGui::SetNextWindowSize(ImVec2(520,600), ImGuiSetCond_FirstUseEver); - if (!ImGui::Begin(title, opened)) - { - ImGui::End(); - return; - } - - ImGui::TextWrapped("This example implements a console with basic coloring, completion and history. A more elaborate implementation may want to store entries along with extra data such as timestamp, emitter, etc."); - ImGui::TextWrapped("Enter 'HELP' for help, press TAB to use text completion."); - - // TODO: display from bottom - // TODO: clip manually - - if (ImGui::SmallButton("Add Dummy Text")) { AddLog("%d some text", Items.size()); AddLog("some more text"); AddLog("display very important message here!"); } ImGui::SameLine(); - if (ImGui::SmallButton("Add Dummy Error")) AddLog("[error] something went wrong"); ImGui::SameLine(); - if (ImGui::SmallButton("Clear")) ClearLog(); - //static float t = 0.0f; if (ImGui::GetTime() - t > 0.02f) { t = ImGui::GetTime(); AddLog("Spam %f", t); } - - ImGui::Separator(); - - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0,0)); - static ImGuiTextFilter filter; - filter.Draw("Filter (\"incl,-excl\") (\"error\")", 180); - //if (ImGui::IsItemHovered()) ImGui::SetKeyboardFocusHere(-1); // Auto focus on hover - ImGui::PopStyleVar(); - ImGui::Separator(); - - // Display every line as a separate entry so we can change their color or add custom widgets. If you only want raw text you can use ImGui::TextUnformatted(log.begin(), log.end()); - // NB- if you have thousands of entries this approach may be too inefficient. You can seek and display only the lines that are visible - CalcListClipping() is a helper to compute this information. - // If your items are of variable size you may want to implement code similar to what CalcListClipping() does. Or split your data into fixed height items to allow random-seeking into your list. - ImGui::BeginChild("ScrollingRegion", ImVec2(0,-ImGui::GetTextLineHeightWithSpacing()*2)); - ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(4,1)); // Tighten spacing - for (size_t i = 0; i < Items.size(); i++) - { - const char* item = Items[i]; - if (!filter.PassFilter(item)) - continue; - ImVec4 col(1,1,1,1); // A better implement may store a type per-item. For the sample let's just parse the text. - if (strstr(item, "[error]")) col = ImVec4(1.0f,0.4f,0.4f,1.0f); - else if (strncmp(item, "# ", 2) == 0) col = ImVec4(1.0f,0.8f,0.6f,1.0f); - ImGui::PushStyleColor(ImGuiCol_Text, col); - ImGui::TextUnformatted(item); - ImGui::PopStyleColor(); - } - if (ScrollToBottom) - ImGui::SetScrollPosHere(); - ScrollToBottom = false; - ImGui::PopStyleVar(); - ImGui::EndChild(); - ImGui::Separator(); - - // Command-line - if (ImGui::InputText("Input", InputBuf, IM_ARRAYSIZE(InputBuf), ImGuiInputTextFlags_EnterReturnsTrue|ImGuiInputTextFlags_CallbackCompletion|ImGuiInputTextFlags_CallbackHistory, &TextEditCallbackStub, (void*)this)) - { - char* input_end = InputBuf+strlen(InputBuf); - while (input_end > InputBuf && input_end[-1] == ' ') input_end--; *input_end = 0; - if (InputBuf[0]) - ExecCommand(InputBuf); - strcpy(InputBuf, ""); - } - - // Demonstrate keeping auto focus on the input box - if (ImGui::IsItemHovered() || (ImGui::IsRootWindowOrAnyChildFocused() && !ImGui::IsAnyItemActive() && !ImGui::IsMouseClicked(0))) - ImGui::SetKeyboardFocusHere(-1); // Auto focus - - ImGui::End(); - } - - void ExecCommand(const char* command_line) - { - AddLog("# %s\n", command_line); - - // Insert into history. First find match and delete it so it can be pushed to the back. This isn't trying to be smart or optimal. - HistoryPos = -1; - for (int i = (int)History.size()-1; i >= 0; i--) - if (ImStricmp(History[i], command_line) == 0) - { - ImGui::MemFree(History[i]); - History.erase(History.begin() + i); - break; - } - History.push_back(ImStrdup(command_line)); - - // Process command - if (ImStricmp(command_line, "CLEAR") == 0) - { - ClearLog(); - } - else if (ImStricmp(command_line, "HELP") == 0) - { - AddLog("Commands:"); - for (size_t i = 0; i < Commands.size(); i++) - AddLog("- %s", Commands[i]); - } - else if (ImStricmp(command_line, "HISTORY") == 0) - { - for (size_t i = History.size() >= 10 ? History.size() - 10 : 0; i < History.size(); i++) - AddLog("%3d: %s\n", i, History[i]); - } - else - { - AddLog("Unknown command: '%s'\n", command_line); - } - } - - static int TextEditCallbackStub(ImGuiTextEditCallbackData* data) - { - ExampleAppConsole* console = (ExampleAppConsole*)data->UserData; - return console->TextEditCallback(data); - } - - int TextEditCallback(ImGuiTextEditCallbackData* data) - { - //AddLog("cursor: %d, selection: %d-%d", data->CursorPos, data->SelectionStart, data->SelectionEnd); - switch (data->EventFlag) - { - case ImGuiInputTextFlags_CallbackCompletion: - { - // Example of TEXT COMPLETION - - // Locate beginning of current word - const char* word_end = data->Buf + data->CursorPos; - const char* word_start = word_end; - while (word_start > data->Buf) - { - const char c = word_start[-1]; - if (ImCharIsSpace(c) || c == ',' || c == ';') - break; - word_start--; - } - - // Build a list of candidates - ImVector candidates; - for (size_t i = 0; i < Commands.size(); i++) - if (ImStrnicmp(Commands[i], word_start, (int)(word_end-word_start)) == 0) - candidates.push_back(Commands[i]); - - if (candidates.size() == 0) - { - // No match - AddLog("No match for \"%.*s\"!\n", word_end-word_start, word_start); - } - else if (candidates.size() == 1) - { - // Single match. Delete the beginning of the word and replace it entirely so we've got nice casing - data->DeleteChars((int)(word_start-data->Buf), (int)(word_end-word_start)); - data->InsertChars(data->CursorPos, candidates[0]); - data->InsertChars(data->CursorPos, " "); - } - else - { - // Multiple matches. Complete as much as we can, so inputing "C" will complete to "CL" and display "CLEAR" and "CLASSIFY" - int match_len = (int)(word_end - word_start); - for (;;) - { - int c = 0; - bool all_candidates_matches = true; - for (size_t i = 0; i < candidates.size() && all_candidates_matches; i++) - if (i == 0) - c = toupper(candidates[i][match_len]); - else if (c != toupper(candidates[i][match_len])) - all_candidates_matches = false; - if (!all_candidates_matches) - break; - match_len++; - } - - if (match_len > 0) - { - data->DeleteChars((int)(word_start - data->Buf), (int)(word_end-word_start)); - data->InsertChars(data->CursorPos, candidates[0], candidates[0] + match_len); - } - - // List matches - AddLog("Possible matches:\n"); - for (size_t i = 0; i < candidates.size(); i++) - AddLog("- %s\n", candidates[i]); - } - - break; - } - case ImGuiInputTextFlags_CallbackHistory: - { - // Example of HISTORY - const int prev_history_pos = HistoryPos; - if (data->EventKey == ImGuiKey_UpArrow) - { - if (HistoryPos == -1) - HistoryPos = (int)(History.size() - 1); - else if (HistoryPos > 0) - HistoryPos--; - } - else if (data->EventKey == ImGuiKey_DownArrow) - { - if (HistoryPos != -1) - if (++HistoryPos >= (int)History.size()) - HistoryPos = -1; - } - - // A better implementation would preserve the data on the current input line along with cursor position. - if (prev_history_pos != HistoryPos) - { - ImFormatString(data->Buf, data->BufSize, "%s", (HistoryPos >= 0) ? History[HistoryPos] : ""); - data->BufDirty = true; - data->CursorPos = data->SelectionStart = data->SelectionEnd = (int)strlen(data->Buf); - } - } - } - return 0; - } -}; - -static void ShowExampleAppConsole(bool* opened) -{ - static ExampleAppConsole console; - console.Run("Example: Console", opened); -} - -static void ShowExampleAppLongText(bool* opened) -{ - ImGui::SetNextWindowSize(ImVec2(520,600), ImGuiSetCond_FirstUseEver); - if (!ImGui::Begin("Example: Long text display", opened)) - { - ImGui::End(); - return; - } - - static int test_type = 0; - static ImGuiTextBuffer log; - static int lines = 0; - ImGui::Text("Printing unusually long amount of text."); - ImGui::Combo("Test type", &test_type, "Single call to TextUnformatted()\0Multiple calls to Text(), clipped manually\0Multiple calls to Text(), not clipped"); - ImGui::Text("Buffer contents: %d lines, %d bytes", lines, log.size()); - if (ImGui::Button("Clear")) { log.clear(); lines = 0; } - ImGui::SameLine(); - if (ImGui::Button("Add 1000 lines")) - { - for (int i = 0; i < 1000; i++) - log.append("%i The quick brown fox jumps over the lazy dog\n", lines+i); - lines += 1000; - } - ImGui::BeginChild("Log"); - switch (test_type) - { - case 0: - // Single call to TextUnformatted() with a big buffer - ImGui::TextUnformatted(log.begin(), log.end()); - break; - case 1: - // Multiple calls to Text(), manually coarsely clipped - demonstrate how to use the CalcListClipping() helper. - ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0,0)); - int display_start, display_end; - ImGui::CalcListClipping(lines, ImGui::GetTextLineHeight(), &display_start, &display_end); - ImGui::SetCursorPosY(ImGui::GetCursorPosY() + (display_start) * ImGui::GetTextLineHeight()); - for (int i = display_start; i < display_end; i++) - ImGui::Text("%i The quick brown fox jumps over the lazy dog\n", i); - ImGui::SetCursorPosY(ImGui::GetCursorPosY() + (lines - display_end) * ImGui::GetTextLineHeight()); - ImGui::PopStyleVar(); - break; - case 2: - // Multiple calls to Text(), not clipped - ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0,0)); - for (int i = 0; i < lines; i++) - ImGui::Text("%i The quick brown fox jumps over the lazy dog\n", i); - ImGui::PopStyleVar(); - break; - } - ImGui::EndChild(); - ImGui::End(); -} - -// End of Sample code -#endif - -//----------------------------------------------------------------------------- -// FONT DATA -//----------------------------------------------------------------------------- -// Compressed with stb_compress() then converted to a C array. -// Use the program in extra_fonts/binary_to_compressed_c.cpp to create the array from a TTF file. -// Decompressor from stb.h (public domain) by Sean Barrett https://github.com/nothings/stb/blob/master/stb.h -//----------------------------------------------------------------------------- - -static unsigned int stb_decompress_length(unsigned char *input) +static const unsigned TEXT_POOL_SIZE = 8000; +static char g_textPool[TEXT_POOL_SIZE]; +static unsigned g_textPoolSize = 0; +static const char* allocText(const char* text) { - return (input[8] << 24) + (input[9] << 16) + (input[10] << 8) + input[11]; -} - -static unsigned char *stb__barrier, *stb__barrier2, *stb__barrier3, *stb__barrier4; -static unsigned char *stb__dout; -static void stb__match(unsigned char *data, unsigned int length) -{ - // INVERSE of memmove... write each byte before copying the next... - IM_ASSERT (stb__dout + length <= stb__barrier); - if (stb__dout + length > stb__barrier) { stb__dout += length; return; } - if (data < stb__barrier4) { stb__dout = stb__barrier+1; return; } - while (length--) *stb__dout++ = *data++; -} - -static void stb__lit(unsigned char *data, unsigned int length) -{ - IM_ASSERT (stb__dout + length <= stb__barrier); - if (stb__dout + length > stb__barrier) { stb__dout += length; return; } - if (data < stb__barrier2) { stb__dout = stb__barrier+1; return; } - memcpy(stb__dout, data, length); - stb__dout += length; -} - -#define stb__in2(x) ((i[x] << 8) + i[(x)+1]) -#define stb__in3(x) ((i[x] << 16) + stb__in2((x)+1)) -#define stb__in4(x) ((i[x] << 24) + stb__in3((x)+1)) - -static unsigned char *stb_decompress_token(unsigned char *i) -{ - if (*i >= 0x20) { // use fewer if's for cases that expand small - if (*i >= 0x80) stb__match(stb__dout-i[1]-1, i[0] - 0x80 + 1), i += 2; - else if (*i >= 0x40) stb__match(stb__dout-(stb__in2(0) - 0x4000 + 1), i[2]+1), i += 3; - else /* *i >= 0x20 */ stb__lit(i+1, i[0] - 0x20 + 1), i += 1 + (i[0] - 0x20 + 1); - } else { // more ifs for cases that expand large, since overhead is amortized - if (*i >= 0x18) stb__match(stb__dout-(stb__in3(0) - 0x180000 + 1), i[3]+1), i += 4; - else if (*i >= 0x10) stb__match(stb__dout-(stb__in3(0) - 0x100000 + 1), stb__in2(3)+1), i += 5; - else if (*i >= 0x08) stb__lit(i+2, stb__in2(0) - 0x0800 + 1), i += 2 + (stb__in2(0) - 0x0800 + 1); - else if (*i == 0x07) stb__lit(i+3, stb__in2(1) + 1), i += 3 + (stb__in2(1) + 1); - else if (*i == 0x06) stb__match(stb__dout-(stb__in3(1)+1), i[4]+1), i += 5; - else if (*i == 0x04) stb__match(stb__dout-(stb__in3(1)+1), stb__in2(4)+1), i += 6; - } - return i; -} - -static unsigned int stb_adler32(unsigned int adler32, unsigned char *buffer, unsigned int buflen) -{ - const unsigned long ADLER_MOD = 65521; - unsigned long s1 = adler32 & 0xffff, s2 = adler32 >> 16; - unsigned long blocklen, i; - - blocklen = buflen % 5552; - while (buflen) { - for (i=0; i + 7 < blocklen; i += 8) { - s1 += buffer[0], s2 += s1; - s1 += buffer[1], s2 += s1; - s1 += buffer[2], s2 += s1; - s1 += buffer[3], s2 += s1; - s1 += buffer[4], s2 += s1; - s1 += buffer[5], s2 += s1; - s1 += buffer[6], s2 += s1; - s1 += buffer[7], s2 += s1; - - buffer += 8; - } - - for (; i < blocklen; ++i) - s1 += *buffer++, s2 += s1; - - s1 %= ADLER_MOD, s2 %= ADLER_MOD; - buflen -= blocklen; - blocklen = 5552; - } - return (unsigned int)(s2 << 16) + (unsigned int)s1; -} - -static unsigned int stb_decompress(unsigned char *output, unsigned char *i, unsigned int length) -{ - unsigned int olen; - if (stb__in4(0) != 0x57bC0000) return 0; - if (stb__in4(4) != 0) return 0; // error! stream is > 4GB - olen = stb_decompress_length(i); - stb__barrier2 = i; - stb__barrier3 = i+length; - stb__barrier = output + olen; - stb__barrier4 = output; - i += 16; - - stb__dout = output; - for (;;) { - unsigned char *old_i = i; - i = stb_decompress_token(i); - if (i == old_i) { - if (*i == 0x05 && i[1] == 0xfa) { - IM_ASSERT(stb__dout == output + olen); - if (stb__dout != output + olen) return 0; - if (stb_adler32(1, output, olen) != (unsigned int) stb__in4(2)) - return 0; - return olen; - } else { - IM_ASSERT(0); /* NOTREACHED */ + unsigned len = strlen(text)+1; + if (g_textPoolSize + len >= TEXT_POOL_SIZE) return 0; - } - } - IM_ASSERT(stb__dout <= output + olen); - if (stb__dout > output + olen) - return 0; - } + char* dst = &g_textPool[g_textPoolSize]; + memcpy(dst, text, len); + g_textPoolSize += len; + return dst; } -//----------------------------------------------------------------------------- -// ProggyClean.ttf -// Copyright (c) 2004, 2005 Tristan Grimmer -// MIT license (see License.txt in http://www.upperbounds.net/download/ProggyClean.ttf.zip) -// Download and more information at http://upperbounds.net -//----------------------------------------------------------------------------- -static const unsigned int proggy_clean_ttf_compressed_size = 9583; -static const unsigned int proggy_clean_ttf_compressed_data[9584/4] = +static const unsigned GFXCMD_QUEUE_SIZE = 5000; +static imguiGfxCmd g_gfxCmdQueue[GFXCMD_QUEUE_SIZE]; +static unsigned g_gfxCmdQueueSize = 0; + +static void resetGfxCmdQueue() { - 0x0000bc57, 0x00000000, 0xf8a00000, 0x00000400, 0x00010037, 0x000c0000, 0x00030080, 0x2f534f40, 0x74eb8832, 0x01000090, 0x2c158248, 0x616d634e, - 0x23120270, 0x03000075, 0x241382a0, 0x74766352, 0x82178220, 0xfc042102, 0x02380482, 0x66796c67, 0x5689af12, 0x04070000, 0x80920000, 0x64616568, - 0xd36691d7, 0xcc201b82, 0x36210382, 0x27108268, 0xc3014208, 0x04010000, 0x243b0f82, 0x78746d68, 0x807e008a, 0x98010000, 0x06020000, 0x61636f6c, - 0xd8b0738c, 0x82050000, 0x0402291e, 0x7078616d, 0xda00ae01, 0x28201f82, 0x202c1082, 0x656d616e, 0x96bb5925, 0x84990000, 0x9e2c1382, 0x74736f70, - 0xef83aca6, 0x249b0000, 0xd22c3382, 0x70657270, 0x12010269, 0xf4040000, 0x08202f82, 0x012ecb84, 0x553c0000, 0x0f5fd5e9, 0x0300f53c, 0x00830008, - 0x7767b722, 0x002b3f82, 0xa692bd00, 0xfe0000d7, 0x83800380, 0x21f1826f, 0x00850002, 0x41820120, 0x40fec026, 0x80030000, 0x05821083, 0x07830120, - 0x0221038a, 0x24118200, 0x90000101, 0x82798200, 0x00022617, 0x00400008, 0x2009820a, 0x82098276, 0x82002006, 0x9001213b, 0x0223c883, 0x828a02bc, - 0x858f2010, 0xc5012507, 0x00023200, 0x04210083, 0x91058309, 0x6c412b03, 0x40007374, 0xac200000, 0x00830008, 0x01000523, 0x834d8380, 0x80032103, - 0x012101bf, 0x23b88280, 0x00800000, 0x0b830382, 0x07820120, 0x83800021, 0x88012001, 0x84002009, 0x2005870f, 0x870d8301, 0x2023901b, 0x83199501, - 0x82002015, 0x84802000, 0x84238267, 0x88002027, 0x8561882d, 0x21058211, 0x13880000, 0x01800022, 0x05850d85, 0x0f828020, 0x03208384, 0x03200582, - 0x47901b84, 0x1b850020, 0x1f821d82, 0x3f831d88, 0x3f410383, 0x84058405, 0x210982cd, 0x09830000, 0x03207789, 0xf38a1384, 0x01203782, 0x13872384, - 0x0b88c983, 0x0d898f84, 0x00202982, 0x23900383, 0x87008021, 0x83df8301, 0x86118d03, 0x863f880d, 0x8f35880f, 0x2160820f, 0x04830300, 0x1c220382, - 0x05820100, 0x4c000022, 0x09831182, 0x04001c24, 0x11823000, 0x0800082e, 0x00000200, 0xff007f00, 0xffffac20, 0x00220982, 0x09848100, 0xdf216682, - 0x843586d5, 0x06012116, 0x04400684, 0xa58120d7, 0x00b127d8, 0x01b88d01, 0x2d8685ff, 0xc100c621, 0xf4be0801, 0x9e011c01, 0x88021402, 0x1403fc02, - 0x9c035803, 0x1404de03, 0x50043204, 0xa2046204, 0x66051605, 0x1206bc05, 0xd6067406, 0x7e073807, 0x4e08ec07, 0x96086c08, 0x1009d008, 0x88094a09, - 0x800a160a, 0x560b040b, 0x2e0cc80b, 0xea0c820c, 0xa40d5e0d, 0x500eea0d, 0x280f960e, 0x1210b00f, 0xe0107410, 0xb6115211, 0x6e120412, 0x4c13c412, - 0xf613ac13, 0xae145814, 0x4015ea14, 0xa6158015, 0x1216b815, 0xc6167e16, 0x8e173417, 0x5618e017, 0xee18ba18, 0x96193619, 0x481ad419, 0xf01a9c1a, - 0xc81b5c1b, 0x4c1c041c, 0xea1c961c, 0x921d2a1d, 0x401ed21d, 0xe01e8e1e, 0x761f241f, 0xa61fa61f, 0x01821020, 0x8a202e34, 0xc820b220, 0x74211421, - 0xee219821, 0x86226222, 0x01820c23, 0x83238021, 0x23983c01, 0x24d823b0, 0x244a2400, 0x24902468, 0x250625ae, 0x25822560, 0x26f825f8, 0x82aa2658, - 0xd8be0801, 0x9a274027, 0x68280a28, 0x0e29a828, 0xb8292029, 0x362af829, 0x602a602a, 0x2a2b022b, 0xac2b5e2b, 0x202ce62b, 0x9a2c342c, 0x5c2d282d, - 0xaa2d782d, 0x262ee82d, 0x262fa62e, 0xf42fb62f, 0xc8305e30, 0xb4313e31, 0x9e321e32, 0x82331e33, 0x5c34ee33, 0x3a35ce34, 0xd4358635, 0x72362636, - 0x7637e636, 0x3a38d837, 0x1239a638, 0xae397439, 0x9a3a2e3a, 0x7c3b063b, 0x3a3ce83b, 0x223d963c, 0xec3d863d, 0xc63e563e, 0x9a3f2a3f, 0x6a401240, - 0x3641d040, 0x0842a241, 0x7a424042, 0xf042b842, 0xcc436243, 0x8a442a44, 0x5845ee44, 0xe245b645, 0xb4465446, 0x7a471447, 0x5448da47, 0x4049c648, - 0x15462400, 0x034d0808, 0x0b000700, 0x13000f00, 0x1b001700, 0x23001f00, 0x2b002700, 0x33002f00, 0x3b003700, 0x43003f00, 0x4b004700, 0x53004f00, - 0x5b005700, 0x63005f00, 0x6b006700, 0x73006f00, 0x7b007700, 0x83007f00, 0x8b008700, 0x00008f00, 0x15333511, 0x20039631, 0x20178205, 0xd3038221, - 0x20739707, 0x25008580, 0x028080fc, 0x05be8080, 0x04204a85, 0x05ce0685, 0x0107002a, 0x02000080, 0x00000400, 0x250d8b41, 0x33350100, 0x03920715, - 0x13820320, 0x858d0120, 0x0e8d0320, 0xff260d83, 0x00808000, 0x54820106, 0x04800223, 0x845b8c80, 0x41332059, 0x078b068f, 0x82000121, 0x82fe2039, - 0x84802003, 0x83042004, 0x23598a0e, 0x00180000, 0x03210082, 0x42ab9080, 0x73942137, 0x2013bb41, 0x8f978205, 0x2027a39b, 0x20b68801, 0x84b286fd, - 0x91c88407, 0x41032011, 0x11a51130, 0x15000027, 0x80ff8000, 0x11af4103, 0x841b0341, 0x8bd983fd, 0x9be99bc9, 0x8343831b, 0x21f1821f, 0xb58300ff, - 0x0f84e889, 0xf78a0484, 0x8000ff22, 0x0020eeb3, 0x14200082, 0x2130ef41, 0xeb431300, 0x4133200a, 0xd7410ecb, 0x9a07200b, 0x2027871b, 0x21238221, - 0xe7828080, 0xe784fd20, 0xe8848020, 0xfe808022, 0x08880d85, 0xba41fd20, 0x82248205, 0x85eab02a, 0x008022e7, 0x2cd74200, 0x44010021, 0xd34406eb, - 0x44312013, 0xcf8b0eef, 0x0d422f8b, 0x82332007, 0x0001212f, 0x8023cf82, 0x83000180, 0x820583de, 0x830682d4, 0x820020d4, 0x82dc850a, 0x20e282e9, - 0xb2ff85fe, 0x010327e9, 0x02000380, 0x0f440400, 0x0c634407, 0x68825982, 0x85048021, 0x260a825d, 0x010b0000, 0x4400ff00, 0x2746103f, 0x08d74209, - 0x4d440720, 0x0eaf4406, 0xc3441d20, 0x23078406, 0xff800002, 0x04845b83, 0x8d05b241, 0x1781436f, 0x6b8c87a5, 0x1521878e, 0x06474505, 0x01210783, - 0x84688c00, 0x8904828e, 0x441e8cf7, 0x0b270cff, 0x80008000, 0x45030003, 0xfb430fab, 0x080f4107, 0x410bf942, 0xd34307e5, 0x070d4207, 0x80800123, - 0x205d85fe, 0x849183fe, 0x20128404, 0x82809702, 0x00002217, 0x41839a09, 0x6b4408cf, 0x0733440f, 0x3b460720, 0x82798707, 0x97802052, 0x0000296f, - 0xff800004, 0x01800100, 0x0021ef89, 0x0a914625, 0x410a4d41, 0x00250ed4, 0x00050000, 0x056d4280, 0x210a7b46, 0x21481300, 0x46ed8512, 0x00210bd1, - 0x89718202, 0x21738877, 0x2b850001, 0x00220582, 0x87450a00, 0x0ddb4606, 0x41079b42, 0x9d420c09, 0x0b09420b, 0x8d820720, 0x9742fc84, 0x42098909, - 0x00241e0f, 0x00800014, 0x0b47da82, 0x0833442a, 0x49078d41, 0x2f450f13, 0x42278f17, 0x01200751, 0x22063742, 0x44808001, 0x20450519, 0x88068906, - 0x83fe2019, 0x4203202a, 0x1a941a58, 0x00820020, 0xe7a40e20, 0x420ce146, 0x854307e9, 0x0fcb4713, 0xff20a182, 0xfe209b82, 0x0c867f8b, 0x0021aea4, - 0x219fa40f, 0x7d41003b, 0x07194214, 0xbf440520, 0x071d4206, 0x6941a590, 0x80802309, 0x028900ff, 0xa9a4b685, 0xc5808021, 0x449b82ab, 0x152007eb, - 0x42134d46, 0x61440a15, 0x051e4208, 0x222b0442, 0x47001100, 0xfd412913, 0x17194714, 0x410f5b41, 0x02220773, 0x09428080, 0x21a98208, 0xd4420001, - 0x481c840d, 0x00232bc9, 0x42120000, 0xe74c261b, 0x149d4405, 0x07209d87, 0x410db944, 0x14421c81, 0x42fd2005, 0x80410bd2, 0x203d8531, 0x06874100, - 0x48256f4a, 0xcb420c95, 0x13934113, 0x44075d44, 0x044c0855, 0x00ff2105, 0xfe228185, 0x45448000, 0x22c5b508, 0x410c0000, 0x7b412087, 0x1bb74514, - 0x32429c85, 0x0a574805, 0x21208943, 0x8ba01300, 0x440dfb4e, 0x77431437, 0x245b4113, 0x200fb145, 0x41108ffe, 0x80203562, 0x00200082, 0x46362b42, - 0x1742178d, 0x4527830f, 0x0f830b2f, 0x4a138146, 0x802409a1, 0xfe8000ff, 0x94419982, 0x09294320, 0x04000022, 0x49050f4f, 0xcb470a63, 0x48032008, - 0x2b48067b, 0x85022008, 0x82638338, 0x00002209, 0x05af4806, 0x900e9f49, 0x84c5873f, 0x214285bd, 0x064900ff, 0x0c894607, 0x00000023, 0x4903820a, - 0x714319f3, 0x0749410c, 0x8a07a145, 0x02152507, 0xfe808000, 0x74490386, 0x8080211b, 0x0c276f82, 0x00018000, 0x48028003, 0x2b2315db, 0x43002f00, - 0x6f82142f, 0x44011521, 0x93510da7, 0x20e68508, 0x06494d80, 0x8e838020, 0x06821286, 0x124bff20, 0x25f3830c, 0x03800080, 0xe74a0380, 0x207b8715, - 0x876b861d, 0x4a152007, 0x07870775, 0xf6876086, 0x8417674a, 0x0a0021f2, 0x431c9743, 0x8d421485, 0x200b830b, 0x06474d03, 0x71828020, 0x04510120, - 0x42da8606, 0x1f831882, 0x001a0022, 0xff4d0082, 0x0b0f532c, 0x0d449b94, 0x4e312007, 0x074f12e7, 0x0bf3490b, 0xbb412120, 0x413f820a, 0xef490857, - 0x80002313, 0xe2830001, 0x6441fc20, 0x8b802006, 0x00012108, 0xfd201582, 0x492c9b48, 0x802014ff, 0x51084347, 0x0f4327f3, 0x17bf4a14, 0x201b7944, - 0x06964201, 0x134ffe20, 0x20d6830b, 0x25d78280, 0xfd800002, 0x05888000, 0x9318dc41, 0x21d282d4, 0xdb481800, 0x0dff542a, 0x45107743, 0xe14813f5, - 0x0f034113, 0x83135d45, 0x47b28437, 0xe4510e73, 0x21f58e06, 0x2b8400fd, 0x1041fcac, 0x08db4b0b, 0x421fdb41, 0xdf4b18df, 0x011d210a, 0x420af350, - 0x6e8308af, 0xac85cb86, 0x1e461082, 0x82b7a407, 0x411420a3, 0xa34130ab, 0x178f4124, 0x41139741, 0x86410d93, 0x82118511, 0x057243d8, 0x8941d9a4, - 0x3093480c, 0x4a13474f, 0xfb5016a9, 0x07ad4108, 0x4a0f9d42, 0xfe200fad, 0x4708aa41, 0x83482dba, 0x288f4d06, 0xb398c3bb, 0x44267b41, 0xb34439d7, - 0x0755410f, 0x200ebb45, 0x0f5f4215, 0x20191343, 0x06df5301, 0xf04c0220, 0x2ba64d07, 0x82050841, 0x430020ce, 0xa78f3627, 0x5213ff42, 0x2f970bc1, - 0x4305ab55, 0xa084111b, 0x450bac45, 0x5f4238b8, 0x010c2106, 0x0220ed82, 0x441bb344, 0x875010af, 0x0737480f, 0x490c5747, 0x0c840c03, 0x4c204b42, - 0x8ba905d7, 0x8b948793, 0x510c0c51, 0xfb4b24b9, 0x1b174107, 0x5709d74c, 0xd1410ca5, 0x079d480f, 0x201ff541, 0x06804780, 0x7d520120, 0x80002205, - 0x20a983fe, 0x47bb83fe, 0x1b8409b4, 0x81580220, 0x4e00202c, 0x4f41282f, 0x0eab4f17, 0x57471520, 0x0e0f4808, 0x8221e041, 0x3e1b4a8b, 0x4407175d, - 0x1b4b071f, 0x4a0f8b07, 0x174a0703, 0x0ba5411b, 0x430fb141, 0x0120057b, 0xfc20dd82, 0x4a056047, 0xf4850c0c, 0x01221982, 0x02828000, 0x1a5d088b, - 0x20094108, 0x8c0e3941, 0x4900200e, 0x7744434f, 0x200b870b, 0x0e4b5a33, 0x2b41f78b, 0x8b138307, 0x0b9f450b, 0x2406f741, 0xfd808001, 0x09475a00, - 0x84000121, 0x5980200e, 0x85450e5d, 0x832c8206, 0x4106831e, 0x00213814, 0x28b34810, 0x410c2f4b, 0x5f4a13d7, 0x0b2b4113, 0x6e43a883, 0x11174b05, - 0x4b066a45, 0xcc470541, 0x5000202b, 0xcb472f4b, 0x44b59f0f, 0xc5430b5b, 0x0d654907, 0x21065544, 0xd6828080, 0xfe201982, 0x8230ec4a, 0x120025c2, - 0x80ff8000, 0x4128d74d, 0x3320408b, 0x410a9f50, 0xdb822793, 0x822bd454, 0x61134b2e, 0x410b214a, 0xad4117c9, 0x0001211f, 0x4206854f, 0x4b430596, - 0x06bb5530, 0x2025cf46, 0x0ddd5747, 0x500ea349, 0x0f840fa7, 0x5213c153, 0x634e08d1, 0x0bbe4809, 0x59316e4d, 0x5b50053f, 0x203f6323, 0x5117eb46, - 0x94450a63, 0x246e410a, 0x63410020, 0x0bdb5f2f, 0x4233ab44, 0x39480757, 0x112d4a07, 0x7241118f, 0x000e2132, 0x9f286f41, 0x0f8762c3, 0x33350723, - 0x094e6415, 0x2010925f, 0x067252fe, 0xd0438020, 0x63a68225, 0x11203a4f, 0x480e6360, 0x5748131f, 0x079b521f, 0x200e2f43, 0x864b8315, 0x113348e7, - 0x85084e48, 0x06855008, 0x5880fd21, 0x7c420925, 0x0c414824, 0x37470c86, 0x1b8b422b, 0x5b0a8755, 0x23410c21, 0x0b83420b, 0x5a082047, 0xf482067f, - 0xa80b4c47, 0x0c0021cf, 0x20207b42, 0x0fb74100, 0x420b8744, 0xeb43076f, 0x0f6f420b, 0x4261fe20, 0x439aa00c, 0x215034e3, 0x0ff9570f, 0x4b1f2d5d, - 0x2d5d0c6f, 0x09634d0b, 0x1f51b8a0, 0x620f200c, 0xaf681e87, 0x24f94d07, 0x4e0f4945, 0xfe200c05, 0x22139742, 0x57048080, 0x23950c20, 0x97601585, - 0x4813201f, 0xad620523, 0x200f8f0f, 0x9e638f15, 0x00002181, 0x41342341, 0x0f930f0b, 0x210b4b62, 0x978f0001, 0xfe200f84, 0x8425c863, 0x2704822b, - 0x80000a00, 0x00038001, 0x610e9768, 0x834514bb, 0x0bc3430f, 0x2107e357, 0x80848080, 0x4400fe21, 0x2e410983, 0x00002a1a, 0x00000700, 0x800380ff, - 0x0fdf5800, 0x59150021, 0xd142163d, 0x0c02410c, 0x01020025, 0x65800300, 0x00240853, 0x1d333501, 0x15220382, 0x35420001, 0x44002008, 0x376406d7, - 0x096f6b19, 0x480bc142, 0x8f4908a7, 0x211f8b1f, 0x9e830001, 0x0584fe20, 0x4180fd21, 0x11850910, 0x8d198259, 0x000021d4, 0x5a08275d, 0x275d1983, - 0x06d9420e, 0x9f08b36a, 0x0f7d47b5, 0x8d8a2f8b, 0x4c0e0b57, 0xe7410e17, 0x42d18c1a, 0xb351087a, 0x1ac36505, 0x4b4a2f20, 0x0b9f450d, 0x430beb53, - 0xa7881015, 0xa5826a83, 0x80200f82, 0x86185a65, 0x4100208e, 0x176c3367, 0x0fe7650b, 0x4a17ad4b, 0x0f4217ed, 0x112e4206, 0x41113a42, 0xf7423169, - 0x0cb34737, 0x560f8b46, 0xa75407e5, 0x5f01200f, 0x31590c48, 0x80802106, 0x42268841, 0x0020091e, 0x4207ef64, 0x69461df7, 0x138d4114, 0x820f5145, - 0x53802090, 0xff200529, 0xb944b183, 0x417e8505, 0x00202561, 0x15210082, 0x42378200, 0x9b431cc3, 0x004f220d, 0x0dd54253, 0x4213f149, 0x7d41133b, - 0x42c9870b, 0x802010f9, 0x420b2c42, 0x8f441138, 0x267c4408, 0x600cb743, 0x8f4109d3, 0x05ab701d, 0x83440020, 0x3521223f, 0x0b794733, 0xfb62fe20, - 0x4afd2010, 0xaf410ae7, 0x25ce8525, 0x01080000, 0x7b6b0000, 0x0973710b, 0x82010021, 0x49038375, 0x33420767, 0x052c4212, 0x58464b85, 0x41fe2005, - 0x50440c27, 0x000c2209, 0x1cb36b80, 0x9b06df44, 0x0f93566f, 0x52830220, 0xfe216e8d, 0x200f8200, 0x0fb86704, 0xb057238d, 0x050b5305, 0x7217eb47, - 0xbd410b6b, 0x0f214610, 0x871f9956, 0x1e91567e, 0x2029b741, 0x20008200, 0x18b7410a, 0x27002322, 0x41095543, 0x0f8f0fb3, 0x41000121, 0x889d111c, - 0x14207b82, 0x00200382, 0x73188761, 0x475013a7, 0x6e33200c, 0x234e0ea3, 0x9b138313, 0x08e54d17, 0x9711094e, 0x2ee74311, 0x4908875e, 0xd75d1f1f, - 0x19ab5238, 0xa2084d48, 0x63a7a9b3, 0x55450b83, 0x0fd74213, 0x440d814c, 0x4f481673, 0x05714323, 0x13000022, 0x412e1f46, 0xdf493459, 0x21c7550f, - 0x8408215f, 0x201d49cb, 0xb1103043, 0x0f0d65d7, 0x452b8d41, 0x594b0f8d, 0x0b004605, 0xb215eb46, 0x000a24d7, 0x47000080, 0x002118cf, 0x06436413, - 0x420bd750, 0x2b500743, 0x076a470c, 0x4105c050, 0xd942053f, 0x0d00211a, 0x5f44779c, 0x0ce94805, 0x51558186, 0x14a54c0b, 0x49082b41, 0x0a4b0888, - 0x8080261f, 0x0d000000, 0x20048201, 0x1deb6a03, 0x420cb372, 0x07201783, 0x4306854d, 0x8b830c59, 0x59093c74, 0x0020250f, 0x67070f4a, 0x2341160b, - 0x00372105, 0x431c515d, 0x554e17ef, 0x0e5d6b05, 0x41115442, 0xb74a1ac1, 0x2243420a, 0x5b4f878f, 0x7507200f, 0x384b086f, 0x09d45409, 0x0020869a, - 0x12200082, 0xab460382, 0x10075329, 0x54138346, 0xaf540fbf, 0x1ea75413, 0x9a0c9e54, 0x0f6b44c1, 0x41000021, 0x47412a4f, 0x07374907, 0x5310bf76, - 0xff2009b4, 0x9a09a64c, 0x8200208d, 0x34c34500, 0x970fe141, 0x1fd74b0f, 0x440a3850, 0x206411f0, 0x27934609, 0x470c5d41, 0x555c2947, 0x1787540f, - 0x6e0f234e, 0x7d540a1b, 0x1d736b08, 0x0026a088, 0x80000e00, 0x9b5200ff, 0x08ef4318, 0x450bff77, 0x1d4d0b83, 0x081f7006, 0xcb691b86, 0x4b022008, - 0xc34b0b33, 0x1d0d4a0c, 0x8025a188, 0x0b000000, 0x52a38201, 0xbf7d0873, 0x0c234511, 0x8f0f894a, 0x4101200f, 0x0c880c9d, 0x2b418ea1, 0x06c74128, - 0x66181341, 0x7b4c0bb9, 0x0c06630b, 0xfe200c87, 0x9ba10882, 0x27091765, 0x01000008, 0x02800380, 0x48113f4e, 0x29430cf5, 0x09a75a0b, 0x31618020, - 0x6d802009, 0x61840e33, 0x8208bf51, 0x0c637d61, 0x7f092379, 0x4f470f4b, 0x1797510c, 0x46076157, 0xf5500fdf, 0x0f616910, 0x1171fe20, 0x82802006, - 0x08696908, 0x41127a4c, 0x3f4a15f3, 0x01042607, 0x0200ff00, 0x1cf77700, 0xff204185, 0x00235b8d, 0x43100000, 0x3b22243f, 0x3b4d3f00, 0x0b937709, - 0xad42f18f, 0x0b1f420f, 0x51084b43, 0x8020104a, 0xb557ff83, 0x052b7f2a, 0x0280ff22, 0x250beb78, 0x00170013, 0xbf6d2500, 0x07db760e, 0x410e2b7f, - 0x00230e4f, 0x49030000, 0x0582055b, 0x07000326, 0x00000b00, 0x580bcd46, 0x00200cdd, 0x57078749, 0x8749160f, 0x0f994f0a, 0x41134761, 0x01200b31, - 0xeb796883, 0x0b41500b, 0x0e90b38e, 0x202e7b51, 0x05d95801, 0x41080570, 0x1d530fc9, 0x0b937a0f, 0xaf8eb387, 0xf743b98f, 0x07c74227, 0x80000523, - 0x0fcb4503, 0x430ca37b, 0x7782077f, 0x8d0a9947, 0x08af4666, 0xeb798020, 0x6459881e, 0xc3740bbf, 0x0feb6f0b, 0x20072748, 0x052b6102, 0x435e0584, - 0x7d088308, 0x03200afd, 0x92109e41, 0x28aa8210, 0x80001500, 0x80030000, 0x0fdb5805, 0x209f4018, 0xa7418d87, 0x0aa3440f, 0x20314961, 0x073a52ff, - 0x6108505d, 0x43181051, 0x00223457, 0xe7820500, 0x50028021, 0x81410d33, 0x063d7108, 0xdb41af84, 0x4d888205, 0x00201198, 0x463d835f, 0x152106d7, - 0x0a355a33, 0x6917614e, 0x75411f4d, 0x184b8b07, 0x1809c344, 0x21091640, 0x0b828000, 0x42808021, 0x26790519, 0x86058605, 0x2428422d, 0x22123b42, - 0x42000080, 0xf587513b, 0x7813677b, 0xaf4d139f, 0x00ff210c, 0x5e0a1d57, 0x3b421546, 0x01032736, 0x02000380, 0x41180480, 0x2f420f07, 0x0c624807, - 0x00000025, 0x18000103, 0x83153741, 0x430120c3, 0x042106b2, 0x088d4d00, 0x2f830620, 0x1810434a, 0x18140345, 0x8507fb41, 0x5ee582ea, 0x0023116c, - 0x8d000600, 0x053b56af, 0xa6554fa2, 0x0d704608, 0x40180d20, 0x47181a43, 0xd37b07ff, 0x0b79500c, 0x420fd745, 0x47450bd9, 0x8471830a, 0x095a777e, - 0x84137542, 0x82002013, 0x2f401800, 0x0007213b, 0x4405e349, 0x0d550ff3, 0x16254c0c, 0x820ffe4a, 0x0400218a, 0x89066f41, 0x106b414f, 0xc84d0120, - 0x80802206, 0x0c9a4b03, 0x00100025, 0x68000200, 0x9d8c2473, 0x44134344, 0xf36a0f33, 0x4678860f, 0x1b440a25, 0x41988c0a, 0x80201879, 0x43079b5e, - 0x4a18080b, 0x0341190b, 0x1259530c, 0x43251552, 0x908205c8, 0x0cac4018, 0x86000421, 0x0e504aa2, 0x0020b891, 0xfb450082, 0x51132014, 0x8f5205f3, - 0x35052108, 0x8505cb59, 0x0f6d4f70, 0x82150021, 0x29af5047, 0x4f004b24, 0x75795300, 0x1b595709, 0x460b6742, 0xbf4b0f0d, 0x5743870b, 0xcb6d1461, - 0x08f64505, 0x4e05ab6c, 0x334126c3, 0x0bcb6b0d, 0x1811034d, 0x4111ef4b, 0x814f1ce5, 0x20af8227, 0x07fd7b80, 0x41188e84, 0xef410f33, 0x80802429, - 0x410d0000, 0xa34205ab, 0x76b7881c, 0xff500b89, 0x0741430f, 0x20086f4a, 0x209d8200, 0x234c18fd, 0x05d4670a, 0x4509af51, 0x9642078d, 0x189e831d, - 0x7c1cc74b, 0xcd4c07b9, 0x0e7c440f, 0x8b7b0320, 0x21108210, 0xc76c8080, 0x03002106, 0x6b23bf41, 0xc549060b, 0x7946180b, 0x0ff7530f, 0x17ad4618, - 0x200ecd45, 0x208c83fd, 0x5e0488fe, 0x032009c6, 0x420d044e, 0x0d8f0d7f, 0x00820020, 0x18001021, 0x6d273b45, 0xfd4c0c93, 0xcf451813, 0x0fe5450f, - 0x5a47c382, 0x820a8b0a, 0x282b4998, 0x410a8b5b, 0x4b232583, 0x54004f00, 0x978f0ce3, 0x500f1944, 0xa95f1709, 0x0280220b, 0x05ba7080, 0xa1530682, - 0x06324c13, 0x91412582, 0x05536e2c, 0x63431020, 0x0f434706, 0x8c11374c, 0x176143d7, 0x4d0f454c, 0xd3680bed, 0x0bee4d17, 0x212b9a41, 0x0f530a00, - 0x140d531c, 0x43139143, 0x95610e8d, 0x0f094415, 0x4205fb56, 0x1b4205cf, 0x17015225, 0x5e0c477f, 0xaf6e0aeb, 0x0ff36218, 0x04849a84, 0x0a454218, - 0x9c430420, 0x23c6822b, 0x04000102, 0x45091b4b, 0xf05f0955, 0x82802007, 0x421c2023, 0x5218282b, 0x7b53173f, 0x0fe7480c, 0x74173b7f, 0x47751317, - 0x634d1807, 0x0f6f430f, 0x24086547, 0xfc808002, 0x0b3c7f80, 0x10840120, 0x188d1282, 0x20096b43, 0x0fc24403, 0x00260faf, 0x0180000b, 0x3f500280, - 0x18002019, 0x450b4941, 0xf3530fb9, 0x18002010, 0x8208a551, 0x06234d56, 0xcb58a39b, 0xc3421805, 0x1313461e, 0x0f855018, 0xd34b0120, 0x6cfe2008, - 0x574f0885, 0x09204114, 0x07000029, 0x00008000, 0x44028002, 0x01420f57, 0x10c95c10, 0x11184c18, 0x80221185, 0x7f421e00, 0x00732240, 0x09cd4977, - 0x6d0b2b42, 0x4f180f8f, 0x8f5a0bcb, 0x9b0f830f, 0x0fb9411f, 0x230b5756, 0x00fd8080, 0x82060745, 0x000121d5, 0x8e0fb277, 0x4a8d4211, 0x24061c53, - 0x04000007, 0x12275280, 0x430c954c, 0x80201545, 0x200f764f, 0x20008200, 0x20ce8308, 0x09534f02, 0x660edf64, 0x73731771, 0xe7411807, 0x20a2820c, - 0x13b64404, 0x8f5d6682, 0x1d6b4508, 0x0cff4d18, 0x3348c58f, 0x0fc34c07, 0x31558b84, 0x8398820f, 0x17514712, 0x240b0e46, 0x80000a00, 0x093b4502, - 0x420f9759, 0xa54c0bf1, 0x0f2b470c, 0x410d314b, 0x2584170c, 0x73b30020, 0xb55fe782, 0x204d8410, 0x08e043fe, 0x4f147e41, 0x022008ab, 0x4b055159, - 0x2950068f, 0x00022208, 0x48511880, 0x82002009, 0x00112300, 0x634dff00, 0x24415f27, 0x180f6d43, 0x4d0b5d45, 0x4d5f05ef, 0x01802317, 0x56188000, - 0xa7840807, 0xc6450220, 0x21ca8229, 0x4b781a00, 0x3359182c, 0x0cf3470f, 0x180bef46, 0x420b0354, 0xff470b07, 0x4515200a, 0x9758239b, 0x4a80200c, - 0xd2410a26, 0x05fb4a08, 0x4b05e241, 0x03200dc9, 0x92290941, 0x00002829, 0x00010900, 0x5b020001, 0x23201363, 0x460d776a, 0xef530fdb, 0x209a890c, - 0x13fc4302, 0x00008024, 0xc4820104, 0x08820220, 0x20086b5b, 0x18518700, 0x8408d349, 0x0da449a1, 0x00080024, 0x7b690280, 0x4c438b1a, 0x01220f63, - 0x4c878000, 0x5c149c53, 0xfb430868, 0x2f56181e, 0x0ccf7b1b, 0x0f075618, 0x2008e347, 0x14144104, 0x00207f83, 0x00207b82, 0x201adf47, 0x16c35a13, - 0x540fdf47, 0x802006c8, 0x5418f185, 0x29430995, 0x00002419, 0x58001600, 0x5720316f, 0x4d051542, 0x4b7b1b03, 0x138f4707, 0xb747b787, 0x4aab8213, - 0x058305fc, 0x20115759, 0x82128401, 0x0a0b44e8, 0x46800121, 0xe64210d0, 0x82129312, 0x4bffdffe, 0x3b41171b, 0x9b27870f, 0x808022ff, 0x085c68fe, - 0x41800021, 0x01410b20, 0x001a213a, 0x47480082, 0x11374e12, 0x56130b4c, 0xdf4b0c65, 0x0b0f590b, 0x0f574c18, 0x830feb4b, 0x075f480f, 0x480b4755, - 0x40490b73, 0x80012206, 0x09d74280, 0x80fe8022, 0x80210e86, 0x056643ff, 0x10820020, 0x420b2646, 0x0b58391a, 0xd74c1808, 0x078b4e22, 0x2007f55f, - 0x4b491807, 0x83802017, 0x65aa82a7, 0x3152099e, 0x068b7616, 0x9b431220, 0x09bb742c, 0x500e376c, 0x8342179b, 0x0a4d5d0f, 0x8020a883, 0x180cd349, - 0x2016bb4b, 0x14476004, 0x84136c43, 0x08cf7813, 0x4f4c0520, 0x156f420f, 0x20085f42, 0x6fd3be03, 0xd4d30803, 0xa7411420, 0x004b222c, 0x0d3b614f, - 0x3f702120, 0x1393410a, 0x8f132745, 0x47421827, 0x41e08209, 0xb05e2bb9, 0x18b7410c, 0x18082647, 0x4107a748, 0xeb8826bf, 0x0ca76018, 0x733ecb41, - 0xd0410d83, 0x43ebaf2a, 0x0420067f, 0x721dab4c, 0x472005bb, 0x4105d341, 0x334844cb, 0x20dba408, 0x47d6ac00, 0x034e3aef, 0x0f8f421b, 0x930f134d, - 0x3521231f, 0xb7421533, 0x42f5ad0a, 0x1e961eaa, 0x17000022, 0x4c367b50, 0x7d491001, 0x0bf5520f, 0x4c18fda7, 0xb8460c55, 0x83fe2005, 0x00fe25b9, - 0x80000180, 0x9e751085, 0x261b5c12, 0x82110341, 0x001123fb, 0x4518fe80, 0xf38c2753, 0x6d134979, 0x295107a7, 0xaf5f180f, 0x0fe3660c, 0x180b6079, - 0x2007bd5f, 0x9aab9103, 0x2f4d1811, 0x05002109, 0x44254746, 0x1d200787, 0x450bab75, 0x4f180f57, 0x4f181361, 0x3b831795, 0xeb4b0120, 0x0b734805, - 0x84078f48, 0x2e1b47bc, 0x00203383, 0xaf065f45, 0x831520d7, 0x130f51a7, 0x1797bf97, 0x2b47d783, 0x18fe2005, 0x4a18a44f, 0xa64d086d, 0x1ab0410d, - 0x6205a258, 0xdbab069f, 0x4f06f778, 0xa963081d, 0x133b670a, 0x8323d141, 0x13195b23, 0x530f5e70, 0xe5ad0824, 0x58001421, 0x1f472b4b, 0x47bf410c, - 0x82000121, 0x83fe20cb, 0x07424404, 0x68068243, 0xd7ad0d3d, 0x00010d26, 0x80020000, 0x4a1c6f43, 0x23681081, 0x10a14f13, 0x8a070e57, 0x430a848f, - 0x7372243e, 0x4397a205, 0xb56c1021, 0x43978f0f, 0x64180505, 0x99aa0ff2, 0x0e000022, 0x20223341, 0x094b4f37, 0x074a3320, 0x2639410a, 0xfe208e84, - 0x8b0e0048, 0x508020a3, 0x9e4308fe, 0x073f4115, 0xe3480420, 0x0c9b5f1b, 0x7c137743, 0x9a95185b, 0x6122b148, 0x979b08df, 0x0fe36c18, 0x48109358, - 0x23441375, 0x0ffd5c0b, 0x180fc746, 0x2011d157, 0x07e95702, 0x58180120, 0x18770ac3, 0x51032008, 0x7d4118e3, 0x80802315, 0x3b4c1900, 0xbb5a1830, - 0x0ceb6109, 0x5b0b3d42, 0x4f181369, 0x4f180b8d, 0x4f180f75, 0x355a1b81, 0x200d820d, 0x18e483fd, 0x4528854f, 0x89420846, 0x1321411f, 0x44086b60, - 0x07421d77, 0x107d4405, 0x4113fd41, 0x5a181bf1, 0x4f180db3, 0x8021128f, 0x20f68280, 0x44a882fe, 0x334d249a, 0x052f6109, 0x1520c3a7, 0xef4eb783, - 0x4ec39b1b, 0xc4c90ee7, 0x20060b4d, 0x256f4905, 0x4d0cf761, 0xcf9b1f13, 0xa213d74e, 0x0e1145d4, 0x50135b42, 0xcb4e398f, 0x20d79f27, 0x08865d80, - 0x186d5018, 0xa90f7142, 0x067342d7, 0x3f450420, 0x65002021, 0xe3560771, 0x24d38f23, 0x15333531, 0x0eb94d01, 0x451c9f41, 0x384322fb, 0x00092108, - 0x19af6b18, 0x6e0c6f5a, 0xbd770bfb, 0x22bb7718, 0x20090f57, 0x25e74204, 0x4207275a, 0xdb5408ef, 0x1769450f, 0x1b1b5518, 0x210b1f57, 0x5e4c8001, - 0x55012006, 0x802107f1, 0x0a306a80, 0x45808021, 0x0d850b88, 0x31744f18, 0x1808ec54, 0x2009575b, 0x45ffa505, 0x1b420c73, 0x180f9f0f, 0x4a0cf748, - 0x501805b2, 0x00210f40, 0x4d118f80, 0xd6823359, 0x072b5118, 0x314ad7aa, 0x8fc79f08, 0x45d78b1f, 0xfe20058f, 0x23325118, 0x7b54d9b5, 0x9fc38f46, - 0x10bb410f, 0x41077b42, 0xc1410faf, 0x27cf441d, 0x46051b4f, 0x04200683, 0x2121d344, 0x8f530043, 0x8fcf9f0e, 0x21df8c1f, 0x50188000, 0x5d180e52, - 0xfd201710, 0x4405c341, 0xd68528e3, 0x20071f6b, 0x1b734305, 0x6b080957, 0x7d422b1f, 0x67002006, 0x7f8317b1, 0x2024cb48, 0x08676e00, 0x8749a39b, - 0x18132006, 0x410a6370, 0x8f490b47, 0x7e1f8f13, 0x551805c3, 0x4c180915, 0xfe200e2f, 0x244d5d18, 0x270bcf44, 0xff000019, 0x04800380, 0x5f253342, - 0xff520df7, 0x13274c18, 0x5542dd93, 0x0776181b, 0xf94a1808, 0x084a4c0c, 0x4308ea5b, 0xde831150, 0x7900fd21, 0x00492c1e, 0x060f4510, 0x17410020, - 0x0ce74526, 0x6206b341, 0x1f561083, 0x9d6c181b, 0x08a0500e, 0x112e4118, 0x60000421, 0xbf901202, 0x4408e241, 0xc7ab0513, 0xb40f0950, 0x055943c7, - 0x4f18ff20, 0xc9ae1cad, 0x32b34f18, 0x7a180120, 0x3d520a05, 0x53d1b40a, 0x80200813, 0x1b815018, 0x832bf86f, 0x67731847, 0x297f4308, 0x6418d54e, - 0x734213f7, 0x056b4b27, 0xdba5fe20, 0x1828aa4e, 0x2031a370, 0x06cb6101, 0x2040ad41, 0x07365300, 0x2558d985, 0x83fe200c, 0x0380211c, 0x542c4743, - 0x052006b7, 0x6021df45, 0x897b0707, 0x18d3c010, 0x20090e70, 0x1d5843ff, 0x540a0e44, 0x002126c5, 0x322f7416, 0x636a5720, 0x0f317409, 0x610fe159, - 0x294617e7, 0x08555213, 0x2006a75d, 0x6cec84fd, 0xfb5907be, 0x3a317405, 0x83808021, 0x180f20ea, 0x4626434a, 0x531818e3, 0xdb59172d, 0x0cbb460c, - 0x2013d859, 0x18b94502, 0x8f46188d, 0x77521842, 0x0a184e38, 0x9585fd20, 0x6a180684, 0xc64507e9, 0x51cbb230, 0xd3440cf3, 0x17ff6a0f, 0x450f5b42, - 0x276407c1, 0x4853180a, 0x21ccb010, 0xcf580013, 0x0c15442d, 0x410a1144, 0x1144359d, 0x5cfe2006, 0xa1410a43, 0x2bb64519, 0x2f5b7618, 0xb512b745, - 0x0cfd6fd1, 0x42089f59, 0xb8450c70, 0x0000232d, 0x50180900, 0xb9491ae3, 0x0fc37610, 0x01210f83, 0x0f3b4100, 0xa01b2742, 0x0ccd426f, 0x6e8f6f94, - 0x9c808021, 0xc7511870, 0x17c74b08, 0x9b147542, 0x44fe2079, 0xd5480c7e, 0x95ef861d, 0x101b597b, 0xf5417594, 0x9f471808, 0x86868d0e, 0x3733491c, - 0x690f4d6d, 0x43440b83, 0x1ba94c0b, 0x660cd16b, 0x802008ae, 0x74126448, 0xcb4f38a3, 0x2cb74b0b, 0x47137755, 0xe3971777, 0x1b5d0120, 0x057a4108, - 0x6e08664d, 0x17421478, 0x11af4208, 0x850c3f42, 0x08234f0c, 0x4321eb4a, 0xf3451095, 0x0f394e0f, 0x4310eb45, 0xc09707b1, 0x54431782, 0xaec08d1d, - 0x0f434dbb, 0x9f0c0b45, 0x0a3b4dbb, 0x4618bdc7, 0x536032eb, 0x17354213, 0x4d134169, 0xc7a30c2f, 0x4e254342, 0x174332cf, 0x43cdae17, 0x6b4706e4, - 0x0e16430d, 0x530b5542, 0x2f7c26bb, 0x13075f31, 0x43175342, 0x60181317, 0x6550114e, 0x28624710, 0x58070021, 0x59181683, 0x2d540cf5, 0x05d5660c, - 0x20090c7b, 0x0e157e02, 0x8000ff2b, 0x14000080, 0x80ff8000, 0x27137e03, 0x336a4b20, 0x0f817107, 0x13876e18, 0x730f2f7e, 0x2f450b75, 0x6d02200b, - 0x6d66094c, 0x4b802009, 0x15820a02, 0x2f45fe20, 0x5e032006, 0x00202fd9, 0x450af741, 0xeb412e0f, 0x0ff3411f, 0x420a8b65, 0xf7410eae, 0x1c664810, - 0x540e1145, 0xbfa509f3, 0x42302f58, 0x80200c35, 0xcb066c47, 0x4b1120c1, 0x41492abb, 0x34854110, 0xa7097b72, 0x251545c7, 0x4b2c7f56, 0xc5b40bab, - 0x940cd54e, 0x2e6151c8, 0x09f35f18, 0x4b420420, 0x09677121, 0x8f24f357, 0x1b5418e1, 0x08915a1f, 0x3143d894, 0x22541805, 0x1b9b4b0e, 0x8c0d3443, - 0x1400240d, 0x18ff8000, 0x582e6387, 0xf99b2b3b, 0x8807a550, 0x17a14790, 0x2184fd20, 0x5758fe20, 0x2354882c, 0x15000080, 0x5e056751, 0x334c2c2f, - 0x97c58f0c, 0x1fd7410f, 0x0d4d4018, 0x4114dc41, 0x04470ed6, 0x0dd54128, 0x00820020, 0x02011523, 0x22008700, 0x86480024, 0x0001240a, 0x8682001a, - 0x0002240b, 0x866c000e, 0x8a03200b, 0x8a042017, 0x0005220b, 0x22218614, 0x84060000, 0x86012017, 0x8212200f, 0x250b8519, 0x000d0001, 0x0b850031, - 0x07000224, 0x0b862600, 0x11000324, 0x0b862d00, 0x238a0420, 0x0a000524, 0x17863e00, 0x17840620, 0x01000324, 0x57820904, 0x0b85a783, 0x0b85a785, - 0x0b85a785, 0x22000325, 0x85007a00, 0x85a7850b, 0x85a7850b, 0x22a7850b, 0x82300032, 0x00342201, 0x0805862f, 0x35003131, 0x54207962, 0x74736972, - 0x47206e61, 0x6d6d6972, 0x65527265, 0x616c7567, 0x58545472, 0x6f725020, 0x43796767, 0x6e61656c, 0x30325454, 0x822f3430, 0x35313502, 0x79006200, - 0x54002000, 0x69007200, 0x74007300, 0x6e006100, 0x47200f82, 0x6d240f84, 0x65006d00, 0x52200982, 0x67240582, 0x6c007500, 0x72201d82, 0x54222b82, - 0x23825800, 0x19825020, 0x67006f22, 0x79220182, 0x1b824300, 0x3b846520, 0x1f825420, 0x41000021, 0x1422099b, 0x0b410000, 0x87088206, 0x01012102, - 0x78080982, 0x01020101, 0x01040103, 0x01060105, 0x01080107, 0x010a0109, 0x010c010b, 0x010e010d, 0x0110010f, 0x01120111, 0x01140113, 0x01160115, - 0x01180117, 0x011a0119, 0x011c011b, 0x011e011d, 0x0020011f, 0x00040003, 0x00060005, 0x00080007, 0x000a0009, 0x000c000b, 0x000e000d, 0x0010000f, - 0x00120011, 0x00140013, 0x00160015, 0x00180017, 0x001a0019, 0x001c001b, 0x001e001d, 0x08bb821f, 0x22002142, 0x24002300, 0x26002500, 0x28002700, - 0x2a002900, 0x2c002b00, 0x2e002d00, 0x30002f00, 0x32003100, 0x34003300, 0x36003500, 0x38003700, 0x3a003900, 0x3c003b00, 0x3e003d00, 0x40003f00, - 0x42004100, 0x4b09f382, 0x00450044, 0x00470046, 0x00490048, 0x004b004a, 0x004d004c, 0x004f004e, 0x00510050, 0x00530052, 0x00550054, 0x00570056, - 0x00590058, 0x005b005a, 0x005d005c, 0x005f005e, 0x01610060, 0x01220121, 0x01240123, 0x01260125, 0x01280127, 0x012a0129, 0x012c012b, 0x012e012d, - 0x0130012f, 0x01320131, 0x01340133, 0x01360135, 0x01380137, 0x013a0139, 0x013c013b, 0x013e013d, 0x0140013f, 0x00ac0041, 0x008400a3, 0x00bd0085, - 0x00e80096, 0x008e0086, 0x009d008b, 0x00a400a9, 0x008a00ef, 0x008300da, 0x00f20093, 0x008d00f3, 0x00880097, 0x00de00c3, 0x009e00f1, 0x00f500aa, - 0x00f600f4, 0x00ad00a2, 0x00c700c9, 0x006200ae, 0x00900063, 0x00cb0064, 0x00c80065, 0x00cf00ca, 0x00cd00cc, 0x00e900ce, 0x00d30066, 0x00d100d0, - 0x006700af, 0x009100f0, 0x00d400d6, 0x006800d5, 0x00ed00eb, 0x006a0089, 0x006b0069, 0x006c006d, 0x00a0006e, 0x0071006f, 0x00720070, 0x00750073, - 0x00760074, 0x00ea0077, 0x007a0078, 0x007b0079, 0x007c007d, 0x00a100b8, 0x007e007f, 0x00810080, 0x00ee00ec, 0x6e750eba, 0x646f6369, 0x78302365, - 0x31303030, 0x32200e8d, 0x33200e8d, 0x34200e8d, 0x35200e8d, 0x36200e8d, 0x37200e8d, 0x38200e8d, 0x39200e8d, 0x61200e8d, 0x62200e8d, 0x63200e8d, - 0x64200e8d, 0x65200e8d, 0x66200e8d, 0x31210e8c, 0x8d0e8d30, 0x8d3120ef, 0x8d3120ef, 0x8d3120ef, 0x8d3120ef, 0x8d3120ef, 0x8d3120ef, 0x8d3120ef, - 0x8d3120ef, 0x8d3120ef, 0x8d3120ef, 0x8d3120ef, 0x8d3120ef, 0x8d3120ef, 0x66312def, 0x6c656406, 0x04657465, 0x6f727545, 0x3820ec8c, 0x3820ec8d, - 0x3820ec8d, 0x3820ec8d, 0x3820ec8d, 0x3820ec8d, 0x3820ec8d, 0x3820ec8d, 0x3820ec8d, 0x3820ec8d, 0x3820ec8d, 0x3820ec8d, 0x3820ec8d, 0x3820ec8d, - 0x3820ec8d, 0x200ddc41, 0x0ddc4139, 0xef8d3920, 0xef8d3920, 0xef8d3920, 0xef8d3920, 0xef8d3920, 0xef8d3920, 0xef8d3920, 0xef8d3920, 0xef8d3920, - 0xef8d3920, 0xef8d3920, 0xef8d3920, 0xef8d3920, 0xef8d3920, 0x00663923, 0x48fa0500, 0x00f762f9, + g_gfxCmdQueueSize = 0; + g_textPoolSize = 0; +} + +static void addGfxCmdScissor(int x, int y, int w, int h) +{ + if (g_gfxCmdQueueSize >= GFXCMD_QUEUE_SIZE) + return; + imguiGfxCmd& cmd = g_gfxCmdQueue[g_gfxCmdQueueSize++]; + cmd.type = IMGUI_GFXCMD_SCISSOR; + cmd.flags = x < 0 ? 0 : 1; // on/off flag. + cmd.col = 0; + cmd.rect.x = (short)x; + cmd.rect.y = (short)y; + cmd.rect.w = (short)w; + cmd.rect.h = (short)h; +} + +static void addGfxCmdRect(float x, float y, float w, float h, unsigned int color) +{ + if (g_gfxCmdQueueSize >= GFXCMD_QUEUE_SIZE) + return; + imguiGfxCmd& cmd = g_gfxCmdQueue[g_gfxCmdQueueSize++]; + cmd.type = IMGUI_GFXCMD_RECT; + cmd.flags = 0; + cmd.col = color; + cmd.rect.x = (short)(x*8.0f); + cmd.rect.y = (short)(y*8.0f); + cmd.rect.w = (short)(w*8.0f); + cmd.rect.h = (short)(h*8.0f); + cmd.rect.r = 0; +} + +static void addGfxCmdLine(float x0, float y0, float x1, float y1, float r, unsigned int color) +{ + if (g_gfxCmdQueueSize >= GFXCMD_QUEUE_SIZE) + return; + imguiGfxCmd& cmd = g_gfxCmdQueue[g_gfxCmdQueueSize++]; + cmd.type = IMGUI_GFXCMD_LINE; + cmd.flags = 0; + cmd.col = color; + cmd.line.x0 = (short)(x0*8.0f); + cmd.line.y0 = (short)(y0*8.0f); + cmd.line.x1 = (short)(x1*8.0f); + cmd.line.y1 = (short)(y1*8.0f); + cmd.line.r = (short)(r*8.0f); +} + +static void addGfxCmdRoundedRect(float x, float y, float w, float h, float r, unsigned int color) +{ + if (g_gfxCmdQueueSize >= GFXCMD_QUEUE_SIZE) + return; + imguiGfxCmd& cmd = g_gfxCmdQueue[g_gfxCmdQueueSize++]; + cmd.type = IMGUI_GFXCMD_RECT; + cmd.flags = 0; + cmd.col = color; + cmd.rect.x = (short)(x*8.0f); + cmd.rect.y = (short)(y*8.0f); + cmd.rect.w = (short)(w*8.0f); + cmd.rect.h = (short)(h*8.0f); + cmd.rect.r = (short)(r*8.0f); +} + +static void addGfxCmdTriangle(int x, int y, int w, int h, int flags, unsigned int color) +{ + if (g_gfxCmdQueueSize >= GFXCMD_QUEUE_SIZE) + return; + imguiGfxCmd& cmd = g_gfxCmdQueue[g_gfxCmdQueueSize++]; + cmd.type = IMGUI_GFXCMD_TRIANGLE; + cmd.flags = (char)flags; + cmd.col = color; + cmd.rect.x = (short)(x*8.0f); + cmd.rect.y = (short)(y*8.0f); + cmd.rect.w = (short)(w*8.0f); + cmd.rect.h = (short)(h*8.0f); +} + +static void addGfxCmdText(int x, int y, int align, const char* text, unsigned int color) +{ + if (g_gfxCmdQueueSize >= GFXCMD_QUEUE_SIZE) + return; + imguiGfxCmd& cmd = g_gfxCmdQueue[g_gfxCmdQueueSize++]; + cmd.type = IMGUI_GFXCMD_TEXT; + cmd.flags = 0; + cmd.col = color; + cmd.text.x = (short)x; + cmd.text.y = (short)y; + cmd.text.align = (short)align; + cmd.text.text = allocText(text); +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +struct GuiState +{ + GuiState() : + left(false), leftPressed(false), leftReleased(false), + mx(-1), my(-1), scroll(0), + active(0), hot(0), hotToBe(0), isHot(false), isActive(false), wentActive(false), + dragX(0), dragY(0), dragOrig(0), widgetX(0), widgetY(0), widgetW(100), + insideCurrentScroll(false), nextItemSameLine(false), areaId(0), widgetId(0) + { + } + + bool left; + bool leftPressed, leftReleased; + int mx,my; + int scroll; + unsigned int active; + unsigned int hot; + unsigned int hotToBe; + bool isHot; + bool isActive; + bool wentActive; + int dragX, dragY; + float dragOrig; + int widgetX, widgetY, widgetW; + bool insideCurrentScroll; + bool nextItemSameLine; + + unsigned int areaId; + unsigned int widgetId; }; -static void GetDefaultCompressedFontDataTTF(const void** ttf_compressed_data, unsigned int* ttf_compressed_size) +static GuiState g_state; + +inline bool anyActive() { - *ttf_compressed_data = proggy_clean_ttf_compressed_data; - *ttf_compressed_size = proggy_clean_ttf_compressed_size; + return g_state.active != 0; } -//----------------------------------------------------------------------------- +inline bool isActive(unsigned int id) +{ + return g_state.active == id; +} -//---- Include imgui_user.inl at the end of imgui.cpp -//---- So you can include code that extends ImGui using its private data/functions. -#ifdef IMGUI_INCLUDE_IMGUI_USER_INL -#include "imgui_user.inl" -#endif +inline bool isHot(unsigned int id) +{ + return g_state.hot == id; +} -//----------------------------------------------------------------------------- +inline bool inRect(int x, int y, int w, int h, bool checkScroll = true) +{ + return (!checkScroll || g_state.insideCurrentScroll) && g_state.mx >= x && g_state.mx <= x+w && g_state.my >= y && g_state.my <= y+h; +} + +inline void clearInput() +{ + g_state.leftPressed = false; + g_state.leftReleased = false; + g_state.scroll = 0; +} + +inline void clearActive() +{ + g_state.active = 0; + // mark all UI for this frame as processed + clearInput(); +} + +inline void setActive(unsigned int id) +{ + g_state.active = id; + g_state.wentActive = true; +} + +inline void setHot(unsigned int id) +{ + g_state.hotToBe = id; +} + + +static bool buttonLogic(unsigned int id, bool over) +{ + bool res = false; + // process down + if (!anyActive()) + { + if (over) + setHot(id); + if (isHot(id) && g_state.leftPressed) + setActive(id); + } + + // if button is active, then react on left up + if (isActive(id)) + { + g_state.isActive = true; + if (over) + setHot(id); + if (g_state.leftReleased) + { + if (isHot(id)) + res = true; + clearActive(); + } + } + + if (isHot(id)) + g_state.isHot = true; + + return res; +} + +static void updateInput(int mx, int my, unsigned char mbut, int scroll) +{ + bool left = (mbut & IMGUI_MBUT_LEFT) != 0; + + g_state.mx = mx; + g_state.my = my; + g_state.leftPressed = !g_state.left && left; + g_state.leftReleased = g_state.left && !left; + g_state.left = left; + + g_state.scroll = scroll; +} + +void imguiBeginFrame(int mx, int my, unsigned char mbut, int scroll) +{ + updateInput(mx,my,mbut,scroll); + + g_state.hot = g_state.hotToBe; + g_state.hotToBe = 0; + + g_state.wentActive = false; + g_state.isActive = false; + g_state.isHot = false; + + g_state.widgetX = 0; + g_state.widgetY = 0; + g_state.widgetW = 0; + + g_state.areaId = 1; + g_state.widgetId = 1; + + resetGfxCmdQueue(); +} + +void imguiEndFrame() +{ + clearInput(); +} + +const imguiGfxCmd* imguiGetRenderQueue() +{ + return g_gfxCmdQueue; +} + +int imguiGetRenderQueueSize() +{ + return g_gfxCmdQueueSize; +} + + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +static int g_scrollTop = 0; +static int g_scrollBottom = 0; +static int g_scrollRight = 0; +static int g_scrollAreaTop = 0; +static int* g_scrollVal = 0; +static int g_focusTop = 0; +static int g_focusBottom = 0; +static unsigned int g_scrollId = 0; +static bool g_insideScrollArea = false; + +bool imguiBeginScrollArea(const char* name, int x, int y, int w, int h, int* scroll) +{ + g_state.areaId++; + g_state.widgetId = 0; + g_scrollId = (g_state.areaId<<16) | g_state.widgetId; + + const int areaHeading = name ? AREA_HEADER : 0; + + g_state.widgetX = x + SCROLL_AREA_PADDING; + g_state.widgetY = y+h-areaHeading + (*scroll); + g_state.widgetW = w - SCROLL_AREA_PADDING*4; + g_scrollTop = y-areaHeading+h; + g_scrollBottom = y+SCROLL_AREA_PADDING; + g_scrollRight = x+w - SCROLL_AREA_PADDING*3; + g_scrollVal = scroll; + + g_scrollAreaTop = g_state.widgetY; + + g_focusTop = y-areaHeading; + g_focusBottom = y-areaHeading+h; + + g_insideScrollArea = inRect(x, y, w, h, false); + g_state.insideCurrentScroll = g_insideScrollArea; + + addGfxCmdRoundedRect((float)x, (float)y, (float)w, (float)h, 6, imguiRGBA(0,0,0,192)); + + if (name) addGfxCmdText(x+areaHeading/2, y+h-areaHeading/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, name, imguiRGBA(255,255,255,128)); + + addGfxCmdScissor(x+SCROLL_AREA_PADDING, y+SCROLL_AREA_PADDING, w-SCROLL_AREA_PADDING*4, h-areaHeading-SCROLL_AREA_PADDING); + + return g_insideScrollArea; +} + +void imguiEndScrollArea() +{ + // Disable scissoring. + addGfxCmdScissor(-1,-1,-1,-1); + + // Draw scroll bar + int x = g_scrollRight+SCROLL_AREA_PADDING/2; + int y = g_scrollBottom; + int w = SCROLL_AREA_PADDING*2; + int h = g_scrollTop - g_scrollBottom; + + int stop = g_scrollAreaTop; + int sbot = g_state.widgetY; + int sh = stop - sbot; // The scrollable area height. + + float barHeight = (float)h/(float)sh; + + if (barHeight < 1) + { + float barY = (float)(y - sbot)/(float)sh; + if (barY < 0) barY = 0; + if (barY > 1) barY = 1; + + // Handle scroll bar logic. + unsigned int hid = g_scrollId; + int hx = x; + int hy = y + (int)(barY*h); + int hw = w; + int hh = (int)(barHeight*h); + + const int range = h - (hh-1); + bool over = inRect(hx, hy, hw, hh); + buttonLogic(hid, over); + if (isActive(hid)) + { + float u = (float)(hy-y) / (float)range; + if (g_state.wentActive) + { + g_state.dragY = g_state.my; + g_state.dragOrig = u; + } + if (g_state.dragY != g_state.my) + { + u = g_state.dragOrig + (g_state.my - g_state.dragY) / (float)range; + if (u < 0) u = 0; + if (u > 1) u = 1; + *g_scrollVal = (int)((1-u) * (sh - h)); + } + } + + // BG + addGfxCmdRoundedRect((float)x, (float)y, (float)w, (float)h, (float)w/2-1, imguiRGBA(0,0,0,196)); + // Bar + if (isActive(hid)) + addGfxCmdRoundedRect((float)hx, (float)hy, (float)hw, (float)hh, (float)w/2-1, imguiRGBA(255,196,0,196)); + else + addGfxCmdRoundedRect((float)hx, (float)hy, (float)hw, (float)hh, (float)w/2-1, isHot(hid) ? imguiRGBA(255,196,0,96) : imguiRGBA(255,255,255,64)); + + // Handle mouse scrolling. + if (g_insideScrollArea) // && !anyActive()) + { + if (g_state.scroll) + { + *g_scrollVal += 20*g_state.scroll; + if (*g_scrollVal < 0) *g_scrollVal = 0; + if (*g_scrollVal > (sh - h)) *g_scrollVal = (sh - h); + } + } + } + g_state.insideCurrentScroll = false; +} + +bool imguiButton(const char* text, bool enabled, int width) +{ + g_state.widgetId++; + unsigned int id = (g_state.areaId<<16) | g_state.widgetId; + + int x = g_state.widgetX; + int y = g_state.widgetY - BUTTON_HEIGHT; + int w = width > 0 ? width : g_state.widgetW; + int h = BUTTON_HEIGHT; + if (g_state.nextItemSameLine) { + g_state.widgetX += width + DEFAULT_HORIZONTAL_SPACING; + } + else { + g_state.widgetY -= BUTTON_HEIGHT + DEFAULT_VERTICAL_SPACING; + } + + bool over = enabled && inRect(x, y, w, h); + bool res = buttonLogic(id, over); + + addGfxCmdRoundedRect((float)x, (float)y, (float)w, (float)h, (float)BUTTON_HEIGHT/2-1, imguiRGBA(128,128,128, isActive(id)?196:96)); + if (enabled) + addGfxCmdText(x+w/2, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_CENTER, text, isHot(id) ? imguiRGBA(255,196,0,255) : imguiRGBA(255,255,255,200)); + else + addGfxCmdText(x+w/2, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_CENTER, text, imguiRGBA(128,128,128,200)); + + return res; +} + +bool imguiItem(const char* text, bool enabled) +{ + g_state.widgetId++; + unsigned int id = (g_state.areaId<<16) | g_state.widgetId; + + int x = g_state.widgetX; + int y = g_state.widgetY - BUTTON_HEIGHT; + int w = g_state.widgetW; + int h = BUTTON_HEIGHT; + g_state.widgetY -= BUTTON_HEIGHT + DEFAULT_VERTICAL_SPACING; + + bool over = enabled && inRect(x, y, w, h); + bool res = buttonLogic(id, over); + + if (isHot(id)) + addGfxCmdRoundedRect((float)x, (float)y, (float)w, (float)h, 2.0f, imguiRGBA(255,196,0,isActive(id)?196:96)); + + if (enabled) + addGfxCmdText(x+BUTTON_HEIGHT/2, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, text, imguiRGBA(255,255,255,200)); + else + addGfxCmdText(x+BUTTON_HEIGHT/2, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, text, imguiRGBA(128,128,128,200)); + + return res; +} + +bool imguiCheck(const char* text, bool checked, bool enabled) +{ + g_state.widgetId++; + unsigned int id = (g_state.areaId<<16) | g_state.widgetId; + + int x = g_state.widgetX; + int y = g_state.widgetY - BUTTON_HEIGHT; + int w = g_state.widgetW; + int h = BUTTON_HEIGHT; + g_state.widgetY -= BUTTON_HEIGHT + DEFAULT_VERTICAL_SPACING; + + bool over = enabled && inRect(x, y, w, h); + bool res = buttonLogic(id, over); + + const int cx = x+BUTTON_HEIGHT/2-CHECK_SIZE/2; + const int cy = y+BUTTON_HEIGHT/2-CHECK_SIZE/2; + addGfxCmdRoundedRect((float)cx-3, (float)cy-3, (float)CHECK_SIZE+6, (float)CHECK_SIZE+6, 4, imguiRGBA(128,128,128, isActive(id)?196:96)); + if (checked) + { + if (enabled) + addGfxCmdRoundedRect((float)cx, (float)cy, (float)CHECK_SIZE, (float)CHECK_SIZE, (float)CHECK_SIZE/2-1, imguiRGBA(255,255,255,isActive(id)?255:200)); + else + addGfxCmdRoundedRect((float)cx, (float)cy, (float)CHECK_SIZE, (float)CHECK_SIZE, (float)CHECK_SIZE/2-1, imguiRGBA(128,128,128,200)); + } + + if (enabled) + addGfxCmdText(x+BUTTON_HEIGHT, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, text, isHot(id) ? imguiRGBA(255,196,0,255) : imguiRGBA(255,255,255,200)); + else + addGfxCmdText(x+BUTTON_HEIGHT, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, text, imguiRGBA(128,128,128,200)); + + return res; +} + +bool imguiCollapse(const char* text, const char* subtext, bool checked, bool enabled) +{ + g_state.widgetId++; + unsigned int id = (g_state.areaId<<16) | g_state.widgetId; + + int x = g_state.widgetX; + int y = g_state.widgetY - BUTTON_HEIGHT; + int w = g_state.widgetW; + int h = BUTTON_HEIGHT; + g_state.widgetY -= BUTTON_HEIGHT; // + DEFAULT_SPACING; + + const int cx = x+BUTTON_HEIGHT/2-CHECK_SIZE/2; + const int cy = y+BUTTON_HEIGHT/2-CHECK_SIZE/2; + + bool over = enabled && inRect(x, y, w, h); + bool res = buttonLogic(id, over); + + if (checked) + addGfxCmdTriangle(cx, cy, CHECK_SIZE, CHECK_SIZE, 2, imguiRGBA(255,255,255,isActive(id)?255:200)); + else + addGfxCmdTriangle(cx, cy, CHECK_SIZE, CHECK_SIZE, 1, imguiRGBA(255,255,255,isActive(id)?255:200)); + + if (enabled) + addGfxCmdText(x+BUTTON_HEIGHT, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, text, isHot(id) ? imguiRGBA(255,196,0,255) : imguiRGBA(255,255,255,200)); + else + addGfxCmdText(x+BUTTON_HEIGHT, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, text, imguiRGBA(128,128,128,200)); + + if (subtext) + addGfxCmdText(x+w-BUTTON_HEIGHT/2, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_RIGHT, subtext, imguiRGBA(255,255,255,128)); + + return res; +} + +void imguiLabel(const char* text) +{ + int x = g_state.widgetX; + int y = g_state.widgetY - BUTTON_HEIGHT; + g_state.widgetY -= BUTTON_HEIGHT; + addGfxCmdText(x, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, text, imguiRGBA(255,255,255,255)); +} + +void imguiValue(const char* text) +{ + const int x = g_state.widgetX; + const int y = g_state.widgetY - BUTTON_HEIGHT; + const int w = g_state.widgetW; + g_state.widgetY -= BUTTON_HEIGHT; + + addGfxCmdText(x+w-BUTTON_HEIGHT/2, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_RIGHT, text, imguiRGBA(255,255,255,200)); +} + +bool imguiSlider(const char* text, float* val, float vmin, float vmax, float vinc, bool enabled) +{ + g_state.widgetId++; + unsigned int id = (g_state.areaId<<16) | g_state.widgetId; + + int x = g_state.widgetX; + int y = g_state.widgetY - BUTTON_HEIGHT; + int w = g_state.widgetW; + int h = SLIDER_HEIGHT; + g_state.widgetY -= SLIDER_HEIGHT + DEFAULT_VERTICAL_SPACING; + + addGfxCmdRoundedRect((float)x, (float)y, (float)w, (float)h, 4.0f, imguiRGBA(0,0,0,128)); + + const int range = w - SLIDER_MARKER_WIDTH; + + float u = (*val - vmin) / (vmax-vmin); + if (u < 0) u = 0; + if (u > 1) u = 1; + int m = (int)(u * range); + + bool over = enabled && inRect(x+m, y, SLIDER_MARKER_WIDTH, SLIDER_HEIGHT); + bool res = buttonLogic(id, over); + bool valChanged = false; + + if (isActive(id)) + { + if (g_state.wentActive) + { + g_state.dragX = g_state.mx; + g_state.dragOrig = u; + } + if (g_state.dragX != g_state.mx) + { + u = g_state.dragOrig + (float)(g_state.mx - g_state.dragX) / (float)range; + if (u < 0) u = 0; + if (u > 1) u = 1; + *val = vmin + u*(vmax-vmin); + *val = floorf(*val/vinc+0.5f)*vinc; // Snap to vinc + m = (int)(u * range); + valChanged = true; + } + } + + if (isActive(id)) + addGfxCmdRoundedRect((float)(x+m), (float)y, (float)SLIDER_MARKER_WIDTH, (float)SLIDER_HEIGHT, 4.0f, imguiRGBA(255,255,255,255)); + else + addGfxCmdRoundedRect((float)(x+m), (float)y, (float)SLIDER_MARKER_WIDTH, (float)SLIDER_HEIGHT, 4.0f, isHot(id) ? imguiRGBA(255,196,0,128) : imguiRGBA(255,255,255,64)); + + // TODO: fix this, take a look at 'nicenum'. + int digits = (int)(ceilf(log10f(vinc))); + char fmt[16]; + snprintf(fmt, 16, "%%.%df", digits >= 0 ? 0 : -digits); + char msg[128]; + snprintf(msg, 128, fmt, *val); + + if (enabled) + { + addGfxCmdText(x+SLIDER_HEIGHT/2, y+SLIDER_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, text, isHot(id) ? imguiRGBA(255,196,0,255) : imguiRGBA(255,255,255,200)); + addGfxCmdText(x+w-SLIDER_HEIGHT/2, y+SLIDER_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_RIGHT, msg, isHot(id) ? imguiRGBA(255,196,0,255) : imguiRGBA(255,255,255,200)); + } + else + { + addGfxCmdText(x+SLIDER_HEIGHT/2, y+SLIDER_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, text, imguiRGBA(128,128,128,200)); + addGfxCmdText(x+w-SLIDER_HEIGHT/2, y+SLIDER_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_RIGHT, msg, imguiRGBA(128,128,128,200)); + } + + return res || valChanged; +} + +void imguiStartLineOfItems() { + g_state.nextItemSameLine = true; +} + +void imguiEndLineOfItems() { + g_state.nextItemSameLine = false; +} + +void imguiIndent() +{ + g_state.widgetX += INDENT_SIZE; + g_state.widgetW -= INDENT_SIZE; +} + +void imguiUnindent() +{ + g_state.widgetX -= INDENT_SIZE; + g_state.widgetW += INDENT_SIZE; +} + +void imguiSeparator() +{ + g_state.widgetY -= DEFAULT_VERTICAL_SPACING*3; +} + +void imguiSeparatorLine() +{ + int x = g_state.widgetX; + int y = g_state.widgetY - DEFAULT_VERTICAL_SPACING*2; + int w = g_state.widgetW; + int h = 1; + g_state.widgetY -= DEFAULT_VERTICAL_SPACING*4; + + addGfxCmdRect((float)x, (float)y, (float)w, (float)h, imguiRGBA(255,255,255,32)); +} + +void imguiDrawText(int x, int y, int align, const char* text, unsigned int color) +{ + addGfxCmdText(x, y, align, text, color); +} + +void imguiDrawLine(float x0, float y0, float x1, float y1, float r, unsigned int color) +{ + addGfxCmdLine(x0, y0, x1, y1, r, color); +} + +void imguiDrawRect(float x, float y, float w, float h, unsigned int color) +{ + addGfxCmdRect(x, y, w, h, color); +} + +void imguiDrawRoundedRect(float x, float y, float w, float h, float r, unsigned int color) +{ + addGfxCmdRoundedRect(x, y, w, h, r, color); +} diff --git a/testbed/imgui/imgui.h b/testbed/imgui/imgui.h index bb9af931..830b6d17 100644 --- a/testbed/imgui/imgui.h +++ b/testbed/imgui/imgui.h @@ -1,1048 +1,125 @@ -// ImGui library v1.39 WIP -// See .cpp file for documentation. -// See ImGui::ShowTestWindow() for sample code. -// Read 'Programmer guide' in .cpp for notes on how to setup ImGui in your codebase. -// Get latest version at https://github.com/ocornut/imgui -#pragma once +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. +// -#include "imconfig.h" // User-editable configuration file -#include // FLT_MAX -#include // va_list -#include // ptrdiff_t, NULL -#include // NULL, malloc, free, qsort, atoi -#include // memset, memmove, memcpy, strlen, strchr, strcpy, strcmp +// Source altered and distributed from https://github.com/AdrienHerubel/imgui -#define IMGUI_VERSION "1.39 WIP" +#ifndef IMGUI_H +#define IMGUI_H -// Define assertion handler. -#ifndef IM_ASSERT -#include -#define IM_ASSERT(_EXPR) assert(_EXPR) -#endif +static const int BUTTON_HEIGHT = 40; +static const int SLIDER_HEIGHT = 20; +static const int SLIDER_MARKER_WIDTH = 10; +static const int CHECK_SIZE = 18; +static const int DEFAULT_VERTICAL_SPACING = 14; +static const int DEFAULT_HORIZONTAL_SPACING = 14; +static const int TEXT_HEIGHT = 16; +static const int FONT_HEIGHT = 30; +static const int SCROLL_AREA_PADDING = 6; +static const int INDENT_SIZE = 16; +static const int AREA_HEADER = 28; -// Define attributes of all API symbols declarations, e.g. for DLL under Windows. -#ifndef IMGUI_API -#define IMGUI_API -#endif - -// Forward declarations -struct ImDrawCmd; -struct ImDrawList; -struct ImFont; -struct ImFontAtlas; -struct ImGuiIO; -struct ImGuiStorage; -struct ImGuiStyle; - -typedef unsigned int ImU32; -typedef unsigned short ImWchar; // character for display -typedef void* ImTextureID; // user data to refer to a texture (e.g. store your texture handle/id) -typedef ImU32 ImGuiID; // unique ID used by widgets (typically hashed from a stack of string) -typedef int ImGuiCol; // enum ImGuiCol_ -typedef int ImGuiStyleVar; // enum ImGuiStyleVar_ -typedef int ImGuiKey; // enum ImGuiKey_ -typedef int ImGuiColorEditMode; // enum ImGuiColorEditMode_ -typedef int ImGuiMouseCursor; // enum ImGuiMouseCursor_ -typedef int ImGuiWindowFlags; // enum ImGuiWindowFlags_ -typedef int ImGuiSetCond; // enum ImGuiSetCond_ -typedef int ImGuiInputTextFlags; // enum ImGuiInputTextFlags_ -struct ImGuiTextEditCallbackData; // for advanced uses of InputText() -typedef int (*ImGuiTextEditCallback)(ImGuiTextEditCallbackData *data); - -struct ImVec2 +enum imguiMouseButton { - float x, y; - ImVec2() { x = y = 0.0f; } - ImVec2(float _x, float _y) { x = _x; y = _y; } - -#ifdef IM_VEC2_CLASS_EXTRA // Define constructor and implicit cast operators to convert back<>forth from your math types and ImVec2. - IM_VEC2_CLASS_EXTRA -#endif + IMGUI_MBUT_LEFT = 0x01, + IMGUI_MBUT_RIGHT = 0x02, }; -struct ImVec4 +enum imguiTextAlign { - float x, y, z, w; - ImVec4() { x = y = z = w = 0.0f; } - ImVec4(float _x, float _y, float _z, float _w) { x = _x; y = _y; z = _z; w = _w; } - -#ifdef IM_VEC4_CLASS_EXTRA // Define constructor and implicit cast operators to convert back<>forth from your math types and ImVec4. - IM_VEC4_CLASS_EXTRA -#endif + IMGUI_ALIGN_LEFT, + IMGUI_ALIGN_CENTER, + IMGUI_ALIGN_RIGHT, }; -namespace ImGui +inline unsigned int imguiRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a=255) { - // Proxy functions to access the MemAllocFn/MemFreeFn pointers in ImGui::GetIO(). The only reason they exist here is to allow ImVector<> to compile inline. - IMGUI_API void* MemAlloc(size_t sz); - IMGUI_API void MemFree(void* ptr); + return (r) | (g << 8) | (b << 16) | (a << 24); } -// std::vector<> like class to avoid dragging dependencies (also: windows implementation of STL with debug enabled is absurdly slow, so let's bypass it so our code runs fast in debug). -// Use '#define ImVector std::vector' if you want to use the STL type or your own type. -// Our implementation does NOT call c++ constructors! because the data types we use don't need them (but that could be added as well). Only provide the minimum functionalities we need. -#ifndef ImVector -template -class ImVector +void imguiBeginFrame(int mx, int my, unsigned char mbut, int scroll); +void imguiEndFrame(); + +bool imguiBeginScrollArea(const char* name, int x, int y, int w, int h, int* scroll); +void imguiEndScrollArea(); + +void imguiStartLineOfItems(); +void imguiEndLineOfItems(); +void imguiIndent(); +void imguiUnindent(); +void imguiSeparator(); +void imguiSeparatorLine(); + +bool imguiButton(const char* text, bool enabled = true, int width = -1); +bool imguiItem(const char* text, bool enabled = true); +bool imguiCheck(const char* text, bool checked, bool enabled = true); +bool imguiCollapse(const char* text, const char* subtext, bool checked, bool enabled = true); +void imguiLabel(const char* text); +void imguiValue(const char* text); +bool imguiSlider(const char* text, float* val, float vmin, float vmax, float vinc, bool enabled = true); + +void imguiDrawText(int x, int y, int align, const char* text, unsigned int color); +void imguiDrawLine(float x0, float y0, float x1, float y1, float r, unsigned int color); +void imguiDrawRoundedRect(float x, float y, float w, float h, float r, unsigned int color); +void imguiDrawRect(float x, float y, float w, float h, unsigned int color); + +// Pull render interface. +enum imguiGfxCmdType { -protected: - size_t Size; - size_t Capacity; - T* Data; - -public: - typedef T value_type; - typedef value_type* iterator; - typedef const value_type* const_iterator; - - ImVector() { Size = Capacity = 0; Data = NULL; } - ~ImVector() { if (Data) ImGui::MemFree(Data); } - - inline bool empty() const { return Size == 0; } - inline size_t size() const { return Size; } - inline size_t capacity() const { return Capacity; } - - inline value_type& at(size_t i) { IM_ASSERT(i < Size); return Data[i]; } - inline const value_type& at(size_t i) const { IM_ASSERT(i < Size); return Data[i]; } - inline value_type& operator[](size_t i) { IM_ASSERT(i < Size); return Data[i]; } - inline const value_type& operator[](size_t i) const { IM_ASSERT(i < Size); return Data[i]; } - - inline void clear() { if (Data) { Size = Capacity = 0; ImGui::MemFree(Data); Data = NULL; } } - inline iterator begin() { return Data; } - inline const_iterator begin() const { return Data; } - inline iterator end() { return Data + Size; } - inline const_iterator end() const { return Data + Size; } - inline value_type& front() { IM_ASSERT(Size > 0); return Data[0]; } - inline const value_type& front() const { IM_ASSERT(Size > 0); return Data[0]; } - inline value_type& back() { IM_ASSERT(Size > 0); return Data[Size-1]; } - inline const value_type& back() const { IM_ASSERT(Size > 0); return Data[Size-1]; } - inline void swap(ImVector& rhs) { const size_t rhs_size = rhs.Size; rhs.Size = Size; Size = rhs_size; const size_t rhs_cap = rhs.Capacity; rhs.Capacity = Capacity; Capacity = rhs_cap; value_type* rhs_data = rhs.Data; rhs.Data = Data; Data = rhs_data; } - - inline void resize(size_t new_size) { if (new_size > Capacity) reserve(new_size); Size = new_size; } - inline void reserve(size_t new_capacity) - { - if (new_capacity <= Capacity) return; - T* new_data = (value_type*)ImGui::MemAlloc(new_capacity * sizeof(value_type)); - memcpy(new_data, Data, Size * sizeof(value_type)); - ImGui::MemFree(Data); - Data = new_data; - Capacity = new_capacity; - } - - inline void push_back(const value_type& v) { if (Size == Capacity) reserve(Capacity ? Capacity * 2 : 4); Data[Size++] = v; } - inline void pop_back() { IM_ASSERT(Size > 0); Size--; } - - inline iterator erase(const_iterator it) { IM_ASSERT(it >= begin() && it < end()); const ptrdiff_t off = it - begin(); memmove(Data + off, Data + off + 1, (Size - (size_t)off - 1) * sizeof(value_type)); Size--; return Data + off; } - inline iterator insert(const_iterator it, const value_type& v) { IM_ASSERT(it >= begin() && it <= end()); const ptrdiff_t off = it - begin(); if (Size == Capacity) reserve(Capacity ? Capacity * 2 : 4); if (off < (int)Size) memmove(Data + off + 1, Data + off, (Size - (size_t)off) * sizeof(value_type)); Data[off] = v; Size++; return Data + off; } -}; -#endif // #ifndef ImVector - -// Helpers at bottom of the file: -// - IMGUI_ONCE_UPON_A_FRAME // Execute a block of code once per frame only (convenient for creating UI within deep-nested code that runs multiple times) -// - struct ImGuiTextFilter // Parse and apply text filters. In format "aaaaa[,bbbb][,ccccc]" -// - struct ImGuiTextBuffer // Text buffer for logging/accumulating text -// - struct ImGuiStorage // Custom key value storage (if you need to alter open/close states manually) -// - struct ImDrawList // Draw command list -// - struct ImFont // TTF font loader, bake glyphs into bitmap - -// ImGui end-user API -// In a namespace so that user can add extra functions in a separate file (e.g. Value() helpers for your vector or common types) -namespace ImGui -{ - // Main - IMGUI_API ImGuiIO& GetIO(); - IMGUI_API ImGuiStyle& GetStyle(); - IMGUI_API void NewFrame(); - IMGUI_API void Render(); - IMGUI_API void Shutdown(); - IMGUI_API void ShowUserGuide(); // help block - IMGUI_API void ShowStyleEditor(ImGuiStyle* ref = NULL); // style editor block - IMGUI_API void ShowTestWindow(bool* opened = NULL); // test window, demonstrate ImGui features - IMGUI_API void ShowMetricsWindow(bool* opened = NULL); // metrics window - - // Window - // See implementation in .cpp for details - IMGUI_API bool Begin(const char* name = "Debug", bool* p_opened = NULL, ImGuiWindowFlags flags = 0); // return false when window is collapsed, so you can early out in your code. 'bool* p_opened' creates a widget on the upper-right to close the window (which sets your bool to false). - IMGUI_API bool Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_use, float bg_alpha = -1.0f, ImGuiWindowFlags flags = 0); // this is the older/longer API. call SetNextWindowSize() instead if you want to set a window size. For regular windows, 'size_on_first_use' only applies to the first time EVER the window is created and probably not what you want! maybe obsolete this API eventually. - IMGUI_API void End(); - IMGUI_API bool BeginChild(const char* str_id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags extra_flags = 0); // size==0.0f: use remaining window size, size<0.0f: use remaining window size minus abs(size). on each axis. - IMGUI_API bool BeginChild(ImGuiID id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags extra_flags = 0); // " - IMGUI_API void EndChild(); - IMGUI_API ImVec2 GetContentRegionMax(); // window or current column boundaries, in windows coordinates - IMGUI_API ImVec2 GetWindowContentRegionMin(); // window boundaries, in windows coordinates - IMGUI_API ImVec2 GetWindowContentRegionMax(); - IMGUI_API ImDrawList* GetWindowDrawList(); // get rendering command-list if you want to append your own draw primitives - IMGUI_API ImFont* GetWindowFont(); - IMGUI_API float GetWindowFontSize(); // size (also height in pixels) of current font with current scale applied - IMGUI_API void SetWindowFontScale(float scale); // per-window font scale. Adjust IO.FontGlobalScale if you want to scale all windows - IMGUI_API ImVec2 GetWindowPos(); // you should rarely need/care about the window position, but it can be useful if you want to do your own drawing - IMGUI_API ImVec2 GetWindowSize(); // get current window position - IMGUI_API float GetWindowWidth(); - IMGUI_API bool GetWindowCollapsed(); - - IMGUI_API void SetNextWindowPos(const ImVec2& pos, ImGuiSetCond cond = 0); // set next window position - call before Begin() - IMGUI_API void SetNextWindowSize(const ImVec2& size, ImGuiSetCond cond = 0); // set next window size. set to ImVec2(0,0) to force an auto-fit - IMGUI_API void SetNextWindowCollapsed(bool collapsed, ImGuiSetCond cond = 0); // set next window collapsed state - IMGUI_API void SetNextWindowFocus(); // set next window to be focused / front-most - IMGUI_API void SetWindowPos(const ImVec2& pos, ImGuiSetCond cond = 0); // set current window position - call within Begin()/End(). may incur tearing - IMGUI_API void SetWindowSize(const ImVec2& size, ImGuiSetCond cond = 0); // set current window size. set to ImVec2(0,0) to force an auto-fit. may incur tearing - IMGUI_API void SetWindowCollapsed(bool collapsed, ImGuiSetCond cond = 0); // set current window collapsed state - IMGUI_API void SetWindowFocus(); // set current window to be focused / front-most - IMGUI_API void SetWindowPos(const char* name, const ImVec2& pos, ImGuiSetCond cond = 0); // set named window position - call within Begin()/End(). may incur tearing - IMGUI_API void SetWindowSize(const char* name, const ImVec2& size, ImGuiSetCond cond = 0); // set named window size. set to ImVec2(0,0) to force an auto-fit. may incur tearing - IMGUI_API void SetWindowCollapsed(const char* name, bool collapsed, ImGuiSetCond cond = 0); // set named window collapsed state - IMGUI_API void SetWindowFocus(const char* name); // set named window to be focused / front-most. use NULL to remove focus. - - IMGUI_API float GetScrollPosY(); // get scrolling position [0..GetScrollMaxY()] - IMGUI_API float GetScrollMaxY(); // get maximum scrolling position == ContentSize.Y - WindowSize.Y - IMGUI_API void SetScrollPosHere(); // adjust scrolling position to center into the current cursor position - IMGUI_API void SetKeyboardFocusHere(int offset = 0); // focus keyboard on the next widget. Use positive 'offset' to access sub components of a multiple component widget - IMGUI_API void SetStateStorage(ImGuiStorage* tree); // replace tree state storage with our own (if you want to manipulate it yourself, typically clear subsection of it) - IMGUI_API ImGuiStorage* GetStateStorage(); - - // Parameters stacks (shared) - IMGUI_API void PushFont(ImFont* font); // use NULL as a shortcut to push default font - IMGUI_API void PopFont(); - IMGUI_API void PushStyleColor(ImGuiCol idx, const ImVec4& col); - IMGUI_API void PopStyleColor(int count = 1); - IMGUI_API void PushStyleVar(ImGuiStyleVar idx, float val); - IMGUI_API void PushStyleVar(ImGuiStyleVar idx, const ImVec2& val); - IMGUI_API void PopStyleVar(int count = 1); - - // Parameters stacks (current window) - IMGUI_API void PushItemWidth(float item_width); // width of items for the common item+label case, pixels. 0.0f = default to ~2/3 of windows width, >0.0f: width in pixels, <0.0f align xx pixels to the right of window (so -0.01f always align width to the right side) - IMGUI_API void PopItemWidth(); - IMGUI_API float CalcItemWidth(); // width of item given pushed settings and current cursor position - IMGUI_API void PushAllowKeyboardFocus(bool v); // allow focusing using TAB/Shift-TAB, enabled by default but you can disable it for certain widgets - IMGUI_API void PopAllowKeyboardFocus(); - IMGUI_API void PushTextWrapPos(float wrap_pos_x = 0.0f); // word-wrapping for Text*() commands. < 0.0f: no wrapping; 0.0f: wrap to end of window (or column); > 0.0f: wrap at 'wrap_pos_x' position in window local space - IMGUI_API void PopTextWrapPos(); - - // Tooltip - IMGUI_API void SetTooltip(const char* fmt, ...); // set tooltip under mouse-cursor, typically use with ImGui::IsHovered(). last call wins - IMGUI_API void SetTooltipV(const char* fmt, va_list args); - IMGUI_API void BeginTooltip(); // use to create full-featured tooltip windows that aren't just text - IMGUI_API void EndTooltip(); - - // Popup - IMGUI_API void BeginPopup(bool* p_opened); - IMGUI_API void EndPopup(); - - // Layout - IMGUI_API void BeginGroup(); - IMGUI_API void EndGroup(); - IMGUI_API void Separator(); // horizontal line - IMGUI_API void SameLine(int column_x = 0, int spacing_w = -1); // call between widgets or groups to layout them horizontally - IMGUI_API void Spacing(); // add vertical spacing - IMGUI_API void Indent(); // move content position toward the right by style.IndentSpacing pixels - IMGUI_API void Unindent(); // move content position back to the left (cancel Indent) - IMGUI_API void Columns(int count = 1, const char* id = NULL, bool border=true); // setup number of columns - IMGUI_API void NextColumn(); // next column - IMGUI_API int GetColumnIndex(); // get current column index - IMGUI_API float GetColumnOffset(int column_index = -1); // get position of column line (in pixels, from the left side of the contents region). pass -1 to use current column, otherwise 0..GetcolumnsCount() inclusive. column 0 is usually 0.0f and not resizable unless you call this - IMGUI_API void SetColumnOffset(int column_index, float offset_x); // set position of column line (in pixels, from the left side of the contents region). pass -1 to use current column - IMGUI_API float GetColumnWidth(int column_index = -1); // column width (== GetColumnOffset(GetColumnIndex()+1) - GetColumnOffset(GetColumnOffset()) - IMGUI_API int GetColumnsCount(); // number of columns (what was passed to Columns()) - IMGUI_API ImVec2 GetCursorPos(); // cursor position is relative to window position - IMGUI_API float GetCursorPosX(); // " - IMGUI_API float GetCursorPosY(); // " - IMGUI_API void SetCursorPos(const ImVec2& pos); // " - IMGUI_API void SetCursorPosX(float x); // " - IMGUI_API void SetCursorPosY(float y); // " - IMGUI_API ImVec2 GetCursorScreenPos(); // cursor position in absolute screen coordinates [0..io.DisplaySize] - IMGUI_API void SetCursorScreenPos(const ImVec2& pos); // cursor position in absolute screen coordinates [0..io.DisplaySize] - IMGUI_API void AlignFirstTextHeightToWidgets(); // call once if the first item on the line is a Text() item and you want to vertically lower it to match subsequent (bigger) widgets - IMGUI_API float GetTextLineHeight(); // height of font == GetWindowFontSize() - IMGUI_API float GetTextLineHeightWithSpacing(); // spacing (in pixels) between 2 consecutive lines of text == GetWindowFontSize() + GetStyle().ItemSpacing.y - - // ID scopes - // If you are creating widgets in a loop you most likely want to push a unique identifier so ImGui can differentiate them - // You can also use "##extra" within your widget name to distinguish them from each others (see 'Programmer Guide') - IMGUI_API void PushID(const char* str_id); // push identifier into the ID stack. IDs are hash of the *entire* stack! - IMGUI_API void PushID(const char* str_id_begin, const char* str_id_end); - IMGUI_API void PushID(const void* ptr_id); - IMGUI_API void PushID(const int int_id); - IMGUI_API void PopID(); - IMGUI_API ImGuiID GetID(const char* str_id); // calculate unique ID (hash of whole ID stack + given parameter). useful if you want to query into ImGuiStorage yourself. otherwise rarely needed - IMGUI_API ImGuiID GetID(const char* str_id_begin, const char* str_id_end); - IMGUI_API ImGuiID GetID(const void* ptr_id); - - // Widgets - IMGUI_API void Text(const char* fmt, ...); - IMGUI_API void TextV(const char* fmt, va_list args); - IMGUI_API void TextColored(const ImVec4& col, const char* fmt, ...); // shortcut for PushStyleColor(ImGuiCol_Text, col); Text(fmt, ...); PopStyleColor(); - IMGUI_API void TextColoredV(const ImVec4& col, const char* fmt, va_list args); - IMGUI_API void TextWrapped(const char* fmt, ...); // shortcut for PushTextWrapPos(0.0f); Text(fmt, ...); PopTextWrapPos(); - IMGUI_API void TextWrappedV(const char* fmt, va_list args); - IMGUI_API void TextUnformatted(const char* text, const char* text_end = NULL); // doesn't require null terminated string if 'text_end' is specified. no copy done to any bounded stack buffer, recommended for long chunks of text - IMGUI_API void LabelText(const char* label, const char* fmt, ...); // display text+label aligned the same way as value+label widgets - IMGUI_API void LabelTextV(const char* label, const char* fmt, va_list args); - IMGUI_API void Bullet(); - IMGUI_API void BulletText(const char* fmt, ...); - IMGUI_API void BulletTextV(const char* fmt, va_list args); - IMGUI_API bool Button(const char* label, const ImVec2& size = ImVec2(0,0), bool repeat_when_held = false); - IMGUI_API bool SmallButton(const char* label); - IMGUI_API bool InvisibleButton(const char* str_id, const ImVec2& size); - IMGUI_API void Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0,0), const ImVec2& uv1 = ImVec2(1,1), const ImVec4& tint_col = ImVec4(1,1,1,1), const ImVec4& border_col = ImVec4(0,0,0,0)); - IMGUI_API bool ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0,0), const ImVec2& uv1 = ImVec2(1,1), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0,0,0,1), const ImVec4& tint_col = ImVec4(1,1,1,1)); // <0 frame_padding uses default frame padding settings. 0 for no padding - IMGUI_API bool CollapsingHeader(const char* label, const char* str_id = NULL, bool display_frame = true, bool default_open = false); - IMGUI_API bool Checkbox(const char* label, bool* v); - IMGUI_API bool CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value); - IMGUI_API bool RadioButton(const char* label, bool active); - IMGUI_API bool RadioButton(const char* label, int* v, int v_button); - IMGUI_API bool Combo(const char* label, int* current_item, const char** items, int items_count, int height_in_items = -1); - IMGUI_API bool Combo(const char* label, int* current_item, const char* items_separated_by_zeros, int height_in_items = -1); // separate items with \0, end item-list with \0\0 - IMGUI_API bool Combo(const char* label, int* current_item, bool (*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int height_in_items = -1); - IMGUI_API bool ColorButton(const ImVec4& col, bool small_height = false, bool outline_border = true); - IMGUI_API bool ColorEdit3(const char* label, float col[3]); - IMGUI_API bool ColorEdit4(const char* label, float col[4], bool show_alpha = true); - IMGUI_API void ColorEditMode(ImGuiColorEditMode mode); - IMGUI_API void PlotLines(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0), size_t stride = sizeof(float)); - IMGUI_API void PlotLines(const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0)); - IMGUI_API void PlotHistogram(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0), size_t stride = sizeof(float)); - IMGUI_API void PlotHistogram(const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0)); - - // Widgets: Sliders (tip: ctrl+click on a slider to input text) - IMGUI_API bool SliderFloat(const char* label, float* v, float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); // adjust display_format to decorate the value with a prefix or a suffix. Use power!=1.0 for logarithmic sliders - IMGUI_API bool SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); - IMGUI_API bool SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); - IMGUI_API bool SliderFloat4(const char* label, float v[4], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); - IMGUI_API bool SliderAngle(const char* label, float* v_rad, float v_degrees_min = -360.0f, float v_degrees_max = +360.0f); - IMGUI_API bool SliderInt(const char* label, int* v, int v_min, int v_max, const char* display_format = "%.0f"); - IMGUI_API bool SliderInt2(const char* label, int v[2], int v_min, int v_max, const char* display_format = "%.0f"); - IMGUI_API bool SliderInt3(const char* label, int v[3], int v_min, int v_max, const char* display_format = "%.0f"); - IMGUI_API bool SliderInt4(const char* label, int v[4], int v_min, int v_max, const char* display_format = "%.0f"); - IMGUI_API bool VSliderFloat(const char* label, const ImVec2& size, float* v, float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); - IMGUI_API bool VSliderInt(const char* label, const ImVec2& size, int* v, int v_min, int v_max, const char* display_format = "%.0f"); - - // Widgets: Drags (tip: ctrl+click on a drag box to input text) - IMGUI_API bool DragFloat(const char* label, float* v, float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f); // If v_max >= v_max we have no bound - IMGUI_API bool DragFloat2(const char* label, float v[2], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f); - IMGUI_API bool DragFloat3(const char* label, float v[3], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f); - IMGUI_API bool DragFloat4(const char* label, float v[4], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f); - IMGUI_API bool DragInt(const char* label, int* v, float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f"); // If v_max >= v_max we have no bound - IMGUI_API bool DragInt2(const char* label, int v[2], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f"); - IMGUI_API bool DragInt3(const char* label, int v[3], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f"); - IMGUI_API bool DragInt4(const char* label, int v[4], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f"); - - // Widgets: Input - IMGUI_API bool InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags = 0, ImGuiTextEditCallback callback = NULL, void* user_data = NULL); - IMGUI_API bool InputFloat(const char* label, float* v, float step = 0.0f, float step_fast = 0.0f, int decimal_precision = -1, ImGuiInputTextFlags extra_flags = 0); - IMGUI_API bool InputFloat2(const char* label, float v[2], int decimal_precision = -1); - IMGUI_API bool InputFloat3(const char* label, float v[3], int decimal_precision = -1); - IMGUI_API bool InputFloat4(const char* label, float v[4], int decimal_precision = -1); - IMGUI_API bool InputInt(const char* label, int* v, int step = 1, int step_fast = 100, ImGuiInputTextFlags extra_flags = 0); - IMGUI_API bool InputInt2(const char* label, int v[2]); - IMGUI_API bool InputInt3(const char* label, int v[3]); - IMGUI_API bool InputInt4(const char* label, int v[4]); - - // Widgets: Trees - IMGUI_API bool TreeNode(const char* str_label_id); // if returning 'true' the node is open and the user is responsible for calling TreePop - IMGUI_API bool TreeNode(const char* str_id, const char* fmt, ...); // " - IMGUI_API bool TreeNode(const void* ptr_id, const char* fmt, ...); // " - IMGUI_API bool TreeNodeV(const char* str_id, const char* fmt, va_list args); // " - IMGUI_API bool TreeNodeV(const void* ptr_id, const char* fmt, va_list args); // " - IMGUI_API void TreePush(const char* str_id = NULL); // already called by TreeNode(), but you can call Push/Pop yourself for layouting purpose - IMGUI_API void TreePush(const void* ptr_id = NULL); // " - IMGUI_API void TreePop(); - IMGUI_API void SetNextTreeNodeOpened(bool opened, ImGuiSetCond cond = 0); // set next tree node to be opened. - - // Widgets: Selectable / Lists - IMGUI_API bool Selectable(const char* label, bool selected = false, const ImVec2& size = ImVec2(0,0)); - IMGUI_API bool Selectable(const char* label, bool* p_selected, const ImVec2& size = ImVec2(0,0)); - IMGUI_API bool ListBox(const char* label, int* current_item, const char** items, int items_count, int height_in_items = -1); - IMGUI_API bool ListBox(const char* label, int* current_item, bool (*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int height_in_items = -1); - IMGUI_API bool ListBoxHeader(const char* label, const ImVec2& size = ImVec2(0,0)); // use if you want to reimplement ListBox() will custom data or interactions. make sure to call ListBoxFooter() afterwards. - IMGUI_API bool ListBoxHeader(const char* label, int items_count, int height_in_items = -1); // " - IMGUI_API void ListBoxFooter(); // terminate the scrolling region - - // Widgets: Value() Helpers. Output single value in "name: value" format (tip: freely declare your own within the ImGui namespace!) - IMGUI_API void Value(const char* prefix, bool b); - IMGUI_API void Value(const char* prefix, int v); - IMGUI_API void Value(const char* prefix, unsigned int v); - IMGUI_API void Value(const char* prefix, float v, const char* float_format = NULL); - IMGUI_API void Color(const char* prefix, const ImVec4& v); - IMGUI_API void Color(const char* prefix, unsigned int v); - - // Logging: all text output from interface is redirected to tty/file/clipboard. Tree nodes are automatically opened. - IMGUI_API void LogToTTY(int max_depth = -1); // start logging to tty - IMGUI_API void LogToFile(int max_depth = -1, const char* filename = NULL); // start logging to file - IMGUI_API void LogToClipboard(int max_depth = -1); // start logging to OS clipboard - IMGUI_API void LogFinish(); // stop logging (close file, etc.) - IMGUI_API void LogButtons(); // helper to display buttons for logging to tty/file/clipboard - IMGUI_API void LogText(const char* fmt, ...); // pass text data straight to log (without being displayed) - - // Utilities - IMGUI_API bool IsItemHovered(); // was the last item hovered by mouse? - IMGUI_API bool IsItemHoveredRect(); // was the last item hovered by mouse? even if another item is active while we are hovering this - IMGUI_API bool IsItemActive(); // was the last item active? (e.g. button being held, text field being edited- items that don't interact will always return false) - IMGUI_API bool IsAnyItemActive(); // - IMGUI_API bool IsItemVisible(); - IMGUI_API ImVec2 GetItemRectMin(); // get bounding rect of last item in screen space - IMGUI_API ImVec2 GetItemRectMax(); // " - IMGUI_API ImVec2 GetItemRectSize(); // " - IMGUI_API bool IsWindowFocused(); // is current window focused (differentiate child windows from each others) - IMGUI_API bool IsRootWindowFocused(); // is current root window focused - IMGUI_API bool IsRootWindowOrAnyChildFocused(); // is current root window or any of its child (including current window) focused - IMGUI_API bool IsRectClipped(const ImVec2& size); // test if rectangle of given size starting from cursor pos is out of clipping region. to perform coarse clipping on user's side (as an optimization) - IMGUI_API bool IsKeyPressed(int key_index, bool repeat = true); // key_index into the keys_down[512] array, imgui doesn't know the semantic of each entry - IMGUI_API bool IsMouseClicked(int button, bool repeat = false); - IMGUI_API bool IsMouseDoubleClicked(int button); - IMGUI_API bool IsMouseHoveringWindow(); // is mouse hovering current window ("window" in API names always refer to current window) - IMGUI_API bool IsMouseHoveringAnyWindow(); // is mouse hovering any active imgui window - IMGUI_API bool IsMouseHoveringRect(const ImVec2& rect_min, const ImVec2& rect_max);// is mouse hovering given bounding rect - IMGUI_API bool IsMouseDragging(int button = 0, float lock_threshold = -1.0f); // is mouse dragging. if lock_threshold < -1.0f uses io.MouseDraggingThreshold - IMGUI_API bool IsPosHoveringAnyWindow(const ImVec2& pos); // is given position hovering any active imgui window - IMGUI_API ImVec2 GetMousePos(); // shortcut to ImGui::GetIO().MousePos provided by user, to be consistent with other calls - IMGUI_API ImVec2 GetMouseDragDelta(int button = 0, float lock_threshold = -1.0f); // dragging amount since clicking, also see: GetItemActiveDragDelta(). if lock_threshold < -1.0f uses io.MouseDraggingThreshold - IMGUI_API void ResetMouseDragDelta(int button = 0); - IMGUI_API ImGuiMouseCursor GetMouseCursor(); // get desired cursor type, reset in ImGui::NewFrame(), this updated during the frame. valid before Render(). If you use software rendering by setting io.MouseDrawCursor ImGui will render those for you - IMGUI_API void SetMouseCursor(ImGuiMouseCursor type); // set desired cursor type - IMGUI_API float GetTime(); - IMGUI_API int GetFrameCount(); - IMGUI_API const char* GetStyleColName(ImGuiCol idx); - IMGUI_API ImVec2 CalcItemRectClosestPoint(const ImVec2& pos, bool on_edge = false, float outward = +0.0f); // utility to find the closest point the last item bounding rectangle edge. useful to visually link items - IMGUI_API ImVec2 CalcTextSize(const char* text, const char* text_end = NULL, bool hide_text_after_double_hash = false, float wrap_width = -1.0f); - IMGUI_API void CalcListClipping(int items_count, float items_height, int* out_items_display_start, int* out_items_display_end); // helper to manually clip large list of items. see comments in implementation - - IMGUI_API void BeginChildFrame(ImGuiID id, const ImVec2& size); // helper to create a child window / scrolling region that looks like a normal widget frame - IMGUI_API void EndChildFrame(); - - IMGUI_API ImU32 ColorConvertFloat4ToU32(const ImVec4& in); - IMGUI_API void ColorConvertRGBtoHSV(float r, float g, float b, float& out_h, float& out_s, float& out_v); - IMGUI_API void ColorConvertHSVtoRGB(float h, float s, float v, float& out_r, float& out_g, float& out_b); - - // Internal state access - if you want to share ImGui state between modules (e.g. DLL) or allocate it yourself - IMGUI_API const char* GetVersion(); - IMGUI_API void* GetInternalState(); - IMGUI_API size_t GetInternalStateSize(); - IMGUI_API void SetInternalState(void* state, bool construct = false); - - // Obsolete (will be removed) - IMGUI_API void GetDefaultFontData(const void** fnt_data, unsigned int* fnt_size, const void** png_data, unsigned int* png_size); // OBSOLETE - static inline void OpenNextNode(bool open) { ImGui::SetNextTreeNodeOpened(open, 0); } // OBSOLETE - static inline bool GetWindowIsFocused() { return ImGui::IsWindowFocused(); } // OBSOLETE - static inline ImVec2 GetItemBoxMin() { return GetItemRectMin(); } // OBSOLETE - static inline ImVec2 GetItemBoxMax() { return GetItemRectMax(); } // OBSOLETE - static inline bool IsClipped(const ImVec2& size) { return IsRectClipped(size); } // OBSOLETE - static inline bool IsMouseHoveringBox(const ImVec2& rect_min, const ImVec2& rect_max) { return IsMouseHoveringRect(rect_min, rect_max); } // OBSOLETE - -} // namespace ImGui - -// Flags for ImGui::Begin() -enum ImGuiWindowFlags_ -{ - // Default: 0 - ImGuiWindowFlags_NoTitleBar = 1 << 0, // Disable title-bar - ImGuiWindowFlags_NoResize = 1 << 1, // Disable user resizing with the lower-right grip - ImGuiWindowFlags_NoMove = 1 << 2, // Disable user moving the window - ImGuiWindowFlags_NoScrollbar = 1 << 3, // Disable scrollbar (window can still scroll with mouse or programatically) - ImGuiWindowFlags_NoScrollWithMouse = 1 << 4, // Disable user scrolling with mouse wheel - ImGuiWindowFlags_NoCollapse = 1 << 5, // Disable user collapsing window by double-clicking on it - ImGuiWindowFlags_AlwaysAutoResize = 1 << 6, // Resize every window to its content every frame - ImGuiWindowFlags_ShowBorders = 1 << 7, // Show borders around windows and items - ImGuiWindowFlags_NoSavedSettings = 1 << 8, // Never load/save settings in .ini file - // [Internal] - ImGuiWindowFlags_ChildWindow = 1 << 9, // For internal use by BeginChild() - ImGuiWindowFlags_ChildWindowAutoFitX = 1 << 10, // For internal use by BeginChild() - ImGuiWindowFlags_ChildWindowAutoFitY = 1 << 11, // For internal use by BeginChild() - ImGuiWindowFlags_ComboBox = 1 << 12, // For internal use by ComboBox() - ImGuiWindowFlags_Tooltip = 1 << 13, // For internal use by BeginTooltip() - ImGuiWindowFlags_Popup = 1 << 14 // For internal use by BeginPopup() + IMGUI_GFXCMD_RECT, + IMGUI_GFXCMD_TRIANGLE, + IMGUI_GFXCMD_LINE, + IMGUI_GFXCMD_TEXT, + IMGUI_GFXCMD_SCISSOR, }; -// Flags for ImGui::InputText() -enum ImGuiInputTextFlags_ +struct imguiGfxRect { - // Default: 0 - ImGuiInputTextFlags_CharsDecimal = 1 << 0, // Allow 0123456789.+-*/ - ImGuiInputTextFlags_CharsHexadecimal = 1 << 1, // Allow 0123456789ABCDEFabcdef - ImGuiInputTextFlags_CharsUppercase = 1 << 2, // Turn a..z into A..Z - ImGuiInputTextFlags_CharsNoBlank = 1 << 3, // Filter out spaces, tabs - ImGuiInputTextFlags_AutoSelectAll = 1 << 4, // Select entire text when first taking mouse focus - ImGuiInputTextFlags_EnterReturnsTrue = 1 << 5, // Return 'true' when Enter is pressed (as opposed to when the value was modified) - ImGuiInputTextFlags_CallbackCompletion = 1 << 6, // Call user function on pressing TAB (for completion handling) - ImGuiInputTextFlags_CallbackHistory = 1 << 7, // Call user function on pressing Up/Down arrows (for history handling) - ImGuiInputTextFlags_CallbackAlways = 1 << 8, // Call user function every time - ImGuiInputTextFlags_CallbackCharFilter = 1 << 9 // Call user function to filter character. Modify data->EventChar to replace/filter input, or return 1 to discard character. + short x,y,w,h,r; }; -// User fill ImGuiIO.KeyMap[] array with indices into the ImGuiIO.KeysDown[512] array -enum ImGuiKey_ +struct imguiGfxText { - ImGuiKey_Tab, - ImGuiKey_LeftArrow, - ImGuiKey_RightArrow, - ImGuiKey_UpArrow, - ImGuiKey_DownArrow, - ImGuiKey_Home, - ImGuiKey_End, - ImGuiKey_Delete, - ImGuiKey_Backspace, - ImGuiKey_Enter, - ImGuiKey_Escape, - ImGuiKey_A, // for CTRL+A: select all - ImGuiKey_C, // for CTRL+C: copy - ImGuiKey_V, // for CTRL+V: paste - ImGuiKey_X, // for CTRL+X: cut - ImGuiKey_Y, // for CTRL+Y: redo - ImGuiKey_Z, // for CTRL+Z: undo - ImGuiKey_COUNT + short x,y,align; + const char* text; }; -// Enumeration for PushStyleColor() / PopStyleColor() -enum ImGuiCol_ +struct imguiGfxLine { - ImGuiCol_Text, - ImGuiCol_WindowBg, - ImGuiCol_ChildWindowBg, - ImGuiCol_Border, - ImGuiCol_BorderShadow, - ImGuiCol_FrameBg, // Background of checkbox, radio button, plot, slider, text input - ImGuiCol_FrameBgHovered, - ImGuiCol_FrameBgActive, - ImGuiCol_TitleBg, - ImGuiCol_TitleBgCollapsed, - ImGuiCol_ScrollbarBg, - ImGuiCol_ScrollbarGrab, - ImGuiCol_ScrollbarGrabHovered, - ImGuiCol_ScrollbarGrabActive, - ImGuiCol_ComboBg, - ImGuiCol_CheckMark, - ImGuiCol_SliderGrab, - ImGuiCol_SliderGrabActive, - ImGuiCol_Button, - ImGuiCol_ButtonHovered, - ImGuiCol_ButtonActive, - ImGuiCol_Header, - ImGuiCol_HeaderHovered, - ImGuiCol_HeaderActive, - ImGuiCol_Column, - ImGuiCol_ColumnHovered, - ImGuiCol_ColumnActive, - ImGuiCol_ResizeGrip, - ImGuiCol_ResizeGripHovered, - ImGuiCol_ResizeGripActive, - ImGuiCol_CloseButton, - ImGuiCol_CloseButtonHovered, - ImGuiCol_CloseButtonActive, - ImGuiCol_PlotLines, - ImGuiCol_PlotLinesHovered, - ImGuiCol_PlotHistogram, - ImGuiCol_PlotHistogramHovered, - ImGuiCol_TextSelectedBg, - ImGuiCol_TooltipBg, - ImGuiCol_COUNT + short x0,y0,x1,y1,r; }; -// Enumeration for PushStyleVar() / PopStyleVar() -// NB: the enum only refers to fields of ImGuiStyle() which makes sense to be pushed/poped in UI code. Feel free to add others. -enum ImGuiStyleVar_ +struct imguiGfxCmd { - ImGuiStyleVar_Alpha, // float - ImGuiStyleVar_WindowPadding, // ImVec2 - ImGuiStyleVar_WindowRounding, // float - ImGuiStyleVar_ChildWindowRounding, // float - ImGuiStyleVar_FramePadding, // ImVec2 - ImGuiStyleVar_FrameRounding, // float - ImGuiStyleVar_ItemSpacing, // ImVec2 - ImGuiStyleVar_ItemInnerSpacing, // ImVec2 - ImGuiStyleVar_IndentSpacing, // float - ImGuiStyleVar_GrabMinSize // float + char type; + char flags; + char pad[2]; + unsigned int col; + union + { + imguiGfxLine line; + imguiGfxRect rect; + imguiGfxText text; + }; }; -// Enumeration for ColorEditMode() -enum ImGuiColorEditMode_ -{ - ImGuiColorEditMode_UserSelect = -2, - ImGuiColorEditMode_UserSelectShowButton = -1, - ImGuiColorEditMode_RGB = 0, - ImGuiColorEditMode_HSV = 1, - ImGuiColorEditMode_HEX = 2 -}; +const imguiGfxCmd* imguiGetRenderQueue(); +int imguiGetRenderQueueSize(); -// Enumeration for GetMouseCursor() -enum ImGuiMouseCursor_ -{ - ImGuiMouseCursor_Arrow = 0, - ImGuiMouseCursor_TextInput, // When hovering over InputText, etc. - ImGuiMouseCursor_Move, // Unused - ImGuiMouseCursor_ResizeNS, // Unused - ImGuiMouseCursor_ResizeEW, // When hovering over a column - ImGuiMouseCursor_ResizeNESW, // Unused - ImGuiMouseCursor_ResizeNWSE, // When hovering over the bottom-right corner of a window - ImGuiMouseCursor_Count_ -}; -// Condition flags for ImGui::SetWindow***(), SetNextWindow***(), SetNextTreeNode***() functions -// All those functions treat 0 as a shortcut to ImGuiSetCond_Always -enum ImGuiSetCond_ -{ - ImGuiSetCond_Always = 1 << 0, // Set the variable - ImGuiSetCond_Once = 1 << 1, // Only set the variable on the first call per runtime session - ImGuiSetCond_FirstUseEver = 1 << 2 // Only set the variable if the window doesn't exist in the .ini file -}; - -struct ImGuiStyle -{ - float Alpha; // Global alpha applies to everything in ImGui - ImVec2 WindowPadding; // Padding within a window - ImVec2 WindowMinSize; // Minimum window size - float WindowRounding; // Radius of window corners rounding. Set to 0.0f to have rectangular windows - float ChildWindowRounding; // Radius of child window corners rounding. Set to 0.0f to have rectangular windows - ImVec2 FramePadding; // Padding within a framed rectangle (used by most widgets) - float FrameRounding; // Radius of frame corners rounding. Set to 0.0f to have rectangular frame (used by most widgets). - ImVec2 ItemSpacing; // Horizontal and vertical spacing between widgets/lines - ImVec2 ItemInnerSpacing; // Horizontal and vertical spacing between within elements of a composed widget (e.g. a slider and its label) - ImVec2 TouchExtraPadding; // Expand reactive bounding box for touch-based system where touch position is not accurate enough. Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget. So don't grow this too much! - ImVec2 AutoFitPadding; // Extra space after auto-fit (double-clicking on resize grip) - float WindowFillAlphaDefault; // Default alpha of window background, if not specified in ImGui::Begin() - float IndentSpacing; // Horizontal indentation when e.g. entering a tree node - float ColumnsMinSpacing; // Minimum horizontal spacing between two columns - float ScrollbarWidth; // Width of the vertical scrollbar - float GrabMinSize; // Minimum width/height of a slider or scrollbar grab - ImVec2 DisplaySafeAreaPadding; // Window positions are clamped to be visible within the display area. If you cannot see the edge of your screen (e.g. on a TV) increase the safe area padding. - ImVec4 Colors[ImGuiCol_COUNT]; - - IMGUI_API ImGuiStyle(); -}; - -// This is where your app communicate with ImGui. Call ImGui::GetIO() to access. -// Read 'Programmer guide' section in .cpp file for general usage. -struct ImGuiIO -{ - //------------------------------------------------------------------ - // Settings (fill once) // Default value: - //------------------------------------------------------------------ - - ImVec2 DisplaySize; // // Display size, in pixels. For clamping windows positions. - float DeltaTime; // = 1.0f/60.0f // Time elapsed since last frame, in seconds. - float IniSavingRate; // = 5.0f // Maximum time between saving positions/sizes to .ini file, in seconds. - const char* IniFilename; // = "imgui.ini" // Path to .ini file. NULL to disable .ini saving. - const char* LogFilename; // = "imgui_log.txt" // Path to .log file (default parameter to ImGui::LogToFile when no file is specified). - float MouseDoubleClickTime; // = 0.30f // Time for a double-click, in seconds. - float MouseDoubleClickMaxDist; // = 6.0f // Distance threshold to stay in to validate a double-click, in pixels. - float MouseDragThreshold; // = 6.0f // Distance threshold before considering we are dragging - int KeyMap[ImGuiKey_COUNT]; // // Map of indices into the KeysDown[512] entries array - void* UserData; // = NULL // Store your own data for retrieval by callbacks. - - ImFontAtlas* Fonts; // // Load and assemble one or more fonts into a single tightly packed texture. Output to Fonts array. - float FontGlobalScale; // = 1.0f // Global scale all fonts - bool FontAllowUserScaling; // = false // Allow user scaling text of individual window with CTRL+Wheel. - ImVec2 DisplayVisibleMin; // (0.0f,0.0f) // If you use DisplaySize as a virtual space larger than your screen, set DisplayVisibleMin/Max to the visible area. - ImVec2 DisplayVisibleMax; // (0.0f,0.0f) // If the values are the same, we defaults to Min=(0.0f) and Max=DisplaySize - - //------------------------------------------------------------------ - // User Functions - //------------------------------------------------------------------ - - // REQUIRED: rendering function. - // See example code if you are unsure of how to implement this. - void (*RenderDrawListsFn)(ImDrawList** const draw_lists, int count); - - // Optional: access OS clipboard - // (default to use native Win32 clipboard on Windows, otherwise uses a private clipboard. Override to access OS clipboard on other architectures) - const char* (*GetClipboardTextFn)(); - void (*SetClipboardTextFn)(const char* text); - - // Optional: override memory allocations. MemFreeFn() may be called with a NULL pointer. - // (default to posix malloc/free) - void* (*MemAllocFn)(size_t sz); - void (*MemFreeFn)(void* ptr); - - // Optional: notify OS Input Method Editor of the screen position of your cursor for text input position (e.g. when using Japanese/Chinese IME in Windows) - // (default to use native imm32 api on Windows) - void (*ImeSetInputScreenPosFn)(int x, int y); - void* ImeWindowHandle; // (Windows) Set this to your HWND to get automatic IME cursor positioning. - - //------------------------------------------------------------------ - // Input - Fill before calling NewFrame() - //------------------------------------------------------------------ - - ImVec2 MousePos; // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.) - bool MouseDown[5]; // Mouse buttons. ImGui itself only uses button 0 (left button). Others buttons allows to track if mouse is being used by your application + available to user as a convenience via IsMouse** API. - float MouseWheel; // Mouse wheel: 1 unit scrolls about 5 lines text. - bool MouseDrawCursor; // Request ImGui to draw a mouse cursor for you (if you are on a platform without a mouse cursor). - bool KeyCtrl; // Keyboard modifier pressed: Control - bool KeyShift; // Keyboard modifier pressed: Shift - bool KeyAlt; // Keyboard modifier pressed: Alt - bool KeysDown[512]; // Keyboard keys that are pressed (in whatever storage order you naturally have access to keyboard data) - ImWchar InputCharacters[16+1]; // List of characters input (translated by user from keypress+keyboard state). Fill using AddInputCharacter() helper. - - // Function - IMGUI_API void AddInputCharacter(ImWchar c); // Helper to add a new character into InputCharacters[] - - //------------------------------------------------------------------ - // Output - Retrieve after calling NewFrame(), you can use them to discard inputs or hide them from the rest of your application - //------------------------------------------------------------------ - - bool WantCaptureMouse; // Mouse is hovering a window or widget is active (= ImGui will use your mouse input) - bool WantCaptureKeyboard; // Widget is active (= ImGui will use your keyboard input) - float Framerate; // Framerate estimation, in frame per second. Rolling average estimation based on IO.DeltaTime over 120 frames - int MetricsRenderVertices; // Vertices processed during last call to Render() - - //------------------------------------------------------------------ - // [Internal] ImGui will maintain those fields for you - //------------------------------------------------------------------ - - ImVec2 MousePosPrev; // Previous mouse position - ImVec2 MouseDelta; // Mouse delta. Note that this is zero if either current or previous position are negative to allow mouse enabling/disabling. - bool MouseClicked[5]; // Mouse button went from !Down to Down - ImVec2 MouseClickedPos[5]; // Position at time of clicking - float MouseClickedTime[5]; // Time of last click (used to figure out double-click) - bool MouseDoubleClicked[5]; // Has mouse button been double-clicked? - bool MouseDownOwned[5]; // Track if button was clicked inside a window. We don't request mouse capture from the application if click started outside ImGui bounds. - float MouseDownTime[5]; // Time the mouse button has been down - float MouseDragMaxDistanceSqr[5]; // Squared maximum distance of how much mouse has traveled from the click point - float KeysDownTime[512]; // Time the keyboard key has been down - - IMGUI_API ImGuiIO(); -}; - -//----------------------------------------------------------------------------- -// Helpers -//----------------------------------------------------------------------------- - -// Helper: execute a block of code once a frame only -// Convenient if you want to quickly create an UI within deep-nested code that runs multiple times every frame. -// Usage: -// IMGUI_ONCE_UPON_A_FRAME -// { -// // code block will be executed one per frame -// } -// Attention! the macro expands into 2 statement so make sure you don't use it within e.g. an if() statement without curly braces. -#define IMGUI_ONCE_UPON_A_FRAME static ImGuiOnceUponAFrame imgui_oaf##__LINE__; if (imgui_oaf##__LINE__) -struct ImGuiOnceUponAFrame -{ - ImGuiOnceUponAFrame() { RefFrame = -1; } - mutable int RefFrame; - operator bool() const { const int current_frame = ImGui::GetFrameCount(); if (RefFrame == current_frame) return false; RefFrame = current_frame; return true; } -}; - -// Helper: Parse and apply text filters. In format "aaaaa[,bbbb][,ccccc]" -struct ImGuiTextFilter -{ - struct TextRange - { - const char* b; - const char* e; - - TextRange() { b = e = NULL; } - TextRange(const char* _b, const char* _e) { b = _b; e = _e; } - const char* begin() const { return b; } - const char* end() const { return e; } - bool empty() const { return b == e; } - char front() const { return *b; } - static bool isblank(char c) { return c == ' ' || c == '\t'; } - void trim_blanks() { while (b < e && isblank(*b)) b++; while (e > b && isblank(*(e-1))) e--; } - IMGUI_API void split(char separator, ImVector& out); - }; - - char InputBuf[256]; - ImVector Filters; - int CountGrep; - - ImGuiTextFilter(const char* default_filter = ""); - void Clear() { InputBuf[0] = 0; Build(); } - void Draw(const char* label = "Filter (inc,-exc)", float width = -1.0f); // Helper calling InputText+Build - bool PassFilter(const char* val) const; - bool IsActive() const { return !Filters.empty(); } - IMGUI_API void Build(); -}; - -// Helper: Text buffer for logging/accumulating text -struct ImGuiTextBuffer -{ - ImVector Buf; - - ImGuiTextBuffer() { Buf.push_back(0); } - const char* begin() const { return &Buf.front(); } - const char* end() const { return &Buf.back(); } // Buf is zero-terminated, so end() will point on the zero-terminator - size_t size() const { return Buf.size()-1; } - bool empty() { return size() >= 1; } - void clear() { Buf.clear(); Buf.push_back(0); } - IMGUI_API void append(const char* fmt, ...); - IMGUI_API void appendv(const char* fmt, va_list args); -}; - -// Helper: Key->value storage -// - Store collapse state for a tree (Int 0/1) -// - Store color edit options (Int using values in ImGuiColorEditMode enum). -// - Custom user storage for temporary values. -// Typically you don't have to worry about this since a storage is held within each Window. -// Declare your own storage if: -// - You want to manipulate the open/close state of a particular sub-tree in your interface (tree node uses Int 0/1 to store their state). -// - You want to store custom debug data easily without adding or editing structures in your code. -struct ImGuiStorage -{ - struct Pair - { - ImGuiID key; - union { int val_i; float val_f; void* val_p; }; - Pair(ImGuiID _key, int _val_i) { key = _key; val_i = _val_i; } - Pair(ImGuiID _key, float _val_f) { key = _key; val_f = _val_f; } - Pair(ImGuiID _key, void* _val_p) { key = _key; val_p = _val_p; } - }; - ImVector Data; - - // - Get***() functions find pair, never add/allocate. Pairs are sorted so a query is O(log N) - // - Set***() functions find pair, insertion on demand if missing. - // - Sorted insertion is costly but should amortize. A typical frame shouldn't need to insert any new pair. - IMGUI_API void Clear(); - IMGUI_API int GetInt(ImGuiID key, int default_val = 0) const; - IMGUI_API void SetInt(ImGuiID key, int val); - IMGUI_API float GetFloat(ImGuiID key, float default_val = 0.0f) const; - IMGUI_API void SetFloat(ImGuiID key, float val); - IMGUI_API void* GetVoidPtr(ImGuiID key) const; // default_val is NULL - IMGUI_API void SetVoidPtr(ImGuiID key, void* val); - - // - Get***Ref() functions finds pair, insert on demand if missing, return pointer. Useful if you intend to do Get+Set. - // - References are only valid until a new value is added to the storage. Calling a Set***() function or a Get***Ref() function invalidates the pointer. - // - A typical use case where this is convenient: - // float* pvar = ImGui::GetFloatRef(key); ImGui::SliderFloat("var", pvar, 0, 100.0f); some_var += *pvar; - // - You can also use this to quickly create temporary editable values during a session of using Edit&Continue, without restarting your application. - IMGUI_API int* GetIntRef(ImGuiID key, int default_val = 0); - IMGUI_API float* GetFloatRef(ImGuiID key, float default_val = 0); - IMGUI_API void** GetVoidPtrRef(ImGuiID key, void* default_val = NULL); - - // Use on your own storage if you know only integer are being stored (open/close all tree nodes) - IMGUI_API void SetAllInt(int val); -}; - -// Shared state of InputText(), passed to callback when a ImGuiInputTextFlags_Callback* flag is used. -struct ImGuiTextEditCallbackData -{ - ImGuiInputTextFlags EventFlag; // One of ImGuiInputTextFlags_Callback* // Read-only - ImGuiInputTextFlags Flags; // What user passed to InputText() // Read-only - void* UserData; // What user passed to InputText() // Read-only - - // CharFilter event: - ImWchar EventChar; // Character input // Read-write (replace character or set to zero) - - // Completion,History,Always events: - ImGuiKey EventKey; // Key pressed (Up/Down/TAB) // Read-only - char* Buf; // Current text // Read-write (pointed data only) - size_t BufSize; // // Read-only - bool BufDirty; // Set if you modify Buf directly // Write - int CursorPos; // // Read-write - int SelectionStart; // // Read-write (== to SelectionEnd when no selection) - int SelectionEnd; // // Read-write - - // NB: calling those function loses selection. - void DeleteChars(int pos, int bytes_count); - void InsertChars(int pos, const char* text, const char* text_end = NULL); -}; - -// ImColor() is just a helper that implicity converts to either ImU32 (packed 4x1 byte) or ImVec4 (4x1 float) -// None of the ImGui API are using ImColor directly but you can use it as a convenience to pass colors in either formats. -struct ImColor -{ - ImVec4 Value; - - ImColor(int r, int g, int b, int a = 255) { Value.x = (float)r / 255.0f; Value.y = (float)g / 255.0f; Value.z = (float)b / 255.0f; Value.w = (float)a / 255.0f; } - ImColor(float r, float g, float b, float a = 1.0f) { Value.x = r; Value.y = g; Value.z = b; Value.w = a; } - ImColor(const ImVec4& col) { Value = col; } - operator ImU32() const { return ImGui::ColorConvertFloat4ToU32(Value); } - operator ImVec4() const { return Value; } - - static ImColor HSV(float h, float s, float v, float a = 1.0f) { float r,g,b; ImGui::ColorConvertHSVtoRGB(h, s, v, r, g, b); return ImColor(r,g,b,a); } -}; - -//----------------------------------------------------------------------------- -// Draw List -// Hold a series of drawing commands. The user provides a renderer for ImDrawList. -//----------------------------------------------------------------------------- - -// Draw callbacks for advanced uses. -// NB- You most likely DO NOT need to care about draw callbacks just to create your own widget or customized UI rendering (you can poke into the draw list for that) -// Draw callback are useful for example if you want to render a complex 3D scene inside a UI element. -// The expected behavior from your rendering loop is: -// if (cmd.user_callback != NULL) -// cmd.user_callback(parent_list, cmd); -// else -// RenderTriangles() -// It is up to you to decide if your rendering loop or the callback should be responsible for backup/restoring rendering state. -typedef void (*ImDrawCallback)(const ImDrawList* parent_list, const ImDrawCmd* cmd); - -// Typically, 1 command = 1 gpu draw call (unless command is a callback) -struct ImDrawCmd -{ - unsigned int vtx_count; // Number of vertices (multiple of 3) to be drawn as triangles. The vertices are stored in the callee ImDrawList's vtx_buffer[] array. - ImVec4 clip_rect; // Clipping rectangle (x1, y1, x2, y2) - ImTextureID texture_id; // User-provided texture ID. Set by user in ImfontAtlas::SetTexID() for fonts or passed to Image*() functions. Ignore if never using images or multiple fonts atlas. - ImDrawCallback user_callback; // If != NULL, call the function instead of rendering the vertices. vtx_count will be 0. clip_rect and texture_id will be set normally. - void* user_callback_data; // The draw callback code can access this. -}; - -// Vertex layout -#ifndef IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT -struct ImDrawVert -{ - ImVec2 pos; - ImVec2 uv; - ImU32 col; -}; -#else -// You can change the vertex format layout by defining IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT in imconfig.h -// The code expect ImVec2 pos (8 bytes), ImVec2 uv (8 bytes), ImU32 col (4 bytes), but you can re-order them or add other fields as needed to simplify integration in your engine. -// The type has to be described by the #define (you can either declare the struct or use a typedef) -IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT; -#endif - -// Draw command list -// This is the low-level list of polygons that ImGui functions are filling. At the end of the frame, all command lists are passed to your ImGuiIO::RenderDrawListFn function for rendering. -// At the moment, each ImGui window contains its own ImDrawList but they could potentially be merged in the future. -// If you want to add custom rendering within a window, you can use ImGui::GetWindowDrawList() to access the current draw list and add your own primitives. -// You can interleave normal ImGui:: calls and adding primitives to the current draw list. -// All positions are in screen coordinates (0,0=top-left, 1 pixel per unit). Primitives are always added to the list and not culled (culling is done at render time and at a higher-level by ImGui:: functions). -// Note that this only gives you access to rendering polygons. If your intent is to create custom widgets and the publicly exposed functions/data aren't sufficient, you can add code in imgui_user.inl -struct ImDrawList -{ - // This is what you have to render - ImVector commands; // Commands. Typically 1 command = 1 gpu draw call. - ImVector vtx_buffer; // Vertex buffer. Each command consume ImDrawCmd::vtx_count of those - - // [Internal to ImGui] - ImVector clip_rect_stack; // [Internal] - ImVector texture_id_stack; // [Internal] - ImDrawVert* vtx_write; // [Internal] point within vtx_buffer after each add command (to avoid using the ImVector<> operators too much) - - ImDrawList() { Clear(); } - IMGUI_API void Clear(); - IMGUI_API void ClearFreeMemory(); - IMGUI_API void PushClipRect(const ImVec4& clip_rect); // Scissoring. The values are x1, y1, x2, y2. - IMGUI_API void PushClipRectFullScreen(); - IMGUI_API void PopClipRect(); - IMGUI_API void PushTextureID(const ImTextureID& texture_id); - IMGUI_API void PopTextureID(); - - // Primitives - IMGUI_API void AddLine(const ImVec2& a, const ImVec2& b, ImU32 col, float thickness = 1.0f); - IMGUI_API void AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners = 0x0F); - IMGUI_API void AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners = 0x0F); - IMGUI_API void AddTriangleFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col); - IMGUI_API void AddCircle(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12); - IMGUI_API void AddCircleFilled(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12); - IMGUI_API void AddArcFast(const ImVec2& center, float radius, ImU32 col, int a_min_12, int a_max_12, bool filled = false, const ImVec2& third_point_offset = ImVec2(0,0)); // Angles in 0..12 range - IMGUI_API void AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL, float wrap_width = 0.0f, const ImVec2* cpu_clip_max = NULL); - IMGUI_API void AddImage(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv0, const ImVec2& uv1, ImU32 col = 0xFFFFFFFF); - - // Advanced - IMGUI_API void AddCallback(ImDrawCallback callback, void* callback_data); // Your rendering function must check for 'user_callback' in ImDrawCmd and call the function instead of rendering triangles. - IMGUI_API void AddDrawCmd(); // This is useful if you need to forcefully create a new draw call (to allow for dependent rendering / blending). Otherwise primitives are merged into the same draw-call as much as possible - - // Internal helpers - IMGUI_API void PrimReserve(unsigned int vtx_count); - IMGUI_API void PrimTriangle(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col); - IMGUI_API void PrimRect(const ImVec2& a, const ImVec2& b, ImU32 col); - IMGUI_API void PrimRectUV(const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, ImU32 col); - IMGUI_API void PrimQuad(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, ImU32 col); - IMGUI_API void PrimLine(const ImVec2& a, const ImVec2& b, ImU32 col, float thickness = 1.0f); - IMGUI_API void UpdateClipRect(); - IMGUI_API void UpdateTextureID(); - IMGUI_API void PrimVtx(const ImVec2& pos, const ImVec2& uv, ImU32 col) { vtx_write->pos = pos; vtx_write->uv = uv; vtx_write->col = col; vtx_write++; } -}; - -// Load and rasterize multiple TTF fonts into a same texture. -// Sharing a texture for multiple fonts allows us to reduce the number of draw calls during rendering. -// We also add custom graphic data into the texture that serves for ImGui. -// 1. (Optional) Call AddFont*** functions. If you don't call any, the default font will be loaded for you. -// 2. Call GetTexDataAsAlpha8() or GetTexDataAsRGBA32() to build and retrieve pixels data. -// 3. Upload the pixels data into a texture within your graphics system. -// 4. Call SetTexID(my_tex_id); and pass the pointer/identifier to your texture. This value will be passed back to you during rendering to identify the texture. -// 5. Call ClearTexData() to free textures memory on the heap. -struct ImFontAtlas -{ - IMGUI_API ImFontAtlas(); - IMGUI_API ~ImFontAtlas(); - IMGUI_API ImFont* AddFontDefault(); - IMGUI_API ImFont* AddFontFromFileTTF(const char* filename, float size_pixels, const ImWchar* glyph_ranges = NULL, int font_no = 0); - IMGUI_API ImFont* AddFontFromMemoryTTF(void* in_ttf_data, unsigned int in_ttf_data_size, float size_pixels, const ImWchar* glyph_ranges = NULL, int font_no = 0); // Pass ownership of 'in_ttf_data' memory, will be deleted after build - IMGUI_API ImFont* AddFontFromMemoryCompressedTTF(const void* in_compressed_ttf_data, unsigned int in_compressed_ttf_data_size, float size_pixels, const ImWchar* glyph_ranges = NULL, int font_no = 0); // 'in_compressed_ttf_data' untouched and still owned by caller. compress with binary_to_compressed_c. - IMGUI_API void ClearTexData(); // Saves RAM once the texture has been copied to graphics memory. - IMGUI_API void Clear(); - - // Retrieve texture data - // User is in charge of copying the pixels into graphics memory, then call SetTextureUserID() - // After loading the texture into your graphic system, store your texture handle in 'TexID' (ignore if you aren't using multiple fonts nor images) - // RGBA32 format is provided for convenience and high compatibility, but note that all RGB pixels are white, so 75% of the memory is wasted. - // Pitch = Width * BytesPerPixels - IMGUI_API void GetTexDataAsAlpha8(unsigned char** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel = NULL); // 1 byte per-pixel - IMGUI_API void GetTexDataAsRGBA32(unsigned char** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel = NULL); // 4 bytes-per-pixel - IMGUI_API void SetTexID(void* id) { TexID = id; } - - // Helpers to retrieve list of common Unicode ranges (2 value per range, values are inclusive, zero-terminated list) - // (Those functions could be static but aren't so most users don't have to refer to the ImFontAtlas:: name ever if in their code; just using io.Fonts->) - IMGUI_API const ImWchar* GetGlyphRangesDefault(); // Basic Latin, Extended Latin - IMGUI_API const ImWchar* GetGlyphRangesJapanese(); // Default + Hiragana, Katakana, Half-Width, Selection of 1946 Ideographs - IMGUI_API const ImWchar* GetGlyphRangesChinese(); // Japanese + full set of about 21000 CJK Unified Ideographs - - // Members - // (Access texture data via GetTexData*() calls which will setup a default font for you.) - void* TexID; // User data to refer to the texture once it has been uploaded to user's graphic systems. It ia passed back to you during rendering. - unsigned char* TexPixelsAlpha8; // 1 component per pixel, each component is unsigned 8-bit. Total size = TexWidth * TexHeight - unsigned int* TexPixelsRGBA32; // 4 component per pixel, each component is unsigned 8-bit. Total size = TexWidth * TexHeight * 4 - int TexWidth; - int TexHeight; - ImVec2 TexUvWhitePixel; // Texture coordinates to a white pixel (part of the TexExtraData block) - ImVector Fonts; - - // Private - struct ImFontAtlasData; - ImVector InputData; // Internal data - IMGUI_API bool Build(); // Build pixels data. This is automatically for you by the GetTexData*** functions. - IMGUI_API void ClearInputData(); // Clear the input TTF data. - IMGUI_API void RenderCustomTexData(int pass, void* rects); -}; - -// TTF font loading and rendering -// ImFontAtlas automatically loads a default embedded font for you when you call GetTexDataAsAlpha8() or GetTexDataAsRGBA32(). -// Kerning isn't supported. At the moment some ImGui code does per-character CalcTextSize calls, need something more state-ful. -struct ImFont -{ - // Members: Settings - float FontSize; // // Height of characters, set during loading (don't change after loading) - float Scale; // = 1.0f // Base font scale, multiplied by the per-window font scale which you can adjust with SetFontScale() - ImVec2 DisplayOffset; // = (0.0f,0.0f) // Offset font rendering by xx pixels - ImWchar FallbackChar; // = '?' // Replacement glyph if one isn't found. Only set via SetFallbackChar() - - // Members: Runtime data - struct Glyph - { - ImWchar Codepoint; - signed short XAdvance; - signed short Width, Height; - signed short XOffset, YOffset; - float U0, V0, U1, V1; // Texture coordinates - }; - ImFontAtlas* ContainerAtlas; // What we has been loaded into - ImVector Glyphs; - const Glyph* FallbackGlyph; // == FindGlyph(FontFallbackChar) - float FallbackXAdvance; // - ImVector IndexXAdvance; // Glyphs->XAdvance directly indexable (for CalcTextSize functions which are often bottleneck in large UI) - ImVector IndexLookup; // Index glyphs by Unicode code-point - - // Methods - IMGUI_API ImFont(); - IMGUI_API ~ImFont(); - IMGUI_API void Clear(); - IMGUI_API void BuildLookupTable(); - IMGUI_API const Glyph* FindGlyph(unsigned short c) const; - IMGUI_API void SetFallbackChar(ImWchar c); - IMGUI_API bool IsLoaded() const { return ContainerAtlas != NULL; } - - // 'max_width' stops rendering after a certain width (could be turned into a 2d size). FLT_MAX to disable. - // 'wrap_width' enable automatic word-wrapping across multiple lines to fit into given width. 0.0f to disable. - IMGUI_API ImVec2 CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end = NULL, const char** remaining = NULL) const; // utf8 - IMGUI_API ImVec2 CalcTextSizeW(float size, float max_width, const ImWchar* text_begin, const ImWchar* text_end, const ImWchar** remaining = NULL) const; // wchar - IMGUI_API void RenderText(float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, ImDrawList* draw_list, float wrap_width = 0.0f, const ImVec2* cpu_clip_max = NULL) const; - IMGUI_API const char* CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) const; -}; - -//---- Include imgui_user.h at the end of imgui.h -//---- So you can include code that extends ImGui using any of the types declared above. -//---- (also convenient for user to only explicitly include vanilla imgui.h) -#ifdef IMGUI_INCLUDE_IMGUI_USER_H -#include "imgui_user.h" -#endif +#endif // IMGUI_H diff --git a/testbed/imgui/imguiRenderGL2.cpp b/testbed/imgui/imguiRenderGL2.cpp new file mode 100644 index 00000000..21308219 --- /dev/null +++ b/testbed/imgui/imguiRenderGL2.cpp @@ -0,0 +1,489 @@ +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. +// + +// Source altered and distributed from https://github.com/AdrienHerubel/imguir + +#define _USE_MATH_DEFINES +#include +#include + +#include "imgui.h" + +#include +/*#ifdef __APPLE__ +#include +#else +#include +#endif +*/ + +// Some math headers don't have PI defined. +static const float PI = 3.14159265f; + +void imguifree(void* ptr, void* userptr); +void* imguimalloc(size_t size, void* userptr); + +#define STBTT_malloc(x,y) imguimalloc(x,y) +#define STBTT_free(x,y) imguifree(x,y) +#define STB_TRUETYPE_IMPLEMENTATION +#include "stb_truetype.h" + +void imguifree(void* ptr, void* /*userptr*/) +{ + free(ptr); +} + +void* imguimalloc(size_t size, void* /*userptr*/) +{ + return malloc(size); +} + +static const unsigned TEMP_COORD_COUNT = 100; +static float g_tempCoords[TEMP_COORD_COUNT*2]; +static float g_tempNormals[TEMP_COORD_COUNT*2]; + +static const int CIRCLE_VERTS = 8*4; +static float g_circleVerts[CIRCLE_VERTS*2]; + +static stbtt_bakedchar g_cdata[96]; // ASCII 32..126 is 95 glyphs +static GLuint g_ftex = 0; + +inline unsigned int RGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a) +{ + return (r) | (g << 8) | (b << 16) | (a << 24); +} + +static void drawPolygon(const float* coords, unsigned numCoords, float r, unsigned int col) +{ + if (numCoords > TEMP_COORD_COUNT) numCoords = TEMP_COORD_COUNT; + + for (unsigned i = 0, j = numCoords-1; i < numCoords; j=i++) + { + const float* v0 = &coords[j*2]; + const float* v1 = &coords[i*2]; + float dx = v1[0] - v0[0]; + float dy = v1[1] - v0[1]; + float d = sqrtf(dx*dx+dy*dy); + if (d > 0) + { + d = 1.0f/d; + dx *= d; + dy *= d; + } + g_tempNormals[j*2+0] = dy; + g_tempNormals[j*2+1] = -dx; + } + + for (unsigned i = 0, j = numCoords-1; i < numCoords; j=i++) + { + float dlx0 = g_tempNormals[j*2+0]; + float dly0 = g_tempNormals[j*2+1]; + float dlx1 = g_tempNormals[i*2+0]; + float dly1 = g_tempNormals[i*2+1]; + float dmx = (dlx0 + dlx1) * 0.5f; + float dmy = (dly0 + dly1) * 0.5f; + float dmr2 = dmx*dmx + dmy*dmy; + if (dmr2 > 0.000001f) + { + float scale = 1.0f / dmr2; + if (scale > 10.0f) scale = 10.0f; + dmx *= scale; + dmy *= scale; + } + g_tempCoords[i*2+0] = coords[i*2+0]+dmx*r; + g_tempCoords[i*2+1] = coords[i*2+1]+dmy*r; + } + + unsigned int colTrans = RGBA(col&0xff, (col>>8)&0xff, (col>>16)&0xff, 0); + + glBegin(GL_TRIANGLES); + + glColor4ubv((GLubyte*)&col); + + for (unsigned i = 0, j = numCoords-1; i < numCoords; j=i++) + { + glVertex2fv(&coords[i*2]); + glVertex2fv(&coords[j*2]); + glColor4ubv((GLubyte*)&colTrans); + glVertex2fv(&g_tempCoords[j*2]); + + glVertex2fv(&g_tempCoords[j*2]); + glVertex2fv(&g_tempCoords[i*2]); + + glColor4ubv((GLubyte*)&col); + glVertex2fv(&coords[i*2]); + } + + glColor4ubv((GLubyte*)&col); + for (unsigned i = 2; i < numCoords; ++i) + { + glVertex2fv(&coords[0]); + glVertex2fv(&coords[(i-1)*2]); + glVertex2fv(&coords[i*2]); + } + + glEnd(); +} + +static void drawRect(float x, float y, float w, float h, float fth, unsigned int col) +{ + float verts[4*2] = + { + x+0.5f, y+0.5f, + x+w-0.5f, y+0.5f, + x+w-0.5f, y+h-0.5f, + x+0.5f, y+h-0.5f, + }; + drawPolygon(verts, 4, fth, col); +} + +/* +static void drawEllipse(float x, float y, float w, float h, float fth, unsigned int col) +{ + float verts[CIRCLE_VERTS*2]; + const float* cverts = g_circleVerts; + float* v = verts; + + for (int i = 0; i < CIRCLE_VERTS; ++i) + { + *v++ = x + cverts[i*2]*w; + *v++ = y + cverts[i*2+1]*h; + } + + drawPolygon(verts, CIRCLE_VERTS, fth, col); +} +*/ + +static void drawRoundedRect(float x, float y, float w, float h, float r, float fth, unsigned int col) +{ + const unsigned n = CIRCLE_VERTS/4; + float verts[(n+1)*4*2]; + const float* cverts = g_circleVerts; + float* v = verts; + + for (unsigned i = 0; i <= n; ++i) + { + *v++ = x+w-r + cverts[i*2]*r; + *v++ = y+h-r + cverts[i*2+1]*r; + } + + for (unsigned i = n; i <= n*2; ++i) + { + *v++ = x+r + cverts[i*2]*r; + *v++ = y+h-r + cverts[i*2+1]*r; + } + + for (unsigned i = n*2; i <= n*3; ++i) + { + *v++ = x+r + cverts[i*2]*r; + *v++ = y+r + cverts[i*2+1]*r; + } + + for (unsigned i = n*3; i < n*4; ++i) + { + *v++ = x+w-r + cverts[i*2]*r; + *v++ = y+r + cverts[i*2+1]*r; + } + *v++ = x+w-r + cverts[0]*r; + *v++ = y+r + cverts[1]*r; + + drawPolygon(verts, (n+1)*4, fth, col); +} + + +static void drawLine(float x0, float y0, float x1, float y1, float r, float fth, unsigned int col) +{ + float dx = x1-x0; + float dy = y1-y0; + float d = sqrtf(dx*dx+dy*dy); + if (d > 0.0001f) + { + d = 1.0f/d; + dx *= d; + dy *= d; + } + float nx = dy; + float ny = -dx; + float verts[4*2]; + r -= fth; + r *= 0.5f; + if (r < 0.01f) r = 0.01f; + dx *= r; + dy *= r; + nx *= r; + ny *= r; + + verts[0] = x0-dx-nx; + verts[1] = y0-dy-ny; + + verts[2] = x0-dx+nx; + verts[3] = y0-dy+ny; + + verts[4] = x1+dx+nx; + verts[5] = y1+dy+ny; + + verts[6] = x1+dx-nx; + verts[7] = y1+dy-ny; + + drawPolygon(verts, 4, fth, col); +} + + +bool imguiRenderGLInit(const char* fontpath) +{ + for (int i = 0; i < CIRCLE_VERTS; ++i) + { + float a = (float)i/(float)CIRCLE_VERTS * PI*2; + g_circleVerts[i*2+0] = cosf(a); + g_circleVerts[i*2+1] = sinf(a); + } + + // Load font. + FILE* fp = fopen(fontpath, "rb"); + if (!fp) return false; + fseek(fp, 0, SEEK_END); + int size = ftell(fp); + fseek(fp, 0, SEEK_SET); + + unsigned char* ttfBuffer = (unsigned char*)malloc(size); + if (!ttfBuffer) + { + fclose(fp); + return false; + } + + fread(ttfBuffer, 1, size, fp); + fclose(fp); + fp = 0; + + unsigned char* bmap = (unsigned char*)malloc(512*512); + if (!bmap) + { + free(ttfBuffer); + return false; + } + + stbtt_BakeFontBitmap(ttfBuffer,0, 15.0f, bmap,512,512, 32,96, g_cdata); + + // can free ttf_buffer at this point + glGenTextures(1, &g_ftex); + glBindTexture(GL_TEXTURE_2D, g_ftex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 512,512, 0, GL_ALPHA, GL_UNSIGNED_BYTE, bmap); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + free(ttfBuffer); + free(bmap); + + return true; +} + +void imguiRenderGLDestroy() +{ + if (g_ftex) + { + glDeleteTextures(1, &g_ftex); + g_ftex = 0; + } +} + +static void getBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, int char_index, + float *xpos, float *ypos, stbtt_aligned_quad *q) +{ + stbtt_bakedchar *b = chardata + char_index; + int round_x = STBTT_ifloor(*xpos + b->xoff); + int round_y = STBTT_ifloor(*ypos - b->yoff); + + q->x0 = (float)round_x; + q->y0 = (float)round_y; + q->x1 = (float)round_x + b->x1 - b->x0; + q->y1 = (float)round_y - b->y1 + b->y0; + + q->s0 = b->x0 / (float)pw; + q->t0 = b->y0 / (float)pw; + q->s1 = b->x1 / (float)ph; + q->t1 = b->y1 / (float)ph; + + *xpos += b->xadvance; +} + +static const float g_tabStops[4] = {150, 210, 270, 330}; + +static float getTextLength(stbtt_bakedchar *chardata, const char* text) +{ + float xpos = 0; + float len = 0; + while (*text) + { + int c = (unsigned char)*text; + if (c == '\t') + { + for (int i = 0; i < 4; ++i) + { + if (xpos < g_tabStops[i]) + { + xpos = g_tabStops[i]; + break; + } + } + } + else if (c >= 32 && c < 128) + { + stbtt_bakedchar *b = chardata + c-32; + int round_x = STBTT_ifloor((xpos + b->xoff) + 0.5); + len = round_x + b->x1 - b->x0 + 0.5f; + xpos += b->xadvance; + } + ++text; + } + return len; +} + +static void drawText(float x, float y, const char *text, int align, unsigned int col) +{ + if (!g_ftex) return; + if (!text) return; + + if (align == IMGUI_ALIGN_CENTER) + x -= getTextLength(g_cdata, text)/2; + else if (align == IMGUI_ALIGN_RIGHT) + x -= getTextLength(g_cdata, text); + + glColor4ub(col&0xff, (col>>8)&0xff, (col>>16)&0xff, (col>>24)&0xff); + + glEnable(GL_TEXTURE_2D); + + // assume orthographic projection with units = screen pixels, origin at top left + glBindTexture(GL_TEXTURE_2D, g_ftex); + + glBegin(GL_TRIANGLES); + + const float ox = x; + + while (*text) + { + int c = (unsigned char)*text; + if (c == '\t') + { + for (int i = 0; i < 4; ++i) + { + if (x < g_tabStops[i]+ox) + { + x = g_tabStops[i]+ox; + break; + } + } + } + else if (c >= 32 && c < 128) + { + stbtt_aligned_quad q; + getBakedQuad(g_cdata, 512,512, c-32, &x,&y,&q); + + glTexCoord2f(q.s0, q.t0); + glVertex2f(q.x0, q.y0); + glTexCoord2f(q.s1, q.t1); + glVertex2f(q.x1, q.y1); + glTexCoord2f(q.s1, q.t0); + glVertex2f(q.x1, q.y0); + + glTexCoord2f(q.s0, q.t0); + glVertex2f(q.x0, q.y0); + glTexCoord2f(q.s0, q.t1); + glVertex2f(q.x0, q.y1); + glTexCoord2f(q.s1, q.t1); + glVertex2f(q.x1, q.y1); + } + ++text; + } + + glEnd(); + glDisable(GL_TEXTURE_2D); +} + +void imguiRenderGLDraw(int width, int height) +{ + const imguiGfxCmd* q = imguiGetRenderQueue(); + int nq = imguiGetRenderQueueSize(); + + const float s = 1.0f/8.0f; + + glDisable(GL_SCISSOR_TEST); + for (int i = 0; i < nq; ++i) + { + const imguiGfxCmd& cmd = q[i]; + if (cmd.type == IMGUI_GFXCMD_RECT) + { + if (cmd.rect.r == 0) + { + drawRect((float)cmd.rect.x*s+0.5f, (float)cmd.rect.y*s+0.5f, + (float)cmd.rect.w*s-1, (float)cmd.rect.h*s-1, + 1.0f, cmd.col); + } + else + { + drawRoundedRect((float)cmd.rect.x*s+0.5f, (float)cmd.rect.y*s+0.5f, + (float)cmd.rect.w*s-1, (float)cmd.rect.h*s-1, + (float)cmd.rect.r*s, 1.0f, cmd.col); + } + } + else if (cmd.type == IMGUI_GFXCMD_LINE) + { + drawLine(cmd.line.x0*s, cmd.line.y0*s, cmd.line.x1*s, cmd.line.y1*s, cmd.line.r*s, 1.0f, cmd.col); + } + else if (cmd.type == IMGUI_GFXCMD_TRIANGLE) + { + if (cmd.flags == 1) + { + const float verts[3*2] = + { + (float)cmd.rect.x*s+0.5f, (float)cmd.rect.y*s+0.5f, + (float)cmd.rect.x*s+0.5f+(float)cmd.rect.w*s-1, (float)cmd.rect.y*s+0.5f+(float)cmd.rect.h*s/2-0.5f, + (float)cmd.rect.x*s+0.5f, (float)cmd.rect.y*s+0.5f+(float)cmd.rect.h*s-1, + }; + drawPolygon(verts, 3, 1.0f, cmd.col); + } + if (cmd.flags == 2) + { + const float verts[3*2] = + { + (float)cmd.rect.x*s+0.5f, (float)cmd.rect.y*s+0.5f+(float)cmd.rect.h*s-1, + (float)cmd.rect.x*s+0.5f+(float)cmd.rect.w*s/2-0.5f, (float)cmd.rect.y*s+0.5f, + (float)cmd.rect.x*s+0.5f+(float)cmd.rect.w*s-1, (float)cmd.rect.y*s+0.5f+(float)cmd.rect.h*s-1, + }; + drawPolygon(verts, 3, 1.0f, cmd.col); + } + } + else if (cmd.type == IMGUI_GFXCMD_TEXT) + { + drawText(cmd.text.x, cmd.text.y, cmd.text.text, cmd.text.align, cmd.col); + } + else if (cmd.type == IMGUI_GFXCMD_SCISSOR) + { + if (cmd.flags) + { + glEnable(GL_SCISSOR_TEST); + glScissor(cmd.rect.x, cmd.rect.y, cmd.rect.w, cmd.rect.h); + } + else + { + glDisable(GL_SCISSOR_TEST); + } + } + } + glDisable(GL_SCISSOR_TEST); +} diff --git a/testbed/imgui/imguiRenderGL2.h b/testbed/imgui/imguiRenderGL2.h new file mode 100644 index 00000000..c36b8045 --- /dev/null +++ b/testbed/imgui/imguiRenderGL2.h @@ -0,0 +1,29 @@ +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. +// + +// Source altered and distributed from https://github.com/AdrienHerubel/imguir + + +#ifndef IMGUI_RENDER_GL_H +#define IMGUI_RENDER_GL_H + +bool imguiRenderGLInit(const char* fontpath); +void imguiRenderGLDestroy(); +void imguiRenderGLDraw(int width, int height); + +#endif // IMGUI_RENDER_GL_H \ No newline at end of file diff --git a/testbed/imgui/imguiRenderGL3.cpp b/testbed/imgui/imguiRenderGL3.cpp new file mode 100644 index 00000000..2a84a6fa --- /dev/null +++ b/testbed/imgui/imguiRenderGL3.cpp @@ -0,0 +1,695 @@ +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. +// + +// Source altered and distributed from https://github.com/AdrienHerubel/imgui + + +#define _USE_MATH_DEFINES +#include +#include + +#include +/*#ifdef __APPLE__ +#include +#else +#include +#endif +*/ + +#include "imgui.h" + +// Some math headers don't have PI defined. +static const float PI = 3.14159265f; + +void imguifree(void* ptr, void* userptr); +void* imguimalloc(size_t size, void* userptr); + +#define STBTT_malloc(x,y) imguimalloc(x,y) +#define STBTT_free(x,y) imguifree(x,y) +#define STB_TRUETYPE_IMPLEMENTATION +#include "stb_truetype.h" + +void imguifree(void* ptr, void* /*userptr*/) +{ + free(ptr); +} + +void* imguimalloc(size_t size, void* /*userptr*/) +{ + return malloc(size); +} + +static const unsigned TEMP_COORD_COUNT = 100; +static float g_tempCoords[TEMP_COORD_COUNT*2]; +static float g_tempNormals[TEMP_COORD_COUNT*2]; +static float g_tempVertices[TEMP_COORD_COUNT * 12 + (TEMP_COORD_COUNT - 2) * 6]; +static float g_tempTextureCoords[TEMP_COORD_COUNT * 12 + (TEMP_COORD_COUNT - 2) * 6]; +static float g_tempColors[TEMP_COORD_COUNT * 24 + (TEMP_COORD_COUNT - 2) * 12]; + +static const int CIRCLE_VERTS = 8*4; +static float g_circleVerts[CIRCLE_VERTS*2]; + +static stbtt_bakedchar g_cdata[96]; // ASCII 32..126 is 95 glyphs +static GLuint g_ftex = 0; +static GLuint g_whitetex = 0; +static GLuint g_vao = 0; +static GLuint g_vbos[3] = {0, 0, 0}; +static GLuint g_program = 0; +static GLuint g_programViewportLocation = 0; +static GLuint g_programTextureLocation = 0; + +inline unsigned int RGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a) +{ + return (r) | (g << 8) | (b << 16) | (a << 24); +} + +static void drawPolygon(const float* coords, unsigned numCoords, float r, unsigned int col) +{ + if (numCoords > TEMP_COORD_COUNT) numCoords = TEMP_COORD_COUNT; + + for (unsigned i = 0, j = numCoords-1; i < numCoords; j=i++) + { + const float* v0 = &coords[j*2]; + const float* v1 = &coords[i*2]; + float dx = v1[0] - v0[0]; + float dy = v1[1] - v0[1]; + float d = sqrtf(dx*dx+dy*dy); + if (d > 0) + { + d = 1.0f/d; + dx *= d; + dy *= d; + } + g_tempNormals[j*2+0] = dy; + g_tempNormals[j*2+1] = -dx; + } + + float colf[4] = { (float) (col&0xff) / 255.f, (float) ((col>>8)&0xff) / 255.f, (float) ((col>>16)&0xff) / 255.f, (float) ((col>>24)&0xff) / 255.f}; + float colTransf[4] = { (float) (col&0xff) / 255.f, (float) ((col>>8)&0xff) / 255.f, (float) ((col>>16)&0xff) / 255.f, 0}; + + for (unsigned i = 0, j = numCoords-1; i < numCoords; j=i++) + { + float dlx0 = g_tempNormals[j*2+0]; + float dly0 = g_tempNormals[j*2+1]; + float dlx1 = g_tempNormals[i*2+0]; + float dly1 = g_tempNormals[i*2+1]; + float dmx = (dlx0 + dlx1) * 0.5f; + float dmy = (dly0 + dly1) * 0.5f; + float dmr2 = dmx*dmx + dmy*dmy; + if (dmr2 > 0.000001f) + { + float scale = 1.0f / dmr2; + if (scale > 10.0f) scale = 10.0f; + dmx *= scale; + dmy *= scale; + } + g_tempCoords[i*2+0] = coords[i*2+0]+dmx*r; + g_tempCoords[i*2+1] = coords[i*2+1]+dmy*r; + } + + int vSize = numCoords * 12 + (numCoords - 2) * 6; + int uvSize = numCoords * 2 * 6 + (numCoords - 2) * 2 * 3; + int cSize = numCoords * 4 * 6 + (numCoords - 2) * 4 * 3; + float * v = g_tempVertices; + float * uv = g_tempTextureCoords; + memset(uv, 0, uvSize * sizeof(float)); + float * c = g_tempColors; + memset(c, 1, cSize * sizeof(float)); + + float * ptrV = v; + float * ptrC = c; + for (unsigned i = 0, j = numCoords-1; i < numCoords; j=i++) + { + *ptrV = coords[i*2]; + *(ptrV+1) = coords[i*2 + 1]; + ptrV += 2; + *ptrV = coords[j*2]; + *(ptrV+1) = coords[j*2 + 1]; + ptrV += 2; + *ptrV = g_tempCoords[j*2]; + *(ptrV+1) = g_tempCoords[j*2 + 1]; + ptrV += 2; + *ptrV = g_tempCoords[j*2]; + *(ptrV+1) = g_tempCoords[j*2 + 1]; + ptrV += 2; + *ptrV = g_tempCoords[i*2]; + *(ptrV+1) = g_tempCoords[i*2 + 1]; + ptrV += 2; + *ptrV = coords[i*2]; + *(ptrV+1) = coords[i*2 + 1]; + ptrV += 2; + + *ptrC = colf[0]; + *(ptrC+1) = colf[1]; + *(ptrC+2) = colf[2]; + *(ptrC+3) = colf[3]; + ptrC += 4; + *ptrC = colf[0]; + *(ptrC+1) = colf[1]; + *(ptrC+2) = colf[2]; + *(ptrC+3) = colf[3]; + ptrC += 4; + *ptrC = colTransf[0]; + *(ptrC+1) = colTransf[1]; + *(ptrC+2) = colTransf[2]; + *(ptrC+3) = colTransf[3]; + ptrC += 4; + *ptrC = colTransf[0]; + *(ptrC+1) = colTransf[1]; + *(ptrC+2) = colTransf[2]; + *(ptrC+3) = colTransf[3]; + ptrC += 4; + *ptrC = colTransf[0]; + *(ptrC+1) = colTransf[1]; + *(ptrC+2) = colTransf[2]; + *(ptrC+3) = colTransf[3]; + ptrC += 4; + *ptrC = colf[0]; + *(ptrC+1) = colf[1]; + *(ptrC+2) = colf[2]; + *(ptrC+3) = colf[3]; + ptrC += 4; + } + + for (unsigned i = 2; i < numCoords; ++i) + { + *ptrV = coords[0]; + *(ptrV+1) = coords[1]; + ptrV += 2; + *ptrV = coords[(i-1)*2]; + *(ptrV+1) = coords[(i-1)*2+1]; + ptrV += 2; + *ptrV = coords[i*2]; + *(ptrV+1) = coords[i*2 + 1]; + ptrV += 2; + + *ptrC = colf[0]; + *(ptrC+1) = colf[1]; + *(ptrC+2) = colf[2]; + *(ptrC+3) = colf[3]; + ptrC += 4; + *ptrC = colf[0]; + *(ptrC+1) = colf[1]; + *(ptrC+2) = colf[2]; + *(ptrC+3) = colf[3]; + ptrC += 4; + *ptrC = colf[0]; + *(ptrC+1) = colf[1]; + *(ptrC+2) = colf[2]; + *(ptrC+3) = colf[3]; + ptrC += 4; + } + glBindTexture(GL_TEXTURE_2D, g_whitetex); + + glBindVertexArray(g_vao); + glBindBuffer(GL_ARRAY_BUFFER, g_vbos[0]); + glBufferData(GL_ARRAY_BUFFER, vSize*sizeof(float), v, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, g_vbos[1]); + glBufferData(GL_ARRAY_BUFFER, uvSize*sizeof(float), uv, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, g_vbos[2]); + glBufferData(GL_ARRAY_BUFFER, cSize*sizeof(float), c, GL_STATIC_DRAW); + glDrawArrays(GL_TRIANGLES, 0, (numCoords * 2 + numCoords - 2)*3); + +} + +static void drawRect(float x, float y, float w, float h, float fth, unsigned int col) +{ + float verts[4*2] = + { + x+0.5f, y+0.5f, + x+w-0.5f, y+0.5f, + x+w-0.5f, y+h-0.5f, + x+0.5f, y+h-0.5f, + }; + drawPolygon(verts, 4, fth, col); +} + +/* +static void drawEllipse(float x, float y, float w, float h, float fth, unsigned int col) +{ + float verts[CIRCLE_VERTS*2]; + const float* cverts = g_circleVerts; + float* v = verts; + + for (int i = 0; i < CIRCLE_VERTS; ++i) + { + *v++ = x + cverts[i*2]*w; + *v++ = y + cverts[i*2+1]*h; + } + + drawPolygon(verts, CIRCLE_VERTS, fth, col); +} +*/ + +static void drawRoundedRect(float x, float y, float w, float h, float r, float fth, unsigned int col) +{ + const unsigned n = CIRCLE_VERTS/4; + float verts[(n+1)*4*2]; + const float* cverts = g_circleVerts; + float* v = verts; + + for (unsigned i = 0; i <= n; ++i) + { + *v++ = x+w-r + cverts[i*2]*r; + *v++ = y+h-r + cverts[i*2+1]*r; + } + + for (unsigned i = n; i <= n*2; ++i) + { + *v++ = x+r + cverts[i*2]*r; + *v++ = y+h-r + cverts[i*2+1]*r; + } + + for (unsigned i = n*2; i <= n*3; ++i) + { + *v++ = x+r + cverts[i*2]*r; + *v++ = y+r + cverts[i*2+1]*r; + } + + for (unsigned i = n*3; i < n*4; ++i) + { + *v++ = x+w-r + cverts[i*2]*r; + *v++ = y+r + cverts[i*2+1]*r; + } + *v++ = x+w-r + cverts[0]*r; + *v++ = y+r + cverts[1]*r; + + drawPolygon(verts, (n+1)*4, fth, col); +} + + +static void drawLine(float x0, float y0, float x1, float y1, float r, float fth, unsigned int col) +{ + float dx = x1-x0; + float dy = y1-y0; + float d = sqrtf(dx*dx+dy*dy); + if (d > 0.0001f) + { + d = 1.0f/d; + dx *= d; + dy *= d; + } + float nx = dy; + float ny = -dx; + float verts[4*2]; + r -= fth; + r *= 0.5f; + if (r < 0.01f) r = 0.01f; + dx *= r; + dy *= r; + nx *= r; + ny *= r; + + verts[0] = x0-dx-nx; + verts[1] = y0-dy-ny; + + verts[2] = x0-dx+nx; + verts[3] = y0-dy+ny; + + verts[4] = x1+dx+nx; + verts[5] = y1+dy+ny; + + verts[6] = x1+dx-nx; + verts[7] = y1+dy-ny; + + drawPolygon(verts, 4, fth, col); +} + + +bool imguiRenderGLInit(const char* fontpath) +{ + for (int i = 0; i < CIRCLE_VERTS; ++i) + { + float a = (float)i/(float)CIRCLE_VERTS * PI*2; + g_circleVerts[i*2+0] = cosf(a); + g_circleVerts[i*2+1] = sinf(a); + } + + // Load font. + FILE* fp = fopen(fontpath, "rb"); + if (!fp) return false; + fseek(fp, 0, SEEK_END); + int size = ftell(fp); + fseek(fp, 0, SEEK_SET); + + unsigned char* ttfBuffer = (unsigned char*)malloc(size); + if (!ttfBuffer) + { + fclose(fp); + return false; + } + + fread(ttfBuffer, 1, size, fp); + fclose(fp); + fp = 0; + + unsigned char* bmap = (unsigned char*)malloc(512*512); + if (!bmap) + { + free(ttfBuffer); + return false; + } + + stbtt_BakeFontBitmap(ttfBuffer,0, FONT_HEIGHT, bmap,512,512, 32,96, g_cdata); + + // can free ttf_buffer at this point + glGenTextures(1, &g_ftex); + glBindTexture(GL_TEXTURE_2D, g_ftex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, 512,512, 0, GL_RED, GL_UNSIGNED_BYTE, bmap); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + // can free ttf_buffer at this point + unsigned char white_alpha = 255; + glGenTextures(1, &g_whitetex); + glBindTexture(GL_TEXTURE_2D, g_whitetex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, 1, 1, 0, GL_RED, GL_UNSIGNED_BYTE, &white_alpha); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glGenVertexArrays(1, &g_vao); + glGenBuffers(3, g_vbos); + + glBindVertexArray(g_vao); + glEnableVertexAttribArray(0); + glEnableVertexAttribArray(1); + glEnableVertexAttribArray(2); + + glBindBuffer(GL_ARRAY_BUFFER, g_vbos[0]); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT)*2, (void*)0); + glBufferData(GL_ARRAY_BUFFER, 0, 0, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, g_vbos[1]); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT)*2, (void*)0); + glBufferData(GL_ARRAY_BUFFER, 0, 0, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, g_vbos[2]); + glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT)*4, (void*)0); + glBufferData(GL_ARRAY_BUFFER, 0, 0, GL_STATIC_DRAW); + g_program = glCreateProgram(); + + const char * vs = + "#version 150\n" + "uniform vec2 Viewport;\n" + "in vec2 VertexPosition;\n" + "in vec2 VertexTexCoord;\n" + "in vec4 VertexColor;\n" + "out vec2 texCoord;\n" + "out vec4 vertexColor;\n" + "void main(void)\n" + "{\n" + " vertexColor = VertexColor;\n" + " texCoord = VertexTexCoord;\n" + " gl_Position = vec4(VertexPosition * 2.0 / Viewport - 1.0, 0.f, 1.0);\n" + "}\n"; + GLuint vso = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vso, 1, (const char **) &vs, NULL); + glCompileShader(vso); + glAttachShader(g_program, vso); + + const char * fs = + "#version 150\n" + "in vec2 texCoord;\n" + "in vec4 vertexColor;\n" + "uniform sampler2D Texture;\n" + "out vec4 Color;\n" + "void main(void)\n" + "{\n" + " float alpha = texture(Texture, texCoord).r;\n" + " Color = vec4(vertexColor.rgb, vertexColor.a * alpha);\n" + "}\n"; + GLuint fso = glCreateShader(GL_FRAGMENT_SHADER); + + glShaderSource(fso, 1, (const char **) &fs, NULL); + glCompileShader(fso); + glAttachShader(g_program, fso); + + glBindAttribLocation(g_program, 0, "VertexPosition"); + glBindAttribLocation(g_program, 1, "VertexTexCoord"); + glBindAttribLocation(g_program, 2, "VertexColor"); + glBindFragDataLocation(g_program, 0, "Color"); + glLinkProgram(g_program); + glDeleteShader(vso); + glDeleteShader(fso); + + glUseProgram(g_program); + g_programViewportLocation = glGetUniformLocation(g_program, "Viewport"); + g_programTextureLocation = glGetUniformLocation(g_program, "Texture"); + + glUseProgram(0); + + + free(ttfBuffer); + free(bmap); + + return true; +} + +void imguiRenderGLDestroy() +{ + if (g_ftex) + { + glDeleteTextures(1, &g_ftex); + g_ftex = 0; + } + + if (g_vao) + { + glDeleteVertexArrays(1, &g_vao); + glDeleteBuffers(3, g_vbos); + g_vao = 0; + } + + if (g_program) + { + glDeleteProgram(g_program); + g_program = 0; + } + +} + +static void getBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, int char_index, + float *xpos, float *ypos, stbtt_aligned_quad *q) +{ + stbtt_bakedchar *b = chardata + char_index; + int round_x = STBTT_ifloor(*xpos + b->xoff); + int round_y = STBTT_ifloor(*ypos - b->yoff); + + q->x0 = (float)round_x; + q->y0 = (float)round_y; + q->x1 = (float)round_x + b->x1 - b->x0; + q->y1 = (float)round_y - b->y1 + b->y0; + + q->s0 = b->x0 / (float)pw; + q->t0 = b->y0 / (float)pw; + q->s1 = b->x1 / (float)ph; + q->t1 = b->y1 / (float)ph; + + *xpos += b->xadvance; +} + +static const float g_tabStops[4] = {150, 210, 270, 330}; + +static float getTextLength(stbtt_bakedchar *chardata, const char* text) +{ + float xpos = 0; + float len = 0; + while (*text) + { + int c = (unsigned char)*text; + if (c == '\t') + { + for (int i = 0; i < 4; ++i) + { + if (xpos < g_tabStops[i]) + { + xpos = g_tabStops[i]; + break; + } + } + } + else if (c >= 32 && c < 128) + { + stbtt_bakedchar *b = chardata + c-32; + int round_x = STBTT_ifloor((xpos + b->xoff) + 0.5); + len = round_x + b->x1 - b->x0 + 0.5f; + xpos += b->xadvance; + } + ++text; + } + return len; +} + +static void drawText(float x, float y, const char *text, int align, unsigned int col) +{ + if (!g_ftex) return; + if (!text) return; + + if (align == IMGUI_ALIGN_CENTER) + x -= getTextLength(g_cdata, text)/2; + else if (align == IMGUI_ALIGN_RIGHT) + x -= getTextLength(g_cdata, text); + + float r = (float) (col&0xff) / 255.f; + float g = (float) ((col>>8)&0xff) / 255.f; + float b = (float) ((col>>16)&0xff) / 255.f; + float a = (float) ((col>>24)&0xff) / 255.f; + + // assume orthographic projection with units = screen pixels, origin at top left + glBindTexture(GL_TEXTURE_2D, g_ftex); + + const float ox = x; + + while (*text) + { + int c = (unsigned char)*text; + if (c == '\t') + { + for (int i = 0; i < 4; ++i) + { + if (x < g_tabStops[i]+ox) + { + x = g_tabStops[i]+ox; + break; + } + } + } + else if (c >= 32 && c < 128) + { + stbtt_aligned_quad q; + getBakedQuad(g_cdata, 512,512, c-32, &x,&y,&q); + + float v[12] = { + q.x0, q.y0, + q.x1, q.y1, + q.x1, q.y0, + q.x0, q.y0, + q.x0, q.y1, + q.x1, q.y1, + }; + float uv[12] = { + q.s0, q.t0, + q.s1, q.t1, + q.s1, q.t0, + q.s0, q.t0, + q.s0, q.t1, + q.s1, q.t1, + }; + float c[24] = { + r, g, b, a, + r, g, b, a, + r, g, b, a, + r, g, b, a, + r, g, b, a, + r, g, b, a, + }; + glBindVertexArray(g_vao); + glBindBuffer(GL_ARRAY_BUFFER, g_vbos[0]); + glBufferData(GL_ARRAY_BUFFER, 12*sizeof(float), v, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, g_vbos[1]); + glBufferData(GL_ARRAY_BUFFER, 12*sizeof(float), uv, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, g_vbos[2]); + glBufferData(GL_ARRAY_BUFFER, 24*sizeof(float), c, GL_STATIC_DRAW); + glDrawArrays(GL_TRIANGLES, 0, 6); + + } + ++text; + } + + //glEnd(); + //glDisable(GL_TEXTURE_2D); +} + + +void imguiRenderGLDraw(int width, int height) +{ + const imguiGfxCmd* q = imguiGetRenderQueue(); + int nq = imguiGetRenderQueueSize(); + + const float s = 1.0f/8.0f; + + glViewport(0, 0, width, height); + glUseProgram(g_program); + glActiveTexture(GL_TEXTURE0); + glUniform2f(g_programViewportLocation, (float) width, (float) height); + glUniform1i(g_programTextureLocation, 0); + + + glDisable(GL_SCISSOR_TEST); + for (int i = 0; i < nq; ++i) + { + const imguiGfxCmd& cmd = q[i]; + if (cmd.type == IMGUI_GFXCMD_RECT) + { + if (cmd.rect.r == 0) + { + drawRect((float)cmd.rect.x*s+0.5f, (float)cmd.rect.y*s+0.5f, + (float)cmd.rect.w*s-1, (float)cmd.rect.h*s-1, + 1.0f, cmd.col); + } + else + { + drawRoundedRect((float)cmd.rect.x*s+0.5f, (float)cmd.rect.y*s+0.5f, + (float)cmd.rect.w*s-1, (float)cmd.rect.h*s-1, + (float)cmd.rect.r*s, 1.0f, cmd.col); + } + } + else if (cmd.type == IMGUI_GFXCMD_LINE) + { + drawLine(cmd.line.x0*s, cmd.line.y0*s, cmd.line.x1*s, cmd.line.y1*s, cmd.line.r*s, 1.0f, cmd.col); + } + else if (cmd.type == IMGUI_GFXCMD_TRIANGLE) + { + if (cmd.flags == 1) + { + const float verts[3*2] = + { + (float)cmd.rect.x*s+0.5f, (float)cmd.rect.y*s+0.5f, + (float)cmd.rect.x*s+0.5f+(float)cmd.rect.w*s-1, (float)cmd.rect.y*s+0.5f+(float)cmd.rect.h*s/2-0.5f, + (float)cmd.rect.x*s+0.5f, (float)cmd.rect.y*s+0.5f+(float)cmd.rect.h*s-1, + }; + drawPolygon(verts, 3, 1.0f, cmd.col); + } + if (cmd.flags == 2) + { + const float verts[3*2] = + { + (float)cmd.rect.x*s+0.5f, (float)cmd.rect.y*s+0.5f+(float)cmd.rect.h*s-1, + (float)cmd.rect.x*s+0.5f+(float)cmd.rect.w*s/2-0.5f, (float)cmd.rect.y*s+0.5f, + (float)cmd.rect.x*s+0.5f+(float)cmd.rect.w*s-1, (float)cmd.rect.y*s+0.5f+(float)cmd.rect.h*s-1, + }; + drawPolygon(verts, 3, 1.0f, cmd.col); + } + } + else if (cmd.type == IMGUI_GFXCMD_TEXT) + { + drawText(cmd.text.x, cmd.text.y, cmd.text.text, cmd.text.align, cmd.col); + } + else if (cmd.type == IMGUI_GFXCMD_SCISSOR) + { + if (cmd.flags) + { + glEnable(GL_SCISSOR_TEST); + glScissor(cmd.rect.x, cmd.rect.y, cmd.rect.w, cmd.rect.h); + } + else + { + glDisable(GL_SCISSOR_TEST); + } + } + } + glDisable(GL_SCISSOR_TEST); +} diff --git a/testbed/imgui/imguiRenderGL3.h b/testbed/imgui/imguiRenderGL3.h new file mode 100644 index 00000000..6c84a043 --- /dev/null +++ b/testbed/imgui/imguiRenderGL3.h @@ -0,0 +1,28 @@ +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. +// + +// Source altered and distributed from https://github.com/AdrienHerubel/imgui + +#ifndef IMGUI_RENDER_GL_H +#define IMGUI_RENDER_GL_H + +bool imguiRenderGLInit(const char* fontpath); +void imguiRenderGLDestroy(); +void imguiRenderGLDraw(int width, int height); + +#endif // IMGUI_RENDER_GL_H \ No newline at end of file diff --git a/testbed/imgui/stb_rect_pack.h b/testbed/imgui/stb_rect_pack.h deleted file mode 100644 index eb0ef2f2..00000000 --- a/testbed/imgui/stb_rect_pack.h +++ /dev/null @@ -1,547 +0,0 @@ -// stb_rect_pack.h - v0.05 - public domain - rectangle packing -// Sean Barrett 2014 -// -// Useful for e.g. packing rectangular textures into an atlas. -// Does not do rotation. -// -// Not necessarily the awesomest packing method, but better than -// the totally naive one in stb_truetype (which is primarily what -// this is meant to replace). -// -// Has only had a few tests run, may have issues. -// -// More docs to come. -// -// No memory allocations; uses qsort() and assert() from stdlib. -// -// This library currently uses the Skyline Bottom-Left algorithm. -// -// Please note: better rectangle packers are welcome! Please -// implement them to the same API, but with a different init -// function. -// -// Version history: -// -// 0.05: added STBRP_ASSERT to allow replacing assert -// 0.04: fixed minor bug in STBRP_LARGE_RECTS support -// 0.01: initial release - -////////////////////////////////////////////////////////////////////////////// -// -// INCLUDE SECTION -// - -#ifndef STB_INCLUDE_STB_RECT_PACK_H -#define STB_INCLUDE_STB_RECT_PACK_H - -#define STB_RECT_PACK_VERSION 1 - -#ifdef STBRP_STATIC -#define STBRP_DEF static -#else -#define STBRP_DEF extern -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct stbrp_context stbrp_context; -typedef struct stbrp_node stbrp_node; -typedef struct stbrp_rect stbrp_rect; - -#ifdef STBRP_LARGE_RECTS -typedef int stbrp_coord; -#else -typedef unsigned short stbrp_coord; -#endif - -STBRP_DEF void stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects); -// Assign packed locations to rectangles. The rectangles are of type -// 'stbrp_rect' defined below, stored in the array 'rects', and there -// are 'num_rects' many of them. -// -// Rectangles which are successfully packed have the 'was_packed' flag -// set to a non-zero value and 'x' and 'y' store the minimum location -// on each axis (i.e. bottom-left in cartesian coordinates, top-left -// if you imagine y increasing downwards). Rectangles which do not fit -// have the 'was_packed' flag set to 0. -// -// You should not try to access the 'rects' array from another thread -// while this function is running, as the function temporarily reorders -// the array while it executes. -// -// To pack into another rectangle, you need to call stbrp_init_target -// again. To continue packing into the same rectangle, you can call -// this function again. Calling this multiple times with multiple rect -// arrays will probably produce worse packing results than calling it -// a single time with the full rectangle array, but the option is -// available. - -struct stbrp_rect -{ - // reserved for your use: - int id; - - // input: - stbrp_coord w, h; - - // output: - stbrp_coord x, y; - int was_packed; // non-zero if valid packing - -}; // 16 bytes, nominally - - -STBRP_DEF void stbrp_init_target (stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes); -// Initialize a rectangle packer to: -// pack a rectangle that is 'width' by 'height' in dimensions -// using temporary storage provided by the array 'nodes', which is 'num_nodes' long -// -// You must call this function every time you start packing into a new target. -// -// There is no "shutdown" function. The 'nodes' memory must stay valid for -// the following stbrp_pack_rects() call (or calls), but can be freed after -// the call (or calls) finish. -// -// Note: to guarantee best results, either: -// 1. make sure 'num_nodes' >= 'width' -// or 2. call stbrp_allow_out_of_mem() defined below with 'allow_out_of_mem = 1' -// -// If you don't do either of the above things, widths will be quantized to multiples -// of small integers to guarantee the algorithm doesn't run out of temporary storage. -// -// If you do #2, then the non-quantized algorithm will be used, but the algorithm -// may run out of temporary storage and be unable to pack some rectangles. - -STBRP_DEF void stbrp_setup_allow_out_of_mem (stbrp_context *context, int allow_out_of_mem); -// Optionally call this function after init but before doing any packing to -// change the handling of the out-of-temp-memory scenario, described above. -// If you call init again, this will be reset to the default (false). - - -STBRP_DEF void stbrp_setup_heuristic (stbrp_context *context, int heuristic); -// Optionally select which packing heuristic the library should use. Different -// heuristics will produce better/worse results for different data sets. -// If you call init again, this will be reset to the default. - -enum -{ - STBRP_HEURISTIC_Skyline_default=0, - STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default, - STBRP_HEURISTIC_Skyline_BF_sortHeight -}; - - -////////////////////////////////////////////////////////////////////////////// -// -// the details of the following structures don't matter to you, but they must -// be visible so you can handle the memory allocations for them - -struct stbrp_node -{ - stbrp_coord x,y; - stbrp_node *next; -}; - -struct stbrp_context -{ - int width; - int height; - int align; - int init_mode; - int heuristic; - int num_nodes; - stbrp_node *active_head; - stbrp_node *free_head; - stbrp_node extra[2]; // we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2' -}; - -#ifdef __cplusplus -} -#endif - -#endif - -////////////////////////////////////////////////////////////////////////////// -// -// IMPLEMENTATION SECTION -// - -#ifdef STB_RECT_PACK_IMPLEMENTATION -#include - -#ifndef STBRP_ASSERT -#include -#define STBRP_ASSERT assert -#endif - -enum -{ - STBRP__INIT_skyline = 1 -}; - -STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic) -{ - switch (context->init_mode) { - case STBRP__INIT_skyline: - STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight); - context->heuristic = heuristic; - break; - default: - STBRP_ASSERT(0); - } -} - -STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_out_of_mem) -{ - if (allow_out_of_mem) - // if it's ok to run out of memory, then don't bother aligning them; - // this gives better packing, but may fail due to OOM (even though - // the rectangles easily fit). @TODO a smarter approach would be to only - // quantize once we've hit OOM, then we could get rid of this parameter. - context->align = 1; - else { - // if it's not ok to run out of memory, then quantize the widths - // so that num_nodes is always enough nodes. - // - // I.e. num_nodes * align >= width - // align >= width / num_nodes - // align = ceil(width/num_nodes) - - context->align = (context->width + context->num_nodes-1) / context->num_nodes; - } -} - -STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes) -{ - int i; -#ifndef STBRP_LARGE_RECTS - STBRP_ASSERT(width <= 0xffff && height <= 0xffff); -#endif - - for (i=0; i < num_nodes-1; ++i) - nodes[i].next = &nodes[i+1]; - nodes[i].next = NULL; - context->init_mode = STBRP__INIT_skyline; - context->heuristic = STBRP_HEURISTIC_Skyline_default; - context->free_head = &nodes[0]; - context->active_head = &context->extra[0]; - context->width = width; - context->height = height; - context->num_nodes = num_nodes; - stbrp_setup_allow_out_of_mem(context, 0); - - // node 0 is the full width, node 1 is the sentinel (lets us not store width explicitly) - context->extra[0].x = 0; - context->extra[0].y = 0; - context->extra[0].next = &context->extra[1]; - context->extra[1].x = (stbrp_coord) width; -#ifdef STBRP_LARGE_RECTS - context->extra[1].y = (1<<30); -#else - context->extra[1].y = 65535; -#endif - context->extra[1].next = NULL; -} - -// find minimum y position if it starts at x1 -static int stbrp__skyline_find_min_y(stbrp_context *c, stbrp_node *first, int x0, int width, int *pwaste) -{ - (void)c; - stbrp_node *node = first; - int x1 = x0 + width; - int min_y, visited_width, waste_area; - STBRP_ASSERT(first->x <= x0); - - #if 0 - // skip in case we're past the node - while (node->next->x <= x0) - ++node; - #else - STBRP_ASSERT(node->next->x > x0); // we ended up handling this in the caller for efficiency - #endif - - STBRP_ASSERT(node->x <= x0); - - min_y = 0; - waste_area = 0; - visited_width = 0; - while (node->x < x1) { - if (node->y > min_y) { - // raise min_y higher. - // we've accounted for all waste up to min_y, - // but we'll now add more waste for everything we've visted - waste_area += visited_width * (node->y - min_y); - min_y = node->y; - // the first time through, visited_width might be reduced - if (node->x < x0) - visited_width += node->next->x - x0; - else - visited_width += node->next->x - node->x; - } else { - // add waste area - int under_width = node->next->x - node->x; - if (under_width + visited_width > width) - under_width = width - visited_width; - waste_area += under_width * (min_y - node->y); - visited_width += under_width; - } - node = node->next; - } - - *pwaste = waste_area; - return min_y; -} - -typedef struct -{ - int x,y; - stbrp_node **prev_link; -} stbrp__findresult; - -static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int width, int height) -{ - int best_waste = (1<<30), best_x, best_y = (1 << 30); - stbrp__findresult fr; - stbrp_node **prev, *node, *tail, **best = NULL; - - // align to multiple of c->align - width = (width + c->align - 1); - width -= width % c->align; - STBRP_ASSERT(width % c->align == 0); - - node = c->active_head; - prev = &c->active_head; - while (node->x + width <= c->width) { - int y,waste; - y = stbrp__skyline_find_min_y(c, node, node->x, width, &waste); - if (c->heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight) { // actually just want to test BL - // bottom left - if (y < best_y) { - best_y = y; - best = prev; - } - } else { - // best-fit - if (y + height <= c->height) { - // can only use it if it first vertically - if (y < best_y || (y == best_y && waste < best_waste)) { - best_y = y; - best_waste = waste; - best = prev; - } - } - } - prev = &node->next; - node = node->next; - } - - best_x = (best == NULL) ? 0 : (*best)->x; - - // if doing best-fit (BF), we also have to try aligning right edge to each node position - // - // e.g, if fitting - // - // ____________________ - // |____________________| - // - // into - // - // | | - // | ____________| - // |____________| - // - // then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned - // - // This makes BF take about 2x the time - - if (c->heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight) { - tail = c->active_head; - node = c->active_head; - prev = &c->active_head; - // find first node that's admissible - while (tail->x < width) - tail = tail->next; - while (tail) { - int xpos = tail->x - width; - int y,waste; - STBRP_ASSERT(xpos >= 0); - // find the left position that matches this - while (node->next->x <= xpos) { - prev = &node->next; - node = node->next; - } - STBRP_ASSERT(node->next->x > xpos && node->x <= xpos); - y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste); - if (y + height < c->height) { - if (y <= best_y) { - if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) { - best_x = xpos; - STBRP_ASSERT(y <= best_y); - best_y = y; - best_waste = waste; - best = prev; - } - } - } - tail = tail->next; - } - } - - fr.prev_link = best; - fr.x = best_x; - fr.y = best_y; - return fr; -} - -static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, int width, int height) -{ - // find best position according to heuristic - stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height); - stbrp_node *node, *cur; - - // bail if: - // 1. it failed - // 2. the best node doesn't fit (we don't always check this) - // 3. we're out of memory - if (res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL) { - res.prev_link = NULL; - return res; - } - - // on success, create new node - node = context->free_head; - node->x = (stbrp_coord) res.x; - node->y = (stbrp_coord) (res.y + height); - - context->free_head = node->next; - - // insert the new node into the right starting point, and - // let 'cur' point to the remaining nodes needing to be - // stiched back in - - cur = *res.prev_link; - if (cur->x < res.x) { - // preserve the existing one, so start testing with the next one - stbrp_node *next = cur->next; - cur->next = node; - cur = next; - } else { - *res.prev_link = node; - } - - // from here, traverse cur and free the nodes, until we get to one - // that shouldn't be freed - while (cur->next && cur->next->x <= res.x + width) { - stbrp_node *next = cur->next; - // move the current node to the free list - cur->next = context->free_head; - context->free_head = cur; - cur = next; - } - - // stitch the list back in - node->next = cur; - - if (cur->x < res.x + width) - cur->x = (stbrp_coord) (res.x + width); - -#ifdef _DEBUG - cur = context->active_head; - while (cur->x < context->width) { - STBRP_ASSERT(cur->x < cur->next->x); - cur = cur->next; - } - STBRP_ASSERT(cur->next == NULL); - - { - stbrp_node *L1 = NULL, *L2 = NULL; - int count=0; - cur = context->active_head; - while (cur) { - L1 = cur; - cur = cur->next; - ++count; - } - cur = context->free_head; - while (cur) { - L2 = cur; - cur = cur->next; - ++count; - } - STBRP_ASSERT(count == context->num_nodes+2); - } -#endif - - return res; -} - -static int rect_height_compare(const void *a, const void *b) -{ - stbrp_rect *p = (stbrp_rect *) a; - stbrp_rect *q = (stbrp_rect *) b; - if (p->h > q->h) - return -1; - if (p->h < q->h) - return 1; - return (p->w > q->w) ? -1 : (p->w < q->w); -} - -static int rect_width_compare(const void *a, const void *b) -{ - stbrp_rect *p = (stbrp_rect *) a; - stbrp_rect *q = (stbrp_rect *) b; - if (p->w > q->w) - return -1; - if (p->w < q->w) - return 1; - return (p->h > q->h) ? -1 : (p->h < q->h); -} - -static int rect_original_order(const void *a, const void *b) -{ - stbrp_rect *p = (stbrp_rect *) a; - stbrp_rect *q = (stbrp_rect *) b; - return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed); -} - -#ifdef STBRP_LARGE_RECTS -#define STBRP__MAXVAL 0xffffffff -#else -#define STBRP__MAXVAL 0xffff -#endif - -STBRP_DEF void stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects) -{ - int i; - - // we use the 'was_packed' field internally to allow sorting/unsorting - for (i=0; i < num_rects; ++i) { - rects[i].was_packed = i; - #ifndef STBRP_LARGE_RECTS - STBRP_ASSERT(rects[i].w <= 0xffff && rects[i].h <= 0xffff); - #endif - } - - // sort according to heuristic - qsort(rects, num_rects, sizeof(rects[0]), rect_height_compare); - - for (i=0; i < num_rects; ++i) { - stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h); - if (fr.prev_link) { - rects[i].x = (stbrp_coord) fr.x; - rects[i].y = (stbrp_coord) fr.y; - } else { - rects[i].x = rects[i].y = STBRP__MAXVAL; - } - } - - // unsort - qsort(rects, num_rects, sizeof(rects[0]), rect_original_order); - - // set was_packed flags - for (i=0; i < num_rects; ++i) - rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL); -} -#endif diff --git a/testbed/imgui/stb_textedit.h b/testbed/imgui/stb_textedit.h deleted file mode 100644 index 5aa79f02..00000000 --- a/testbed/imgui/stb_textedit.h +++ /dev/null @@ -1,1254 +0,0 @@ -// stb_textedit.h - v1.4 - public domain - Sean Barrett -// Development of this library was sponsored by RAD Game Tools -// -// This C header file implements the guts of a multi-line text-editing -// widget; you implement display, word-wrapping, and low-level string -// insertion/deletion, and stb_textedit will map user inputs into -// insertions & deletions, plus updates to the cursor position, -// selection state, and undo state. -// -// It is intended for use in games and other systems that need to build -// their own custom widgets and which do not have heavy text-editing -// requirements (this library is not recommended for use for editing large -// texts, as its performance does not scale and it has limited undo). -// -// Non-trivial behaviors are modelled after Windows text controls. -// -// -// LICENSE -// -// This software has been placed in the public domain by its author. -// Where that dedication is not recognized, you are granted a perpetual, -// irrevocable license to copy and modify this file as you see fit. -// -// -// DEPENDENCIES -// -// Uses the C runtime function 'memmove'. Uses no other functions. -// Performs no runtime allocations. -// -// -// VERSION HISTORY -// -// 1.4 (2014-08-17) fix signed/unsigned warnings -// 1.3 (2014-06-19) fix mouse clicking to round to nearest char boundary -// 1.2 (2014-05-27) fix some RAD types that had crept into the new code -// 1.1 (2013-12-15) move-by-word (requires STB_TEXTEDIT_IS_SPACE ) -// 1.0 (2012-07-26) improve documentation, initial public release -// 0.3 (2012-02-24) bugfixes, single-line mode; insert mode -// 0.2 (2011-11-28) fixes to undo/redo -// 0.1 (2010-07-08) initial version -// -// ADDITIONAL CONTRIBUTORS -// -// Ulf Winklemann: move-by-word in 1.1 -// Scott Graham: mouse selection bugfix in 1.3 -// -// USAGE -// -// This file behaves differently depending on what symbols you define -// before including it. -// -// -// Header-file mode: -// -// If you do not define STB_TEXTEDIT_IMPLEMENTATION before including this, -// it will operate in "header file" mode. In this mode, it declares a -// single public symbol, STB_TexteditState, which encapsulates the current -// state of a text widget (except for the string, which you will store -// separately). -// -// To compile in this mode, you must define STB_TEXTEDIT_CHARTYPE to a -// primitive type that defines a single character (e.g. char, wchar_t, etc). -// -// To save space or increase undo-ability, you can optionally define the -// following things that are used by the undo system: -// -// STB_TEXTEDIT_POSITIONTYPE small int type encoding a valid cursor position -// STB_TEXTEDIT_UNDOSTATECOUNT the number of undo states to allow -// STB_TEXTEDIT_UNDOCHARCOUNT the number of characters to store in the undo buffer -// -// If you don't define these, they are set to permissive types and -// moderate sizes. The undo system does no memory allocations, so -// it grows STB_TexteditState by the worst-case storage which is (in bytes): -// -// [4 + sizeof(STB_TEXTEDIT_POSITIONTYPE)] * STB_TEXTEDIT_UNDOSTATE_COUNT -// + sizeof(STB_TEXTEDIT_CHARTYPE) * STB_TEXTEDIT_UNDOCHAR_COUNT -// -// -// Implementation mode: -// -// If you define STB_TEXTEDIT_IMPLEMENTATION before including this, it -// will compile the implementation of the text edit widget, depending -// on a large number of symbols which must be defined before the include. -// -// The implementation is defined only as static functions. You will then -// need to provide your own APIs in the same file which will access the -// static functions. -// -// The basic concept is that you provide a "string" object which -// behaves like an array of characters. stb_textedit uses indices to -// refer to positions in the string, implicitly representing positions -// in the displayed textedit. This is true for both plain text and -// rich text; even with rich text stb_truetype interacts with your -// code as if there was an array of all the displayed characters. -// -// Symbols that must be the same in header-file and implementation mode: -// -// STB_TEXTEDIT_CHARTYPE the character type -// STB_TEXTEDIT_POSITIONTYPE small type that a valid cursor position -// STB_TEXTEDIT_UNDOSTATECOUNT the number of undo states to allow -// STB_TEXTEDIT_UNDOCHARCOUNT the number of characters to store in the undo buffer -// -// Symbols you must define for implementation mode: -// -// STB_TEXTEDIT_STRING the type of object representing a string being edited, -// typically this is a wrapper object with other data you need -// -// STB_TEXTEDIT_STRINGLEN(obj) the length of the string (ideally O(1)) -// STB_TEXTEDIT_LAYOUTROW(&r,obj,n) returns the results of laying out a line of characters -// starting from character #n (see discussion below) -// STB_TEXTEDIT_GETWIDTH(obj,n,i) returns the pixel delta from the xpos of the i'th character -// to the xpos of the i+1'th char for a line of characters -// starting at character #n (i.e. accounts for kerning -// with previous char) -// STB_TEXTEDIT_KEYTOTEXT(k) maps a keyboard input to an insertable character -// (return type is int, -1 means not valid to insert) -// STB_TEXTEDIT_GETCHAR(obj,i) returns the i'th character of obj, 0-based -// STB_TEXTEDIT_NEWLINE the character returned by _GETCHAR() we recognize -// as manually wordwrapping for end-of-line positioning -// -// STB_TEXTEDIT_DELETECHARS(obj,i,n) delete n characters starting at i -// STB_TEXTEDIT_INSERTCHARS(obj,i,c*,n) insert n characters at i (pointed to by STB_TEXTEDIT_CHARTYPE*) -// -// STB_TEXTEDIT_K_SHIFT a power of two that is or'd in to a keyboard input to represent the shift key -// -// STB_TEXTEDIT_K_LEFT keyboard input to move cursor left -// STB_TEXTEDIT_K_RIGHT keyboard input to move cursor right -// STB_TEXTEDIT_K_UP keyboard input to move cursor up -// STB_TEXTEDIT_K_DOWN keyboard input to move cursor down -// STB_TEXTEDIT_K_LINESTART keyboard input to move cursor to start of line // e.g. HOME -// STB_TEXTEDIT_K_LINEEND keyboard input to move cursor to end of line // e.g. END -// STB_TEXTEDIT_K_TEXTSTART keyboard input to move cursor to start of text // e.g. ctrl-HOME -// STB_TEXTEDIT_K_TEXTEND keyboard input to move cursor to end of text // e.g. ctrl-END -// STB_TEXTEDIT_K_DELETE keyboard input to delete selection or character under cursor -// STB_TEXTEDIT_K_BACKSPACE keyboard input to delete selection or character left of cursor -// STB_TEXTEDIT_K_UNDO keyboard input to perform undo -// STB_TEXTEDIT_K_REDO keyboard input to perform redo -// -// Optional: -// STB_TEXTEDIT_K_INSERT keyboard input to toggle insert mode -// STB_TEXTEDIT_IS_SPACE(ch) true if character is whitespace (e.g. 'isspace'), -// required for WORDLEFT/WORDRIGHT -// STB_TEXTEDIT_K_WORDLEFT keyboard input to move cursor left one word // e.g. ctrl-LEFT -// STB_TEXTEDIT_K_WORDRIGHT keyboard input to move cursor right one word // e.g. ctrl-RIGHT -// -// Todo: -// STB_TEXTEDIT_K_PGUP keyboard input to move cursor up a page -// STB_TEXTEDIT_K_PGDOWN keyboard input to move cursor down a page -// -// Keyboard input must be encoded as a single integer value; e.g. a character code -// and some bitflags that represent shift states. to simplify the interface, SHIFT must -// be a bitflag, so we can test the shifted state of cursor movements to allow selection, -// i.e. (STB_TEXTED_K_RIGHT|STB_TEXTEDIT_K_SHIFT) should be shifted right-arrow. -// -// You can encode other things, such as CONTROL or ALT, in additional bits, and -// then test for their presence in e.g. STB_TEXTEDIT_K_WORDLEFT. For example, -// my Windows implementations add an additional CONTROL bit, and an additional KEYDOWN -// bit. Then all of the STB_TEXTEDIT_K_ values bitwise-or in the KEYDOWN bit, -// and I pass both WM_KEYDOWN and WM_CHAR events to the "key" function in the -// API below. The control keys will only match WM_KEYDOWN events because of the -// keydown bit I add, and STB_TEXTEDIT_KEYTOTEXT only tests for the KEYDOWN -// bit so it only decodes WM_CHAR events. -// -// STB_TEXTEDIT_LAYOUTROW returns information about the shape of one displayed -// row of characters assuming they start on the i'th character--the width and -// the height and the number of characters consumed. This allows this library -// to traverse the entire layout incrementally. You need to compute word-wrapping -// here. -// -// Each textfield keeps its own insert mode state, which is not how normal -// applications work. To keep an app-wide insert mode, update/copy the -// "insert_mode" field of STB_TexteditState before/after calling API functions. -// -// API -// -// void stb_textedit_initialize_state(STB_TexteditState *state, int is_single_line) -// -// void stb_textedit_click(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y) -// void stb_textedit_drag(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y) -// int stb_textedit_cut(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) -// int stb_textedit_paste(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE *text, int len) -// void stb_textedit_key(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int key) -// -// Each of these functions potentially updates the string and updates the -// state. -// -// initialize_state: -// set the textedit state to a known good default state when initially -// constructing the textedit. -// -// click: -// call this with the mouse x,y on a mouse down; it will update the cursor -// and reset the selection start/end to the cursor point. the x,y must -// be relative to the text widget, with (0,0) being the top left. -// -// drag: -// call this with the mouse x,y on a mouse drag/up; it will update the -// cursor and the selection end point -// -// cut: -// call this to delete the current selection; returns true if there was -// one. you should FIRST copy the current selection to the system paste buffer. -// (To copy, just copy the current selection out of the string yourself.) -// -// paste: -// call this to paste text at the current cursor point or over the current -// selection if there is one. -// -// key: -// call this for keyboard inputs sent to the textfield. you can use it -// for "key down" events or for "translated" key events. if you need to -// do both (as in Win32), or distinguish Unicode characters from control -// inputs, set a high bit to distinguish the two; then you can define the -// various definitions like STB_TEXTEDIT_K_LEFT have the is-key-event bit -// set, and make STB_TEXTEDIT_KEYTOCHAR check that the is-key-event bit is -// clear. -// -// When rendering, you can read the cursor position and selection state from -// the STB_TexteditState. -// -// -// Notes: -// -// This is designed to be usable in IMGUI, so it allows for the possibility of -// running in an IMGUI that has NOT cached the multi-line layout. For this -// reason, it provides an interface that is compatible with computing the -// layout incrementally--we try to make sure we make as few passes through -// as possible. (For example, to locate the mouse pointer in the text, we -// could define functions that return the X and Y positions of characters -// and binary search Y and then X, but if we're doing dynamic layout this -// will run the layout algorithm many times, so instead we manually search -// forward in one pass. Similar logic applies to e.g. up-arrow and -// down-arrow movement.) -// -// If it's run in a widget that *has* cached the layout, then this is less -// efficient, but it's not horrible on modern computers. But you wouldn't -// want to edit million-line files with it. - - -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//// -//// Header-file mode -//// -//// - -#ifndef INCLUDE_STB_TEXTEDIT_H -#define INCLUDE_STB_TEXTEDIT_H - -//////////////////////////////////////////////////////////////////////// -// -// STB_TexteditState -// -// Definition of STB_TexteditState which you should store -// per-textfield; it includes cursor position, selection state, -// and undo state. -// - -#ifndef STB_TEXTEDIT_UNDOSTATECOUNT -#define STB_TEXTEDIT_UNDOSTATECOUNT 99 -#endif -#ifndef STB_TEXTEDIT_UNDOCHARCOUNT -#define STB_TEXTEDIT_UNDOCHARCOUNT 999 -#endif -#ifndef STB_TEXTEDIT_CHARTYPE -#define STB_TEXTEDIT_CHARTYPE int -#endif -#ifndef STB_TEXTEDIT_POSITIONTYPE -#define STB_TEXTEDIT_POSITIONTYPE int -#endif - -typedef struct -{ - // private data - STB_TEXTEDIT_POSITIONTYPE where; - short insert_length; - short delete_length; - short char_storage; -} StbUndoRecord; - -typedef struct -{ - // private data - StbUndoRecord undo_rec [STB_TEXTEDIT_UNDOSTATECOUNT]; - STB_TEXTEDIT_CHARTYPE undo_char[STB_TEXTEDIT_UNDOCHARCOUNT]; - short undo_point, redo_point; - short undo_char_point, redo_char_point; -} StbUndoState; - -typedef struct -{ - ///////////////////// - // - // public data - // - - int cursor; - // position of the text cursor within the string - - int select_start; // selection start point - int select_end; - // selection start and end point in characters; if equal, no selection. - // note that start may be less than or greater than end (e.g. when - // dragging the mouse, start is where the initial click was, and you - // can drag in either direction) - - unsigned char insert_mode; - // each textfield keeps its own insert mode state. to keep an app-wide - // insert mode, copy this value in/out of the app state - - ///////////////////// - // - // private data - // - unsigned char cursor_at_end_of_line; // not implemented yet - unsigned char initialized; - unsigned char has_preferred_x; - unsigned char single_line; - unsigned char padding1, padding2, padding3; - float preferred_x; // this determines where the cursor up/down tries to seek to along x - StbUndoState undostate; -} STB_TexteditState; - - -//////////////////////////////////////////////////////////////////////// -// -// StbTexteditRow -// -// Result of layout query, used by stb_textedit to determine where -// the text in each row is. - -// result of layout query -typedef struct -{ - float x0,x1; // starting x location, end x location (allows for align=right, etc) - float baseline_y_delta; // position of baseline relative to previous row's baseline - float ymin,ymax; // height of row above and below baseline - int num_chars; -} StbTexteditRow; -#endif //INCLUDE_STB_TEXTEDIT_H - - -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//// -//// Implementation mode -//// -//// - - -// implementation isn't include-guarded, since it might have indirectly -// included just the "header" portion -#ifdef STB_TEXTEDIT_IMPLEMENTATION - -#include // memmove - - -///////////////////////////////////////////////////////////////////////////// -// -// Mouse input handling -// - -// traverse the layout to locate the nearest character to a display position -static int stb_text_locate_coord(STB_TEXTEDIT_STRING *str, float x, float y) -{ - StbTexteditRow r; - int n = STB_TEXTEDIT_STRINGLEN(str); - float base_y = 0, prev_x; - int i=0, k; - - if (y < 0) - return 0; - - r.x0 = r.x1 = 0; - r.ymin = r.ymax = 0; - r.num_chars = 0; - - // search rows to find one that straddles 'y' - while (i < n) { - STB_TEXTEDIT_LAYOUTROW(&r, str, i); - if (r.num_chars <= 0) - return n; - - if (y < base_y + r.ymax) - break; - - i += r.num_chars; - base_y += r.baseline_y_delta; - } - - // below all text, return 'after' last character - if (i >= n) - return n; - - // check if it's before the beginning of the line - if (x < r.x0) - return i; - - // check if it's before the end of the line - if (x < r.x1) { - // search characters in row for one that straddles 'x' - k = i; - prev_x = r.x0; - for (i=0; i < r.num_chars; ++i) { - float w = STB_TEXTEDIT_GETWIDTH(str, k, i); - if (x < prev_x+w) { - if (x < prev_x+w/2) - return k+i; - else - return k+i+1; - } - prev_x += w; - } - // shouldn't happen, but if it does, fall through to end-of-line case - } - - // if the last character is a newline, return that. otherwise return 'after' the last character - if (STB_TEXTEDIT_GETCHAR(str, i+r.num_chars-1) == STB_TEXTEDIT_NEWLINE) - return i+r.num_chars-1; - else - return i+r.num_chars; -} - -// API click: on mouse down, move the cursor to the clicked location, and reset the selection -static void stb_textedit_click(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y) -{ - state->cursor = stb_text_locate_coord(str, x, y); - state->select_start = state->cursor; - state->select_end = state->cursor; - state->has_preferred_x = 0; -} - -// API drag: on mouse drag, move the cursor and selection endpoint to the clicked location -static void stb_textedit_drag(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y) -{ - int p = stb_text_locate_coord(str, x, y); - state->cursor = state->select_end = p; -} - -///////////////////////////////////////////////////////////////////////////// -// -// Keyboard input handling -// - -// forward declarations -static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state); -static void stb_text_redo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state); -static void stb_text_makeundo_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length); -static void stb_text_makeundo_insert(STB_TexteditState *state, int where, int length); -static void stb_text_makeundo_replace(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length); - -typedef struct -{ - float x,y; // position of n'th character - float height; // height of line - int first_char, length; // first char of row, and length - int prev_first; // first char of previous row -} StbFindState; - -// find the x/y location of a character, and remember info about the previous row in -// case we get a move-up event (for page up, we'll have to rescan) -static void stb_textedit_find_charpos(StbFindState *find, STB_TEXTEDIT_STRING *str, int n, int single_line) -{ - StbTexteditRow r; - int prev_start = 0; - int z = STB_TEXTEDIT_STRINGLEN(str); - int i=0, first; - - if (n == z) { - // if it's at the end, then find the last line -- simpler than trying to - // explicitly handle this case in the regular code - if (single_line) { - STB_TEXTEDIT_LAYOUTROW(&r, str, 0); - find->y = 0; - find->first_char = 0; - find->length = z; - find->height = r.ymax - r.ymin; - find->x = r.x1; - } else { - find->y = 0; - find->x = 0; - find->height = 1; - while (i < z) { - STB_TEXTEDIT_LAYOUTROW(&r, str, i); - prev_start = i; - i += r.num_chars; - } - find->first_char = i; - find->length = 0; - find->prev_first = prev_start; - } - return; - } - - // search rows to find the one that straddles character n - find->y = 0; - - for(;;) { - STB_TEXTEDIT_LAYOUTROW(&r, str, i); - if (n < i + r.num_chars) - break; - prev_start = i; - i += r.num_chars; - find->y += r.baseline_y_delta; - } - - find->first_char = first = i; - find->length = r.num_chars; - find->height = r.ymax - r.ymin; - find->prev_first = prev_start; - - // now scan to find xpos - find->x = r.x0; - i = 0; - for (i=0; first+i < n; ++i) - find->x += STB_TEXTEDIT_GETWIDTH(str, first, i); -} - -#define STB_TEXT_HAS_SELECTION(s) ((s)->select_start != (s)->select_end) - -// make the selection/cursor state valid if client altered the string -static void stb_textedit_clamp(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) -{ - int n = STB_TEXTEDIT_STRINGLEN(str); - if (STB_TEXT_HAS_SELECTION(state)) { - if (state->select_start > n) state->select_start = n; - if (state->select_end > n) state->select_end = n; - // if clamping forced them to be equal, move the cursor to match - if (state->select_start == state->select_end) - state->cursor = state->select_start; - } - if (state->cursor > n) state->cursor = n; -} - -// delete characters while updating undo -static void stb_textedit_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int len) -{ - stb_text_makeundo_delete(str, state, where, len); - STB_TEXTEDIT_DELETECHARS(str, where, len); - state->has_preferred_x = 0; -} - -// delete the section -static void stb_textedit_delete_selection(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) -{ - stb_textedit_clamp(str, state); - if (STB_TEXT_HAS_SELECTION(state)) { - if (state->select_start < state->select_end) { - stb_textedit_delete(str, state, state->select_start, state->select_end - state->select_start); - state->select_end = state->cursor = state->select_start; - } else { - stb_textedit_delete(str, state, state->select_end, state->select_start - state->select_end); - state->select_start = state->cursor = state->select_end; - } - state->has_preferred_x = 0; - } -} - -// canoncialize the selection so start <= end -static void stb_textedit_sortselection(STB_TexteditState *state) -{ - if (state->select_end < state->select_start) { - int temp = state->select_end; - state->select_end = state->select_start; - state->select_start = temp; - } -} - -// move cursor to first character of selection -static void stb_textedit_move_to_first(STB_TexteditState *state) -{ - if (STB_TEXT_HAS_SELECTION(state)) { - stb_textedit_sortselection(state); - state->cursor = state->select_start; - state->select_end = state->select_start; - state->has_preferred_x = 0; - } -} - -// move cursor to last character of selection -static void stb_textedit_move_to_last(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) -{ - if (STB_TEXT_HAS_SELECTION(state)) { - stb_textedit_sortselection(state); - stb_textedit_clamp(str, state); - state->cursor = state->select_end; - state->select_start = state->select_end; - state->has_preferred_x = 0; - } -} - -#ifdef STB_TEXTEDIT_IS_SPACE -static int is_word_boundary( STB_TEXTEDIT_STRING *_str, int _idx ) -{ - return _idx > 0 ? (STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(_str,_idx-1) ) && !STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(_str, _idx) ) ) : 1; -} - -static int stb_textedit_move_to_word_previous( STB_TEXTEDIT_STRING *_str, STB_TexteditState *_state ) -{ - int c = _state->cursor - 1; - while( c >= 0 && !is_word_boundary( _str, c ) ) - --c; - - if( c < 0 ) - c = 0; - - return c; -} - -static int stb_textedit_move_to_word_next( STB_TEXTEDIT_STRING *_str, STB_TexteditState *_state ) -{ - const int len = STB_TEXTEDIT_STRINGLEN(_str); - int c = _state->cursor+1; - while( c < len && !is_word_boundary( _str, c ) ) - ++c; - - if( c > len ) - c = len; - - return c; -} -#endif - -// update selection and cursor to match each other -static void stb_textedit_prep_selection_at_cursor(STB_TexteditState *state) -{ - if (!STB_TEXT_HAS_SELECTION(state)) - state->select_start = state->select_end = state->cursor; - else - state->cursor = state->select_end; -} - -// API cut: delete selection -static int stb_textedit_cut(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) -{ - if (STB_TEXT_HAS_SELECTION(state)) { - stb_textedit_delete_selection(str,state); // implicity clamps - state->has_preferred_x = 0; - return 1; - } - return 0; -} - -// API paste: replace existing selection with passed-in text -static int stb_textedit_paste(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE const *ctext, int len) -{ - STB_TEXTEDIT_CHARTYPE *text = (STB_TEXTEDIT_CHARTYPE *) ctext; - // if there's a selection, the paste should delete it - stb_textedit_clamp(str, state); - stb_textedit_delete_selection(str,state); - // try to insert the characters - if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, text, len)) { - stb_text_makeundo_insert(state, state->cursor, len); - state->cursor += len; - state->has_preferred_x = 0; - return 1; - } - // remove the undo since we didn't actually insert the characters - if (state->undostate.undo_point) - --state->undostate.undo_point; - return 0; -} - -// API key: process a keyboard input -static void stb_textedit_key(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int key) -{ -retry: - switch (key) { - default: { - int c = STB_TEXTEDIT_KEYTOTEXT(key); - if (c > 0) { - STB_TEXTEDIT_CHARTYPE ch = (STB_TEXTEDIT_CHARTYPE) c; - - // can't add newline in single-line mode - if (c == '\n' && state->single_line) - break; - - if (state->insert_mode && !STB_TEXT_HAS_SELECTION(state) && state->cursor < STB_TEXTEDIT_STRINGLEN(str)) { - stb_text_makeundo_replace(str, state, state->cursor, 1, 1); - STB_TEXTEDIT_DELETECHARS(str, state->cursor, 1); - if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, &ch, 1)) { - ++state->cursor; - state->has_preferred_x = 0; - } - } else { - stb_textedit_delete_selection(str,state); // implicity clamps - if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, &ch, 1)) { - stb_text_makeundo_insert(state, state->cursor, 1); - ++state->cursor; - state->has_preferred_x = 0; - } - } - } - break; - } - -#ifdef STB_TEXTEDIT_K_INSERT - case STB_TEXTEDIT_K_INSERT: - state->insert_mode = !state->insert_mode; - break; -#endif - - case STB_TEXTEDIT_K_UNDO: - stb_text_undo(str, state); - state->has_preferred_x = 0; - break; - - case STB_TEXTEDIT_K_REDO: - stb_text_redo(str, state); - state->has_preferred_x = 0; - break; - - case STB_TEXTEDIT_K_LEFT: - // if currently there's a selection, move cursor to start of selection - if (STB_TEXT_HAS_SELECTION(state)) - stb_textedit_move_to_first(state); - else - if (state->cursor > 0) - --state->cursor; - state->has_preferred_x = 0; - break; - - case STB_TEXTEDIT_K_RIGHT: - // if currently there's a selection, move cursor to end of selection - if (STB_TEXT_HAS_SELECTION(state)) - stb_textedit_move_to_last(str, state); - else - ++state->cursor; - stb_textedit_clamp(str, state); - state->has_preferred_x = 0; - break; - - case STB_TEXTEDIT_K_LEFT | STB_TEXTEDIT_K_SHIFT: - stb_textedit_clamp(str, state); - stb_textedit_prep_selection_at_cursor(state); - // move selection left - if (state->select_end > 0) - --state->select_end; - state->cursor = state->select_end; - state->has_preferred_x = 0; - break; - -#ifdef STB_TEXTEDIT_IS_SPACE - case STB_TEXTEDIT_K_WORDLEFT: - if (STB_TEXT_HAS_SELECTION(state)) - stb_textedit_move_to_first(state); - else { - state->cursor = stb_textedit_move_to_word_previous(str, state); - stb_textedit_clamp( str, state ); - } - break; - - case STB_TEXTEDIT_K_WORDRIGHT: - if (STB_TEXT_HAS_SELECTION(state)) - stb_textedit_move_to_last(str, state); - else { - state->cursor = stb_textedit_move_to_word_next(str, state); - stb_textedit_clamp( str, state ); - } - break; - - case STB_TEXTEDIT_K_WORDLEFT | STB_TEXTEDIT_K_SHIFT: - if( !STB_TEXT_HAS_SELECTION( state ) ) - stb_textedit_prep_selection_at_cursor(state); - - state->cursor = stb_textedit_move_to_word_previous(str, state); - state->select_end = state->cursor; - - stb_textedit_clamp( str, state ); - break; - - case STB_TEXTEDIT_K_WORDRIGHT | STB_TEXTEDIT_K_SHIFT: - if( !STB_TEXT_HAS_SELECTION( state ) ) - stb_textedit_prep_selection_at_cursor(state); - - state->cursor = stb_textedit_move_to_word_next(str, state); - state->select_end = state->cursor; - - stb_textedit_clamp( str, state ); - break; -#endif - - case STB_TEXTEDIT_K_RIGHT | STB_TEXTEDIT_K_SHIFT: - stb_textedit_prep_selection_at_cursor(state); - // move selection right - ++state->select_end; - stb_textedit_clamp(str, state); - state->cursor = state->select_end; - state->has_preferred_x = 0; - break; - - case STB_TEXTEDIT_K_DOWN: - case STB_TEXTEDIT_K_DOWN | STB_TEXTEDIT_K_SHIFT: { - StbFindState find; - StbTexteditRow row; - int i, sel = (key & STB_TEXTEDIT_K_SHIFT) != 0; - - if (state->single_line) { - // on windows, up&down in single-line behave like left&right - key = STB_TEXTEDIT_K_RIGHT | (key & STB_TEXTEDIT_K_SHIFT); - goto retry; - } - - if (sel) - stb_textedit_prep_selection_at_cursor(state); - else if (STB_TEXT_HAS_SELECTION(state)) - stb_textedit_move_to_last(str,state); - - // compute current position of cursor point - stb_textedit_clamp(str, state); - stb_textedit_find_charpos(&find, str, state->cursor, state->single_line); - - // now find character position down a row - if (find.length) { - float goal_x = state->has_preferred_x ? state->preferred_x : find.x; - float x; - int start = find.first_char + find.length; - state->cursor = start; - STB_TEXTEDIT_LAYOUTROW(&row, str, state->cursor); - x = row.x0; - for (i=0; i < row.num_chars; ++i) { - float dx = STB_TEXTEDIT_GETWIDTH(str, start, i); - #ifdef STB_TEXTEDIT_GETWIDTH_NEWLINE - if (dx == STB_TEXTEDIT_GETWIDTH_NEWLINE) - break; - #endif - x += dx; - if (x > goal_x) - break; - ++state->cursor; - } - stb_textedit_clamp(str, state); - - state->has_preferred_x = 1; - state->preferred_x = goal_x; - - if (sel) - state->select_end = state->cursor; - } - break; - } - - case STB_TEXTEDIT_K_UP: - case STB_TEXTEDIT_K_UP | STB_TEXTEDIT_K_SHIFT: { - StbFindState find; - StbTexteditRow row; - int i, sel = (key & STB_TEXTEDIT_K_SHIFT) != 0; - - if (state->single_line) { - // on windows, up&down become left&right - key = STB_TEXTEDIT_K_LEFT | (key & STB_TEXTEDIT_K_SHIFT); - goto retry; - } - - if (sel) - stb_textedit_prep_selection_at_cursor(state); - else if (STB_TEXT_HAS_SELECTION(state)) - stb_textedit_move_to_first(state); - - // compute current position of cursor point - stb_textedit_clamp(str, state); - stb_textedit_find_charpos(&find, str, state->cursor, state->single_line); - - // can only go up if there's a previous row - if (find.prev_first != find.first_char) { - // now find character position up a row - float goal_x = state->has_preferred_x ? state->preferred_x : find.x; - float x; - state->cursor = find.prev_first; - STB_TEXTEDIT_LAYOUTROW(&row, str, state->cursor); - x = row.x0; - for (i=0; i < row.num_chars; ++i) { - float dx = STB_TEXTEDIT_GETWIDTH(str, find.prev_first, i); - #ifdef STB_TEXTEDIT_GETWIDTH_NEWLINE - if (dx == STB_TEXTEDIT_GETWIDTH_NEWLINE) - break; - #endif - x += dx; - if (x > goal_x) - break; - ++state->cursor; - } - stb_textedit_clamp(str, state); - - state->has_preferred_x = 1; - state->preferred_x = goal_x; - - if (sel) - state->select_end = state->cursor; - } - break; - } - - case STB_TEXTEDIT_K_DELETE: - case STB_TEXTEDIT_K_DELETE | STB_TEXTEDIT_K_SHIFT: - if (STB_TEXT_HAS_SELECTION(state)) - stb_textedit_delete_selection(str, state); - else { - int n = STB_TEXTEDIT_STRINGLEN(str); - if (state->cursor < n) - stb_textedit_delete(str, state, state->cursor, 1); - } - state->has_preferred_x = 0; - break; - - case STB_TEXTEDIT_K_BACKSPACE: - case STB_TEXTEDIT_K_BACKSPACE | STB_TEXTEDIT_K_SHIFT: - if (STB_TEXT_HAS_SELECTION(state)) - stb_textedit_delete_selection(str, state); - else { - stb_textedit_clamp(str, state); - if (state->cursor > 0) { - stb_textedit_delete(str, state, state->cursor-1, 1); - --state->cursor; - } - } - state->has_preferred_x = 0; - break; - - case STB_TEXTEDIT_K_TEXTSTART: - state->cursor = state->select_start = state->select_end = 0; - state->has_preferred_x = 0; - break; - - case STB_TEXTEDIT_K_TEXTEND: - state->cursor = STB_TEXTEDIT_STRINGLEN(str); - state->select_start = state->select_end = 0; - state->has_preferred_x = 0; - break; - - case STB_TEXTEDIT_K_TEXTSTART | STB_TEXTEDIT_K_SHIFT: - stb_textedit_prep_selection_at_cursor(state); - state->cursor = state->select_end = 0; - state->has_preferred_x = 0; - break; - - case STB_TEXTEDIT_K_TEXTEND | STB_TEXTEDIT_K_SHIFT: - stb_textedit_prep_selection_at_cursor(state); - state->cursor = state->select_end = STB_TEXTEDIT_STRINGLEN(str); - state->has_preferred_x = 0; - break; - - - case STB_TEXTEDIT_K_LINESTART: { - StbFindState find; - stb_textedit_clamp(str, state); - stb_textedit_move_to_first(state); - stb_textedit_find_charpos(&find, str, state->cursor, state->single_line); - state->cursor = find.first_char; - state->has_preferred_x = 0; - break; - } - - case STB_TEXTEDIT_K_LINEEND: { - StbFindState find; - stb_textedit_clamp(str, state); - stb_textedit_move_to_first(state); - stb_textedit_find_charpos(&find, str, state->cursor, state->single_line); - state->cursor = find.first_char + find.length; - state->has_preferred_x = 0; - break; - } - - case STB_TEXTEDIT_K_LINESTART | STB_TEXTEDIT_K_SHIFT: { - StbFindState find; - stb_textedit_clamp(str, state); - stb_textedit_prep_selection_at_cursor(state); - stb_textedit_find_charpos(&find, str, state->cursor, state->single_line); - state->cursor = state->select_end = find.first_char; - state->has_preferred_x = 0; - break; - } - - case STB_TEXTEDIT_K_LINEEND | STB_TEXTEDIT_K_SHIFT: { - StbFindState find; - stb_textedit_clamp(str, state); - stb_textedit_prep_selection_at_cursor(state); - stb_textedit_find_charpos(&find, str, state->cursor, state->single_line); - state->cursor = state->select_end = find.first_char + find.length; - state->has_preferred_x = 0; - break; - } - -// @TODO: -// STB_TEXTEDIT_K_PGUP - move cursor up a page -// STB_TEXTEDIT_K_PGDOWN - move cursor down a page - } -} - -///////////////////////////////////////////////////////////////////////////// -// -// Undo processing -// -// @OPTIMIZE: the undo/redo buffer should be circular - -static void stb_textedit_flush_redo(StbUndoState *state) -{ - state->redo_point = STB_TEXTEDIT_UNDOSTATECOUNT; - state->redo_char_point = STB_TEXTEDIT_UNDOCHARCOUNT; -} - -// discard the oldest entry in the undo list -static void stb_textedit_discard_undo(StbUndoState *state) -{ - if (state->undo_point > 0) { - // if the 0th undo state has characters, clean those up - if (state->undo_rec[0].char_storage >= 0) { - int n = state->undo_rec[0].insert_length, i; - // delete n characters from all other records - state->undo_char_point = state->undo_char_point - (short) n; // vsnet05 - memmove(state->undo_char, state->undo_char + n, (size_t) ((size_t)state->undo_char_point*sizeof(STB_TEXTEDIT_CHARTYPE))); - for (i=0; i < state->undo_point; ++i) - if (state->undo_rec[i].char_storage >= 0) - state->undo_rec[i].char_storage = state->undo_rec[i].char_storage - (short) n; // vsnet05 // @OPTIMIZE: get rid of char_storage and infer it - } - --state->undo_point; - memmove(state->undo_rec, state->undo_rec+1, (size_t) ((size_t)state->undo_point*sizeof(state->undo_rec[0]))); - } -} - -// discard the oldest entry in the redo list--it's bad if this -// ever happens, but because undo & redo have to store the actual -// characters in different cases, the redo character buffer can -// fill up even though the undo buffer didn't -static void stb_textedit_discard_redo(StbUndoState *state) -{ - int k = STB_TEXTEDIT_UNDOSTATECOUNT-1; - - if (state->redo_point <= k) { - // if the k'th undo state has characters, clean those up - if (state->undo_rec[k].char_storage >= 0) { - int n = state->undo_rec[k].insert_length, i; - // delete n characters from all other records - state->redo_char_point = state->redo_char_point + (short) n; // vsnet05 - memmove(state->undo_char + state->redo_char_point, state->undo_char + state->redo_char_point-n, (size_t) ((size_t)(STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_char_point)*sizeof(STB_TEXTEDIT_CHARTYPE))); - for (i=state->redo_point; i < k; ++i) - if (state->undo_rec[i].char_storage >= 0) - state->undo_rec[i].char_storage = state->undo_rec[i].char_storage + (short) n; // vsnet05 - } - ++state->redo_point; - memmove(state->undo_rec + state->redo_point-1, state->undo_rec + state->redo_point, (size_t) ((size_t)(STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point)*sizeof(state->undo_rec[0]))); - } -} - -static StbUndoRecord *stb_text_create_undo_record(StbUndoState *state, int numchars) -{ - // any time we create a new undo record, we discard redo - stb_textedit_flush_redo(state); - - // if we have no free records, we have to make room, by sliding the - // existing records down - if (state->undo_point == STB_TEXTEDIT_UNDOSTATECOUNT) - stb_textedit_discard_undo(state); - - // if the characters to store won't possibly fit in the buffer, we can't undo - if (numchars > STB_TEXTEDIT_UNDOCHARCOUNT) { - state->undo_point = 0; - state->undo_char_point = 0; - return NULL; - } - - // if we don't have enough free characters in the buffer, we have to make room - while (state->undo_char_point + numchars > STB_TEXTEDIT_UNDOCHARCOUNT) - stb_textedit_discard_undo(state); - - return &state->undo_rec[state->undo_point++]; -} - -static STB_TEXTEDIT_CHARTYPE *stb_text_createundo(StbUndoState *state, int pos, int insert_len, int delete_len) -{ - StbUndoRecord *r = stb_text_create_undo_record(state, insert_len); - if (r == NULL) - return NULL; - - r->where = pos; - r->insert_length = (short) insert_len; - r->delete_length = (short) delete_len; - - if (insert_len == 0) { - r->char_storage = -1; - return NULL; - } else { - r->char_storage = state->undo_char_point; - state->undo_char_point = state->undo_char_point + (short) insert_len; - return &state->undo_char[r->char_storage]; - } -} - -static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) -{ - StbUndoState *s = &state->undostate; - StbUndoRecord u, *r; - if (s->undo_point == 0) - return; - - // we need to do two things: apply the undo record, and create a redo record - u = s->undo_rec[s->undo_point-1]; - r = &s->undo_rec[s->redo_point-1]; - r->char_storage = -1; - - r->insert_length = u.delete_length; - r->delete_length = u.insert_length; - r->where = u.where; - - if (u.delete_length) { - // if the undo record says to delete characters, then the redo record will - // need to re-insert the characters that get deleted, so we need to store - // them. - - // there are three cases: - // there's enough room to store the characters - // characters stored for *redoing* don't leave room for redo - // characters stored for *undoing* don't leave room for redo - // if the last is true, we have to bail - - if (s->undo_char_point + u.delete_length >= STB_TEXTEDIT_UNDOCHARCOUNT) { - // the undo records take up too much character space; there's no space to store the redo characters - r->insert_length = 0; - } else { - int i; - - // there's definitely room to store the characters eventually - while (s->undo_char_point + u.delete_length > s->redo_char_point) { - // there's currently not enough room, so discard a redo record - stb_textedit_discard_redo(s); - // should never happen: - if (s->redo_point == STB_TEXTEDIT_UNDOSTATECOUNT) - return; - } - r = &s->undo_rec[s->redo_point-1]; - - r->char_storage = s->redo_char_point - u.delete_length; - s->redo_char_point = s->redo_char_point - (short) u.delete_length; - - // now save the characters - for (i=0; i < u.delete_length; ++i) - s->undo_char[r->char_storage + i] = STB_TEXTEDIT_GETCHAR(str, u.where + i); - } - - // now we can carry out the deletion - STB_TEXTEDIT_DELETECHARS(str, u.where, u.delete_length); - } - - // check type of recorded action: - if (u.insert_length) { - // easy case: was a deletion, so we need to insert n characters - STB_TEXTEDIT_INSERTCHARS(str, u.where, &s->undo_char[u.char_storage], u.insert_length); - s->undo_char_point -= u.insert_length; - } - - state->cursor = u.where + u.insert_length; - - s->undo_point--; - s->redo_point--; -} - -static void stb_text_redo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) -{ - StbUndoState *s = &state->undostate; - StbUndoRecord *u, r; - if (s->redo_point == STB_TEXTEDIT_UNDOSTATECOUNT) - return; - - // we need to do two things: apply the redo record, and create an undo record - u = &s->undo_rec[s->undo_point]; - r = s->undo_rec[s->redo_point]; - - // we KNOW there must be room for the undo record, because the redo record - // was derived from an undo record - - u->delete_length = r.insert_length; - u->insert_length = r.delete_length; - u->where = r.where; - u->char_storage = -1; - - if (r.delete_length) { - // the redo record requires us to delete characters, so the undo record - // needs to store the characters - - if (s->undo_char_point + u->insert_length > s->redo_char_point) { - u->insert_length = 0; - u->delete_length = 0; - } else { - int i; - u->char_storage = s->undo_char_point; - s->undo_char_point = s->undo_char_point + u->insert_length; - - // now save the characters - for (i=0; i < u->insert_length; ++i) - s->undo_char[u->char_storage + i] = STB_TEXTEDIT_GETCHAR(str, u->where + i); - } - - STB_TEXTEDIT_DELETECHARS(str, r.where, r.delete_length); - } - - if (r.insert_length) { - // easy case: need to insert n characters - STB_TEXTEDIT_INSERTCHARS(str, r.where, &s->undo_char[r.char_storage], r.insert_length); - } - - state->cursor = r.where + r.insert_length; - - s->undo_point++; - s->redo_point++; -} - -static void stb_text_makeundo_insert(STB_TexteditState *state, int where, int length) -{ - stb_text_createundo(&state->undostate, where, 0, length); -} - -static void stb_text_makeundo_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length) -{ - int i; - STB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, length, 0); - if (p) { - for (i=0; i < length; ++i) - p[i] = STB_TEXTEDIT_GETCHAR(str, where+i); - } -} - -static void stb_text_makeundo_replace(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length) -{ - int i; - STB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, old_length, new_length); - if (p) { - for (i=0; i < old_length; ++i) - p[i] = STB_TEXTEDIT_GETCHAR(str, where+i); - } -} - -// reset the state to default -static void stb_textedit_clear_state(STB_TexteditState *state, int is_single_line) -{ - state->undostate.undo_point = 0; - state->undostate.undo_char_point = 0; - state->undostate.redo_point = STB_TEXTEDIT_UNDOSTATECOUNT; - state->undostate.redo_char_point = STB_TEXTEDIT_UNDOCHARCOUNT; - state->select_end = state->select_start = 0; - state->cursor = 0; - state->has_preferred_x = 0; - state->preferred_x = 0; - state->cursor_at_end_of_line = 0; - state->initialized = 1; - state->single_line = (unsigned char) is_single_line; - state->insert_mode = 0; -} - -// API initialize -static void stb_textedit_initialize_state(STB_TexteditState *state, int is_single_line) -{ - stb_textedit_clear_state(state, is_single_line); -} -#endif//STB_TEXTEDIT_IMPLEMENTATION diff --git a/testbed/imgui/stb_truetype.h b/testbed/imgui/stb_truetype.h index 3c5d6f30..9f07124a 100644 --- a/testbed/imgui/stb_truetype.h +++ b/testbed/imgui/stb_truetype.h @@ -1,8 +1,5 @@ -// [ImGui] this is a slightly modified version of stb_truetype.h 1.02 -// [ImGui] we added stbtt_PackFontRangesGatherRects() and stbtt_PackFontRangesRenderIntoRects() and modified stbtt_PackBegin() - -// stb_truetype.h - v1.02 - public domain -// authored from 2009-2014 by Sean Barrett / RAD Game Tools +// stb_truetype.h - v0.6c - public domain +// authored from 2009-2012 by Sean Barrett / RAD Game Tools // // This library processes TrueType files: // parse files @@ -24,34 +21,15 @@ // Mikko Mononen: compound shape support, more cmap formats // Tor Andersson: kerning, subpixel rendering // -// Bug/warning reports/fixes: +// Bug/warning reports: // "Zer" on mollyrocket (with fix) // Cass Everitt // stoiko (Haemimont Games) // Brian Hook // Walter van Niftrik -// David Gow -// David Given -// Ivan-Assen Ivanov -// Anthony Pesch -// Johan Duparc -// Hou Qiming -// Fabian "ryg" Giesen -// -// Misc other: -// Ryan Gordon // // VERSION HISTORY // -// 1.02 (2014-12-10) fix various warnings & compile issues w/ stb_rect_pack, C++ -// 1.01 (2014-12-08) fix subpixel position when oversampling to exactly match -// non-oversampled; STBTT_POINT_SIZE for packed case only -// 1.00 (2014-12-06) add new PackBegin etc. API, w/ support for oversampling -// 0.99 (2014-09-18) fix multiple bugs with subpixel rendering (ryg) -// 0.9 (2014-08-07) support certain mac/iOS fonts without an MS platformID -// 0.8b (2014-07-07) fix a warning -// 0.8 (2014-05-25) fix a few more warnings -// 0.7 (2013-09-25) bugfix: subpixel glyph bug fixed in 0.5 had come back // 0.6c (2012-07-24) improve documentation // 0.6b (2012-07-20) fix a few more warnings // 0.6 (2012-07-17) fix warnings; added stbtt_ScaleForMappingEmToPixels, @@ -68,7 +46,7 @@ // updated Hello World! sample to use kerning and subpixel // fixed some warnings // 0.3 (2009-06-24) cmap fmt=12, compound shapes (MM) -// userdata, malloc-from-userdata, non-zero fill (stb) +// userdata, malloc-from-userdata, non-zero fill (STB) // 0.2 (2009-03-11) Fix unsigned/signed char warnings // 0.1 (2009-03-09) First public release // @@ -86,18 +64,11 @@ // before the #include of this file. This expands out the actual // implementation into that C/C++ file. // -// Simple 3D API (don't ship this, but it's fine for tools and quick start) +// Simple 3D API (don't ship this, but it's fine for tools and quick start, +// and you can cut and paste from it to move to more advanced) // stbtt_BakeFontBitmap() -- bake a font to a bitmap for use as texture // stbtt_GetBakedQuad() -- compute quad to draw for a given char // -// Improved 3D API (more shippable): -// #include "stb_rect_pack.h" -- optional, but you really want it -// stbtt_PackBegin() -// stbtt_PackSetOversample() -- for improved quality on small fonts -// stbtt_PackFontRanges() -- pack and renders -// stbtt_PackEnd() -// stbtt_GetPackedQuad() -// // "Load" a font file from a memory buffer (you have to keep the buffer loaded) // stbtt_InitFont() // stbtt_GetFontOffsetForIndex() -- use for TTC font collections @@ -251,7 +222,7 @@ void my_stbtt_print(float x, float y, char *text) while (*text) { if (*text >= 32 && *text < 128) { stbtt_aligned_quad q; - stbtt_GetBakedQuad(cdata, 512,512, *text-32, &x,&y,&q,1);//1=opengl & d3d10+,0=d3d9 + stbtt_GetBakedQuad(cdata, 512,512, *text-32, &x,&y,&q,1);//1=opengl,0=old d3d glTexCoord2f(q.s0,q.t1); glVertex2f(q.x0,q.y0); glTexCoord2f(q.s1,q.t1); glVertex2f(q.x1,q.y0); glTexCoord2f(q.s1,q.t0); glVertex2f(q.x1,q.y1); @@ -320,7 +291,7 @@ int main(int arg, char **argv) { stbtt_fontinfo font; int i,j,ascent,baseline,ch=0; - float scale, xpos=2; // leave a little padding in case the character extends left + float scale, xpos=0; char *text = "Heljo World!"; fread(buffer, 1, 1000000, fopen("c:/windows/fonts/arialbd.ttf", "rb")); @@ -379,12 +350,6 @@ int main(int arg, char **argv) typedef char stbtt__check_size32[sizeof(stbtt_int32)==4 ? 1 : -1]; typedef char stbtt__check_size16[sizeof(stbtt_int16)==2 ? 1 : -1]; - #ifdef STBTT_STATIC - #define STBTT_DEF static - #else - #define STBTT_DEF extern - #endif - // #define your own STBTT_sort() to override this to avoid qsort #ifndef STBTT_sort #include @@ -398,16 +363,11 @@ int main(int arg, char **argv) #define STBTT_iceil(x) ((int) ceil(x)) #endif - #ifndef STBTT_sqrt - #include - #define STBTT_sqrt(x) sqrt(x) - #endif - // #define your own functions "STBTT_malloc" / "STBTT_free" to avoid malloc.h #ifndef STBTT_malloc - #include - #define STBTT_malloc(x,u) ((void)(u),malloc(x)) - #define STBTT_free(x,u) ((void)(u),free(x)) + #include + #define STBTT_malloc(x,u) malloc(x) + #define STBTT_free(x,u) free(x) #endif #ifndef STBTT_assert @@ -451,10 +411,10 @@ extern "C" { typedef struct { unsigned short x0,y0,x1,y1; // coordinates of bbox in bitmap - float xoff,yoff,xadvance; + float xoff,yoff,xadvance; } stbtt_bakedchar; -STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset, // font location (use offset=0 for plain .ttf) +extern int stbtt_BakeFontBitmap(const unsigned char *data, int offset, // font location (use offset=0 for plain .ttf) float pixel_height, // height of font in pixels unsigned char *pixels, int pw, int ph, // bitmap to be filled in int first_char, int num_chars, // characters to bake @@ -470,7 +430,7 @@ typedef struct float x1,y1,s1,t1; // bottom-right } stbtt_aligned_quad; -STBTT_DEF void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, // same data as above +extern void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, // same data as above int char_index, // character to display float *xpos, float *ypos, // pointers to current position in screen pixel space stbtt_aligned_quad *q, // output: quad to draw @@ -486,117 +446,13 @@ STBTT_DEF void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, // // It's inefficient; you might want to c&p it and optimize it. - -////////////////////////////////////////////////////////////////////////////// -// -// NEW TEXTURE BAKING API -// -// This provides options for packing multiple fonts into one atlas, not -// perfectly but better than nothing. - -typedef struct -{ - unsigned short x0,y0,x1,y1; // coordinates of bbox in bitmap - float xoff,yoff,xadvance; - float xoff2,yoff2; -} stbtt_packedchar; - -typedef struct stbtt_pack_context stbtt_pack_context; -typedef struct stbtt_fontinfo stbtt_fontinfo; -#ifndef STB_RECT_PACK_VERSION -typedef struct stbrp_rect stbrp_rect; -#endif - -STBTT_DEF int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, int width, int height, int stride_in_bytes, int padding, void *alloc_context); -// Initializes a packing context stored in the passed-in stbtt_pack_context. -// Future calls using this context will pack characters into the bitmap passed -// in here: a 1-channel bitmap that is weight x height. stride_in_bytes is -// the distance from one row to the next (or 0 to mean they are packed tightly -// together). "padding" is // the amount of padding to leave between each -// character (normally you want '1' for bitmaps you'll use as textures with -// bilinear filtering). -// -// Returns 0 on failure, 1 on success. - -STBTT_DEF void stbtt_PackEnd (stbtt_pack_context *spc); -// Cleans up the packing context and frees all memory. - -#define STBTT_POINT_SIZE(x) (-(x)) - -STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, float font_size, - int first_unicode_char_in_range, int num_chars_in_range, stbtt_packedchar *chardata_for_range); -// Creates character bitmaps from the font_index'th font found in fontdata (use -// font_index=0 if you don't know what that is). It creates num_chars_in_range -// bitmaps for characters with unicode values starting at first_unicode_char_in_range -// and increasing. Data for how to render them is stored in chardata_for_range; -// pass these to stbtt_GetPackedQuad to get back renderable quads. -// -// font_size is the full height of the character from ascender to descender, -// as computed by stbtt_ScaleForPixelHeight. To use a point size as computed -// by stbtt_ScaleForMappingEmToPixels, wrap the point size in STBTT_POINT_SIZE() -// and pass that result as 'font_size': -// ..., 20 , ... // font max minus min y is 20 pixels tall -// ..., STBTT_POINT_SIZE(20), ... // 'M' is 20 pixels tall - -typedef struct -{ - float font_size; - int first_unicode_char_in_range; - int num_chars_in_range; - stbtt_packedchar *chardata_for_range; // output -} stbtt_pack_range; - -STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges); -// Creates character bitmaps from multiple ranges of characters stored in -// ranges. This will usually create a better-packed bitmap than multiple -// calls to stbtt_PackFontRange. - -STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects); -STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects); -// Those functions are called by stbtt_PackFontRanges(). If you want to -// pack multiple fonts or custom data into a same texture, you may copy -// the contents of stbtt_PackFontRanges() and create a custom version -// using those functions. - -STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h_oversample, unsigned int v_oversample); -// Oversampling a font increases the quality by allowing higher-quality subpixel -// positioning, and is especially valuable at smaller text sizes. -// -// This function sets the amount of oversampling for all following calls to -// stbtt_PackFontRange(s). The default (no oversampling) is achieved by -// h_oversample=1, v_oversample=1. The total number of pixels required is -// h_oversample*v_oversample larger than the default; for example, 2x2 -// oversampling requires 4x the storage of 1x1. For best results, render -// oversampled textures with bilinear filtering. Look at the readme in -// stb/tests/oversample for information about oversampled fonts - -STBTT_DEF void stbtt_GetPackedQuad(stbtt_packedchar *chardata, int pw, int ph, // same data as above - int char_index, // character to display - float *xpos, float *ypos, // pointers to current position in screen pixel space - stbtt_aligned_quad *q, // output: quad to draw - int align_to_integer); - -// this is an opaque structure that you shouldn't mess with which holds -// all the context needed from PackBegin to PackEnd. -struct stbtt_pack_context { - void *user_allocator_context; - void *pack_info; - int width; - int height; - int stride_in_bytes; - int padding; - unsigned int h_oversample, v_oversample; - unsigned char *pixels; - void *nodes; -}; - ////////////////////////////////////////////////////////////////////////////// // // FONT LOADING // // -STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index); +extern int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index); // Each .ttf/.ttc file may have more than one font. Each font has a sequential // index number starting from 0. Call this function to get the font offset for // a given index; it returns -1 if the index is out of range. A regular .ttf @@ -620,7 +476,7 @@ typedef struct stbtt_fontinfo int indexToLocFormat; // format needed to map from glyph index to glyph } stbtt_fontinfo; -STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data, int offset); +extern int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data, int offset); // Given an offset into the file that defines a font, this function builds // the necessary cached info for the rest of the system. You must allocate // the stbtt_fontinfo yourself, and stbtt_InitFont will fill it out. You don't @@ -632,7 +488,7 @@ STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data, in // // CHARACTER TO GLYPH-INDEX CONVERSIOn -STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codepoint); +int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codepoint); // If you're going to perform multiple operations on the same character // and you want a speed-up, call this function with the character you're // going to process, then use glyph-based functions instead of the @@ -644,7 +500,7 @@ STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codep // CHARACTER PROPERTIES // -STBTT_DEF float stbtt_ScaleForPixelHeight(const stbtt_fontinfo *info, float pixels); +extern float stbtt_ScaleForPixelHeight(const stbtt_fontinfo *info, float pixels); // computes a scale factor to produce a font whose "height" is 'pixels' tall. // Height is measured as the distance from the highest ascender to the lowest // descender; in other words, it's equivalent to calling stbtt_GetFontVMetrics @@ -652,12 +508,12 @@ STBTT_DEF float stbtt_ScaleForPixelHeight(const stbtt_fontinfo *info, float pixe // scale = pixels / (ascent - descent) // so if you prefer to measure height by the ascent only, use a similar calculation. -STBTT_DEF float stbtt_ScaleForMappingEmToPixels(const stbtt_fontinfo *info, float pixels); +extern float stbtt_ScaleForMappingEmToPixels(const stbtt_fontinfo *info, float pixels); // computes a scale factor to produce a font whose EM size is mapped to // 'pixels' tall. This is probably what traditional APIs compute, but // I'm not positive. -STBTT_DEF void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, int *descent, int *lineGap); +extern void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, int *descent, int *lineGap); // ascent is the coordinate above the baseline the font extends; descent // is the coordinate below the baseline the font extends (i.e. it is typically negative) // lineGap is the spacing between one row's descent and the next row's ascent... @@ -665,23 +521,24 @@ STBTT_DEF void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, in // these are expressed in unscaled coordinates, so you must multiply by // the scale factor for a given size -STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int *x0, int *y0, int *x1, int *y1); +extern void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int *x0, int *y0, int *x1, int *y1); // the bounding box around all possible characters -STBTT_DEF void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, int codepoint, int *advanceWidth, int *leftSideBearing); +extern void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, int codepoint, int *advanceWidth, int *leftSideBearing); // leftSideBearing is the offset from the current horizontal position to the left edge of the character // advanceWidth is the offset from the current horizontal position to the next horizontal position // these are expressed in unscaled coordinates -STBTT_DEF int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2); +extern int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2); // an additional amount to add to the 'advance' value between ch1 and ch2 +// @TODO; for now always returns 0! -STBTT_DEF int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, int *x0, int *y0, int *x1, int *y1); +extern int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, int *x0, int *y0, int *x1, int *y1); // Gets the bounding box of the visible part of the glyph, in unscaled coordinates -STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_index, int *advanceWidth, int *leftSideBearing); -STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2); -STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1); +extern void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_index, int *advanceWidth, int *leftSideBearing); +extern int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2); +extern int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1); // as above, but takes one or more glyph indices for greater efficiency @@ -709,22 +566,15 @@ STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, in } stbtt_vertex; #endif -STBTT_DEF int stbtt_IsGlyphEmpty(const stbtt_fontinfo *info, int glyph_index); +extern int stbtt_IsGlyphEmpty(const stbtt_fontinfo *info, int glyph_index); // returns non-zero if nothing is drawn for this glyph -STBTT_DEF int stbtt_GetCodepointShape(const stbtt_fontinfo *info, int unicode_codepoint, stbtt_vertex **vertices); -STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **vertices); +extern int stbtt_GetCodepointShape(const stbtt_fontinfo *info, int unicode_codepoint, stbtt_vertex **vertices); +extern int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **vertices); // returns # of vertices and fills *vertices with the pointer to them // these are expressed in "unscaled" coordinates -// -// The shape is a series of countours. Each one starts with -// a STBTT_moveto, then consists of a series of mixed -// STBTT_lineto and STBTT_curveto segments. A lineto -// draws a line from previous endpoint to its x,y; a curveto -// draws a quadratic bezier from previous endpoint to -// its x,y, using cx,cy as the bezier control point. -STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *vertices); +extern void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *vertices); // frees the data allocated above ////////////////////////////////////////////////////////////////////////////// @@ -732,10 +582,10 @@ STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *vertice // BITMAP RENDERING // -STBTT_DEF void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata); +extern void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata); // frees the bitmap allocated below -STBTT_DEF unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int codepoint, int *width, int *height, int *xoff, int *yoff); +extern unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int codepoint, int *width, int *height, int *xoff, int *yoff); // allocates a large-enough single-channel 8bpp bitmap and renders the // specified character/glyph at the specified scale into it, with // antialiasing. 0 is no coverage (transparent), 255 is fully covered (opaque). @@ -744,39 +594,39 @@ STBTT_DEF unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, fl // // xoff/yoff are the offset it pixel space from the glyph origin to the top-left of the bitmap -STBTT_DEF unsigned char *stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint, int *width, int *height, int *xoff, int *yoff); +extern unsigned char *stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint, int *width, int *height, int *xoff, int *yoff); // the same as stbtt_GetCodepoitnBitmap, but you can specify a subpixel // shift for the character -STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int codepoint); +extern void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int codepoint); // the same as stbtt_GetCodepointBitmap, but you pass in storage for the bitmap // in the form of 'output', with row spacing of 'out_stride' bytes. the bitmap // is clipped to out_w/out_h bytes. Call stbtt_GetCodepointBitmapBox to get the // width and height and positioning info for it first. -STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint); +extern void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint); // same as stbtt_MakeCodepointBitmap, but you can specify a subpixel // shift for the character -STBTT_DEF void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1); +extern void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1); // get the bbox of the bitmap centered around the glyph origin; so the // bitmap width is ix1-ix0, height is iy1-iy0, and location to place // the bitmap top left is (leftSideBearing*scale,iy0). // (Note that the bitmap uses y-increases-down, but the shape uses // y-increases-up, so CodepointBitmapBox and CodepointBox are inverted.) -STBTT_DEF void stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1); +extern void stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1); // same as stbtt_GetCodepointBitmapBox, but you can specify a subpixel // shift for the character // the following functions are equivalent to the above functions, but operate // on glyph indices instead of Unicode codepoints (for efficiency) -STBTT_DEF unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int glyph, int *width, int *height, int *xoff, int *yoff); -STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int glyph, int *width, int *height, int *xoff, int *yoff); -STBTT_DEF void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int glyph); -STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int glyph); -STBTT_DEF void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1); -STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y,float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1); +extern unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int glyph, int *width, int *height, int *xoff, int *yoff); +extern unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int glyph, int *width, int *height, int *xoff, int *yoff); +extern void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int glyph); +extern void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int glyph); +extern void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1); +extern void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y,float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1); // @TODO: don't expose this structure @@ -786,7 +636,7 @@ typedef struct unsigned char *pixels; } stbtt__bitmap; -STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result, float flatness_in_pixels, stbtt_vertex *vertices, int num_verts, float scale_x, float scale_y, float shift_x, float shift_y, int x_off, int y_off, int invert, void *userdata); +extern void stbtt_Rasterize(stbtt__bitmap *result, float flatness_in_pixels, stbtt_vertex *vertices, int num_verts, float scale_x, float scale_y, float shift_x, float shift_y, int x_off, int y_off, int invert, void *userdata); ////////////////////////////////////////////////////////////////////////////// // @@ -810,7 +660,7 @@ STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result, float flatness_in_pixels, // You have to have called stbtt_InitFont() first. -STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *fontdata, const char *name, int flags); +extern int stbtt_FindMatchingFont(const unsigned char *fontdata, const char *name, int flags); // returns the offset (not index) of the font that matches, or -1 if none // if you use STBTT_MACSTYLE_DONTCARE, use a font name like "Arial Bold". // if you use any other flag, use a font name like "Arial"; this checks @@ -821,11 +671,11 @@ STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *fontdata, const char * #define STBTT_MACSTYLE_UNDERSCORE 4 #define STBTT_MACSTYLE_NONE 8 // <= not same as 0, this makes us check the bitfield is 0 -STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2); +extern int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2); // returns 1/0 whether the first string interpreted as utf8 is identical to // the second string interpreted as big-endian utf16... useful for strings from next func -STBTT_DEF const char *stbtt_GetFontNameString(const stbtt_fontinfo *font, int *length, int platformID, int encodingID, int languageID, int nameID); +extern const char *stbtt_GetFontNameString(const stbtt_fontinfo *font, int *length, int platformID, int encodingID, int languageID, int nameID); // returns the string (which may be big-endian double byte, e.g. for unicode) // and puts the length in bytes in *length. // @@ -897,12 +747,6 @@ enum { // languageID for STBTT_PLATFORM_ID_MAC #ifdef STB_TRUETYPE_IMPLEMENTATION -#ifndef STBTT_MAX_OVERSAMPLE -#define STBTT_MAX_OVERSAMPLE 8 -#endif - -typedef int stbtt__test_oversample_pow2[(STBTT_MAX_OVERSAMPLE & (STBTT_MAX_OVERSAMPLE-1)) == 0 ? 1 : -1]; - ////////////////////////////////////////////////////////////////////////// // // accessors to parse data from file @@ -924,10 +768,10 @@ typedef int stbtt__test_oversample_pow2[(STBTT_MAX_OVERSAMPLE & (STBTT_MAX_OVERS #else - static stbtt_uint16 ttUSHORT(const stbtt_uint8 *p) { return p[0]*256 + p[1]; } - static stbtt_int16 ttSHORT(const stbtt_uint8 *p) { return p[0]*256 + p[1]; } - static stbtt_uint32 ttULONG(const stbtt_uint8 *p) { return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; } - static stbtt_int32 ttLONG(const stbtt_uint8 *p) { return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; } + stbtt_uint16 ttUSHORT(const stbtt_uint8 *p) { return p[0]*256 + p[1]; } + stbtt_int16 ttSHORT(const stbtt_uint8 *p) { return p[0]*256 + p[1]; } + stbtt_uint32 ttULONG(const stbtt_uint8 *p) { return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; } + stbtt_int32 ttLONG(const stbtt_uint8 *p) { return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; } #endif @@ -958,7 +802,7 @@ static stbtt_uint32 stbtt__find_table(stbtt_uint8 *data, stbtt_uint32 fontstart, return 0; } -STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *font_collection, int index) +int stbtt_GetFontOffsetForIndex(const unsigned char *font_collection, int index) { // if it's just a font, there's only one valid index if (stbtt__isfont(font_collection)) @@ -977,7 +821,7 @@ STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *font_collection, return -1; } -STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data2, int fontstart) +int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data2, int fontstart) { stbtt_uint8 *data = (stbtt_uint8 *) data2; stbtt_uint32 cmap, t; @@ -1020,11 +864,6 @@ STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data2, i break; } break; - case STBTT_PLATFORM_ID_UNICODE: - // Mac/iOS has these - // all the encodingIDs are unicode, so we don't bother to check it - info->index_map = cmap + ttULONG(data+encoding_record+4); - break; } } if (info->index_map == 0) @@ -1034,7 +873,7 @@ STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data2, i return 1; } -STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codepoint) +int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codepoint) { stbtt_uint8 *data = info->data; stbtt_uint32 index_map = info->index_map; @@ -1076,7 +915,10 @@ STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codep // now decrement to bias correctly to find smallest search -= 2; while (entrySelector) { + stbtt_uint16 start, end; searchRange >>= 1; + start = ttUSHORT(data + search + 2 + segcount*2 + 2); + end = ttUSHORT(data + search + 2); start = ttUSHORT(data + search + searchRange*2 + segcount*2 + 2); end = ttUSHORT(data + search + searchRange*2); if (unicode_codepoint > end) @@ -1126,7 +968,7 @@ STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codep return 0; } -STBTT_DEF int stbtt_GetCodepointShape(const stbtt_fontinfo *info, int unicode_codepoint, stbtt_vertex **vertices) +int stbtt_GetCodepointShape(const stbtt_fontinfo *info, int unicode_codepoint, stbtt_vertex **vertices) { return stbtt_GetGlyphShape(info, stbtt_FindGlyphIndex(info, unicode_codepoint), vertices); } @@ -1158,7 +1000,7 @@ static int stbtt__GetGlyfOffset(const stbtt_fontinfo *info, int glyph_index) return g1==g2 ? -1 : g1; // if length is 0, return -1 } -STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1) +int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1) { int g = stbtt__GetGlyfOffset(info, glyph_index); if (g < 0) return 0; @@ -1170,12 +1012,12 @@ STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int return 1; } -STBTT_DEF int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, int *x0, int *y0, int *x1, int *y1) +int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, int *x0, int *y0, int *x1, int *y1) { return stbtt_GetGlyphBox(info, stbtt_FindGlyphIndex(info,codepoint), x0,y0,x1,y1); } -STBTT_DEF int stbtt_IsGlyphEmpty(const stbtt_fontinfo *info, int glyph_index) +int stbtt_IsGlyphEmpty(const stbtt_fontinfo *info, int glyph_index) { stbtt_int16 numberOfContours; int g = stbtt__GetGlyfOffset(info, glyph_index); @@ -1200,7 +1042,7 @@ static int stbtt__close_shape(stbtt_vertex *vertices, int num_vertices, int was_ return num_vertices; } -STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **pvertices) +int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **pvertices) { stbtt_int16 numberOfContours; stbtt_uint8 *endPtsOfContours; @@ -1381,8 +1223,8 @@ STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, s } // Find transformation scales. - m = (float) STBTT_sqrt(mtx[0]*mtx[0] + mtx[1]*mtx[1]); - n = (float) STBTT_sqrt(mtx[2]*mtx[2] + mtx[3]*mtx[3]); + m = (float) sqrt(mtx[0]*mtx[0] + mtx[1]*mtx[1]); + n = (float) sqrt(mtx[2]*mtx[2] + mtx[3]*mtx[3]); // Get indexed glyph. comp_num_verts = stbtt_GetGlyphShape(info, gidx, &comp_verts); @@ -1405,8 +1247,8 @@ STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, s if (comp_verts) STBTT_free(comp_verts, info->userdata); return 0; } - if (num_vertices > 0) STBTT_memcpy(tmp, vertices, num_vertices*sizeof(stbtt_vertex)); - STBTT_memcpy(tmp+num_vertices, comp_verts, comp_num_verts*sizeof(stbtt_vertex)); + if (num_vertices > 0) memcpy(tmp, vertices, num_vertices*sizeof(stbtt_vertex)); + memcpy(tmp+num_vertices, comp_verts, comp_num_verts*sizeof(stbtt_vertex)); if (vertices) STBTT_free(vertices, info->userdata); vertices = tmp; STBTT_free(comp_verts, info->userdata); @@ -1426,7 +1268,7 @@ STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, s return num_vertices; } -STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_index, int *advanceWidth, int *leftSideBearing) +void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_index, int *advanceWidth, int *leftSideBearing) { stbtt_uint16 numOfLongHorMetrics = ttUSHORT(info->data+info->hhea + 34); if (glyph_index < numOfLongHorMetrics) { @@ -1438,7 +1280,7 @@ STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_inde } } -STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2) +int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2) { stbtt_uint8 *data = info->data + info->kern; stbtt_uint32 needle, straw; @@ -1468,26 +1310,26 @@ STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1, return 0; } -STBTT_DEF int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2) +int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2) { if (!info->kern) // if no kerning table, don't waste time looking up both codepoint->glyphs return 0; return stbtt_GetGlyphKernAdvance(info, stbtt_FindGlyphIndex(info,ch1), stbtt_FindGlyphIndex(info,ch2)); } -STBTT_DEF void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, int codepoint, int *advanceWidth, int *leftSideBearing) +void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, int codepoint, int *advanceWidth, int *leftSideBearing) { stbtt_GetGlyphHMetrics(info, stbtt_FindGlyphIndex(info,codepoint), advanceWidth, leftSideBearing); } -STBTT_DEF void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, int *descent, int *lineGap) +void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, int *descent, int *lineGap) { if (ascent ) *ascent = ttSHORT(info->data+info->hhea + 4); if (descent) *descent = ttSHORT(info->data+info->hhea + 6); if (lineGap) *lineGap = ttSHORT(info->data+info->hhea + 8); } -STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int *x0, int *y0, int *x1, int *y1) +void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int *x0, int *y0, int *x1, int *y1) { *x0 = ttSHORT(info->data + info->head + 36); *y0 = ttSHORT(info->data + info->head + 38); @@ -1495,19 +1337,19 @@ STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int *x0, int *y1 = ttSHORT(info->data + info->head + 42); } -STBTT_DEF float stbtt_ScaleForPixelHeight(const stbtt_fontinfo *info, float height) +float stbtt_ScaleForPixelHeight(const stbtt_fontinfo *info, float height) { int fheight = ttSHORT(info->data + info->hhea + 4) - ttSHORT(info->data + info->hhea + 6); return (float) height / fheight; } -STBTT_DEF float stbtt_ScaleForMappingEmToPixels(const stbtt_fontinfo *info, float pixels) +float stbtt_ScaleForMappingEmToPixels(const stbtt_fontinfo *info, float pixels) { int unitsPerEm = ttUSHORT(info->data + info->head + 18); return pixels / unitsPerEm; } -STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *v) +void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *v) { STBTT_free(v, info->userdata); } @@ -1517,35 +1359,28 @@ STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *v) // antialiasing software rasterizer // -STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y,float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1) +void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y,float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1) { int x0,y0,x1,y1; - if (!stbtt_GetGlyphBox(font, glyph, &x0,&y0,&x1,&y1)) { - // e.g. space character - if (ix0) *ix0 = 0; - if (iy0) *iy0 = 0; - if (ix1) *ix1 = 0; - if (iy1) *iy1 = 0; - } else { - // move to integral bboxes (treating pixels as little squares, what pixels get touched)? - if (ix0) *ix0 = STBTT_ifloor( x0 * scale_x + shift_x); - if (iy0) *iy0 = STBTT_ifloor(-y1 * scale_y + shift_y); - if (ix1) *ix1 = STBTT_iceil ( x1 * scale_x + shift_x); - if (iy1) *iy1 = STBTT_iceil (-y0 * scale_y + shift_y); - } + if (!stbtt_GetGlyphBox(font, glyph, &x0,&y0,&x1,&y1)) + x0=y0=x1=y1=0; // e.g. space character + // now move to integral bboxes (treating pixels as little squares, what pixels get touched)? + if (ix0) *ix0 = STBTT_ifloor(x0 * scale_x + shift_x); + if (iy0) *iy0 = -STBTT_iceil (y1 * scale_y + shift_y); + if (ix1) *ix1 = STBTT_iceil (x1 * scale_x + shift_x); + if (iy1) *iy1 = -STBTT_ifloor(y0 * scale_y + shift_y); } - -STBTT_DEF void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1) +void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1) { stbtt_GetGlyphBitmapBoxSubpixel(font, glyph, scale_x, scale_y,0.0f,0.0f, ix0, iy0, ix1, iy1); } -STBTT_DEF void stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1) +void stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1) { stbtt_GetGlyphBitmapBoxSubpixel(font, stbtt_FindGlyphIndex(font,codepoint), scale_x, scale_y,shift_x,shift_y, ix0,iy0,ix1,iy1); } -STBTT_DEF void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1) +void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1) { stbtt_GetCodepointBitmapBoxSubpixel(font, codepoint, scale_x, scale_y,0.0f,0.0f, ix0,iy0,ix1,iy1); } @@ -1781,9 +1616,9 @@ static void stbtt__rasterize(stbtt__bitmap *result, stbtt__point *pts, int *wcou a=j,b=k; } e[n].x0 = p[a].x * scale_x + shift_x; - e[n].y0 = (p[a].y * y_scale_inv + shift_y) * vsubsample; + e[n].y0 = p[a].y * y_scale_inv * vsubsample + shift_y; e[n].x1 = p[b].x * scale_x + shift_x; - e[n].y1 = (p[b].y * y_scale_inv + shift_y) * vsubsample; + e[n].y1 = p[b].y * y_scale_inv * vsubsample + shift_y; ++n; } } @@ -1826,7 +1661,7 @@ static int stbtt__tesselate_curve(stbtt__point *points, int *num_points, float x } // returns number of contours -static stbtt__point *stbtt_FlattenCurves(stbtt_vertex *vertices, int num_verts, float objspace_flatness, int **contour_lengths, int *num_contours, void *userdata) +stbtt__point *stbtt_FlattenCurves(stbtt_vertex *vertices, int num_verts, float objspace_flatness, int **contour_lengths, int *num_contours, void *userdata) { stbtt__point *points=0; int num_points=0; @@ -1895,7 +1730,7 @@ error: return NULL; } -STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result, float flatness_in_pixels, stbtt_vertex *vertices, int num_verts, float scale_x, float scale_y, float shift_x, float shift_y, int x_off, int y_off, int invert, void *userdata) +void stbtt_Rasterize(stbtt__bitmap *result, float flatness_in_pixels, stbtt_vertex *vertices, int num_verts, float scale_x, float scale_y, float shift_x, float shift_y, int x_off, int y_off, int invert, void *userdata) { float scale = scale_x > scale_y ? scale_y : scale_x; int winding_count, *winding_lengths; @@ -1907,12 +1742,12 @@ STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result, float flatness_in_pixels, } } -STBTT_DEF void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata) +void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata) { STBTT_free(bitmap, userdata); } -STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int glyph, int *width, int *height, int *xoff, int *yoff) +unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int glyph, int *width, int *height, int *xoff, int *yoff) { int ix0,iy0,ix1,iy1; stbtt__bitmap gbm; @@ -1925,7 +1760,7 @@ STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info scale_y = scale_x; } - stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0,&iy0,&ix1,&iy1); + stbtt_GetGlyphBitmapBox(info, glyph, scale_x, scale_y, &ix0,&iy0,&ix1,&iy1); // now we get the size gbm.w = (ix1 - ix0); @@ -1949,12 +1784,12 @@ STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info return gbm.pixels; } -STBTT_DEF unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int glyph, int *width, int *height, int *xoff, int *yoff) +unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int glyph, int *width, int *height, int *xoff, int *yoff) { return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y, 0.0f, 0.0f, glyph, width, height, xoff, yoff); } -STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int glyph) +void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int glyph) { int ix0,iy0; stbtt_vertex *vertices; @@ -1973,27 +1808,27 @@ STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info, unsigne STBTT_free(vertices, info->userdata); } -STBTT_DEF void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int glyph) +void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int glyph) { stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, 0.0f,0.0f, glyph); } -STBTT_DEF unsigned char *stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint, int *width, int *height, int *xoff, int *yoff) +unsigned char *stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint, int *width, int *height, int *xoff, int *yoff) { return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y,shift_x,shift_y, stbtt_FindGlyphIndex(info,codepoint), width,height,xoff,yoff); } -STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint) +void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint) { stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, shift_x, shift_y, stbtt_FindGlyphIndex(info,codepoint)); } -STBTT_DEF unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int codepoint, int *width, int *height, int *xoff, int *yoff) +unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int codepoint, int *width, int *height, int *xoff, int *yoff) { return stbtt_GetCodepointBitmapSubpixel(info, scale_x, scale_y, 0.0f,0.0f, codepoint, width,height,xoff,yoff); } -STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int codepoint) +void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int codepoint) { stbtt_MakeCodepointBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, 0.0f,0.0f, codepoint); } @@ -2004,7 +1839,7 @@ STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned ch // // This is SUPER-CRAPPY packing to keep source code small -STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset, // font location (use offset=0 for plain .ttf) +extern int stbtt_BakeFontBitmap(const unsigned char *data, int offset, // font location (use offset=0 for plain .ttf) float pixel_height, // height of font in pixels unsigned char *pixels, int pw, int ph, // bitmap to be filled in int first_char, int num_chars, // characters to bake @@ -2013,8 +1848,7 @@ STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset, // fo float scale; int x,y,bottom_y, i; stbtt_fontinfo f; - if (!stbtt_InitFont(&f, data, offset)) - return -1; + stbtt_InitFont(&f, data, offset); STBTT_memset(pixels, 0, pw*ph); // background of 0 around pixels x=y=1; bottom_y = 1; @@ -2042,14 +1876,14 @@ STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset, // fo chardata[i].xadvance = scale * advance; chardata[i].xoff = (float) x0; chardata[i].yoff = (float) y0; - x = x + gw + 1; - if (y+gh+1 > bottom_y) - bottom_y = y+gh+1; + x = x + gw + 2; + if (y+gh+2 > bottom_y) + bottom_y = y+gh+2; } return bottom_y; } -STBTT_DEF void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int opengl_fillrule) +void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int opengl_fillrule) { float d3d_bias = opengl_fillrule ? 0 : -0.5f; float ipw = 1.0f / pw, iph = 1.0f / ph; @@ -2070,431 +1904,6 @@ STBTT_DEF void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, int *xpos += b->xadvance; } -////////////////////////////////////////////////////////////////////////////// -// -// rectangle packing replacement routines if you don't have stb_rect_pack.h -// - -#ifndef STB_RECT_PACK_VERSION -#ifdef _MSC_VER -#define STBTT__NOTUSED(v) (void)(v) -#else -#define STBTT__NOTUSED(v) (void)sizeof(v) -#endif - -typedef int stbrp_coord; - -//////////////////////////////////////////////////////////////////////////////////// -// // -// // -// COMPILER WARNING ?!?!? // -// // -// // -// if you get a compile warning due to these symbols being defined more than // -// once, move #include "stb_rect_pack.h" before #include "stb_truetype.h" // -// // -//////////////////////////////////////////////////////////////////////////////////// - -typedef struct -{ - int width,height; - int x,y,bottom_y; -} stbrp_context; - -typedef struct -{ - unsigned char x; -} stbrp_node; - -struct stbrp_rect -{ - stbrp_coord x,y; - int id,w,h,was_packed; -}; - -static void stbrp_init_target(stbrp_context *con, int pw, int ph, stbrp_node *nodes, int num_nodes) -{ - con->width = pw; - con->height = ph; - con->x = 0; - con->y = 0; - con->bottom_y = 0; - STBTT__NOTUSED(nodes); - STBTT__NOTUSED(num_nodes); -} - -static void stbrp_pack_rects(stbrp_context *con, stbrp_rect *rects, int num_rects) -{ - int i; - for (i=0; i < num_rects; ++i) { - if (con->x + rects[i].w > con->width) { - con->x = 0; - con->y = con->bottom_y; - } - if (con->y + rects[i].h > con->height) - break; - rects[i].x = con->x; - rects[i].y = con->y; - rects[i].was_packed = 1; - con->x += rects[i].w; - if (con->y + rects[i].h > con->bottom_y) - con->bottom_y = con->y + rects[i].h; - } - for ( ; i < num_rects; ++i) - rects[i].was_packed = 0; -} -#endif - -////////////////////////////////////////////////////////////////////////////// -// -// bitmap baking -// -// This is SUPER-AWESOME (tm Ryan Gordon) packing using stb_rect_pack.h. If -// stb_rect_pack.h isn't available, it uses the BakeFontBitmap strategy. - -STBTT_DEF int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, int pw, int ph, int stride_in_bytes, int padding, void *alloc_context) -{ - stbrp_context *context = (stbrp_context *) STBTT_malloc(sizeof(*context) ,alloc_context); - int num_nodes = pw - padding; - stbrp_node *nodes = (stbrp_node *) STBTT_malloc(sizeof(*nodes ) * num_nodes,alloc_context); - - if (context == NULL || nodes == NULL) { - if (context != NULL) STBTT_free(context, alloc_context); - if (nodes != NULL) STBTT_free(nodes , alloc_context); - return 0; - } - - spc->user_allocator_context = alloc_context; - spc->width = pw; - spc->height = ph; - spc->pixels = pixels; - spc->pack_info = context; - spc->nodes = nodes; - spc->padding = padding; - spc->stride_in_bytes = stride_in_bytes != 0 ? stride_in_bytes : pw; - spc->h_oversample = 1; - spc->v_oversample = 1; - - stbrp_init_target(context, pw-padding, ph-padding, nodes, num_nodes); - - if (pixels) - STBTT_memset(pixels, 0, pw*ph); // background of 0 around pixels - - return 1; -} - -STBTT_DEF void stbtt_PackEnd (stbtt_pack_context *spc) -{ - STBTT_free(spc->nodes , spc->user_allocator_context); - STBTT_free(spc->pack_info, spc->user_allocator_context); -} - -STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h_oversample, unsigned int v_oversample) -{ - STBTT_assert(h_oversample <= STBTT_MAX_OVERSAMPLE); - STBTT_assert(v_oversample <= STBTT_MAX_OVERSAMPLE); - if (h_oversample <= STBTT_MAX_OVERSAMPLE) - spc->h_oversample = h_oversample; - if (v_oversample <= STBTT_MAX_OVERSAMPLE) - spc->v_oversample = v_oversample; -} - -#define STBTT__OVER_MASK (STBTT_MAX_OVERSAMPLE-1) - -static void stbtt__h_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width) -{ - unsigned char buffer[STBTT_MAX_OVERSAMPLE]; - int safe_w = w - kernel_width; - int j; - for (j=0; j < h; ++j) { - int i; - unsigned int total; - memset(buffer, 0, kernel_width); - - total = 0; - - // make kernel_width a constant in common cases so compiler can optimize out the divide - switch (kernel_width) { - case 2: - for (i=0; i <= safe_w; ++i) { - total += pixels[i] - buffer[i & STBTT__OVER_MASK]; - buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i]; - pixels[i] = (unsigned char) (total / 2); - } - break; - case 3: - for (i=0; i <= safe_w; ++i) { - total += pixels[i] - buffer[i & STBTT__OVER_MASK]; - buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i]; - pixels[i] = (unsigned char) (total / 3); - } - break; - case 4: - for (i=0; i <= safe_w; ++i) { - total += pixels[i] - buffer[i & STBTT__OVER_MASK]; - buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i]; - pixels[i] = (unsigned char) (total / 4); - } - break; - default: - for (i=0; i <= safe_w; ++i) { - total += pixels[i] - buffer[i & STBTT__OVER_MASK]; - buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i]; - pixels[i] = (unsigned char) (total / kernel_width); - } - break; - } - - for (; i < w; ++i) { - STBTT_assert(pixels[i] == 0); - total -= buffer[i & STBTT__OVER_MASK]; - pixels[i] = (unsigned char) (total / kernel_width); - } - - pixels += stride_in_bytes; - } -} - -static void stbtt__v_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width) -{ - unsigned char buffer[STBTT_MAX_OVERSAMPLE]; - int safe_h = h - kernel_width; - int j; - for (j=0; j < w; ++j) { - int i; - unsigned int total; - memset(buffer, 0, kernel_width); - - total = 0; - - // make kernel_width a constant in common cases so compiler can optimize out the divide - switch (kernel_width) { - case 2: - for (i=0; i <= safe_h; ++i) { - total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; - buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes]; - pixels[i*stride_in_bytes] = (unsigned char) (total / 2); - } - break; - case 3: - for (i=0; i <= safe_h; ++i) { - total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; - buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes]; - pixels[i*stride_in_bytes] = (unsigned char) (total / 3); - } - break; - case 4: - for (i=0; i <= safe_h; ++i) { - total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; - buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes]; - pixels[i*stride_in_bytes] = (unsigned char) (total / 4); - } - break; - default: - for (i=0; i <= safe_h; ++i) { - total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; - buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes]; - pixels[i*stride_in_bytes] = (unsigned char) (total / kernel_width); - } - break; - } - - for (; i < h; ++i) { - STBTT_assert(pixels[i*stride_in_bytes] == 0); - total -= buffer[i & STBTT__OVER_MASK]; - pixels[i*stride_in_bytes] = (unsigned char) (total / kernel_width); - } - - pixels += 1; - } -} - -static float stbtt__oversample_shift(int oversample) -{ - if (!oversample) - return 0.0f; - - // The prefilter is a box filter of width "oversample", - // which shifts phase by (oversample - 1)/2 pixels in - // oversampled space. We want to shift in the opposite - // direction to counter this. - return (float)-(oversample - 1) / (2.0f * (float)oversample); -} - -// rects array must be big enough to accommodate all characters in the given ranges -STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects) -{ - int i,j,k; - - k=0; - for (i=0; i < num_ranges; ++i) { - float fh = ranges[i].font_size; - float scale = fh > 0 ? stbtt_ScaleForPixelHeight(info, fh) : stbtt_ScaleForMappingEmToPixels(info, -fh); - for (j=0; j < ranges[i].num_chars_in_range; ++j) { - int x0,y0,x1,y1; - int glyph = stbtt_FindGlyphIndex(info,ranges[i].first_unicode_char_in_range + j); - if (glyph) { - stbtt_GetGlyphBitmapBoxSubpixel(info,glyph, - scale * spc->h_oversample, - scale * spc->v_oversample, - 0,0, - &x0,&y0,&x1,&y1); - rects[k].w = (stbrp_coord) (x1-x0 + spc->padding + spc->h_oversample-1); - rects[k].h = (stbrp_coord) (y1-y0 + spc->padding + spc->v_oversample-1); - } else { - rects[k].w = rects[k].h = 1; - } - ++k; - } - } - - return k; -} - -// rects array must be big enough to accommodate all characters in the given ranges -STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects) -{ - float recip_h = 1.0f / spc->h_oversample; - float recip_v = 1.0f / spc->v_oversample; - float sub_x = stbtt__oversample_shift(spc->h_oversample); - float sub_y = stbtt__oversample_shift(spc->v_oversample); - int i,j,k, return_value = 1; - - k = 0; - for (i=0; i < num_ranges; ++i) { - float fh = ranges[i].font_size; - float scale = fh > 0 ? stbtt_ScaleForPixelHeight(info, fh) : stbtt_ScaleForMappingEmToPixels(info, -fh); - for (j=0; j < ranges[i].num_chars_in_range; ++j) { - stbrp_rect *r = &rects[k]; - if (r->was_packed) { - stbtt_packedchar *bc = &ranges[i].chardata_for_range[j]; - int advance, lsb, x0,y0,x1,y1; - int glyph = stbtt_FindGlyphIndex(info, ranges[i].first_unicode_char_in_range + j); - stbrp_coord pad = (stbrp_coord) spc->padding; - - // pad on left and top - r->x += pad; - r->y += pad; - r->w -= pad; - r->h -= pad; - stbtt_GetGlyphHMetrics(info, glyph, &advance, &lsb); - stbtt_GetGlyphBitmapBox(info, glyph, - scale * spc->h_oversample, - scale * spc->v_oversample, - &x0,&y0,&x1,&y1); - stbtt_MakeGlyphBitmapSubpixel(info, - spc->pixels + r->x + r->y*spc->stride_in_bytes, - r->w - spc->h_oversample+1, - r->h - spc->v_oversample+1, - spc->stride_in_bytes, - scale * spc->h_oversample, - scale * spc->v_oversample, - 0,0, - glyph); - - if (spc->h_oversample > 1) - stbtt__h_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes, - r->w, r->h, spc->stride_in_bytes, - spc->h_oversample); - - if (spc->v_oversample > 1) - stbtt__v_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes, - r->w, r->h, spc->stride_in_bytes, - spc->v_oversample); - - bc->x0 = (stbtt_int16) r->x; - bc->y0 = (stbtt_int16) r->y; - bc->x1 = (stbtt_int16) (r->x + r->w); - bc->y1 = (stbtt_int16) (r->y + r->h); - bc->xadvance = scale * advance; - bc->xoff = (float) x0 * recip_h + sub_x; - bc->yoff = (float) y0 * recip_v + sub_y; - bc->xoff2 = (x0 + r->w) * recip_h + sub_x; - bc->yoff2 = (y0 + r->h) * recip_v + sub_y; - } else { - return_value = 0; // if any fail, report failure - } - - ++k; - } - } - - return return_value; -} - -STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges) -{ - stbtt_fontinfo info; - int i,j,n, return_value = 1; - stbrp_context *context = (stbrp_context *) spc->pack_info; - stbrp_rect *rects; - - // flag all characters as NOT packed - for (i=0; i < num_ranges; ++i) - for (j=0; j < ranges[i].num_chars_in_range; ++j) - ranges[i].chardata_for_range[j].x0 = - ranges[i].chardata_for_range[j].y0 = - ranges[i].chardata_for_range[j].x1 = - ranges[i].chardata_for_range[j].y1 = 0; - - n = 0; - for (i=0; i < num_ranges; ++i) - n += ranges[i].num_chars_in_range; - - rects = (stbrp_rect *) STBTT_malloc(sizeof(*rects) * n, spc->user_allocator_context); - if (rects == NULL) - return 0; - - stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata,font_index)); - - n = stbtt_PackFontRangesGatherRects(spc, &info, ranges, num_ranges, rects); - - stbrp_pack_rects(context, rects, n); - - return_value = stbtt_PackFontRangesRenderIntoRects(spc, &info, ranges, num_ranges, rects); - - return return_value; -} - -STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, float font_size, - int first_unicode_char_in_range, int num_chars_in_range, stbtt_packedchar *chardata_for_range) -{ - stbtt_pack_range range; - range.first_unicode_char_in_range = first_unicode_char_in_range; - range.num_chars_in_range = num_chars_in_range; - range.chardata_for_range = chardata_for_range; - range.font_size = font_size; - return stbtt_PackFontRanges(spc, fontdata, font_index, &range, 1); -} - -STBTT_DEF void stbtt_GetPackedQuad(stbtt_packedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int align_to_integer) -{ - float ipw = 1.0f / pw, iph = 1.0f / ph; - stbtt_packedchar *b = chardata + char_index; - - if (align_to_integer) { - float x = (float) STBTT_ifloor((*xpos + b->xoff) + 0.5); - float y = (float) STBTT_ifloor((*ypos + b->yoff) + 0.5); - q->x0 = x; - q->y0 = y; - q->x1 = x + b->xoff2 - b->xoff; - q->y1 = y + b->yoff2 - b->yoff; - } else { - q->x0 = *xpos + b->xoff; - q->y0 = *ypos + b->yoff; - q->x1 = *xpos + b->xoff2; - q->y1 = *ypos + b->yoff2; - } - - q->s0 = b->x0 * ipw; - q->t0 = b->y0 * iph; - q->s1 = b->x1 * ipw; - q->t1 = b->y1 * iph; - - *xpos += b->xadvance; -} - - ////////////////////////////////////////////////////////////////////////////// // // font name matching -- recommended not to use this @@ -2540,14 +1949,14 @@ static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(const stbtt_uint8 return i; } -STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2) +int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2) { return len1 == stbtt__CompareUTF8toUTF16_bigendian_prefix((const stbtt_uint8*) s1, len1, (const stbtt_uint8*) s2, len2); } // returns results in whatever encoding you request... but note that 2-byte encodings // will be BIG-ENDIAN... use stbtt_CompareUTF8toUTF16_bigendian() to compare -STBTT_DEF const char *stbtt_GetFontNameString(const stbtt_fontinfo *font, int *length, int platformID, int encodingID, int languageID, int nameID) +const char *stbtt_GetFontNameString(const stbtt_fontinfo *font, int *length, int platformID, int encodingID, int languageID, int nameID) { stbtt_int32 i,count,stringOffset; stbtt_uint8 *fc = font->data; @@ -2583,16 +1992,14 @@ static int stbtt__matchpair(stbtt_uint8 *fc, stbtt_uint32 nm, stbtt_uint8 *name, // is this a Unicode encoding? if (platform == 0 || (platform == 3 && encoding == 1) || (platform == 3 && encoding == 10)) { - stbtt_int32 slen = ttUSHORT(fc+loc+8); - stbtt_int32 off = ttUSHORT(fc+loc+10); + stbtt_int32 slen = ttUSHORT(fc+loc+8), off = ttUSHORT(fc+loc+10); // check if there's a prefix match stbtt_int32 matchlen = stbtt__CompareUTF8toUTF16_bigendian_prefix(name, nlen, fc+stringOffset+off,slen); if (matchlen >= 0) { // check for target_id+1 immediately following, with same encoding & language if (i+1 < count && ttUSHORT(fc+loc+12+6) == next_id && ttUSHORT(fc+loc+12) == platform && ttUSHORT(fc+loc+12+2) == encoding && ttUSHORT(fc+loc+12+4) == language) { - slen = ttUSHORT(fc+loc+12+8); - off = ttUSHORT(fc+loc+12+10); + stbtt_int32 slen = ttUSHORT(fc+loc+12+8), off = ttUSHORT(fc+loc+12+10); if (slen == 0) { if (matchlen == nlen) return 1; @@ -2644,7 +2051,7 @@ static int stbtt__matches(stbtt_uint8 *fc, stbtt_uint32 offset, stbtt_uint8 *nam return 0; } -STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *font_collection, const char *name_utf8, stbtt_int32 flags) +int stbtt_FindMatchingFont(const unsigned char *font_collection, const char *name_utf8, stbtt_int32 flags) { stbtt_int32 i; for (i=0;;++i) { @@ -2655,4 +2062,4 @@ STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *font_collection, const } } -#endif // STB_TRUETYPE_IMPLEMENTATION +#endif // STB_TRUETYPE_IMPLEMENTATION \ No newline at end of file diff --git a/testbed/scenes/collisionshapes/CollisionShapesScene.cpp b/testbed/scenes/collisionshapes/CollisionShapesScene.cpp index 784243e2..040fec2b 100644 --- a/testbed/scenes/collisionshapes/CollisionShapesScene.cpp +++ b/testbed/scenes/collisionshapes/CollisionShapesScene.cpp @@ -216,6 +216,17 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name) // Change the material properties of the rigid body rp3d::Material& material = mFloor->getRigidBody()->getMaterial(); material.setBounciness(rp3d::decimal(0.2)); + + // Get the physics engine parameters + mEngineSettings.isGravityEnabled = mDynamicsWorld->isGravityEnabled(); + rp3d::Vector3 gravityVector = mDynamicsWorld->getGravity(); + mEngineSettings.gravity = openglframework::Vector3(gravityVector.x, gravityVector.y, gravityVector.z); + mEngineSettings.isSleepingEnabled = mDynamicsWorld->isSleepingEnabled(); + mEngineSettings.sleepLinearVelocity = mDynamicsWorld->getSleepLinearVelocity(); + mEngineSettings.sleepAngularVelocity = mDynamicsWorld->getSleepAngularVelocity(); + mEngineSettings.nbPositionSolverIterations = mDynamicsWorld->getNbIterationsPositionSolver(); + mEngineSettings.nbVelocitySolverIterations = mDynamicsWorld->getNbIterationsVelocitySolver(); + mEngineSettings.timeBeforeSleep = mDynamicsWorld->getTimeBeforeSleep(); } // Destructor @@ -309,6 +320,18 @@ CollisionShapesScene::~CollisionShapesScene() { // Update the physics world (take a simulation step) void CollisionShapesScene::updatePhysics() { + // Update the physics engine parameters + mDynamicsWorld->setIsGratityEnabled(mEngineSettings.isGravityEnabled); + rp3d::Vector3 gravity(mEngineSettings.gravity.x, mEngineSettings.gravity.y, + mEngineSettings.gravity.z); + mDynamicsWorld->setGravity(gravity); + mDynamicsWorld->enableSleeping(mEngineSettings.isSleepingEnabled); + mDynamicsWorld->setSleepLinearVelocity(mEngineSettings.sleepLinearVelocity); + mDynamicsWorld->setSleepAngularVelocity(mEngineSettings.sleepAngularVelocity); + mDynamicsWorld->setNbIterationsPositionSolver(mEngineSettings.nbPositionSolverIterations); + mDynamicsWorld->setNbIterationsVelocitySolver(mEngineSettings.nbVelocitySolverIterations); + mDynamicsWorld->setTimeBeforeSleep(mEngineSettings.timeBeforeSleep); + // Take a simulation step mDynamicsWorld->update(mEngineSettings.timeStep); } diff --git a/testbed/scenes/cubes/CubesScene.cpp b/testbed/scenes/cubes/CubesScene.cpp index 4842dd34..6cb500ea 100644 --- a/testbed/scenes/cubes/CubesScene.cpp +++ b/testbed/scenes/cubes/CubesScene.cpp @@ -89,6 +89,17 @@ CubesScene::CubesScene(const std::string& name) // Change the material properties of the floor rigid body rp3d::Material& material = mFloor->getRigidBody()->getMaterial(); material.setBounciness(rp3d::decimal(0.3)); + + // Get the physics engine parameters + mEngineSettings.isGravityEnabled = mDynamicsWorld->isGravityEnabled(); + rp3d::Vector3 gravityVector = mDynamicsWorld->getGravity(); + mEngineSettings.gravity = openglframework::Vector3(gravityVector.x, gravityVector.y, gravityVector.z); + mEngineSettings.isSleepingEnabled = mDynamicsWorld->isSleepingEnabled(); + mEngineSettings.sleepLinearVelocity = mDynamicsWorld->getSleepLinearVelocity(); + mEngineSettings.sleepAngularVelocity = mDynamicsWorld->getSleepAngularVelocity(); + mEngineSettings.nbPositionSolverIterations = mDynamicsWorld->getNbIterationsPositionSolver(); + mEngineSettings.nbVelocitySolverIterations = mDynamicsWorld->getNbIterationsVelocitySolver(); + mEngineSettings.timeBeforeSleep = mDynamicsWorld->getTimeBeforeSleep(); } // Destructor @@ -120,6 +131,19 @@ CubesScene::~CubesScene() { // Update the physics world (take a simulation step) void CubesScene::updatePhysics() { + + // Update the physics engine parameters + mDynamicsWorld->setIsGratityEnabled(mEngineSettings.isGravityEnabled); + rp3d::Vector3 gravity(mEngineSettings.gravity.x, mEngineSettings.gravity.y, + mEngineSettings.gravity.z); + mDynamicsWorld->setGravity(gravity); + mDynamicsWorld->enableSleeping(mEngineSettings.isSleepingEnabled); + mDynamicsWorld->setSleepLinearVelocity(mEngineSettings.sleepLinearVelocity); + mDynamicsWorld->setSleepAngularVelocity(mEngineSettings.sleepAngularVelocity); + mDynamicsWorld->setNbIterationsPositionSolver(mEngineSettings.nbPositionSolverIterations); + mDynamicsWorld->setNbIterationsVelocitySolver(mEngineSettings.nbVelocitySolverIterations); + mDynamicsWorld->setTimeBeforeSleep(mEngineSettings.timeBeforeSleep); + // Take a simulation step mDynamicsWorld->update(mEngineSettings.timeStep); } diff --git a/testbed/scenes/joints/JointsScene.cpp b/testbed/scenes/joints/JointsScene.cpp index 27c09e99..ea5e413b 100644 --- a/testbed/scenes/joints/JointsScene.cpp +++ b/testbed/scenes/joints/JointsScene.cpp @@ -72,6 +72,17 @@ JointsScene::JointsScene(const std::string& name) // Create the floor createFloor(); + + // Get the physics engine parameters + mEngineSettings.isGravityEnabled = mDynamicsWorld->isGravityEnabled(); + rp3d::Vector3 gravityVector = mDynamicsWorld->getGravity(); + mEngineSettings.gravity = openglframework::Vector3(gravityVector.x, gravityVector.y, gravityVector.z); + mEngineSettings.isSleepingEnabled = mDynamicsWorld->isSleepingEnabled(); + mEngineSettings.sleepLinearVelocity = mDynamicsWorld->getSleepLinearVelocity(); + mEngineSettings.sleepAngularVelocity = mDynamicsWorld->getSleepAngularVelocity(); + mEngineSettings.nbPositionSolverIterations = mDynamicsWorld->getNbIterationsPositionSolver(); + mEngineSettings.nbVelocitySolverIterations = mDynamicsWorld->getNbIterationsVelocitySolver(); + mEngineSettings.timeBeforeSleep = mDynamicsWorld->getTimeBeforeSleep(); } // Destructor @@ -119,6 +130,18 @@ JointsScene::~JointsScene() { // Update the physics world (take a simulation step) void JointsScene::updatePhysics() { + // Update the physics engine parameters + mDynamicsWorld->setIsGratityEnabled(mEngineSettings.isGravityEnabled); + rp3d::Vector3 gravity(mEngineSettings.gravity.x, mEngineSettings.gravity.y, + mEngineSettings.gravity.z); + mDynamicsWorld->setGravity(gravity); + mDynamicsWorld->enableSleeping(mEngineSettings.isSleepingEnabled); + mDynamicsWorld->setSleepLinearVelocity(mEngineSettings.sleepLinearVelocity); + mDynamicsWorld->setSleepAngularVelocity(mEngineSettings.sleepAngularVelocity); + mDynamicsWorld->setNbIterationsPositionSolver(mEngineSettings.nbPositionSolverIterations); + mDynamicsWorld->setNbIterationsVelocitySolver(mEngineSettings.nbVelocitySolverIterations); + mDynamicsWorld->setTimeBeforeSleep(mEngineSettings.timeBeforeSleep); + // Update the motor speed of the Slider Joint (to move up and down) long double motorSpeed = 2 * cos(mEngineSettings.elapsedTime * 1.5); mSliderJoint->setMotorSpeed(rp3d::decimal(motorSpeed)); diff --git a/testbed/scenes/raycast/RaycastScene.cpp b/testbed/scenes/raycast/RaycastScene.cpp index 774bb1bc..a7d6bee0 100644 --- a/testbed/scenes/raycast/RaycastScene.cpp +++ b/testbed/scenes/raycast/RaycastScene.cpp @@ -237,6 +237,7 @@ RaycastScene::~RaycastScene() { // Update the physics world (take a simulation step) void RaycastScene::updatePhysics() { + } // Take a step for the simulation diff --git a/testbed/src/Gui.cpp b/testbed/src/Gui.cpp index 7a1ac83f..fe485b2d 100644 --- a/testbed/src/Gui.cpp +++ b/testbed/src/Gui.cpp @@ -40,6 +40,8 @@ Shader Gui::mShader; openglframework::VertexBufferObject Gui::mVBO(GL_ARRAY_BUFFER); openglframework::VertexArrayObject Gui::mVAO; Gui::LeftPane Gui::mLeftPane = SCENES; +double Gui::mScrollX = 0.0; +double Gui::mScrollY = 0.0; // Constructor Gui::Gui() { @@ -61,13 +63,7 @@ Gui::~Gui() { mShader.destroy(); - if (g_FontTexture) - { - glDeleteTextures(1, &g_FontTexture); - ImGui::GetIO().Fonts->TexID = 0; - g_FontTexture = 0; - } - ImGui::Shutdown(); + imguiRenderGLDestroy(); } // Create and return the singleton instance of this class @@ -79,149 +75,196 @@ Gui& Gui::getInstance() { /// Initialize the GUI void Gui::init() { - ImGuiIO& io = ImGui::GetIO(); - io.KeyMap[ImGuiKey_Tab] = GLFW_KEY_TAB; - io.KeyMap[ImGuiKey_LeftArrow] = GLFW_KEY_LEFT; - io.KeyMap[ImGuiKey_RightArrow] = GLFW_KEY_RIGHT; - io.KeyMap[ImGuiKey_UpArrow] = GLFW_KEY_UP; - io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN; - io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; - io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; - io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; - io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; - io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; - io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; - io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; - io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; - io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; - io.KeyMap[ImGuiKey_X] = GLFW_KEY_X; - io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; - io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; - - io.RenderDrawListsFn = renderDrawLists; - io.SetClipboardTextFn = setClipboardText; - io.GetClipboardTextFn = getClipboardText; - - io.FontGlobalScale = GUI_SCALING; + // Init UI + if (!imguiRenderGLInit("DroidSans.ttf")) { + fprintf(stderr, "Could not init GUI renderer.\n"); + exit(EXIT_FAILURE); + } } void Gui::displayHeader() { TestbedApplication& app = TestbedApplication::getInstance(); - ImVec2 buttonSize(120, 40); + int windowWidth, windowHeight; + glfwGetWindowSize(mWindow, &windowWidth, &windowHeight); - int display_w, display_h; - glfwGetFramebufferSize(mWindow, &display_w, &display_h); + const int button_width = 150; - ImGuiWindowFlags window_flags = 0; - window_flags |= ImGuiWindowFlags_NoTitleBar; - window_flags |= ImGuiWindowFlags_NoResize; - window_flags |= ImGuiWindowFlags_NoMove; + int scrollarea = 0; + imguiBeginScrollArea(NULL, 0, app.mWindowToFramebufferRatio.y * (windowHeight - HEADER_HEIGHT), + app.mWindowToFramebufferRatio.x * windowWidth, + app.mWindowToFramebufferRatio.y * HEADER_HEIGHT, &scrollarea); - ImGui::PushID("Header"); - ImGui::PushStyleColor(ImGuiCol_WindowBg, BACKGROUND_COLOR); + imguiStartLineOfItems(); - ImGui::Begin("Header", NULL, ImVec2(display_w, HEADER_HEIGHT), 1.0f, window_flags); - ImGui::SetWindowPos(ImVec2(0, 0)); + // ----- Left Pane Header ----- // - bool isRunning = app.mTimer.isRunning(); - if (ImGui::Button(isRunning ? "Pause" : "Play", buttonSize)) { - app.togglePlayPauseSimulation(); - } - ImGui::SameLine(); + // Play/Pause + if (imguiButton(app.mTimer.isRunning() ? "Pause" : "Play", true, button_width)) { + app.togglePlayPauseSimulation(); + } - if (ImGui::Button("Step", buttonSize)) { - app.toggleTakeSinglePhysicsStep(); - } - ImGui::SameLine(); + // Step + if (imguiButton("Step", !app.mTimer.isRunning(), button_width)) { + app.toggleTakeSinglePhysicsStep(); + } - if (ImGui::Button("Restart", buttonSize)) { - app.restartSimulation(); - } - ImGui::SameLine(); + // Restart + if (imguiButton("Restart", true, button_width)) { + app.restartSimulation(); + } - ImGui::End(); - - ImGui::PopStyleColor(1); - ImGui::PopID(); + imguiEndLineOfItems(); + imguiEndScrollArea(); } void Gui::displayLeftPane() { - const int nbButtonsHeader = 4; - ImVec2 buttonSize(LEFT_PANE_WIDTH / nbButtonsHeader - 9, LEFT_PANE_HEADER_HEIGHT); + TestbedApplication& app = TestbedApplication::getInstance(); - int display_w, display_h; - glfwGetFramebufferSize(mWindow, &display_w, &display_h); + int windowWidth, windowHeight; + glfwGetWindowSize(mWindow, &windowWidth, &windowHeight); - ImGuiWindowFlags window_flags = 0; - window_flags |= ImGuiWindowFlags_NoTitleBar; - window_flags |= ImGuiWindowFlags_NoResize; - window_flags |= ImGuiWindowFlags_NoMove; + int scrollarea = 0; + imguiBeginScrollArea(NULL, 0, app.mWindowToFramebufferRatio.y * (windowHeight - HEADER_HEIGHT - LEFT_PANE_HEADER_HEIGHT), + app.mWindowToFramebufferRatio.x * LEFT_PANE_WIDTH, + app.mWindowToFramebufferRatio.y * LEFT_PANE_HEADER_HEIGHT, &scrollarea); - ImGui::PushID("LeftPane"); - ImGui::PushStyleColor(ImGuiCol_WindowBg, BACKGROUND_COLOR); + imguiStartLineOfItems(); - ImGui::Begin("LeftPane", NULL, ImVec2(LEFT_PANE_WIDTH, display_h - HEADER_HEIGHT), 1.0f, window_flags); - ImGui::SetWindowPos(ImVec2(0, HEADER_HEIGHT)); + // ----- Left Pane Header ----- // + int widthButton = app.mWindowToFramebufferRatio.x * LEFT_PANE_WIDTH / 5; + if (imguiButton("Scenes", true, widthButton)) { + mLeftPane = SCENES; + } - // ----- Left Pane Header ----- // - if (ImGui::Button("Scenes", buttonSize)) { - mLeftPane = SCENES; - } - ImGui::SameLine(); + if (imguiButton("Physics", true, widthButton)) { + mLeftPane = PHYSICS; + } - if (ImGui::Button("Physics", buttonSize)) { - mLeftPane = PHYSICS; - } - ImGui::SameLine(); + imguiButton("Rendering", true, widthButton); + imguiButton("Profiling", true, widthButton); + imguiEndLineOfItems(); + imguiEndScrollArea(); - ImGui::Button("Rendering", buttonSize); ImGui::SameLine(); - ImGui::Button("Profiling", buttonSize); - - // Display the left pane content - switch(mLeftPane) { - case SCENES: displayScenesPane(); break; - case PHYSICS: displayPhysicsPane(); break; - case RENDERING: displayRenderingPane(); break; - case PROFILING: displayProfilingPane(); break; - } - - ImGui::End(); - - ImGui::PopStyleColor(1); - ImGui::PopID(); + // Display the left pane content + switch(mLeftPane) { + case SCENES: displayScenesPane(); break; + case PHYSICS: displayPhysicsPane(); break; + case RENDERING: displayRenderingPane(); break; + case PROFILING: displayProfilingPane(); break; + } } // Display the list of scenes void Gui::displayScenesPane() { + TestbedApplication& app = TestbedApplication::getInstance(); + static int choice = 0; int startChoice = choice; - TestbedApplication& app = TestbedApplication::getInstance(); + int scrollarea = 1; + int windowWidth, windowHeight; + glfwGetWindowSize(mWindow, &windowWidth, &windowHeight); + std::vector scenes = app.getScenes(); + imguiBeginScrollArea("Scenes", 0, 0, + app.mWindowToFramebufferRatio.x * LEFT_PANE_WIDTH, + app.mWindowToFramebufferRatio.y * (windowHeight - HEADER_HEIGHT - LEFT_PANE_HEADER_HEIGHT), + &scrollarea); + // For each scene for (int i=0; igetName().c_str(), &choice, i); + if (imguiCheck(scenes[i]->getName().c_str(), choice == i)) { + choice = i; + } } - - // If the user changed scene if (choice != startChoice) { app.switchScene(scenes[choice]); } + + imguiEndScrollArea(); } void Gui::displayPhysicsPane() { TestbedApplication& app = TestbedApplication::getInstance(); - // Physics time step - //float timestep = app.ge; - //ImGui::InputFloat("Timestep", ×tep, 0.01f, 1.0f); + int windowWidth, windowHeight; + glfwGetWindowSize(mWindow, &windowWidth, &windowHeight); + + int scrollarea = 2; + imguiBeginScrollArea("Physics Engine Parameters", 0, 0, + app.mWindowToFramebufferRatio.x * LEFT_PANE_WIDTH, + app.mWindowToFramebufferRatio.y * (windowHeight - HEADER_HEIGHT - LEFT_PANE_HEADER_HEIGHT), + &scrollarea); + + // Enabled/Disable Sleeping + bool toggle = imguiCheck("Sleeping enabled", app.mEngineSettings.isSleepingEnabled); + if (toggle) { + app.mEngineSettings.isSleepingEnabled = !app.mEngineSettings.isSleepingEnabled; + } + + // Enabled/Disable Gravity + toggle = imguiCheck("Gravity enabled", app.mEngineSettings.isGravityEnabled); + if (toggle) { + app.mEngineSettings.isGravityEnabled = !app.mEngineSettings.isGravityEnabled; + } + + // Timestep + float timeStep = app.mEngineSettings.timeStep; + if (imguiSlider("Timestep", &timeStep, 0.001f, 1.0f, 0.001f)) { + app.mEngineSettings.timeStep = timeStep; + } + + // Nb velocity solver iterations + float nbVelocityIterations = static_cast(app.mEngineSettings.nbVelocitySolverIterations); + if (imguiSlider("Velocity Solver Iterations", &nbVelocityIterations, 1.0f, 100.0f, 1.0f)) { + app.mEngineSettings.nbVelocitySolverIterations = static_cast(nbVelocityIterations); + } + + // Nb position solver iterations + float nbPositionIterations = static_cast(app.mEngineSettings.nbPositionSolverIterations); + if (imguiSlider("Position Solver Iterations", &nbPositionIterations, 1.0f, 100.0f, 1.0f)) { + app.mEngineSettings.nbPositionSolverIterations = static_cast(nbPositionIterations); + } + + // Time before sleep + float timeBeforeSleep = app.mEngineSettings.timeBeforeSleep; + if (imguiSlider("Time before sleep", &timeBeforeSleep, 0.0f, 60.0f, 0.5f)) { + app.mEngineSettings.timeBeforeSleep = timeBeforeSleep; + } + + // Sleep linear velocity + float sleepLinearVelocity = app.mEngineSettings.sleepLinearVelocity; + if (imguiSlider("Sleep linear velocity", &sleepLinearVelocity, 0.0f, 30.0f, 0.5f)) { + app.mEngineSettings.sleepLinearVelocity = sleepLinearVelocity; + } + + // Sleep angular velocity + float sleepAngularVelocity = app.mEngineSettings.sleepAngularVelocity; + if (imguiSlider("Sleep angular velocity", &sleepAngularVelocity, 0.0f, 30.0f, 0.5f)) { + app.mEngineSettings.sleepAngularVelocity = sleepAngularVelocity; + } + + // Gravity vector + openglframework::Vector3 gravity = app.mEngineSettings.gravity; + float gravityX = gravity.x, gravityY = gravity.y, gravityZ = gravity.z; + if (imguiSlider("Gravity X", &gravityX, -50.0f, 50.0f, 0.5f)) { + app.mEngineSettings.gravity.x = gravityX; + } + if (imguiSlider("Gravity Y", &gravityY, -50.0f, 50.0f, 0.5f)) { + app.mEngineSettings.gravity.y = gravityY; + } + if (imguiSlider("Gravity Z", &gravityZ, -50.0f, 50.0f, 0.5f)) { + app.mEngineSettings.gravity.z = gravityZ; + } + + imguiEndScrollArea(); } void Gui::displayRenderingPane() { @@ -232,224 +275,40 @@ void Gui::displayProfilingPane() { } -void Gui::createDeviceObjects() { - - mShader.create("shaders/gui.vert", "shaders/gui.frag"); - - GLuint shaderID = mShader.getProgramObjectId(); - g_AttribLocationTex = glGetUniformLocation(shaderID, "Texture"); - g_AttribLocationProjMtx = glGetUniformLocation(shaderID, "ProjMtx"); - g_AttribLocationPosition = glGetAttribLocation(shaderID, "Position"); - g_AttribLocationUV = glGetAttribLocation(shaderID, "UV"); - g_AttribLocationColor = glGetAttribLocation(shaderID, "Color"); - - mVBO.create(); - - mVAO.create(); - mVAO.bind(); - mVBO.bind(); - glEnableVertexAttribArray(g_AttribLocationPosition); - glEnableVertexAttribArray(g_AttribLocationUV); - glEnableVertexAttribArray(g_AttribLocationColor); -#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) - glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); - glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); - glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); -#undef OFFSETOF - mVAO.unbind(); - mVBO.unbind(); - - createFontTextures(); -} - // Display the GUI void Gui::render() { - ImGuiIO& io = ImGui::GetIO(); - //glfwPollEvents(); - beginNewFrame(); + TestbedApplication& app = TestbedApplication::getInstance(); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_DEPTH_TEST); + + int display_w, display_h; + glfwGetFramebufferSize(mWindow, &display_w, &display_h); + + int windowWidth, windowHeight; + glfwGetWindowSize(mWindow, &windowWidth, &windowHeight); + + // Mouse position + double mouseX, mouseY; + glfwGetCursorPos(mWindow, &mouseX, &mouseY); + + // Mouse buttons + int leftButton = glfwGetMouseButton(mWindow, GLFW_MOUSE_BUTTON_LEFT); + unsigned char mousebutton = 0; + if(leftButton == GLFW_PRESS ) { + mousebutton |= IMGUI_MBUT_LEFT; + } + + imguiBeginFrame(app.mWindowToFramebufferRatio.x * mouseX, + app.mWindowToFramebufferRatio.y * (windowHeight - mouseY), mousebutton, -mScrollY); + resetScroll(); displayHeader(); displayLeftPane(); - ImGui::ShowTestWindow(); + imguiEndFrame(); - // Render the GUI - ImGui::Render(); -} - -void Gui::beginNewFrame() { - - if (!g_FontTexture) - createDeviceObjects(); - - ImGuiIO& io = ImGui::GetIO(); - - // Setup display size (every frame to accommodate for window resizing) - int w, h; - int display_w, display_h; - glfwGetWindowSize(mWindow, &w, &h); - glfwGetFramebufferSize(mWindow, &display_w, &display_h); - io.DisplaySize = ImVec2((float)display_w, (float)display_h); - - // Setup time step - double current_time = glfwGetTime(); - io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); - g_Time = current_time; - - // Setup inputs - // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) - if (glfwGetWindowAttrib(mWindow, GLFW_FOCUSED)) - { - double mouse_x, mouse_y; - glfwGetCursorPos(mWindow, &mouse_x, &mouse_y); - mouse_x *= (float)display_w / w; // Convert mouse coordinates to pixels - mouse_y *= (float)display_h / h; - io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.) - } - else - { - io.MousePos = ImVec2(-1,-1); - } - - for (int i = 0; i < 3; i++) - { - io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(mWindow, i) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. - g_MousePressed[i] = false; - } - - io.MouseWheel = g_MouseWheel; - g_MouseWheel = 0.0f; - - // Hide/show hardware mouse cursor - glfwSetInputMode(mWindow, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); - - // Start the frame - ImGui::NewFrame(); -} - -void Gui::createFontTextures() -{ - ImGuiIO& io = ImGui::GetIO(); - - unsigned char* pixels; - int width, height; - io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader. - - glGenTextures(1, &g_FontTexture); - glBindTexture(GL_TEXTURE_2D, g_FontTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); - - // Store our identifier - io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; -} - -// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) -// If text or lines are blurry when integrating ImGui in your engine: -// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) -void Gui::renderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count) -{ - if (cmd_lists_count == 0) - return; - - // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled - GLint last_program, last_texture; - glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); - glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - glEnable(GL_BLEND); - glBlendEquation(GL_FUNC_ADD); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glEnable(GL_SCISSOR_TEST); - glActiveTexture(GL_TEXTURE0); - - - // Setup orthographic projection matrix - const float width = ImGui::GetIO().DisplaySize.x; - const float height = ImGui::GetIO().DisplaySize.y; - Matrix4 orthoProj(2.0f / width, 0.0f, 0.0f, 0.0f, - 0.0f, 2.0/-height, 0.0f, 0.0f, - 0.0f, 0.0f, -1.0f, 0.0f, - -1.0f, 1.0f, 0.0f, 1.0f); - const float ortho_projection[4][4] = - { - { 2.0f/width, 0.0f, 0.0f, 0.0f }, - { 0.0f, 2.0f/-height, 0.0f, 0.0f }, - { 0.0f, 0.0f, -1.0f, 0.0f }, - { -1.0f, 1.0f, 0.0f, 1.0f }, - }; - - mShader.bind(); - //mShader.setIntUniform("Texture", 0); - //mShader.setMatrix4x4Uniform("ProjMtx", orthoProj); - ///glUseProgram(g_ShaderHandle); - glUniform1i(g_AttribLocationTex, 0); - glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); - - // Grow our buffer according to what we need - size_t total_vtx_count = 0; - for (int n = 0; n < cmd_lists_count; n++) - total_vtx_count += cmd_lists[n]->vtx_buffer.size(); - mVBO.bind(); - size_t needed_vtx_size = total_vtx_count * sizeof(ImDrawVert); - if (g_VboSize < needed_vtx_size) - { - g_VboSize = needed_vtx_size + 5000 * sizeof(ImDrawVert); // Grow buffer - mVBO.copyDataIntoVBO(g_VboSize, NULL, GL_STREAM_DRAW); - //glBufferData(GL_ARRAY_BUFFER, g_VboSize, NULL, GL_STREAM_DRAW); - } - - // Copy and convert all vertices into a single contiguous buffer - unsigned char* buffer_data = (unsigned char*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); - if (!buffer_data) - return; - for (int n = 0; n < cmd_lists_count; n++) - { - const ImDrawList* cmd_list = cmd_lists[n]; - memcpy(buffer_data, &cmd_list->vtx_buffer[0], cmd_list->vtx_buffer.size() * sizeof(ImDrawVert)); - buffer_data += cmd_list->vtx_buffer.size() * sizeof(ImDrawVert); - } - glUnmapBuffer(GL_ARRAY_BUFFER); - mVBO.unbind(); - mVAO.bind(); - - int cmd_offset = 0; - for (int n = 0; n < cmd_lists_count; n++) - { - const ImDrawList* cmd_list = cmd_lists[n]; - int vtx_offset = cmd_offset; - const ImDrawCmd* pcmd_end = cmd_list->commands.end(); - for (const ImDrawCmd* pcmd = cmd_list->commands.begin(); pcmd != pcmd_end; pcmd++) - { - if (pcmd->user_callback) - { - pcmd->user_callback(cmd_list, pcmd); - } - else - { - glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->texture_id); - glScissor((int)pcmd->clip_rect.x, (int)(height - pcmd->clip_rect.w), (int)(pcmd->clip_rect.z - pcmd->clip_rect.x), (int)(pcmd->clip_rect.w - pcmd->clip_rect.y)); - glDrawArrays(GL_TRIANGLES, vtx_offset, pcmd->vtx_count); - } - vtx_offset += pcmd->vtx_count; - } - cmd_offset = vtx_offset; - } - - // Restore modified state - mVAO.unbind(); - glUseProgram(last_program); - glDisable(GL_SCISSOR_TEST); - glBindTexture(GL_TEXTURE_2D, last_texture); -} - -const char* Gui::getClipboardText() { - return glfwGetClipboardString(mWindow); -} - -void Gui::setClipboardText(const char* text) { - glfwSetClipboardString(mWindow, text); + imguiRenderGLDraw(display_w, display_h); } diff --git a/testbed/src/Gui.h b/testbed/src/Gui.h index 39b2aeb4..53d07bef 100644 --- a/testbed/src/Gui.h +++ b/testbed/src/Gui.h @@ -27,7 +27,8 @@ #define GUI_H // Libraries -#include +#include "imgui.h" +#include "imguiRenderGL3.h" #include #include #include "openglframework.h" @@ -35,9 +36,8 @@ // Constants const float GUI_SCALING = 2.0f; const int HEADER_HEIGHT = 80; -const int LEFT_PANE_WIDTH = 700; +const int LEFT_PANE_WIDTH = 300; const int LEFT_PANE_HEADER_HEIGHT = 60; -const ImColor BACKGROUND_COLOR = ImColor(41, 41, 41, 255); using namespace openglframework; @@ -72,21 +72,10 @@ class Gui { static openglframework::VertexArrayObject mVAO; static LeftPane mLeftPane; + static double mScrollX, mScrollY; // -------------------- Methods -------------------- // - void createDeviceObjects(); - - void createFontTextures(); - - void beginNewFrame(); - - static void renderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count); - - static const char* getClipboardText(); - - static void setClipboardText(const char* text); - static void displayHeader(); static void displayLeftPane(); @@ -97,6 +86,9 @@ class Gui { static void displayRenderingPane(); static void displayProfilingPane(); + static void resetScroll(); + + public : // -------------------- Methods -------------------- // @@ -117,10 +109,22 @@ class Gui { void render(); static void setWindow(GLFWwindow* window); + + static void setScroll(double scrollX, double scrollY); }; inline void Gui::setWindow(GLFWwindow* window) { mWindow = window; } +inline void Gui::resetScroll() { + mScrollX = 0.0; + mScrollY = 0.0; +} + +inline void Gui::setScroll(double scrollX, double scrollY) { + mScrollX = scrollX; + mScrollY = scrollY; +} + #endif diff --git a/testbed/src/Scene.h b/testbed/src/Scene.h index e6460805..53c7c077 100644 --- a/testbed/src/Scene.h +++ b/testbed/src/Scene.h @@ -155,6 +155,9 @@ class Scene { /// Return a reference to the camera const openglframework::Camera& getCamera() const; + /// Get the engine settings + EngineSettings getEngineSettings() const; + /// Set the engine settings void setEngineSettings(const EngineSettings& settings); @@ -186,6 +189,11 @@ inline void Scene::setWindowDimension(int width, int height) { mWindowHeight = height; } +// Get the engine settings +inline EngineSettings Scene::getEngineSettings() const { + return mEngineSettings; +} + // Set the engine settings inline void Scene::setEngineSettings(const EngineSettings& settings) { mEngineSettings = settings; diff --git a/testbed/src/TestbedApplication.cpp b/testbed/src/TestbedApplication.cpp index d972aeb3..13c22318 100644 --- a/testbed/src/TestbedApplication.cpp +++ b/testbed/src/TestbedApplication.cpp @@ -53,12 +53,12 @@ TestbedApplication& TestbedApplication::getInstance() { TestbedApplication::TestbedApplication() : mFPS(0), mNbFrames(0), mPreviousTime(0) { mCurrentScene = NULL; - mEngineSettings.timeStep = DEFAULT_TIMESTEP; mIsMultisamplingActive = true; mWidth = 1280; mHeight = 720; mSinglePhysicsStepEnabled = false; mSinglePhysicsStepDone = false; + mWindowToFramebufferRatio = Vector2(1, 1); } // Destructor @@ -164,7 +164,11 @@ void TestbedApplication::createScenes() { mScenes.push_back(raycastScene); assert(mScenes.size() > 0); - mCurrentScene = mScenes[0]; + mCurrentScene = mScenes[1]; + + // Get the engine settings from the scene + mEngineSettings = mCurrentScene->getEngineSettings(); + mEngineSettings.timeStep = DEFAULT_TIMESTEP; } // Remove all the scenes @@ -236,20 +240,25 @@ void TestbedApplication::update() { // Render void TestbedApplication::render() { - // Get the framebuffer dimension - int width, height; - glfwGetFramebufferSize(mWindow, &width, &height); + int bufferWidth, bufferHeight; + glfwGetFramebufferSize(mWindow, &bufferWidth, &bufferHeight); + + int windowWidth, windowHeight; + glfwGetWindowSize(mWindow, &windowWidth, &windowHeight); + + // Compute the window to framebuffer ratio + mWindowToFramebufferRatio.x = float(bufferWidth) / float(windowWidth); + mWindowToFramebufferRatio.y = float(bufferHeight) / float(windowHeight); // Resize the OpenGL viewport - glViewport(LEFT_PANE_WIDTH, HEADER_HEIGHT, - width - LEFT_PANE_WIDTH, height - HEADER_HEIGHT); + glViewport(mWindowToFramebufferRatio.x * LEFT_PANE_WIDTH, + 0, + bufferWidth - mWindowToFramebufferRatio.x * LEFT_PANE_WIDTH, + bufferHeight - mWindowToFramebufferRatio.y * HEADER_HEIGHT); // Render the scene mCurrentScene->render(); - // Resize the OpenGL viewport - glViewport(0, 0, width, height); - // Display the GUI Gui::getInstance().render(); @@ -311,6 +320,11 @@ void TestbedApplication::switchScene(Scene* newScene) { mCurrentScene = newScene; + // Get the engine settings of the scene + float currentTimeStep = mEngineSettings.timeStep; + mEngineSettings = mCurrentScene->getEngineSettings(); + mEngineSettings.timeStep = currentTimeStep; + // Reset the scene mCurrentScene->reset(); } @@ -397,6 +411,10 @@ void TestbedApplication::keyboard(GLFWwindow* window, int key, int scancode, // Callback method to receive scrolling events void TestbedApplication::scroll(GLFWwindow* window, double xAxis, double yAxis) { + + // Update scroll on the GUI + Gui::getInstance().setScroll(xAxis, yAxis); + getInstance().mCurrentScene->scrollingEvent(xAxis, yAxis, SCROLL_SENSITIVITY); } diff --git a/testbed/src/TestbedApplication.h b/testbed/src/TestbedApplication.h index eb5d2276..1c2d22c0 100644 --- a/testbed/src/TestbedApplication.h +++ b/testbed/src/TestbedApplication.h @@ -87,6 +87,8 @@ class TestbedApplication { /// True if the single physics step has been taken already bool mSinglePhysicsStepDone; + openglframework::Vector2 mWindowToFramebufferRatio; + // -------------------- Methods -------------------- // /// Private constructor (for the singleton class) From 58992169e74cc1cca8681d59fddfc5744b73eac6 Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Sun, 12 Jul 2015 00:05:49 +0200 Subject: [PATCH 18/36] Working on the testbed application --- testbed/imgui/imgui.cpp | 50 ++++++++++++++++-------------- testbed/imgui/imgui.h | 15 +++++---- testbed/src/Gui.cpp | 30 ++++++++++++++---- testbed/src/Gui.h | 2 +- testbed/src/TestbedApplication.cpp | 4 +-- 5 files changed, 62 insertions(+), 39 deletions(-) diff --git a/testbed/imgui/imgui.cpp b/testbed/imgui/imgui.cpp index 77fdae25..6c962314 100644 --- a/testbed/imgui/imgui.cpp +++ b/testbed/imgui/imgui.cpp @@ -149,7 +149,8 @@ struct GuiState mx(-1), my(-1), scroll(0), active(0), hot(0), hotToBe(0), isHot(false), isActive(false), wentActive(false), dragX(0), dragY(0), dragOrig(0), widgetX(0), widgetY(0), widgetW(100), - insideCurrentScroll(false), nextItemSameLine(false), areaId(0), widgetId(0) + insideCurrentScroll(false), nextItemSameLine(false), newLinePreviousX(0), + areaId(0), widgetId(0) { } @@ -168,6 +169,7 @@ struct GuiState int widgetX, widgetY, widgetW; bool insideCurrentScroll; bool nextItemSameLine; + int newLinePreviousX; unsigned int areaId; unsigned int widgetId; @@ -324,7 +326,7 @@ bool imguiBeginScrollArea(const char* name, int x, int y, int w, int h, int* scr const int areaHeading = name ? AREA_HEADER : 0; g_state.widgetX = x + SCROLL_AREA_PADDING; - g_state.widgetY = y+h-areaHeading + (*scroll); + g_state.widgetY = y+h-areaHeading + (*scroll) - SCROll_AREA_TOP_PADDING; g_state.widgetW = w - SCROLL_AREA_PADDING*4; g_scrollTop = y-areaHeading+h; g_scrollBottom = y+SCROLL_AREA_PADDING; @@ -339,7 +341,7 @@ bool imguiBeginScrollArea(const char* name, int x, int y, int w, int h, int* scr g_insideScrollArea = inRect(x, y, w, h, false); g_state.insideCurrentScroll = g_insideScrollArea; - addGfxCmdRoundedRect((float)x, (float)y, (float)w, (float)h, 6, imguiRGBA(0,0,0,192)); + addGfxCmdRoundedRect((float)x, (float)y, (float)w, (float)h, 6, imguiRGBA(40,40,40,192)); if (name) addGfxCmdText(x+areaHeading/2, y+h-areaHeading/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, name, imguiRGBA(255,255,255,128)); @@ -430,10 +432,10 @@ bool imguiButton(const char* text, bool enabled, int width) int w = width > 0 ? width : g_state.widgetW; int h = BUTTON_HEIGHT; if (g_state.nextItemSameLine) { - g_state.widgetX += width + DEFAULT_HORIZONTAL_SPACING; + g_state.widgetX += width; } else { - g_state.widgetY -= BUTTON_HEIGHT + DEFAULT_VERTICAL_SPACING; + g_state.widgetY -= BUTTON_HEIGHT; } bool over = enabled && inRect(x, y, w, h); @@ -482,7 +484,12 @@ bool imguiCheck(const char* text, bool checked, bool enabled) int y = g_state.widgetY - BUTTON_HEIGHT; int w = g_state.widgetW; int h = BUTTON_HEIGHT; - g_state.widgetY -= BUTTON_HEIGHT + DEFAULT_VERTICAL_SPACING; + if (g_state.nextItemSameLine) { + g_state.widgetX += w; + } + else { + g_state.widgetY -= BUTTON_HEIGHT; + } bool over = enabled && inRect(x, y, w, h); bool res = buttonLogic(id, over); @@ -626,40 +633,35 @@ bool imguiSlider(const char* text, float* val, float vmin, float vmax, float vin return res || valChanged; } -void imguiStartLineOfItems() { +void imguiStartLine() { g_state.nextItemSameLine = true; + g_state.newLinePreviousX = g_state.widgetX; } -void imguiEndLineOfItems() { +void imguiEndLine() { g_state.nextItemSameLine = false; + g_state.widgetX = g_state.newLinePreviousX; + g_state.newLinePreviousX = 0; } -void imguiIndent() +void imguiVerticalSpace(int spaceY) { - g_state.widgetX += INDENT_SIZE; - g_state.widgetW -= INDENT_SIZE; + g_state.widgetY -= spaceY; } -void imguiUnindent() -{ - g_state.widgetX -= INDENT_SIZE; - g_state.widgetW += INDENT_SIZE; -} - -void imguiSeparator() -{ - g_state.widgetY -= DEFAULT_VERTICAL_SPACING*3; +void imguiHorizontalSpace(int spaceX) { + g_state.widgetX += spaceX; } void imguiSeparatorLine() { int x = g_state.widgetX; - int y = g_state.widgetY - DEFAULT_VERTICAL_SPACING*2; + int y = g_state.widgetY; int w = g_state.widgetW; - int h = 1; - g_state.widgetY -= DEFAULT_VERTICAL_SPACING*4; + int h = SEPARATOR_LINE_WIDTH; + g_state.widgetY -= SEPARATOR_LINE_WIDTH; - addGfxCmdRect((float)x, (float)y, (float)w, (float)h, imguiRGBA(255,255,255,32)); + addGfxCmdRect((float)x, (float)y, (float)w, (float)h, imguiRGBA(255,255,255,70)); } void imguiDrawText(int x, int y, int align, const char* text, unsigned int color) diff --git a/testbed/imgui/imgui.h b/testbed/imgui/imgui.h index 830b6d17..64f28109 100644 --- a/testbed/imgui/imgui.h +++ b/testbed/imgui/imgui.h @@ -23,16 +23,18 @@ #define IMGUI_H static const int BUTTON_HEIGHT = 40; -static const int SLIDER_HEIGHT = 20; +static const int SLIDER_HEIGHT = 30; static const int SLIDER_MARKER_WIDTH = 10; static const int CHECK_SIZE = 18; static const int DEFAULT_VERTICAL_SPACING = 14; static const int DEFAULT_HORIZONTAL_SPACING = 14; static const int TEXT_HEIGHT = 16; static const int FONT_HEIGHT = 30; -static const int SCROLL_AREA_PADDING = 6; +static const int SCROll_AREA_TOP_PADDING = 5; +static const int SCROLL_AREA_PADDING = 5; static const int INDENT_SIZE = 16; -static const int AREA_HEADER = 28; +static const int AREA_HEADER = 20; +static const int SEPARATOR_LINE_WIDTH = 2; enum imguiMouseButton { @@ -58,11 +60,12 @@ void imguiEndFrame(); bool imguiBeginScrollArea(const char* name, int x, int y, int w, int h, int* scroll); void imguiEndScrollArea(); -void imguiStartLineOfItems(); -void imguiEndLineOfItems(); +void imguiStartLine(); +void imguiEndLine(); void imguiIndent(); void imguiUnindent(); -void imguiSeparator(); +void imguiVerticalSpace(int spaceY); +void imguiHorizontalSpace(int spaceX); void imguiSeparatorLine(); bool imguiButton(const char* text, bool enabled = true, int width = -1); diff --git a/testbed/src/Gui.cpp b/testbed/src/Gui.cpp index fe485b2d..c7619add 100644 --- a/testbed/src/Gui.cpp +++ b/testbed/src/Gui.cpp @@ -96,7 +96,9 @@ void Gui::displayHeader() { app.mWindowToFramebufferRatio.x * windowWidth, app.mWindowToFramebufferRatio.y * HEADER_HEIGHT, &scrollarea); - imguiStartLineOfItems(); + imguiHorizontalSpace(10); + imguiVerticalSpace(20); + imguiStartLine(); // ----- Left Pane Header ----- // @@ -104,18 +106,20 @@ void Gui::displayHeader() { if (imguiButton(app.mTimer.isRunning() ? "Pause" : "Play", true, button_width)) { app.togglePlayPauseSimulation(); } + imguiHorizontalSpace(5); // Step if (imguiButton("Step", !app.mTimer.isRunning(), button_width)) { app.toggleTakeSinglePhysicsStep(); } + imguiHorizontalSpace(5); // Restart if (imguiButton("Restart", true, button_width)) { app.restartSimulation(); } - imguiEndLineOfItems(); + imguiEndLine(); imguiEndScrollArea(); } @@ -131,21 +135,30 @@ void Gui::displayLeftPane() { app.mWindowToFramebufferRatio.x * LEFT_PANE_WIDTH, app.mWindowToFramebufferRatio.y * LEFT_PANE_HEADER_HEIGHT, &scrollarea); - imguiStartLineOfItems(); + imguiSeparatorLine(); + imguiVerticalSpace(5); + imguiStartLine(); // ----- Left Pane Header ----- // - int widthButton = app.mWindowToFramebufferRatio.x * LEFT_PANE_WIDTH / 5; + int widthButton = app.mWindowToFramebufferRatio.x * LEFT_PANE_WIDTH / 4.3; if (imguiButton("Scenes", true, widthButton)) { mLeftPane = SCENES; } + imguiHorizontalSpace(5); if (imguiButton("Physics", true, widthButton)) { mLeftPane = PHYSICS; } + imguiHorizontalSpace(5); imguiButton("Rendering", true, widthButton); + imguiHorizontalSpace(5); + imguiButton("Profiling", true, widthButton); - imguiEndLineOfItems(); + + imguiEndLine(); + imguiVerticalSpace(BUTTON_HEIGHT + 8); + imguiSeparatorLine(); imguiEndScrollArea(); // Display the left pane content @@ -175,6 +188,8 @@ void Gui::displayScenesPane() { app.mWindowToFramebufferRatio.y * (windowHeight - HEADER_HEIGHT - LEFT_PANE_HEADER_HEIGHT), &scrollarea); + imguiVerticalSpace(15); + // For each scene for (int i=0; i 0); - mCurrentScene = mScenes[1]; + mCurrentScene = mScenes[0]; // Get the engine settings from the scene mEngineSettings = mCurrentScene->getEngineSettings(); From cec1ac793767f5226131e6127639afaf59d57d18 Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Tue, 21 Jul 2015 23:18:32 +0000 Subject: [PATCH 19/36] Start working on shadow mapping --- testbed/CMakeLists.txt | 2 + testbed/common/Box.cpp | 53 ++++---- testbed/common/Box.h | 6 +- testbed/opengl-framework/src/Shader.h | 100 +++++++++----- testbed/opengl-framework/src/Texture2D.cpp | 22 ++++ testbed/opengl-framework/src/Texture2D.h | 4 + .../collisionshapes/CollisionShapesScene.cpp | 4 +- testbed/scenes/cubes/CubesScene.cpp | 39 ++---- testbed/scenes/cubes/CubesScene.h | 17 +-- testbed/scenes/joints/JointsScene.cpp | 14 +- testbed/scenes/raycast/RaycastScene.cpp | 2 +- testbed/shaders/depth.frag | 13 +- testbed/shaders/depth.vert | 13 +- testbed/shaders/gui.frag | 10 -- testbed/shaders/gui.vert | 15 --- testbed/src/SceneDemo.cpp | 124 ++++++++++++++++++ testbed/src/SceneDemo.h | 94 +++++++++++++ 17 files changed, 383 insertions(+), 149 deletions(-) delete mode 100644 testbed/shaders/gui.frag delete mode 100644 testbed/shaders/gui.vert create mode 100644 testbed/src/SceneDemo.cpp create mode 100644 testbed/src/SceneDemo.h diff --git a/testbed/CMakeLists.txt b/testbed/CMakeLists.txt index 4dc2511b..ff842cff 100644 --- a/testbed/CMakeLists.txt +++ b/testbed/CMakeLists.txt @@ -39,6 +39,8 @@ SET(TESTBED_SOURCES src/Gui.cpp src/Scene.h src/Scene.cpp + src/SceneDemo.h + src/SceneDemo.cpp src/Timer.h src/Timer.cpp ) diff --git a/testbed/common/Box.cpp b/testbed/common/Box.cpp index 3845644a..e3fc397a 100644 --- a/testbed/common/Box.cpp +++ b/testbed/common/Box.cpp @@ -59,7 +59,7 @@ GLuint Box::mCubeIndices[36] = { 0, 1, 2, // Constructor Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &position, - reactphysics3d::CollisionWorld* world, openglframework::Shader& shader) + reactphysics3d::CollisionWorld* world) : openglframework::Object3D(), mColor(0.01f, 0.62f, 0.39f, 1.0f) { // Initialize the size of the box @@ -98,7 +98,7 @@ Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &p if (totalNbBoxes == 0) { // Create the Vertex Buffer - createVBOAndVAO(shader); + createVBOAndVAO(); } totalNbBoxes++; @@ -107,8 +107,8 @@ Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &p } // Constructor -Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &position, - float mass, reactphysics3d::DynamicsWorld* world, openglframework::Shader& shader) +Box::Box(const openglframework::Vector3& size, const openglframework::Vector3& position, + float mass, reactphysics3d::DynamicsWorld* world) : openglframework::Object3D(), mColor(0.01f, 0.62f, 0.39f, 1.0f) { // Initialize the size of the box @@ -147,7 +147,7 @@ Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &p if (totalNbBoxes == 0) { // Create the Vertex Buffer - createVBOAndVAO(shader); + createVBOAndVAO(); } totalNbBoxes++; @@ -173,9 +173,14 @@ Box::~Box() { void Box::render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix) { + // Bind the VAO + mVAO.bind(); + // Bind the shader shader.bind(); + mVBOVertices.bind(); + // Set the model to camera matrix const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix; shader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix); @@ -184,18 +189,30 @@ void Box::render(openglframework::Shader& shader, // model-view matrix) const openglframework::Matrix3 normalMatrix = localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose(); - shader.setMatrix3x3Uniform("normalMatrix", normalMatrix); + shader.setMatrix3x3Uniform("normalMatrix", normalMatrix, false); // Set the vertex color openglframework::Vector4 color(mColor.r, mColor.g, mColor.b, mColor.a); - shader.setVector4Uniform("vertexColor", color); + shader.setVector4Uniform("vertexColor", color, false); - // Bind the VAO - mVAO.bind(); + // Get the location of shader attribute variables + GLint vertexPositionLoc = shader.getAttribLocation("vertexPosition"); + GLint vertexNormalLoc = shader.getAttribLocation("vertexNormal", false); + + glEnableVertexAttribArray(vertexPositionLoc); + if (vertexNormalLoc != -1) glEnableVertexAttribArray(vertexNormalLoc); + + glVertexAttribPointer(vertexPositionLoc, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), MEMBER_OFFSET(VertexData, position)); + if (vertexNormalLoc != -1) glVertexAttribPointer(vertexNormalLoc, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), MEMBER_OFFSET(VertexData, normal)); // Draw the geometry of the box glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, (char*)NULL); + glDisableVertexAttribArray(vertexPositionLoc); + if (vertexNormalLoc != -1) glDisableVertexAttribArray(vertexNormalLoc); + + mVBOVertices.unbind(); + // Unbind the VAO mVAO.unbind(); @@ -230,14 +247,7 @@ void Box::updateTransform(float interpolationFactor) { // Create the Vertex Buffer Objects used to render to box with OpenGL. /// We create two VBOs (one for vertices and one for indices) to render all the boxes /// in the simulation. -void Box::createVBOAndVAO(openglframework::Shader& shader) { - - // Bind the shader - shader.bind(); - - // Get the location of shader attribute variables - GLint vertexPositionLoc = shader.getAttribLocation("vertexPosition"); - GLint vertexNormalLoc = shader.getAttribLocation("vertexNormal"); +void Box::createVBOAndVAO() { // Create the VBO for the vertices data mVBOVertices.create(); @@ -258,20 +268,11 @@ void Box::createVBOAndVAO(openglframework::Shader& shader) { // Bind the VBO of vertices mVBOVertices.bind(); - glEnableVertexAttribArray(vertexPositionLoc); - glEnableVertexAttribArray(vertexNormalLoc); - - glVertexAttribPointer(vertexPositionLoc, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), MEMBER_OFFSET(VertexData, position)); - glVertexAttribPointer(vertexNormalLoc, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), MEMBER_OFFSET(VertexData, normal)); - // Bind the VBO of indices mVBOIndices.bind(); // Unbind the VAO mVAO.unbind(); - - // Unbind the shader - shader.unbind(); } // Reset the transform diff --git a/testbed/common/Box.h b/testbed/common/Box.h index efacafb4..b322dc8b 100644 --- a/testbed/common/Box.h +++ b/testbed/common/Box.h @@ -86,7 +86,7 @@ class Box : public openglframework::Object3D { // -------------------- Methods -------------------- // /// Create a the VAO and VBOs to render to box with OpenGL - static void createVBOAndVAO(openglframework::Shader &shader); + static void createVBOAndVAO(); public : @@ -94,11 +94,11 @@ class Box : public openglframework::Object3D { /// Constructor Box(const openglframework::Vector3& size, const openglframework::Vector3& position, - reactphysics3d::CollisionWorld* world, openglframework::Shader &shader); + reactphysics3d::CollisionWorld* world); /// Constructor Box(const openglframework::Vector3& size, const openglframework::Vector3& position, - float mass, reactphysics3d::DynamicsWorld *world, openglframework::Shader& shader); + float mass, reactphysics3d::DynamicsWorld *world); /// Destructor ~Box(); diff --git a/testbed/opengl-framework/src/Shader.h b/testbed/opengl-framework/src/Shader.h index 734ee56c..9205fbe0 100644 --- a/testbed/opengl-framework/src/Shader.h +++ b/testbed/opengl-framework/src/Shader.h @@ -34,6 +34,7 @@ #include "maths/Vector4.h" #include #include +#include #include namespace openglframework { @@ -78,57 +79,57 @@ class Shader { void unbind() const; // Return the location of a uniform variable inside a shader program - GLint getUniformLocation(const std::string& variableName) const; + GLint getUniformLocation(const std::string& variableName, bool errorIfMissing = true) const; // Return the location of an attribute variable inside a shader program - GLint getAttribLocation(const std::string& variableName) const; + GLint getAttribLocation(const std::string& variableName, bool errorIfMissing = true) const; // Set a float uniform value to this shader (be careful if the uniform is not // used in the shader, the compiler will remove it, then when you will try // to set it, an assert will occur) - void setFloatUniform(const std::string& variableName, float value) const; + void setFloatUniform(const std::string& variableName, float value, bool errorIfMissing = true) const; // Set an int uniform value to this shader (be careful if the uniform is not // used in the shader, the compiler will remove it, then when you will try // to set it, an assert will occur) - void setIntUniform(const std::string& variableName, int value) const; + void setIntUniform(const std::string& variableName, int value, bool errorIfMissing = true) const; // Set a vector 2 uniform value to this shader (be careful if the uniform is not // used in the shader, the compiler will remove it, then when you will try // to set it, an assert will occur) - void setVector2Uniform(const std::string& variableName, const Vector2& v) const; + void setVector2Uniform(const std::string& variableName, const Vector2& v, bool errorIfMissing = true) const; // Set a vector 3 uniform value to this shader (be careful if the uniform is not // used in the shader, the compiler will remove it, then when you will try // to set it, an assert will occur) - void setVector3Uniform(const std::string& variableName, const Vector3& v) const; + void setVector3Uniform(const std::string& variableName, const Vector3& v, bool errorIfMissing = true) const; // Set a vector 4 uniform value to this shader (be careful if the uniform is not // used in the shader, the compiler will remove it, then when you will try // to set it, an assert will occur) - void setVector4Uniform(const std::string& variableName, const Vector4 &v) const; + void setVector4Uniform(const std::string& variableName, const Vector4 &v, bool errorIfMissing = true) const; // Set a 3x3 matrix uniform value to this shader (be careful if the uniform is not // used in the shader, the compiler will remove it, then when you will try // to set it, an assert will occur) void setMatrix3x3Uniform(const std::string& variableName, const float* matrix, - bool transpose = false) const; + bool transpose = false, bool errorIfMissing = true) const; // Set a 3x3 matrix uniform value to this shader (be careful if the uniform is not // used in the shader, the compiler will remove it, then when you will try // to set it, an assert will occur) - void setMatrix3x3Uniform(const std::string& variableName, const Matrix3& matrix) const; + void setMatrix3x3Uniform(const std::string& variableName, const Matrix3& matrix, bool errorIfMissing = true) const; // Set a 4x4 matrix uniform value to this shader (be careful if the uniform is not // used in the shader, the compiler will remove it, then when you will try // to set it, an assert will occur) void setMatrix4x4Uniform(const std::string& variableName, const float* matrix, - bool transpose = false) const; + bool transpose = false, bool errorIfMissing = true) const; // Set a 4x4 matrix uniform value to this shader (be careful if the uniform is not // used in the shader, the compiler will remove it, then when you will try // to set it, an assert will occur) - void setMatrix4x4Uniform(const std::string& variableName, const Matrix4& matrix) const; + void setMatrix4x4Uniform(const std::string& variableName, const Matrix4& matrix, bool errorIfMissing = true) const; // Return the shader object program ID GLuint getProgramObjectId() const; @@ -150,28 +151,30 @@ inline void Shader::unbind() const { } // Return the location of a uniform variable inside a shader program -inline GLint Shader::getUniformLocation(const std::string& variableName) const { +inline GLint Shader::getUniformLocation(const std::string& variableName, bool errorIfMissing) const { assert(mProgramObjectID != 0); GLint location = glGetUniformLocation(mProgramObjectID, variableName.c_str()); - if (location == -1) { + if (location == -1 && errorIfMissing) { std::cerr << "Error in vertex shader " << mFilenameVertexShader << " or in fragment shader" << mFilenameFragmentShader << " : No Uniform variable : " << variableName << std::endl; + throw std::logic_error("Error in Shader"); } - assert(location != -1); + return location; } // Return the location of an attribute variable inside a shader program -inline GLint Shader::getAttribLocation(const std::string& variableName) const { +inline GLint Shader::getAttribLocation(const std::string& variableName, bool errorIfMissing) const { assert(mProgramObjectID != 0); GLint location = glGetAttribLocation(mProgramObjectID, variableName.c_str()); - if (location == -1) { + if (location == -1 && errorIfMissing) { std::cerr << "Error in vertex shader " << mFilenameVertexShader << " or in fragment shader" << mFilenameFragmentShader << " : No Uniform variable : " << variableName << std::endl; + throw std::logic_error("Error in Shader"); } - assert(location != -1); + return location; } @@ -184,56 +187,74 @@ inline void Shader::destroy() { // Set a float uniform value to this shader (be careful if the uniform is not // used in the shader, the compiler will remove it, then when you will try // to set it, an assert will occur) -inline void Shader::setFloatUniform(const std::string& variableName, float value) const { +inline void Shader::setFloatUniform(const std::string& variableName, float value, bool errorIfMissing) const { assert(mProgramObjectID != 0); - glUniform1f(getUniformLocation(variableName), value); + GLint location = getUniformLocation(variableName, errorIfMissing); + if (location != -1) { + glUniform1f(location, value); + } } // Set an int uniform value to this shader (be careful if the uniform is not // used in the shader, the compiler will remove it, then when you will try // to set it, an assert will occur) -inline void Shader::setIntUniform(const std::string& variableName, int value) const { +inline void Shader::setIntUniform(const std::string& variableName, int value, bool errorIfMissing) const { assert(mProgramObjectID != 0); - glUniform1i(getUniformLocation(variableName), value); + GLint location = getUniformLocation(variableName, errorIfMissing); + if (location != -1) { + glUniform1i(location, value); + } } // Set a vector 2 uniform value to this shader (be careful if the uniform is not // used in the shader, the compiler will remove it, then when you will try // to set it, an assert will occur) -inline void Shader::setVector2Uniform(const std::string& variableName, const Vector2& v) const { +inline void Shader::setVector2Uniform(const std::string& variableName, const Vector2& v, bool errorIfMissing) const { assert(mProgramObjectID != 0); - glUniform2f(getUniformLocation(variableName), v.x, v.y); + GLint location = getUniformLocation(variableName, errorIfMissing); + if (location != -1) { + glUniform2f(location, v.x, v.y); + } } // Set a vector 3 uniform value to this shader (be careful if the uniform is not // used in the shader, the compiler will remove it, then when you will try // to set it, an assert will occur) -inline void Shader::setVector3Uniform(const std::string& variableName, const Vector3 &v) const { +inline void Shader::setVector3Uniform(const std::string& variableName, const Vector3 &v, bool errorIfMissing) const { assert(mProgramObjectID != 0); - glUniform3f(getUniformLocation(variableName), v.x, v.y, v.z); + GLint location = getUniformLocation(variableName, errorIfMissing); + if (location != -1) { + glUniform3f(location, v.x, v.y, v.z); + } } // Set a vector 4 uniform value to this shader (be careful if the uniform is not // used in the shader, the compiler will remove it, then when you will try // to set it, an assert will occur) -inline void Shader::setVector4Uniform(const std::string& variableName, const Vector4& v) const { +inline void Shader::setVector4Uniform(const std::string& variableName, const Vector4& v, bool errorIfMissing) const { assert(mProgramObjectID != 0); - glUniform4f(getUniformLocation(variableName), v.x, v.y, v.z, v.w); + GLint location = getUniformLocation(variableName, errorIfMissing); + if (location != -1) { + glUniform4f(location, v.x, v.y, v.z, v.w); + } } // Set a 4x4 matrix uniform value to this shader (be careful if the uniform is not // used in the shader, the compiler will remove it, then when you will try // to set it, an assert will occur) inline void Shader::setMatrix3x3Uniform(const std::string& variableName, const float* matrix, - bool transpose) const { + bool transpose, bool errorIfMissing) const { assert(mProgramObjectID != 0); - glUniformMatrix3fv(getUniformLocation(variableName), 1, transpose, matrix); + GLint location = getUniformLocation(variableName, errorIfMissing); + if (location != -1) { + glUniformMatrix3fv(location, 1, transpose, matrix); + } } // Set a 3x3 matrix uniform value to this shader (be careful if the uniform is not // used in the shader, the compiler will remove it, then when you will try // to set it, an assert will occur) -inline void Shader::setMatrix3x3Uniform(const std::string& variableName, const Matrix3& matrix) const { +inline void Shader::setMatrix3x3Uniform(const std::string& variableName, const Matrix3& matrix, bool errorIfMissing) const { assert(mProgramObjectID != 0); GLfloat mat[9]; for (int i=0; i<3; i++) { @@ -241,22 +262,28 @@ inline void Shader::setMatrix3x3Uniform(const std::string& variableName, const M mat[i*3 + j] = matrix.getValue(i, j); } } - glUniformMatrix3fv(getUniformLocation(variableName), 1, true, mat); + GLint location = getUniformLocation(variableName, errorIfMissing); + if (location != -1) { + glUniformMatrix3fv(location, 1, true, mat); + } } // Set a 4x4 matrix uniform value to this shader (be careful if the uniform is not // used in the shader, the compiler will remove it, then when you will try // to set it, an assert will occur) inline void Shader::setMatrix4x4Uniform(const std::string& variableName, const float* matrix, - bool transpose) const { + bool transpose, bool errorIfMissing) const { assert(mProgramObjectID != 0); - glUniformMatrix4fv(getUniformLocation(variableName), 1, transpose, matrix); + GLint location = getUniformLocation(variableName, errorIfMissing); + if (location != -1) { + glUniformMatrix4fv(location, 1, transpose, matrix); + } } // Set a 4x4 matrix uniform value to this shader (be careful if the uniform is not // used in the shader, the compiler will remove it, then when you will try // to set it, an assert will occur) -inline void Shader::setMatrix4x4Uniform(const std::string& variableName, const Matrix4& matrix) const { +inline void Shader::setMatrix4x4Uniform(const std::string& variableName, const Matrix4& matrix, bool errorIfMissing) const { assert(mProgramObjectID != 0); GLfloat mat[16]; for (int i=0; i<4; i++) { @@ -264,7 +291,10 @@ inline void Shader::setMatrix4x4Uniform(const std::string& variableName, const M mat[i*4 + j] = matrix.m[i][j]; } } - glUniformMatrix4fv(getUniformLocation(variableName), 1, true, mat); + GLint location = getUniformLocation(variableName, errorIfMissing); + if (location != -1) { + glUniformMatrix4fv(location, 1, true, mat); + } } // Return the shader object program ID diff --git a/testbed/opengl-framework/src/Texture2D.cpp b/testbed/opengl-framework/src/Texture2D.cpp index 1b316b73..6a3f4498 100644 --- a/testbed/opengl-framework/src/Texture2D.cpp +++ b/testbed/opengl-framework/src/Texture2D.cpp @@ -72,6 +72,28 @@ void Texture2D::create(uint width, uint height, uint internalFormat, uint format glBindTexture(GL_TEXTURE_2D, 0); } +// Create the texture +void Texture2D::create(uint width, uint height, uint internalFormat, uint format, uint type, + uint minFilter, uint maxFilter, uint wrapS, uint wrapT, void* data) { + + // Destroy the current texture + destroy(); + + mWidth = width; + mHeight = height; + + // Create the OpenGL texture + glGenTextures(1, &mID); + assert(mID != 0); + glBindTexture(GL_TEXTURE_2D, mID); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, maxFilter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter); + glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, mWidth, mHeight, 0, format, type, data); + glBindTexture(GL_TEXTURE_2D, 0); +} + // Destroy the texture void Texture2D::destroy() { if (mID != 0) { diff --git a/testbed/opengl-framework/src/Texture2D.h b/testbed/opengl-framework/src/Texture2D.h index 9c6fa1c0..08087081 100644 --- a/testbed/opengl-framework/src/Texture2D.h +++ b/testbed/opengl-framework/src/Texture2D.h @@ -71,6 +71,10 @@ class Texture2D { void create(uint width, uint height, uint internalFormat, uint format, uint type, void* data = NULL); + // Create the texture + void create(uint width, uint height, uint internalFormat, uint format, uint type, + uint minFilter, uint maxFilter, uint wrapS, uint wrapT, void* data); + // Destroy the texture void destroy(); diff --git a/testbed/scenes/collisionshapes/CollisionShapesScene.cpp b/testbed/scenes/collisionshapes/CollisionShapesScene.cpp index 040fec2b..758c773b 100644 --- a/testbed/scenes/collisionshapes/CollisionShapesScene.cpp +++ b/testbed/scenes/collisionshapes/CollisionShapesScene.cpp @@ -90,7 +90,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name) radius * sin(angle)); // Create a sphere and a corresponding rigid in the dynamics world - Box* box = new Box(BOX_SIZE, position , BOX_MASS, mDynamicsWorld, mPhongShader); + Box* box = new Box(BOX_SIZE, position , BOX_MASS, mDynamicsWorld); // Change the material properties of the rigid body rp3d::Material& material = box->getRigidBody()->getMaterial(); @@ -208,7 +208,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name) // Create the floor openglframework::Vector3 floorPosition(0, 0, 0); - mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld, mPhongShader); + mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld); // The floor must be a static rigid body mFloor->getRigidBody()->setType(rp3d::STATIC); diff --git a/testbed/scenes/cubes/CubesScene.cpp b/testbed/scenes/cubes/CubesScene.cpp index 6cb500ea..ce1b5bbf 100644 --- a/testbed/scenes/cubes/CubesScene.cpp +++ b/testbed/scenes/cubes/CubesScene.cpp @@ -32,18 +32,13 @@ using namespace cubesscene; // Constructor CubesScene::CubesScene(const std::string& name) - : Scene(name), mLight0(0), - mPhongShader("shaders/phong.vert", "shaders/phong.frag") { - - // Move the light 0 - mLight0.translateWorld(Vector3(7, 15, 15)); + : SceneDemo(name, SCENE_RADIUS) { // Compute the radius and the center of the scene - float radiusScene = 30.0f; openglframework::Vector3 center(0, 5, 0); // Set the center of the scene - setScenePosition(center, radiusScene); + setScenePosition(center, SCENE_RADIUS); // Gravity vector in the dynamics world rp3d::Vector3 gravity(0, rp3d::decimal(-5.81), 0); @@ -69,7 +64,7 @@ CubesScene::CubesScene(const std::string& name) 0); // Create a cube and a corresponding rigid in the dynamics world - Box* cube = new Box(BOX_SIZE, position , BOX_MASS, mDynamicsWorld, mPhongShader); + Box* cube = new Box(BOX_SIZE, position , BOX_MASS, mDynamicsWorld); // Change the material properties of the rigid body rp3d::Material& material = cube->getRigidBody()->getMaterial(); @@ -81,7 +76,7 @@ CubesScene::CubesScene(const std::string& name) // Create the floor openglframework::Vector3 floorPosition(0, 0, 0); - mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld, mPhongShader); + mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld); // The floor must be a static rigid body mFloor->getRigidBody()->setType(rp3d::STATIC); @@ -171,39 +166,25 @@ void CubesScene::update() { } } -// Render the scene -void CubesScene::render() { - - glEnable(GL_DEPTH_TEST); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glEnable(GL_CULL_FACE); +// Render the scene in a single pass +void CubesScene::renderSinglePass(Shader& shader) { // Get the world-space to camera-space matrix const openglframework::Matrix4 worldToCameraMatrix = mCamera.getTransformMatrix().getInverse(); // Bind the shader - mPhongShader.bind(); - - // Set the variables of the shader - mPhongShader.setMatrix4x4Uniform("projectionMatrix", mCamera.getProjectionMatrix()); - mPhongShader.setVector3Uniform("light0PosCameraSpace",worldToCameraMatrix * mLight0.getOrigin()); - mPhongShader.setVector3Uniform("lightAmbientColor", Vector3(0.3f, 0.3f, 0.3f)); - const Color& diffCol = mLight0.getDiffuseColor(); - const Color& specCol = mLight0.getSpecularColor(); - mPhongShader.setVector3Uniform("light0DiffuseColor", Vector3(diffCol.r, diffCol.g, diffCol.b)); - mPhongShader.setVector3Uniform("light0SpecularColor", Vector3(specCol.r, specCol.g, specCol.b)); - mPhongShader.setFloatUniform("shininess", 60.0f); + shader.bind(); // Render all the cubes of the scene for (std::vector::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { - (*it)->render(mPhongShader, worldToCameraMatrix); + (*it)->render(shader, worldToCameraMatrix); } // Render the floor - mFloor->render(mPhongShader, worldToCameraMatrix); + mFloor->render(shader, worldToCameraMatrix); // Unbind the shader - mPhongShader.unbind(); + shader.unbind(); } // Reset the scene diff --git a/testbed/scenes/cubes/CubesScene.h b/testbed/scenes/cubes/CubesScene.h index 4c3df694..695aa89a 100644 --- a/testbed/scenes/cubes/CubesScene.h +++ b/testbed/scenes/cubes/CubesScene.h @@ -30,30 +30,25 @@ #include "openglframework.h" #include "reactphysics3d.h" #include "Box.h" -#include "Scene.h" +#include "SceneDemo.h" namespace cubesscene { // Constants -const int NB_CUBES = 20; // Number of boxes in the scene +const float SCENE_RADIUS = 30.0f; // Radius of the scene in meters +const int NB_CUBES = 20; // Number of boxes in the scene const openglframework::Vector3 BOX_SIZE(2, 2, 2); // Box dimensions in meters const openglframework::Vector3 FLOOR_SIZE(50, 0.5f, 50); // Floor dimensions in meters const float BOX_MASS = 1.0f; // Box mass in kilograms const float FLOOR_MASS = 100.0f; // Floor mass in kilograms // Class CubesScene -class CubesScene : public Scene { +class CubesScene : public SceneDemo { protected : // -------------------- Attributes -------------------- // - /// Light 0 - openglframework::Light mLight0; - - /// Phong shader - openglframework::Shader mPhongShader; - /// All the boxes of the scene std::vector mBoxes; @@ -80,8 +75,8 @@ class CubesScene : public Scene { /// Update the scene (take a simulation step) virtual void update(); - /// Render the scene - virtual void render(); + /// Render the scene in a single pass + virtual void renderSinglePass(openglframework::Shader& shader); /// Reset the scene virtual void reset(); diff --git a/testbed/scenes/joints/JointsScene.cpp b/testbed/scenes/joints/JointsScene.cpp index ea5e413b..655c629e 100644 --- a/testbed/scenes/joints/JointsScene.cpp +++ b/testbed/scenes/joints/JointsScene.cpp @@ -291,7 +291,7 @@ void JointsScene::createBallAndSocketJoints() { // Create a box and a corresponding rigid in the dynamics world mBallAndSocketJointChainBoxes[i] = new Box(boxDimension, positionBox , boxMass, - mDynamicsWorld, mPhongShader); + mDynamicsWorld); // The fist box cannot move (static body) if (i == 0) { @@ -336,7 +336,7 @@ void JointsScene::createSliderJoint() { // Create a box and a corresponding rigid in the dynamics world openglframework::Vector3 box1Dimension(2, 4, 2); - mSliderJointBottomBox = new Box(box1Dimension, positionBox1 , BOX_MASS, mDynamicsWorld, mPhongShader); + mSliderJointBottomBox = new Box(box1Dimension, positionBox1 , BOX_MASS, mDynamicsWorld); // The fist box cannot move mSliderJointBottomBox->getRigidBody()->setType(rp3d::STATIC); @@ -352,7 +352,7 @@ void JointsScene::createSliderJoint() { // Create a box and a corresponding rigid in the dynamics world openglframework::Vector3 box2Dimension(1.5f, 4, 1.5f); - mSliderJointTopBox = new Box(box2Dimension, positionBox2, BOX_MASS, mDynamicsWorld, mPhongShader); + mSliderJointTopBox = new Box(box2Dimension, positionBox2, BOX_MASS, mDynamicsWorld); // Change the material properties of the rigid body rp3d::Material& material2 = mSliderJointTopBox->getRigidBody()->getMaterial(); @@ -388,7 +388,7 @@ void JointsScene::createPropellerHingeJoint() { // Create a box and a corresponding rigid in the dynamics world openglframework::Vector3 boxDimension(10, 1, 1); - mPropellerBox = new Box(boxDimension, positionBox1 , BOX_MASS, mDynamicsWorld, mPhongShader); + mPropellerBox = new Box(boxDimension, positionBox1 , BOX_MASS, mDynamicsWorld); // Change the material properties of the rigid body rp3d::Material& material = mPropellerBox->getRigidBody()->getMaterial(); @@ -423,7 +423,7 @@ void JointsScene::createFixedJoints() { // Create a box and a corresponding rigid in the dynamics world openglframework::Vector3 boxDimension(1.5, 1.5, 1.5); - mFixedJointBox1 = new Box(boxDimension, positionBox1 , BOX_MASS, mDynamicsWorld, mPhongShader); + mFixedJointBox1 = new Box(boxDimension, positionBox1 , BOX_MASS, mDynamicsWorld); // Change the material properties of the rigid body rp3d::Material& material1 = mFixedJointBox1->getRigidBody()->getMaterial(); @@ -435,7 +435,7 @@ void JointsScene::createFixedJoints() { openglframework::Vector3 positionBox2(-5, 7, 0); // Create a box and a corresponding rigid in the dynamics world - mFixedJointBox2 = new Box(boxDimension, positionBox2 , BOX_MASS, mDynamicsWorld, mPhongShader); + mFixedJointBox2 = new Box(boxDimension, positionBox2 , BOX_MASS, mDynamicsWorld); // Change the material properties of the rigid body rp3d::Material& material2 = mFixedJointBox2->getRigidBody()->getMaterial(); @@ -470,7 +470,7 @@ void JointsScene::createFloor() { // Create the floor openglframework::Vector3 floorPosition(0, 0, 0); - mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld, mPhongShader); + mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld); // The floor must be a static rigid body mFloor->getRigidBody()->setType(rp3d::STATIC); diff --git a/testbed/scenes/raycast/RaycastScene.cpp b/testbed/scenes/raycast/RaycastScene.cpp index a7d6bee0..3d74979e 100644 --- a/testbed/scenes/raycast/RaycastScene.cpp +++ b/testbed/scenes/raycast/RaycastScene.cpp @@ -60,7 +60,7 @@ RaycastScene::RaycastScene(const std::string& name) openglframework::Vector3 position2(0, 0, 0); // Create a box and a corresponding collision body in the dynamics world - mBox = new Box(BOX_SIZE, position2, mCollisionWorld, mPhongShader); + mBox = new Box(BOX_SIZE, position2, mCollisionWorld); mBox->getCollisionBody()->setIsActive(false); // ---------- Sphere ---------- // diff --git a/testbed/shaders/depth.frag b/testbed/shaders/depth.frag index 9b32019e..75c12abe 100644 --- a/testbed/shaders/depth.frag +++ b/testbed/shaders/depth.frag @@ -1,3 +1,5 @@ +#version 330 + /******************************************************************************** * OpenGL-Framework * * Copyright (c) 2015 Daniel Chappuis * @@ -6,7 +8,7 @@ * This software is provided 'as-is', without any express or implied warranty. * * In no event will the authors be held liable for any damages arising from the * * use of this software. * -* * +* * * Permission is granted to anyone to use this software for any purpose, * * including commercial applications, and to alter it and redistribute it * * freely, subject to the following restrictions: * @@ -23,10 +25,11 @@ * * ********************************************************************************/ -void main(void) { +// Out variable +out vec4 color; // Output color - // Compute the depth of the pixel - float depth = +void main() { - gl_FragColor = vec4(depth, depth, depth, 1); + // Compute the final color + color = vec4(1, 1, 1, 1); } diff --git a/testbed/shaders/depth.vert b/testbed/shaders/depth.vert index 09b9ff9a..ec0c0705 100644 --- a/testbed/shaders/depth.vert +++ b/testbed/shaders/depth.vert @@ -1,3 +1,5 @@ +#version 330 + /******************************************************************************** * OpenGL-Framework * * Copyright (c) 2015 Daniel Chappuis * @@ -24,13 +26,14 @@ ********************************************************************************/ // Uniform variables -uniform mat4 modelToWorldMatrix; // Model too world coordinates matrix -uniform mat4 worldToCameraMatrix; // World to camera coordinates matrix +uniform mat4 localToCameraMatrix; // Local-space to camera-space matrix uniform mat4 projectionMatrix; // Projection matrix -void main(void) { +// In variables +in vec4 vertexPosition; + +void main() { // Compute the clip-space vertex coordinates - gl_Position = projectionMatrix * worldToCameraMatrix * - modelToWorldMatrix * gl_Vertex; + gl_Position = projectionMatrix * localToCameraMatrix * vertexPosition; } diff --git a/testbed/shaders/gui.frag b/testbed/shaders/gui.frag deleted file mode 100644 index a00d52bb..00000000 --- a/testbed/shaders/gui.frag +++ /dev/null @@ -1,10 +0,0 @@ -#version 330 -uniform sampler2D Texture; -in vec2 Frag_UV; -in vec4 Frag_Color; -out vec4 Out_Color; - -void main() -{ - Out_Color = Frag_Color * texture( Texture, Frag_UV.st); -} diff --git a/testbed/shaders/gui.vert b/testbed/shaders/gui.vert deleted file mode 100644 index 18870a74..00000000 --- a/testbed/shaders/gui.vert +++ /dev/null @@ -1,15 +0,0 @@ -#version 330 - -uniform mat4 ProjMtx; -in vec2 Position; -in vec2 UV; -in vec4 Color; -out vec2 Frag_UV; -out vec4 Frag_Color; - -void main() -{ - Frag_UV = UV; - Frag_Color = Color; - gl_Position = ProjMtx * vec4(Position.xy,0,1); -} diff --git a/testbed/src/SceneDemo.cpp b/testbed/src/SceneDemo.cpp new file mode 100644 index 00000000..0b5fa0ef --- /dev/null +++ b/testbed/src/SceneDemo.cpp @@ -0,0 +1,124 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Libraries +#include "SceneDemo.h" +#include + +using namespace openglframework; + +// Constructor +SceneDemo::SceneDemo(const std::string& name, float sceneRadius) : Scene(name), mLight0(0), + mDepthShader("shaders/depth.vert", "shaders/depth.frag"), + mPhongShader("shaders/phong.vert", "shaders/phong.frag") { + + // Move the light0 + mLight0.translateWorld(Vector3(7, 15, 15)); + + // Camera at light0 postion for the shadow map + mShadowMapLightCamera.translateWorld(mLight0.getOrigin()); + mShadowMapLightCamera.setDimensions(SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT); + mShadowMapLightCamera.setFieldOfView(45.0f); + mShadowMapLightCamera.setSceneRadius(sceneRadius); + mShadowMapLightCamera.setZoom(1.0); + + // Bias matrix for the shadow map + mShadowMapBiasMatrix.setAllValues(0.5f, 0.0f, 0.0f, 0.5f, + 0.0f, 0.5f, 0.5f, 0.5f, + 0.0f, 0.0f, 0.0f, 0.5f, + 0.0f, 0.0f, 0.0f, 1.0f); + + // Create the Shadow map FBO and texture + createShadowMapFBOAndTexture(); +} + +// Destructor +SceneDemo::~SceneDemo() { + + mShadowMapTexture.destroy(); + mFBOShadowMap.destroy(); +} + +// Render the scene (in multiple passes for shadow mapping) +void SceneDemo::render() { + + glEnable(GL_DEPTH_TEST); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glEnable(GL_CULL_FACE); + + // Get the world-space to camera-space matrix + const openglframework::Matrix4 worldToCameraMatrix = mCamera.getTransformMatrix().getInverse(); + + // ---------- Render the scene to generate the shadow map (first pass) ----------- // + + // Bind the shader + mDepthShader.bind(); + + // Set the variables of the shader + mDepthShader.setMatrix4x4Uniform("projectionMatrix", mCamera.getProjectionMatrix()); + + // Render the objects of the scene + renderSinglePass(mDepthShader); + + // Unbind the shader + mDepthShader.unbind(); + + // ---------- Render the scene for final rendering (second pass) ----------- // + + mPhongShader.bind(); + + // Set the variables of the shader + mPhongShader.setMatrix4x4Uniform("projectionMatrix", mCamera.getProjectionMatrix()); + mPhongShader.setVector3Uniform("light0PosCameraSpace",worldToCameraMatrix * mLight0.getOrigin()); + mPhongShader.setVector3Uniform("lightAmbientColor", Vector3(0.3f, 0.3f, 0.3f)); + const Color& diffCol = mLight0.getDiffuseColor(); + const Color& specCol = mLight0.getSpecularColor(); + mPhongShader.setVector3Uniform("light0DiffuseColor", Vector3(diffCol.r, diffCol.g, diffCol.b)); + mPhongShader.setVector3Uniform("light0SpecularColor", Vector3(specCol.r, specCol.g, specCol.b)); + mPhongShader.setFloatUniform("shininess", 60.0f); + + // Render the objects of the scene + renderSinglePass(mPhongShader); + + mPhongShader.unbind(); +} + +// Create the Shadow map FBO and texture +void SceneDemo::createShadowMapFBOAndTexture() { + + // Create the texture for the depth values + mShadowMapTexture.create(SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, + GL_UNSIGNED_BYTE, GL_NEAREST, GL_NEAREST, GL_CLAMP, GL_CLAMP, NULL); + + // Create the FBO for the shadow map + mFBOShadowMap.create(0, 0, false); + mFBOShadowMap.bind(GL_NONE); + mFBOShadowMap.attachTexture(GL_DEPTH_ATTACHMENT_EXT, mShadowMapTexture.getID()); +} + +// Render the shadow map +void SceneDemo::renderShadowMap() { + +} diff --git a/testbed/src/SceneDemo.h b/testbed/src/SceneDemo.h new file mode 100644 index 00000000..4bcc8d91 --- /dev/null +++ b/testbed/src/SceneDemo.h @@ -0,0 +1,94 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +#ifndef SCENEDEMO_H +#define SCENEDEMO_H + +// Libraries +#include "Scene.h" + +// Constants +const int SHADOWMAP_WIDTH = 1024; +const int SHADOWMAP_HEIGHT = 1024; + +// Class SceneDemo +// Abstract class that represents a 3D scene for the ReactPhysics3D examples. +// This scene has a single light source with shadow mapping. +class SceneDemo : public Scene { + + protected: + + // -------------------- Attributes -------------------- // + + /// Light 0 + openglframework::Light mLight0; + + /// FBO for the shadow map + openglframework::FrameBufferObject mFBOShadowMap; + + /// Shadow map texture + openglframework::Texture2D mShadowMapTexture; + + /// Camera at light0 position for the shadow map + openglframework::Camera mShadowMapLightCamera; + + /// Bias matrix for the shadow map + openglframework::Matrix4 mShadowMapBiasMatrix; + + /// Depth shader to render the shadow map + openglframework::Shader mDepthShader; + + /// Phong shader + openglframework::Shader mPhongShader; + + + // -------------------- Methods -------------------- // + + // Create the Shadow map FBO and texture + void createShadowMapFBOAndTexture(); + + // Render the shadow map + void renderShadowMap(); + + public: + + // -------------------- Methods -------------------- // + + /// Constructor + SceneDemo(const std::string& name, float sceneRadius); + + /// Destructor + virtual ~SceneDemo(); + + /// Render the scene (possibly in multiple passes for shadow mapping) + virtual void render(); + + /// Render the scene in a single pass + virtual void renderSinglePass(openglframework::Shader& shader)=0; +}; + +#endif + + From 2ad9fb2c06b764d3f0d944ece1c7b194367c1a0d Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Sat, 25 Jul 2015 00:26:26 +0000 Subject: [PATCH 20/36] Continue working on the shadow mapping for the testbed application --- .../opengl-framework/src/FrameBufferObject.h | 8 +- testbed/opengl-framework/src/Light.cpp | 38 ------ testbed/opengl-framework/src/Light.h | 39 ------ testbed/opengl-framework/src/Texture2D.h | 2 - testbed/scenes/cubes/CubesScene.cpp | 5 +- testbed/scenes/cubes/CubesScene.h | 3 +- testbed/shaders/quad.frag | 42 ++++++ testbed/shaders/quad.vert | 41 ++++++ testbed/src/Scene.cpp | 4 +- testbed/src/Scene.h | 14 ++ testbed/src/SceneDemo.cpp | 120 ++++++++++++++++-- testbed/src/SceneDemo.h | 18 ++- testbed/src/TestbedApplication.cpp | 10 +- 13 files changed, 233 insertions(+), 111 deletions(-) create mode 100644 testbed/shaders/quad.frag create mode 100644 testbed/shaders/quad.vert diff --git a/testbed/opengl-framework/src/FrameBufferObject.h b/testbed/opengl-framework/src/FrameBufferObject.h index a76951c7..6194510a 100644 --- a/testbed/opengl-framework/src/FrameBufferObject.h +++ b/testbed/opengl-framework/src/FrameBufferObject.h @@ -65,7 +65,7 @@ class FrameBufferObject { void attachTexture(uint position, uint textureID); // Bind the FBO - void bind(uint position) const; + void bind() const; // Unbind the FBO void unbind() const; @@ -78,18 +78,14 @@ class FrameBufferObject { }; // Bind the FBO -inline void FrameBufferObject::bind(uint position) const { +inline void FrameBufferObject::bind() const { assert(mFrameBufferID != 0); glBindFramebuffer(GL_FRAMEBUFFER, mFrameBufferID); - glDrawBuffer(position); - glReadBuffer(position); } // Unbind the FBO inline void FrameBufferObject::unbind() const { assert(mFrameBufferID != 0); - glDrawBuffer(GL_NONE); - glReadBuffer(GL_NONE); glBindFramebuffer(GL_FRAMEBUFFER, 0); } diff --git a/testbed/opengl-framework/src/Light.cpp b/testbed/opengl-framework/src/Light.cpp index cd1831eb..9bffc0c6 100644 --- a/testbed/opengl-framework/src/Light.cpp +++ b/testbed/opengl-framework/src/Light.cpp @@ -60,41 +60,3 @@ void Light::init() { glLightfv(mLightID, GL_DIFFUSE, diffuseColor); glLightfv(mLightID, GL_SPECULAR, specularColor); } - -// Create a shadow map associated with this light -bool Light::createShadowMap(uint width, uint height) { - - // Destroy the current shadow map - destroyShadowMap(); - - // Create the Framebuffer object to render the shadow map - bool isFBOCreated = mFBOShadowMap.create(width, height, false); - if (!isFBOCreated) { - std::cerr << "Error : Cannot create the Shadow Map !" << std::endl; - destroyShadowMap(); - return false; - } - - // Bind the Framebuffer object - mFBOShadowMap.bind(GL_NONE); - - // Create the shadow map depth texture - mShadowMap.create(width, height, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE); - - // Attache the shadow map texture to the Framebuffer object - mFBOShadowMap.attachTexture(GL_DEPTH_ATTACHMENT_EXT, mShadowMap.getID()); - - // Unbind the Framebuffer object - mFBOShadowMap.unbind(); - - // TODO : Change the path of the shader here so that it does not depend on the build folder - bool isShaderCreated = mDepthShader.create("../../opengl-framework/src/shaders/depth.vert", - "../../opengl-framework/src/shaders/depth.vert"); - if (!isShaderCreated) { - std::cerr << "Error : Cannot create the Shadow Map !" << std::endl; - destroyShadowMap(); - return false; - } - - return true; -} diff --git a/testbed/opengl-framework/src/Light.h b/testbed/opengl-framework/src/Light.h index 8f8323d9..9ecc63b9 100644 --- a/testbed/opengl-framework/src/Light.h +++ b/testbed/opengl-framework/src/Light.h @@ -31,7 +31,6 @@ #include "maths/Vector3.h" #include "Object3D.h" #include "Texture2D.h" -#include "FrameBufferObject.h" #include "Shader.h" #include @@ -56,15 +55,6 @@ class Light : public Object3D { // True if the light is active bool mIsActive; - // Shadow map associated with this light - Texture2D mShadowMap; - - // Framebuffer object to render the shadow map - FrameBufferObject mFBOShadowMap; - - // Shader to render the depth of the scene into a texture - Shader mDepthShader; - public: // -------------------- Methods -------------------- // @@ -101,18 +91,6 @@ class Light : public Object3D { // Disable the light void disable(); - - // Create a shadow map associated with this light - bool createShadowMap(uint width, uint height); - - // Call this method before rendering the scene for the shadow map computation - void startRenderingShadowMap(); - - // Call this method after having rendered the scene for the shadow map computation - void stopRenderingShadowMap(); - - // Destroy the shadow map associated with this light - void destroyShadowMap(); }; // Return the diffuse color @@ -159,23 +137,6 @@ inline void Light::disable() { glDisable(GL_LIGHT0 + mLightID); } -// Destroy the shadow map associated with this light -inline void Light::destroyShadowMap() { - mShadowMap.destroy(); - mFBOShadowMap.destroy(); - mDepthShader.destroy(); -} - -// Call this method before rendering the scene for the shadow map computation -inline void Light::startRenderingShadowMap() { - assert(mShadowMap.getID()); -} - -// Call this method after having rendered the scene for the shadow map computation -inline void Light::stopRenderingShadowMap() { - assert(mShadowMap.getID()); -} - } #endif diff --git a/testbed/opengl-framework/src/Texture2D.h b/testbed/opengl-framework/src/Texture2D.h index 08087081..f765e1ac 100644 --- a/testbed/opengl-framework/src/Texture2D.h +++ b/testbed/opengl-framework/src/Texture2D.h @@ -103,7 +103,6 @@ class Texture2D { // Bind the texture inline void Texture2D::bind() const { assert(mID != 0); - glEnable(GL_TEXTURE_2D); glActiveTexture(GL_TEXTURE0 + mLayer); glBindTexture(GL_TEXTURE_2D, mID); } @@ -113,7 +112,6 @@ inline void Texture2D::unbind() const { assert(mID != 0); glActiveTexture(GL_TEXTURE0 + mLayer); glBindTexture(GL_TEXTURE_2D, 0); - glDisable(GL_TEXTURE_2D); } // Get the OpenGL texture ID diff --git a/testbed/scenes/cubes/CubesScene.cpp b/testbed/scenes/cubes/CubesScene.cpp index ce1b5bbf..1defa9ce 100644 --- a/testbed/scenes/cubes/CubesScene.cpp +++ b/testbed/scenes/cubes/CubesScene.cpp @@ -167,10 +167,7 @@ void CubesScene::update() { } // Render the scene in a single pass -void CubesScene::renderSinglePass(Shader& shader) { - - // Get the world-space to camera-space matrix - const openglframework::Matrix4 worldToCameraMatrix = mCamera.getTransformMatrix().getInverse(); +void CubesScene::renderSinglePass(Shader& shader, const openglframework::Matrix4& worldToCameraMatrix) { // Bind the shader shader.bind(); diff --git a/testbed/scenes/cubes/CubesScene.h b/testbed/scenes/cubes/CubesScene.h index 695aa89a..02db7d4c 100644 --- a/testbed/scenes/cubes/CubesScene.h +++ b/testbed/scenes/cubes/CubesScene.h @@ -76,7 +76,8 @@ class CubesScene : public SceneDemo { virtual void update(); /// Render the scene in a single pass - virtual void renderSinglePass(openglframework::Shader& shader); + virtual void renderSinglePass(openglframework::Shader& shader, + const openglframework::Matrix4& worldToCameraMatrix); /// Reset the scene virtual void reset(); diff --git a/testbed/shaders/quad.frag b/testbed/shaders/quad.frag new file mode 100644 index 00000000..a6a842ba --- /dev/null +++ b/testbed/shaders/quad.frag @@ -0,0 +1,42 @@ +#version 330 + +/******************************************************************************** +* OpenGL-Framework * +* Copyright (c) 2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Uniform variables +uniform sampler2D textureSampler; // Texture + +// In variables +in vec2 texCoords; // Texture coordinates + +// Out variable +out vec4 color; // Output color + +void main() { + + // Get the texture color + float depthColor = texture(textureSampler, texCoords).r; + color = vec4(depthColor, depthColor, depthColor, 1); +} diff --git a/testbed/shaders/quad.vert b/testbed/shaders/quad.vert new file mode 100644 index 00000000..81c6ee9e --- /dev/null +++ b/testbed/shaders/quad.vert @@ -0,0 +1,41 @@ +#version 330 + +/******************************************************************************** +* OpenGL-Framework * +* Copyright (c) 2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// In variables +in vec4 vertexPosition; + +// Out variables +out vec2 texCoords; // Texture coordinates + +void main() { + + // Compute the texture coordinates + texCoords = (vertexPosition.xy + vec2(1, 1)) / 2.0; + + // Compute the clip-space vertex coordinates + gl_Position = vec4(vertexPosition.xyz, 1); +} diff --git a/testbed/src/Scene.cpp b/testbed/src/Scene.cpp index 5d832746..ea64fc13 100644 --- a/testbed/src/Scene.cpp +++ b/testbed/src/Scene.cpp @@ -30,7 +30,9 @@ using namespace openglframework; // Constructor -Scene::Scene(const std::string& name) : mName(name), mInterpolationFactor(0.0f) { +Scene::Scene(const std::string& name) + : mName(name), mInterpolationFactor(0.0f), mViewportX(0), mViewportY(0), + mViewportWidth(0), mViewportHeight(0) { } diff --git a/testbed/src/Scene.h b/testbed/src/Scene.h index 53c7c077..d4e05892 100644 --- a/testbed/src/Scene.h +++ b/testbed/src/Scene.h @@ -87,6 +87,9 @@ class Scene { /// Interpolation factor for the bodies in the current frame float mInterpolationFactor; + /// Viewport x,y, width and height values + int mViewportX, mViewportY, mViewportWidth, mViewportHeight; + // -------------------- Methods -------------------- // /// Set the scene position (where the camera needs to look at) @@ -152,6 +155,9 @@ class Scene { /// Set the window dimension void setWindowDimension(int width, int height); + /// Set the viewport to render the scene + void setViewport(int x, int y, int width, int height); + /// Return a reference to the camera const openglframework::Camera& getCamera() const; @@ -189,6 +195,14 @@ inline void Scene::setWindowDimension(int width, int height) { mWindowHeight = height; } +// Set the viewport to render the scene +inline void Scene::setViewport(int x, int y, int width, int height) { + mViewportX = x; + mViewportY = y; + mViewportWidth = width; + mViewportHeight = height; +} + // Get the engine settings inline EngineSettings Scene::getEngineSettings() const { return mEngineSettings; diff --git a/testbed/src/SceneDemo.cpp b/testbed/src/SceneDemo.cpp index 0b5fa0ef..e48f1090 100644 --- a/testbed/src/SceneDemo.cpp +++ b/testbed/src/SceneDemo.cpp @@ -32,10 +32,12 @@ using namespace openglframework; // Constructor SceneDemo::SceneDemo(const std::string& name, float sceneRadius) : Scene(name), mLight0(0), mDepthShader("shaders/depth.vert", "shaders/depth.frag"), - mPhongShader("shaders/phong.vert", "shaders/phong.frag") { + mPhongShader("shaders/phong.vert", "shaders/phong.frag"), + mQuadShader("shaders/quad.vert", "shaders/quad.frag"), + mVBOQuad(GL_ARRAY_BUFFER) { // Move the light0 - mLight0.translateWorld(Vector3(7, 15, 15)); + mLight0.translateWorld(Vector3(20, 20, 20)); // Camera at light0 postion for the shadow map mShadowMapLightCamera.translateWorld(mLight0.getOrigin()); @@ -52,6 +54,8 @@ SceneDemo::SceneDemo(const std::string& name, float sceneRadius) : Scene(name), // Create the Shadow map FBO and texture createShadowMapFBOAndTexture(); + + createQuadVBO(); } // Destructor @@ -65,28 +69,45 @@ SceneDemo::~SceneDemo() { void SceneDemo::render() { glEnable(GL_DEPTH_TEST); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_CULL_FACE); - // Get the world-space to camera-space matrix - const openglframework::Matrix4 worldToCameraMatrix = mCamera.getTransformMatrix().getInverse(); - // ---------- Render the scene to generate the shadow map (first pass) ----------- // + // Get the world-space to camera-space matrix + const openglframework::Matrix4 worldToLightCameraMatrix = mShadowMapLightCamera.getTransformMatrix().getInverse(); + + mFBOShadowMap.bind(); + // Bind the shader mDepthShader.bind(); // Set the variables of the shader - mDepthShader.setMatrix4x4Uniform("projectionMatrix", mCamera.getProjectionMatrix()); + mDepthShader.setMatrix4x4Uniform("projectionMatrix", mShadowMapBiasMatrix * mShadowMapLightCamera.getProjectionMatrix()); + + // Set the viewport to render into the shadow map texture + glViewport(0, 0, SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT); + + // Clear previous frame values + glClear( GL_DEPTH_BUFFER_BIT); + + // Disable color rendering, we only want to write to the Z-Buffer + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); // Render the objects of the scene - renderSinglePass(mDepthShader); + renderSinglePass(mDepthShader, worldToLightCameraMatrix); // Unbind the shader mDepthShader.unbind(); + mFBOShadowMap.unbind(); + + // ---------- Render the scene for final rendering (second pass) ----------- // + // Get the world-space to camera-space matrix + const openglframework::Matrix4 worldToCameraMatrix = mCamera.getTransformMatrix().getInverse(); + + mPhongShader.bind(); // Set the variables of the shader @@ -99,10 +120,22 @@ void SceneDemo::render() { mPhongShader.setVector3Uniform("light0SpecularColor", Vector3(specCol.r, specCol.g, specCol.b)); mPhongShader.setFloatUniform("shininess", 60.0f); + // Set the viewport to render the scene + glViewport(mViewportX, mViewportY, mViewportWidth, mViewportHeight); + + //Enabling color write (previously disabled for light POV z-buffer rendering) + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + + // Clear previous frame values + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + // Render the objects of the scene - renderSinglePass(mPhongShader); + renderSinglePass(mPhongShader, worldToCameraMatrix); mPhongShader.unbind(); + + + // drawTextureQuad(); } // Create the Shadow map FBO and texture @@ -111,14 +144,77 @@ void SceneDemo::createShadowMapFBOAndTexture() { // Create the texture for the depth values mShadowMapTexture.create(SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, GL_NEAREST, GL_NEAREST, GL_CLAMP, GL_CLAMP, NULL); + mShadowMapTexture.setLayer(1); // Create the FBO for the shadow map mFBOShadowMap.create(0, 0, false); - mFBOShadowMap.bind(GL_NONE); + mFBOShadowMap.bind(); + + // Tell OpenGL that we won't bind a color texture with the currently binded FBO + glDrawBuffer(GL_NONE); + glReadBuffer(GL_NONE); + mFBOShadowMap.attachTexture(GL_DEPTH_ATTACHMENT_EXT, mShadowMapTexture.getID()); + mFBOShadowMap.unbind(); } -// Render the shadow map -void SceneDemo::renderShadowMap() { +// TODO : Delete this +void SceneDemo::createQuadVBO() { + mVAOQuad.create(); + mVAOQuad.bind(); + + static const GLfloat quadVertexData[] = { + -1.0f, -1.0f, 0.0f, + 1.0f, -1.0f, 0.0f, + -1.0f, 1.0f, 0.0f, + -1.0f, 1.0f, 0.0f, + 1.0f, -1.0f, 0.0f, + 1.0f, 1.0f, 0.0f, + }; + + mVBOQuad.create(); + mVBOQuad.bind(); + mVBOQuad.copyDataIntoVBO(sizeof(quadVertexData), quadVertexData, GL_STATIC_DRAW); + mVBOQuad.unbind(); + + mVAOQuad.unbind(); +} + +// TODO : Delete this +void SceneDemo::drawTextureQuad() { + + glViewport(mViewportX, mViewportY, mViewportWidth, mViewportHeight); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + + // Clear previous frame values + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + mVAOQuad.bind(); + mQuadShader.bind(); + mShadowMapTexture.bind(); + mQuadShader.setIntUniform("textureSampler", mShadowMapTexture.getID()); + mVBOQuad.bind(); + + GLint vertexPositionLoc = mQuadShader.getAttribLocation("vertexPosition"); + glEnableVertexAttribArray(vertexPositionLoc); + + glVertexAttribPointer( + vertexPositionLoc, // attribute 0. No particular reason for 0, but must match the layout in the shader. + 3, // size + GL_FLOAT, // type + GL_FALSE, // normalized? + 0, // stride + (void*)0 // array buffer offset + ); + + // Draw the triangles ! + glDrawArrays(GL_TRIANGLES, 0, 6); // 2*3 indices starting at 0 -> 2 triangles + + glDisableVertexAttribArray(vertexPositionLoc); + + mVBOQuad.unbind(); + mShadowMapTexture.unbind(); + mQuadShader.unbind(); + mVAOQuad.unbind(); } diff --git a/testbed/src/SceneDemo.h b/testbed/src/SceneDemo.h index 4bcc8d91..87b5f989 100644 --- a/testbed/src/SceneDemo.h +++ b/testbed/src/SceneDemo.h @@ -63,14 +63,25 @@ class SceneDemo : public Scene { /// Phong shader openglframework::Shader mPhongShader; + // TODO : Delete this + openglframework::Shader mQuadShader; + + // TODO : Delete this + openglframework::VertexArrayObject mVAOQuad; + + openglframework::VertexBufferObject mVBOQuad; + // -------------------- Methods -------------------- // // Create the Shadow map FBO and texture void createShadowMapFBOAndTexture(); - // Render the shadow map - void renderShadowMap(); + // TODO : Delete this + void createQuadVBO(); + + // TODO : Delete this + void drawTextureQuad(); public: @@ -86,7 +97,8 @@ class SceneDemo : public Scene { virtual void render(); /// Render the scene in a single pass - virtual void renderSinglePass(openglframework::Shader& shader)=0; + virtual void renderSinglePass(openglframework::Shader& shader, + const openglframework::Matrix4& worldToCameraMatrix)=0; }; #endif diff --git a/testbed/src/TestbedApplication.cpp b/testbed/src/TestbedApplication.cpp index d32b927f..d81887f9 100644 --- a/testbed/src/TestbedApplication.cpp +++ b/testbed/src/TestbedApplication.cpp @@ -250,11 +250,11 @@ void TestbedApplication::render() { mWindowToFramebufferRatio.x = float(bufferWidth) / float(windowWidth); mWindowToFramebufferRatio.y = float(bufferHeight) / float(windowHeight); - // Resize the OpenGL viewport - glViewport(mWindowToFramebufferRatio.x * LEFT_PANE_WIDTH, - 0, - bufferWidth - mWindowToFramebufferRatio.x * LEFT_PANE_WIDTH, - bufferHeight - mWindowToFramebufferRatio.y * HEADER_HEIGHT); + // Set the viewport of the scene + mCurrentScene->setViewport(mWindowToFramebufferRatio.x * LEFT_PANE_WIDTH, + 0, + bufferWidth - mWindowToFramebufferRatio.x * LEFT_PANE_WIDTH, + bufferHeight - mWindowToFramebufferRatio.y * HEADER_HEIGHT); // Render the scene mCurrentScene->render(); From b5f1557bd60c3c0853f4d5180ecf3535db90dec9 Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Sat, 25 Jul 2015 23:28:27 +0000 Subject: [PATCH 21/36] Continue working on shadow mapping for the testbed application --- testbed/common/Box.cpp | 5 +++-- testbed/shaders/depth.vert | 5 +++-- testbed/shaders/phong.frag | 15 ++++++++++++++- testbed/shaders/phong.vert | 11 +++++++++-- testbed/src/SceneDemo.cpp | 36 +++++++++++++++++++++--------------- testbed/src/SceneDemo.h | 3 --- 6 files changed, 50 insertions(+), 25 deletions(-) diff --git a/testbed/common/Box.cpp b/testbed/common/Box.cpp index e3fc397a..3a1659aa 100644 --- a/testbed/common/Box.cpp +++ b/testbed/common/Box.cpp @@ -182,11 +182,12 @@ void Box::render(openglframework::Shader& shader, mVBOVertices.bind(); // Set the model to camera matrix - const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix; - shader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix); + shader.setMatrix4x4Uniform("localToWorldMatrix", mTransformMatrix); + shader.setMatrix4x4Uniform("worldToCameraMatrix", worldToCameraMatrix); // Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the // model-view matrix) + const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix; const openglframework::Matrix3 normalMatrix = localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose(); shader.setMatrix3x3Uniform("normalMatrix", normalMatrix, false); diff --git a/testbed/shaders/depth.vert b/testbed/shaders/depth.vert index ec0c0705..c4af178a 100644 --- a/testbed/shaders/depth.vert +++ b/testbed/shaders/depth.vert @@ -26,7 +26,8 @@ ********************************************************************************/ // Uniform variables -uniform mat4 localToCameraMatrix; // Local-space to camera-space matrix +uniform mat4 localToWorldMatrix; // Local-space to world-space matrix +uniform mat4 worldToCameraMatrix; // World-space to camera-space matrix uniform mat4 projectionMatrix; // Projection matrix // In variables @@ -35,5 +36,5 @@ in vec4 vertexPosition; void main() { // Compute the clip-space vertex coordinates - gl_Position = projectionMatrix * localToCameraMatrix * vertexPosition; + gl_Position = projectionMatrix * worldToCameraMatrix * localToWorldMatrix * vertexPosition; } diff --git a/testbed/shaders/phong.frag b/testbed/shaders/phong.frag index 2f5777f1..677b289a 100644 --- a/testbed/shaders/phong.frag +++ b/testbed/shaders/phong.frag @@ -32,6 +32,7 @@ uniform vec3 light0DiffuseColor; // Light 0 diffuse color uniform vec3 light0SpecularColor; // Light 0 specular color uniform float shininess; // Shininess uniform sampler2D textureSampler; // Texture +uniform sampler2D shadowMapSampler; // Shadow map texture sampler uniform bool isTexture; // True if we need to use the texture uniform vec4 vertexColor; // Vertex color @@ -39,6 +40,7 @@ uniform vec4 vertexColor; // Vertex color in vec3 vertexPosCameraSpace; // Camera-space position of the vertex in vec3 vertexNormalCameraSpace; // Vertex normal in camera-space in vec2 texCoords; // Texture coordinates +in vec4 shadowMapCoords; // Shadow map texture coords // Out variable out vec4 color; // Output color @@ -67,6 +69,17 @@ void main() { if (diffuseFactor < 0.0) specularFactor = 0.0; vec3 specular = light0SpecularColor * specularFactor; + // Compute shadow factor + vec4 shadowMapCoordsOverW = shadowMapCoords / shadowMapCoords.w ; + shadowMapCoordsOverW += 0.0005; + vec2 shadowMapCoordsWithBias = (shadowMapCoordsOverW.xy + vec2(1, 1)) * 0.5; + float distanceInShadowMap = texture(shadowMapSampler, shadowMapCoordsWithBias).r; + float shadow = 0.0; + if (shadowMapCoords.w > 0) { + shadow = distanceInShadowMap < shadowMapCoordsOverW.z ? 0.0 : 1.0; + } + // Compute the final color - color = vec4(ambient + diffuse + specular, 1.0); + color = vec4(ambient + shadow * vertexColor.rgb, 1.0); + //color = vec4(distanceInShadowMap, distanceInShadowMap, distanceInShadowMap, 1.0); } diff --git a/testbed/shaders/phong.vert b/testbed/shaders/phong.vert index 3e9a5398..491558fb 100644 --- a/testbed/shaders/phong.vert +++ b/testbed/shaders/phong.vert @@ -26,9 +26,12 @@ ********************************************************************************/ // Uniform variables -uniform mat4 localToCameraMatrix; // Local-space to camera-space matrix +uniform mat4 localToWorldMatrix; // Local-space to world-space matrix +uniform mat4 worldToCameraMatrix; // World-space to camera-space matrix +uniform mat4 worldToLight0CameraMatrix; // World-space to light0 camera-space matrix (for shadow mapping) uniform mat4 projectionMatrix; // Projection matrix uniform mat3 normalMatrix; // Normal matrix +uniform mat4 shadowMapProjectionMatrix; // Shadow map projection matrix // In variables in vec4 vertexPosition; @@ -39,11 +42,12 @@ in vec2 textureCoords; out vec3 vertexPosCameraSpace; // Camera-space position of the vertex out vec3 vertexNormalCameraSpace; // Vertex normal in camera-space out vec2 texCoords; // Texture coordinates +out vec4 shadowMapCoords; // Shadow map texture coords void main() { // Compute the vertex position - vec4 positionCameraSpace = localToCameraMatrix * vertexPosition; + vec4 positionCameraSpace = worldToCameraMatrix * localToWorldMatrix * vertexPosition; vertexPosCameraSpace = positionCameraSpace.xyz; // Compute the world surface normal @@ -52,6 +56,9 @@ void main() { // Get the texture coordinates texCoords = textureCoords; + // Compute the texture coords of the vertex in the shadow map + shadowMapCoords = shadowMapProjectionMatrix * worldToLight0CameraMatrix * localToWorldMatrix * vertexPosition; + // Compute the clip-space vertex coordinates gl_Position = projectionMatrix * positionCameraSpace; } diff --git a/testbed/src/SceneDemo.cpp b/testbed/src/SceneDemo.cpp index e48f1090..69ab76db 100644 --- a/testbed/src/SceneDemo.cpp +++ b/testbed/src/SceneDemo.cpp @@ -37,20 +37,15 @@ SceneDemo::SceneDemo(const std::string& name, float sceneRadius) : Scene(name), mVBOQuad(GL_ARRAY_BUFFER) { // Move the light0 - mLight0.translateWorld(Vector3(20, 20, 20)); + mLight0.translateWorld(Vector3(0, 60, 00)); // Camera at light0 postion for the shadow map mShadowMapLightCamera.translateWorld(mLight0.getOrigin()); + mShadowMapLightCamera.rotateLocal(Vector3(1, 0, 0), -PI / 2.0f); mShadowMapLightCamera.setDimensions(SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT); - mShadowMapLightCamera.setFieldOfView(45.0f); - mShadowMapLightCamera.setSceneRadius(sceneRadius); - mShadowMapLightCamera.setZoom(1.0); - - // Bias matrix for the shadow map - mShadowMapBiasMatrix.setAllValues(0.5f, 0.0f, 0.0f, 0.5f, - 0.0f, 0.5f, 0.5f, 0.5f, - 0.0f, 0.0f, 0.0f, 0.5f, - 0.0f, 0.0f, 0.0f, 1.0f); + mShadowMapLightCamera.setFieldOfView(70.0f); + mShadowMapLightCamera.setSceneRadius(200); + //mShadowMapLightCamera.setZoom(1.0); // Create the Shadow map FBO and texture createShadowMapFBOAndTexture(); @@ -73,6 +68,11 @@ void SceneDemo::render() { // ---------- Render the scene to generate the shadow map (first pass) ----------- // + // Culling switching, rendering only backface, this is done to avoid self-shadowing + glCullFace(GL_FRONT); + + Matrix4 shadowMapProjMatrix = mShadowMapLightCamera.getProjectionMatrix(); + // Get the world-space to camera-space matrix const openglframework::Matrix4 worldToLightCameraMatrix = mShadowMapLightCamera.getTransformMatrix().getInverse(); @@ -82,7 +82,7 @@ void SceneDemo::render() { mDepthShader.bind(); // Set the variables of the shader - mDepthShader.setMatrix4x4Uniform("projectionMatrix", mShadowMapBiasMatrix * mShadowMapLightCamera.getProjectionMatrix()); + mDepthShader.setMatrix4x4Uniform("projectionMatrix", shadowMapProjMatrix); // Set the viewport to render into the shadow map texture glViewport(0, 0, SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT); @@ -104,21 +104,27 @@ void SceneDemo::render() { // ---------- Render the scene for final rendering (second pass) ----------- // + glCullFace(GL_BACK); + // Get the world-space to camera-space matrix const openglframework::Matrix4 worldToCameraMatrix = mCamera.getTransformMatrix().getInverse(); - mPhongShader.bind(); + mShadowMapTexture.bind(); + // Set the variables of the shader mPhongShader.setMatrix4x4Uniform("projectionMatrix", mCamera.getProjectionMatrix()); - mPhongShader.setVector3Uniform("light0PosCameraSpace",worldToCameraMatrix * mLight0.getOrigin()); + mPhongShader.setMatrix4x4Uniform("shadowMapProjectionMatrix", shadowMapProjMatrix); + mPhongShader.setMatrix4x4Uniform("worldToLight0CameraMatrix", worldToLightCameraMatrix); + mPhongShader.setVector3Uniform("light0PosCameraSpace", worldToCameraMatrix * mLight0.getOrigin()); mPhongShader.setVector3Uniform("lightAmbientColor", Vector3(0.3f, 0.3f, 0.3f)); const Color& diffCol = mLight0.getDiffuseColor(); const Color& specCol = mLight0.getSpecularColor(); mPhongShader.setVector3Uniform("light0DiffuseColor", Vector3(diffCol.r, diffCol.g, diffCol.b)); mPhongShader.setVector3Uniform("light0SpecularColor", Vector3(specCol.r, specCol.g, specCol.b)); mPhongShader.setFloatUniform("shininess", 60.0f); + mPhongShader.setIntUniform("shadowMapSampler", mShadowMapTexture.getID()); // Set the viewport to render the scene glViewport(mViewportX, mViewportY, mViewportWidth, mViewportHeight); @@ -132,10 +138,10 @@ void SceneDemo::render() { // Render the objects of the scene renderSinglePass(mPhongShader, worldToCameraMatrix); + mShadowMapTexture.unbind(); mPhongShader.unbind(); - - // drawTextureQuad(); + //drawTextureQuad(); } // Create the Shadow map FBO and texture diff --git a/testbed/src/SceneDemo.h b/testbed/src/SceneDemo.h index 87b5f989..28d571a9 100644 --- a/testbed/src/SceneDemo.h +++ b/testbed/src/SceneDemo.h @@ -54,9 +54,6 @@ class SceneDemo : public Scene { /// Camera at light0 position for the shadow map openglframework::Camera mShadowMapLightCamera; - /// Bias matrix for the shadow map - openglframework::Matrix4 mShadowMapBiasMatrix; - /// Depth shader to render the shadow map openglframework::Shader mDepthShader; From 6884adf0c2f8eeee2f05cd768d79733b932aa17c Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Sun, 26 Jul 2015 22:30:45 +0000 Subject: [PATCH 22/36] Fix issue with shadow mapping --- testbed/opengl-framework/src/maths/Matrix4.h | 58 +++++++++++++++++++- testbed/shaders/phong.frag | 6 +- testbed/src/SceneDemo.cpp | 10 +++- testbed/src/SceneDemo.h | 3 + 4 files changed, 70 insertions(+), 7 deletions(-) diff --git a/testbed/opengl-framework/src/maths/Matrix4.h b/testbed/opengl-framework/src/maths/Matrix4.h index bcfbcebd..f481ecc9 100644 --- a/testbed/opengl-framework/src/maths/Matrix4.h +++ b/testbed/opengl-framework/src/maths/Matrix4.h @@ -27,7 +27,7 @@ #define MATRIX4_H // Libraries -#include +#include #include #include #include "Vector3.h" @@ -376,6 +376,15 @@ class Matrix4 { // Return a 4x4 rotation matrix static Matrix4 rotationMatrix(const Vector3& axis, float angle); + + // Return a 4x4 perspective projection matrix + static Matrix4 perspectiveProjectionMatrix(float near, float far, + int width, int height, + float fieldOfView); + + // Return a 4x4 orthographic projection matrix + static Matrix4 orthoProjectionMatrix(float near, float far, int width, + int height); }; // * operator @@ -422,6 +431,53 @@ inline Matrix4 Matrix4::rotationMatrix(const Vector3& axis, float angle) { return rotationMatrix; } +// Return a 4x4 perspective projection matrix +inline Matrix4 Matrix4::perspectiveProjectionMatrix(float near, float far, int width, int height, + float fieldOfView) { + + // Compute the aspect ratio + float aspect = float(width) / float(height); + + float top = near * tan((fieldOfView / 2.0f) * (float(M_PI) / 180.0f)); + float bottom = -top; + float left = bottom * aspect; + float right = top * aspect; + + float fx = 2.0f * near / (right - left); + float fy = 2.0f * near / (top - bottom); + float fz = -(far + near) / (far - near); + float fw = -2.0f * far * near / (far - near); + + // Compute the projection matrix + return Matrix4(fx, 0, 0, 0, + 0, fy, 0, 0, + 0, 0, fz, fw, + 0, 0, -1, 0); +} + +// Return a 4x4 orthographic projection matrix +inline Matrix4 Matrix4::orthoProjectionMatrix(float near, float far, int width, int height) { + + // Compute the aspect ratio + float aspect = float(width) / float(height); + + float top = height * 0.5f; + float bottom = -top; + float left = bottom * aspect; + float right = top * aspect; + + float fx = 2.0f / (right - left); + float fy = 2.0f / (top - bottom); + float fz = -2.0f / (far - near); + float fw = -(far + near) / (far - near); + + // Compute the projection matrix + return Matrix4(fx, 0, 0, 0, + 0, fy, 0, 0, + 0, 0, fz, fw, + 0, 0, 0, 1); +} + } #endif //_MATRIX4_H diff --git a/testbed/shaders/phong.frag b/testbed/shaders/phong.frag index 677b289a..498f7238 100644 --- a/testbed/shaders/phong.frag +++ b/testbed/shaders/phong.frag @@ -71,9 +71,8 @@ void main() { // Compute shadow factor vec4 shadowMapCoordsOverW = shadowMapCoords / shadowMapCoords.w ; - shadowMapCoordsOverW += 0.0005; - vec2 shadowMapCoordsWithBias = (shadowMapCoordsOverW.xy + vec2(1, 1)) * 0.5; - float distanceInShadowMap = texture(shadowMapSampler, shadowMapCoordsWithBias).r; + //shadowMapCoordsOverW += 0.0005; + float distanceInShadowMap = texture(shadowMapSampler, shadowMapCoordsOverW.xy).r; float shadow = 0.0; if (shadowMapCoords.w > 0) { shadow = distanceInShadowMap < shadowMapCoordsOverW.z ? 0.0 : 1.0; @@ -81,5 +80,4 @@ void main() { // Compute the final color color = vec4(ambient + shadow * vertexColor.rgb, 1.0); - //color = vec4(distanceInShadowMap, distanceInShadowMap, distanceInShadowMap, 1.0); } diff --git a/testbed/src/SceneDemo.cpp b/testbed/src/SceneDemo.cpp index 69ab76db..efee5fcc 100644 --- a/testbed/src/SceneDemo.cpp +++ b/testbed/src/SceneDemo.cpp @@ -47,6 +47,12 @@ SceneDemo::SceneDemo(const std::string& name, float sceneRadius) : Scene(name), mShadowMapLightCamera.setSceneRadius(200); //mShadowMapLightCamera.setZoom(1.0); + + mShadowMapBiasMatrix.setAllValues(0.5, 0.0, 0.0, 0.5, + 0.0, 0.5, 0.0, 0.5, + 0.0, 0.0, 0.5, 0.5, + 0.0, 0.0, 0.0, 1.0); + // Create the Shadow map FBO and texture createShadowMapFBOAndTexture(); @@ -115,7 +121,7 @@ void SceneDemo::render() { // Set the variables of the shader mPhongShader.setMatrix4x4Uniform("projectionMatrix", mCamera.getProjectionMatrix()); - mPhongShader.setMatrix4x4Uniform("shadowMapProjectionMatrix", shadowMapProjMatrix); + mPhongShader.setMatrix4x4Uniform("shadowMapProjectionMatrix", mShadowMapBiasMatrix * shadowMapProjMatrix); mPhongShader.setMatrix4x4Uniform("worldToLight0CameraMatrix", worldToLightCameraMatrix); mPhongShader.setVector3Uniform("light0PosCameraSpace", worldToCameraMatrix * mLight0.getOrigin()); mPhongShader.setVector3Uniform("lightAmbientColor", Vector3(0.3f, 0.3f, 0.3f)); @@ -148,7 +154,7 @@ void SceneDemo::render() { void SceneDemo::createShadowMapFBOAndTexture() { // Create the texture for the depth values - mShadowMapTexture.create(SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, + mShadowMapTexture.create(SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, GL_NEAREST, GL_NEAREST, GL_CLAMP, GL_CLAMP, NULL); mShadowMapTexture.setLayer(1); diff --git a/testbed/src/SceneDemo.h b/testbed/src/SceneDemo.h index 28d571a9..92e64c10 100644 --- a/testbed/src/SceneDemo.h +++ b/testbed/src/SceneDemo.h @@ -51,6 +51,9 @@ class SceneDemo : public Scene { /// Shadow map texture openglframework::Texture2D mShadowMapTexture; + /// Shadow map bias matrix + openglframework::Matrix4 mShadowMapBiasMatrix; + /// Camera at light0 position for the shadow map openglframework::Camera mShadowMapLightCamera; From a35340a930d7879f60588b29aa86a5699f955938 Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Wed, 29 Jul 2015 18:15:20 +0200 Subject: [PATCH 23/36] Modify scenes to use the SceneDome class --- testbed/common/Capsule.cpp | 53 +++++++------ testbed/common/Capsule.h | 7 +- testbed/common/Cone.cpp | 53 +++++++------ testbed/common/Cone.h | 7 +- testbed/common/ConvexMesh.cpp | 54 ++++++------- testbed/common/ConvexMesh.h | 7 +- testbed/common/Cylinder.cpp | 54 ++++++------- testbed/common/Cylinder.h | 8 +- testbed/common/Dumbbell.cpp | 55 +++++++------ testbed/common/Dumbbell.h | 6 +- testbed/common/Line.cpp | 5 +- testbed/common/Sphere.cpp | 53 +++++++------ testbed/common/Sphere.h | 8 +- testbed/common/VisualContactPoint.cpp | 46 +++++------ testbed/common/VisualContactPoint.h | 3 +- .../src/FrameBufferObject.cpp | 2 +- testbed/opengl-framework/src/Shader.cpp | 2 +- testbed/opengl-framework/src/Shader.h | 6 +- testbed/opengl-framework/src/Texture2D.cpp | 2 +- .../src/VertexArrayObject.cpp | 4 +- .../src/VertexBufferObject.cpp | 4 +- testbed/opengl-framework/src/maths/Matrix3.h | 7 ++ testbed/opengl-framework/src/maths/Matrix4.h | 11 +++ .../collisionshapes/CollisionShapesScene.cpp | 63 +++++---------- .../collisionshapes/CollisionShapesScene.h | 13 ++- testbed/scenes/joints/JointsScene.cpp | 43 +++------- testbed/scenes/joints/JointsScene.h | 10 ++- testbed/scenes/raycast/RaycastScene.cpp | 79 ++++++++----------- testbed/scenes/raycast/RaycastScene.h | 12 +-- testbed/shaders/phong.frag | 8 +- testbed/src/SceneDemo.cpp | 8 +- testbed/src/SceneDemo.h | 4 +- 32 files changed, 332 insertions(+), 365 deletions(-) diff --git a/testbed/common/Capsule.cpp b/testbed/common/Capsule.cpp index 7a38838b..a97f0ea4 100644 --- a/testbed/common/Capsule.cpp +++ b/testbed/common/Capsule.cpp @@ -36,7 +36,7 @@ int Capsule::totalNbCapsules = 0; // Constructor Capsule::Capsule(float radius, float height, const openglframework::Vector3& position, reactphysics3d::CollisionWorld* world, - const std::string& meshFolderPath, openglframework::Shader& shader) + const std::string& meshFolderPath) : openglframework::Mesh(), mRadius(radius), mHeight(height) { // Load the mesh from a file @@ -76,7 +76,7 @@ Capsule::Capsule(float radius, float height, const openglframework::Vector3& pos // Create the VBOs and VAO if (totalNbCapsules == 0) { - createVBOAndVAO(shader); + createVBOAndVAO(); } totalNbCapsules++; @@ -85,7 +85,7 @@ Capsule::Capsule(float radius, float height, const openglframework::Vector3& pos // Constructor Capsule::Capsule(float radius, float height, const openglframework::Vector3& position, float mass, reactphysics3d::DynamicsWorld* dynamicsWorld, - const std::string& meshFolderPath, openglframework::Shader &shader) + const std::string& meshFolderPath) : openglframework::Mesh(), mRadius(radius), mHeight(height), mColor(0.5f, 0.5f, 0.5f, 1.0f) { @@ -126,7 +126,7 @@ Capsule::Capsule(float radius, float height, const openglframework::Vector3& pos // Create the VBOs and VAO if (totalNbCapsules == 0) { - createVBOAndVAO(shader); + createVBOAndVAO(); } totalNbCapsules++; @@ -159,27 +159,45 @@ void Capsule::render(openglframework::Shader& shader, shader.bind(); // Set the model to camera matrix - const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix; - shader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix); + shader.setMatrix4x4Uniform("localToWorldMatrix", mTransformMatrix); + shader.setMatrix4x4Uniform("worldToCameraMatrix", worldToCameraMatrix); // Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the // model-view matrix) + const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix; const openglframework::Matrix3 normalMatrix = localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose(); - shader.setMatrix3x3Uniform("normalMatrix", normalMatrix); + shader.setMatrix3x3Uniform("normalMatrix", normalMatrix, false); // Set the vertex color openglframework::Vector4 color(mColor.r, mColor.g, mColor.b, mColor.a); - shader.setVector4Uniform("vertexColor", color); + shader.setVector4Uniform("vertexColor", color, false); // Bind the VAO mVAO.bind(); + mVBOVertices.bind(); + + // Get the location of shader attribute variables + GLint vertexPositionLoc = shader.getAttribLocation("vertexPosition"); + GLint vertexNormalLoc = shader.getAttribLocation("vertexNormal", false); + + glEnableVertexAttribArray(vertexPositionLoc); + if (vertexNormalLoc != -1) glEnableVertexAttribArray(vertexNormalLoc); + + glVertexAttribPointer(vertexPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL); + if (vertexNormalLoc != -1) glVertexAttribPointer(vertexNormalLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL); + // For each part of the mesh for (unsigned int i=0; iaddCollisionShape(collisionShape, rp3d::Transform::identity()); // Create the VBOs and VAO - createVBOAndVAO(shader); + createVBOAndVAO(); } // Constructor ConvexMesh::ConvexMesh(const openglframework::Vector3 &position, float mass, reactphysics3d::DynamicsWorld* dynamicsWorld, - const std::string& meshFolderPath, openglframework::Shader &shader) + const std::string& meshFolderPath) : openglframework::Mesh(), mVBOVertices(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER), mVBOIndices(GL_ELEMENT_ARRAY_BUFFER), mColor(0.5f, 0.5f, 0.5f, 1.0f) { @@ -157,7 +156,7 @@ ConvexMesh::ConvexMesh(const openglframework::Vector3 &position, float mass, mRigidBody = body; // Create the VBOs and VAO - createVBOAndVAO(shader); + createVBOAndVAO(); } // Destructor @@ -182,27 +181,45 @@ void ConvexMesh::render(openglframework::Shader& shader, shader.bind(); // Set the model to camera matrix - const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix; - shader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix); + shader.setMatrix4x4Uniform("localToWorldMatrix", mTransformMatrix); + shader.setMatrix4x4Uniform("worldToCameraMatrix", worldToCameraMatrix); // Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the // model-view matrix) + const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix; const openglframework::Matrix3 normalMatrix = localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose(); - shader.setMatrix3x3Uniform("normalMatrix", normalMatrix); + shader.setMatrix3x3Uniform("normalMatrix", normalMatrix, false); // Set the vertex color openglframework::Vector4 color(mColor.r, mColor.g, mColor.b, mColor.a); - shader.setVector4Uniform("vertexColor", color); + shader.setVector4Uniform("vertexColor", color, false); // Bind the VAO mVAO.bind(); + mVBOVertices.bind(); + + // Get the location of shader attribute variables + GLint vertexPositionLoc = shader.getAttribLocation("vertexPosition"); + GLint vertexNormalLoc = shader.getAttribLocation("vertexNormal", false); + + glEnableVertexAttribArray(vertexPositionLoc); + if (vertexNormalLoc != -1) glEnableVertexAttribArray(vertexNormalLoc); + + glVertexAttribPointer(vertexPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL); + if (vertexNormalLoc != -1) glVertexAttribPointer(vertexNormalLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL); + // For each part of the mesh for (unsigned int i=0; igetRigidBody()->getMaterial(); @@ -111,7 +106,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name) // Create a sphere and a corresponding rigid in the dynamics world Sphere* sphere = new Sphere(SPHERE_RADIUS, position , BOX_MASS, mDynamicsWorld, - meshFolderPath, mPhongShader); + meshFolderPath); // Change the material properties of the rigid body rp3d::Material& material = sphere->getRigidBody()->getMaterial(); @@ -132,7 +127,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name) // Create a cone and a corresponding rigid in the dynamics world Cone* cone = new Cone(CONE_RADIUS, CONE_HEIGHT, position, CONE_MASS, mDynamicsWorld, - meshFolderPath, mPhongShader); + meshFolderPath); // Change the material properties of the rigid body rp3d::Material& material = cone->getRigidBody()->getMaterial(); @@ -153,7 +148,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name) // Create a cylinder and a corresponding rigid in the dynamics world Cylinder* cylinder = new Cylinder(CYLINDER_RADIUS, CYLINDER_HEIGHT, position , - CYLINDER_MASS, mDynamicsWorld, meshFolderPath, mPhongShader); + CYLINDER_MASS, mDynamicsWorld, meshFolderPath); // Change the material properties of the rigid body rp3d::Material& material = cylinder->getRigidBody()->getMaterial(); @@ -174,8 +169,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name) // Create a cylinder and a corresponding rigid in the dynamics world Capsule* capsule = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, position , - CAPSULE_MASS, mDynamicsWorld, meshFolderPath, - mPhongShader); + CAPSULE_MASS, mDynamicsWorld, meshFolderPath); // Change the material properties of the rigid body rp3d::Material& material = capsule->getRigidBody()->getMaterial(); @@ -195,8 +189,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name) radius * sin(angle)); // Create a convex mesh and a corresponding rigid in the dynamics world - ConvexMesh* mesh = new ConvexMesh(position, MESH_MASS, mDynamicsWorld, meshFolderPath, - mPhongShader); + ConvexMesh* mesh = new ConvexMesh(position, MESH_MASS, mDynamicsWorld, meshFolderPath); // Change the material properties of the rigid body rp3d::Material& material = mesh->getRigidBody()->getMaterial(); @@ -394,70 +387,54 @@ void CollisionShapesScene::update() { } // Render the scene -void CollisionShapesScene::render() { - - glEnable(GL_DEPTH_TEST); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glEnable(GL_CULL_FACE); - - // Get the world-space to camera-space matrix - const openglframework::Matrix4 worldToCameraMatrix = mCamera.getTransformMatrix().getInverse(); +void CollisionShapesScene::renderSinglePass(openglframework::Shader& shader, + const openglframework::Matrix4& worldToCameraMatrix) { // Bind the shader - mPhongShader.bind(); - - // Set the variables of the shader - mPhongShader.setMatrix4x4Uniform("projectionMatrix", mCamera.getProjectionMatrix()); - mPhongShader.setVector3Uniform("light0PosCameraSpace", worldToCameraMatrix * mLight0.getOrigin()); - mPhongShader.setVector3Uniform("lightAmbientColor", Vector3(0.3f, 0.3f, 0.3f)); - const Color& diffColLight0 = mLight0.getDiffuseColor(); - const Color& specColLight0 = mLight0.getSpecularColor(); - mPhongShader.setVector3Uniform("light0DiffuseColor", Vector3(diffColLight0.r, diffColLight0.g, diffColLight0.b)); - mPhongShader.setVector3Uniform("light0SpecularColor", Vector3(specColLight0.r, specColLight0.g, specColLight0.b)); - mPhongShader.setFloatUniform("shininess", 200.0f); + shader.bind(); // Render all the boxes of the scene for (std::vector::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { - (*it)->render(mPhongShader, worldToCameraMatrix); + (*it)->render(shader, worldToCameraMatrix); } // Render all the sphere of the scene for (std::vector::iterator it = mSpheres.begin(); it != mSpheres.end(); ++it) { - (*it)->render(mPhongShader, worldToCameraMatrix); + (*it)->render(shader, worldToCameraMatrix); } // Render all the cones of the scene for (std::vector::iterator it = mCones.begin(); it != mCones.end(); ++it) { - (*it)->render(mPhongShader, worldToCameraMatrix); + (*it)->render(shader, worldToCameraMatrix); } // Render all the cylinders of the scene for (std::vector::iterator it = mCylinders.begin(); it != mCylinders.end(); ++it) { - (*it)->render(mPhongShader, worldToCameraMatrix); + (*it)->render(shader, worldToCameraMatrix); } // Render all the capsules of the scene for (std::vector::iterator it = mCapsules.begin(); it != mCapsules.end(); ++it) { - (*it)->render(mPhongShader, worldToCameraMatrix); + (*it)->render(shader, worldToCameraMatrix); } // Render all the convex meshes of the scene for (std::vector::iterator it = mConvexMeshes.begin(); it != mConvexMeshes.end(); ++it) { - (*it)->render(mPhongShader, worldToCameraMatrix); + (*it)->render(shader, worldToCameraMatrix); } // Render all the dumbbells of the scene for (std::vector::iterator it = mDumbbells.begin(); it != mDumbbells.end(); ++it) { - (*it)->render(mPhongShader, worldToCameraMatrix); + (*it)->render(shader, worldToCameraMatrix); } // Render the floor - mFloor->render(mPhongShader, worldToCameraMatrix); + mFloor->render(shader, worldToCameraMatrix); // Unbind the shader - mPhongShader.unbind(); + shader.unbind(); } /// Reset the scene diff --git a/testbed/scenes/collisionshapes/CollisionShapesScene.h b/testbed/scenes/collisionshapes/CollisionShapesScene.h index a12d3fa3..92fd166b 100644 --- a/testbed/scenes/collisionshapes/CollisionShapesScene.h +++ b/testbed/scenes/collisionshapes/CollisionShapesScene.h @@ -29,7 +29,7 @@ // Libraries #include "openglframework.h" #include "reactphysics3d.h" -#include "Scene.h" +#include "SceneDemo.h" #include "Sphere.h" #include "Box.h" #include "Cone.h" @@ -44,6 +44,7 @@ namespace collisionshapesscene { // Constants +const float SCENE_RADIUS = 30.0f; const int NB_BOXES = 3; const int NB_CUBES = 3; const int NB_CONES = 3; @@ -69,15 +70,12 @@ const float MESH_MASS = 1.0f; const float FLOOR_MASS = 100.0f; // Floor mass in kilograms // Class CollisionShapesScene -class CollisionShapesScene : public Scene{ +class CollisionShapesScene : public SceneDemo { private : // -------------------- Attributes -------------------- // - /// Light 0 - openglframework::Light mLight0; - /// Phong shader openglframework::Shader mPhongShader; @@ -121,8 +119,9 @@ class CollisionShapesScene : public Scene{ /// Take a step for the simulation virtual void update(); - /// Render the scene - virtual void render(); + /// Render the scene in a single pass + virtual void renderSinglePass(openglframework::Shader& shader, + const openglframework::Matrix4& worldToCameraMatrix); /// Reset the scene virtual void reset(); diff --git a/testbed/scenes/joints/JointsScene.cpp b/testbed/scenes/joints/JointsScene.cpp index 655c629e..5a60023d 100644 --- a/testbed/scenes/joints/JointsScene.cpp +++ b/testbed/scenes/joints/JointsScene.cpp @@ -33,18 +33,17 @@ using namespace jointsscene; // Constructor JointsScene::JointsScene(const std::string& name) - : Scene(name), mLight0(0), mPhongShader("shaders/phong.vert", + : SceneDemo(name, SCENE_RADIUS), mLight0(0), mPhongShader("shaders/phong.vert", "shaders/phong.frag") { // Move the light 0 mLight0.translateWorld(Vector3(7, 15, 15)); // Compute the radius and the center of the scene - float radiusScene = 30.0f; openglframework::Vector3 center(0, 5, 0); // Set the center of the scene - setScenePosition(center, radiusScene); + setScenePosition(center, SCENE_RADIUS); // Gravity vector in the dynamics world rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0); @@ -168,43 +167,27 @@ void JointsScene::update() { } // Render the scene -void JointsScene::render() { - - glEnable(GL_DEPTH_TEST); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glEnable(GL_CULL_FACE); - - // Get the world-space to camera-space matrix - const openglframework::Matrix4 worldToCameraMatrix = mCamera.getTransformMatrix().getInverse(); +void JointsScene::renderSinglePass(openglframework::Shader& shader, + const openglframework::Matrix4& worldToCameraMatrix) { // Bind the shader - mPhongShader.bind(); - - // Set the variables of the shader - mPhongShader.setVector3Uniform("light0PosCameraSpace",worldToCameraMatrix * mLight0.getOrigin()); - mPhongShader.setMatrix4x4Uniform("projectionMatrix", mCamera.getProjectionMatrix()); - mPhongShader.setVector3Uniform("lightAmbientColor", Vector3(0.3f, 0.3f, 0.3f)); - const Color& diffCol = mLight0.getDiffuseColor(); - const Color& specCol = mLight0.getSpecularColor(); - mPhongShader.setVector3Uniform("light0DiffuseColor", Vector3(diffCol.r, diffCol.g, diffCol.b)); - mPhongShader.setVector3Uniform("light0SpecularColor", Vector3(specCol.r, specCol.g, specCol.b)); - mPhongShader.setFloatUniform("shininess", 60.0f); + shader.bind(); // Render all the boxes - mSliderJointBottomBox->render(mPhongShader, worldToCameraMatrix); - mSliderJointTopBox->render(mPhongShader, worldToCameraMatrix); - mPropellerBox->render(mPhongShader, worldToCameraMatrix); - mFixedJointBox1->render(mPhongShader, worldToCameraMatrix); - mFixedJointBox2->render(mPhongShader, worldToCameraMatrix); + mSliderJointBottomBox->render(shader, worldToCameraMatrix); + mSliderJointTopBox->render(shader, worldToCameraMatrix); + mPropellerBox->render(shader, worldToCameraMatrix); + mFixedJointBox1->render(shader, worldToCameraMatrix); + mFixedJointBox2->render(shader, worldToCameraMatrix); for (int i=0; irender(mPhongShader, worldToCameraMatrix); + mBallAndSocketJointChainBoxes[i]->render(shader, worldToCameraMatrix); } // Render the floor - mFloor->render(mPhongShader, worldToCameraMatrix); + mFloor->render(shader, worldToCameraMatrix); // Unbind the shader - mPhongShader.unbind(); + shader.unbind(); } // Reset the scene diff --git a/testbed/scenes/joints/JointsScene.h b/testbed/scenes/joints/JointsScene.h index a55682e9..2795a7fd 100644 --- a/testbed/scenes/joints/JointsScene.h +++ b/testbed/scenes/joints/JointsScene.h @@ -30,11 +30,12 @@ #include "openglframework.h" #include "reactphysics3d.h" #include "Box.h" -#include "Scene.h" +#include "SceneDemo.h" namespace jointsscene { // Constants +const float SCENE_RADIUS = 30.0f; const openglframework::Vector3 BOX_SIZE(2, 2, 2); // Box dimensions in meters const openglframework::Vector3 FLOOR_SIZE(20, 0.5f, 20); // Floor dimensions in meters const float BOX_MASS = 1.0f; // Box mass in kilograms @@ -43,7 +44,7 @@ const int NB_BALLSOCKETJOINT_BOXES = 7; // Number of Ball-An const int NB_HINGE_BOXES = 7; // Number of Hinge chain boxes // Class JointsScene -class JointsScene : public Scene { +class JointsScene : public SceneDemo { protected : @@ -134,8 +135,9 @@ class JointsScene : public Scene { /// Take a step for the simulation virtual void update(); - /// Render the scene - virtual void render(); + /// Render the scene in a single pass + virtual void renderSinglePass(openglframework::Shader& shader, + const openglframework::Matrix4& worldToCameraMatrix); /// Reset the scene virtual void reset(); diff --git a/testbed/scenes/raycast/RaycastScene.cpp b/testbed/scenes/raycast/RaycastScene.cpp index 3d74979e..d26c2e8a 100644 --- a/testbed/scenes/raycast/RaycastScene.cpp +++ b/testbed/scenes/raycast/RaycastScene.cpp @@ -32,7 +32,7 @@ using namespace raycastscene; // Constructor RaycastScene::RaycastScene(const std::string& name) - : Scene(name), mLight0(0), mCurrentBodyIndex(-1), mAreNormalsDisplayed(false), + : SceneDemo(name, SCENE_RADIUS), mLight0(0), mCurrentBodyIndex(-1), mAreNormalsDisplayed(false), mPhongShader("shaders/phong.vert", "shaders/phong.frag"), mMeshFolderPath("meshes/"), mRaycastManager(mPhongShader, mMeshFolderPath), mVBOVertices(GL_ARRAY_BUFFER) { @@ -41,11 +41,10 @@ RaycastScene::RaycastScene(const std::string& name) mLight0.translateWorld(Vector3(50, 50, 50)); // Compute the radius and the center of the scene - float radiusScene = 30.0f; openglframework::Vector3 center(0, 0, 0); // Set the center of the scene - setScenePosition(center, radiusScene); + setScenePosition(center, SCENE_RADIUS); // Create the dynamics world for the physics simulation mCollisionWorld = new rp3d::CollisionWorld(); @@ -54,7 +53,7 @@ RaycastScene::RaycastScene(const std::string& name) openglframework::Vector3 position1(0, 0, 0); // Create a convex mesh and a corresponding collision body in the dynamics world - mDumbbell = new Dumbbell(position1, mCollisionWorld, mMeshFolderPath, mPhongShader); + mDumbbell = new Dumbbell(position1, mCollisionWorld, mMeshFolderPath); // ---------- Box ---------- // openglframework::Vector3 position2(0, 0, 0); @@ -68,34 +67,34 @@ RaycastScene::RaycastScene(const std::string& name) // Create a sphere and a corresponding collision body in the dynamics world mSphere = new Sphere(SPHERE_RADIUS, position3, mCollisionWorld, - mMeshFolderPath, mPhongShader); + mMeshFolderPath); // ---------- Cone ---------- // openglframework::Vector3 position4(0, 0, 0); // Create a cone and a corresponding collision body in the dynamics world mCone = new Cone(CONE_RADIUS, CONE_HEIGHT, position4, mCollisionWorld, - mMeshFolderPath, mPhongShader); + mMeshFolderPath); // ---------- Cylinder ---------- // openglframework::Vector3 position5(0, 0, 0); // Create a cylinder and a corresponding collision body in the dynamics world mCylinder = new Cylinder(CYLINDER_RADIUS, CYLINDER_HEIGHT, position5, - mCollisionWorld, mMeshFolderPath, mPhongShader); + mCollisionWorld, mMeshFolderPath); // ---------- Capsule ---------- // openglframework::Vector3 position6(0, 0, 0); // Create a cylinder and a corresponding collision body in the dynamics world mCapsule = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, position6 , - mCollisionWorld, mMeshFolderPath, mPhongShader); + mCollisionWorld, mMeshFolderPath); // ---------- Convex Mesh ---------- // openglframework::Vector3 position7(0, 0, 0); // Create a convex mesh and a corresponding collision body in the dynamics world - mConvexMesh = new ConvexMesh(position7, mCollisionWorld, mMeshFolderPath, mPhongShader); + mConvexMesh = new ConvexMesh(position7, mCollisionWorld, mMeshFolderPath); // Create the lines that will be used for raycasting createLines(); @@ -266,41 +265,26 @@ void RaycastScene::update() { } // Render the scene -void RaycastScene::render() { - - glEnable(GL_DEPTH_TEST); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glEnable(GL_CULL_FACE); +void RaycastScene::renderSinglePass(openglframework::Shader& shader, + const openglframework::Matrix4& worldToCameraMatrix) { // Bind the shader - mPhongShader.bind(); - - // Get the world-space to camera-space matrix - const openglframework::Matrix4 worldToCameraMatrix = mCamera.getTransformMatrix().getInverse(); - - // Set the variables of the shader - mPhongShader.setMatrix4x4Uniform("projectionMatrix", mCamera.getProjectionMatrix()); - mPhongShader.setVector3Uniform("light0PosCameraSpace",worldToCameraMatrix * mLight0.getOrigin()); - mPhongShader.setVector3Uniform("lightAmbientColor", Vector3(0.3f, 0.3f, 0.3f)); - const Color& diffCol = mLight0.getDiffuseColor(); - const Color& specCol = mLight0.getSpecularColor(); - mPhongShader.setVector3Uniform("light0DiffuseColor", Vector3(diffCol.r, diffCol.g, diffCol.b)); - mPhongShader.setVector3Uniform("light0SpecularColor", Vector3(specCol.r, specCol.g, specCol.b)); - mPhongShader.setFloatUniform("shininess", 60.0f); + shader.bind(); // Set the model to camera matrix - const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix; - mPhongShader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix); + const Matrix4 localToCameraMatrix = Matrix4::identity(); + shader.setMatrix4x4Uniform("localToWorldMatrix", localToCameraMatrix); + shader.setMatrix4x4Uniform("worldToCameraMatrix", worldToCameraMatrix); // Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the // model-view matrix) const openglframework::Matrix3 normalMatrix = localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose(); - mPhongShader.setMatrix3x3Uniform("normalMatrix", normalMatrix); + shader.setMatrix3x3Uniform("normalMatrix", normalMatrix, false); // Set the vertex color openglframework::Vector4 color(1, 0, 0, 1); - mPhongShader.setVector4Uniform("vertexColor", color); + shader.setVector4Uniform("vertexColor", color, false); // Bind the VAO mVAO.bind(); @@ -311,41 +295,40 @@ void RaycastScene::render() { // Unbind the VAO mVAO.unbind(); - mPhongShader.unbind(); + shader.unbind(); // Render the shapes - if (mBox->getCollisionBody()->isActive()) mBox->render(mPhongShader, worldToCameraMatrix); - if (mSphere->getCollisionBody()->isActive()) mSphere->render(mPhongShader, worldToCameraMatrix); - if (mCone->getCollisionBody()->isActive()) mCone->render(mPhongShader, worldToCameraMatrix); - if (mCylinder->getCollisionBody()->isActive()) mCylinder->render(mPhongShader, worldToCameraMatrix); - if (mCapsule->getCollisionBody()->isActive()) mCapsule->render(mPhongShader, worldToCameraMatrix); - if (mConvexMesh->getCollisionBody()->isActive()) mConvexMesh->render(mPhongShader, worldToCameraMatrix); - if (mDumbbell->getCollisionBody()->isActive()) mDumbbell->render(mPhongShader, worldToCameraMatrix); + if (mBox->getCollisionBody()->isActive()) mBox->render(shader, worldToCameraMatrix); + if (mSphere->getCollisionBody()->isActive()) mSphere->render(shader, worldToCameraMatrix); + if (mCone->getCollisionBody()->isActive()) mCone->render(shader, worldToCameraMatrix); + if (mCylinder->getCollisionBody()->isActive()) mCylinder->render(shader, worldToCameraMatrix); + if (mCapsule->getCollisionBody()->isActive()) mCapsule->render(shader, worldToCameraMatrix); + if (mConvexMesh->getCollisionBody()->isActive()) mConvexMesh->render(shader, worldToCameraMatrix); + if (mDumbbell->getCollisionBody()->isActive()) mDumbbell->render(shader, worldToCameraMatrix); //mPhongShader.unbind(); - mPhongShader.bind(); + shader.bind(); - mPhongShader.setVector3Uniform("light0SpecularColor", Vector3(0, 0, 0)); openglframework::Vector4 redColor(1, 0, 0, 1); - mPhongShader.setVector4Uniform("vertexColor", redColor); + shader.setVector4Uniform("vertexColor", redColor, false); // Render all the raycast hit points mRaycastManager.render(worldToCameraMatrix, mAreNormalsDisplayed); - mPhongShader.unbind(); - mPhongShader.bind(); + shader.unbind(); + shader.bind(); openglframework::Vector4 blueColor(0, 0.62, 0.92, 1); - mPhongShader.setVector4Uniform("vertexColor", blueColor); + shader.setVector4Uniform("vertexColor", blueColor, false); // Render the lines for (std::vector::iterator it = mLines.begin(); it != mLines.end(); ++it) { - (*it)->render(mPhongShader, worldToCameraMatrix); + (*it)->render(shader, worldToCameraMatrix); } // Unbind the shader - mPhongShader.unbind(); + shader.unbind(); } // Create the Vertex Buffer Objects used to render with OpenGL. diff --git a/testbed/scenes/raycast/RaycastScene.h b/testbed/scenes/raycast/RaycastScene.h index 79fa8c9d..a58837fc 100644 --- a/testbed/scenes/raycast/RaycastScene.h +++ b/testbed/scenes/raycast/RaycastScene.h @@ -31,7 +31,7 @@ #include #include "openglframework.h" #include "reactphysics3d.h" -#include "Scene.h" +#include "SceneDemo.h" #include "Sphere.h" #include "Box.h" #include "Cone.h" @@ -46,6 +46,7 @@ namespace raycastscene { // Constants +const float SCENE_RADIUS = 30.0f; const openglframework::Vector3 BOX_SIZE(4, 2, 1); const float SPHERE_RADIUS = 3.0f; const float CONE_RADIUS = 3.0f; @@ -87,7 +88,7 @@ class RaycastManager : public rp3d::RaycastCallback { virtual rp3d::decimal notifyRaycastHit(const rp3d::RaycastInfo& raycastInfo) { rp3d::Vector3 hitPos = raycastInfo.worldPoint; openglframework::Vector3 position(hitPos.x, hitPos.y, hitPos.z); - VisualContactPoint* point = new VisualContactPoint(position, mShader, mMeshFolderPath); + VisualContactPoint* point = new VisualContactPoint(position, mMeshFolderPath); mHitPoints.push_back(point); // Create a line to display the normal at hit point @@ -137,7 +138,7 @@ class RaycastManager : public rp3d::RaycastCallback { }; // Class RaycastScene -class RaycastScene : public Scene { +class RaycastScene : public SceneDemo { private : @@ -211,8 +212,9 @@ class RaycastScene : public Scene { /// Take a step for the simulation virtual void update(); - /// Render the scene - virtual void render(); + /// Render the scene in a single pass + virtual void renderSinglePass(openglframework::Shader& shader, + const openglframework::Matrix4& worldToCameraMatrix); /// Reset the scene virtual void reset(); diff --git a/testbed/shaders/phong.frag b/testbed/shaders/phong.frag index 498f7238..bb6354e0 100644 --- a/testbed/shaders/phong.frag +++ b/testbed/shaders/phong.frag @@ -70,12 +70,14 @@ void main() { vec3 specular = light0SpecularColor * specularFactor; // Compute shadow factor - vec4 shadowMapCoordsOverW = shadowMapCoords / shadowMapCoords.w ; - //shadowMapCoordsOverW += 0.0005; + float shadowBias = 0.005; + vec4 shadowMapUV = shadowMapCoords; + shadowMapUV.z -= shadowBias; + vec4 shadowMapCoordsOverW = shadowMapUV / shadowMapUV.w ; float distanceInShadowMap = texture(shadowMapSampler, shadowMapCoordsOverW.xy).r; float shadow = 0.0; if (shadowMapCoords.w > 0) { - shadow = distanceInShadowMap < shadowMapCoordsOverW.z ? 0.0 : 1.0; + shadow = distanceInShadowMap < shadowMapCoordsOverW.z ? 0.5 : 1.0; } // Compute the final color diff --git a/testbed/src/SceneDemo.cpp b/testbed/src/SceneDemo.cpp index efee5fcc..52f4fe8a 100644 --- a/testbed/src/SceneDemo.cpp +++ b/testbed/src/SceneDemo.cpp @@ -37,11 +37,11 @@ SceneDemo::SceneDemo(const std::string& name, float sceneRadius) : Scene(name), mVBOQuad(GL_ARRAY_BUFFER) { // Move the light0 - mLight0.translateWorld(Vector3(0, 60, 00)); + mLight0.translateWorld(Vector3(0, 40, 40)); // Camera at light0 postion for the shadow map mShadowMapLightCamera.translateWorld(mLight0.getOrigin()); - mShadowMapLightCamera.rotateLocal(Vector3(1, 0, 0), -PI / 2.0f); + mShadowMapLightCamera.rotateLocal(Vector3(1, 0, 0), -PI / 4.0f); mShadowMapLightCamera.setDimensions(SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT); mShadowMapLightCamera.setFieldOfView(70.0f); mShadowMapLightCamera.setSceneRadius(200); @@ -64,6 +64,8 @@ SceneDemo::~SceneDemo() { mShadowMapTexture.destroy(); mFBOShadowMap.destroy(); + mVBOQuad.destroy(); + } // Render the scene (in multiple passes for shadow mapping) @@ -75,7 +77,7 @@ void SceneDemo::render() { // ---------- Render the scene to generate the shadow map (first pass) ----------- // // Culling switching, rendering only backface, this is done to avoid self-shadowing - glCullFace(GL_FRONT); + glCullFace(GL_BACK); Matrix4 shadowMapProjMatrix = mShadowMapLightCamera.getProjectionMatrix(); diff --git a/testbed/src/SceneDemo.h b/testbed/src/SceneDemo.h index 92e64c10..83649abf 100644 --- a/testbed/src/SceneDemo.h +++ b/testbed/src/SceneDemo.h @@ -30,8 +30,8 @@ #include "Scene.h" // Constants -const int SHADOWMAP_WIDTH = 1024; -const int SHADOWMAP_HEIGHT = 1024; +const int SHADOWMAP_WIDTH = 2048; +const int SHADOWMAP_HEIGHT = 2048; // Class SceneDemo // Abstract class that represents a 3D scene for the ReactPhysics3D examples. From a355a563f8ce3dd16ed44f982b82b47c02fb79a8 Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Fri, 31 Jul 2015 21:54:02 +0200 Subject: [PATCH 24/36] Working on shadow mapping --- testbed/shaders/phong.frag | 8 ++++++-- testbed/src/Gui.cpp | 32 ++++++++++++++++++++++++++++++-- testbed/src/SceneDemo.cpp | 7 ++++++- 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/testbed/shaders/phong.frag b/testbed/shaders/phong.frag index bb6354e0..565df414 100644 --- a/testbed/shaders/phong.frag +++ b/testbed/shaders/phong.frag @@ -70,15 +70,19 @@ void main() { vec3 specular = light0SpecularColor * specularFactor; // Compute shadow factor - float shadowBias = 0.005; + float bias = 0.00001; + float shadowBias = -0.000; vec4 shadowMapUV = shadowMapCoords; shadowMapUV.z -= shadowBias; vec4 shadowMapCoordsOverW = shadowMapUV / shadowMapUV.w ; - float distanceInShadowMap = texture(shadowMapSampler, shadowMapCoordsOverW.xy).r; + float distanceInShadowMap = texture(shadowMapSampler, shadowMapCoordsOverW.xy).r + bias; float shadow = 0.0; if (shadowMapCoords.w > 0) { shadow = distanceInShadowMap < shadowMapCoordsOverW.z ? 0.5 : 1.0; } + if (abs(dot(N, L0)) < 0.01) { + shadow = 0.5; + } // Compute the final color color = vec4(ambient + shadow * vertexColor.rgb, 1.0); diff --git a/testbed/src/Gui.cpp b/testbed/src/Gui.cpp index c7619add..290bca0d 100644 --- a/testbed/src/Gui.cpp +++ b/testbed/src/Gui.cpp @@ -135,11 +135,39 @@ void Gui::displayLeftPane() { app.mWindowToFramebufferRatio.x * LEFT_PANE_WIDTH, app.mWindowToFramebufferRatio.y * LEFT_PANE_HEADER_HEIGHT, &scrollarea); + // ------ Header ----- // + + imguiHorizontalSpace(10); + imguiVerticalSpace(20); + imguiStartLine(); + + const int button_width = 150; + + // Play/Pause + if (imguiButton(app.mTimer.isRunning() ? "Pause" : "Play", true, button_width)) { + app.togglePlayPauseSimulation(); + } + imguiHorizontalSpace(5); + + // Step + if (imguiButton("Step", !app.mTimer.isRunning(), button_width)) { + app.toggleTakeSinglePhysicsStep(); + } + imguiHorizontalSpace(5); + + // Restart + if (imguiButton("Restart", true, button_width)) { + app.restartSimulation(); + } + + imguiEndLine(); + imguiSeparatorLine(); imguiVerticalSpace(5); imguiStartLine(); - // ----- Left Pane Header ----- // + // ----- Left Pane Tabs ----- // + int widthButton = app.mWindowToFramebufferRatio.x * LEFT_PANE_WIDTH / 4.3; if (imguiButton("Scenes", true, widthButton)) { mLeftPane = SCENES; @@ -323,7 +351,7 @@ void Gui::render() { - app.mWindowToFramebufferRatio.y * mScrollY); resetScroll(); - displayHeader(); + //displayHeader(); displayLeftPane(); imguiEndFrame(); diff --git a/testbed/src/SceneDemo.cpp b/testbed/src/SceneDemo.cpp index 52f4fe8a..5fc1a37f 100644 --- a/testbed/src/SceneDemo.cpp +++ b/testbed/src/SceneDemo.cpp @@ -44,7 +44,7 @@ SceneDemo::SceneDemo(const std::string& name, float sceneRadius) : Scene(name), mShadowMapLightCamera.rotateLocal(Vector3(1, 0, 0), -PI / 4.0f); mShadowMapLightCamera.setDimensions(SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT); mShadowMapLightCamera.setFieldOfView(70.0f); - mShadowMapLightCamera.setSceneRadius(200); + mShadowMapLightCamera.setSceneRadius(100); //mShadowMapLightCamera.setZoom(1.0); @@ -76,6 +76,9 @@ void SceneDemo::render() { // ---------- Render the scene to generate the shadow map (first pass) ----------- // + //glEnable(GL_POLYGON_OFFSET_FILL); + //glPolygonOffset(8.0, 4.0); + // Culling switching, rendering only backface, this is done to avoid self-shadowing glCullFace(GL_BACK); @@ -109,6 +112,8 @@ void SceneDemo::render() { mFBOShadowMap.unbind(); + glDisable(GL_POLYGON_OFFSET_FILL); + // ---------- Render the scene for final rendering (second pass) ----------- // From c7bff41ba87f661ad7bebde656d517fd1bd7aaa9 Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Mon, 3 Aug 2015 23:05:55 +0200 Subject: [PATCH 25/36] Fix issue in shadow mapping --- testbed/common/Box.cpp | 124 +++++++++++++----- testbed/common/Box.h | 12 +- testbed/opengl-framework/src/Texture2D.cpp | 8 +- testbed/opengl-framework/src/Texture2D.h | 28 ++-- .../collisionshapes/CollisionShapesScene.cpp | 3 - .../collisionshapes/CollisionShapesScene.h | 17 +-- testbed/scenes/cubes/CubesScene.cpp | 5 +- testbed/scenes/joints/JointsScene.cpp | 9 +- testbed/scenes/joints/JointsScene.h | 8 +- testbed/scenes/raycast/RaycastScene.cpp | 6 +- testbed/scenes/raycast/RaycastScene.h | 6 - testbed/shaders/phong.frag | 26 ++-- testbed/src/SceneDemo.cpp | 81 ++++++------ testbed/src/SceneDemo.h | 28 ++++ testbed/src/TestbedApplication.cpp | 4 - 15 files changed, 210 insertions(+), 155 deletions(-) diff --git a/testbed/common/Box.cpp b/testbed/common/Box.cpp index 3a1659aa..cc97b04e 100644 --- a/testbed/common/Box.cpp +++ b/testbed/common/Box.cpp @@ -31,32 +31,85 @@ // Initialize static variables openglframework::VertexBufferObject Box::mVBOVertices(GL_ARRAY_BUFFER); -openglframework::VertexBufferObject Box::mVBOIndices(GL_ELEMENT_ARRAY_BUFFER); +openglframework::VertexBufferObject Box::mVBONormals(GL_ARRAY_BUFFER); openglframework::VertexArrayObject Box::mVAO; int Box::totalNbBoxes = 0; -VertexData Box::mCubeVertices[8] = { - {openglframework::Vector3(1,1,1),openglframework::Vector3(1,1,1),openglframework::Color(1,0,0,1)}, - {openglframework::Vector3(-1,1,1),openglframework::Vector3(-1,1,1),openglframework::Color(1,0,0,1)}, - {openglframework::Vector3(-1,-1,1),openglframework::Vector3(-1,-1,1),openglframework::Color(1,0,0,1)}, - {openglframework::Vector3(1,-1,1),openglframework::Vector3(1,-1,1),openglframework::Color(1,0,0,1)}, - {openglframework::Vector3(1,-1,-1),openglframework::Vector3(1,-1,-1),openglframework::Color(1,0,0,1)}, - {openglframework::Vector3(-1,-1,-1),openglframework::Vector3(-1,-1,-1),openglframework::Color(1,0,0,1)}, - {openglframework::Vector3(-1,1,-1),openglframework::Vector3(-1,1,-1),openglframework::Color(1,0,0,1)}, - {openglframework::Vector3(1,1,-1),openglframework::Vector3(1,1,-1),openglframework::Color(1,0,0,1)} +GLfloat Box::mCubeVertices[108] = { + -1.0f,-1.0f,-1.0f, // triangle 1 : begin + -1.0f,-1.0f, 1.0f, + -1.0f, 1.0f, 1.0f, // triangle 1 : end + 1.0f, 1.0f,-1.0f, // triangle 2 : begin + -1.0f,-1.0f,-1.0f, + -1.0f, 1.0f,-1.0f, // triangle 2 : end + 1.0f,-1.0f, 1.0f, + -1.0f,-1.0f,-1.0f, + 1.0f,-1.0f,-1.0f, + 1.0f, 1.0f,-1.0f, + 1.0f,-1.0f,-1.0f, + -1.0f,-1.0f,-1.0f, + -1.0f,-1.0f,-1.0f, + -1.0f, 1.0f, 1.0f, + -1.0f, 1.0f,-1.0f, + 1.0f,-1.0f, 1.0f, + -1.0f,-1.0f, 1.0f, + -1.0f,-1.0f,-1.0f, + -1.0f, 1.0f, 1.0f, + -1.0f,-1.0f, 1.0f, + 1.0f,-1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, + 1.0f,-1.0f,-1.0f, + 1.0f, 1.0f,-1.0f, + 1.0f,-1.0f,-1.0f, + 1.0f, 1.0f, 1.0f, + 1.0f,-1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f,-1.0f, + -1.0f, 1.0f,-1.0f, + 1.0f, 1.0f, 1.0f, + -1.0f, 1.0f,-1.0f, + -1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, + -1.0f, 1.0f, 1.0f, + 1.0f,-1.0f, 1.0f +}; +GLfloat Box::mCubeNormals[108] = { + -1.0f, 0.0f, 0.0f, // triangle 1 : begin + -1.0f, 0.0f, 0.0f, + -1.0f, 0.0f, 0.0f, // triangle 1 : end + 0.0f, 0.0f,-1.0f, // triangle 2 : begin + 0.0f, 0.0f,-1.0f, + 0.0f, 0.0f,-1.0f, // triangle 2 : end + 0.0f,-1.0f, 0.0f, + 0.0f,-1.0f, 0.0f, + 0.0f,-1.0f, 0.0f,// + 0.0f, 0.0f,-1.0f, + 0.0f, 0.0f,-1.0f, + 0.0f, 0.0f,-1.0f,// + -1.0f, 0.0f, 0.0f, + -1.0f, 0.0f, 0.0f, + -1.0f, 0.0f,0.0f,// + 0.0f,-1.0f, 0.0f, + 0.0f,-1.0f, 0.0f, + 0.0f,-1.0f, 0.0f,// + 0.0f, 0.0f, 1.0f, + 0.0f, 0.0f, 1.0f, + 0.0f, 0.0f, 1.0f,// + 1.0f, 0.0f, 0.0f, + 1.0f, 0.0f, 0.0f, + 1.0f, 0.0f, 0.0f,// + 1.0f, 0.0f, 0.0f, + 1.0f, 0.0f, 0.0f, + 1.0f, 0.0f, 0.0f,// + 0.0f, 1.0f, 0.0f, + 0.0f, 1.0f, 0.0f, + 0.0f, 1.0f, 0.0f,// + 0.0f, 1.0f, 0.0f, + 0.0f, 1.0f, 0.0f, + 0.0f, 1.0f, 0.0f,// + 0.0f, 0.0f, 1.0f, + 0.0f, 0.0f, 1.0f, + 0.0f, 0.0f, 1.0f// }; -GLuint Box::mCubeIndices[36] = { 0, 1, 2, - 2, 3, 0, - 7, 4, 5, - 5, 6, 7, - 6, 5, 2, - 2, 1, 6, - 7, 0, 3, - 3, 4, 7, - 7, 6, 1, - 1, 0, 7, - 3, 2, 5, - 5, 4, 3}; - // Constructor Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &position, reactphysics3d::CollisionWorld* world) @@ -161,8 +214,8 @@ Box::~Box() { if (totalNbBoxes == 1) { // Destroy the VBOs and VAO - mVBOIndices.destroy(); mVBOVertices.destroy(); + mVBONormals.destroy(); mVAO.destroy(); } @@ -201,17 +254,20 @@ void Box::render(openglframework::Shader& shader, GLint vertexNormalLoc = shader.getAttribLocation("vertexNormal", false); glEnableVertexAttribArray(vertexPositionLoc); - if (vertexNormalLoc != -1) glEnableVertexAttribArray(vertexNormalLoc); + glVertexAttribPointer(vertexPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, NULL); - glVertexAttribPointer(vertexPositionLoc, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), MEMBER_OFFSET(VertexData, position)); - if (vertexNormalLoc != -1) glVertexAttribPointer(vertexNormalLoc, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), MEMBER_OFFSET(VertexData, normal)); + mVBONormals.bind(); + + if (vertexNormalLoc != -1) glEnableVertexAttribArray(vertexNormalLoc); + if (vertexNormalLoc != -1) glVertexAttribPointer(vertexNormalLoc, 3, GL_FLOAT, GL_FALSE, 0, NULL); // Draw the geometry of the box - glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, (char*)NULL); + glDrawArrays(GL_TRIANGLES, 0, 36); glDisableVertexAttribArray(vertexPositionLoc); if (vertexNormalLoc != -1) glDisableVertexAttribArray(vertexNormalLoc); + mVBONormals.unbind(); mVBOVertices.unbind(); // Unbind the VAO @@ -256,11 +312,11 @@ void Box::createVBOAndVAO() { mVBOVertices.copyDataIntoVBO(sizeof(mCubeVertices), mCubeVertices, GL_STATIC_DRAW); mVBOVertices.unbind(); - // Create th VBO for the indices data - mVBOIndices.create(); - mVBOIndices.bind(); - mVBOIndices.copyDataIntoVBO(sizeof(mCubeIndices), mCubeIndices, GL_STATIC_DRAW); - mVBOIndices.unbind(); + // Create th VBO for the normals data + mVBONormals.create(); + mVBONormals.bind(); + mVBONormals.copyDataIntoVBO(sizeof(mCubeNormals), mCubeNormals, GL_STATIC_DRAW); + mVBONormals.unbind(); // Create the VAO for both VBOs mVAO.create(); @@ -270,7 +326,7 @@ void Box::createVBOAndVAO() { mVBOVertices.bind(); // Bind the VBO of indices - mVBOIndices.bind(); + mVBONormals.bind(); // Unbind the VAO mVAO.unbind(); diff --git a/testbed/common/Box.h b/testbed/common/Box.h index b322dc8b..d5759bb1 100644 --- a/testbed/common/Box.h +++ b/testbed/common/Box.h @@ -65,17 +65,17 @@ class Box : public openglframework::Object3D { /// Vertex Buffer Object for the vertices data used to render the box with OpenGL static openglframework::VertexBufferObject mVBOVertices; - /// Vertex Buffer Object for the indices used to render the box with OpenGL - static openglframework::VertexBufferObject mVBOIndices; + /// Vertex Buffer Object for the normales used to render the box with OpenGL + static openglframework::VertexBufferObject mVBONormals; /// Vertex Array Object for the vertex data static openglframework::VertexArrayObject mVAO; - /// Vertex data for each vertex of the cube (used to render the box) - static VertexData mCubeVertices[8]; + /// Vertices coordinates of the triangles of the box + static GLfloat mCubeVertices[108]; - /// Indices of the cube (used to render the box) - static GLuint mCubeIndices[36]; + /// Vertices normals of the triangles of the box + static GLfloat mCubeNormals[108]; /// Total number of boxes created static int totalNbBoxes; diff --git a/testbed/opengl-framework/src/Texture2D.cpp b/testbed/opengl-framework/src/Texture2D.cpp index 94d8905e..2bc8f0a5 100644 --- a/testbed/opengl-framework/src/Texture2D.cpp +++ b/testbed/opengl-framework/src/Texture2D.cpp @@ -33,13 +33,13 @@ using namespace openglframework; // Constructor -Texture2D::Texture2D() : mID(0), mLayer(0), mWidth(0), mHeight(0) { +Texture2D::Texture2D() : mID(0), mUnit(0), mWidth(0), mHeight(0) { } // Constructor Texture2D::Texture2D(uint width, uint height, uint internalFormat, uint format, uint type) - : mID(0), mLayer(0), mWidth(0), mHeight(0){ + : mID(0), mUnit(0), mWidth(0), mHeight(0) { // Create the texture create(width, height, internalFormat, format, type); @@ -52,7 +52,7 @@ Texture2D::~Texture2D() { // Create the texture void Texture2D::create(uint width, uint height, uint internalFormat, uint format, uint type, - void* data) { + void* data) { // Destroy the current texture destroy(); @@ -99,7 +99,7 @@ void Texture2D::destroy() { if (mID != 0) { glDeleteTextures(1, &mID); mID = 0; - mLayer = 0; + mUnit = 0; mWidth = 0; mHeight = 0; } diff --git a/testbed/opengl-framework/src/Texture2D.h b/testbed/opengl-framework/src/Texture2D.h index f765e1ac..5f8ce3ae 100644 --- a/testbed/opengl-framework/src/Texture2D.h +++ b/testbed/opengl-framework/src/Texture2D.h @@ -45,8 +45,8 @@ class Texture2D { // OpenGL texture ID GLuint mID; - // Layer of the texture - GLuint mLayer; + // Current texture unit for this texture + GLuint mUnit; // Width uint mWidth; @@ -87,11 +87,11 @@ class Texture2D { // Get the OpenGL texture ID uint getID() const; - // Get the layer of the texture - uint getLayer() const; + // Get the unit of the texture + uint getUnit() const; - // Set the layer of the texture - void setLayer(uint layer); + // Set the unit of the texture + void setUnit(uint unit); // Get the width uint getWidth() const; @@ -103,14 +103,14 @@ class Texture2D { // Bind the texture inline void Texture2D::bind() const { assert(mID != 0); - glActiveTexture(GL_TEXTURE0 + mLayer); + glActiveTexture(GL_TEXTURE0 + mUnit); glBindTexture(GL_TEXTURE_2D, mID); } // Unbind the texture inline void Texture2D::unbind() const { assert(mID != 0); - glActiveTexture(GL_TEXTURE0 + mLayer); + glActiveTexture(GL_TEXTURE0 + mUnit); glBindTexture(GL_TEXTURE_2D, 0); } @@ -119,14 +119,14 @@ inline uint Texture2D::getID() const { return mID; } -// Get the layer of the texture -inline uint Texture2D::getLayer() const { - return mLayer; +// Get the unit of the texture +inline uint Texture2D::getUnit() const { + return mUnit; } -// Set the layer of the texture -inline void Texture2D::setLayer(uint layer) { - mLayer = layer; +// Set the unit of the texture +inline void Texture2D::setUnit(uint unit) { + mUnit = unit; } // Get the width diff --git a/testbed/scenes/collisionshapes/CollisionShapesScene.cpp b/testbed/scenes/collisionshapes/CollisionShapesScene.cpp index 46c34f4a..1fc06b7e 100644 --- a/testbed/scenes/collisionshapes/CollisionShapesScene.cpp +++ b/testbed/scenes/collisionshapes/CollisionShapesScene.cpp @@ -225,9 +225,6 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name) // Destructor CollisionShapesScene::~CollisionShapesScene() { - // Destroy the shader - mPhongShader.destroy(); - // Destroy all the boxes of the scene for (std::vector::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { diff --git a/testbed/scenes/collisionshapes/CollisionShapesScene.h b/testbed/scenes/collisionshapes/CollisionShapesScene.h index 92fd166b..a75528e7 100644 --- a/testbed/scenes/collisionshapes/CollisionShapesScene.h +++ b/testbed/scenes/collisionshapes/CollisionShapesScene.h @@ -46,12 +46,12 @@ namespace collisionshapesscene { // Constants const float SCENE_RADIUS = 30.0f; const int NB_BOXES = 3; -const int NB_CUBES = 3; -const int NB_CONES = 3; -const int NB_CYLINDERS = 3; -const int NB_CAPSULES = 3; -const int NB_MESHES = 2; -const int NB_COMPOUND_SHAPES = 2; +const int NB_CUBES = 0; +const int NB_CONES = 0; +const int NB_CYLINDERS = 0; +const int NB_CAPSULES = 0; +const int NB_MESHES = 0; +const int NB_COMPOUND_SHAPES = 0; const openglframework::Vector3 BOX_SIZE(2, 2, 2); const float SPHERE_RADIUS = 1.5f; const float CONE_RADIUS = 2.0f; @@ -61,7 +61,7 @@ const float CYLINDER_HEIGHT = 5.0f; const float CAPSULE_RADIUS = 1.0f; const float CAPSULE_HEIGHT = 1.0f; const float DUMBBELL_HEIGHT = 1.0f; -const openglframework::Vector3 FLOOR_SIZE(20, 0.5f, 20); // Floor dimensions in meters +const openglframework::Vector3 FLOOR_SIZE(50, 0.5f, 50); // Floor dimensions in meters const float BOX_MASS = 1.0f; const float CONE_MASS = 1.0f; const float CYLINDER_MASS = 1.0f; @@ -76,9 +76,6 @@ class CollisionShapesScene : public SceneDemo { // -------------------- Attributes -------------------- // - /// Phong shader - openglframework::Shader mPhongShader; - /// All the spheres of the scene std::vector mBoxes; diff --git a/testbed/scenes/cubes/CubesScene.cpp b/testbed/scenes/cubes/CubesScene.cpp index 1defa9ce..0215e6d3 100644 --- a/testbed/scenes/cubes/CubesScene.cpp +++ b/testbed/scenes/cubes/CubesScene.cpp @@ -41,7 +41,7 @@ CubesScene::CubesScene(const std::string& name) setScenePosition(center, SCENE_RADIUS); // Gravity vector in the dynamics world - rp3d::Vector3 gravity(0, rp3d::decimal(-5.81), 0); + rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0); // Time step for the physics simulation rp3d::decimal timeStep = 1.0f / 60.0f; @@ -100,9 +100,6 @@ CubesScene::CubesScene(const std::string& name) // Destructor CubesScene::~CubesScene() { - // Destroy the shader - mPhongShader.destroy(); - // Destroy all the cubes of the scene for (std::vector::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { diff --git a/testbed/scenes/joints/JointsScene.cpp b/testbed/scenes/joints/JointsScene.cpp index 5a60023d..50d7deb1 100644 --- a/testbed/scenes/joints/JointsScene.cpp +++ b/testbed/scenes/joints/JointsScene.cpp @@ -33,11 +33,7 @@ using namespace jointsscene; // Constructor JointsScene::JointsScene(const std::string& name) - : SceneDemo(name, SCENE_RADIUS), mLight0(0), mPhongShader("shaders/phong.vert", - "shaders/phong.frag") { - - // Move the light 0 - mLight0.translateWorld(Vector3(7, 15, 15)); + : SceneDemo(name, SCENE_RADIUS) { // Compute the radius and the center of the scene openglframework::Vector3 center(0, 5, 0); @@ -87,9 +83,6 @@ JointsScene::JointsScene(const std::string& name) // Destructor JointsScene::~JointsScene() { - // Destroy the shader - mPhongShader.destroy(); - // Destroy the joints mDynamicsWorld->destroyJoint(mSliderJoint); mDynamicsWorld->destroyJoint(mPropellerHingeJoint); diff --git a/testbed/scenes/joints/JointsScene.h b/testbed/scenes/joints/JointsScene.h index 2795a7fd..b2d22c07 100644 --- a/testbed/scenes/joints/JointsScene.h +++ b/testbed/scenes/joints/JointsScene.h @@ -37,7 +37,7 @@ namespace jointsscene { // Constants const float SCENE_RADIUS = 30.0f; const openglframework::Vector3 BOX_SIZE(2, 2, 2); // Box dimensions in meters -const openglframework::Vector3 FLOOR_SIZE(20, 0.5f, 20); // Floor dimensions in meters +const openglframework::Vector3 FLOOR_SIZE(50, 0.5f, 50); // Floor dimensions in meters const float BOX_MASS = 1.0f; // Box mass in kilograms const float FLOOR_MASS = 100.0f; // Floor mass in kilograms const int NB_BALLSOCKETJOINT_BOXES = 7; // Number of Ball-And-Socket chain boxes @@ -50,12 +50,6 @@ class JointsScene : public SceneDemo { // -------------------- Attributes -------------------- // - /// Light 0 - openglframework::Light mLight0; - - /// Phong shader - openglframework::Shader mPhongShader; - /// Boxes of Ball-And-Socket joint chain Box* mBallAndSocketJointChainBoxes[NB_BALLSOCKETJOINT_BOXES]; diff --git a/testbed/scenes/raycast/RaycastScene.cpp b/testbed/scenes/raycast/RaycastScene.cpp index d26c2e8a..4e82fb6a 100644 --- a/testbed/scenes/raycast/RaycastScene.cpp +++ b/testbed/scenes/raycast/RaycastScene.cpp @@ -32,14 +32,10 @@ using namespace raycastscene; // Constructor RaycastScene::RaycastScene(const std::string& name) - : SceneDemo(name, SCENE_RADIUS), mLight0(0), mCurrentBodyIndex(-1), mAreNormalsDisplayed(false), - mPhongShader("shaders/phong.vert", "shaders/phong.frag"), + : SceneDemo(name, SCENE_RADIUS), mCurrentBodyIndex(-1), mAreNormalsDisplayed(false), mMeshFolderPath("meshes/"), mRaycastManager(mPhongShader, mMeshFolderPath), mVBOVertices(GL_ARRAY_BUFFER) { - // Move the light 0 - mLight0.translateWorld(Vector3(50, 50, 50)); - // Compute the radius and the center of the scene openglframework::Vector3 center(0, 0, 0); diff --git a/testbed/scenes/raycast/RaycastScene.h b/testbed/scenes/raycast/RaycastScene.h index a58837fc..9110a5bb 100644 --- a/testbed/scenes/raycast/RaycastScene.h +++ b/testbed/scenes/raycast/RaycastScene.h @@ -144,12 +144,6 @@ class RaycastScene : public SceneDemo { // -------------------- Attributes -------------------- // - /// Light 0 - openglframework::Light mLight0; - - /// Phong shader - openglframework::Shader mPhongShader; - /// Contact point mesh folder path std::string mMeshFolderPath; diff --git a/testbed/shaders/phong.frag b/testbed/shaders/phong.frag index 565df414..a4c044f0 100644 --- a/testbed/shaders/phong.frag +++ b/testbed/shaders/phong.frag @@ -35,6 +35,7 @@ uniform sampler2D textureSampler; // Texture uniform sampler2D shadowMapSampler; // Shadow map texture sampler uniform bool isTexture; // True if we need to use the texture uniform vec4 vertexColor; // Vertex color +uniform bool isShadowEnabled; // True if shadow mapping is enabled // In variables in vec3 vertexPosCameraSpace; // Camera-space position of the vertex @@ -70,20 +71,19 @@ void main() { vec3 specular = light0SpecularColor * specularFactor; // Compute shadow factor - float bias = 0.00001; - float shadowBias = -0.000; - vec4 shadowMapUV = shadowMapCoords; - shadowMapUV.z -= shadowBias; - vec4 shadowMapCoordsOverW = shadowMapUV / shadowMapUV.w ; - float distanceInShadowMap = texture(shadowMapSampler, shadowMapCoordsOverW.xy).r + bias; - float shadow = 0.0; - if (shadowMapCoords.w > 0) { - shadow = distanceInShadowMap < shadowMapCoordsOverW.z ? 0.5 : 1.0; - } - if (abs(dot(N, L0)) < 0.01) { - shadow = 0.5; + float shadow = 1.0; + if (isShadowEnabled) { + float bias = 0.0001; + float shadowBias = -0.000; + vec4 shadowMapUV = shadowMapCoords; + shadowMapUV.z -= shadowBias; + vec4 shadowMapCoordsOverW = shadowMapUV / shadowMapUV.w ; + float distanceInShadowMap = texture(shadowMapSampler, shadowMapCoordsOverW.xy).r + bias; + if (shadowMapCoords.w > 0) { + shadow = distanceInShadowMap < shadowMapCoordsOverW.z ? 0.5 : 1.0; + } } // Compute the final color - color = vec4(ambient + shadow * vertexColor.rgb, 1.0); + color = vec4(ambient + shadow * diffuse, 1.0); } diff --git a/testbed/src/SceneDemo.cpp b/testbed/src/SceneDemo.cpp index 5fc1a37f..6a5ddfbe 100644 --- a/testbed/src/SceneDemo.cpp +++ b/testbed/src/SceneDemo.cpp @@ -29,13 +29,18 @@ using namespace openglframework; +int SceneDemo::shadowMapTextureLevel = 0; + // Constructor -SceneDemo::SceneDemo(const std::string& name, float sceneRadius) : Scene(name), mLight0(0), +SceneDemo::SceneDemo(const std::string& name, float sceneRadius) : Scene(name), + mLight0(0), mIsShadowMappingEnabled(true), mIsShadowMappingInitialized(false), mDepthShader("shaders/depth.vert", "shaders/depth.frag"), mPhongShader("shaders/phong.vert", "shaders/phong.frag"), mQuadShader("shaders/quad.vert", "shaders/quad.frag"), mVBOQuad(GL_ARRAY_BUFFER) { + shadowMapTextureLevel++; + // Move the light0 mLight0.translateWorld(Vector3(0, 40, 40)); @@ -47,14 +52,15 @@ SceneDemo::SceneDemo(const std::string& name, float sceneRadius) : Scene(name), mShadowMapLightCamera.setSceneRadius(100); //mShadowMapLightCamera.setZoom(1.0); - mShadowMapBiasMatrix.setAllValues(0.5, 0.0, 0.0, 0.5, 0.0, 0.5, 0.0, 0.5, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 1.0); // Create the Shadow map FBO and texture - createShadowMapFBOAndTexture(); + if (mIsShadowMappingEnabled) { + createShadowMapFBOAndTexture(); + } createQuadVBO(); } @@ -71,49 +77,50 @@ SceneDemo::~SceneDemo() { // Render the scene (in multiple passes for shadow mapping) void SceneDemo::render() { + const Color& diffCol = mLight0.getDiffuseColor(); + const Color& specCol = mLight0.getSpecularColor(); + glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); // ---------- Render the scene to generate the shadow map (first pass) ----------- // - //glEnable(GL_POLYGON_OFFSET_FILL); - //glPolygonOffset(8.0, 4.0); - - // Culling switching, rendering only backface, this is done to avoid self-shadowing - glCullFace(GL_BACK); - - Matrix4 shadowMapProjMatrix = mShadowMapLightCamera.getProjectionMatrix(); - - // Get the world-space to camera-space matrix + const Matrix4 shadowMapProjMatrix = mShadowMapLightCamera.getProjectionMatrix(); const openglframework::Matrix4 worldToLightCameraMatrix = mShadowMapLightCamera.getTransformMatrix().getInverse(); - mFBOShadowMap.bind(); + // If Shadow Mapping is enabled + if (mIsShadowMappingEnabled) { - // Bind the shader - mDepthShader.bind(); + // Culling switching, rendering only backface, this is done to avoid self-shadowing + glCullFace(GL_BACK); - // Set the variables of the shader - mDepthShader.setMatrix4x4Uniform("projectionMatrix", shadowMapProjMatrix); + mFBOShadowMap.bind(); - // Set the viewport to render into the shadow map texture - glViewport(0, 0, SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT); + // Bind the shader + mDepthShader.bind(); - // Clear previous frame values - glClear( GL_DEPTH_BUFFER_BIT); + // Set the variables of the shader + mDepthShader.setMatrix4x4Uniform("projectionMatrix", shadowMapProjMatrix); - // Disable color rendering, we only want to write to the Z-Buffer - glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + // Set the viewport to render into the shadow map texture + glViewport(0, 0, SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT); - // Render the objects of the scene - renderSinglePass(mDepthShader, worldToLightCameraMatrix); + // Clear previous frame values + glClear(GL_DEPTH_BUFFER_BIT); - // Unbind the shader - mDepthShader.unbind(); + // Disable color rendering, we only want to write to the Z-Buffer + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - mFBOShadowMap.unbind(); + // Render the objects of the scene + renderSinglePass(mDepthShader, worldToLightCameraMatrix); - glDisable(GL_POLYGON_OFFSET_FILL); + // Unbind the shader + mDepthShader.unbind(); + mFBOShadowMap.unbind(); + + glDisable(GL_POLYGON_OFFSET_FILL); + } // ---------- Render the scene for final rendering (second pass) ----------- // @@ -124,20 +131,20 @@ void SceneDemo::render() { mPhongShader.bind(); - mShadowMapTexture.bind(); + if (mIsShadowMappingEnabled) mShadowMapTexture.bind(); + const GLuint textureUnit = 0; // Set the variables of the shader mPhongShader.setMatrix4x4Uniform("projectionMatrix", mCamera.getProjectionMatrix()); mPhongShader.setMatrix4x4Uniform("shadowMapProjectionMatrix", mShadowMapBiasMatrix * shadowMapProjMatrix); mPhongShader.setMatrix4x4Uniform("worldToLight0CameraMatrix", worldToLightCameraMatrix); mPhongShader.setVector3Uniform("light0PosCameraSpace", worldToCameraMatrix * mLight0.getOrigin()); - mPhongShader.setVector3Uniform("lightAmbientColor", Vector3(0.3f, 0.3f, 0.3f)); - const Color& diffCol = mLight0.getDiffuseColor(); - const Color& specCol = mLight0.getSpecularColor(); + mPhongShader.setVector3Uniform("lightAmbientColor", Vector3(0.4f, 0.4f, 0.4f)); mPhongShader.setVector3Uniform("light0DiffuseColor", Vector3(diffCol.r, diffCol.g, diffCol.b)); mPhongShader.setVector3Uniform("light0SpecularColor", Vector3(specCol.r, specCol.g, specCol.b)); mPhongShader.setFloatUniform("shininess", 60.0f); - mPhongShader.setIntUniform("shadowMapSampler", mShadowMapTexture.getID()); + mPhongShader.setIntUniform("shadowMapSampler", textureUnit); + mPhongShader.setIntUniform("isShadowEnabled", mIsShadowMappingEnabled); // Set the viewport to render the scene glViewport(mViewportX, mViewportY, mViewportWidth, mViewportHeight); @@ -151,7 +158,7 @@ void SceneDemo::render() { // Render the objects of the scene renderSinglePass(mPhongShader, worldToCameraMatrix); - mShadowMapTexture.unbind(); + if (mIsShadowMappingEnabled) mShadowMapTexture.unbind(); mPhongShader.unbind(); //drawTextureQuad(); @@ -163,7 +170,6 @@ void SceneDemo::createShadowMapFBOAndTexture() { // Create the texture for the depth values mShadowMapTexture.create(SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, GL_NEAREST, GL_NEAREST, GL_CLAMP, GL_CLAMP, NULL); - mShadowMapTexture.setLayer(1); // Create the FBO for the shadow map mFBOShadowMap.create(0, 0, false); @@ -175,6 +181,8 @@ void SceneDemo::createShadowMapFBOAndTexture() { mFBOShadowMap.attachTexture(GL_DEPTH_ATTACHMENT_EXT, mShadowMapTexture.getID()); mFBOShadowMap.unbind(); + + mIsShadowMappingInitialized = true; } // TODO : Delete this @@ -200,7 +208,6 @@ void SceneDemo::createQuadVBO() { mVAOQuad.unbind(); } -// TODO : Delete this void SceneDemo::drawTextureQuad() { glViewport(mViewportX, mViewportY, mViewportWidth, mViewportHeight); diff --git a/testbed/src/SceneDemo.h b/testbed/src/SceneDemo.h index 83649abf..8893e26c 100644 --- a/testbed/src/SceneDemo.h +++ b/testbed/src/SceneDemo.h @@ -45,12 +45,20 @@ class SceneDemo : public Scene { /// Light 0 openglframework::Light mLight0; + /// True if the shadow mapping is enabled + bool mIsShadowMappingEnabled; + + /// True if the shadows FBO, textures have been created + bool mIsShadowMappingInitialized; + /// FBO for the shadow map openglframework::FrameBufferObject mFBOShadowMap; /// Shadow map texture openglframework::Texture2D mShadowMapTexture; + static int shadowMapTextureLevel; + /// Shadow map bias matrix openglframework::Matrix4 mShadowMapBiasMatrix; @@ -99,8 +107,28 @@ class SceneDemo : public Scene { /// Render the scene in a single pass virtual void renderSinglePass(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix)=0; + + /// Return true if the shadow mapping is enabled + bool getIsShadowMappingEnabled() const; + + /// Enabled/Disable the shadow mapping + void setIsShadowMappingEnabled(bool isShadowMappingEnabled); }; +// Return true if the shadow mapping is enabled +inline bool SceneDemo::getIsShadowMappingEnabled() const { + return mIsShadowMappingEnabled; +} + +// Enabled/Disable the shadow mapping +inline void SceneDemo::setIsShadowMappingEnabled(bool isShadowMappingEnabled) { + mIsShadowMappingEnabled = isShadowMappingEnabled; + + if (mIsShadowMappingEnabled && !mIsShadowMappingInitialized) { + createShadowMapFBOAndTexture(); + } +} + #endif diff --git a/testbed/src/TestbedApplication.cpp b/testbed/src/TestbedApplication.cpp index d81887f9..6cbeb41a 100644 --- a/testbed/src/TestbedApplication.cpp +++ b/testbed/src/TestbedApplication.cpp @@ -276,10 +276,6 @@ void TestbedApplication::reshape() { // Resize the camera viewport mCurrentScene->reshape(width - LEFT_PANE_WIDTH, height - HEADER_HEIGHT); - // Resize the OpenGL viewport - //glViewport(LEFT_PANE_WIDTH, HEADER_HEIGHT, - // width - LEFT_PANE_WIDTH, height - HEADER_HEIGHT); - // Update the window size of the scene int windowWidth, windowHeight; glfwGetWindowSize(mWindow, &windowWidth, &windowHeight); From 5d7cb3cfd5dd723cf6a82386f5d8d39ed81d5c1f Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Thu, 6 Aug 2015 21:06:35 +0200 Subject: [PATCH 26/36] Working on the testbed application --- testbed/CMakeLists.txt | 2 + testbed/common/Box.h | 13 -- .../collisionshapes/CollisionShapesScene.cpp | 1 + .../collisionshapes/CollisionShapesScene.h | 12 +- testbed/scenes/cubes/CubesScene.cpp | 9 ++ testbed/scenes/cubes/CubesScene.h | 3 + testbed/scenes/joints/JointsScene.cpp | 1 + testbed/scenes/raycast/RaycastScene.cpp | 2 +- testbed/scenes/raycast/RaycastScene.h | 9 ++ testbed/src/Gui.cpp | 129 ++++++++++++------ testbed/src/Gui.h | 18 ++- testbed/src/PhysicsEventListener.cpp | 38 ++++++ testbed/src/PhysicsEventListener.h | 66 +++++++++ testbed/src/Scene.cpp | 4 +- testbed/src/Scene.h | 32 ++++- testbed/src/SceneDemo.cpp | 5 +- testbed/src/SceneDemo.h | 22 +-- testbed/src/TestbedApplication.cpp | 36 +++-- testbed/src/TestbedApplication.h | 38 +++++- 19 files changed, 337 insertions(+), 103 deletions(-) create mode 100644 testbed/src/PhysicsEventListener.cpp create mode 100644 testbed/src/PhysicsEventListener.h diff --git a/testbed/CMakeLists.txt b/testbed/CMakeLists.txt index ff842cff..9f6ed161 100644 --- a/testbed/CMakeLists.txt +++ b/testbed/CMakeLists.txt @@ -43,6 +43,8 @@ SET(TESTBED_SOURCES src/SceneDemo.cpp src/Timer.h src/Timer.cpp + src/PhysicsEventListener.h + src/PhysicsEventListener.cpp ) # IMGUI source files diff --git a/testbed/common/Box.h b/testbed/common/Box.h index d5759bb1..90d4a203 100644 --- a/testbed/common/Box.h +++ b/testbed/common/Box.h @@ -30,19 +30,6 @@ #include "openglframework.h" #include "reactphysics3d.h" -// Structure VertexData -struct VertexData { - - /// Vertex position - openglframework::Vector3 position; - - /// Vertex normal - openglframework::Vector3 normal; - - // Vertex color - openglframework::Color color; -}; - // Class Box class Box : public openglframework::Object3D { diff --git a/testbed/scenes/collisionshapes/CollisionShapesScene.cpp b/testbed/scenes/collisionshapes/CollisionShapesScene.cpp index 1fc06b7e..baf7559d 100644 --- a/testbed/scenes/collisionshapes/CollisionShapesScene.cpp +++ b/testbed/scenes/collisionshapes/CollisionShapesScene.cpp @@ -202,6 +202,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name) // Create the floor openglframework::Vector3 floorPosition(0, 0, 0); mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld); + mFloor->setColor(Color(0.70f, 0.70f, 0.7f, 1.0f)); // The floor must be a static rigid body mFloor->getRigidBody()->setType(rp3d::STATIC); diff --git a/testbed/scenes/collisionshapes/CollisionShapesScene.h b/testbed/scenes/collisionshapes/CollisionShapesScene.h index a75528e7..0befba55 100644 --- a/testbed/scenes/collisionshapes/CollisionShapesScene.h +++ b/testbed/scenes/collisionshapes/CollisionShapesScene.h @@ -46,12 +46,12 @@ namespace collisionshapesscene { // Constants const float SCENE_RADIUS = 30.0f; const int NB_BOXES = 3; -const int NB_CUBES = 0; -const int NB_CONES = 0; -const int NB_CYLINDERS = 0; -const int NB_CAPSULES = 0; -const int NB_MESHES = 0; -const int NB_COMPOUND_SHAPES = 0; +const int NB_CUBES = 5; +const int NB_CONES = 3; +const int NB_CYLINDERS = 3; +const int NB_CAPSULES = 4; +const int NB_MESHES = 4; +const int NB_COMPOUND_SHAPES = 3; const openglframework::Vector3 BOX_SIZE(2, 2, 2); const float SPHERE_RADIUS = 1.5f; const float CONE_RADIUS = 2.0f; diff --git a/testbed/scenes/cubes/CubesScene.cpp b/testbed/scenes/cubes/CubesScene.cpp index 0215e6d3..1cd18ef3 100644 --- a/testbed/scenes/cubes/CubesScene.cpp +++ b/testbed/scenes/cubes/CubesScene.cpp @@ -77,6 +77,7 @@ CubesScene::CubesScene(const std::string& name) // Create the floor openglframework::Vector3 floorPosition(0, 0, 0); mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld); + mFloor->setColor(Color(0.70f, 0.70f, 0.7f, 1.0f)); // The floor must be a static rigid body mFloor->getRigidBody()->setType(rp3d::STATIC); @@ -202,3 +203,11 @@ void CubesScene::reset() { mBoxes[i]->resetTransform(transform); } } + +// Return all the contact points of the scene +std::vector CubesScene::getContactPoints() const { + + std::vector contactPoints; + + return contactPoints; +} diff --git a/testbed/scenes/cubes/CubesScene.h b/testbed/scenes/cubes/CubesScene.h index 02db7d4c..07d4c770 100644 --- a/testbed/scenes/cubes/CubesScene.h +++ b/testbed/scenes/cubes/CubesScene.h @@ -81,6 +81,9 @@ class CubesScene : public SceneDemo { /// Reset the scene virtual void reset(); + + /// Return all the contact points of the scene + std::vector virtual getContactPoints() const; }; } diff --git a/testbed/scenes/joints/JointsScene.cpp b/testbed/scenes/joints/JointsScene.cpp index 50d7deb1..be0ae28f 100644 --- a/testbed/scenes/joints/JointsScene.cpp +++ b/testbed/scenes/joints/JointsScene.cpp @@ -447,6 +447,7 @@ void JointsScene::createFloor() { // Create the floor openglframework::Vector3 floorPosition(0, 0, 0); mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld); + mFloor->setColor(Color(0.70f, 0.70f, 0.7f, 1.0f)); // The floor must be a static rigid body mFloor->getRigidBody()->setType(rp3d::STATIC); diff --git a/testbed/scenes/raycast/RaycastScene.cpp b/testbed/scenes/raycast/RaycastScene.cpp index 4e82fb6a..caa0b4ab 100644 --- a/testbed/scenes/raycast/RaycastScene.cpp +++ b/testbed/scenes/raycast/RaycastScene.cpp @@ -32,7 +32,7 @@ using namespace raycastscene; // Constructor RaycastScene::RaycastScene(const std::string& name) - : SceneDemo(name, SCENE_RADIUS), mCurrentBodyIndex(-1), mAreNormalsDisplayed(false), + : SceneDemo(name, SCENE_RADIUS, false), mCurrentBodyIndex(-1), mAreNormalsDisplayed(false), mMeshFolderPath("meshes/"), mRaycastManager(mPhongShader, mMeshFolderPath), mVBOVertices(GL_ARRAY_BUFFER) { diff --git a/testbed/scenes/raycast/RaycastScene.h b/testbed/scenes/raycast/RaycastScene.h index 9110a5bb..67e0f873 100644 --- a/testbed/scenes/raycast/RaycastScene.h +++ b/testbed/scenes/raycast/RaycastScene.h @@ -221,6 +221,9 @@ class RaycastScene : public SceneDemo { /// Called when a keyboard event occurs virtual void keyboardEvent(int key, int scancode, int action, int mods); + + /// Enabled/Disable the shadow mapping + void virtual setIsShadowMappingEnabled(bool isShadowMappingEnabled); }; // Display or not the surface normals at hit points @@ -228,6 +231,12 @@ inline void RaycastScene::showHideNormals() { mAreNormalsDisplayed = !mAreNormalsDisplayed; } +// Enabled/Disable the shadow mapping +inline void RaycastScene::setIsShadowMappingEnabled(bool isShadowMappingEnabled) { + + SceneDemo::setIsShadowMappingEnabled(false); +} + } #endif diff --git a/testbed/src/Gui.cpp b/testbed/src/Gui.cpp index 290bca0d..d45e0fce 100644 --- a/testbed/src/Gui.cpp +++ b/testbed/src/Gui.cpp @@ -26,6 +26,8 @@ // Libraries #include "Gui.h" #include +#include +#include #include "TestbedApplication.h" GLFWwindow* Gui::mWindow = NULL; @@ -42,6 +44,10 @@ openglframework::VertexArrayObject Gui::mVAO; Gui::LeftPane Gui::mLeftPane = SCENES; double Gui::mScrollX = 0.0; double Gui::mScrollY = 0.0; +double Gui::mTimeSinceLastProfilingDisplay = 0; +double Gui::mCachedFPS = 0; +double Gui::mCachedUpdateTime = 0; +double Gui::mCachedPhysicsUpdateTime = 0; // Constructor Gui::Gui() { @@ -80,47 +86,8 @@ void Gui::init() { fprintf(stderr, "Could not init GUI renderer.\n"); exit(EXIT_FAILURE); } -} -void Gui::displayHeader() { - - TestbedApplication& app = TestbedApplication::getInstance(); - - int windowWidth, windowHeight; - glfwGetWindowSize(mWindow, &windowWidth, &windowHeight); - - const int button_width = 150; - - int scrollarea = 0; - imguiBeginScrollArea(NULL, 0, app.mWindowToFramebufferRatio.y * (windowHeight - HEADER_HEIGHT), - app.mWindowToFramebufferRatio.x * windowWidth, - app.mWindowToFramebufferRatio.y * HEADER_HEIGHT, &scrollarea); - - imguiHorizontalSpace(10); - imguiVerticalSpace(20); - imguiStartLine(); - - // ----- Left Pane Header ----- // - - // Play/Pause - if (imguiButton(app.mTimer.isRunning() ? "Pause" : "Play", true, button_width)) { - app.togglePlayPauseSimulation(); - } - imguiHorizontalSpace(5); - - // Step - if (imguiButton("Step", !app.mTimer.isRunning(), button_width)) { - app.toggleTakeSinglePhysicsStep(); - } - imguiHorizontalSpace(5); - - // Restart - if (imguiButton("Restart", true, button_width)) { - app.restartSimulation(); - } - - imguiEndLine(); - imguiEndScrollArea(); + mTimeSinceLastProfilingDisplay = glfwGetTime(); } void Gui::displayLeftPane() { @@ -131,7 +98,7 @@ void Gui::displayLeftPane() { glfwGetWindowSize(mWindow, &windowWidth, &windowHeight); int scrollarea = 0; - imguiBeginScrollArea(NULL, 0, app.mWindowToFramebufferRatio.y * (windowHeight - HEADER_HEIGHT - LEFT_PANE_HEADER_HEIGHT), + imguiBeginScrollArea(NULL, 0, app.mWindowToFramebufferRatio.y * (windowHeight - LEFT_PANE_HEADER_HEIGHT), app.mWindowToFramebufferRatio.x * LEFT_PANE_WIDTH, app.mWindowToFramebufferRatio.y * LEFT_PANE_HEADER_HEIGHT, &scrollarea); @@ -161,6 +128,7 @@ void Gui::displayLeftPane() { } imguiEndLine(); + imguiVerticalSpace(70); imguiSeparatorLine(); imguiVerticalSpace(5); @@ -179,10 +147,14 @@ void Gui::displayLeftPane() { } imguiHorizontalSpace(5); - imguiButton("Rendering", true, widthButton); + if (imguiButton("Rendering", true, widthButton)) { + mLeftPane = RENDERING; + } imguiHorizontalSpace(5); - imguiButton("Profiling", true, widthButton); + if (imguiButton("Profiling", true, widthButton)) { + mLeftPane = PROFILING; + } imguiEndLine(); imguiVerticalSpace(BUTTON_HEIGHT + 8); @@ -213,7 +185,7 @@ void Gui::displayScenesPane() { imguiBeginScrollArea("Scenes", 0, 0, app.mWindowToFramebufferRatio.x * LEFT_PANE_WIDTH, - app.mWindowToFramebufferRatio.y * (windowHeight - HEADER_HEIGHT - LEFT_PANE_HEADER_HEIGHT), + app.mWindowToFramebufferRatio.y * (windowHeight - LEFT_PANE_HEADER_HEIGHT), &scrollarea); imguiVerticalSpace(15); @@ -243,7 +215,7 @@ void Gui::displayPhysicsPane() { int scrollarea = 2; imguiBeginScrollArea("Physics Engine Parameters", 0, 0, app.mWindowToFramebufferRatio.x * LEFT_PANE_WIDTH, - app.mWindowToFramebufferRatio.y * (windowHeight - HEADER_HEIGHT - LEFT_PANE_HEADER_HEIGHT), + app.mWindowToFramebufferRatio.y * (windowHeight - LEFT_PANE_HEADER_HEIGHT), &scrollarea); imguiVerticalSpace(15); @@ -314,10 +286,77 @@ void Gui::displayPhysicsPane() { void Gui::displayRenderingPane() { + TestbedApplication& app = TestbedApplication::getInstance(); + + int windowWidth, windowHeight; + glfwGetWindowSize(mWindow, &windowWidth, &windowHeight); + + int scrollarea = 2; + imguiBeginScrollArea("Rendering Parameters", 0, 0, + app.mWindowToFramebufferRatio.x * LEFT_PANE_WIDTH, + app.mWindowToFramebufferRatio.y * (windowHeight - LEFT_PANE_HEADER_HEIGHT), + &scrollarea); + + imguiVerticalSpace(15); + + // Enabled/Disable VSync + bool toggleVSync = imguiCheck("V Sync", app.mIsVSyncEnabled); + if (toggleVSync) { + app.enableVSync(!app.mIsVSyncEnabled); + } + + // Enabled/Disable Shadows + bool toggleShadows = imguiCheck("Shadows", app.mIsShadowMappingEnabled); + if (toggleShadows) { + app.enableShadows(!app.mIsShadowMappingEnabled); + } + + imguiEndScrollArea(); } void Gui::displayProfilingPane() { + TestbedApplication& app = TestbedApplication::getInstance(); + + double currentTime = glfwGetTime(); + if ((currentTime - mTimeSinceLastProfilingDisplay) > TIME_INTERVAL_DISPLAY_PROFILING_INFO) { + mTimeSinceLastProfilingDisplay = currentTime; + mCachedFPS = app.mFPS; + mCachedUpdateTime = app.mUpdateTime; + mCachedPhysicsUpdateTime = app.mPhysicsUpdateTime; + } + + int windowWidth, windowHeight; + glfwGetWindowSize(mWindow, &windowWidth, &windowHeight); + + int scrollarea = 2; + imguiBeginScrollArea("Profiling", 0, 0, + app.mWindowToFramebufferRatio.x * LEFT_PANE_WIDTH, + app.mWindowToFramebufferRatio.y * (windowHeight - LEFT_PANE_HEADER_HEIGHT), + &scrollarea); + + imguiVerticalSpace(15); + + // Framerate (FPS) + std::stringstream ss; + ss << std::setprecision(4) << mCachedFPS; + std::string fps = std::string("FPS : ") + ss.str(); + imguiItem(fps.c_str()); + + // Update time + std::stringstream ss1; + double updateTime = mCachedUpdateTime * 1000.0; + ss1 << std::setprecision(4) << updateTime; + std::string updateTimeStr = std::string("Update time (ms) : ") + ss1.str(); + imguiItem(updateTimeStr.c_str()); + + // Update time (physics) + std::stringstream ss2; + ss2 << std::setprecision(4) << (mCachedPhysicsUpdateTime * 1000.0); + std::string updatePhysicsTimeStr = std::string("Update physics time (ms) : ") + ss2.str(); + imguiItem(updatePhysicsTimeStr.c_str()); + + imguiEndScrollArea(); } // Display the GUI diff --git a/testbed/src/Gui.h b/testbed/src/Gui.h index 0b2183a7..52354eb1 100644 --- a/testbed/src/Gui.h +++ b/testbed/src/Gui.h @@ -35,9 +35,9 @@ // Constants const float GUI_SCALING = 2.0f; -const int HEADER_HEIGHT = 80; const int LEFT_PANE_WIDTH = 300; -const int LEFT_PANE_HEADER_HEIGHT = 50; +const int LEFT_PANE_HEADER_HEIGHT = 90; +const double TIME_INTERVAL_DISPLAY_PROFILING_INFO = 1.0; using namespace openglframework; @@ -64,7 +64,6 @@ class Gui { static bool g_MousePressed[3]; static float g_MouseWheel; static GLuint g_FontTexture; - //static int g_ShaderHandle, g_VertHandle, g_FragHandle; static int g_AttribLocationTex, g_AttribLocationProjMtx; static int g_AttribLocationPosition, g_AttribLocationUV, g_AttribLocationColor; static size_t g_VboSize; @@ -76,7 +75,6 @@ class Gui { // -------------------- Methods -------------------- // - static void displayHeader(); static void displayLeftPane(); /// Display the list of scenes @@ -88,6 +86,18 @@ class Gui { static void resetScroll(); + /// Current time (in seconds) from last profiling time display + static double mTimeSinceLastProfilingDisplay; + + /// Cached Framerate + static double mCachedFPS; + + /// Cached update time + static double mCachedUpdateTime; + + // Cached update physics time + static double mCachedPhysicsUpdateTime; + public : diff --git a/testbed/src/PhysicsEventListener.cpp b/testbed/src/PhysicsEventListener.cpp new file mode 100644 index 00000000..8d34b9b0 --- /dev/null +++ b/testbed/src/PhysicsEventListener.cpp @@ -0,0 +1,38 @@ + +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Libraries +#include "PhysicsEventListener.h" + +// Called when a new contact point is found between two bodies that were separated before +void PhysicsEventListener::beginContact(const rp3d::ContactPointInfo& contact) { + +} + +// Called when a new contact point is found between two bodies +void PhysicsEventListener::newContact(const rp3d::ContactPointInfo& contact) { + +} diff --git a/testbed/src/PhysicsEventListener.h b/testbed/src/PhysicsEventListener.h new file mode 100644 index 00000000..d9227feb --- /dev/null +++ b/testbed/src/PhysicsEventListener.h @@ -0,0 +1,66 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +#ifndef PHYSICSEVENTLISTENER_H +#define PHYSICSEVENTLISTENER_H + +// Libraries +#include "reactphysics3d.h" +#include "openglframework.h" + +// Structure ContactPoint +struct ContactPoint { + + public: + openglframework::Vector3 point; + + /// Constructor + ContactPoint(const openglframework::Vector3& contactPoint) : point(contactPoint) { + + } +}; + +// Class PhysicsEventListener +// This class inherits from the EventListener class +// of ReactPhysics3D in order to be notified of events +// that occured in a physics world +class PhysicsEventListener : rp3d::EventListener { + + private: + + // Current contact points + std::vector mCurrentContactPoints; + + public: + + /// Called when a new contact point is found between two bodies that were separated before + virtual void beginContact(const rp3d::ContactPointInfo& contact); + + /// Called when a new contact point is found between two bodies + virtual void newContact(const rp3d::ContactPointInfo& contact); +}; + +#endif + diff --git a/testbed/src/Scene.cpp b/testbed/src/Scene.cpp index ea64fc13..65ac681f 100644 --- a/testbed/src/Scene.cpp +++ b/testbed/src/Scene.cpp @@ -30,9 +30,9 @@ using namespace openglframework; // Constructor -Scene::Scene(const std::string& name) +Scene::Scene(const std::string& name, bool isShadowMappingEnabled) : mName(name), mInterpolationFactor(0.0f), mViewportX(0), mViewportY(0), - mViewportWidth(0), mViewportHeight(0) { + mViewportWidth(0), mViewportHeight(0), mIsShadowMappingEnabled(isShadowMappingEnabled) { } diff --git a/testbed/src/Scene.h b/testbed/src/Scene.h index d4e05892..a558f95b 100644 --- a/testbed/src/Scene.h +++ b/testbed/src/Scene.h @@ -28,6 +28,7 @@ // Libraries #include "openglframework.h" +#include "PhysicsEventListener.h" /// Structure EngineSettings /// This structure contains several physics engine parameters @@ -90,6 +91,9 @@ class Scene { /// Viewport x,y, width and height values int mViewportX, mViewportY, mViewportWidth, mViewportHeight; + /// True if the shadow mapping is enabled + bool mIsShadowMappingEnabled; + // -------------------- Methods -------------------- // /// Set the scene position (where the camera needs to look at) @@ -117,7 +121,7 @@ class Scene { // -------------------- Methods -------------------- // /// Constructor - Scene(const std::string& name); + Scene(const std::string& name, bool isShadowMappingEnabled = false); /// Destructor virtual ~Scene(); @@ -172,6 +176,15 @@ class Scene { /// Return the name of the scene std::string getName() const; + + /// Return true if the shadow mapping is enabled + bool getIsShadowMappingEnabled() const; + + /// Enabled/Disable the shadow mapping + void virtual setIsShadowMappingEnabled(bool isShadowMappingEnabled); + + /// Return all the contact points of the scene + std::vector virtual getContactPoints() const; }; // Called when a keyboard event occurs @@ -223,4 +236,21 @@ inline std::string Scene::getName() const { return mName; } +// Return true if the shadow mapping is enabled +inline bool Scene::getIsShadowMappingEnabled() const { + return mIsShadowMappingEnabled; +} + +// Enabled/Disable the shadow mapping +inline void Scene::setIsShadowMappingEnabled(bool isShadowMappingEnabled) { + mIsShadowMappingEnabled = isShadowMappingEnabled; +} + +// Return all the contact points of the scene +inline std::vector Scene::getContactPoints() const { + + // Return an empty list of contact points + return std::vector(); +} + #endif diff --git a/testbed/src/SceneDemo.cpp b/testbed/src/SceneDemo.cpp index 6a5ddfbe..d4c88503 100644 --- a/testbed/src/SceneDemo.cpp +++ b/testbed/src/SceneDemo.cpp @@ -32,8 +32,9 @@ using namespace openglframework; int SceneDemo::shadowMapTextureLevel = 0; // Constructor -SceneDemo::SceneDemo(const std::string& name, float sceneRadius) : Scene(name), - mLight0(0), mIsShadowMappingEnabled(true), mIsShadowMappingInitialized(false), +SceneDemo::SceneDemo(const std::string& name, float sceneRadius, bool isShadowMappingEnabled) + : Scene(name, isShadowMappingEnabled), + mLight0(0), mIsShadowMappingInitialized(false), mDepthShader("shaders/depth.vert", "shaders/depth.frag"), mPhongShader("shaders/phong.vert", "shaders/phong.frag"), mQuadShader("shaders/quad.vert", "shaders/quad.frag"), diff --git a/testbed/src/SceneDemo.h b/testbed/src/SceneDemo.h index 8893e26c..f8439431 100644 --- a/testbed/src/SceneDemo.h +++ b/testbed/src/SceneDemo.h @@ -30,8 +30,8 @@ #include "Scene.h" // Constants -const int SHADOWMAP_WIDTH = 2048; -const int SHADOWMAP_HEIGHT = 2048; +const int SHADOWMAP_WIDTH = 1024; +const int SHADOWMAP_HEIGHT = 1024; // Class SceneDemo // Abstract class that represents a 3D scene for the ReactPhysics3D examples. @@ -45,9 +45,6 @@ class SceneDemo : public Scene { /// Light 0 openglframework::Light mLight0; - /// True if the shadow mapping is enabled - bool mIsShadowMappingEnabled; - /// True if the shadows FBO, textures have been created bool mIsShadowMappingInitialized; @@ -96,7 +93,7 @@ class SceneDemo : public Scene { // -------------------- Methods -------------------- // /// Constructor - SceneDemo(const std::string& name, float sceneRadius); + SceneDemo(const std::string& name, float sceneRadius, bool isShadowMappingEnabled = true); /// Destructor virtual ~SceneDemo(); @@ -108,21 +105,14 @@ class SceneDemo : public Scene { virtual void renderSinglePass(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix)=0; - /// Return true if the shadow mapping is enabled - bool getIsShadowMappingEnabled() const; - /// Enabled/Disable the shadow mapping - void setIsShadowMappingEnabled(bool isShadowMappingEnabled); + void virtual setIsShadowMappingEnabled(bool isShadowMappingEnabled); }; -// Return true if the shadow mapping is enabled -inline bool SceneDemo::getIsShadowMappingEnabled() const { - return mIsShadowMappingEnabled; -} - // Enabled/Disable the shadow mapping inline void SceneDemo::setIsShadowMappingEnabled(bool isShadowMappingEnabled) { - mIsShadowMappingEnabled = isShadowMappingEnabled; + + Scene::setIsShadowMappingEnabled(isShadowMappingEnabled); if (mIsShadowMappingEnabled && !mIsShadowMappingInitialized) { createShadowMapFBOAndTexture(); diff --git a/testbed/src/TestbedApplication.cpp b/testbed/src/TestbedApplication.cpp index 6cbeb41a..973d648e 100644 --- a/testbed/src/TestbedApplication.cpp +++ b/testbed/src/TestbedApplication.cpp @@ -50,7 +50,9 @@ TestbedApplication& TestbedApplication::getInstance() { } // Constructor -TestbedApplication::TestbedApplication() : mFPS(0), mNbFrames(0), mPreviousTime(0) { +TestbedApplication::TestbedApplication() + : mFPS(0), mNbFrames(0), mPreviousTime(0), + mUpdateTime(0), mPhysicsUpdateTime(0) { mCurrentScene = NULL; mIsMultisamplingActive = true; @@ -59,6 +61,8 @@ TestbedApplication::TestbedApplication() : mFPS(0), mNbFrames(0), mPreviousTime( mSinglePhysicsStepEnabled = false; mSinglePhysicsStepDone = false; mWindowToFramebufferRatio = Vector2(1, 1); + mIsShadowMappingEnabled = true; + mIsVSyncEnabled = true; } // Destructor @@ -107,8 +111,8 @@ void TestbedApplication::init() { } glfwMakeContextCurrent(mWindow); - // Disable Vertical Synchronization - glfwSwapInterval(0); + // Vertical Synchronization + enableVSync(mIsVSyncEnabled); // Initialize the GLEW library glewExperimental = GL_TRUE; @@ -214,6 +218,8 @@ void TestbedApplication::updatePhysics() { void TestbedApplication::update() { + double currentTime = glfwGetTime(); + // Update the physics if (mSinglePhysicsStepEnabled && !mSinglePhysicsStepDone) { updateSinglePhysicsStep(); @@ -223,6 +229,9 @@ void TestbedApplication::update() { updatePhysics(); } + // Compute the physics update time + mPhysicsUpdateTime = glfwGetTime() - currentTime; + // Compute the interpolation factor float factor = mTimer.computeInterpolationFactor(mEngineSettings.timeStep); assert(factor >= 0.0f && factor <= 1.0f); @@ -230,11 +239,11 @@ void TestbedApplication::update() { // Notify the scene about the interpolation factor mCurrentScene->setInterpolationFactor(factor); + // Enable/Disable shadow mapping + mCurrentScene->setIsShadowMappingEnabled(mIsShadowMappingEnabled); + // Update the scene mCurrentScene->update(); - - // Compute the current framerate - //application->computeFPS(); } // Render @@ -254,7 +263,7 @@ void TestbedApplication::render() { mCurrentScene->setViewport(mWindowToFramebufferRatio.x * LEFT_PANE_WIDTH, 0, bufferWidth - mWindowToFramebufferRatio.x * LEFT_PANE_WIDTH, - bufferHeight - mWindowToFramebufferRatio.y * HEADER_HEIGHT); + bufferHeight); // Render the scene mCurrentScene->render(); @@ -274,7 +283,7 @@ void TestbedApplication::reshape() { glfwGetFramebufferSize(mWindow, &width, &height); // Resize the camera viewport - mCurrentScene->reshape(width - LEFT_PANE_WIDTH, height - HEADER_HEIGHT); + mCurrentScene->reshape(width - LEFT_PANE_WIDTH, height); // Update the window size of the scene int windowWidth, windowHeight; @@ -305,6 +314,9 @@ void TestbedApplication::startMainLoop() { // Process events glfwPollEvents(); + // Compute the current framerate + computeFPS(); + checkOpenGLErrors(); } } @@ -355,17 +367,19 @@ void TestbedApplication::computeFPS() { mNbFrames++; - // Get the number of milliseconds since glutInit called + // Get the number of seconds since start mCurrentTime = glfwGetTime(); // Calculate time passed - double timeInterval = mCurrentTime - mPreviousTime; + mUpdateTime = mCurrentTime - mPreviousTime; + double timeInterval = mUpdateTime * 1000.0; // Update the FPS counter each second - if(timeInterval > 1.0) { + if(timeInterval > 0.0001) { // calculate the number of frames per second mFPS = static_cast(mNbFrames) / timeInterval; + mFPS *= 1000.0; // Set time mPreviousTime = mCurrentTime; diff --git a/testbed/src/TestbedApplication.h b/testbed/src/TestbedApplication.h index 1c2d22c0..75d14918 100644 --- a/testbed/src/TestbedApplication.h +++ b/testbed/src/TestbedApplication.h @@ -69,12 +69,18 @@ class TestbedApplication { /// Number of frames during the last second int mNbFrames; - /// Current time for fps computation + /// Current time for fps computation (in seconds) double mCurrentTime; - /// Previous time for fps computation + /// Previous time for fps computation (in seconds) double mPreviousTime; + /// Update time (in seconds) + double mUpdateTime; + + /// Physics update time (in seconds) + double mPhysicsUpdateTime; + /// True if multisampling is active bool mIsMultisamplingActive; @@ -89,6 +95,12 @@ class TestbedApplication { openglframework::Vector2 mWindowToFramebufferRatio; + /// True if shadow mapping is enabled + bool mIsShadowMappingEnabled; + + /// True if vsync is enabled + bool mIsVSyncEnabled; + // -------------------- Methods -------------------- // /// Private constructor (for the singleton class) @@ -160,6 +172,9 @@ class TestbedApplication { /// Set the variable to know if we need to take a single physics step void toggleTakeSinglePhysicsStep(); + /// Enable/Disable shadow mapping + void enableShadows(bool enable); + public : // -------------------- Methods -------------------- // @@ -179,6 +194,9 @@ class TestbedApplication { /// Change the current scene void switchScene(Scene* newScene); + /// Enable/Disable Vertical synchronization + void enableVSync(bool enable); + // -------------------- Friendship -------------------- // friend class Gui; @@ -216,4 +234,20 @@ inline void TestbedApplication::toggleTakeSinglePhysicsStep() { } } +// Enable/Disable shadow mapping +inline void TestbedApplication::enableShadows(bool enable) { + mIsShadowMappingEnabled = enable; +} + +// Enable/Disable Vertical synchronization +inline void TestbedApplication::enableVSync(bool enable) { + mIsVSyncEnabled = enable; + if (mIsVSyncEnabled) { + glfwSwapInterval(1); + } + else { + glfwSwapInterval(0); + } +} + #endif From 047f612c3735aa3ceab1951057c757503907a83c Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Sat, 8 Aug 2015 11:40:37 +0200 Subject: [PATCH 27/36] Refactoring and adding colors to the testbed application --- testbed/CMakeLists.txt | 2 + testbed/common/Box.cpp | 41 ++------ testbed/common/Box.h | 42 ++------ testbed/common/Capsule.cpp | 49 +++------- testbed/common/Capsule.h | 32 ++----- testbed/common/Cone.cpp | 50 +++------- testbed/common/Cone.h | 32 ++----- testbed/common/ConvexMesh.cpp | 47 +++------ testbed/common/ConvexMesh.h | 32 ++----- testbed/common/Cylinder.cpp | 49 +++------- testbed/common/Cylinder.h | 32 ++----- testbed/common/Dumbbell.cpp | 35 ++----- testbed/common/Dumbbell.h | 32 ++----- testbed/common/PhysicsObject.cpp | 59 ++++++++++++ testbed/common/PhysicsObject.h | 96 +++++++++++++++++++ testbed/common/Sphere.cpp | 47 +++------ testbed/common/Sphere.h | 32 ++----- testbed/common/VisualContactPoint.cpp | 7 +- testbed/opengl-framework/src/Mesh.h | 8 +- .../collisionshapes/CollisionShapesScene.cpp | 33 ++++++- .../collisionshapes/CollisionShapesScene.h | 12 +-- testbed/scenes/cubes/CubesScene.cpp | 17 ++-- testbed/scenes/cubes/CubesScene.h | 2 +- testbed/scenes/joints/JointsScene.cpp | 29 +++++- testbed/scenes/raycast/RaycastScene.cpp | 28 ++++++ testbed/shaders/phong.frag | 11 +-- testbed/src/Gui.h | 2 +- testbed/src/SceneDemo.cpp | 23 +++-- testbed/src/SceneDemo.h | 12 ++- 29 files changed, 434 insertions(+), 459 deletions(-) create mode 100644 testbed/common/PhysicsObject.cpp create mode 100644 testbed/common/PhysicsObject.h diff --git a/testbed/CMakeLists.txt b/testbed/CMakeLists.txt index 9f6ed161..1696484d 100644 --- a/testbed/CMakeLists.txt +++ b/testbed/CMakeLists.txt @@ -74,6 +74,8 @@ SET(COMMON_SOURCES common/Cylinder.cpp common/Dumbbell.h common/Dumbbell.cpp + common/PhysicsObject.h + common/PhysicsObject.cpp common/VisualContactPoint.h common/VisualContactPoint.cpp ) diff --git a/testbed/common/Box.cpp b/testbed/common/Box.cpp index cc97b04e..1111f083 100644 --- a/testbed/common/Box.cpp +++ b/testbed/common/Box.cpp @@ -113,7 +113,7 @@ GLfloat Box::mCubeNormals[108] = { // Constructor Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &position, reactphysics3d::CollisionWorld* world) - : openglframework::Object3D(), mColor(0.01f, 0.62f, 0.39f, 1.0f) { + : openglframework::Object3D() { // Initialize the size of the box mSize[0] = size.x * 0.5f; @@ -142,10 +142,10 @@ Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &p mPreviousTransform = transform; // Create a rigid body in the dynamics world - mRigidBody = world->createCollisionBody(transform); + mBody = world->createCollisionBody(transform); // Add the collision shape to the body - mRigidBody->addCollisionShape(collisionShape, rp3d::Transform::identity()); + mBody->addCollisionShape(collisionShape, rp3d::Transform::identity()); // If the Vertex Buffer object has not been created yet if (totalNbBoxes == 0) { @@ -162,7 +162,7 @@ Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &p // Constructor Box::Box(const openglframework::Vector3& size, const openglframework::Vector3& position, float mass, reactphysics3d::DynamicsWorld* world) - : openglframework::Object3D(), mColor(0.01f, 0.62f, 0.39f, 1.0f) { + : openglframework::Object3D() { // Initialize the size of the box mSize[0] = size.x * 0.5f; @@ -194,7 +194,7 @@ Box::Box(const openglframework::Vector3& size, const openglframework::Vector3& p // Add the collision shape to the body body->addCollisionShape(collisionShape, rp3d::Transform::identity(), mass); - mRigidBody = body; + mBody = body; // If the Vertex Buffer object has not been created yet if (totalNbBoxes == 0) { @@ -246,7 +246,8 @@ void Box::render(openglframework::Shader& shader, shader.setMatrix3x3Uniform("normalMatrix", normalMatrix, false); // Set the vertex color - openglframework::Vector4 color(mColor.r, mColor.g, mColor.b, mColor.a); + openglframework::Color currentColor = mBody->isSleeping() ? mSleepingColor : mColor; + openglframework::Vector4 color(currentColor.r, currentColor.g, currentColor.b, currentColor.a); shader.setVector4Uniform("vertexColor", color, false); // Get the location of shader attribute variables @@ -277,29 +278,7 @@ void Box::render(openglframework::Shader& shader, shader.unbind(); } -// Update the transform matrix of the box -void Box::updateTransform(float interpolationFactor) { - // Get the transform of the rigid body - rp3d::Transform transform = mRigidBody->getTransform(); - - // Interpolate the transform between the previous one and the new one - rp3d::Transform interpolatedTransform = rp3d::Transform::interpolateTransforms(mPreviousTransform, - transform, - interpolationFactor); - mPreviousTransform = transform; - - // Compute the transform used for rendering the box - rp3d::decimal matrix[16]; - interpolatedTransform.getOpenGLMatrix(matrix); - openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12], - matrix[1], matrix[5], matrix[9], matrix[13], - matrix[2], matrix[6], matrix[10], matrix[14], - matrix[3], matrix[7], matrix[11], matrix[15]); - - // Apply the scaling matrix to have the correct box dimensions - mTransformMatrix = newMatrix * mScalingMatrix; -} // Create the Vertex Buffer Objects used to render to box with OpenGL. /// We create two VBOs (one for vertices and one for indices) to render all the boxes @@ -336,12 +315,12 @@ void Box::createVBOAndVAO() { void Box::resetTransform(const rp3d::Transform& transform) { // Reset the transform - mRigidBody->setTransform(transform); + mBody->setTransform(transform); - mRigidBody->setIsSleeping(false); + mBody->setIsSleeping(false); // Reset the velocity of the rigid body - rp3d::RigidBody* rigidBody = dynamic_cast(mRigidBody); + rp3d::RigidBody* rigidBody = dynamic_cast(mBody); if (rigidBody != NULL) { rigidBody->setLinearVelocity(rp3d::Vector3(0, 0, 0)); rigidBody->setAngularVelocity(rp3d::Vector3(0, 0, 0)); diff --git a/testbed/common/Box.h b/testbed/common/Box.h index 90d4a203..a879c92a 100644 --- a/testbed/common/Box.h +++ b/testbed/common/Box.h @@ -29,9 +29,10 @@ // Libraries #include "openglframework.h" #include "reactphysics3d.h" +#include "PhysicsObject.h" // Class Box -class Box : public openglframework::Object3D { +class Box : public openglframework::Object3D, public PhysicsObject { private : @@ -40,12 +41,6 @@ class Box : public openglframework::Object3D { /// Size of each side of the box float mSize[3]; - /// Rigid body used to simulate the dynamics of the box - rp3d::CollisionBody* mRigidBody; - - /// Previous transform of the body (for interpolation) - rp3d::Transform mPreviousTransform; - /// Scaling matrix (applied to a cube to obtain the correct box dimensions) openglframework::Matrix4 mScalingMatrix; @@ -67,9 +62,6 @@ class Box : public openglframework::Object3D { /// Total number of boxes created static int totalNbBoxes; - /// Main color of the box - openglframework::Color mColor; - // -------------------- Methods -------------------- // /// Create a the VAO and VBOs to render to box with OpenGL @@ -90,38 +82,20 @@ class Box : public openglframework::Object3D { /// Destructor ~Box(); - /// Return a pointer to the collision body of the box - reactphysics3d::CollisionBody* getCollisionBody(); - - /// Return a pointer to the rigid body of the box - reactphysics3d::RigidBody* getRigidBody(); - - /// Update the transform matrix of the box - void updateTransform(float interpolationFactor); - /// Render the cube at the correct position and with the correct orientation void render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix); - /// Set the color of the box - void setColor(const openglframework::Color& color); - /// Set the position of the box void resetTransform(const rp3d::Transform& transform); + + /// Update the transform matrix of the object + virtual void updateTransform(float interpolationFactor); }; -// Return a pointer to the collision body of the box -inline rp3d::CollisionBody* Box::getCollisionBody() { - return mRigidBody; +// Update the transform matrix of the object +inline void Box::updateTransform(float interpolationFactor) { + mTransformMatrix = computeTransform(interpolationFactor, mScalingMatrix); } -// Return a pointer to the rigid body of the box -inline rp3d::RigidBody* Box::getRigidBody() { - return dynamic_cast(mRigidBody); -} - -// Set the color of the box -inline void Box::setColor(const openglframework::Color& color) { - mColor = color; -} #endif diff --git a/testbed/common/Capsule.cpp b/testbed/common/Capsule.cpp index a97f0ea4..b65146d4 100644 --- a/testbed/common/Capsule.cpp +++ b/testbed/common/Capsule.cpp @@ -67,10 +67,10 @@ Capsule::Capsule(float radius, float height, const openglframework::Vector3& pos mPreviousTransform = transform; // Create a rigid body corresponding in the dynamics world - mRigidBody = world->createCollisionBody(transform); + mBody = world->createCollisionBody(transform); // Add a collision shape to the body and specify the mass of the shape - mRigidBody->addCollisionShape(collisionShape, rp3d::Transform::identity()); + mBody->addCollisionShape(collisionShape, rp3d::Transform::identity()); mTransformMatrix = mTransformMatrix * mScalingMatrix; @@ -86,8 +86,7 @@ Capsule::Capsule(float radius, float height, const openglframework::Vector3& pos Capsule::Capsule(float radius, float height, const openglframework::Vector3& position, float mass, reactphysics3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath) - : openglframework::Mesh(), mRadius(radius), mHeight(height), - mColor(0.5f, 0.5f, 0.5f, 1.0f) { + : openglframework::Mesh(), mRadius(radius), mHeight(height) { // Load the mesh from a file openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "capsule.obj", *this); @@ -120,7 +119,7 @@ Capsule::Capsule(float radius, float height, const openglframework::Vector3& pos // Add a collision shape to the body and specify the mass of the shape body->addCollisionShape(collisionShape, rp3d::Transform::identity(), mass); - mRigidBody = body; + mBody = body; mTransformMatrix = mTransformMatrix * mScalingMatrix; @@ -170,7 +169,8 @@ void Capsule::render(openglframework::Shader& shader, shader.setMatrix3x3Uniform("normalMatrix", normalMatrix, false); // Set the vertex color - openglframework::Vector4 color(mColor.r, mColor.g, mColor.b, mColor.a); + openglframework::Color currentColor = mBody->isSleeping() ? mSleepingColor : mColor; + openglframework::Vector4 color(currentColor.r, currentColor.g, currentColor.b, currentColor.a); shader.setVector4Uniform("vertexColor", color, false); // Bind the VAO @@ -183,10 +183,12 @@ void Capsule::render(openglframework::Shader& shader, GLint vertexNormalLoc = shader.getAttribLocation("vertexNormal", false); glEnableVertexAttribArray(vertexPositionLoc); - if (vertexNormalLoc != -1) glEnableVertexAttribArray(vertexNormalLoc); - glVertexAttribPointer(vertexPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL); + + mVBONormals.bind(); + if (vertexNormalLoc != -1) glVertexAttribPointer(vertexNormalLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL); + if (vertexNormalLoc != -1) glEnableVertexAttribArray(vertexNormalLoc); // For each part of the mesh for (unsigned int i=0; igetTransform(); - - // Interpolate the transform between the previous one and the new one - rp3d::Transform interpolatedTransform = rp3d::Transform::interpolateTransforms(mPreviousTransform, - transform, - interpolationFactor); - mPreviousTransform = transform; - - // Compute the transform used for rendering the sphere - rp3d::decimal matrix[16]; - interpolatedTransform.getOpenGLMatrix(matrix); - openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12], - matrix[1], matrix[5], matrix[9], matrix[13], - matrix[2], matrix[6], matrix[10], matrix[14], - matrix[3], matrix[7], matrix[11], matrix[15]); - - // Apply the scaling matrix to have the correct sphere dimensions - mTransformMatrix = newMatrix * mScalingMatrix; -} - // Create the Vertex Buffer Objects used to render with OpenGL. /// We create two VBOs (one for vertices and one for indices) void Capsule::createVBOAndVAO() { @@ -289,12 +268,12 @@ void Capsule::createVBOAndVAO() { void Capsule::resetTransform(const rp3d::Transform& transform) { // Reset the transform - mRigidBody->setTransform(transform); + mBody->setTransform(transform); - mRigidBody->setIsSleeping(false); + mBody->setIsSleeping(false); // Reset the velocity of the rigid body - rp3d::RigidBody* rigidBody = dynamic_cast(mRigidBody); + rp3d::RigidBody* rigidBody = dynamic_cast(mBody); if (rigidBody != NULL) { rigidBody->setLinearVelocity(rp3d::Vector3(0, 0, 0)); rigidBody->setAngularVelocity(rp3d::Vector3(0, 0, 0)); diff --git a/testbed/common/Capsule.h b/testbed/common/Capsule.h index de9f610e..c1a37779 100644 --- a/testbed/common/Capsule.h +++ b/testbed/common/Capsule.h @@ -29,9 +29,10 @@ // Libraries #include "openglframework.h" #include "reactphysics3d.h" +#include "PhysicsObject.h" // Class Sphere -class Capsule : public openglframework::Mesh { +class Capsule : public openglframework::Mesh, public PhysicsObject { private : @@ -43,9 +44,6 @@ class Capsule : public openglframework::Mesh { /// Height of the capsule float mHeight; - /// Rigid body used to simulate the dynamics of the sphere - rp3d::CollisionBody* mRigidBody; - /// Scaling matrix (applied to a sphere to obtain the correct sphere dimensions) openglframework::Matrix4 mScalingMatrix; @@ -70,9 +68,6 @@ class Capsule : public openglframework::Mesh { // Total number of capsules created static int totalNbCapsules; - /// Color - openglframework::Color mColor; - // -------------------- Methods -------------------- // // Create the Vertex Buffer Objects used to render with OpenGL. @@ -94,31 +89,20 @@ class Capsule : public openglframework::Mesh { /// Destructor ~Capsule(); - /// Return a pointer to the collision body of the box - reactphysics3d::CollisionBody* getCollisionBody(); - - /// Return a pointer to the rigid body of the box - reactphysics3d::RigidBody* getRigidBody(); - - /// Update the transform matrix of the sphere - void updateTransform(float interpolationFactor); - /// Render the sphere at the correct position and with the correct orientation void render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix); /// Set the position of the box void resetTransform(const rp3d::Transform& transform); + + /// Update the transform matrix of the object + virtual void updateTransform(float interpolationFactor); }; -// Return a pointer to the collision body of the box -inline rp3d::CollisionBody* Capsule::getCollisionBody() { - return mRigidBody; -} - -// Return a pointer to the rigid body of the box -inline rp3d::RigidBody* Capsule::getRigidBody() { - return dynamic_cast(mRigidBody); +// Update the transform matrix of the object +inline void Capsule::updateTransform(float interpolationFactor) { + mTransformMatrix = computeTransform(interpolationFactor, mScalingMatrix); } #endif diff --git a/testbed/common/Cone.cpp b/testbed/common/Cone.cpp index 88ffdf8c..6657ed9d 100644 --- a/testbed/common/Cone.cpp +++ b/testbed/common/Cone.cpp @@ -37,8 +37,7 @@ int Cone::totalNbCones = 0; Cone::Cone(float radius, float height, const openglframework::Vector3 &position, reactphysics3d::CollisionWorld* world, const std::string& meshFolderPath) - : openglframework::Mesh(), mRadius(radius), mHeight(height), - mColor(0.5f, 0.5f, 0.5f, 1.0f) { + : openglframework::Mesh(), mRadius(radius), mHeight(height) { // Load the mesh from a file openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "cone.obj", *this); @@ -68,10 +67,10 @@ Cone::Cone(float radius, float height, const openglframework::Vector3 &position, mPreviousTransform = transform; // Create a rigid body corresponding to the cone in the dynamics world - mRigidBody = world->createCollisionBody(transform); + mBody = world->createCollisionBody(transform); // Add a collision shape to the body and specify the mass of the shape - mRigidBody->addCollisionShape(collisionShape, rp3d::Transform::identity()); + mBody->addCollisionShape(collisionShape, rp3d::Transform::identity()); mTransformMatrix = mTransformMatrix * mScalingMatrix; @@ -87,8 +86,7 @@ Cone::Cone(float radius, float height, const openglframework::Vector3 &position, Cone::Cone(float radius, float height, const openglframework::Vector3 &position, float mass, reactphysics3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath) - : openglframework::Mesh(), mRadius(radius), mHeight(height), - mColor(0.5f, 0.5f, 0.5f, 1.0f) { + : openglframework::Mesh(), mRadius(radius), mHeight(height) { // Load the mesh from a file openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "cone.obj", *this); @@ -121,7 +119,7 @@ Cone::Cone(float radius, float height, const openglframework::Vector3 &position, // Add a collision shape to the body and specify the mass of the shape body->addCollisionShape(collisionShape, rp3d::Transform::identity(), mass); - mRigidBody = body; + mBody = body; mTransformMatrix = mTransformMatrix * mScalingMatrix; @@ -183,10 +181,12 @@ void Cone::render(openglframework::Shader& shader, GLint vertexNormalLoc = shader.getAttribLocation("vertexNormal", false); glEnableVertexAttribArray(vertexPositionLoc); - if (vertexNormalLoc != -1) glEnableVertexAttribArray(vertexNormalLoc); - glVertexAttribPointer(vertexPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL); + + mVBONormals.bind(); + if (vertexNormalLoc != -1) glVertexAttribPointer(vertexNormalLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL); + if (vertexNormalLoc != -1) glEnableVertexAttribArray(vertexNormalLoc); // For each part of the mesh for (unsigned int i=0; igetTransform(); - - // Interpolate the transform between the previous one and the new one - rp3d::Transform interpolatedTransform = rp3d::Transform::interpolateTransforms(mPreviousTransform, - transform, - interpolationFactor); - - mPreviousTransform = transform; - - // Compute the transform used for rendering the cone - rp3d::decimal matrix[16]; - interpolatedTransform.getOpenGLMatrix(matrix); - openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12], - matrix[1], matrix[5], matrix[9], matrix[13], - matrix[2], matrix[6], matrix[10], matrix[14], - matrix[3], matrix[7], matrix[11], matrix[15]); - - // Apply the scaling matrix to have the correct cone dimensions - mTransformMatrix = newMatrix * mScalingMatrix; -} - // Create the Vertex Buffer Objects used to render with OpenGL. /// We create two VBOs (one for vertices and one for indices) void Cone::createVBOAndVAO() { @@ -290,12 +266,12 @@ void Cone::createVBOAndVAO() { void Cone::resetTransform(const rp3d::Transform& transform) { // Reset the transform - mRigidBody->setTransform(transform); + mBody->setTransform(transform); - mRigidBody->setIsSleeping(false); + mBody->setIsSleeping(false); // Reset the velocity of the rigid body - rp3d::RigidBody* rigidBody = dynamic_cast(mRigidBody); + rp3d::RigidBody* rigidBody = dynamic_cast(mBody); if (rigidBody != NULL) { rigidBody->setLinearVelocity(rp3d::Vector3(0, 0, 0)); rigidBody->setAngularVelocity(rp3d::Vector3(0, 0, 0)); diff --git a/testbed/common/Cone.h b/testbed/common/Cone.h index a2cb113a..1d256752 100644 --- a/testbed/common/Cone.h +++ b/testbed/common/Cone.h @@ -29,9 +29,10 @@ // Libraries #include "openglframework.h" #include "reactphysics3d.h" +#include "PhysicsObject.h" // Class Cone -class Cone : public openglframework::Mesh { +class Cone : public openglframework::Mesh, public PhysicsObject { private : @@ -43,9 +44,6 @@ class Cone : public openglframework::Mesh { /// Height of the cone float mHeight; - /// Rigid body used to simulate the dynamics of the cone - rp3d::CollisionBody* mRigidBody; - /// Scaling matrix (applied to a sphere to obtain the correct cone dimensions) openglframework::Matrix4 mScalingMatrix; @@ -70,9 +68,6 @@ class Cone : public openglframework::Mesh { // Total number of cones created static int totalNbCones; - /// Color - openglframework::Color mColor; - // -------------------- Methods -------------------- // // Create the Vertex Buffer Objects used to render with OpenGL. @@ -93,31 +88,20 @@ class Cone : public openglframework::Mesh { /// Destructor ~Cone(); - /// Return a pointer to the collision body of the box - reactphysics3d::CollisionBody* getCollisionBody(); - - /// Return a pointer to the rigid body of the box - reactphysics3d::RigidBody* getRigidBody(); - - /// Update the transform matrix of the cone - void updateTransform(float interpolationFactor); - /// Render the cone at the correct position and with the correct orientation void render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix); /// Set the position of the box void resetTransform(const rp3d::Transform& transform); + + /// Update the transform matrix of the object + virtual void updateTransform(float interpolationFactor); }; -// Return a pointer to the collision body of the box -inline rp3d::CollisionBody* Cone::getCollisionBody() { - return mRigidBody; -} - -// Return a pointer to the rigid body of the box -inline rp3d::RigidBody* Cone::getRigidBody() { - return dynamic_cast(mRigidBody); +// Update the transform matrix of the object +inline void Cone::updateTransform(float interpolationFactor) { + mTransformMatrix = computeTransform(interpolationFactor, mScalingMatrix); } #endif diff --git a/testbed/common/ConvexMesh.cpp b/testbed/common/ConvexMesh.cpp index f6810269..cd766e5a 100644 --- a/testbed/common/ConvexMesh.cpp +++ b/testbed/common/ConvexMesh.cpp @@ -32,7 +32,7 @@ ConvexMesh::ConvexMesh(const openglframework::Vector3 &position, const std::string& meshFolderPath) : openglframework::Mesh(), mVBOVertices(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER), - mVBOIndices(GL_ELEMENT_ARRAY_BUFFER), mColor(0.5f, 0.5f, 0.5f, 1.0f) { + mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) { // Load the mesh from a file openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "convexmesh.obj", *this); @@ -84,10 +84,10 @@ ConvexMesh::ConvexMesh(const openglframework::Vector3 &position, mPreviousTransform = transform; // Create a rigid body corresponding to the sphere in the dynamics world - mRigidBody = world->createCollisionBody(transform); + mBody = world->createCollisionBody(transform); // Add a collision shape to the body and specify the mass of the collision shape - mRigidBody->addCollisionShape(collisionShape, rp3d::Transform::identity()); + mBody->addCollisionShape(collisionShape, rp3d::Transform::identity()); // Create the VBOs and VAO createVBOAndVAO(); @@ -99,7 +99,7 @@ ConvexMesh::ConvexMesh(const openglframework::Vector3 &position, float mass, const std::string& meshFolderPath) : openglframework::Mesh(), mVBOVertices(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER), - mVBOIndices(GL_ELEMENT_ARRAY_BUFFER), mColor(0.5f, 0.5f, 0.5f, 1.0f) { + mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) { // Load the mesh from a file openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "convexmesh.obj", *this); @@ -153,7 +153,7 @@ ConvexMesh::ConvexMesh(const openglframework::Vector3 &position, float mass, // Add a collision shape to the body and specify the mass of the collision shape body->addCollisionShape(collisionShape, rp3d::Transform::identity(), mass); - mRigidBody = body; + mBody = body; // Create the VBOs and VAO createVBOAndVAO(); @@ -205,10 +205,12 @@ void ConvexMesh::render(openglframework::Shader& shader, GLint vertexNormalLoc = shader.getAttribLocation("vertexNormal", false); glEnableVertexAttribArray(vertexPositionLoc); - if (vertexNormalLoc != -1) glEnableVertexAttribArray(vertexNormalLoc); - glVertexAttribPointer(vertexPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL); + + mVBONormals.bind(); + if (vertexNormalLoc != -1) glVertexAttribPointer(vertexNormalLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL); + if (vertexNormalLoc != -1) glEnableVertexAttribArray(vertexNormalLoc); // For each part of the mesh for (unsigned int i=0; igetTransform(); - - // Interpolate the transform between the previous one and the new one - rp3d::Transform interpolatedTransform = rp3d::Transform::interpolateTransforms(mPreviousTransform, - transform, - interpolationFactor); - mPreviousTransform = transform; - - // Compute the transform used for rendering the sphere - rp3d::decimal matrix[16]; - interpolatedTransform.getOpenGLMatrix(matrix); - openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12], - matrix[1], matrix[5], matrix[9], matrix[13], - matrix[2], matrix[6], matrix[10], matrix[14], - matrix[3], matrix[7], matrix[11], matrix[15]); - - // Apply the scaling matrix to have the correct sphere dimensions - mTransformMatrix = newMatrix; -} - // Create the Vertex Buffer Objects used to render with OpenGL. /// We create two VBOs (one for vertices and one for indices) void ConvexMesh::createVBOAndVAO() { @@ -311,12 +290,12 @@ void ConvexMesh::createVBOAndVAO() { void ConvexMesh::resetTransform(const rp3d::Transform& transform) { // Reset the transform - mRigidBody->setTransform(transform); + mBody->setTransform(transform); - mRigidBody->setIsSleeping(false); + mBody->setIsSleeping(false); // Reset the velocity of the rigid body - rp3d::RigidBody* rigidBody = dynamic_cast(mRigidBody); + rp3d::RigidBody* rigidBody = dynamic_cast(mBody); if (rigidBody != NULL) { rigidBody->setLinearVelocity(rp3d::Vector3(0, 0, 0)); rigidBody->setAngularVelocity(rp3d::Vector3(0, 0, 0)); diff --git a/testbed/common/ConvexMesh.h b/testbed/common/ConvexMesh.h index b201e1ab..4a4cdcdb 100644 --- a/testbed/common/ConvexMesh.h +++ b/testbed/common/ConvexMesh.h @@ -29,17 +29,15 @@ // Libraries #include "openglframework.h" #include "reactphysics3d.h" +#include "PhysicsObject.h" // Class ConvexMesh -class ConvexMesh : public openglframework::Mesh { +class ConvexMesh : public openglframework::Mesh, public PhysicsObject { private : // -------------------- Attributes -------------------- // - /// Rigid body used to simulate the dynamics of the mesh - rp3d::CollisionBody* mRigidBody; - /// Previous transform (for interpolation) rp3d::Transform mPreviousTransform; @@ -58,9 +56,6 @@ class ConvexMesh : public openglframework::Mesh { /// Vertex Array Object for the vertex data openglframework::VertexArrayObject mVAO; - /// Color - openglframework::Color mColor; - // -------------------- Methods -------------------- // // Create the Vertex Buffer Objects used to render with OpenGL. @@ -81,31 +76,20 @@ class ConvexMesh : public openglframework::Mesh { /// Destructor ~ConvexMesh(); - /// Return a pointer to the collision body of the box - reactphysics3d::CollisionBody* getCollisionBody(); - - /// Return a pointer to the rigid body of the box - reactphysics3d::RigidBody* getRigidBody(); - - /// Update the transform matrix of the mesh - void updateTransform(float interpolationFactor); - /// Render the mesh at the correct position and with the correct orientation void render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix); /// Set the position of the box void resetTransform(const rp3d::Transform& transform); + + /// Update the transform matrix of the object + virtual void updateTransform(float interpolationFactor); }; -// Return a pointer to the collision body of the box -inline rp3d::CollisionBody* ConvexMesh::getCollisionBody() { - return mRigidBody; -} - -// Return a pointer to the rigid body of the box -inline rp3d::RigidBody* ConvexMesh::getRigidBody() { - return dynamic_cast(mRigidBody); +// Update the transform matrix of the object +inline void ConvexMesh::updateTransform(float interpolationFactor) { + mTransformMatrix = computeTransform(interpolationFactor, openglframework::Matrix4::identity()); } #endif diff --git a/testbed/common/Cylinder.cpp b/testbed/common/Cylinder.cpp index 0c2fe1fd..2aa45923 100644 --- a/testbed/common/Cylinder.cpp +++ b/testbed/common/Cylinder.cpp @@ -37,8 +37,7 @@ int Cylinder::totalNbCylinders = 0; Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& position, reactphysics3d::CollisionWorld* world, const std::string& meshFolderPath) - : openglframework::Mesh(), mRadius(radius), mHeight(height), - mColor(0.5f, 0.5f, 0.5f, 1.0f) { + : openglframework::Mesh(), mRadius(radius), mHeight(height) { // Load the mesh from a file openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "cylinder.obj", *this); @@ -68,10 +67,10 @@ Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& p mPreviousTransform = transform; // Create a rigid body corresponding to the cylinder in the dynamics world - mRigidBody = world->createCollisionBody(transform); + mBody = world->createCollisionBody(transform); // Add a collision shape to the body and specify the mass of the shape - mRigidBody->addCollisionShape(collisionShape, rp3d::Transform::identity()); + mBody->addCollisionShape(collisionShape, rp3d::Transform::identity()); mTransformMatrix = mTransformMatrix * mScalingMatrix; @@ -87,8 +86,7 @@ Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& p Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& position, float mass, reactphysics3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath) - : openglframework::Mesh(), mRadius(radius), mHeight(height), - mColor(0.5f, 0.5f, 0.5f, 1.0f) { + : openglframework::Mesh(), mRadius(radius), mHeight(height) { // Load the mesh from a file openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "cylinder.obj", *this); @@ -123,7 +121,7 @@ Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& p mTransformMatrix = mTransformMatrix * mScalingMatrix; - mRigidBody = body; + mBody = body; // Create the VBOs and VAO if (totalNbCylinders == 0) { @@ -184,10 +182,12 @@ void Cylinder::render(openglframework::Shader& shader, GLint vertexNormalLoc = shader.getAttribLocation("vertexNormal", false); glEnableVertexAttribArray(vertexPositionLoc); - if (vertexNormalLoc != -1) glEnableVertexAttribArray(vertexNormalLoc); - glVertexAttribPointer(vertexPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL); + + mVBONormals.bind(); + if (vertexNormalLoc != -1) glVertexAttribPointer(vertexNormalLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL); + if (vertexNormalLoc != -1) glEnableVertexAttribArray(vertexNormalLoc); // For each part of the mesh for (unsigned int i=0; igetTransform(); - - // Interpolate the transform between the previous one and the new one - rp3d::Transform interpolatedTransform = rp3d::Transform::interpolateTransforms(mPreviousTransform, - transform, - interpolationFactor); - mPreviousTransform = transform; - - // Compute the transform used for rendering the cylinder - rp3d::decimal matrix[16]; - interpolatedTransform.getOpenGLMatrix(matrix); - openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12], - matrix[1], matrix[5], matrix[9], matrix[13], - matrix[2], matrix[6], matrix[10], matrix[14], - matrix[3], matrix[7], matrix[11], matrix[15]); - - // Apply the scaling matrix to have the correct cylinder dimensions - mTransformMatrix = newMatrix * mScalingMatrix; -} - // Create the Vertex Buffer Objects used to render with OpenGL. /// We create two VBOs (one for vertices and one for indices) void Cylinder::createVBOAndVAO() { @@ -290,12 +267,12 @@ void Cylinder::createVBOAndVAO() { void Cylinder::resetTransform(const rp3d::Transform& transform) { // Reset the transform - mRigidBody->setTransform(transform); + mBody->setTransform(transform); - mRigidBody->setIsSleeping(false); + mBody->setIsSleeping(false); // Reset the velocity of the rigid body - rp3d::RigidBody* rigidBody = dynamic_cast(mRigidBody); + rp3d::RigidBody* rigidBody = dynamic_cast(mBody); if (rigidBody != NULL) { rigidBody->setLinearVelocity(rp3d::Vector3(0, 0, 0)); rigidBody->setAngularVelocity(rp3d::Vector3(0, 0, 0)); diff --git a/testbed/common/Cylinder.h b/testbed/common/Cylinder.h index 65758222..17379e7c 100644 --- a/testbed/common/Cylinder.h +++ b/testbed/common/Cylinder.h @@ -29,9 +29,10 @@ // Libraries #include "openglframework.h" #include "reactphysics3d.h" +#include "PhysicsObject.h" // Class Cylinder -class Cylinder : public openglframework::Mesh { +class Cylinder : public openglframework::Mesh, public PhysicsObject { private : @@ -43,9 +44,6 @@ class Cylinder : public openglframework::Mesh { /// Height of the cylinder float mHeight; - /// Rigid body used to simulate the dynamics of the cylinder - rp3d::CollisionBody* mRigidBody; - /// Scaling matrix (applied to a sphere to obtain the correct cylinder dimensions) openglframework::Matrix4 mScalingMatrix; @@ -70,9 +68,6 @@ class Cylinder : public openglframework::Mesh { // Total number of capsules created static int totalNbCylinders; - /// Color - openglframework::Color mColor; - // -------------------- Methods -------------------- // // Create the Vertex Buffer Objects used to render with OpenGL. @@ -93,31 +88,20 @@ class Cylinder : public openglframework::Mesh { /// Destructor ~Cylinder(); - /// Return a pointer to the collision body of the box - reactphysics3d::CollisionBody* getCollisionBody(); - - /// Return a pointer to the rigid body of the box - reactphysics3d::RigidBody* getRigidBody(); - - /// Update the transform matrix of the cylinder - void updateTransform(float interpolationFactor); - /// Render the cylinder at the correct position and with the correct orientation void render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix); /// Set the position of the box void resetTransform(const rp3d::Transform& transform); + + /// Update the transform matrix of the object + virtual void updateTransform(float interpolationFactor); }; -// Return a pointer to the collision body of the box -inline rp3d::CollisionBody* Cylinder::getCollisionBody() { - return mRigidBody; -} - -// Return a pointer to the rigid body of the box -inline rp3d::RigidBody* Cylinder::getRigidBody() { - return dynamic_cast(mRigidBody); +// Update the transform matrix of the object +inline void Cylinder::updateTransform(float interpolationFactor) { + mTransformMatrix = computeTransform(interpolationFactor, mScalingMatrix); } #endif diff --git a/testbed/common/Dumbbell.cpp b/testbed/common/Dumbbell.cpp index 41239a58..630630ee 100644 --- a/testbed/common/Dumbbell.cpp +++ b/testbed/common/Dumbbell.cpp @@ -36,7 +36,7 @@ int Dumbbell::totalNbDumbbells = 0; // Constructor Dumbbell::Dumbbell(const openglframework::Vector3 &position, reactphysics3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath) - : openglframework::Mesh(), mColor(0.5f, 0.5f, 0.5f, 1.0f) { + : openglframework::Mesh() { // Load the mesh from a file openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "dumbbell.obj", *this); @@ -105,7 +105,7 @@ Dumbbell::Dumbbell(const openglframework::Vector3 &position, // Constructor Dumbbell::Dumbbell(const openglframework::Vector3 &position, reactphysics3d::CollisionWorld* world, const std::string& meshFolderPath) - : openglframework::Mesh(), mColor(0.5f, 0.5f, 0.5f, 1.0f) { + : openglframework::Mesh() { // Load the mesh from a file openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "dumbbell.obj", *this); @@ -218,9 +218,11 @@ void Dumbbell::render(openglframework::Shader& shader, GLint vertexNormalLoc = shader.getAttribLocation("vertexNormal", false); glEnableVertexAttribArray(vertexPositionLoc); - if (vertexNormalLoc != -1) glEnableVertexAttribArray(vertexNormalLoc); - glVertexAttribPointer(vertexPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL); + + mVBONormals.bind(); + + if (vertexNormalLoc != -1) glEnableVertexAttribArray(vertexNormalLoc); if (vertexNormalLoc != -1) glVertexAttribPointer(vertexNormalLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL); // For each part of the mesh @@ -231,6 +233,7 @@ void Dumbbell::render(openglframework::Shader& shader, glDisableVertexAttribArray(vertexPositionLoc); if (vertexNormalLoc != -1) glDisableVertexAttribArray(vertexNormalLoc); + mVBONormals.unbind(); mVBOVertices.unbind(); // Unbind the VAO @@ -240,30 +243,6 @@ void Dumbbell::render(openglframework::Shader& shader, shader.unbind(); } -// Update the transform matrix of the sphere -void Dumbbell::updateTransform(float interpolationFactor) { - - // Get the transform of the rigid body - rp3d::Transform transform = mBody->getTransform(); - - // Interpolate the transform between the previous one and the new one - rp3d::Transform interpolatedTransform = rp3d::Transform::interpolateTransforms(mPreviousTransform, - transform, - interpolationFactor); - mPreviousTransform = transform; - - // Compute the transform used for rendering the sphere - rp3d::decimal matrix[16]; - interpolatedTransform.getOpenGLMatrix(matrix); - openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12], - matrix[1], matrix[5], matrix[9], matrix[13], - matrix[2], matrix[6], matrix[10], matrix[14], - matrix[3], matrix[7], matrix[11], matrix[15]); - - // Apply the scaling matrix to have the correct sphere dimensions - mTransformMatrix = newMatrix * mScalingMatrix; -} - // Create the Vertex Buffer Objects used to render with OpenGL. /// We create two VBOs (one for vertices and one for indices) void Dumbbell::createVBOAndVAO() { diff --git a/testbed/common/Dumbbell.h b/testbed/common/Dumbbell.h index d5740ecd..cde7cea9 100644 --- a/testbed/common/Dumbbell.h +++ b/testbed/common/Dumbbell.h @@ -29,9 +29,10 @@ // Libraries #include "openglframework.h" #include "reactphysics3d.h" +#include "PhysicsObject.h" // Class Sphere -class Dumbbell : public openglframework::Mesh { +class Dumbbell : public openglframework::Mesh, public PhysicsObject { private : @@ -40,9 +41,6 @@ class Dumbbell : public openglframework::Mesh { /// Radius of the spheres float mRadius; - /// Rigid body used to simulate the dynamics of the sphere - rp3d::CollisionBody* mBody; - /// Scaling matrix (applied to a sphere to obtain the correct sphere dimensions) openglframework::Matrix4 mScalingMatrix; @@ -67,9 +65,6 @@ class Dumbbell : public openglframework::Mesh { // Total number of capsules created static int totalNbDumbbells; - /// Color - openglframework::Color mColor; - // -------------------- Methods -------------------- // // Create the Vertex Buffer Objects used to render with OpenGL. @@ -91,31 +86,20 @@ class Dumbbell : public openglframework::Mesh { /// Destructor ~Dumbbell(); - /// Return a pointer to the rigid body - rp3d::RigidBody* getRigidBody(); - - /// Return a pointer to the body - rp3d::CollisionBody* getCollisionBody(); - - /// Update the transform matrix of the sphere - void updateTransform(float interpolationFactor); - /// Render the sphere at the correct position and with the correct orientation void render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix); /// Set the position of the box void resetTransform(const rp3d::Transform& transform); + + /// Update the transform matrix of the object + virtual void updateTransform(float interpolationFactor); }; -// Return a pointer to the rigid body of the sphere -inline rp3d::RigidBody* Dumbbell::getRigidBody() { - return dynamic_cast(mBody); -} - -// Return a pointer to the body -inline rp3d::CollisionBody* Dumbbell::getCollisionBody() { - return mBody; +// Update the transform matrix of the object +inline void Dumbbell::updateTransform(float interpolationFactor) { + mTransformMatrix = computeTransform(interpolationFactor, mScalingMatrix); } #endif diff --git a/testbed/common/PhysicsObject.cpp b/testbed/common/PhysicsObject.cpp new file mode 100644 index 00000000..3bc7be77 --- /dev/null +++ b/testbed/common/PhysicsObject.cpp @@ -0,0 +1,59 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Libraries +#include "PhysicsObject.h" + +/// Constructor +PhysicsObject::PhysicsObject() { + + mColor = openglframework::Color(1, 1, 1, 1); + mSleepingColor = openglframework::Color(1, 0, 0, 1); +} + +// Compute the new transform matrix +openglframework::Matrix4 PhysicsObject::computeTransform(float interpolationFactor, + const openglframework::Matrix4& scalingMatrix) { + + // Get the transform of the rigid body + rp3d::Transform transform = mBody->getTransform(); + + // Interpolate the transform between the previous one and the new one + rp3d::Transform interpolatedTransform = rp3d::Transform::interpolateTransforms(mPreviousTransform, + transform, + interpolationFactor); + mPreviousTransform = transform; + + // Compute the transform used for rendering the box + rp3d::decimal matrix[16]; + interpolatedTransform.getOpenGLMatrix(matrix); + openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12], + matrix[1], matrix[5], matrix[9], matrix[13], + matrix[2], matrix[6], matrix[10], matrix[14], + matrix[3], matrix[7], matrix[11], matrix[15]); + + // Apply the scaling matrix to have the correct box dimensions + return newMatrix * scalingMatrix; +} diff --git a/testbed/common/PhysicsObject.h b/testbed/common/PhysicsObject.h new file mode 100644 index 00000000..1e1ef69d --- /dev/null +++ b/testbed/common/PhysicsObject.h @@ -0,0 +1,96 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +#ifndef PHYSICSOBJECT_H +#define PHYSICSOBJECT_H + +// Libraries +#include "openglframework.h" +#include "reactphysics3d.h" + +// Class PhysicsObject +class PhysicsObject { + + protected: + + /// Body used to simulate the dynamics of the box + rp3d::CollisionBody* mBody; + + /// Previous transform of the body (for interpolation) + rp3d::Transform mPreviousTransform; + + /// Main color of the box + openglframework::Color mColor; + + /// Sleeping color + openglframework::Color mSleepingColor; + + // Compute the new transform matrix + openglframework::Matrix4 computeTransform(float interpolationFactor, + const openglframework::Matrix4 &scalingMatrix); + + public: + + /// Constructor + PhysicsObject(); + + /// Update the transform matrix of the object + virtual void updateTransform(float interpolationFactor)=0; + + /// Set the color of the box + void setColor(const openglframework::Color& color); + + /// Set the sleeping color of the box + void setSleepingColor(const openglframework::Color& color); + + /// Return a pointer to the collision body of the box + reactphysics3d::CollisionBody* getCollisionBody(); + + /// Return a pointer to the rigid body of the box + reactphysics3d::RigidBody* getRigidBody(); +}; + +// Set the color of the box +inline void PhysicsObject::setColor(const openglframework::Color& color) { + mColor = color; +} + +// Set the sleeping color of the box +inline void PhysicsObject::setSleepingColor(const openglframework::Color& color) { + mSleepingColor = color; +} + +// Return a pointer to the collision body of the box +inline rp3d::CollisionBody* PhysicsObject::getCollisionBody() { + return mBody; +} + +// Return a pointer to the rigid body of the box (NULL if it's not a rigid body) +inline rp3d::RigidBody* PhysicsObject::getRigidBody() { + return dynamic_cast(mBody); +} + +#endif + diff --git a/testbed/common/Sphere.cpp b/testbed/common/Sphere.cpp index 8d31f1a9..61fe9671 100644 --- a/testbed/common/Sphere.cpp +++ b/testbed/common/Sphere.cpp @@ -37,7 +37,7 @@ int Sphere::totalNbSpheres = 0; Sphere::Sphere(float radius, const openglframework::Vector3 &position, reactphysics3d::CollisionWorld* world, const std::string& meshFolderPath) - : openglframework::Mesh(), mRadius(radius), mColor(0.5f, 0.5f, 0.5f, 1.0f) { + : openglframework::Mesh(), mRadius(radius) { // Load the mesh from a file openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "sphere.obj", *this); @@ -67,10 +67,10 @@ Sphere::Sphere(float radius, const openglframework::Vector3 &position, mPreviousTransform = transform; // Create a rigid body corresponding to the sphere in the dynamics world - mRigidBody = world->createCollisionBody(transform); + mBody = world->createCollisionBody(transform); // Add a collision shape to the body and specify the mass of the shape - mRigidBody->addCollisionShape(collisionShape, rp3d::Transform::identity()); + mBody->addCollisionShape(collisionShape, rp3d::Transform::identity()); mTransformMatrix = mTransformMatrix * mScalingMatrix; @@ -86,7 +86,7 @@ Sphere::Sphere(float radius, const openglframework::Vector3 &position, Sphere::Sphere(float radius, const openglframework::Vector3 &position, float mass, reactphysics3d::DynamicsWorld* world, const std::string& meshFolderPath) - : openglframework::Mesh(), mRadius(radius), mColor(0.5f, 0.5f, 0.5f, 1.0f) { + : openglframework::Mesh(), mRadius(radius) { // Load the mesh from a file openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "sphere.obj", *this); @@ -119,7 +119,7 @@ Sphere::Sphere(float radius, const openglframework::Vector3 &position, // Add a collision shape to the body and specify the mass of the shape body->addCollisionShape(collisionShape, rp3d::Transform::identity(), mass); - mRigidBody = body; + mBody = body; mTransformMatrix = mTransformMatrix * mScalingMatrix; @@ -181,10 +181,12 @@ void Sphere::render(openglframework::Shader& shader, GLint vertexNormalLoc = shader.getAttribLocation("vertexNormal", false); glEnableVertexAttribArray(vertexPositionLoc); - if (vertexNormalLoc != -1) glEnableVertexAttribArray(vertexNormalLoc); - glVertexAttribPointer(vertexPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL); + + mVBONormals.bind(); + if (vertexNormalLoc != -1) glVertexAttribPointer(vertexNormalLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL); + if (vertexNormalLoc != -1) glEnableVertexAttribArray(vertexNormalLoc); // For each part of the mesh for (unsigned int i=0; igetTransform(); - - // Interpolate the transform between the previous one and the new one - rp3d::Transform interpolatedTransform = rp3d::Transform::interpolateTransforms(mPreviousTransform, - transform, - interpolationFactor); - mPreviousTransform = transform; - - // Compute the transform used for rendering the sphere - rp3d::decimal matrix[16]; - interpolatedTransform.getOpenGLMatrix(matrix); - openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12], - matrix[1], matrix[5], matrix[9], matrix[13], - matrix[2], matrix[6], matrix[10], matrix[14], - matrix[3], matrix[7], matrix[11], matrix[15]); - - // Apply the scaling matrix to have the correct sphere dimensions - mTransformMatrix = newMatrix * mScalingMatrix; -} - // Create the Vertex Buffer Objects used to render with OpenGL. /// We create two VBOs (one for vertices and one for indices) void Sphere::createVBOAndVAO() { @@ -287,12 +266,12 @@ void Sphere::createVBOAndVAO() { void Sphere::resetTransform(const rp3d::Transform& transform) { // Reset the transform - mRigidBody->setTransform(transform); + mBody->setTransform(transform); - mRigidBody->setIsSleeping(false); + mBody->setIsSleeping(false); // Reset the velocity of the rigid body - rp3d::RigidBody* rigidBody = dynamic_cast(mRigidBody); + rp3d::RigidBody* rigidBody = dynamic_cast(mBody); if (rigidBody != NULL) { rigidBody->setLinearVelocity(rp3d::Vector3(0, 0, 0)); rigidBody->setAngularVelocity(rp3d::Vector3(0, 0, 0)); diff --git a/testbed/common/Sphere.h b/testbed/common/Sphere.h index 74eea2b2..99a27ecc 100644 --- a/testbed/common/Sphere.h +++ b/testbed/common/Sphere.h @@ -29,9 +29,10 @@ // Libraries #include "openglframework.h" #include "reactphysics3d.h" +#include "PhysicsObject.h" // Class Sphere -class Sphere : public openglframework::Mesh { +class Sphere : public openglframework::Mesh, public PhysicsObject { private : @@ -40,9 +41,6 @@ class Sphere : public openglframework::Mesh { /// Radius of the sphere float mRadius; - /// Rigid body used to simulate the dynamics of the sphere - rp3d::CollisionBody* mRigidBody; - /// Scaling matrix (applied to a sphere to obtain the correct sphere dimensions) openglframework::Matrix4 mScalingMatrix; @@ -67,9 +65,6 @@ class Sphere : public openglframework::Mesh { // Total number of capsules created static int totalNbSpheres; - /// Color - openglframework::Color mColor; - // -------------------- Methods -------------------- // // Create the Vertex Buffer Objects used to render with OpenGL. @@ -90,31 +85,20 @@ class Sphere : public openglframework::Mesh { /// Destructor ~Sphere(); - /// Return a pointer to the collision body of the box - reactphysics3d::CollisionBody* getCollisionBody(); - - /// Return a pointer to the rigid body of the box - reactphysics3d::RigidBody* getRigidBody(); - - /// Update the transform matrix of the sphere - void updateTransform(float interpolationFactor); - /// Render the sphere at the correct position and with the correct orientation void render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix); /// Set the position of the box void resetTransform(const rp3d::Transform& transform); + + /// Update the transform matrix of the object + virtual void updateTransform(float interpolationFactor); }; -// Return a pointer to the collision body of the box -inline rp3d::CollisionBody* Sphere::getCollisionBody() { - return mRigidBody; -} - -// Return a pointer to the rigid body of the box -inline rp3d::RigidBody* Sphere::getRigidBody() { - return dynamic_cast(mRigidBody); +// Update the transform matrix of the object +inline void Sphere::updateTransform(float interpolationFactor) { + mTransformMatrix = computeTransform(interpolationFactor, mScalingMatrix); } #endif diff --git a/testbed/common/VisualContactPoint.cpp b/testbed/common/VisualContactPoint.cpp index 797b7ffb..fa4a177b 100644 --- a/testbed/common/VisualContactPoint.cpp +++ b/testbed/common/VisualContactPoint.cpp @@ -119,10 +119,12 @@ void VisualContactPoint::render(openglframework::Shader& shader, GLint vertexNormalLoc = shader.getAttribLocation("vertexNormal", false); glEnableVertexAttribArray(vertexPositionLoc); - if (vertexNormalLoc != -1) glEnableVertexAttribArray(vertexNormalLoc); - glVertexAttribPointer(vertexPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL); + + mVBONormals.bind(); + if (vertexNormalLoc != -1) glVertexAttribPointer(vertexNormalLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL); + if (vertexNormalLoc != -1) glEnableVertexAttribArray(vertexNormalLoc); // For each part of the mesh for (unsigned int i=0; isetColor(mDemoColors[i % mNbDemoColors]); + dumbbell->setSleepingColor(mRedColorDemo); + // Change the material properties of the rigid body rp3d::Material& material = dumbbell->getRigidBody()->getMaterial(); material.setBounciness(rp3d::decimal(0.2)); @@ -87,6 +91,10 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name) // Create a sphere and a corresponding rigid in the dynamics world Box* box = new Box(BOX_SIZE, position , BOX_MASS, mDynamicsWorld); + // Set the box color + box->setColor(mDemoColors[i % mNbDemoColors]); + box->setSleepingColor(mRedColorDemo); + // Change the material properties of the rigid body rp3d::Material& material = box->getRigidBody()->getMaterial(); material.setBounciness(rp3d::decimal(0.2)); @@ -108,6 +116,10 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name) Sphere* sphere = new Sphere(SPHERE_RADIUS, position , BOX_MASS, mDynamicsWorld, meshFolderPath); + // Set the box color + sphere->setColor(mDemoColors[i % mNbDemoColors]); + sphere->setSleepingColor(mRedColorDemo); + // Change the material properties of the rigid body rp3d::Material& material = sphere->getRigidBody()->getMaterial(); material.setBounciness(rp3d::decimal(0.2)); @@ -129,6 +141,10 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name) Cone* cone = new Cone(CONE_RADIUS, CONE_HEIGHT, position, CONE_MASS, mDynamicsWorld, meshFolderPath); + // Set the box color + cone->setColor(mDemoColors[i % mNbDemoColors]); + cone->setSleepingColor(mRedColorDemo); + // Change the material properties of the rigid body rp3d::Material& material = cone->getRigidBody()->getMaterial(); material.setBounciness(rp3d::decimal(0.2)); @@ -150,6 +166,10 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name) Cylinder* cylinder = new Cylinder(CYLINDER_RADIUS, CYLINDER_HEIGHT, position , CYLINDER_MASS, mDynamicsWorld, meshFolderPath); + // Set the box color + cylinder->setColor(mDemoColors[i % mNbDemoColors]); + cylinder->setSleepingColor(mRedColorDemo); + // Change the material properties of the rigid body rp3d::Material& material = cylinder->getRigidBody()->getMaterial(); material.setBounciness(rp3d::decimal(0.2)); @@ -171,6 +191,10 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name) Capsule* capsule = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, position , CAPSULE_MASS, mDynamicsWorld, meshFolderPath); + // Set the box color + capsule->setColor(mDemoColors[i % mNbDemoColors]); + capsule->setSleepingColor(mRedColorDemo); + // Change the material properties of the rigid body rp3d::Material& material = capsule->getRigidBody()->getMaterial(); material.setBounciness(rp3d::decimal(0.2)); @@ -191,6 +215,10 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name) // Create a convex mesh and a corresponding rigid in the dynamics world ConvexMesh* mesh = new ConvexMesh(position, MESH_MASS, mDynamicsWorld, meshFolderPath); + // Set the box color + mesh->setColor(mDemoColors[i % mNbDemoColors]); + mesh->setSleepingColor(mRedColorDemo); + // Change the material properties of the rigid body rp3d::Material& material = mesh->getRigidBody()->getMaterial(); material.setBounciness(rp3d::decimal(0.2)); @@ -202,7 +230,10 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name) // Create the floor openglframework::Vector3 floorPosition(0, 0, 0); mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld); - mFloor->setColor(Color(0.70f, 0.70f, 0.7f, 1.0f)); + + // Set the box color + mFloor->setColor(mGreyColorDemo); + mFloor->setSleepingColor(mRedColorDemo); // The floor must be a static rigid body mFloor->getRigidBody()->setType(rp3d::STATIC); diff --git a/testbed/scenes/collisionshapes/CollisionShapesScene.h b/testbed/scenes/collisionshapes/CollisionShapesScene.h index 0befba55..8c7a13e1 100644 --- a/testbed/scenes/collisionshapes/CollisionShapesScene.h +++ b/testbed/scenes/collisionshapes/CollisionShapesScene.h @@ -45,12 +45,12 @@ namespace collisionshapesscene { // Constants const float SCENE_RADIUS = 30.0f; -const int NB_BOXES = 3; -const int NB_CUBES = 5; -const int NB_CONES = 3; -const int NB_CYLINDERS = 3; -const int NB_CAPSULES = 4; -const int NB_MESHES = 4; +const int NB_BOXES = 5; +const int NB_CUBES = 4; +const int NB_CONES = 4; +const int NB_CYLINDERS = 6; +const int NB_CAPSULES = 5; +const int NB_MESHES = 7; const int NB_COMPOUND_SHAPES = 3; const openglframework::Vector3 BOX_SIZE(2, 2, 2); const float SPHERE_RADIUS = 1.5f; diff --git a/testbed/scenes/cubes/CubesScene.cpp b/testbed/scenes/cubes/CubesScene.cpp index 1cd18ef3..05c05063 100644 --- a/testbed/scenes/cubes/CubesScene.cpp +++ b/testbed/scenes/cubes/CubesScene.cpp @@ -66,6 +66,10 @@ CubesScene::CubesScene(const std::string& name) // Create a cube and a corresponding rigid in the dynamics world Box* cube = new Box(BOX_SIZE, position , BOX_MASS, mDynamicsWorld); + // Set the box color + cube->setColor(mDemoColors[i % mNbDemoColors]); + cube->setSleepingColor(mRedColorDemo); + // Change the material properties of the rigid body rp3d::Material& material = cube->getRigidBody()->getMaterial(); material.setBounciness(rp3d::decimal(0.4)); @@ -77,7 +81,8 @@ CubesScene::CubesScene(const std::string& name) // Create the floor openglframework::Vector3 floorPosition(0, 0, 0); mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld); - mFloor->setColor(Color(0.70f, 0.70f, 0.7f, 1.0f)); + mFloor->setColor(mGreyColorDemo); + mFloor->setSleepingColor(mGreyColorDemo); // The floor must be a static rigid body mFloor->getRigidBody()->setType(rp3d::STATIC); @@ -152,16 +157,6 @@ void CubesScene::update() { } mFloor->updateTransform(mInterpolationFactor); - - // Set the color of the awake/sleeping bodies - for (uint i=0; igetRigidBody()->isSleeping()) { - mBoxes[i]->setColor(Color(1, 0, 0, 1)); - } - else { - mBoxes[i]->setColor(Color(0, 1, 0, 1)); - } - } } // Render the scene in a single pass diff --git a/testbed/scenes/cubes/CubesScene.h b/testbed/scenes/cubes/CubesScene.h index 07d4c770..05331724 100644 --- a/testbed/scenes/cubes/CubesScene.h +++ b/testbed/scenes/cubes/CubesScene.h @@ -36,7 +36,7 @@ namespace cubesscene { // Constants const float SCENE_RADIUS = 30.0f; // Radius of the scene in meters -const int NB_CUBES = 20; // Number of boxes in the scene +const int NB_CUBES = 30; // Number of boxes in the scene const openglframework::Vector3 BOX_SIZE(2, 2, 2); // Box dimensions in meters const openglframework::Vector3 FLOOR_SIZE(50, 0.5f, 50); // Floor dimensions in meters const float BOX_MASS = 1.0f; // Box mass in kilograms diff --git a/testbed/scenes/joints/JointsScene.cpp b/testbed/scenes/joints/JointsScene.cpp index be0ae28f..9406ee21 100644 --- a/testbed/scenes/joints/JointsScene.cpp +++ b/testbed/scenes/joints/JointsScene.cpp @@ -269,6 +269,10 @@ void JointsScene::createBallAndSocketJoints() { mBallAndSocketJointChainBoxes[i] = new Box(boxDimension, positionBox , boxMass, mDynamicsWorld); + // Set the box color + mBallAndSocketJointChainBoxes[i]->setColor(mDemoColors[i % mNbDemoColors]); + mBallAndSocketJointChainBoxes[i]->setSleepingColor(mRedColorDemo); + // The fist box cannot move (static body) if (i == 0) { mBallAndSocketJointChainBoxes[i]->getRigidBody()->setType(rp3d::STATIC); @@ -314,6 +318,10 @@ void JointsScene::createSliderJoint() { openglframework::Vector3 box1Dimension(2, 4, 2); mSliderJointBottomBox = new Box(box1Dimension, positionBox1 , BOX_MASS, mDynamicsWorld); + // Set the box color + mSliderJointBottomBox->setColor(mBlueColorDemo); + mSliderJointBottomBox->setSleepingColor(mRedColorDemo); + // The fist box cannot move mSliderJointBottomBox->getRigidBody()->setType(rp3d::STATIC); @@ -330,6 +338,10 @@ void JointsScene::createSliderJoint() { openglframework::Vector3 box2Dimension(1.5f, 4, 1.5f); mSliderJointTopBox = new Box(box2Dimension, positionBox2, BOX_MASS, mDynamicsWorld); + // Set the box color + mSliderJointTopBox->setColor(mOrangeColorDemo); + mSliderJointTopBox->setSleepingColor(mRedColorDemo); + // Change the material properties of the rigid body rp3d::Material& material2 = mSliderJointTopBox->getRigidBody()->getMaterial(); material2.setBounciness(0.4f); @@ -366,6 +378,10 @@ void JointsScene::createPropellerHingeJoint() { openglframework::Vector3 boxDimension(10, 1, 1); mPropellerBox = new Box(boxDimension, positionBox1 , BOX_MASS, mDynamicsWorld); + // Set the box color + mPropellerBox->setColor(mYellowColorDemo); + mPropellerBox->setSleepingColor(mRedColorDemo); + // Change the material properties of the rigid body rp3d::Material& material = mPropellerBox->getRigidBody()->getMaterial(); material.setBounciness(rp3d::decimal(0.4)); @@ -401,6 +417,10 @@ void JointsScene::createFixedJoints() { openglframework::Vector3 boxDimension(1.5, 1.5, 1.5); mFixedJointBox1 = new Box(boxDimension, positionBox1 , BOX_MASS, mDynamicsWorld); + // Set the box color + mFixedJointBox1->setColor(mPinkColorDemo); + mFixedJointBox1->setSleepingColor(mRedColorDemo); + // Change the material properties of the rigid body rp3d::Material& material1 = mFixedJointBox1->getRigidBody()->getMaterial(); material1.setBounciness(rp3d::decimal(0.4)); @@ -413,6 +433,10 @@ void JointsScene::createFixedJoints() { // Create a box and a corresponding rigid in the dynamics world mFixedJointBox2 = new Box(boxDimension, positionBox2 , BOX_MASS, mDynamicsWorld); + // Set the box color + mFixedJointBox2->setColor(mBlueColorDemo); + mFixedJointBox2->setSleepingColor(mRedColorDemo); + // Change the material properties of the rigid body rp3d::Material& material2 = mFixedJointBox2->getRigidBody()->getMaterial(); material2.setBounciness(rp3d::decimal(0.4)); @@ -447,7 +471,10 @@ void JointsScene::createFloor() { // Create the floor openglframework::Vector3 floorPosition(0, 0, 0); mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld); - mFloor->setColor(Color(0.70f, 0.70f, 0.7f, 1.0f)); + + // Set the box color + mFloor->setColor(mGreyColorDemo); + mFloor->setSleepingColor(mRedColorDemo); // The floor must be a static rigid body mFloor->getRigidBody()->setType(rp3d::STATIC); diff --git a/testbed/scenes/raycast/RaycastScene.cpp b/testbed/scenes/raycast/RaycastScene.cpp index caa0b4ab..ed60e7df 100644 --- a/testbed/scenes/raycast/RaycastScene.cpp +++ b/testbed/scenes/raycast/RaycastScene.cpp @@ -51,6 +51,10 @@ RaycastScene::RaycastScene(const std::string& name) // Create a convex mesh and a corresponding collision body in the dynamics world mDumbbell = new Dumbbell(position1, mCollisionWorld, mMeshFolderPath); + // Set the box color + mDumbbell->setColor(mGreyColorDemo); + mDumbbell->setSleepingColor(mRedColorDemo); + // ---------- Box ---------- // openglframework::Vector3 position2(0, 0, 0); @@ -58,6 +62,10 @@ RaycastScene::RaycastScene(const std::string& name) mBox = new Box(BOX_SIZE, position2, mCollisionWorld); mBox->getCollisionBody()->setIsActive(false); + // Set the box color + mBox->setColor(mGreyColorDemo); + mBox->setSleepingColor(mRedColorDemo); + // ---------- Sphere ---------- // openglframework::Vector3 position3(0, 0, 0); @@ -65,6 +73,10 @@ RaycastScene::RaycastScene(const std::string& name) mSphere = new Sphere(SPHERE_RADIUS, position3, mCollisionWorld, mMeshFolderPath); + // Set the color + mSphere->setColor(mGreyColorDemo); + mSphere->setSleepingColor(mRedColorDemo); + // ---------- Cone ---------- // openglframework::Vector3 position4(0, 0, 0); @@ -72,6 +84,10 @@ RaycastScene::RaycastScene(const std::string& name) mCone = new Cone(CONE_RADIUS, CONE_HEIGHT, position4, mCollisionWorld, mMeshFolderPath); + // Set the color + mCone->setColor(mGreyColorDemo); + mCone->setSleepingColor(mRedColorDemo); + // ---------- Cylinder ---------- // openglframework::Vector3 position5(0, 0, 0); @@ -79,6 +95,10 @@ RaycastScene::RaycastScene(const std::string& name) mCylinder = new Cylinder(CYLINDER_RADIUS, CYLINDER_HEIGHT, position5, mCollisionWorld, mMeshFolderPath); + // Set the color + mCylinder->setColor(mGreyColorDemo); + mCylinder->setSleepingColor(mRedColorDemo); + // ---------- Capsule ---------- // openglframework::Vector3 position6(0, 0, 0); @@ -86,12 +106,20 @@ RaycastScene::RaycastScene(const std::string& name) mCapsule = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, position6 , mCollisionWorld, mMeshFolderPath); + // Set the color + mCapsule->setColor(mGreyColorDemo); + mCapsule->setSleepingColor(mRedColorDemo); + // ---------- Convex Mesh ---------- // openglframework::Vector3 position7(0, 0, 0); // Create a convex mesh and a corresponding collision body in the dynamics world mConvexMesh = new ConvexMesh(position7, mCollisionWorld, mMeshFolderPath); + // Set the color + mConvexMesh->setColor(mGreyColorDemo); + mConvexMesh->setSleepingColor(mRedColorDemo); + // Create the lines that will be used for raycasting createLines(); diff --git a/testbed/shaders/phong.frag b/testbed/shaders/phong.frag index a4c044f0..e34c8abd 100644 --- a/testbed/shaders/phong.frag +++ b/testbed/shaders/phong.frag @@ -29,8 +29,6 @@ uniform vec3 lightAmbientColor; // Lights ambient color uniform vec3 light0PosCameraSpace; // Camera-space position of the light uniform vec3 light0DiffuseColor; // Light 0 diffuse color -uniform vec3 light0SpecularColor; // Light 0 specular color -uniform float shininess; // Shininess uniform sampler2D textureSampler; // Texture uniform sampler2D shadowMapSampler; // Shadow map texture sampler uniform bool isTexture; // True if we need to use the texture @@ -63,17 +61,10 @@ void main() { float diffuseFactor = max(dot(N, L0), 0.0); vec3 diffuse = light0DiffuseColor * diffuseFactor * textureColor; - // Compute the specular term of light 0 - vec3 V = normalize(-vertexPosCameraSpace); - vec3 H0 = normalize(V + L0); - float specularFactor = pow(max(dot(N, H0), 0.0), shininess); - if (diffuseFactor < 0.0) specularFactor = 0.0; - vec3 specular = light0SpecularColor * specularFactor; - // Compute shadow factor float shadow = 1.0; if (isShadowEnabled) { - float bias = 0.0001; + float bias = 0.0003; float shadowBias = -0.000; vec4 shadowMapUV = shadowMapCoords; shadowMapUV.z -= shadowBias; diff --git a/testbed/src/Gui.h b/testbed/src/Gui.h index 52354eb1..c794d57d 100644 --- a/testbed/src/Gui.h +++ b/testbed/src/Gui.h @@ -37,7 +37,7 @@ const float GUI_SCALING = 2.0f; const int LEFT_PANE_WIDTH = 300; const int LEFT_PANE_HEADER_HEIGHT = 90; -const double TIME_INTERVAL_DISPLAY_PROFILING_INFO = 1.0; +const double TIME_INTERVAL_DISPLAY_PROFILING_INFO = 0.2; using namespace openglframework; diff --git a/testbed/src/SceneDemo.cpp b/testbed/src/SceneDemo.cpp index d4c88503..8be46a64 100644 --- a/testbed/src/SceneDemo.cpp +++ b/testbed/src/SceneDemo.cpp @@ -30,6 +30,15 @@ using namespace openglframework; int SceneDemo::shadowMapTextureLevel = 0; +openglframework::Color SceneDemo::mGreyColorDemo = Color(0.70f, 0.70f, 0.7f, 1.0); +openglframework::Color SceneDemo::mYellowColorDemo = Color(0.9, 0.88, 0.145, 1.0); +openglframework::Color SceneDemo::mBlueColorDemo = Color(0, 0.66, 0.95, 1.0); +openglframework::Color SceneDemo::mOrangeColorDemo = Color(0.9, 0.35, 0, 1.0); +openglframework::Color SceneDemo::mPinkColorDemo = Color(0.83, 0.48, 0.64, 1.0); +openglframework::Color SceneDemo::mRedColorDemo = Color(0.95, 0, 0, 1.0); +int SceneDemo::mNbDemoColors = 4; +openglframework::Color SceneDemo::mDemoColors[] = {SceneDemo::mYellowColorDemo, SceneDemo::mBlueColorDemo, + SceneDemo::mOrangeColorDemo, SceneDemo::mPinkColorDemo}; // Constructor SceneDemo::SceneDemo(const std::string& name, float sceneRadius, bool isShadowMappingEnabled) @@ -43,15 +52,16 @@ SceneDemo::SceneDemo(const std::string& name, float sceneRadius, bool isShadowMa shadowMapTextureLevel++; // Move the light0 - mLight0.translateWorld(Vector3(0, 40, 40)); + mLight0.translateWorld(Vector3(-2, 35, 40)); // Camera at light0 postion for the shadow map mShadowMapLightCamera.translateWorld(mLight0.getOrigin()); mShadowMapLightCamera.rotateLocal(Vector3(1, 0, 0), -PI / 4.0f); + mShadowMapLightCamera.rotateWorld(Vector3(0, 1, 0), PI / 8.0f); + mShadowMapLightCamera.setDimensions(SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT); - mShadowMapLightCamera.setFieldOfView(70.0f); + mShadowMapLightCamera.setFieldOfView(80.0f); mShadowMapLightCamera.setSceneRadius(100); - //mShadowMapLightCamera.setZoom(1.0); mShadowMapBiasMatrix.setAllValues(0.5, 0.0, 0.0, 0.5, 0.0, 0.5, 0.0, 0.5, @@ -142,8 +152,6 @@ void SceneDemo::render() { mPhongShader.setVector3Uniform("light0PosCameraSpace", worldToCameraMatrix * mLight0.getOrigin()); mPhongShader.setVector3Uniform("lightAmbientColor", Vector3(0.4f, 0.4f, 0.4f)); mPhongShader.setVector3Uniform("light0DiffuseColor", Vector3(diffCol.r, diffCol.g, diffCol.b)); - mPhongShader.setVector3Uniform("light0SpecularColor", Vector3(specCol.r, specCol.g, specCol.b)); - mPhongShader.setFloatUniform("shininess", 60.0f); mPhongShader.setIntUniform("shadowMapSampler", textureUnit); mPhongShader.setIntUniform("isShadowEnabled", mIsShadowMappingEnabled); @@ -186,7 +194,6 @@ void SceneDemo::createShadowMapFBOAndTexture() { mIsShadowMappingInitialized = true; } -// TODO : Delete this void SceneDemo::createQuadVBO() { mVAOQuad.create(); @@ -217,10 +224,12 @@ void SceneDemo::drawTextureQuad() { // Clear previous frame values glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + const GLuint textureUnit = 0; + mVAOQuad.bind(); mQuadShader.bind(); mShadowMapTexture.bind(); - mQuadShader.setIntUniform("textureSampler", mShadowMapTexture.getID()); + mQuadShader.setIntUniform("textureSampler", textureUnit); mVBOQuad.bind(); GLint vertexPositionLoc = mQuadShader.getAttribLocation("vertexPosition"); diff --git a/testbed/src/SceneDemo.h b/testbed/src/SceneDemo.h index f8439431..770a4e26 100644 --- a/testbed/src/SceneDemo.h +++ b/testbed/src/SceneDemo.h @@ -30,8 +30,8 @@ #include "Scene.h" // Constants -const int SHADOWMAP_WIDTH = 1024; -const int SHADOWMAP_HEIGHT = 1024; +const int SHADOWMAP_WIDTH = 2048; +const int SHADOWMAP_HEIGHT = 2048; // Class SceneDemo // Abstract class that represents a 3D scene for the ReactPhysics3D examples. @@ -76,6 +76,14 @@ class SceneDemo : public Scene { openglframework::VertexBufferObject mVBOQuad; + static openglframework::Color mGreyColorDemo; + static openglframework::Color mYellowColorDemo; + static openglframework::Color mBlueColorDemo; + static openglframework::Color mOrangeColorDemo; + static openglframework::Color mPinkColorDemo; + static openglframework::Color mRedColorDemo; + static openglframework::Color mDemoColors[]; + static int mNbDemoColors; // -------------------- Methods -------------------- // From 2a3fe8f8d1d47ebe83aa15758eed4961095096d5 Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Tue, 11 Aug 2015 06:58:55 +0200 Subject: [PATCH 28/36] Handle division by zero in a better way in Vector2, Vector3 getUnit() and normalize() --- src/mathematics/Vector2.cpp | 4 +- src/mathematics/Vector2.h | 4 +- src/mathematics/Vector3.cpp | 4 +- src/mathematics/Vector3.h | 4 +- testbed/src/PhysicsEventListener.cpp | 38 ---------------- testbed/src/PhysicsEventListener.h | 66 ---------------------------- 6 files changed, 12 insertions(+), 108 deletions(-) delete mode 100644 testbed/src/PhysicsEventListener.cpp delete mode 100644 testbed/src/PhysicsEventListener.h diff --git a/src/mathematics/Vector2.cpp b/src/mathematics/Vector2.cpp index ccad70dc..80c0ca34 100644 --- a/src/mathematics/Vector2.cpp +++ b/src/mathematics/Vector2.cpp @@ -54,7 +54,9 @@ Vector2::~Vector2() { Vector2 Vector2::getUnit() const { decimal lengthVector = length(); - assert(lengthVector > MACHINE_EPSILON); + if (lengthVector < MACHINE_EPSILON) { + return *this; + } // Compute and return the unit vector decimal lengthInv = decimal(1.0) / lengthVector; diff --git a/src/mathematics/Vector2.h b/src/mathematics/Vector2.h index 666d60c7..1083d26a 100644 --- a/src/mathematics/Vector2.h +++ b/src/mathematics/Vector2.h @@ -178,7 +178,9 @@ inline decimal Vector2::dot(const Vector2& vector) const { // Normalize the vector inline void Vector2::normalize() { decimal l = length(); - assert(l > std::numeric_limits::epsilon()); + if (l < MACHINE_EPSILON) { + return; + } x /= l; y /= l; } diff --git a/src/mathematics/Vector3.cpp b/src/mathematics/Vector3.cpp index 1e33136a..48bb714f 100644 --- a/src/mathematics/Vector3.cpp +++ b/src/mathematics/Vector3.cpp @@ -55,7 +55,9 @@ Vector3::~Vector3() { Vector3 Vector3::getUnit() const { decimal lengthVector = length(); - assert(lengthVector > MACHINE_EPSILON); + if (lengthVector < MACHINE_EPSILON) { + return *this; + } // Compute and return the unit vector decimal lengthInv = decimal(1.0) / lengthVector; diff --git a/src/mathematics/Vector3.h b/src/mathematics/Vector3.h index f8710fe3..f8ffb77f 100644 --- a/src/mathematics/Vector3.h +++ b/src/mathematics/Vector3.h @@ -193,7 +193,9 @@ inline Vector3 Vector3::cross(const Vector3& vector) const { // Normalize the vector inline void Vector3::normalize() { decimal l = length(); - assert(l > std::numeric_limits::epsilon()); + if (l < MACHINE_EPSILON) { + return; + } x /= l; y /= l; z /= l; diff --git a/testbed/src/PhysicsEventListener.cpp b/testbed/src/PhysicsEventListener.cpp deleted file mode 100644 index 8d34b9b0..00000000 --- a/testbed/src/PhysicsEventListener.cpp +++ /dev/null @@ -1,38 +0,0 @@ - -/******************************************************************************** -* ReactPhysics3D physics library, http://www.reactphysics3d.com * -* Copyright (c) 2010-2015 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -// Libraries -#include "PhysicsEventListener.h" - -// Called when a new contact point is found between two bodies that were separated before -void PhysicsEventListener::beginContact(const rp3d::ContactPointInfo& contact) { - -} - -// Called when a new contact point is found between two bodies -void PhysicsEventListener::newContact(const rp3d::ContactPointInfo& contact) { - -} diff --git a/testbed/src/PhysicsEventListener.h b/testbed/src/PhysicsEventListener.h deleted file mode 100644 index d9227feb..00000000 --- a/testbed/src/PhysicsEventListener.h +++ /dev/null @@ -1,66 +0,0 @@ -/******************************************************************************** -* ReactPhysics3D physics library, http://www.reactphysics3d.com * -* Copyright (c) 2010-2015 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -#ifndef PHYSICSEVENTLISTENER_H -#define PHYSICSEVENTLISTENER_H - -// Libraries -#include "reactphysics3d.h" -#include "openglframework.h" - -// Structure ContactPoint -struct ContactPoint { - - public: - openglframework::Vector3 point; - - /// Constructor - ContactPoint(const openglframework::Vector3& contactPoint) : point(contactPoint) { - - } -}; - -// Class PhysicsEventListener -// This class inherits from the EventListener class -// of ReactPhysics3D in order to be notified of events -// that occured in a physics world -class PhysicsEventListener : rp3d::EventListener { - - private: - - // Current contact points - std::vector mCurrentContactPoints; - - public: - - /// Called when a new contact point is found between two bodies that were separated before - virtual void beginContact(const rp3d::ContactPointInfo& contact); - - /// Called when a new contact point is found between two bodies - virtual void newContact(const rp3d::ContactPointInfo& contact); -}; - -#endif - From a4e28ddcf1a01ca11edac51a2438a8c78e9e493f Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Tue, 11 Aug 2015 18:32:06 +0200 Subject: [PATCH 29/36] Add getContactsList() method to DynamicsWorld --- src/engine/DynamicsWorld.cpp | 20 ++++++++++++++++++++ src/engine/DynamicsWorld.h | 3 +++ 2 files changed, 23 insertions(+) diff --git a/src/engine/DynamicsWorld.cpp b/src/engine/DynamicsWorld.cpp index 97fcfcda..7fe62461 100644 --- a/src/engine/DynamicsWorld.cpp +++ b/src/engine/DynamicsWorld.cpp @@ -952,3 +952,23 @@ void DynamicsWorld::testCollision(CollisionCallback* callback) { // Perform the collision detection and report contacts mCollisionDetection.reportCollisionBetweenShapes(callback, emptySet, emptySet); } + +/// Return the list of all contacts of the world +std::vector DynamicsWorld::getContactsList() const { + + std::vector contactManifolds; + + // For each currently overlapping pair of bodies + std::map::const_iterator it; + for (it = mCollisionDetection.mOverlappingPairs.begin(); + it != mCollisionDetection.mOverlappingPairs.end(); ++it) { + + OverlappingPair* pair = it->second; + + // Get the contact manifold + contactManifolds.push_back(pair->getContactManifold()); + } + + // Return all the contact manifold + return contactManifolds; +} diff --git a/src/engine/DynamicsWorld.h b/src/engine/DynamicsWorld.h index 6e39416a..519ff6d9 100644 --- a/src/engine/DynamicsWorld.h +++ b/src/engine/DynamicsWorld.h @@ -297,6 +297,9 @@ class DynamicsWorld : public CollisionWorld { /// Test and report collisions between all shapes of the world virtual void testCollision(CollisionCallback* callback); + /// Return the list of all contacts of the world + std::vector getContactsList() const; + // -------------------- Friendship -------------------- // friend class RigidBody; From ce80426a2c713daac80465d97ee5318e42f9855a Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Tue, 11 Aug 2015 18:32:45 +0200 Subject: [PATCH 30/36] Shadow map issue --- testbed/CMakeLists.txt | 2 - testbed/common/VisualContactPoint.cpp | 29 ++---- testbed/common/VisualContactPoint.h | 5 +- .../collisionshapes/CollisionShapesScene.cpp | 4 +- .../collisionshapes/CollisionShapesScene.h | 22 +++-- testbed/scenes/cubes/CubesScene.cpp | 10 +- testbed/scenes/cubes/CubesScene.h | 7 +- testbed/scenes/joints/JointsScene.cpp | 4 +- testbed/scenes/joints/JointsScene.h | 8 ++ testbed/scenes/raycast/RaycastScene.cpp | 4 + testbed/scenes/raycast/RaycastScene.h | 32 ++++++- testbed/shaders/phong.frag | 28 +++++- testbed/src/Gui.cpp | 7 ++ testbed/src/Gui.h | 2 +- testbed/src/Scene.cpp | 3 +- testbed/src/Scene.h | 25 ++++- testbed/src/SceneDemo.cpp | 96 ++++++++++++++++++- testbed/src/SceneDemo.h | 24 ++++- testbed/src/TestbedApplication.cpp | 6 +- testbed/src/TestbedApplication.h | 11 +++ 20 files changed, 268 insertions(+), 61 deletions(-) diff --git a/testbed/CMakeLists.txt b/testbed/CMakeLists.txt index 1696484d..4d3ecdac 100644 --- a/testbed/CMakeLists.txt +++ b/testbed/CMakeLists.txt @@ -43,8 +43,6 @@ SET(TESTBED_SOURCES src/SceneDemo.cpp src/Timer.h src/Timer.cpp - src/PhysicsEventListener.h - src/PhysicsEventListener.cpp ) # IMGUI source files diff --git a/testbed/common/VisualContactPoint.cpp b/testbed/common/VisualContactPoint.cpp index fa4a177b..c3048a69 100644 --- a/testbed/common/VisualContactPoint.cpp +++ b/testbed/common/VisualContactPoint.cpp @@ -33,7 +33,6 @@ openglframework::VertexBufferObject VisualContactPoint::mVBOIndices(GL_ELEMENT_A openglframework::VertexArrayObject VisualContactPoint::mVAO; int VisualContactPoint::mNbTotalPoints = 0; openglframework::Mesh VisualContactPoint::mMesh; -int VisualContactPoint::totalNbBoxes = 0; // Constructor VisualContactPoint::VisualContactPoint(const openglframework::Vector3& position, @@ -42,31 +41,11 @@ VisualContactPoint::VisualContactPoint(const openglframework::Vector3& position, // Initialize the position where the mesh will be rendered translateWorld(position); - - // Create the VBOs and VAO - if (totalNbBoxes == 0) { - createStaticData(meshFolderPath); - createVBOAndVAO(); - } - - totalNbBoxes++; } // Destructor VisualContactPoint::~VisualContactPoint() { - if (totalNbBoxes == 1) { - - // Destroy the VBOs and VAO - mVBOIndices.destroy(); - mVBOVertices.destroy(); - mVBONormals.destroy(); - mVAO.destroy(); - - destroyStaticData(); - } - - totalNbBoxes--; } // Load and initialize the mesh for all the contact points @@ -79,11 +58,19 @@ void VisualContactPoint::createStaticData(const std::string& meshFolderPath) { mMesh.calculateNormals(); mMesh.scaleVertices(VISUAL_CONTACT_POINT_RADIUS); + + createVBOAndVAO(); } // Destroy the mesh for the contact points void VisualContactPoint::destroyStaticData() { + // Destroy the VBOs and VAO + mVBOIndices.destroy(); + mVBOVertices.destroy(); + mVBONormals.destroy(); + mVAO.destroy(); + mMesh.destroy(); } diff --git a/testbed/common/VisualContactPoint.h b/testbed/common/VisualContactPoint.h index 9294a757..fb2e7012 100644 --- a/testbed/common/VisualContactPoint.h +++ b/testbed/common/VisualContactPoint.h @@ -29,7 +29,7 @@ // Libraries #include "openglframework.h" -const float VISUAL_CONTACT_POINT_RADIUS = 0.1f; +const float VISUAL_CONTACT_POINT_RADIUS = 0.2f; // Class VisualContactPoint class VisualContactPoint : public openglframework::Object3D { @@ -56,9 +56,6 @@ class VisualContactPoint : public openglframework::Object3D { /// Vertex Array Object for the vertex data static openglframework::VertexArrayObject mVAO; - /// Total number of points created - static int totalNbBoxes; - /// Color openglframework::Color mColor; diff --git a/testbed/scenes/collisionshapes/CollisionShapesScene.cpp b/testbed/scenes/collisionshapes/CollisionShapesScene.cpp index aa0e1ca0..b63cb03c 100644 --- a/testbed/scenes/collisionshapes/CollisionShapesScene.cpp +++ b/testbed/scenes/collisionshapes/CollisionShapesScene.cpp @@ -233,7 +233,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name) // Set the box color mFloor->setColor(mGreyColorDemo); - mFloor->setSleepingColor(mRedColorDemo); + mFloor->setSleepingColor(mGreyColorDemo); // The floor must be a static rigid body mFloor->getRigidBody()->setType(rp3d::STATIC); @@ -361,6 +361,8 @@ void CollisionShapesScene::updatePhysics() { // Take a step for the simulation void CollisionShapesScene::update() { + SceneDemo::update(); + // Update the position and orientation of the boxes for (std::vector::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { diff --git a/testbed/scenes/collisionshapes/CollisionShapesScene.h b/testbed/scenes/collisionshapes/CollisionShapesScene.h index 8c7a13e1..d7f41726 100644 --- a/testbed/scenes/collisionshapes/CollisionShapesScene.h +++ b/testbed/scenes/collisionshapes/CollisionShapesScene.h @@ -45,13 +45,13 @@ namespace collisionshapesscene { // Constants const float SCENE_RADIUS = 30.0f; -const int NB_BOXES = 5; -const int NB_CUBES = 4; -const int NB_CONES = 4; -const int NB_CYLINDERS = 6; -const int NB_CAPSULES = 5; -const int NB_MESHES = 7; -const int NB_COMPOUND_SHAPES = 3; +const int NB_BOXES = 4; +const int NB_CUBES = 6; +const int NB_CONES = 6; +const int NB_CYLINDERS = 5; +const int NB_CAPSULES = 4; +const int NB_MESHES = 5; +const int NB_COMPOUND_SHAPES = 4; const openglframework::Vector3 BOX_SIZE(2, 2, 2); const float SPHERE_RADIUS = 1.5f; const float CONE_RADIUS = 2.0f; @@ -122,8 +122,16 @@ class CollisionShapesScene : public SceneDemo { /// Reset the scene virtual void reset(); + + /// Return all the contact points of the scene + virtual std::vector getContactPoints() const; }; +// Return all the contact points of the scene +inline std::vector CollisionShapesScene::getContactPoints() const { + return computeContactPointsOfWorld(mDynamicsWorld); +} + } #endif diff --git a/testbed/scenes/cubes/CubesScene.cpp b/testbed/scenes/cubes/CubesScene.cpp index 05c05063..0898801f 100644 --- a/testbed/scenes/cubes/CubesScene.cpp +++ b/testbed/scenes/cubes/CubesScene.cpp @@ -149,6 +149,8 @@ void CubesScene::updatePhysics() { // Update the scene void CubesScene::update() { + SceneDemo::update(); + // Update the position and orientation of the boxes for (std::vector::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { @@ -198,11 +200,3 @@ void CubesScene::reset() { mBoxes[i]->resetTransform(transform); } } - -// Return all the contact points of the scene -std::vector CubesScene::getContactPoints() const { - - std::vector contactPoints; - - return contactPoints; -} diff --git a/testbed/scenes/cubes/CubesScene.h b/testbed/scenes/cubes/CubesScene.h index 05331724..57dfb99f 100644 --- a/testbed/scenes/cubes/CubesScene.h +++ b/testbed/scenes/cubes/CubesScene.h @@ -83,9 +83,14 @@ class CubesScene : public SceneDemo { virtual void reset(); /// Return all the contact points of the scene - std::vector virtual getContactPoints() const; + virtual std::vector getContactPoints() const; }; +// Return all the contact points of the scene +inline std::vector CubesScene::getContactPoints() const { + return computeContactPointsOfWorld(mDynamicsWorld); +} + } #endif diff --git a/testbed/scenes/joints/JointsScene.cpp b/testbed/scenes/joints/JointsScene.cpp index 9406ee21..dd3255d4 100644 --- a/testbed/scenes/joints/JointsScene.cpp +++ b/testbed/scenes/joints/JointsScene.cpp @@ -145,6 +145,8 @@ void JointsScene::updatePhysics() { // Take a step for the simulation void JointsScene::update() { + SceneDemo::update(); + // Update the position and orientation of the boxes mSliderJointBottomBox->updateTransform(mInterpolationFactor); mSliderJointTopBox->updateTransform(mInterpolationFactor); @@ -474,7 +476,7 @@ void JointsScene::createFloor() { // Set the box color mFloor->setColor(mGreyColorDemo); - mFloor->setSleepingColor(mRedColorDemo); + mFloor->setSleepingColor(mGreyColorDemo); // The floor must be a static rigid body mFloor->getRigidBody()->setType(rp3d::STATIC); diff --git a/testbed/scenes/joints/JointsScene.h b/testbed/scenes/joints/JointsScene.h index b2d22c07..39ceecb2 100644 --- a/testbed/scenes/joints/JointsScene.h +++ b/testbed/scenes/joints/JointsScene.h @@ -135,8 +135,16 @@ class JointsScene : public SceneDemo { /// Reset the scene virtual void reset(); + + /// Return all the contact points of the scene + virtual std::vector getContactPoints() const; }; +// Return all the contact points of the scene +inline std::vector JointsScene::getContactPoints() const { + return computeContactPointsOfWorld(mDynamicsWorld); +} + } #endif diff --git a/testbed/scenes/raycast/RaycastScene.cpp b/testbed/scenes/raycast/RaycastScene.cpp index ed60e7df..c1eef947 100644 --- a/testbed/scenes/raycast/RaycastScene.cpp +++ b/testbed/scenes/raycast/RaycastScene.cpp @@ -36,6 +36,8 @@ RaycastScene::RaycastScene(const std::string& name) mMeshFolderPath("meshes/"), mRaycastManager(mPhongShader, mMeshFolderPath), mVBOVertices(GL_ARRAY_BUFFER) { + mIsContactPointsDisplayed = true; + // Compute the radius and the center of the scene openglframework::Vector3 center(0, 0, 0); @@ -286,6 +288,8 @@ void RaycastScene::update() { // callback class in argument. mCollisionWorld->raycast(ray, &mRaycastManager); } + + SceneDemo::update(); } // Render the scene diff --git a/testbed/scenes/raycast/RaycastScene.h b/testbed/scenes/raycast/RaycastScene.h index 67e0f873..bccfb9cb 100644 --- a/testbed/scenes/raycast/RaycastScene.h +++ b/testbed/scenes/raycast/RaycastScene.h @@ -66,7 +66,7 @@ class RaycastManager : public rp3d::RaycastCallback { private: /// All the visual contact points - std::vector mHitPoints; + std::vector mHitPoints; /// All the normals at hit points std::vector mNormals; @@ -88,8 +88,7 @@ class RaycastManager : public rp3d::RaycastCallback { virtual rp3d::decimal notifyRaycastHit(const rp3d::RaycastInfo& raycastInfo) { rp3d::Vector3 hitPos = raycastInfo.worldPoint; openglframework::Vector3 position(hitPos.x, hitPos.y, hitPos.z); - VisualContactPoint* point = new VisualContactPoint(position, mMeshFolderPath); - mHitPoints.push_back(point); + mHitPoints.push_back(ContactPoint(position)); // Create a line to display the normal at hit point rp3d::Vector3 n = raycastInfo.worldNormal; @@ -103,11 +102,13 @@ class RaycastManager : public rp3d::RaycastCallback { void render(const openglframework::Matrix4& worldToCameraMatrix, bool showNormals) { + /* // Render all the raycast hit points - for (std::vector::iterator it = mHitPoints.begin(); + for (std::vector::iterator it = mHitPoints.begin(); it != mHitPoints.end(); ++it) { (*it)->render(mShader, worldToCameraMatrix); } + */ if (showNormals) { @@ -121,11 +122,13 @@ class RaycastManager : public rp3d::RaycastCallback { void resetPoints() { + /* // Destroy all the visual contact points for (std::vector::iterator it = mHitPoints.begin(); it != mHitPoints.end(); ++it) { delete (*it); } + */ mHitPoints.clear(); // Destroy all the normals @@ -135,6 +138,10 @@ class RaycastManager : public rp3d::RaycastCallback { } mNormals.clear(); } + + std::vector getHitPoints() const { + return mHitPoints; + } }; // Class RaycastScene @@ -224,6 +231,12 @@ class RaycastScene : public SceneDemo { /// Enabled/Disable the shadow mapping void virtual setIsShadowMappingEnabled(bool isShadowMappingEnabled); + + /// Display/Hide the contact points + void virtual setIsContactPointsDisplayed(bool display); + + /// Return all the contact points of the scene + virtual std::vector getContactPoints() const; }; // Display or not the surface normals at hit points @@ -233,10 +246,19 @@ inline void RaycastScene::showHideNormals() { // Enabled/Disable the shadow mapping inline void RaycastScene::setIsShadowMappingEnabled(bool isShadowMappingEnabled) { - SceneDemo::setIsShadowMappingEnabled(false); } +// Display/Hide the contact points +inline void RaycastScene::setIsContactPointsDisplayed(bool display) { + SceneDemo::setIsContactPointsDisplayed(true); +} + +// Return all the contact points of the scene +inline std::vector RaycastScene::getContactPoints() const { + return mRaycastManager.getHitPoints(); +} + } #endif diff --git a/testbed/shaders/phong.frag b/testbed/shaders/phong.frag index e34c8abd..cbf7f0e4 100644 --- a/testbed/shaders/phong.frag +++ b/testbed/shaders/phong.frag @@ -34,6 +34,7 @@ uniform sampler2D shadowMapSampler; // Shadow map texture sampler uniform bool isTexture; // True if we need to use the texture uniform vec4 vertexColor; // Vertex color uniform bool isShadowEnabled; // True if shadow mapping is enabled +uniform vec2 shadowMapDimension; // Shadow map dimension // In variables in vec3 vertexPosCameraSpace; // Camera-space position of the vertex @@ -44,6 +45,13 @@ in vec4 shadowMapCoords; // Shadow map texture coords // Out variable out vec4 color; // Output color +// Texture for PCF Shadow mapping +float textureLookupPCF(sampler2D map, vec2 texCoords, vec2 offset) +{ + vec2 shadowMapScale = vec2(1.0, 1.0) / shadowMapDimension; + return texture(map, texCoords.xy + offset * shadowMapScale).r; +} + void main() { // Compute the ambient term @@ -61,18 +69,36 @@ void main() { float diffuseFactor = max(dot(N, L0), 0.0); vec3 diffuse = light0DiffuseColor * diffuseFactor * textureColor; + // Compute shadow factor float shadow = 1.0; if (isShadowEnabled) { + shadow = 0.0; float bias = 0.0003; float shadowBias = -0.000; vec4 shadowMapUV = shadowMapCoords; shadowMapUV.z -= shadowBias; - vec4 shadowMapCoordsOverW = shadowMapUV / shadowMapUV.w ; + vec4 shadowMapCoordsOverW = shadowMapUV / shadowMapUV.w; + + /* + // PCF Shadow Mapping + for (float i=-1; i<=1; i++) { + for (float j=-1; j<=1; j++) { + float distInShadowMap = textureLookupPCF(shadowMapSampler, shadowMapCoordsOverW.xy, vec2(i, j)) + bias; + if (shadowMapCoords.w > 0) { + shadow += distInShadowMap < shadowMapCoordsOverW.z ? 0.5 : 1.0; + } + } + } + shadow /= 9.0; + */ + + float distanceInShadowMap = texture(shadowMapSampler, shadowMapCoordsOverW.xy).r + bias; if (shadowMapCoords.w > 0) { shadow = distanceInShadowMap < shadowMapCoordsOverW.z ? 0.5 : 1.0; } + } // Compute the final color diff --git a/testbed/src/Gui.cpp b/testbed/src/Gui.cpp index d45e0fce..a80ed525 100644 --- a/testbed/src/Gui.cpp +++ b/testbed/src/Gui.cpp @@ -299,6 +299,13 @@ void Gui::displayRenderingPane() { imguiVerticalSpace(15); + + // Display/Hide contact points + bool toggleContactPoints = imguiCheck("Contacts", app.mIsContactPointsDisplayed); + if (toggleContactPoints) { + app.displayContactPoints(!app.mIsContactPointsDisplayed); + } + // Enabled/Disable VSync bool toggleVSync = imguiCheck("V Sync", app.mIsVSyncEnabled); if (toggleVSync) { diff --git a/testbed/src/Gui.h b/testbed/src/Gui.h index c794d57d..19d5dc07 100644 --- a/testbed/src/Gui.h +++ b/testbed/src/Gui.h @@ -37,7 +37,7 @@ const float GUI_SCALING = 2.0f; const int LEFT_PANE_WIDTH = 300; const int LEFT_PANE_HEADER_HEIGHT = 90; -const double TIME_INTERVAL_DISPLAY_PROFILING_INFO = 0.2; +const double TIME_INTERVAL_DISPLAY_PROFILING_INFO = 0.3; using namespace openglframework; diff --git a/testbed/src/Scene.cpp b/testbed/src/Scene.cpp index 65ac681f..7e71968b 100644 --- a/testbed/src/Scene.cpp +++ b/testbed/src/Scene.cpp @@ -32,7 +32,8 @@ using namespace openglframework; // Constructor Scene::Scene(const std::string& name, bool isShadowMappingEnabled) : mName(name), mInterpolationFactor(0.0f), mViewportX(0), mViewportY(0), - mViewportWidth(0), mViewportHeight(0), mIsShadowMappingEnabled(isShadowMappingEnabled) { + mViewportWidth(0), mViewportHeight(0), mIsShadowMappingEnabled(isShadowMappingEnabled), + mIsContactPointsDisplayed(true) { } diff --git a/testbed/src/Scene.h b/testbed/src/Scene.h index a558f95b..2091caac 100644 --- a/testbed/src/Scene.h +++ b/testbed/src/Scene.h @@ -28,7 +28,18 @@ // Libraries #include "openglframework.h" -#include "PhysicsEventListener.h" + +// Structure ContactPoint +struct ContactPoint { + + public: + openglframework::Vector3 point; + + /// Constructor + ContactPoint(const openglframework::Vector3& pointWorld) : point(pointWorld) { + + } +}; /// Structure EngineSettings /// This structure contains several physics engine parameters @@ -94,6 +105,9 @@ class Scene { /// True if the shadow mapping is enabled bool mIsShadowMappingEnabled; + /// True if contact points are displayed + bool mIsContactPointsDisplayed; + // -------------------- Methods -------------------- // /// Set the scene position (where the camera needs to look at) @@ -106,7 +120,6 @@ class Scene { bool mapMouseCoordinatesToSphere(double xMouse, double yMouse, openglframework::Vector3& spherePoint) const; - /// Zoom the camera void zoom(float zoomDiff); @@ -183,6 +196,9 @@ class Scene { /// Enabled/Disable the shadow mapping void virtual setIsShadowMappingEnabled(bool isShadowMappingEnabled); + /// Display/Hide the contact points + void virtual setIsContactPointsDisplayed(bool display); + /// Return all the contact points of the scene std::vector virtual getContactPoints() const; }; @@ -246,6 +262,11 @@ inline void Scene::setIsShadowMappingEnabled(bool isShadowMappingEnabled) { mIsShadowMappingEnabled = isShadowMappingEnabled; } +// Display/Hide the contact points +inline void Scene::setIsContactPointsDisplayed(bool display) { + mIsContactPointsDisplayed = display; +} + // Return all the contact points of the scene inline std::vector Scene::getContactPoints() const { diff --git a/testbed/src/SceneDemo.cpp b/testbed/src/SceneDemo.cpp index 8be46a64..ea8c9305 100644 --- a/testbed/src/SceneDemo.cpp +++ b/testbed/src/SceneDemo.cpp @@ -47,7 +47,7 @@ SceneDemo::SceneDemo(const std::string& name, float sceneRadius, bool isShadowMa mDepthShader("shaders/depth.vert", "shaders/depth.frag"), mPhongShader("shaders/phong.vert", "shaders/phong.frag"), mQuadShader("shaders/quad.vert", "shaders/quad.frag"), - mVBOQuad(GL_ARRAY_BUFFER) { + mVBOQuad(GL_ARRAY_BUFFER), mMeshFolderPath("meshes/") { shadowMapTextureLevel++; @@ -74,6 +74,8 @@ SceneDemo::SceneDemo(const std::string& name, float sceneRadius, bool isShadowMa } createQuadVBO(); + + VisualContactPoint::createStaticData(mMeshFolderPath); } // Destructor @@ -83,13 +85,23 @@ SceneDemo::~SceneDemo() { mFBOShadowMap.destroy(); mVBOQuad.destroy(); + // Destroy the contact points + removeAllContactPoints(); + + VisualContactPoint::destroyStaticData(); +} + +// Update the scene +void SceneDemo::update() { + + // Update the contact points + updateContactPoints(); } // Render the scene (in multiple passes for shadow mapping) void SceneDemo::render() { const Color& diffCol = mLight0.getDiffuseColor(); - const Color& specCol = mLight0.getSpecularColor(); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); @@ -154,6 +166,7 @@ void SceneDemo::render() { mPhongShader.setVector3Uniform("light0DiffuseColor", Vector3(diffCol.r, diffCol.g, diffCol.b)); mPhongShader.setIntUniform("shadowMapSampler", textureUnit); mPhongShader.setIntUniform("isShadowEnabled", mIsShadowMappingEnabled); + //mPhongShader.setVector2Uniform("shadowMapDimension", Vector2(SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT)); // Set the viewport to render the scene glViewport(mViewportX, mViewportY, mViewportWidth, mViewportHeight); @@ -167,10 +180,15 @@ void SceneDemo::render() { // Render the objects of the scene renderSinglePass(mPhongShader, worldToCameraMatrix); + // Render the contact points + if (mIsContactPointsDisplayed) { + renderContactPoints(mPhongShader, worldToCameraMatrix); + } + if (mIsShadowMappingEnabled) mShadowMapTexture.unbind(); mPhongShader.unbind(); - //drawTextureQuad(); + drawTextureQuad(); } // Create the Shadow map FBO and texture @@ -194,6 +212,7 @@ void SceneDemo::createShadowMapFBOAndTexture() { mIsShadowMappingInitialized = true; } +// Used for debugging shadow maps void SceneDemo::createQuadVBO() { mVAOQuad.create(); @@ -254,3 +273,74 @@ void SceneDemo::drawTextureQuad() { mQuadShader.unbind(); mVAOQuad.unbind(); } + +// Gather and create contact points +void SceneDemo::updateContactPoints() { + + // Remove the previous contact points + removeAllContactPoints(); + + if (mIsContactPointsDisplayed) { + + // Get the current contact points of the scene + std::vector contactPoints = getContactPoints(); + + // For each contact point + std::vector::const_iterator it; + for (it = contactPoints.begin(); it != contactPoints.end(); ++it) { + + // Create a visual contact point for rendering + VisualContactPoint* point = new VisualContactPoint(it->point, mMeshFolderPath); + mContactPoints.push_back(point); + } + } +} + +// Render the contact points +void SceneDemo::renderContactPoints(openglframework::Shader& shader, + const openglframework::Matrix4& worldToCameraMatrix) { + + // Render all the raycast hit points + for (std::vector::iterator it = mContactPoints.begin(); + it != mContactPoints.end(); ++it) { + (*it)->render(shader, worldToCameraMatrix); + } +} + +void SceneDemo::removeAllContactPoints() { + + // Destroy all the visual contact points + for (std::vector::iterator it = mContactPoints.begin(); + it != mContactPoints.end(); ++it) { + delete (*it); + } + mContactPoints.clear(); +} + +// Return all the contact points of the scene +std::vector SceneDemo::computeContactPointsOfWorld(const rp3d::DynamicsWorld* world) const { + + std::vector contactPoints; + + // Get the list of contact manifolds from the world + std::vector manifolds = world->getContactsList(); + + // For each contact manifold + std::vector::const_iterator it; + for (it = manifolds.begin(); it != manifolds.end(); ++it) { + + const rp3d::ContactManifold* manifold = *it; + + // For each contact point of the manifold + for (uint i=0; igetNbContactPoints(); i++) { + + rp3d::ContactPoint* contactPoint = manifold->getContactPoint(i); + rp3d::Vector3 point = contactPoint->getWorldPointOnBody1(); + ContactPoint contact(openglframework::Vector3(point.x, point.y, point.z)); + contactPoints.push_back(contact); + } + + } + + return contactPoints; +} diff --git a/testbed/src/SceneDemo.h b/testbed/src/SceneDemo.h index 770a4e26..5ec37b45 100644 --- a/testbed/src/SceneDemo.h +++ b/testbed/src/SceneDemo.h @@ -28,6 +28,8 @@ // Libraries #include "Scene.h" +#include "VisualContactPoint.h" +#include "reactphysics3d.h" // Constants const int SHADOWMAP_WIDTH = 2048; @@ -56,6 +58,9 @@ class SceneDemo : public Scene { static int shadowMapTextureLevel; + /// All the visual contact points + std::vector mContactPoints; + /// Shadow map bias matrix openglframework::Matrix4 mShadowMapBiasMatrix; @@ -85,17 +90,28 @@ class SceneDemo : public Scene { static openglframework::Color mDemoColors[]; static int mNbDemoColors; + std::string mMeshFolderPath; + // -------------------- Methods -------------------- // // Create the Shadow map FBO and texture void createShadowMapFBOAndTexture(); - // TODO : Delete this + // Used for debugging shadow maps void createQuadVBO(); // TODO : Delete this void drawTextureQuad(); + // Update the contact points + void updateContactPoints(); + + // Render the contact points + void renderContactPoints(openglframework::Shader& shader, + const openglframework::Matrix4& worldToCameraMatrix); + + void removeAllContactPoints(); + public: // -------------------- Methods -------------------- // @@ -106,6 +122,9 @@ class SceneDemo : public Scene { /// Destructor virtual ~SceneDemo(); + /// Update the scene + virtual void update(); + /// Render the scene (possibly in multiple passes for shadow mapping) virtual void render(); @@ -115,6 +134,9 @@ class SceneDemo : public Scene { /// Enabled/Disable the shadow mapping void virtual setIsShadowMappingEnabled(bool isShadowMappingEnabled); + + /// Return all the contact points of the scene + std::vector computeContactPointsOfWorld(const rp3d::DynamicsWorld* world) const; }; // Enabled/Disable the shadow mapping diff --git a/testbed/src/TestbedApplication.cpp b/testbed/src/TestbedApplication.cpp index 973d648e..fc958671 100644 --- a/testbed/src/TestbedApplication.cpp +++ b/testbed/src/TestbedApplication.cpp @@ -63,13 +63,12 @@ TestbedApplication::TestbedApplication() mWindowToFramebufferRatio = Vector2(1, 1); mIsShadowMappingEnabled = true; mIsVSyncEnabled = true; + mIsContactPointsDisplayed = false; } // Destructor TestbedApplication::~TestbedApplication() { - // TODO : Check that this method is called at the end - // Destroy all the scenes destroyScenes(); @@ -242,6 +241,9 @@ void TestbedApplication::update() { // Enable/Disable shadow mapping mCurrentScene->setIsShadowMappingEnabled(mIsShadowMappingEnabled); + // Display/Hide contact points + mCurrentScene->setIsContactPointsDisplayed(mIsContactPointsDisplayed); + // Update the scene mCurrentScene->update(); } diff --git a/testbed/src/TestbedApplication.h b/testbed/src/TestbedApplication.h index 75d14918..6abd7b8a 100644 --- a/testbed/src/TestbedApplication.h +++ b/testbed/src/TestbedApplication.h @@ -98,6 +98,9 @@ class TestbedApplication { /// True if shadow mapping is enabled bool mIsShadowMappingEnabled; + /// True if contact points are displayed + bool mIsContactPointsDisplayed; + /// True if vsync is enabled bool mIsVSyncEnabled; @@ -175,6 +178,9 @@ class TestbedApplication { /// Enable/Disable shadow mapping void enableShadows(bool enable); + /// Display/Hide contact points + void displayContactPoints(bool display); + public : // -------------------- Methods -------------------- // @@ -239,6 +245,11 @@ inline void TestbedApplication::enableShadows(bool enable) { mIsShadowMappingEnabled = enable; } +/// Display/Hide contact points +inline void TestbedApplication::displayContactPoints(bool display) { + mIsContactPointsDisplayed = display; +} + // Enable/Disable Vertical synchronization inline void TestbedApplication::enableVSync(bool enable) { mIsVSyncEnabled = enable; From 06e68baa391677c5dfc1e1627556ced60112f7b1 Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Tue, 11 Aug 2015 21:40:07 +0200 Subject: [PATCH 31/36] Fix rendering issue in RaycastScene --- testbed/common/VisualContactPoint.cpp | 19 ++++++++--- testbed/common/VisualContactPoint.h | 3 ++ testbed/scenes/raycast/RaycastScene.cpp | 42 +++++++++---------------- testbed/scenes/raycast/RaycastScene.h | 28 ----------------- testbed/src/SceneDemo.cpp | 2 +- 5 files changed, 32 insertions(+), 62 deletions(-) diff --git a/testbed/common/VisualContactPoint.cpp b/testbed/common/VisualContactPoint.cpp index c3048a69..b0d5351d 100644 --- a/testbed/common/VisualContactPoint.cpp +++ b/testbed/common/VisualContactPoint.cpp @@ -33,6 +33,7 @@ openglframework::VertexBufferObject VisualContactPoint::mVBOIndices(GL_ELEMENT_A openglframework::VertexArrayObject VisualContactPoint::mVAO; int VisualContactPoint::mNbTotalPoints = 0; openglframework::Mesh VisualContactPoint::mMesh; +bool VisualContactPoint::mStaticDataCreated = false; // Constructor VisualContactPoint::VisualContactPoint(const openglframework::Vector3& position, @@ -51,6 +52,8 @@ VisualContactPoint::~VisualContactPoint() { // Load and initialize the mesh for all the contact points void VisualContactPoint::createStaticData(const std::string& meshFolderPath) { + if (mStaticDataCreated) return; + // Load the mesh from a file openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "sphere.obj", mMesh); @@ -60,11 +63,15 @@ void VisualContactPoint::createStaticData(const std::string& meshFolderPath) { mMesh.scaleVertices(VISUAL_CONTACT_POINT_RADIUS); createVBOAndVAO(); + + mStaticDataCreated = true; } // Destroy the mesh for the contact points void VisualContactPoint::destroyStaticData() { + if (!mStaticDataCreated) return; + // Destroy the VBOs and VAO mVBOIndices.destroy(); mVBOVertices.destroy(); @@ -72,15 +79,22 @@ void VisualContactPoint::destroyStaticData() { mVAO.destroy(); mMesh.destroy(); + + mStaticDataCreated = false; } // Render the sphere at the correct position and with the correct orientation void VisualContactPoint::render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix) { + // Bind the VAO + mVAO.bind(); + // Bind the shader shader.bind(); + mVBOVertices.bind(); + // Set the model to camera matrix shader.setMatrix4x4Uniform("localToWorldMatrix", mTransformMatrix); shader.setMatrix4x4Uniform("worldToCameraMatrix", worldToCameraMatrix); @@ -96,11 +110,6 @@ void VisualContactPoint::render(openglframework::Shader& shader, openglframework::Vector4 color(mColor.r, mColor.g, mColor.b, mColor.a); shader.setVector4Uniform("vertexColor", color, false); - // Bind the VAO - mVAO.bind(); - - mVBOVertices.bind(); - // Get the location of shader attribute variables GLint vertexPositionLoc = shader.getAttribLocation("vertexPosition"); GLint vertexNormalLoc = shader.getAttribLocation("vertexNormal", false); diff --git a/testbed/common/VisualContactPoint.h b/testbed/common/VisualContactPoint.h index fb2e7012..ed4e03a6 100644 --- a/testbed/common/VisualContactPoint.h +++ b/testbed/common/VisualContactPoint.h @@ -56,6 +56,9 @@ class VisualContactPoint : public openglframework::Object3D { /// Vertex Array Object for the vertex data static openglframework::VertexArrayObject mVAO; + /// True if static data (VBO, VAO) has been created already + static bool mStaticDataCreated; + /// Color openglframework::Color mColor; diff --git a/testbed/scenes/raycast/RaycastScene.cpp b/testbed/scenes/raycast/RaycastScene.cpp index c1eef947..c437df5b 100644 --- a/testbed/scenes/raycast/RaycastScene.cpp +++ b/testbed/scenes/raycast/RaycastScene.cpp @@ -296,9 +296,14 @@ void RaycastScene::update() { void RaycastScene::renderSinglePass(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix) { + // Bind the VAO + mVAO.bind(); + // Bind the shader shader.bind(); + mVBOVertices.bind(); + // Set the model to camera matrix const Matrix4 localToCameraMatrix = Matrix4::identity(); shader.setMatrix4x4Uniform("localToWorldMatrix", localToCameraMatrix); @@ -314,12 +319,19 @@ void RaycastScene::renderSinglePass(openglframework::Shader& shader, openglframework::Vector4 color(1, 0, 0, 1); shader.setVector4Uniform("vertexColor", color, false); - // Bind the VAO - mVAO.bind(); + // Get the location of shader attribute variables + GLint vertexPositionLoc = shader.getAttribLocation("vertexPosition"); + + glEnableVertexAttribArray(vertexPositionLoc); + glVertexAttribPointer(vertexPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL); // Draw the lines glDrawArrays(GL_LINES, 0, NB_RAYS); + glDisableVertexAttribArray(vertexPositionLoc); + + mVBOVertices.unbind(); + // Unbind the VAO mVAO.unbind(); @@ -335,27 +347,6 @@ void RaycastScene::renderSinglePass(openglframework::Shader& shader, if (mDumbbell->getCollisionBody()->isActive()) mDumbbell->render(shader, worldToCameraMatrix); //mPhongShader.unbind(); - shader.bind(); - - openglframework::Vector4 redColor(1, 0, 0, 1); - shader.setVector4Uniform("vertexColor", redColor, false); - - // Render all the raycast hit points - mRaycastManager.render(worldToCameraMatrix, mAreNormalsDisplayed); - - shader.unbind(); - shader.bind(); - - openglframework::Vector4 blueColor(0, 0.62, 0.92, 1); - shader.setVector4Uniform("vertexColor", blueColor, false); - - // Render the lines - for (std::vector::iterator it = mLines.begin(); it != mLines.end(); - ++it) { - (*it)->render(shader, worldToCameraMatrix); - } - - // Unbind the shader shader.unbind(); } @@ -366,9 +357,6 @@ void RaycastScene::createVBOAndVAO(openglframework::Shader& shader) { // Bind the shader shader.bind(); - // Get the location of shader attribute variables - GLint vertexPositionLoc = shader.getAttribLocation("vertexPosition"); - // Create the VBO for the vertices data mVBOVertices.create(); mVBOVertices.bind(); @@ -382,8 +370,6 @@ void RaycastScene::createVBOAndVAO(openglframework::Shader& shader) { // Bind the VBO of vertices mVBOVertices.bind(); - glEnableVertexAttribArray(vertexPositionLoc); - glVertexAttribPointer(vertexPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL); // Unbind the VAO mVAO.unbind(); diff --git a/testbed/scenes/raycast/RaycastScene.h b/testbed/scenes/raycast/RaycastScene.h index bccfb9cb..84cb0702 100644 --- a/testbed/scenes/raycast/RaycastScene.h +++ b/testbed/scenes/raycast/RaycastScene.h @@ -99,36 +99,8 @@ class RaycastManager : public rp3d::RaycastCallback { return raycastInfo.hitFraction; } - void render(const openglframework::Matrix4& worldToCameraMatrix, - bool showNormals) { - - /* - // Render all the raycast hit points - for (std::vector::iterator it = mHitPoints.begin(); - it != mHitPoints.end(); ++it) { - (*it)->render(mShader, worldToCameraMatrix); - } - */ - - if (showNormals) { - - // Render all the normals at hit points - for (std::vector::iterator it = mNormals.begin(); - it != mNormals.end(); ++it) { - (*it)->render(mShader, worldToCameraMatrix); - } - } - } - void resetPoints() { - /* - // Destroy all the visual contact points - for (std::vector::iterator it = mHitPoints.begin(); - it != mHitPoints.end(); ++it) { - delete (*it); - } - */ mHitPoints.clear(); // Destroy all the normals diff --git a/testbed/src/SceneDemo.cpp b/testbed/src/SceneDemo.cpp index ea8c9305..596644a9 100644 --- a/testbed/src/SceneDemo.cpp +++ b/testbed/src/SceneDemo.cpp @@ -188,7 +188,7 @@ void SceneDemo::render() { if (mIsShadowMappingEnabled) mShadowMapTexture.unbind(); mPhongShader.unbind(); - drawTextureQuad(); + //drawTextureQuad(); } // Create the Shadow map FBO and texture From bd3fc98fbab1ed155a559ed6de8068363b7eb3bc Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Tue, 11 Aug 2015 22:28:16 +0200 Subject: [PATCH 32/36] Modifications in testbed application --- testbed/common/Box.cpp | 2 ++ testbed/scenes/cubes/CubesScene.cpp | 1 - testbed/shaders/phong.frag | 7 ++----- testbed/src/SceneDemo.cpp | 2 +- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/testbed/common/Box.cpp b/testbed/common/Box.cpp index 1111f083..dc5e9d94 100644 --- a/testbed/common/Box.cpp +++ b/testbed/common/Box.cpp @@ -188,6 +188,8 @@ Box::Box(const openglframework::Vector3& size, const openglframework::Vector3& p rp3d::Quaternion initOrientation = rp3d::Quaternion::identity(); rp3d::Transform transform(initPosition, initOrientation); + mPreviousTransform = transform; + // Create a rigid body in the dynamics world rp3d::RigidBody* body = world->createRigidBody(transform); diff --git a/testbed/scenes/cubes/CubesScene.cpp b/testbed/scenes/cubes/CubesScene.cpp index 0898801f..c4652972 100644 --- a/testbed/scenes/cubes/CubesScene.cpp +++ b/testbed/scenes/cubes/CubesScene.cpp @@ -129,7 +129,6 @@ CubesScene::~CubesScene() { // Update the physics world (take a simulation step) void CubesScene::updatePhysics() { - // Update the physics engine parameters mDynamicsWorld->setIsGratityEnabled(mEngineSettings.isGravityEnabled); rp3d::Vector3 gravity(mEngineSettings.gravity.x, mEngineSettings.gravity.y, diff --git a/testbed/shaders/phong.frag b/testbed/shaders/phong.frag index cbf7f0e4..73c76ba6 100644 --- a/testbed/shaders/phong.frag +++ b/testbed/shaders/phong.frag @@ -69,7 +69,6 @@ void main() { float diffuseFactor = max(dot(N, L0), 0.0); vec3 diffuse = light0DiffuseColor * diffuseFactor * textureColor; - // Compute shadow factor float shadow = 1.0; if (isShadowEnabled) { @@ -80,7 +79,6 @@ void main() { shadowMapUV.z -= shadowBias; vec4 shadowMapCoordsOverW = shadowMapUV / shadowMapUV.w; - /* // PCF Shadow Mapping for (float i=-1; i<=1; i++) { for (float j=-1; j<=1; j++) { @@ -91,14 +89,13 @@ void main() { } } shadow /= 9.0; - */ - + /* float distanceInShadowMap = texture(shadowMapSampler, shadowMapCoordsOverW.xy).r + bias; if (shadowMapCoords.w > 0) { shadow = distanceInShadowMap < shadowMapCoordsOverW.z ? 0.5 : 1.0; } - + */ } // Compute the final color diff --git a/testbed/src/SceneDemo.cpp b/testbed/src/SceneDemo.cpp index 596644a9..7fe881b9 100644 --- a/testbed/src/SceneDemo.cpp +++ b/testbed/src/SceneDemo.cpp @@ -166,7 +166,7 @@ void SceneDemo::render() { mPhongShader.setVector3Uniform("light0DiffuseColor", Vector3(diffCol.r, diffCol.g, diffCol.b)); mPhongShader.setIntUniform("shadowMapSampler", textureUnit); mPhongShader.setIntUniform("isShadowEnabled", mIsShadowMappingEnabled); - //mPhongShader.setVector2Uniform("shadowMapDimension", Vector2(SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT)); + mPhongShader.setVector2Uniform("shadowMapDimension", Vector2(SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT)); // Set the viewport to render the scene glViewport(mViewportX, mViewportY, mViewportWidth, mViewportHeight); From b47201fcdf09164205ffe0f2e95db03e0437f9de Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Wed, 12 Aug 2015 18:14:40 +0200 Subject: [PATCH 33/36] Update documentation --- .../UserManual/ReactPhysics3D-UserManual.pdf | Bin 505214 -> 512961 bytes .../UserManual/ReactPhysics3D-UserManual.tex | 99 +++++++++++++++++- 2 files changed, 94 insertions(+), 5 deletions(-) diff --git a/documentation/UserManual/ReactPhysics3D-UserManual.pdf b/documentation/UserManual/ReactPhysics3D-UserManual.pdf index aa1391a555e4db226e04b0277c0d409d2c936c0a..10f744a2c90c2876edcda5068fde2f31b8003648 100644 GIT binary patch delta 152211 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

+d1acYp1{TZ}bs)uO2bPAMK+44sHszXJV5eD$& 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%0AHKa22?2;?Q3}?oYnE85^i6a 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

VSnI))khlY%P(778+3AKfPK9wxTuxU_q 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 delta 133011 zcmV)aK&rom#vj3_ACM#hI3SbZ&?tX}QOiz)Kos5c6?X}VT;^WpMR#h|XkwxU-53{0 zv5@qEP}2189fmfkZVZdLGjkqu4g!`S;4TpVtXFxE+>!y7XsjW~zkn=Zsx@dO&}hgP z@E*QYMY(&bBUa&|Z^}NMM{z1-xN1JTqB}$%`2(mF1!oX*hSu7N_u5z8gnWN2HY0l| zRwLMXS|Ec=N_tO;+DdRpl*|+NEiyK&y1vGB3gaQ=`?-i3kX7igcFE&lJa(0x4 z*LBghL(`Aw;3f~qr4>LxWHHM$q{^AA49a!z9iYsZQja(r{gq+uH|!D}50m>f!F(G$ zyYD0$pLF9hVc#u_F zW#>Z9g^YD&3nWsL(B-fk`rVk{gv1xqz=D)7;qRY!rThSsdw*|}fl(8)rU3&`0ya65 z;m|058+wm6|gm89ILUtfS1lqH#> zD5<_!7ve028X6(s?d1A;jVMz?|D14MNo85=0ggV8wn z6kZgwh@!Agp{b%jN59&6G{AVEIVWx&3SuIE21F5a?5&mLl;IJ->D7Ni*k<^)8 zD<+aM5i+-qpNN@;i3BEIMVf`FsTXBh+3}hx);*rW__tY-&Z^W6)tqz>Wia%7k>%rT zc4z-3$-{b*!jC-rT$*xeSD=!}kVBAItOsdv;+zLDW&_5AUv*$(#R%c>;@W(Phzi|* zf_8;P1)C7zH?cpGVmdXmF$~DFneYAsar8EuMQ+wt=vs}sHVO3nHiY)09c{N{oP~oZ z<_JBhu~Ds#Kll`5DhR~-(2KSMB!>rhSDN`GOH2+!Af`GkZ%xt_>krVk6{8G4Zh#=d zn`|~N+?2noCi?9tkkGrL;B6GNJBkl~ks_ffGxIrjR8#DmU_HX7>!ig-?{*HyEx*^Z zhC|l8uU0AZE;UL0`^07TvdWT*UP8Y;)TUiVl!V2igeNnf=b42*Od=c__XBDGCQ{%~ zt|zKLDgir=+RVHt@;s}WN$&B+m4>3s$1YX5qOeA9sK z7g)jChlqsS!93H+JGYZ<##W4!J(Ux!HU0FHEBakG)Vp6%&vX*6!9+Efa7n&{BgX)Z z-UAKo$;`d*2wM_Q3lO>m$U#Yes|6QmhO=COwBah-tDCB}tV{g8&6jMJ zPTey+79}h+hAfABDuva5^PTisOsy=vDUFNjKC7GHY`W1SyurcGEZb}^KGfrLZLC$v z;6lzG(Lrae*a>idKLpG}@WJU!nnT7XE21=lWTxP0=#jrQJqI5Abvik|Pc;U@1M|~- zoBi0=P?o(lFds37*_2-|=0 z(p@q+<0qsqU5fGzp9bv9V@w&_z9=0|%)GIl5>0}+GS=zL`UWX3ynaD{Pt5tH$53exe4LqS5OSvd50B|22;qYXLM?xlAHhR}oXOi?gZl+2?_(Hi?laQ8O1zMYNC>sS zBps%7Qq2mpNr~zByeNG?tfi)ugH?_Lpz{@9%p931|GlXm?I%YsMtYQ-86tW}Pue27 zMmAZNk4F|tYL#_c7DZm=z;6{*BQ(5Smn%;z|5J0XY+z>3_F8D)29NG157U1#fZOxu zP3huu!*V<{lR5}vA`efH`HUZ$VBBh8WhUDHlW$^2BTv{nv4q^ol!v$#It)O6UA?2Itu=>ne{XbGP`q-6e=?~MYZs;-1SUYYn)6ZJd598q)xUQ}p z57m}Jc#qP2T-Emb6Fz@9E9!hw>{O`~;wXXh9yJn>v^8?j#-XEwTyCK|`jomZ$kHm( z3g--0j#z648gHDnt9`8$XrlwW=zq`5)QKZ^n+tWjMer?XR-gLQ0xAMK9zU@SgXmM` zSlie2j|!KwDtKTuEaEmSU<@Vbu{3&H{3Dl#1j4_U$)b!+Y=(cIyB}3++fr-wY@M6X zKT{y`1v#19ocv~rrlxn4F=R=A%5@ zeljBB6Iu|xU&f+Mm)CZif2B?jcM$8EJ*dr%(}N6rav`o?pj6o^b!hUXQ11dTy2fPK z3xHa`pi()o;c;)J%I!)ON?djxPF}D`$}ZBwv}}$FaZ68_B@BISGa5!g=Xq_PzkYaY zm-96qjY7vWdouP2Eybg+x-k=s6DoHN6x)GrW~1iNO$xR-fvy%9Ng|~=OoWIiaboDU zXKw~q{{R?ay5O_^S}ZsOGcYtUli|=Pf4v&pcBD4)-Cw~YK4+RicgUW+B-xp49`=&) zZqA-;9vB+iY-n(R9>@9mt&3=&yFKpi#q%N+C8;FUO@&Hva2LeE`>S}Uqf{D%seXU; z+m!%(9Ec!IBP#-@MWo_1$TwGrmQk9dfe=w@Owbm=?bSa{A!VaP9+Gm;QJRc&e^D&b z>Cm5liGww?{Q&c*GzlK5=LUN-tt$8cq-Oij;sOfKZ%4#3GB9v&LppYmRmq9mIavTQ zjg(P~2wfKrAXl|7X$l?|0o zOHP`^F;3yq@E*zpre2h|3UgSqp_S{fBDf;BB)FTv+^1f40ZI7rdX;D-4&|E4r)8z4 z!i*SL69d=F5>H9=F{wlxZm4Xi{N(XVPM4%83x_JPC|Moe66f2AEH+C^f1xM--;*qs zWlL(qM_6-0D|fUDhiaT0ihJ&D{(N)j*@Ywbw}fZkCv}ErABSG*+0UkMf@hy^=t9p< zBvFh6>^!>J^XS^aNdkit!yf&Sq}q^FpO-MGgV1ppdF1|7*lZ;F84;7wV%2fgbJcRy zaP`F1w=-lltI8Rba@Movf9f0X1?hlW50v-UZB+Q5*u$31fvzm5= z+Yma^+VVDXBy(R-^($}zM0wk^4CLd^R4hE*qQ|a}G;!fuVCqeDz0%T#e;ZLuqyfm& z>&kWU20=SEqYS(Ne_#|aPkQEIW9iY%5X1mOrkn7_lx_QFll5ip`J+>qYeO8Xvc6yp z^9O)U<5>CVP0zr6 z=Edgt(AXCT3S6a*#G4HL2*Vr$;Bav?V5T7o&JZ*{=nLHIe;MKT$o;#%tSScctmY2o zEhFlpSQl%wIoOlc&RY!hm`DryjjDcRCyzv5CJ>V~w6s1eYeq2l064;Dz@nxS@ZYB7 zk=-yZ>lxZ@h3K~h2$}Sc*e`Z1;~HSfdOD|HK=!fn5Lp`3?Y7=ckq{vPKJ>``CJM$D zV$(3o+otOnf9}go!O%xi5rmVF=soa;VIb-gb-wp~A8BLYl-LH4X3uqzv8nRcZJTXy z%LbeSN{9TF5mSGq!1qZlVcoReL3BTXb&K%0i(3t2<}RYjXj9;QQKug7%N%)gBn z`!0Lm;kIoy2(ddlvMO-U;6v@Os-5%v+_I81a&Ugef0O0#fq?V0#RJKxfZ=#(g$V4_ z2G^8v$El|=6HkM(1>4k7tkittsIN*6&I&002tw%pKAODxjyqK4$2M!9kYwaHtpcE= zv>lEPr6X&GgDAqoj1FQ{U9SbhJl0K@3TQZ$#Ai<>83}79r;-+E{Ytl8&ma9g&7p-E zEeG*4e{V$1Xa?A__Vpv#4MID6AT$nPkJHZw&iyV=?rCGB0AvJ(5#f09Vkh*&ShwX} zdDNX8@p{^_gtQrq4Kba^G+eWDV3_4UgGduN0 zrv(4dJEw&6p?96G5qQQ9p~%bICss!VTTiUre>)re!AopVT80l9dV#)ZJN{;2Ap|bB z>)UPabqg@8TiA&R!0K^riSoW38g?3kA5HDCWw$r}u4Sbu`@yXNGRyO#D%xyy^h{&_ z=(G=4@}2?=_(pe9*33q=&&GIX@tdzZ-$w^7N?j~SFe0+C4ZzA&%KhXqf#}FVY`B_q zfAhWr<|p-W{y;*+jye2EC(*0}#A{9MTbW0W<2FQ$z0e4}v)`Q$NQTuEd-UM8NYoJ2 zMmkRB0gY$ON}0q@+450VFL9YVca+r)vWi(39?&WIU7r zUKh97w(^9$5*as%7XZDpBbv3~9ur+UeYj<-z^>(vm}Xh-VzJ6i_0mQAxA zybFG_jZP`~kP!R&K9d6y>GSZSt+R?TlTd9S#!)XBsbj7lQ(xwBjQ1fZ)T%EZDj&Vh zXOU^THw#9reilBSD6A$w1i%=Iz`#EHmHcqcpTnHvt`IvM`xt4zW{6zs_?bA4nwztlb;1jgJ|+P?1PsWkM<+p|RoccF>|=9KqlJ z!7c#d(zkEB;pd7z3UZIqg#YwGe}8HQW_26rShPnu#}=((a9(E4_l*~CHw!83VHhbf z_{Uht#~kp#n3tXJ{gGmMJbN)%Lif@&+yY~KpW=6aoYY;p`+>kI8y=cNghnwa{uvZ( zx$x_3ObVey5+!ih(Tcw>28v{>sDurlKofFybPUr#X%fIlJH}dH@z49qf7ez@fSSlf zGC~KWPQSLA488E$>U;_>Ut8^M=*uM}Fer(IebtP_d&)>~{vo6C6P4v8JF#p=LWten zHkLV+{p9AmJ@?L4rr_0_UP5^fNS&^{lc5(X@A(v7R^Gi0z4D!_GJ%4LW9wZSCj=g- zRQ}HK;M!7$Uy*Kq^_iPXe=Ea(O>$@XL_3>F22JfH1mC zB+Tm_nqaFpWU-~sb7Hx0Lek-{3y|$SarUB1PBA#M(`cgmlhP-T>!o9m?!dFNPp_$5 z`_~euuT*<)dTtnDCH?X&Va@xb&amcj=%vzw_6q73<-ESB;dDQ-)zc1 z%KBP_cbt8HJ`FD?X?W0>=hN^o0q6Lo2|qN|r)wocdIbe>)+B5Daz6jqivun2EfQuD z@WD$~Go}QJS--pS$EFTv#*Ayr-<+dQF$3_h?R_Vof1XdrXF7SmBfaLP@gWYzg%E1K z;~V{>38o1d%rZH83r48~>(j}WG)h?&ZtL>5t#9I$SDfO{$MiBZ@kSi85JyuA765*# z2Eg>G5Pt8bgwtV|J9}}S9o_8M&N!{obfwSK2r*e0ri)Y@euI=mJfu{S0b)oD3;!-< zOL;_0fBvy(us6$ScItQs)&dmZ0I&phJWej_<=-M(%UQ|-*C;D(5${I#%X6RLdKR} z3avC8jn3~+%x@LoH2xo7CAmQgWo~41baG{3lbW6$12#A~li|=Qe;QqrqsH-le+7@I zD&iPEhs%>4$F6gwT!~k)%XRhxDTroZTJ zaIKByT0h*m^89vj_wIWYSxPxc7<$%XZRyZ){ltocz|l!)Emqb?yPSEkeb{09Fq=c0 z)w8+pMRv8uXKd$fe^#e6Ww&`%HjG+VGKW`G?UwOPRXol-4I~<8_Q&E!OT|tYCf3~3 zu%Y4&7c=eI6)#v-OsC!E&7T;2#*!R_P6!J}7Yf|iiJ*HKcaC@;$vVoaanN*r7TpaaD{+#@i%@ly>pNZ& z!N$H5d7``Te`fR8g_Z>RD$&9Kt zS`iI(Y~u$2KKQOK?tbMQ}-QGxagv;&yRg z0g`DIK)as(2(0jlX}(=hi!2K4CBZqhEn%J~-CFs;fB!kF1hfUUkDt-K*Zpy%9asC4 z_~S9DEBx_s>8<|wY6=(lbJQ(JTQj z2wn{Y3_76#*LDOs-U)}p098i03N-|7hI)y;pSbtHy$}3o8JTgf=3Y7&%ehx^ujF3C zyW^%hlPLdjdjTU_2svPg-XIguy##$ZURDO0>V*E zZ(PuuyN-@MYwpKR;7fh&L%FQ8wBcfytEEr|!1+oa3{a&Ho>b{GWxgK1qrmk&TqrZ1 zfAXSWXqWz*M#d|0+V4;hU71?drupbUB0^rh%reYMW zCMf&Qp080h`J>q!@Kh>8XZGf>sEIAo1fe^ATfnW21rtY>B`QucS>`+i@PK+9JUJuxZm zfaStQ$_wrLBFpwDPFgio09fUDj*6rpwm`mnp|rPe%?RAH1cL??`{ez@ZDhENZ0hfYrf6iU8VN%GiK)E<+9=Irw3Itj+a(rmSEkU`eqCnRP zIwY%}ax^L&&RfP*LL%kvzp9)#Dx!{f(}i@$YXXpn?ziYV%Y)a6lBZ|RLu)b$iz zkD^8w`f^!q09%Bx)7xdWp8Xv}-HHN!k0NslmJ*7ppe?AKIQwwlF1N+hrlGW@=#{;> z-4mWuo08hiw5g4jIy$GKe@lY5UE&!?y84OW1Hsv~$&R0dP6C=Sftj9=y4*~AOK&vO z>nXf$rlSkJd9vffRYL7go$PQTtVw4y86!ni&=%D4==}+X+dZ{;kHY5U1h56A9dZaK zfDt|hfj@WWT+>BTx=2BALvVKPQj)sBOX`Ny#bYl1RAEr*N1;TDe+cE~DFF)yhJb)P zq1x@Taz!s-TvPG$_%@Bqt1}8mff2pb_3@?N1zTOnCu?8KQ%*7)Kel)IW-9>;b`8af zqDnwC@}mOhP#6+KvHd}2(*@xvsSZGUj^3Ik=j#Bfm7#GUPGeiM4TT)tb#X|pJ0HXg z<_{3z0c9+lr=;B7e-C~L83dD(*gQa@+2BQd$Wt=;HKWOv!V{R0KqeEKKQ(Heu){p6 zmf3j;_#JWa%uget84w;vzIPH^A`bb6&pqaf2q2H}NfKx9X^U|!&2D8n=IF3@me$nfX{i!aydp=i0YdG8sGa?d&apnQ+`tdl+crOtcm3(vb-0|3!p|{$E6#j6+n|b7?As zH-bVRN;`b_T&BBx+58I90()G&f8S&+CG&ryd;J3ECS7WuQ5@tz&!qTXfbVND<)`4-?+7~ATz*sVz z0>j)L%IMIv+!G(kwqmv!I$H5U%lvoO5760raZIX?Pml>!qYys2E9|jWqi+I>_>F!# zJMakQT?nwNB^0?w)=TVjl?12sObPo`M!^YWN?yzfxj7B**%&sCb&i=6xG$Ny?fS?LO&6wo^b~b-{i0~lS$^Cc|KkK z{C|9u_cocqXXlg_BB;do&)7==8p-yu06u?9bvshq&nl@(92G@|T+dpi;1>E8T)+<^ zwiqAgy9u~vKX9T@o5GuqWj9Dt{)v?p*IseGe+L2r^M-|3!5o#*zs?{@A`82)Lgzy$ zh00tv{2Czy@Q(J;aj!P1sm!5ll5SVK(h>+@fLRUu6qaZ%mocU_JFbq0)|yJ0YX)Vz zny0bHt4UF`ge6+b1~F<{-JT00x*sx6A|vcH$DcDl^W&zGnZBZQk)Y3*(&ZV^ ze{toF3DMOAUeAYyxA}5a3zW*+l`KF5? zpddKyK5dUbVP9D>(1GKIlYAW=Q@Y$bjw^4pj;jg0ZXLthym_%e1AXHtC#x0U8(K6U z*QW&6VjU-0e{4QBcDcIeU6`vY4X;H&5`m9)f<(UWDm7ROy7ylo8QQ>;k)9Ki5vmge zGBqI1RpxA9 z(o|WO1@~p}A-q5M=GA7K#7XFj-6l5S0ef*cR7cOPe@CRYXYL#d?EQ`p`8>4z-nGZm zc^HWY&rBQt$H1h0R~)aVbiOHl$L*@&39y=_)pRIdiqomCcExt{%l%)2tu`vl9K2JN zra3DyR4pkHWiw%;2p0Dxw`fIppHG`D3@8f{6h9oK(GL@?-CuqCL^5@CsW#gbrr&RD z916#>e;o%G!m40oB{ zKi>UtfA_yT4Gf|{2hOQn2f2+@l-OW*yhC!VoOR*}LFa@0-9In>a>Z@NDpxjs%F5j0 zG@EHuq}_b#hhL(ggm0jyO27p_(a0l?W?pshe=lIQ&?D8~z~Qz!qxWAaltxD7(ET#& zT<8h1RXXVK7C6B`YMp;Cm4-E}?1E9vA zmaZl5Yaq3alr?d%O^iyDn00v%I0{bbI3v^mTtIz2pOk53b98SS{`Rpcj@7Pz-*y`v z*5&Kh=M#bwl!?S44p;aMaGOru$YKNrm=S4VL=5;wOyNtwB5?|xwyvul@DYD2fBoQh z!_*z8oCsielto}xtP_DUYK<9c?RBuZL!<6U0F2`fUp3PAv}vr`2BtWRpzKlaN>mlOhI@x zV!W6zo*|4!XjsotFMO;3rcsMUf0Q}J$68v9Xd$h8M7!Eu_@3FeA~b$t!el36gm%Kl z6FU)czoraZEly`vGo#gj3VX$kX&ggw`i4-PjHScB6~76X$1nZ4^W(HaMo)+wI|NuK zzAJtnTc@nGD~?`+cY&h=(C&uk{CqpISg5;j_XJ+D6QHMOq>Q4;zUH^2f73~-oK9{_ z_a$MNsU+7cVW=c@ayS-rhI&AqCHdh$R5GADSq+ln&RW>_x^KC4?mah#1C~DP!fVLc ztClT6c(iPLdRFozQ6|b(69_HcvUtd66h@?iDh9peT$5W)iYCgY=`u%L6ov6)+|YhB zi+yAA7(uy2kO|2>m{iHTe|RV=nJj?z@@4NOmt|#Ng8V^;| zu*g88`cnqota(odRQ$0A4}d_<%+(e#?c5VnY~Bip40y)b?SKHyfB$iyW$r=AXWa`R zl7_>6Eikqg%VsQUNueZ*KqI}>h>Z=q_>oT|+0x$c&-KzrcAYOkI=*ZG&D-PXPEB$t{m`|W1k%3j!nD)*WD_R8-?*60i8T|z z0&%Q#F0t?y^@rh2e~YQqX-vxGNk|+(1NmO^^0=Qo?$%~O>T!TPZfw??L{N05>6EOh z2Ewb^d0w^{E~^p2({T+HI+zm-eH=2Vgd?ds6T{1JQB|#}Lk4u?tsL&}WIzlf{>V0j z#@vQ5_F_Zye^hokHU@shgn(HF53L6#-2?`yGG;n@8~sW9p;@^ z2wLn6oWXi>tLErlk<$xQF%Ay8g%K7(Ha}iIRl|W3$qmV&`pVKt@Ddz(@N2TCP!~k$ zs_b%NLXDveA{#n|^t^OP^zG6iRZ*z)OfP58WK%0;tU7~aG4;c9r zQX-WPUl{jm%g64}k8;!L39YN^;fWP`6I&ny^c1DbttrZq0w+&HVT?;d{F2iHmFoyf z0fmsJmFT2E3TIhK0#+gex=++*a#4e0mybMG0{$}j##98&I>lS_j*#c8o5(!Pv#}x) zoqX3be;Ku-_c-pUxsggrV`FY^>|+W^^Yk)*s$HZ@%3K%&3^~e3X7u|8g1@LM8DCJn zG>NpLk^iIW2TunFMhpQIj+d%ijTo&Wr*9RzYaVMHT{y@LIlUnf0Q89gqflL-4X_1~ zAl8+O9S?Poc_PS<@2UsXC&^s+hA!9Hk~a?Ne_X{@K;X};mK#ACG-fA0^xhMqCF^2W z@}ynnNjv6A%uss%55SEuavH^LOsSfYn-FF~ zf3KZb$k5W=vJMgJkxl4Q2g%2x@98MWM~W2HJQ9y}{w0(~8EXbZq_#Gf+S-kkH-2qA zQ?PDELhm_^bw$ktzDgnPt+4D5g=BdEoZCFkFf*+E&zX6YK@151L_Eq&Rg$r@e`r9S zu5M(OWTpYFPS#`BGo#}gvzE7w6&)7~e=YxmnOP`b@5I%uPGZJ$z~n2p6+py08Q6xd zBumlN49^<)J^RfFJ*k|a1qtSa4h+F|sUb}!!GjFASVqzqMh4F!SggXeSdxBC2?^B! z7oMBWJa0O~ZaW{gh&5}%pJc#0PzwqrJ}O2h-1W)ZS1jf;WqlF>=9$VSirP1AfBCqU zx-zHiG;&u%6!7YZ!Y+7`F%T5zQM@!m)xfz`4f1DEs?ld~Po%V-a`K-?cLd=!I()o= zJ1kUJa{;CLMZDGXYG*E+r+O~OV|Le7i?Xla*O2>*P0ck{(JiJnOlYh%^y?tbQySmxnjuM8lEy*?dHGU{p*Wwq@76_XGub+ z#cZKeEUm}-T?KQKG^(3b(O}m`UCp2+k}0^K^H3lH5G0~fB;sWB1__&JHwQ@l#B%|$ zjEZ6o8{riJZ~I6qi)DGgV@TPxeoB*9?S0*B{Ho99E{Qw{$lr)Z=9kMy0$p}u8;+E##{@ZJRpe;>0AD`G49smo2?wv79^?ACq{{P;L04R&?I?_Ty~ zlwmV|uPk?DaiOG&Q)|X*8z=+itl@>UpcUITJbr%y88lTtevf2vfXHB{SFa{nlkQxv zI|ANMmZ0w3UU#6An06`CI7u?ttOMUuyvJT;IuWe0g*F*mG(4C2X5%3zf0Q6xY;_VO z`_EmKZ_8!-6YwFU&Fc1+)lBa7wqEUi5s84GJf$I`5d!I&T@|;}94k!M$+&c5#brp9CW|Phn9@^-1`E?z$ZW9k=U>Ha1w-IVvCiD= znI>*=GNane{tcK$Oc;4Ng44W6q2dGP)vQIdU@-SrMGK3Bd3Cs`H!hvH*Fad0_^k2SRowR&ti$51)xyth}>a=)YY zhd~r*4@UPfBAvtt++nIB%)o(@B;qy>eF+}`@U@$!eD3=UBwfos4nn?{nFQZ!o?WQ@Psi#pTQH9icMy(?FmWrBN-@UzF9(t zSmF<{g8Gd=#IRpdd-Pa4>Kn??5;~SM_LGc|yXYPDn;!0nT;^x;oP02!*VZ1}gw+%> z`!7#3f0sG{rSKq6B)b~zCzCST9cVL%dT>6AD}wlYX?hT>9v<*c-d&-bs3aTX~3g@3w;=qm~*4YdWe zfB7KfT=%OwRs5g&^$>~^pXuqfKhxD2pXq;&7e~iJDz5zROPUS-CUMvQo8*}!Uz5xm z>Tiz9|K$@Pm9cQwIRU1qE(k#TrLPS@7h^ah0F4>?>+?2~n%Jhv_4Bs({YQpDckTNt z>c1W2Z4B8ROR)a-=?|xuJQcBA@}Gi9f3jF=eHF``qPoB`_e)=EnHOU?!!pMVeFn?4 zAT-rq-@T-0w1+Q0offa?|EyjA)lYRB(BJm|c{%#KEv1y)ML+fbf^pKEV#LeRV@@IX z_U?o`K&HGL{HIVHB-)&YzaRYL@GwZySJZz?{dxe|ok+<)`Aw3Z`1CpaqI&7me`lQe zPpWpNH^d7OJDtuJ8oo=x#!0L1s7OOY_A$6bgtu_%2;JeOBfQe}F?I&m$N1V`AL9$% zOlH0e1p&`^m5i5?Z?LGu4(f2SzFYwlp_-rh$^+`kBd8mHwe0U^hnMVa!Nnd8l~-uI zY29qfmJ2I1d{FXr@|??R9F^YSe>9>7<7I~z+w`I9AZz+B~3ZMT#L-SX1PU-$3pwIi5OxXR*MXRr!n1x@deM&#^L_Auo92yv_$q;4N{e zL^*PwoR033f$BE)H3p+vE}&=}*hUu0xKt?PdTP6RTmAv+l+goMas9bse=cut=iF}h zN^6I=^=xnbO*z_=zXErM*Yiu1$U3hcJk7S=7Q{3v%LuH|76L8bFyObcDz^B} z2&k|Dz$>oFIaPHtk@Vdff6NMNYe0yh)2$mSSTJ~-0Rr23Q}RLvFm2k%acKm|U!JdL#t5u!T2R?wK%m zQ`;~iP7`~c^(K&o+EeCXoaOV?xFlEtYM!hCVcWcI{Z2@+xZs2p;1DSo*Yygp;O|nvg)_hDSQ&!c#3hWi6+5ku>Iqmi6}WiP8b1@pInqe@TbRR9wAAqPw{m&|1cQ4ubX9mY&f5UK!?K(bf)13$JUBK(B zAg9_J*@||0Z!1=$ArhtD6(|yMc8^nojN#=l_#kWvd{88GgMfo8*-Q}Z&18Vi)7T#b z)1VQ`5r>EQwB|4*8b>P*e_B&zW~TPZvVxR4WORzlf3)yX70*02bq|D<9tl^XLZ`0} zBs)cwF&x!{Pbx^w)Lw3gh3(=olyKsBFbA4j+~-dlN~4wT>qAc_>^?zDCkdL{mu61r z;aEu7{2X_vOMpGKzTEO;L9J3)Lf)VGUxoDgZM_0J*xlZ?MR&J*EIw7>3?F%MviIU~ zfivu4Jb%K2E2>F3^S&~)y&ZqnDPiN(Ktf<3H;43vrps}a$=7!`{|8a}Kqd-hZe(+G za%Ev{3T19&Z(?c+Hj@!s69h6jH#L*t&?;jum64OXo`nqi&Ch02==8}eN|U?S5<#~Fq+&?qREG=sQ!kD zG)U9;!_|MT1f)k3F-elpiiy)AR8caSt*X6rD;vggpOt@m ziBqel3nP)VtA749n#>{ZCum0{@#Kk0uCX-pT21}|tUCSB;tUQicSl4rG*GeEAsxBU zs(9e&H0cW2hGJ4;W*zzT;p+D8>dkv&CrOxCX(x9JXjp|ZvCyy%MZ6h2Tm zZWF+;pjlXq%GR}qB^i5IWblQCqM&f@hiK$ssc2Y=aV6KmUqJ~?kVB|REpb9IWleNS zbVYPd^sFa9*A(B~?YljhgvzK<++Ls632v{cdam0$nZp3L*X_`mZjV^v^b&uub9d&D zyHha!n!Vi@uTU7yDeUSjD2M>nzMfu-$OM1(dHuGqls3T@ltYl}NKzLW+)?;U;RA)) z9(%2WUm_E|#@dmF>flGxzP}Ouj_8j>|ApwgT^SATcCQ(S%?R$uAG-?dzi-|v<;Pv( zfL)6?l*Uc2l?#QAdBl=Xh7y0c2x)>3Wja+d_zKY=uaKnCd-Gn{HlJv6EoCUIUtw-x zJd}~aJX@rXtLi(9B|*AcadNfHm?-o6e9k0HlXN&u5YF>#%c)O!we&@^bXNK5MUTxr z2np4`f`IVxZ7+&)=JSh1ufo$*#z9f8=Gd)pdToRZe)NT&Den<`iQRt^I@H>7x8~Te zf_1GxNt9qd=>}W%Dcl5BeR5Y0Cn=g|XVQLI)4_WFqh#s2@6 zuAyZfD_`t}mHfDOwox29H->ZWa~kfOo0@03=93v5_sreid^p5!CAGM``Qwt@{7fojYa}MB!Yk7f-qls2`H=(P{xFf zAl!}(<&VS4qXur!I)xd-!uMDWH}O{0Gj05I4#$nW*P+Y8FKsk)FN_0+iMf5&E z1mL}BB%sSF($^b!)Afr5`6#^MrWZl4HLPC)|5wUAJZx;^Aus0GYoqi z?QSso$%8E*ZxLZggb&BD+#RjSHVW1ab1PuV$nPMTa()fwEaRKF!6=lLZ~6PUC7feD z8iJI0ww;xEgNZDn5?tneyooox`n1SXhE4hl-V|8U`S~(V;jtD#t~yUN%&2< zRD{JV=SVF-2&SbBexAmHU?=7g?3AGI_n9wE-ELRo7!k zy?VZYUnTf2;p(Yr!Pk4x+pMZ*^;Pg{U>oG*0q_bv2akvPvjOa_BfA^%Yn4QPK#^*6 z8qdTSh9@52!1LMECQP&>)z^wJpELq294Wi}aYubyawL^~wNiF~!qoC$$DJgaI?w#P~Er*5ux zPzir-A$t;h7Z4*r$VMzt-0SJJ*G0y*?f4$E>oP_%TjWs*&rsf>xf zabTKPIG}iEx+~VLQ%eeqqb~(JavU22x=dEgsWTkXS{V+s-I=+bIg)BLJ2|&A`|mit zQ9oI$9}qC)T>1rT78VeUa($nCbF(FDzTJO`^twF*?y=&aJ(CWq$cBmP+0xHsOCYd@ zZ(5=chmlHG+rlSJX-m#~Qp~Cf{D3oX!7)Ep7T!h|IYtT}Tw?;zNZgWqZ^x=VzMlk0IT<#%DVs$&Pc3>JAHhwq! zok5E*f)yVq(F#bXOt{{G0WGugATJ(n3nKkcG-Jc7Wl8IR3i1V4-O1B7aaa~>QG_qQ zE4Lep12(lg$)dHIbd6(;k((q~=J$U~G-f3moyGJSYUsw(Z8vXfF(IRw2~3``im^^k zY4eI;4B7aTE|d5}wHA*SJ~X>AHOaserj|{E>WSdJm*{PgEfzUiM)jI;OQB!~W?wdL zkr>#UxUO;kkd@@xjCcMvfLgSkP=o=hVK9S)_k^Z{g+0)Q@+n7mK-e7c*0z6M6%4iI zxGl45Yh53KE_`tU1+8X4*6Ni-a~~Q5J@}kVY7<7VWgKA}y~k?!Ho8^y%x(1P9FA|J zdmZ|AhhY2=xi?m09Pmj6J0d;G{pud86FgH>^<2+% zGKT@4soS9oAMhyy4cgGjq&eWLUr8uG#e3&x8rC4x+nZNT@L-Gf@fEw`Y<**JCQ;XI zY}>YN+Y{UN#7>^r6Wg|}Niwl*+qQG_zTf?G>wZ=Jr>m>GPIv9S&OWEtTD#KIb*AP- zXc7Y8k>2UtV%A(SsMlK6V(%T>=}hr5PrG3x=<$*_e}(Uok&4JOnP+nXNVCVLgPxX5 zNr8v~f(llnZ6)LReRze4=MTrTG4OgTnV`HVnE*Go2g&RDqifw8GgXZt5|!=?G#hjkNMqOwGb-@Qk53NtCp%fr78 z4@zkrr>)uSv!a8&!^{Dyqqy}K-Mpy=8aJ~Z{#ro$*4G1=pDs_kP~VZ-A2HK zw#bM6Ke<%2sBZRGfq~&H&p(5kIx6znBMXGRBCHckk8^cRzwZn$lpv z!*GpYe-J;KGS;Yzc>4AxUg4WN=V|)(i+k`pTHT`&@@@}sjT-m`=0NcxpeOi(DKELT zy+~f$y!USM@iuJwVJ|crgzCe8M0iN7Wqv=rTC-KdCupQ~OTKUW+z)1cE8C>51&EC} z`1#Avl_r?-{?YpS_BI3lxli-R`Kf*12>OvpVPNu}mg=amnN2UL@!C`RMGiDD*LC1k z?G73zSL-4kS7yMoTN%uipQ~8sa*rD6_H_x2mcxlULlqTmd&2gGVA4PhGbilOIoa0r@!|)LbiJr?v#ggbfI*Zjx;J9l z3S%nGt?et!+tA#)N%;zK-krMD6qfqReNCHgUuhYg#uE6mcImT@hOblheR~6y zLFsG8xgI1DbY_pXuX>z%9@+wD%pkcCPI5JVfKK<7KM(+m3GZ&_C?>!WIakX_)EW%%d zhzfVmO4ppj?TB!{jUN8OTy?8V)%uTg#8Nv(IJfTm=F8cU&iou zdG;hsqk92fTPDAUnzej@RQUx&JRw4dSK|dPWPrE~p<0}f!AD0{tSjO)N3Nq@tbY`4WpH1ON0V(de`K+m&`C`n$~C8zY$p-Q`K`f)qsv>ldh2m$C*;i{b_w0FG{J;i z4AHk+&i~l|9!`g5aOhIK+zYuPxJ~Asiy~USIrzH?qugnjn&Dm<~n8%Bvx}R7h0rRXNt`oe)~A>1}d|IPg}w>l4G-Avj#5m z&Jbnq^(MIhV;z{MhwW_#)>wG_jQV^A8zJEiY)`y7Pds{|g+z)J*f8Yc2=jKil^!xp z50Dj##-|p4tiQ^L_M3Uha!{6~8TW~xGAY7`?BRi+R z{g8SWOcZU3pb651UW}NAv3-NBKd?7}`R}81Vs=kiy?STH(|2~B`lO~U15F+fW19nG zniK9SQ6)DxbrP9vAuTJkWme;=are>ZoYcGbwtxjeL@I#jbFt{pxS@fk0Df0DpEEb` zM_#*dFSl%=0n4@*Dpl7+@qNF{>$_tWNgbq@=2TQ9c6SCse0Ps`(viP;(8TASBJOjl@dg4|x;1qu=Vd~>-Wc-0Y$owKb zq@<=y)1&NS?7}@iY4iA>vAk_soNOeX&uWR7` zP=Rn76qBz$A615Op3^!Q4R63SKYC3E^Hc(CB}E&w6(hu(DCbMM`+n8ZKS5+De&Ky$ zsJEmrE*_}0SSbL#Z+!1-2=fe+!}D#=-aZ{dRj-YxVpVDL)`dvI%Ara zc0(bT-8eO%)k!qm_%(^j=^Xl{u6qRimXo!NbtQyl{WyR~3Zs&A27Gr=*M)Lao|g+iC6e#?&(2Dn-H&?OxiDM1{r-wPMQPX-;7hYQ%+X;Ok9qElcyNb(`OdpL z3X{MGTn>QG$ZbGzn5Ceb?CbnM0r7Z#w<5(>^`u?;5@lgLx?rkeSU9<0xRt(rH6rui z9EiQo(P9+y-a4z_imS9nDbxl8d7+Ww9aqsNyv)$&vY?&f9P(k#%}o&ev#Q0!Xt|-U z_}GM_6G1)>z{yQ$nvc8G#N+J%kLkhbD^yvT3LD@XtLFD}h*l}TYKz_Tf$@m28(FpH z9Wz{xVoA_l3W!btXDt23a;JK$WE0qg?Xs;tynZ(bPJ%w8(P?oM8LqmY1&gDBVAA;_V8zP#; z^B(>Q!@q?;VR)VP6NX!}KVkR>6&q6M_WMcvti>eDG-;aJ0Is=!jw+pQgp2{FCfRLO+*)C`_=3{RKoBEwh4q zRSJ3xiu`({J{dPq#)y#2b1c$-9$^dp0}48QKdIId{PTqXvQVYvGylf*Q9>WSK?_Ht zi+g57e$tKqu$Ia|vAf7coSm}fIHA=3T{RjO=UY$6O8PW%j?`sL!w}%h7fE}>+k&jH zjK>)k8FEJ;&;I;@+v8&q&h1{SqK5rxveb6G6S^HfpFF&Up1E}Ae9!qz3Ycn|{eZ!l zx(N6yq(ASXP#n#%dm=hU*5n^hgL|--oh$hZe+B9$KOuWYIn4i;g~R{KG2&qQf7THM z&Ei!zqG-kZO}*gDkkgEm>O#`quT*ox-X7PK9LQgfhhSp~W07Oi zs`h0Q!&wX%(0I52iKxS*u?|ro_YO&N4iHD#Dr`|xM8#}|#_D_vm`ew^SXsN+eAdAf z#XWPBI#i8$)MZ6nE(#K+I%={SB3Z|i+Oh>z^Xy4*&p3*QTB(ZcP@XhcUh%PSPN*=l zd?hlr$Y6>18L9+raAy~>W2_3zv79D;x+}I$;zp%%`T>)w_2(P=ff zAm*$*tPVK-`cos3G$y#-t<_9|cmqYx#vph*mxG?XhN1+UmQNjn@|oOTeER6`R!F); zrhrCXX%bb$PLw3EKpBu-8yZ;}S{gx>^Uxhp6Hp{TLj7%Tl64(8sA$$G@WsbWW5P@8 z_g7Xp5yW5KS&R#wQnT$Ob}YkuAQ1ccjQq}ZpV1i%!koiU!ID#-Ef-f4b+xZzDo&fP zK*~#cCLqxU_7&-TkWM%Ro^+3uZha*a0eS%_{3Gn;sWIye!7#|@<3H!_8ogq@ah&lS zOcVitZ6+vDN{C!6Xn~O8TyyNbS(tE|_OZWNz*OfhQ-lKG?nZ0^0Nxcp$$6gDcuPPQM_9{<$&(iF$L za|B!aVUUbrq@Oeyj!1-)KF=C|u^iIyu-mk>bbQc3*~ncCYSX$N`oG<=WzWgSHX_YO zN&RF)w=k5LT|50lAw7g9{(hrTef|1#mf=r3M04npjP)$wBttBNowZaTTO>{A=N3MI z^R=x?KIYMgUybt~D;1|~R=dCu)FmBHUZgky*XleGLjVG4 z0^UijFfHzJj}(Xpxiod~HzU`U_6rfflaId&Qvnh7bqb%d%u~s!^pZIrjfxeRZwl-2 zx+qMsqoqx($+~4$6fp~d2!dhuX5==_qE4<99}$&Iq&3U+581=7v8Jr)C|4zhWx8*B zZ|kD8C(hq#4htZ$;ks+X2%(|8bk$A}C5Oh%<wmqKg@ERwvjXbq&p!TfLD1HmAgBkf(>cLAb4Agk85ohVUxT*wvJc1HV zsZ{vmqHef)h`qo;JQzOOdG*DBDU(&bar))i+mLM-1_)DRNlf-Sy96-0$g~ZD6=LTe zkJh|8awAzQq0bIYIi8KS`G$;rIhNbhB1D{!Jg{Hz@R_bxG*`Tw4wT{9xS0xPLQ z>D}toTq$iPqkmKW+DI1!C{2HGa~}YuiX#m=MQbboSIiqI{XlPbL8ytx2l}GP$$Ps- z6LLW0Ua4~}P@e&mor2ln&U{I)Bs|}4?jIQ?wCo+!7l~Zu@Fh~F4g&OQB@^$ss&9m? z1c>qw-owzbKx>vj10-FPEaWcyI#-9uFEd>)>WMm7NHjD$&6Yj@SUW6gH1=4+0UFp6 z?Q@Fc3+%r^d(UX^(^}{p)GqwY=u-x$xnQX|(5=S&DSG&nPVi!;Q0=Q9OicN~Teb23 zU}8!q9KZaEaR2+zn&Z`=Km{;v9ii711l*8AAA}3`Tg-DoB#2!O6Txqj?_y^U6RlYM zc@LIcFS?hGIzW+!RY7nUtD-vZHPvdEVnZw&|4I5EnS?#d-%?;$84P51aMTAgxy@J1 zSB+SlQ$kB%P@@;W&~S-=v4_hD6W3;9@LgR&aZ4ac$RZCoC7oOVR{&c(2|nnub7S>G zTQ`i)%pU_ReKuj(-M%EH9MM{uM0kcmV;oN|DzN_{;sN&e+lfY@*N9!r@qYb1Vf8P$ zGq|S2m%snTz!hmGaVXp*P4SjwnK0gWamf`B4zTs9UGB-v6kYF>SDuxKoZ@LW4*UtwP5u^W=YKiv( zRWB==Ckm*SnQiPieB-_IHHj-X&-Haq(0DX>^zBadoUa9AA#P=^lsT(leB@+`}8<2rX9j6;!!>ToqOX-rSdk zSlP6A_lbpjAJX#W$a7&5Hq!{oarCd_8hnn9rr zhTiCe`9d>lvK6dB@uTN4FJzcj343|i&>&YMGCGxPlSWX?_DgIE&GAfx8@_pwpZkeZ z>)&AZRIY&;#jGk@@vA_@_q-lVl(MlQ*y)jC?t5Y!EiJDsUy<-JTTlZ z4uF(OV5`aXZ0@8;Y{=J<#pM2&VsEf{(nblWDrnNK-%0zJ15+q!l2K}Y3sWhAEox8ZtYg}|BbAP1p}@a0ac`quVG7u(w`=I0qIQx%K@=Y+kjChJAP+3j zoS*SB{QAkOvH72pW?UsUztp!ReI_viFu-myf0Kz8aeoAf$gd4Hh69_0|DbC2)iQEa?5v69o3tni?FCaYAJJa>J&MeM+V2O7$41S=<_qSt{ zKa)LCHt-u;c2(22KK(5@=IaR_?f)uEybU#Fom}b+cVn{I(c1%Hj-EBJolXM*h;v7- z#NEZh9vY|mO{6Ca1S~-=Y*&pBvBG61go(W7d*SUQLW>(sa~B(uaMcEE)*<8D7WM!ZWu<$af4QgZ)9I%@(( z4(j8^#``f1Tg~tBNxpsLadQH{4iJBAmhAmXF)$4ZFGMhWDdS%f*$NJjDxZic2*p!Y<7)GBfYpf= z2OC$fsri?HD=O#ng|344k0~TgvTAXMG?Le{{>i5U^4R<2;o$i*&2174iwViK)3p|A zu;Wp&HY5k@mf5cF)AuaGp*ikwydd6PK>oXY(%U6GXUt05X>lbL;62|4*)MKe9qsr3%r*i2N=puq&?Vcq?UG& znZfJm@(r3xN?K56)0<6m4K<+Jfij>bEWdHJ>Qcj(Z}TsLy~#}wiZXO05a@eS-B9A= zUYtUK@ny3=u`Rlwg6LQ*dmp}b_cjj)0gPxTBo9fcX2JzsfPpfh(}i_>MkIXj^vQvd zzcmj}nBO>hhLb<~R%qJ?`pO4lg~oU*qzYSshx^)m4Ix5XEhLMjPVzBQW!BoYcd#l9 zC(B0=1jMMqJ}M?A2l6L+Saih44fd+dO}Wi@2^Y{tTMVggKTec!}}Dv6>VMQUiN>3 zT9hCy=n?C=-k;p{c2i>NZTl1CJN_2Xt2XM>P^Gu}DC0AuyK)(>sAVzoF)1urrT8&;3N$H{8Y-4K%6X|0 z>5$DsxOs9&TCOSZnvGsV5OSgh9l+B^H^K0l{~4Mmcv$NJZ>XokV(UTQMa$Smn`15j8tyiah!hF3kk=l1i)4xLsf zvYS_{csV<6vH|)hZUZQsasIQL6Jwh@JK4d~an#(9f|njr+#C;}!ZoFR_JvfxEe?#+ z@jxL0dA(X54oC+i18KeVf8N?_d*TEZyICJz?wOoz_nMAMfuOoOoK9TAx=}6v_8ZX9 zWaHW6M=0qrjYeIl6srTJ!K1#Vo=F6&qFw|O5AN}9u-;MQ)eX*;{(TxJN{$@nCr!Tg z*1`JFq6DI(VPE5C>*i93HFeD?`Wn>&q6oV_2-e>Ly8>^EP( z)d?5ufK?=JA~ho4KlEeGvL`mUbpdqoq62gNl{3~%x)@Fz!)*IK6=A!%onBOTa;!*QALHj?MO8%fWc zY68yk>6O6yCqzgx=p%Y-{1;$~Ny^FWjLByFk9iuX_H{^DrE0MOfTRB@#@~^Fy&S|V zZ$pwQliJ7)aEeCh!Bo4d`272TXUZ_w2aQUe9jpx{%IZwbqz51Mw?-KMxV3O=$bMrH_3+iB((Y#txo_;X6HP^Ba-ya4LE;qOnjzm%727U^m@!gWoAg8d*i_3k;-DZm%zZ7jooYg zI_6;M9Vz}}`9%&`V7TieX{R=SQpkcvw@fwK&QOat)*EXYS|!37*l=^fz^cr$y5N9_ zWPy^r!68KgA3*S~sXR(@)zUQMxl6k)L&vPka(D18E7~9O1qlN$z&_M9BhiBVSC53+ zdu<{^?@C?Hp-0hXTh)5=)N}j{FIgi}#{k84XO!y5l9C3XlNI>jQAE%c4!9&+d&^xb zoM<7@O_ipMHdJH5m2pJR$kMth_&2hkrvaj&YnimHHwC;QhpJpP}Kk!96jomazo;-2&?<9zqQ*TA_KPy zb)5Vwsontq5&hj8Z~nH6|5~bzPPg7<4IZ0<*h;}uq(kX(OuPe5mVS;eZ$JQ=0Gr_< z2BmRJt!+*%0*2Czv=lp&IenjJc$=#3UQ>^70|2{it-L4)1ZZ zo~^gB8s;<_l9GKwOqz!`MZksT4@h!adGB%gLKaP*f$I?8bID)P63SO$Q|QYyR(JLg zXZ*EQ;!$NNaos6K%%WY#;k4N}CO%DR`ci4yJ@67$jb(ToRFc=Cu$di+rzG(q7hy*x z@JDgL_-8eD)Kysr_|A6i%O`8kkjet1Q$?5zsi0cV&vh>NOnH>)VdCed$o#FI602eEuXLvwfz`U+wr|BtjGSgZ=aWZRNN^D~I zJ0W_3#RJA&N4V5Zqe-N19@wg+vjkeK-f=@*I+)GRA?gl#PG;X4eXZQss z@b}10L67}yS5Tg+bcQQTc&-MW->!X=j6|>J8uqZFqf6y*p(W2R1132-+W11MuJ$2< z_;k!?E2T8Bas^_r;sB6aF0f+Q0{2wRZ^*V0mBas3tb{QCS2N4Z#ge%5Lv+`cbzbK{ z>VDU_k(yM6$^o0*nxn9Cvbj7Z9}P$*ic*Pmk@mWHSax>@mPWH%P8j=Q6BX->+OB*?*};KtK&VAgK^Hoa4Ez8$w;ItM(fnvh8zmbPGk}`3~P?OmtpaoxqQwX2Ok}@8q_(Waw zPj0-;p}(9^@ZJ>Km(URZ@a`Z+!rsB9w<1B-pJzriiWMnGUD9C`P7Z)aUDR%tJ{H?F zl~aq95>Yfbbva%;J5C|nTbMpEGa5)sp$7r0gCqpO*^@Cz4=ID-i}CP^JUZMy>H2nW zi_k=*jjSi%E;c29X5maZ?_Iz@+glzGIdV#|2n&SEvRu@mnOWGhRBTh=r){wE;2vlf zzV(aVQyQYYG{n_3?gLPXC3ar;2dFC`>3rdICFOu1KXM*x&}(X{b!VFw_O&my~$ zfejJEY9+gXY9V~-H?xjZ9l^RaHl54wz^35x5FMw$<>|&c&F`TA&b7C}J##c+0?CD= zeX_fnU~LSj+}8U8F5@Y1Y4YL%M^Sz=B)zWZ|6=`5J(k4m&0Rm7eA z`V!EhyeIhP&rw&9>9mp3RdbUv)TdRyvv%A|(_m7!H9)=yqY9nFa25J@y|Hj{tq~** z4Ln=+G0k7H4hjX~OWcC5w1j{wGh{{NJOZE!;5-800=~6ikX@^YX50m`Ct>*ncx#mR zJc?0*a%mtY3}lDbFQX!3j~GGPN$&A#xuY?b>H^8yr6TwjeYh~0{1A|i5M7^zr zxdRgXd8q7X#LZAslIAY@ASKx?yxh`Wq_U#`*-j7dQi3s+h zIS$Fsx;k#wYDwkpjAG(y%tUF&{7vFB8GX*bZEy+&`wlr*y zg1)(=gEZNZSa_Xk!&;Uo#-fx#+{e|wx&e=dYeK|(pq)a%l~w@`jtw}i^S0r+um-3H zQ0_?)-i%pd9#pr8h(8at22qhU2b&GGi9TPVqE(PUG6yoEk-nhzH9-H8k(p6S222>g zi8wBqxj+1dmFYVL@yp1w_XcwH+2ly`GT(IL>AQDbm&#A=B%v-BcKW=Gd;oNie2(WD zgPBs%Rm=VW)MJxDzS5U;kBIEs7GQW@r(l!F52qkgTAqxJzH}e*$3F?ZS=QP;=;^8O zc>u%~f|vXv+ophg_H99@anGR$n_c?phYc3z`>ZlO*-c4`7w?OR?iH`oh=OvZd9_~s zYOs|-ekhB1Zzg_;KFcX~9r3hqUaoh|b+ucqRq@iC(>)VJiZuymCw%Eq4p{mam1Pe` zNzzu73zcmiIpyGA#_Jmci-nyc^M{(6AJ1gpV%cR#ElyQUre%CAC)|yQx zJD@ilK(X7D5j#lXJEgq4xd6|$_m{$^fTW)$8hCscK?7nU#R2m?GRmlY2mhAqR)4oR z+V*{E8cK$3GV_WuLVtQM_RfcNR_y^IHo4c)XU!`^;CgIPusLG+>dPxFa+EQ}ubMgZ z%Qf0*pQq_=pX64|JzrNGbFxn!B3>o_U@ zyBMyy2`s$6$b@lYl=yW98s!G>nTDCG_?R6&x3UwEfBefG0BC!E&JMmO1;H+|GBq=- zj*zPe+&o1XbWEZs7gQD20ec5@0-`1DtL;k0B&0w7(mW@Wtjb_Qr%$E&eX4J|xm$qrrNgxx>bqlAWL+7cqnN3*?ma3$ zIh*Wk1%)|8-m0DxivQ|U^28NY_Scs#!oiY3dPZ@N$!aD?+Q~!|MP`X()=1j!*X3MEWZhivlX96j#a zbK|US*6-!RlY&l1xxx8Y@>F@Q>!Gz^ophmGRP-;B=scgnq|R`_Ti_cL8L*rc@>iWx zOsu}H>^SQVI?;q;+ywW@Sc z6?kINZBFkNKaq)`_h~RFWiSp!Dt;w|3eexTy%`XkG6OiEd{7k`^)dD#~X!>uwP11ChJ^Ad}H&nveP4i4)A_cl*|m;m=D zm`Q(Af6sVB5%(CHr!E$T;3MEQzA3`NkmQ=9`)|wW$YlBdnU80OmL$$+@OPsI@?m3V z7z9=D5gT1pDoDV#LFVpE5<+xgRt!5+^femD^O)f}|8Jj{94%-b{YncGD0|$Qy$z5Zu@w1?sFV z(H|nHPk%{neeybbLs-IQCw+_`GP$J!4W%~j;pyc8uFlM{C-N=e*mEiLUe)CD&tbzm zQEIn3F`}Pp(ecFZ#M}ZfGN5$HiCA_RkCiVtfm>+blabW%1SeLNh6h z)DEV{B>kS6sBr-0^Ndj+`T$6F3!M%FmC2-DswaLBU>s9o1I0)hMJ`D7jHxnO;0U^` zGkt(A`LRGu&$Z&wpFlXE`+2|vNNA;Mr z^@hFugYTy@L65ZJUQr`y*jRimX83#gh6h9k{NWgRn=4*X_3%65T5SxSSWR9^4OMxu z^*GN4(2$AL;JS_N_1UL|dU`2X~+Z7$mdlPac4ab z5KZw+adWu-3$%3YR;RPTV;~IL4^c_({;XOm4!Mu4u%s9deU>{u&X?VZy$OFGKGvA; z1L5@6O$1o$T9W`VBd}|=c7v1FD9`}_4`VP>qv8B);0{}VBd=N8`$~w<{Wj-^AVMMy zrB9wQ6P-CUMRFt6Ae{^_(n2Oa6YrMGKx0JKCGi10GOPTU-93C|#LZ~Fs z+ypMdswm0}vMoxu;7^d*6U>Q1+c$wATL$5m9M7oLyiQx^tDHs-TtxxxXOExuDh~NC zRc?EWXC@Rm8$x|+!+P6IUzmvWq_8uwR!UtZ;xCLl7t{Q7;@*B!mO=XS1@(NV0Rm~X zV|x4SvV!x@H%?OUBOcq7=a*Fvf2E>JNWTN1CtiArNZ$0O0VC;tG38?bPY_v`6HT|= z6v7hCm63nPK9%%7i=W3LCFg{Y%3rWB5LYz+EgD+QWPyc*F**N#_bL`W3l zzkaz-FUz5AKq}oFQQ&lws9{*Wb+^CXONe-*jS$I;(*+Gk}$;4~p zHi_4DzaHYL*E^gsR~}F+6sAXnn*w-p-oBoxG=;aP>tYo2ZiGl%xiUP}{?XTET=b7% zI(T^TvMBfU4XlRBC53BtvNk*0E{~{>c-<@Y>USHYkf1BgB-lwLlKq0MB?gv}((u61fUvH+qj(m3{c zF3aXM{XX?B6t-nm6O7AI*&~HVH(t4q%~$zZLYi z;)a*SoXJi~!{k_4-wiJ&={;{^WaJO6S&&1eZTfyw4FUE$6>bvh^TX{%i>Swd^^kmJ zA3{%}Pw;04u}Q{U_T-y$!yo8paSK=re$|Vw3O#I-;Qk}9r7A~L6#+ywDZRkZCU_3N2sBSP77wgxr4VAsg14eJbMpyaj3L70Y5&h$uE9GO)_0!X8RZ2`_f|kJ6rOCc;A}Cy z4wOtwS;QiQWh6H-$7bhguvBJ_&tdbm2SE$kRUt-`@>6$bOT;b3nYL2d?w1KD; zpH}pr?j3~cJn1pd-{I)i{F6pJbO7Pb{HnN_{q}6j%SLuItp&y;sOKSMh%V_yV$hx1 z^=xBWpGlQnZ3^PzdKvkqUT3w6xhn$=Bxth|H}eGI!1;|!1xvGjUf`~9h$3@%VhrXb z>EZ~WwqK4wxpn<;7&-;v1Lrg2Ch^@q(_i!Mc zBmiDBF4ZOmE}M;{`AtW&BveAFcx%6F^iB#;tr9ohWHL!4rbswAdch{vud;7UF`}9I zgvhTB^(n(Us#15!H?d%aqv0zgB?wuo*uZ#n>g`uABg@%??I}{~X9;CWFu4FqR=d?H zlK<1T%=PEYGRk!xrG^F6&;L|w>$)-0DkWgYW}JQ#OHK4Mzl!GQ+h`-}wv^_*o5lwK zSbdjJly<~{Nj!kD2TPD>r?Nc@)QRyxq}l)L&$Io+hqV~FX&29_GlNN;x(Xj1Yir0C zP`d9l;E{bvE0{8ku&jto>}5NFjFB7n89rYG4BPl;y>cnAlOasN`Sv9O80pyn}?f&qY5y`E2&9j;*s=%{o1 zblQc63V~)^GT2Bzmfs3(c%g$jsxtrKw?(h)SC7}9Mg@WcsiiMD*&N8Y!wq6>b(Va z!J2X zi7V9wdZ~TY-_(ees<>GkE2031B2`A&>()utkAqrg7cdK2$GQ0sx6OYVG;t?^Az2i? z3WmL1A1E4pJ8Sw}9y9R+5S&kYUh&MQJrGF2W3~`#=z2$wnN}WQbNfvvu>07J?|;C( z{`Cjk>tFwa?MJ7f-BR}SCT)$xEM=fNWFg*T~jgS;$l!F{=ffE&pbpc4}sIcD18 zv}EN8nN6*0(=mZ~Pk>*$EbH(4*Jsw5(f#Mf;5!FN?pGn%0$+0k(C^jvbo{O92EEo= zj4vzl^uKwN!VLbF#lg|Jo-ZsStE3(!=rE=}2^IW)j0$df+IgCO}4d?(yZLLiLw!{Zx=KSxD1r?wgYutWa;^ykdUmc_h z{`udgnV0oEg;W56_WKOSXh6JWguh$|S@O{5+f)>a_;?-aOGE7L1)m!MZ$I5CnbzGE zN#^9YZrVf{-jY^d9nnr zqM2yRuChis%FJHxP2XY7UeC1)FZivZatEpQd=~{npy(NPXXWZpv9a@5P36zR?nCLh zfpAZ8D6KyTtlo zr}n!gT;K+hf@`;h=KAeZp-#};v!&)e-&Xw&`!`z&dflH13`WL{5C!vf!8B7 zXI>CQk~V$F`(of=;V`|rv<1~cWA`M$Q#2T%*j;*Jpb`P7Yela8ECui`IZK>y0&5@~ z1Hg3lH*)|e5x3x1LrKk45S-t@oS!XSyj&>C6=9dqPnN{Gt$jN8E;{fB9NLM@ikXLH zQwv{V>uES6bJ-`V_7hAH@fVDq&Z@{9d!`Qum!v1~tT9?2`7%Xk+IC;?*KISj_+^j*9RQF{?SX(Mht<;{}SMuE-J-JxFmn3qV7YM&HTjWFl^gTv>`VvDsh%%)Y*C#$2frg}sUr-Qhh%QD_ znAmgII(Hv^f*Q~1&3@afsFU#(>Ih)VLoR}+aSV+B>v+s-{OiHG9u7O&bcQlQ;7`1d zW+;F}cAGAR$&F2&ErksM#8b%)tt?-PctylVYma&U6vng!DHM6HbH?h|IsYGC9D_8g z06Jr_KgL2!Ok2pNQzxfL58%PEe(^|IiEp7ud<36cNFU}f(@_6ZLb_SOfcFeTLX&d%}&A6Wg|J+qUf!+Y{S7;Ym(x+qP}nc5?IkKir2~_hDvs z)v8*nclWn?uiZWUH96U6B<*^l8IE@SW|#_1(hNXWAl-|6K*Qw#lfIF)N&y}uV@mHW z!&o=*iAx(B-zHkqsWDKu^5)<$po2F)ZN431A1!7b@@0`Fm_4@7%8OAJ^VNb8nnj!v zz^EGNpTosp!bpt`{7)}I-`JS)MlYB~nbn-t_!Nkey+B|h_}Eiljh+Q9NGg?GP^oM+ zQ~)p*p>tT`;H=U#R+R7c=M3$9H`%Qi zJc`gbd$%GSA+J;ra$1290+_^90WSS$WpHL8Pn1WpzAFcIW}hp2aHlM+HFW zhy{1b7cHmkQ746cpBo#%8)(|Wf6WG=IS@46Fqw8n6A3LWyz9B;9I1PFyTetkw`$T3 ztibAO*uwds*Ajq@+8*B%gCe}7)_rz{LV6`&$VAuVr~n5&QCMR+dflaXew$*{Ojw;b zx8?aYWC0_pBR>|XIP8w3DzF+_|2?z3BUtKpWGu)|T)jvOj{=A`;$$1a zDN8{lO|XmLiju3+{#X>Bgr3pd<`xyF9~MJikn!;*J!+-AL1&4p8e$Q;C`O~;&qy@! zn#f34t57c(LlqaV2})_Z9j@?kOMP9<9@v8{GgyFNwea163BE#-A_Qy*V{Be(fbx1I zJ_j*x{bheT!ISrf#mE}q83I`3n^3+%O_rnw9oz01LrIvCZ+}iWBQZCEZJ`yB{Nz0- zQ0n$>Z#=$9<2Kd;%P51RK?IC>k$nJB`J|*?SA!>SCu)Rif!bhTcS$xBQ{e#6B1hA~ zD=!y*?S<@~q9rk}PuRxl?<6#IL6Y`qQNJAki3-zX19y6P3q7Q)o#qXpQQ$w$(B-gm z>~gBx-mdCQIKGVsFDX*GmroGH2*XB6s23GmBbn|<_-M}K{WBKrCw;YdXr$wv+ zqkyrn{EzjG3V^GZwBB_4=@)|UX)B5XBorwBK11$y#GK@&ZNNP5cqb^c5D`PFFO}nK zSNz@i4jf64C{HS)mlbQ^PsWd~Y3N?73G`s@&SL*GnPRaou&v+eK^K^gXjjmfwOM5@ z-kuX_o_F0&K3Bhfcu|>DS#>N8As?-Df_i#om*g<_4)`r8dB^PeF+1Pa`E~lVo(`o~ znZK%wEl7kpc)6yoX_hG$n!*o+E-#J0f5}GzcJOn|MOhBC*FgFDT6=!wUWd+#UwikN6bt1=(o8_wD}fV z2mwlT6+&q@xg4kXLL&Rjeme!A1V3e`6@XQ!3s}OyfQO2569Y4n0)>JR{`?XGK>;Kf zi&2y7$Y0<>eoIIE>S}h?sc@^XB9U~*EVC2dQ!Rsca1xBZ=Bf$yQc&D`U$7VIL@kH} zD%D6AC7Q+yqE$e)mS=^l|l)^-}f1$PkAP z3dz(61Ayxx;HYE$mc8Yc^3F4@mJaC4fakO|@MtQ7m>%Mn*oE>77axK5Rw-^;2BhOP zRXzJ2g-1bjF0f{uzcw`uJT|rP?%Hi`-xJ&_RV%`a*$3pbL=Mv^L?v~nLyB=`0BLwi zhb_NfrV1gWi7cGafRy-A9^-zKWW%O zPh8P7x1gdowGYkOB%$Sru6~uZh6UR?$-%@q_=6v5_mAl)u%z0^vZNXeux~cCj5PhC zAdTaUnZd8Y^E3 zT+tkEBsWFVjl-s*iM`p)Tf&y3T&4mmc`#k?b_KQdzP)J0jUqX187Y)5N2-MgsTsLX zLAP~|-PzhmpduUNk6z>**sqtkBp%|;msQko+_jy7&p$o9PsPx61D19EY|rWZ8HZz) zs(~(^mC$@r(`3UfS&{_v%jEGv{G1FO4?uNBcE*iwT{SNuVubTDNM=$}bh1ll#(9<3 zEv!f?b1+J(TU2@qkR{8O(@te=2BL^FvrB3oWgiz{mQ{gwR5EX+8?7wyssXl9jO#Bg zbgtjeqBTeiXLD$T1Uw?{C%`vLEI)S)v0kRpnx)Z33l;8{WaQ34)-*&Fogo_SlsQ!M zb&a`QCk6YFsvDbTi^)(G-eqvOrMrs4NvgBZFTbHym z>$D25&W^^5n@{B#Ssa@O$EjG=*fyja3%L51efyOu0bCFKtT{vP-%H_zrjPekfi>N` z09*tXmNRrfdrb|y$s<+h6ve;B(ts1!BipcF%Q9gX3HGDxKud>1q;o1A%~u6>`&}`H|eqWftIFA2WilD;bnU%S7$o1qbsrJiL05s~1r@5#?u=+Tn%nBY&G*9>6YBrj|s z74sM|iIDg}$Tmp_k9BHn_~>xVzsE>^sSB0o@b{?>|1-$>7H) zKmX^G-`Rys;97n<>!J_}ZRJ~`+G8yG|0*eu&Gzrb^pX|K%q^umQDSGmc)8gFu>nAC zQbyBTn*dB~LrF3oQJQPVhfck=YHE|L;%?>6v4!Q0JWHc~S<-LKIQYsLF+I9`FUh*- zer$8tg!%wR3+rgmlM^+)O^n;$np^U<5_Xa1_05go67xd2Ed>nZ>J8nM;4~S|%1oA{ zepau*unna54Yb`5G|pdpEa+5v0tj|=k#t>auc*B-)YQl^z~Df4Q|ux_>VVVrPVw8C zVn^_y;ZrF_OUL?Ik{wm@X1@beZE(Ym3@5DgTgep$eX&wcE$v+P`B_ zZFp?m5SH(tQf|f!SCCl|Q7-?ct>lM}P0#fL40dS71Y`}&R~nuWE4b=m;aFtJU>;Z$ z-p$fjYUCPQW2~5O@^Qc!kd1m5{ihUCdi5U4FS&upL&RatBR5(3kJ6ak+WyTigAGZ# z4Z=U>gJ=J+a~aReOwf*gmP9qr%!TP{5js~4o5^)6w0Ad&T7rYwhe4`1GSTbAsqR$ol4AUJ&LQeQMMn0%mTn=Pd0rJ;`3k=GXtvRIIV9aod&1$bfd- z)-g@KuWdj3cU}#dMZYx(j{U+Kj(uQFvsXRi-8pme_7(m+q(yHmN=yv1b1DRV@L`%q zo~iBamFmCsg4UnO5}b~=^}hY{g6m!wq!|jU@>{P(cA;yYl!y|Vo2p^SXMLWSF7#Pp zF_7UewXx^kM?ZDQki-bqOAN7zWB~pX=CRho-*;J^4VC-lKpj-}(PD4~0uD&;U!)D! z3WOnBe{oxj0cUK|2a%M#cbMR7{=m}uU9^dJMLoxqgK#L3pa>0q2BhP~`XwWZt=yb% zf?{vLvPi?HvHNvitu4ZL?3{z|#XukG#_&Vnl&>}S9w7j`xp#SfOCk+$YXJ11(+@FfItg z5Fmr;y^Zdfqo!56zmzFg7nX6O+$Df&Yv1xAJY554$;T8zCeXIoLPRhQQv3#c?^P9* zPaSYJ-3-tR4zN$rr!_km7V4qVLu*%S6WF=07LcrupNnfGA4+uv6#7`$9L_v1Fx-MTfoW@WBUfQVV58|CRrA!yoB*lJ*C7f!kka3OD0lKQCP1Hb&<}UN% z_BVNyov(nbxotBDvYXYWcd~57;xwb(l!x>eiJMdor~tBQ_rlV@wzN|{r9}0C5t<2Y z2Gf)aulKVT&Emy8(npUyK(<+)U?B~v#|8>3FFEjuHqeZs`7@3-<~F(e1d6Iu@6Kqb zrhNm29G=yR@gAH7gI9U@8_rACKdGZb2El1)P3_j9(%Q&}8)8# z#vu*zi>L+`c7K1rAf82M;@W#i^d00~ILp!c&1y6a07@64Wfh{|3Bp43i1j>SOY zlYb2=`~F<*v#-|<^cfC+$yw-7t9n&`HcqSKeRI!KaHKn#g$*57sFTCrR=2QE*gUS9 zjxb&-!0Q(#7oj=}vP%a0+zR=)VdMfP#}ThmF>&Ft0OC6ybyJL@(+NH19KIp*(7szHdRt8sqG})pABzP;xH-5A3`d( zi$~9H65jj#)Ud8Lpnq%r%DtngAcQz3g@<&F0YKQE?Wh ze6(PU;AF0!RtOf5A04$6KrKq0r-tMhj_iab*$!3O=K4&UM_&(FcbF%2Ohr+nu{JZd zA?D*K`#U~pM3Jg#!LSlDPk3I(W@%Ust`M_Ha3|6QQ5T#0oV7i;@FjMG{#OVT#0 z7jOj)xr;TExb9Zdu?w9bG#08t-g^JM%3gU^b8QUk3I@uXpiJ0=iTOBA1hlXSbT;lh zWsbEgsPe|O%6yNSuGJ;@!-aip`}7;vkBOcr7uukVk6c0bTI&-Cr1#S#^n%Ugu_q)8 z>=Boy-ycP_$AFIOZ+`6U`VjX+Z^%Y;}u{Z-Z1Yz`M(iK`^mcA1IttaCCq35mf-3xMZg z`0t=G+_b-$K=|cef|p$_$NU%uhhW*T1m$$@4KI%}B|(Mzh$1ENHkez1%bHs>dS6-; zGQkqZ_OgY$InsNrQs_+rln)xtA54XT4RwHTXEa!HLtZtqZ|Csduo;-=YO{ZIu!eHF za=N0Y16{qmMS=~gi8kVDYs4_-A;56bo0DsxeKe^K1d8 z?D|O0zmLi$I7^#*4kWy#_$_{Zxzd1!F~I@-oFFm7@bhxUxf1YGhq$zDaUy$8k=PQW zYE_|+P=R0P^hYu1W3v@Ir!b_Ul4ys6cDZvBTrQsbVJpGe;}{?AxKCbu7Qlo`6r`DO zMLj1E&S*Yb+@yHqyT~OrCVfg9$v2oW7Ci<@UA~K)FX;*J@N-Ov7-GVXwov8kFX0`f zga@+>m7>v76f9I=AEa}o=NZcq2Ik>XV8r_oO#Vl(Nvj{hjutFVY@F|IU;LkQ%BC|_ z!JI?86yc4lEqP$p*6;v}G-U+hmR<2I*rxs#g^oKQBNk=bimiF*++;eTb%=u=6C_TeaulieauB$Jwy#41hH@} z^4+3=SbyzAsYi;6AHHK9-u?cUsGR-Nvs()sp4I8|)FZYhTVCv+e4QF2|7fcE%g{vN zW2~fH&7s>#YZGsJAC%4&i%UAG4)(c(F}?-&|Eu-&09!1omQW1Q^}J_}yJ^6$loT3^ zY~mJEY~KWT*XqLA#_LIL-!00RocGFti1y&s|NSB{VKpSmx zfBbpc?Ipve2=DE=cBpx`Rx3V9Rg0n!5_GV@}IE`$98Ua24O()|bC)F1E)12HIe z!7cv(5CqcE^O6_I0C@w1?JL4)bvc$kZOz~YrfyQh-8{+jm#LEqqCT5tW89FDLY%kg z!@zSk7;=Lwf|#Us!~N{sb5SrB!1>FU?~QU-hezQ7D=}l|;|HPK-9I?u?B*A-_up4N z2~* zosn&0Npk#Dm}12j`gK0s%M0xDgHiY&j4tl}%zfhUH*fr`23|><5m4(A(7p(9AH7w} z{wMA6su9IZj^Ie*@w|d9WtgItsVgB*A?xcUu+?(t3k){nPKO$X`o3-8dnkTZPRwlS zv?2d4bPO&<)@8as7EOPAx$9gR{WwC>coL_SFGb?u=5k(xp-}lDcFL(@@2?HcTS=_J zG&V0^vuUr~-~4&!LO@^Iarh9aFVMr(>l5q*Tdesn9TDk$x-LA=qFx2^o3_s9)>hfR z;O|_~$vwNUXtbA^cmHVw+!g-vwKj0Zvw}{TDws^E;#?< zrG&K_An6kGV11NW$dGaGt-QNL{C)cPcI}m2UBNrmTpb-HX>u-quz%N!X~+K_M>+?+ z(Se8`I0@g3KkHr$1NtJsVW)ae3Q$5x0~P^617+mm{Eumn8n9}&KXSWikSBqS>AV8D zdZ9I7*H@;3e+s^)B3+s~ zUWO5s69~pd0Ln*9(sZ)>kbO-`0$)fI=!(xM5BWB{-npqbHj@oY^$3DxBw^?jiXOVS zNRk3z137}+jD7`s0r~UEG^FQIS^+7pN1yFc9LpHh0I2-*M_bbT)kkD*^{xgamx|Ao z(E9Vii~Q%eyD_kv&;7SzV9~#JOz$3M{)WP)?WA=P2gi9 zH{k8)E}b{{6!4J|L9c4^LmK2Q_?DW1A5c+{*^xy`nymU@%*U38-ipMG6sxh~Lg&VM z0pAR?8HQV&S566Th?iK-hyic^VO{h1`)f;XRSDOUIRmrMpB_1|^}I_|58?jvF^?l{ zNh2=oaM7) zIw;jQs<-L+_fyfU8`9_oe2MLp4HF&8a5ShN@XV5O0re$#6S))IweeNMLI|Gy3%|;~ z-F$CuSs;95vTDGp75W2eVMiLvfTnl;4lleqIN+-A_Rf1^V2gLv$tu058nN!uOJ#X@ z%QxLgs*xC82tl-60!geZ9-<}h$Jj{#>FuL)S9SBWzVT)P^-;aZAn`iH5c+9hEdww> zTTzWvIa)OKO`RcpSr(Sy+{j+B43;<5GMOaeK#FM_qiNR?(tJ7#0@qj`aWxpbKedUl zpVk3RD6+g=$Q>PhX7zoh*r~1Lj#4(fI`*1wha14F1@_vwv^<^?(441s zs#NVh?Ie3aCRjt5)jbfz zm}O3JJ7vxFrAE3Lmdy<&T})e@cfBf80`nODscxw6KHIe%t3idEcpZ$k@RO1?nhZoB z)QGHko!N28e;c%LIhVi0O=1FoD;bayIdb{3O$b28(kFjDk7VIZs}aA^6_(O@CR)!H zJs;|fITg>}*^B+76_bn_>*Z80uNUT7-W^izH&TWsV#Pchp@)YvhWm$3(N%D>DGT|X zIdu!PRHRma=Rs!oQ}XFc5M^{;%O6Pw=C>+*EWH~jB2a%4I5Si8F31DsXe1$Yu$FvIj=|g9|!u zB1x+?BG*7_yoISvHw;9;x(Xj9;bKq&L*RM9@%StxLHyPcI7~^5Fg)I-S5d3hX1Y%K z(W=vO!hqH^GX(-ltuZ#P!9=50>San`dD1%RdMcU*e+6^#e6lU)L6g>?)n(Dz7J*dl z;R5lJFGJQn#t?#tX1p1!h0iE&H>7^~w)#Qln2ml}_pbkMUY=iomC)p@_EG9UVNKvM z0jz)YtZm;sn%i@0$Tg9x5RGNSOVAm<)^U+a$yH{Jdyh3@_6g4T4FOF^Y|FOUc})-# zg|zkSl|fvNB2D|coAHm37YQN2m9lu;)fsEn=8n%nlW7g$r6b>WgJV0HamnhjDfO}vCy0a7w(ot8 zU!iQIIe@!uT14F;*YvRv`7k@GjPyIqhJYN0(*9K-;ke*iwwcm8Ud~cnUrV( zQW=3(T7Uv49vlI9E2GJY_|8ujCal(d5~A~>39OL8`d8K z`_^vv=)7}4M0L@Tx0Y}snG5sQRou;^Bma7w;7N)JLsjyupW&VqY^j2EFcDixG4`A# zG$?E-&CDo<2LBexO*U*moW8ylnsD)qj4$CXj73*qm%GOMCQTa2GM}U24G44`@=f8n z886+;b7~h?3I-T~ZWtDd=Qq|x7zro;sMUwV-vubZqm`n9+TU4Jh!O>jT$U~GJ}mWs zv7Tv;tH4V-xm))G)T&=!IXmuP-_keUf!|^^oJ9}-;N>FWYZ;9wk9ko52sq?6Xkw)R z0K!ro>WeXBi0M%(W~Kt-QFRhq&dA@~72FGW5<11c?}l|TalSm&C&#*UCCwPSc#(ol zxDgw$prZEs=ebk1h;{<5Dg%Sb>YZU-ilQb1c||bj|8)hUU4!2ll$gNKZ-uM&Bd@Ks zqQYX)kGPg98oBcgr?&!c$qjxLn*zSyg($<#LD@iCl#ot|R_96BOtwD{wR!f8K7Xro zXqU5JcjLf{GXd2N>82oW1>&-TL0)HI(SRaGLy$I*YzvSAF?xzxe^BLqirf&dJ+SEF zn+LE5Ft1h~RI3#G7(Np)?db0(l?8ae^6$)^T+DCNyvD!#7)xOH9L{M3a1#<6R@FX? zqPqjmkM(A0$L+Svv|_T~T*EH+VB3ogA5m%0XT)sbr~KTpQpER?ipwl&d~Ql&cP%9|CP7P5gez{KTf0 zl0r2aC3*fsjgQGFEtC_OFU)ijoap9IvQskSI|mQ%%B9r2(PS(GE)jBN)z&h<4lmq0 z8k@vX=|9h>?};f_mJ?0RHr=f!P7LW-01C^nz<4}Qo9(Mi0$VM_w|D~(SHU#&&yIne0$uG$?fg;fYj#A1rr{ecr>#}AzPaemaY`yZV8=MxzESgJhE%6Ive zZx&QTi$Ns+Nx@eC-0ALr8)fUijZ#fB1B00}*9AM(vUge?`pg{q{E$ROlj2=Rs-uvq zs@Pq$6Acp!4>+Tcu_h?Tb1`WQ(%*5$E5myT`dupPpghdAe7gaEPftZ{*TcYTQ$9`p zfe{H_OZs$8*Va3*yDO73av0-If8^hrtCV9TDT=|nVm z?w;AG6}3KHsF-a%r_f32xVsOb8U(8R>MIMjG$eFv2T0C$V{I*69saXKRy=_*Sh$}V z@F@s-I7~7D*cIH;cqwjpNJT~W^F#~zhsKE$f@j-1HWfrYP?7ImOBbeW!UB6Ugxp~K zY#zCPUz$vyZpZ^)VbA>=u_Au^e=iU{iXcA)=$tJ7@exu1u=VWMIq&$oh2xlO zmLdy8r8#%}pJtx4cWPSLd-i5FAs5w+ZEa{MM&&>^;<{h|@!J$ffEFwGB8~1kaBho8 zM+Th}!f)vf%yo5jygXLc1t=@!6mhq7K-aNG%Hg+=M%3}b(Wmtu-<0WBpQpR+>NR%e zOuA--9yS|0x6?ZU4Ex;%>*=OP!y)zPIGbnMYIIdKo_U=$TxoLJb<|*V>-HkVW>c13 zRZ{2_+{+Uw*3^hpP0f{T%zim&(v4d_9Uq28agMo0A}haN?fuXq{*e7a;X+c6+>ey? z3~D838rHT7mc-uCVvvE!Vd?69v}?@r*CLVOn7#QYdWX*dEc2p_Q{vS9zF6Q>86Sb& zm^{%pkoF)F(iga2z>>*@NzYtB5XS!*;}zC8P|G2=k7Qg#WMJ(;l!{YZI?N&PN46KT zkK}JyM{N}uqnvI)$oGDY)wX|fXSQSJn2t+C@W&$g?v@^|X#k6`{(D>T#Gnt~$Y!mXZSR`=F4j8T`aHvGih!sZZ#uAGQhFCku zCFMRt-xe*K_^R^JYjB>+{ z$$^gg^m4;{4419*QbNB>_`H@LI?hp|q0^45pz%hP|7KnUwp1dJmYuYsM##f)^1hzd z53J)CqV!c7ylz)@;KtDHTVm8yQM9fgS&wM?3jt-Dj`- zQu7Un$e{^DT_6}M{ADm-f92aZLycD!VX;%%W4i0ZuHlINrFZnS3Qh}N*d<0=@i;^I zV2Aq|B*7N9lrNqqv1d7&pD5AotRh!Z;qkzLkG9bO+p#-)ZgRfnYZX5&u*dopOBx|k zl(*6uXo0LhcMm7DrS#2l1}OLfl-R>J0TTmiVvIXKFH12H&Sg>8?~@ySl_>^RYaUty z+?YcsMAuYv2@tKP#M#vtFs$D!O0w~-Azw$iFutyL`LgOEy$c#7g#YiCQ2qAt1u^m%wL=-3Kb7wP6hBc;9Z*}sMsL}jHx3F&cFCmZ@PJ@2MN+ifcoGy{!$cS zTg|r(MV|D&pDXGa1gJ*TaDCGRrzUmuaZ@XT0 zZkTgCgqK4em$kYNGj@&#I~ap07?-y`f|YZ1v0>*AaRP1wsN$mIyBwp)+Uv4MuV_`~ zmYcuCmgR*r<(|s?pp1%uE(RdXU#5N-9~D4eP)B28Rv99hqEdU^F079bqN6P4NIaj* zP`GU~qV=tEvjWU_Xrfe0wv+XX=$(`m=!3A)242dP&%q~z?&41S+LJ1@&;AS7wG)UIDl0g1)k zs(1i8>yR~jg4W7Gij05dI4-h^=Kt<*Y#YH}uPm^-a&mCQa*{(Nz}LRxQN6nZxAMZF z*ftQKSEO2yAd}2448z@a3|qt|FLw;XJ@r)ApW1bnHFCtXSWeI+GWa#Yw@_Ts%~}z- zW}>A%`kTs{d2zb{{3?CC$0cMb3kle9$q#u|aA9 z`PKDC?WI>%JPV&joDr2PBo~@CNk_XymiCyjZ@oPA(%$UwJ z=6V;~=yL9o(3pXJg~L{II-td~upJScIukS8h5$=V1&BRB`h#dxF&EO3^+-saTb%FC zKZ|ZUj7PUoXr?uB^7Ny$UcW!$xy&6BSG||B@go5R$R}zz=xuh~k_|IR6Y@vy>t??) z_Wp=+T44P-RnNg@R&hPx3$GJm=Bd!g%Y~wE=Hd0*P8>(y6NL<<8a?J_96fI@c056Wi)C=?QduH381nB2zxk@*xgjNlWAK9^%~#`QL!$Een!Kke0vW15AXQUB@HZ-g1b_kPgjz8 z`_;|*@3}|<4i^4eqEJr>4-%;KaN;PWN!tR((5yF8;PAX1C?e&utU7dO>wyj-|*vYeP1c0FlZy{0G08nB9e{ZMOTJKs<)Y zeF8;zRGu#e*Aa_cDc9e97NCa7PF4U&Y{Dhue3Jvp1Rb?Gt9RrWAgTpp!52*rrHt}e z!VeGQVo=+?F88~YZaGIYzpV!QXxx_^GrUlZLkK@(oGkozuZlo3G}q5thz_)E!&Ps? zWU36{kh!I-4-JYJcp|o*-etP;H~_6`KItA0sFZRATPch8jmkgtQfYP~{ap^Q-_S~3 zmeU%Oifsycf)@PgW5L+tGgk>j?3@hCd~LU46=@qack@e8Dv&(+n)dfu?2 z5p_uo+DgA5);Sw&PxnwlfzznKjMdno9T5$WLZG5Mj!$GU8?O-YK7J>@c#jYQqX(g- zL)wkdl%#2N%wu2foG4Lt`jX&n3&V@B92#p65WZm z{EQqQ5-bO4P9tCHm;>!;rvwfp@zRrg)BbKt*2(T;0;+GzR65WKd&DDP6ldFWC_>>C ziQLx-pKYs)0z4E5P0MTFKO%pGy$l7+idXQpWAmZb z4Dw-Uj<-C<-hEeuvf&bdvC=g!L?EHte9i7e4p7W9suR|2B-3aIvA+kn;`;q*{B-my zE(NUY;957F;;P?^`S6wzm5*5SVLhLCM*(jhp@oYy|K~bP9JT2Cm{-Bo3wP$3&-d8D z!Pr3KMNT=?aod6;JRMf}s5Kpwn98*z5tTQ8RVfD!JwpjC^L`|?6LWOBSv7&tK_bHo zBcGZ{wnf5;^l@scTLEuj)%rQ$>F2LXMoDCK zlIZ1;2g7GG?*}1U&m4L0zRuqFcRWa*!eC37r<+@z5x<1ZIyKJ;Ylqq=I}pBn*D99A z2K>AYj=3!AKTr-L@Lw14PypBd$!c-BlH<`VnGFXM!;9KOT_!cZ@1k{@(Nr?_9KpBU z*MInQm4^+pH(79*0_eNQ5we9Zw`6D

sPBoyVI{(@@@TnKP?RDicXcFnPZ^C7bRB!IOYUH<)%`&0p5 zRYp+4CIyQRlqUiuTs% z-=@(KOanygzlwm2Dr5Js)c3DfqG!mojiwed7t6Oe&6Zdyhq- z-;v1bV~vDrc<#{WA$(gwiS#E&7)QGc!Ik^NGr<+F2{^W$lYphkG?%1)3SeSZ<@ag{ zx)zoZURkaL_<#kWPt}4@YnCcmT)5;h84+)4$ycIft*5>$b~LtEtfUS*soIpgpT?Ck z^891l-1}0^pN9Tp#<*&kmD$)!@^r1>xowRk_@uyQ5N;+yLbH=FPI0Hli(3O(8a8fh zSftRrWc{w(3V?!9pnw`iCY<_Y6bds+g~AO7l^QgC82Uu!6^|~PT&M*0uS;M3V?#qO zF09S;FCVp{{iNB%1yhUYmrlGznUOFV4%8R9R|}Oz*DkBp(oAWU+_6^cD-;Pqn=zUsF`^7*Nbh|oNCZ@a}a<2yK%a=A8pd`goN6_XuJTi%9j>0#&?4xGGr zNMk*M{eabA7fi?mY5C+S!C^jn*kFzQA5t)P_b;Xd3s9WV@Ff=2fS)vy4M-td_1X9$ zH#|`xIN#WV2i$c(cN5Xe1zQ1GA&&GlRV8I*^{O6nq7b?1uGAhzG6U7NzN>yu6QN^@ zh8Ygdjrwm%8tLEC&B^8zZeTX1l%J2Miy`ozp#ajy5Ym+YS_%3L9krwf6-x?xqOts~ z=kA{fD@x0FUB#7Wygv=5XLZiaMHvopS=}0#oEUJuz^ViRm+1*hPOwc*wokPQf|&g1 z>}>!mGx;Ya)lf~DO-*)&Yy(q0!niS1Gaw^6_YJApJpi`^eFu%~F7ZE67Jv047gPfr z^eL$}6}=Rw>LMf54!#?UMJ-#Z{CG3DV(HLb(8)5Bk|B~o#Qw~L-9u=XhMI&IG7$OB zet?T2CmMoCbHyENl>9UPZln43N51n7ZgHZ!FPBZs0zKURBMO$o8 z_K)tmess6?{If*O^^flOizeL8K_yVlaz$D|Wd_}R8$}>|{6N>~vviaJAHQyKH@~4e zQVmNFl!pqRKUA0;`wOQ(l2~dF=XmJVbg9WFbW@sjsasu^Yx(_(5<*q8?0}*Cm9>!z z3qN$m(vrKK*^Zg#nEsl;!$=}GZ5XgKOaG-pb9VD6^l<#6VUrltanRb)L!`ee>AnGJ z34@&-Uj6R>3KZuV#8-3+aLn=cGa5J$?sni0+xIhKZxr#{{WE}W9ldQ;gfCo17+jyz zM9!G7{<`VO&ARF7^|ZkPSuMB=Qd!xoP9B~<%Qa~)v0v>n}BntuML4YQm zb&!_rdYh`}bUq;f)W5HoFYBB+eF#Eb4sAQo+_X!iBSYLqPxHTk6{voL z4cs?N#s4||$eu`y2l7cy$1|Ee!4j}@*2ps+t2%|UGrHJXpJ@Qjzp#28ZG2bOpuO&} z!$O86?i3R=gUAVBgs64IeV74yu(P#&j%V{07`ZDtl&G)(Kw33J8s2qGOa%;FuZ9-4 zeBweDXOQR&7(*UE<2@_DQUt9^ljRCLVGj@UsTUIvNXRj4kWU>u_+&|N%q;8e@=%Qy8iPSzw9w5VC3lgo?Nzb4qkqM_Fb86Nh?WW zaw3D>fUBy9oYu;0Lw3PMVIKPl9?u~KQ8-A=V%k{sC_#ro2h@-; z3X#0!?VLNJDj6^|K-!X>pH7nrxF$=D(TO8CXStlBP zGyVb|$PC)Km1cuyQ`KwXJm9YRjZP15P)853d|MRJR}Jbo7F{!Pc~z^Gfe0C^qPj1| zv}ZV}7v18vJ9x9cPn+??_Hn8Kn1}a=5zoc;f$F)vdf7(=fd|L%^o+k(=5(h7K@xvo z0_#Wna{3^qERIeB-rJ9VZG=zinG&hOyMr8tfWK3h!dS^#ag67fD;C;9qSYWci21vD zfy~h!{I7{A7J?u)wC1WHY?a(-Gu(%mbR$|Tx-2$G2LpX=5PG~I${Y_C@PD{^$KcAk zu4_29ZQHhOcWm3%iEZ2JblkD+q+`1~ww=7^x}RU)SGB6nkF{%`#X08O6XOI!MBV$U)A<{PC!&B)K*Si1lphwE&xYNn~{H zE;Bt;-=(<`moEW%B-t*x0eft;(Pj(GaeGtx2XTQ--=!s+=>FvQRb<03g}+R6g9#5KvuJMPP8V9Qb7RB) zY1hkArbpLMKB3z>_FYUJ<28w37U5X3%idGi?6;F+*8At*%b8#G9R)5|(sI%3m%gLf zH$O0DR{D3J|o_f z7dtyWywA*RZsr1Zolj;h{jnr_kJyLAgyAfwwh>$5gyG1!2kZ-{SGWPSQHzjvBsRhr z(lSRF02Q;MTiirEa^a6@OM34|B1_nyv&1Er$b7~n&nGVtTL-bbTae0UwR|r-?i5@j z=zWpNrAyF~H~-eL%)_Bwf>K(+*bfcODG#d24;F$fO?pGzNMVh*%*jjNij}#n=dl2qu~^cc2$ZbR zfCn(TO@-)g2<|~UGz2f|2NM^@Za~ljym7tcuq-`{Hbe$*x*uIA=+wb*eKHkfDXd&- z$UKAvjGUja1|uHi>LYi4{@)FR=Rnh#QO;j|!;4%VqM6v+|?48hUstQ9PKM6sV1$EZy`9 zxSH})ZQe?!$TMx?#(_!kN_}6CT!?axLKkrO+@#T07a#TAi*a|&k z`bS2usy^0u^2_=28%HBmdXpAu)|i%HUh5(a>2^y|p~k)Z#If;-^Z8%G_EBlFSRRJ@ zV;IQsk0hM`o+EZU6WmLUUmmQv&gN;0bK zB;sV=q+riy@qCJ!%{y^;fkb~nzVf*!l|hj_K7xHecfMJ3-}dlq2&i<}>-zGTy4Pdg}_YnXPj14#-A2g~HPeMG>E55{h#i z@9g`dgBJZprRt1(#BFie3(Ap#+BdsjkyY)n86LPy!==t=)<&zB&+ylM{x$k#g zcSbFF zZRu5h$cGk93!mH2@QXtzFkH@48Av-4!1yqAs32|QL1 zIDJu}r|tiq#&&n9U04#-U_R z*Jyx#aHlnjW?QpD+~jzF7vq@2uMw|pfP?D^`C&!SBoy`GPLH4c+w%?1b*j?0K~6dU z#chL|0S!cu(}7W!(^Z>eT0Yj2nc=Xb{F+IZ#}5Cfnr7=1`ND6j!}ouC2k00XCJVmr zFM6Z9H=r3>Ww$FrY4kzW@P!zTLVr!UIl7lAE2}0ZBSeZGUEG!$WhwF&9^FMr00>VY zgAVKO4<_1YO)!@H#uCu9{bJhC#=;%k6MTVdSYfz6*DI}$u&`445XjBB?S?8RFzTaW z4JLo7n(Rak|CJ2HBK-avyhThPlCjnzfvJ(wk(4UA`RGuo+lH}2N()rW?##y*noAr{ zgC(vQ6~bH=%{>mL{D~kBlZ=k!0BUI-g&DUi{55l8lx_OY(;rZ2I!pJNpg7Tb$H&J` z&~Pqf+%SCHP_#J1Q>-Ijq^IIoa44L{0?zs5&oHIuZWt9`sWASc zV+rXoCdrB3VZk!0@eRfN7p>8ai_C8LRumA=M?vO{Bg_WEEjNlkF~kxN06YBe85rQ2 zx-p<#=-5wi5R>$Bsh_e zHBf(jLkEf<(rduR+GC0IyBE%s8itY^GCZDbLanxYqiw`>*ckOy)n2Kr(W`$3(;Rer z4%}=V&`Rpdx>%hCB%<%(1Mty*#0Ry;26{erCRyLQBsLLK=!ZKna?&Lf?L?L!MQz?R z#|LrGmv?nD{Lo0Ha}EhKu2vX=-lUGw4e$rWT>VQus!fa{1GC0am+H(?3$7Aa6@o{# z7rngZa+e;!c_Ang44}QNu%AL8is&VaC(i6HJ4&ACCCi8J+ffDz&503l=eDqS&n?sU zh)>~YjK({$+e{!DpLFeeQhq0hXAo8g=^NtGC zrzaX>bLOwh?>tnj4$ewxo!Y^}1}Z88CF-Vvr{6JD(Ir1+%b<^vBCRj_1C@Bf2T#P} zRd9gv4|CKy3>2=kr}$jgLvGN&_>Vh_3E2cdh|pHC9Xx%PGp^I1)KRgk4RMjF;x1v5 z5jSjwM*zUar#SwHs+p5gffYmU5IkMBke6)>2G!Z$G>5+do-?EzsDU*-0N>28y)%~{ zhm!E!B&O^NVo-$&t%BV103t<>z!UToVK@h~zi>>~UV=*2-8W~{Q}MuEhnwEoTY5LJ zOpWN4)S?1u=NbPtOp3qmyoeAWhu8U2`kU4V10Xh0iIT{);CxyoZAe2<3OYL_<;T6+ z=V+o!6wd6meRa~L@UvO#R4e{XaJlVA^9Vg9Erzi`__qJhbG?@=xTm zXDV&HFm{}>pjoh!Cnrec=K~!BkbSb76p42V{DHw4Bn|KkPw*s~?k+t=v4wxEZ{@+R z^l$(Gq4&Viq5`HhGMFe+ct%`Q4(%FGtJa*z|*ZuvvaNVq7-~BQfN$`QKOAF{=$c+f7iLAmNbKOeppPlpj@(PtN z&&NQJg-SgJA!d*M9^~VxARp4St*$Y)QP;>r)<`P~TY&YR!=FqkJ+V=3G0MCdd6^9# z&w!TJGW#cc&99o63 ze9WP8-6Ke`C7xCwQn6zx9_iAL)t_R5ctaq?j!M?m^MJu~wL%%*#2+@Lc#R;yK6n#6y-S)kYw;It<&vBFaRGoRSZ{=3F2v;Y>6!LE3a%c=1Rj|)QiEr|5 z%#27KS@xsteY&!CGQY4knEJ6%Z8{W*9Gxvy=w)X+?Q_0)yo9lvW=?y>lV;Wo3?UQ< zfai(-b>mq30hWC5VJEuu>q3{vNQXB?j#}?CyiBoJ^uxXOC7vBw*e<#Lh+AF!*{G5N z-ZgXLuo6p>6X!t9Me5a%WF)lWB+Egpj=v}LG7N2Pr&9XDJPwqMjhh&Ch8p67|6mZ1 z-m=K5Ls5CH*3N`GS>-Z{R68n>{U?SZfKHN>A@2cc3TFy4UG+TYAnM@tJ)-KoRJvXzQV)oR!$kYtS75Kk;JaAB+e?N`mh$+I>&8oL z>sL5#<@W^{ntzRh#s1lLBAY)%`~?%0ZAv)C^kTwJ@pSl#Hjc~?6(te^* zug<@7C^f~p9T`Z-!pH#Py<98-<@nU0GC84^y(GGrJcf_+I&w(JYK%d`4c}^nuGr8d zI2ObQ{}f#XgQ%d@XE^AiA|^T$8Jy>>N~}B~J8lATIw&*yX~=W`?n&F{_*f+H_Bh|5OHyZ|q&gZ+?nKTG(na}S8*CBHNbS_I-Lgz!> z*-(TnN0Qf5@u->~gd|l7DM6fs4tSASidmmp@L$f_V+lrBV%0?``-z+udLWzIcp#i|2s$5><#1&x$_YIo}|vgg6||&e9H{ zuCdpJzI&iC-wY!_J-v4TuKi595&JeK^ak4Mxg?qMx@$Wc<*&}K!NarRVZI66h%6 zolZBNPimd(n;y|yrQ+Zsk)YbS@R@!P_1TtnLY+n(sPgV@t+vpMyX(b7UOu0mxf{p) zd44-<@fmA9b$4}e2mEOa_9)LyfrP|0km3bvjbNk1NQTn6H|>%-a~oY-?Hk0clD_W9 zJV6aA(t4rOMU#PmKI0uy*L0UBIFR9K#r0Qs%!Sqs;=5k%;($x6<^)8U8a8d~s9u#? z`I@WMWH6J7_lMlumFBuGtT;>e`j~)ajW$7h&jyM6FHpygE zNW(BIIXAtMmZABwy;U@i!a(QytJvIDL;fS|J+%X zLYDfK@Ere?;CE7Tb#O7-Q476h0XAqpQFlX>{tu1;KJEiYkR&_pOsEx=+C^btWeLaG zJR&Qo%kz2`@mU3>C?JoZiA6_}#wOScy%=K?d*$~lU=P;S@Bmzn;G=V#zP@WBSgadF zg0ZHLo`5i@1!qubXImTk08h_s!8-lg%!CYu_EmHBnyjWNT4+GZD=2lpRFL31M zg`jY$6w(!Md}EEUT)Ip(bl0T$d!UJOF+c+Gm?r<~L1je=hqB}m)xm}2_XM)-TcQyW zzs$dOyLlO?NzM%62J`&VA9Dp-iQDDgH~{SHgM-9_g>KJAnubZ6xlYk+(~hw=VmnUO zj0y3v!3R}exMyP$@@H*6e)kg=4AYBQ+7%FdQi^&10-Pe?NaL$Im0D0sSrHmgXJGS> z(4zMGX#^9KfzbH>gTGLgx~Q8++0cfzd}aCBTc>a6&;|oW0L+vvHs{m5;jBn=16HmN zv(-{I`t%F|=Z*LSirx$j>vZ9WMzd->3noxtSD11{fL4_77N_otVS0iqz1|y$dkk!X zP9ghLX+pXp?U=o`Vl9Ph2adSL78k+8uWnCOT};#;!1Z;C-Ruvpl4qzIk+AW6>;;or zW}KA9+q8=Sv;?Uq@2w$}W8K`iDx(G3RVj*oXQd)lqi)rADp`C3x8P+rZ|+`_NC3!~ zfJCE=>J#+$Rpow;`X0y)HFTIxp>4RzCfC|hle!*FO{(ni~6})AO8UUQ=ve!vn(EPfM%*0x=mQ7470o9sMhf-)*uni z<*-ocI%#o{za1<&Up8>FN(#n#*`pdFag;?QEEkr|M^L&vvc+oa^>B!6RZJ-{)5E+guYG znMMj60zU6{t-~A^A^8e_AmsD@2lhhh-9o?jROGaDR|ZoxV9!9yUy&;+IX$(!0@@O|>{0D}~^M&h`e-nWel-xb`ud z-ECC}tjA5TIUL{!${}Mw#o1>&p;~ZH2`EzEz;f4`htegg{qsqCYMTyCY98+>{*i;| z;e+z%_4p6kdm5dFF$y-VM5bt1V6=Q`(n5jDx%<`no`T8YPRw4U0U zO08VY=A)K5kt(Q@iztcR;8Fmk)tMFpG16!5yl4#(af_VvA(H+-YhfW6Xf3dDvi)E7 zu^rH%a{K-T7qC=eB~?bF*2w|+CbP(oA-X}Jiy^CG?Qp3B^ry&dY&ie|jztA)x6=u( zK^gA`{$(YSM&^-5mS*?+okQ-dY6VYy-yEIY3riPMx4^Wh?&Rt*CrF@B6)fux%l_+G z_t||{i@EV7w?KK>CA>4xG;k6#`&hLA80tp`@9KZQ96cTbGDbrqWHC?+`ZsAP%Uo!7 zF4!G0Crs$eC5tFIDx~5F=4VTq)g%J`UXs?@Wktn&7-%~E`Z)3}ttsqiO8ecJ&)k3Q z+&fpc-zN;As?u5g{KJrVk!n{-R}6nbaz@DGbMnCXdX$Gi&i<(wSaC0x0!_6B(2dAY zxe`&SV*%a&&dxPel!^FRAs71wat`a37MPj|nPJzjiRDB%u9J`Lgj~1ERNutNg|(VH zKKk`5V(QuEQ-m1t{H}G<7~#3C`|zW6vdO^5zDu^Rf8ru4qJL(`VKZnjUM|ikElV1` zx}kzDcS%usXrY^~y}iczwNY6e;5y$rxiI=D$7|;WYhw7m=499p0e-mqm*kL8>kB2U zvl^cpmn5`!RPmRT*bY0f{r%=Us;r}Uj$ner59L>^$W3y3V^*(g9Z4P8niOpP@8BbK zLeJc{fXMjTI4+gUx+wokVMsO*_rMRV@LCOxs<1l7cvZ$0+W!OP1n{PstLGXRUB}WBQ9I{~e zQTm)84qZ)!YrMW`FcIkV8!Ko(465B)OS&=Lw+R;6Th$pAF?2?Z4~1;A@XPw=J!>+*0;p9OReYwbCw`_U z94r=4m;Ei>)M?^4b(Ym6pjvyrO2iIRnczl%Ib?Ck4712SFK-XPjFOP_R#*FaT-I`` z3+x37HfMvzc3r z5uqBY+x^Dz=C1;O0-&0p`4LwgqUr%P*k{5by!qloTpS`QX(%~~ITx`cq#72JZfB3T zJCu32(;wRFU$1_@x^S3LqgA02X>h~99Ko5{=1|;mHg^Bib8`iyaXrYEDYxD9?ygbX z002F~%|-6=rv(cs3uh@qBcS=Ztb}wfaomvokOMQ4r(n&z07fkr)n+cS?1<*F=8^}I zQ^$RgAgN%c2Av)KGmz!rtW~B_GxR;ifpv(PMN_1W2E_}>VgDH0@T_NpKbZH+I9O4y zSw-w41acfA?a4?N5&}6-2t#)ay6Msg^f8Wr`AHcqSb%rVF!tKg34%Kug1gc3Z8p5<^u-%;LkT z3oSI{d}9;#kRqh<`*29TZ4@bk^kZbI;XFgM!(!YtG z+P5`)Ksc1)-|^;w9iIl-${E=mzhsM8;CtQi150!rb~Dzezam`VW#WSqN~v z;`FWprzn%;a5GbU_-ny1%z<6BX$B+oJbtKalR8EvZ6TzOU4g+nl>qjBAp*TRJbocU zy|dxlUkGI1u_OA`V5no69TpW;n$9-6kNQjo@g|^|39x)x+5XPU-rynH6#Etl(X`c= z_;X$WK`(GkGwlXYvk;+TE@l(3JD--{n1NA|m6oB&_!HK!rnw)#E)_7f&K=_GZ2u}hCN(&#lEo2NqlVp4udGsw za@>2~anOx71m;47{vZIC+FA?~*D(&Ipjx{Y1nk0Zz#9rd#6f>J#h`MCXHk8rfmKROuoD=G>w>3@Mf(EGQ_;wvbpGe%78q zG~dq~&Y6s?Fl}loQss};?d3lXXl$ILSFQj~nhwf#{USnINddX*=&)w;Aovjc5McEV z6n}YVA6wf-Wm?4#off~=3z{B4rH0ZxZBj9IB8}+$Q2P=s(<2R&J8n>ZsYmF4H%Cn~ zgg&J2QVxwzbmNIy$`BJOF~MpY%|at0;zwgSUzSo>98)P6a7}o~-s+BtP=B#9@Q{r{ zgOCB9&yv2=ZH~>ekKx}t z%NO)}P+2Y(*`HP4)RFgvVX|+`Mt2$$6Of6q8AFxlkOA2KtX7DcuAFy1nmhw|$JLH#UI|k@BP4lLo;3P142d1{cw4GGwl|>GHdNAC|CqVu9 z<%T<;+0B%YFvu9vN|rY7&8=6NrHDfrD5oEVQVaIa%R{f<4XCLWrz&4$ILrkThAbS^ zo&+&fpx+`Jo((3W>waRUqA7H+B9TPd_YxzXKLGrgor8;L%|{ zcK93iz^s$bYgM=s8#S^*N*ig&uk8I2Cm5u_>>m4Rs8JHuh^>mCtimY#2yO63;BnQ= z`)#QZ<>8bl@CJZR7Xt`*VH7J!N-{8OVt5%ZSg%8OLsW4Kqt)F_yOqt_8^V-y2_?_JQ+%TEl16wk~ir zn#9VTO^*)e%E|3pZA0<5p4VM{@iToB#`!8*2&FW=6If2XBTrz-kk zUGsZz7oE}C*g(tJ$^Zb_*il{B+#2R{SBQ+FxTC#)J-9y`J@_|xFuO8L9w{^%tnT%7 z9k-Mq;B~~|^m7kFMIa>BP_E~h=#Q|+y}kU(TuJH=LuWcLA4DcMVMW#2q*vgTXX^t> zgKT2-hiOA+s4HrBH78=P>pT~9#QfL(lXa92VB%1Z2h^eud)0f8?;Y*qFdaq&IldeY zJmRAGFBE4R;sleusAEZM9Wvg~;Qn8N>V$ImU!m3f2_eOEd@p_^ax76yaKvzx2VAT8 zgu(s?zwv_&3`;Lf#=af5?h9<2HXp9$irT6dFkU0dneG&&30@;4&3}pn#an?&hs#MVT1Mw6;Jv}29pFl4>q zDGU1*6?KcSBLYE6BQ@~Cmd8Ggnw{;#C8-MDPL1t~M^bh(l3eVSbtsAtI~>NtacF61 z0KgV4LDO{@8QpsdC7w&M3+(~!!52zRJj;@Em|5`Li9_R zEro&1{AtNI+L)Vv$N|Gs{YSDp9a2&Q%HC-#uf!si)ybGwk>Kvz{D-WkZK%DzMVm#s zDux3;yEXfP{IFEq;aOF;=QmNbtYl5%>HeJ5OiOb5y0Vu8jHzAxFlUvTtkti6HBw8^I5B$RJ@4Y8*@ooRD6&q^wjq=>G($!EjDX_ z#tEiehWanhwLeU{;Bx3wiN({rWupq>H1fIX!e3(4@a<1XCom|>THS7cub#BeClEzi zUXtuV27Nr~7*AO!ev<006?Ca5!b8iinIAK08hsHxsGrKpsm-)#DT{hn1LHcESeVzf zR@KFeC4+@v-yR546V+1}{xPqrTYIemEZ1fm7>CBI{?&wX+BAi%Bp^Db0K4o`z%~hV zbL|_A5@g5K686vrESiQ}aWcc4_4~g7gHQ6}eD@^zTpg8{n;}g1?ilY^Vv=iKf*w@? z(&P^f*IeS@m-wXlERAjrcFT=+v=}H$VU2r@URA zZkyb#AlI@9Jl%75j19;H^R-=*Z^Eb8A;F)EW=`32y$*2Sc^!OqHc@CX|D8 z5XmsVP_Pi8-sCT^r4{5-KNK(n!o*<$j8UK_M7sK)@LOx(#|9#L`4cUcd>8`bMuE#M+_ zm!SHN|C*VbOS`jQ~K6ev)JRs%FdFg6w998+AuuezSA*mGRgg-TIn}@JcaBQV- zu??zV0IJG_XUxEVe2L`}&zu=Zhw#PPlDt7T5|cV>TI^2#nXv}g9JkCQof1s$N|8p> zk`(9b9eWBO7v1G}0|-F^LTi-=tkwbtSF)>Ne}2r9hcq(0inoA~nXJ`=c6n@Qn^vC? z^IkR1D3!;5x}hLdR}RzAZHLFGocf-rq$fz76fZbLFr|gEz~OTyD4&W+!W0$oX@Jbb z2tv$Rp5VHnP(?RnDu{XCfqsC9_YKTz-OTM8`w_pH^`@Eb07Py46N8kC<{TThOYL;I zM?dpqDsE?)`ItiMQ0S#yOr=#m9jaJ8iV#Q01suc)BbbOYgX{jC zx{X*kF~9Ids7{}5kJWzPTu)in%D=DwpbrGJql*H7iN^*NO|W0(~09w7YHL;rK6VNadipV%Rfg>+1MfJ6I&n=z`v#_9$9pParhsPuh0?rjw zg8TtRB)9k&eri&?MEecF#3y3^d7qNuySkxfz&;LlBm%g{TpG%Rw&K9q+gHuZjSMv{ z4hHcB+VA z(H8p>SS^IdpojoZ69{l`VTxwv*rCiPqBZXh{pJ7MGyW3idAu%ixWj#4Z;w>Q=)G&r z6p}F$XfOVIL^4{InHs|X@i##O#!G_)LMRxIlEwV>H!_&=X_N~i*LD!W!lfi|CMMZF1e~T9PW;>uVJmLuhYJZM&Af>BzrP}QiQuP6-^W>(%ngN{ z1=u^B1(0{6zr}s>n#(7yiTEMJ{R;ZT8Ss+%StYaZsNKDa$=q9jOQ{81$`jk%V)*lF zP~Qw3TBJXq)PXoH)UMWZ@s)vjY&(qrHTRlJqt)C#`S-tx-}Vny`j8}EAN@V=L;YpHr zV6&x$fylXDxMYOXLLS9r_PqssOGm(QtoZ}Su^|ARyNXg+MK!vCO8j-JO$HF~_$77y zKFh2Ay_Jkt*5YiqaV#QEyF=aWr-kCz9YQsgi8bZJRSxYmS5xWlg0G!7G~0+NR}&ZL~T zPNe;UF|`$@i#4mmNPoYsTnE7OIqsI;(a6&&rH!aI9i8v*%Y&s7h$K)*zTY&`-cKkn zZB>IKZef)S9=hxMCaLN4D6o+N!0cR2uqo5#gXmq;-LVC1ug2;)m(US51?}*zGhLhy zKD~@OxzTOctWZvt24gTds%#m@rW)|O%EFz4jKwED?7-yvcf}(ck~jc!jSiM}oLP!u z#eM02dJNED)V?&( zV948RU|tjFU0n@1mqSV4Ye8iMq-!vc$SlT8)7X5x+=<~z&ggj2=l{z4LMY{LdJszf z3_7=@DYwgt7Wil;>th475f7<+?ar?pN5CSJg#DZ$<=5!9seAdnjD(NBJ!?8#X`Vgu zoqp?N{q7S_(P@QYZ!7-YSJ=f%kE~HAV6H;53d%Yo?&ay#HcKDYbfeCt-FOJ=RYAn+ zXXvn{Bm-sGKodaim-W}w0B|H^-UK?zoiO`J6{po=F5|y{4VDjp77e~JUcd4Znd~NO zhs9qaxHt;lBirSthf5POa63<-?M`8|dOl|}?lvgU{p6Njx0BR{vW99i>{6J6QvV4{ z^-|M`bGEYO@XNWQJa2The4z5T>~YT)9q!BcPZ0KxqZ19dS9VO-HsnQ3cCVi)GH!&w zePHRpqIFah&>w)Gw&qsO#cz@2`jff) zF%H_yX2GpZ>tYrmjh4mOnIg{(c_7ug*|%YJZ`!q{#d=IKx<^jmAr1wwtjF}$@PToc z`8b+Y6=)pM6-TIZbb!~?-p@}U$Ly{{B-;2a7j`^n*A55Y?u01ffxfm|*(_xN2jIM}Rtq5Grg zMvdj&4&E{wl1wAsbQ6fMf9oodTCRZ5f3$6Ra_2Oj9ji?1N1GKuoApUdmjww)W=eoO zFB;>F5}7UjDb65*{5*GHd7-Og2_iF$HN{pQ{L>|D8K@d)0);s+oauk6fd$eY%jpgq zAVICxAL9RuFILl;<&g-7&>;IC&w}JKpDqy#7 zFwqs2{sTqQre150si$WOOiMpkGL}pbBZhJeu6d!LOwsfEeHMXMk9eo$-?$CYome7` zYXp1V{+O~^t9PGqY$3Du{dt5KsbZh7(TB@GaRK8C8G=C}bMu(N#Nf!=6WFhCe5m~p zH*O7ERjSyTk=?O|yKNBwg3f6rPm8Z@=553FQI+m68VtvZM5!=sofC0UN@*F zp`bt@SY+k$zCt@3-xJ1NmS+HNT=Q(NA(>t#vz-6Bz{lU?SYjt8Lql2sYG*O?$H)v6 zguGUm5X{pSiAHR$_w9;LhrSKe;WhUvc@~jVqj%Rrv2&n7o!AvXLIv(PcrtBLkM5dL zuyig+o}S4r9TM>``aEpui`;kifsm)U>XqeY?Atg{o0xE)npr7idQr|g5G9ThrxL!$3BR6HlW=RcA7vWH-xFM$+srh(?%7L$+N zKAKTNzhKcDu7Nf16pmO-!8+jr2Da0}nNqE`6teH(OmkHMdF&e_IJFpYE0A1k)?YPf9=bjREIoJ>1i+q~s$l{vneJqT`DZ~mICEbyE&gBg|- z*{eJu49xjs+Xa?NDk+}iHqV`$^UK}RoO~&e&E>!bnvY7TEXes%sXF20-rt6X-ws!G!s4NXnH%ae!8o3fgf?!E2?Wqz<( zzL{X=e63Ud6`@RDdabW+Gb=$m&zt^uBY?#R@YN+MNEf=;T4cZnWyF6&VdnY*IfUN& z;hOR3*KZqAf7MlR_A8Y)?q<18%F&^<21 zRt)^^>y+yu{IRe?<1v$j*)ueL&>w@k?ju``)=}bh7cNe9_uvsT;SW^S>&Uu=`wQg& zO>}^1;O^s6R^haX#IzSCpV>5gln?O}HKW1RAD?8WnkW^ev>)NMq2pL6=s(hXL-DBP?Nd8#oQ)_ms@vSP zA=qzP7504^o?cmqQl6;f|CV(#Ep+$lyB-7BCQ7|@?(9^tDLZ*=B=kGUkKq`me1;B3 zNM-4j`$LbJjRl;U?<2ufP1BbsE@uoi$)t zPyJ^S-oy*WeCUkpXB)je^lwNfh%jgA`VdR12;S5Nf_?wJde+L?P2B^mL;R+-hn)aG zP$Ls$0ow`d#!|FH&Pv8}r$PxIqpMd(NVNM7MZlNvM?^2^4!uQ`9ameZ-tI0{2Cr8X zsegVHV*C0p2&4N`g=s;4|6e}V~+(*<6g1iN3k8Bz0L z9Iw`?IN0ChhK{{F21@o=yWNL=QJ5%znqN$}&t$5B(=pO;4%HiqxKYOja&GH6L-kw+ z+!6iH70OXG>+H2o7=S;F7b4!ZOe&nE zVz7(RF?m=I%NN#Q&(CW|mURw(=e`jSFo0XyxN)Y^PG)p~^cQ3wepPhrCiV?r7+={W zp6Gobd!uSU54*(#*FvXJJuU*)$&S9BskD1?j*#powli5jXSb<}T>Y58aKYDa{BW|2 z4PLJaDwvF;8}e#;9#7J7Mm<=!bQ4|@YB)m@*DP%ByaF9k#?(-{!q&>j-+CQ8BD~Eg zuh?&~SkCFXNqUh*St0Y&+w(6#fjd#Ne}E*$mHmn;c#i=R zH{XpJH_RoIM+-t&wwW$*H6DkOVb-nADuyL|syXyu!9P{znK_o<1Og6Ox--Ok)Mh0>via*@rb;#++X@D?oXngB*Q%vJ%m~Tok;3_Q zSqF55SeKjA4SQ2fCl5NU8{cF5LswKbys_q1AkIS8Lh5kM>6drD#h^~SQ$kyJ41rSl)S-4 zn>L-wfgVuIR&m#v-fFS&ugkqI2;`{3(rmFKfmk|>;`%|ay=8Z>7PHa87RcP`A7uzV z);k0P7VRnhnKda*2YmrCJQr&vR9#)^6HUr|%fPHXk5o9(EExRw$J}>`JKyF;&<%WD z{QBE635lmlG(B}N%sUSiDWuN}3PIw9NY$i9i~|4xz~>mYyWyoM@dzNch;Sq&A7*pf zz+;IbIv5k^R9w~EK+<4KeEyNsw+qh`w&sSYx-O3QZR_(D%j0r=AgliVJqH%D$w$l6{BpEfjjAsE?TW{_P!A0Oi$kgKSGL8hPPOX zNDBB!X^NNpS&4wQ*M=sDXO>ay1tMjK!nA;D?oc|30)@vl$0~sLd-P~v);Psc9_Y!tD5F>4ThTjaiuk-;&Zg?%{jl?@a_2Q={XFY1r1f$F`a zbzMS)aoodehrX_+1`rz^d>&jn*ifp9=zYLC=%V;riWv-hCF7Ti+OkD(39+K2uGgF< zJglS#vZTV@T2N-ZIJ!Hn!nu(UegOg=Ok1$iQBPh7$UuD?ZI_d(n z3OAlWxf9xlLq|}te!i04ZLrZDFs|BvlhCo_q=NUtj7ub$_YAA??8mMJ7FY>~uD$^G zk7T0&rplnbBmWHf#h~S|LucTTIdo==M4d9xD!w<$fv|7NnF+K}bGKn5`B@^L+9a#P zI=|Yp8SncxM-=zxz#d@ry2YS`B)o;~=6xEp?9J@pAviBz>Be(aE*L&rFapahspYrZ z#8Wta&}|z&Kg6`Dx~@NKm%G9Rfd+uO8}$6D5XkA9=uP=h4DephO6i*bzl5u>ihcqr zFY~?EzP8QEM=WF;U2yrrfYeBYxTo*Q-3!akTJt?$mhSX15xbTtFLkcn%OA-WHt9gp zEklfe!9I$yVb*9XDhl-XQGHSebUFT@HZE%T!7Qfv-U;m7ETLy|1|t?`XF&Fj#53-o z^z@E)W9#U-eQLuI;WX@!uAAAnOt#wk7!~4lFKI%ukNuE_wjNc+8f8t&%iu@dyqHU< zF(<9*aFkl#2|)S9T)hveO!sqPQla#glJbz0Rcx06d785j`tqNSm{3s+)B6p6<&Wn2 zEnQQGqeLoXB0n9#hLT~|7(j@;VeJ{V6W4P|sL71I!!s`hPXWw8hj?LuB8E#QbhU~7 zKx}V=J1xm#XC&MvPc0(%AZxz@(fZ#d`&L8vgfsbQt5f=tpe%8w+yIX{+ZqfiubNMLZ=)FcEV|3C-YOT8Q^X(z=)<4g5L3G8fx?l$lT0^>bRLu|}LN%p@f8Usl7UZp)cUJi#g zvFkx?g7TWeSn>zAqP$Waer-LTGl$TUrL=BlcKIJy@UBfvNo(m`-q*~2x=YhjU^z9H z5m=g2>9Qd{s6^g8iv4ci+C&A5syef8o9uI0wrt|aV?d-rcR7+R6cDuoAXvLAXCRT?cBz>C^pE>?b@n$>s#x5n4&dVewSWl_n-&E`yq#>7<`si z_S4<^`a-TKSD|aBv6+rY1qNAbeHL>?GCg4HjnvWX@~>+bV|B?xzHzO>m`@ML%Sg$@ z{kE}$L+-84di(%fzeloGUCS22Xt)B@^7M14l)O1$p|Vc!1+k`n7&q8(HSIfRTiE_S z({oEv3;{jk^7c70_gZ-C<2?eblcFS4V$1pQFo0 zeYzAH@Gw|Utdkd_xfvPLgy)$^@?O4v0>hBHM-YWmDZQ5I9*>`=-Cvr2jT%-M%zn^< zgjaPsGhFfVI3%FVP(1suDR=UH^q6&@-%x!KNDchG+Cg0XEnrH#Fg{j6_5mqK{oo3@87eFxo77)zBP^gvq)@8` z8>wg%w*iATUXmZGHv(w!ydwCW8-f@Z@{kVE*M4!xb4+nL_Bq4FgA1*zObm~73`14z z_YuPyyNhL8U@34<&-c2s%EZneXN52Bx98rjNl_oebggYstGPiqv585#V2~-UQwv-(xtmWY^v+!OK zyvDNdDr^`ke#s)nx`Nu&^$jk`^lAt}$<~g^^Qx{IFZ@*|Z~`IwPU>9D7RhEe-!d`L z@Sz>82aSwRah$7J@p#8cf*gYn-qZF>fX;MML~@;}+Y~-www#;5d~D`_&WK02fZ(jl zBtic9tN9$SL>UEvAjkbYWLlKrAoxA}tEXAaY!(^(8&Gx9f?=(U$LEqfX0Mw6WD8gxcQ~M z&1wFH_K>d|vS0W5vJ-_@2zavnlPk3LP@aRpe*26v69${g5|JUQbQU>BpW;NiwQILRGrZ4M^_P4A_i?G z0@GNwU{$F756)7dPd7_q6*i4x)RX5{St&QdAgJi6tgRrA<*PG%El{X}I=&S3&l9^w z0AUm5R?R?)w}5)Ld{8uke1$CdfPMk0>`{|eupNqQ`NcO`{h?dO0q>iRtDj1WDVJo? z)SQOHC)=;Iym(QWVYp6G!eI_Uh_FyQX68DZpUic2u8EAMY#7ZZ|2QT)^3V`x*l!@d zsSkY&G~@oBxMRbT3k5uqZCj>n++NDh6NS_UD+d@leyA<&jDNUx<=srA+Wmr^l&qf* z;qeYIsvu_)XXT=P^6)uAXBX^Z!V*wx^>5Y)+>KHa)%I{`Bg~QS;94zq?n%FDoDsl2 zFoqs%|4SgCX@9}6VCF-zJ6ehx&Mqe2{`c!!M~_eE%s|a$cmz<%lZv^=5{B@3b_dE$ z;3%-&4l5oximBpV+W#$~jF3=$G%F(_yZ@lfaVy-#ireSWwOD$1#&t)1TrN5edN+W} zVnNCgbFg8J!X=Y?*G0EF4~XJ7dZAZyl^dK>^F<&{p{;tKP<54GnL6=apO0<*v*D7_Re*^lhyaI>TBq@lVx-G zw~7fSxN6V=cj~E#?s@ueH+}U{bUBU*3?Wojj#0?nINoBM!EcRt5M0X6KwkLj2?{g_ z9SXB9dpnzc`ZQAnuns|1@8D1(KY0C4aHhZY`sLLEPvd_D(J^mny$@#sXWm`%q@;sF zKhtO45me3;srfLW1uBzT53duaNzg@9&`k>PJ;UcVsx|vT;;3BxN!K4%8ZBBV|-Fn~b_L;wHF#ENIG{*M}ZhMxy+F|YQ!LN{$-nch3N4|8dy?;)k9M_Nw79Xi@z}yGh_O&@ET4WEN zYRbB$SNk;oJggyY&!{85XV2e8v}QW$XnIoFO{R)+Q}JQ#)zgtgKlChxZ}RQT-u;!i zB-Tb6S)8<(@t1X5t@x~g_N)`v)ckjGi10-qfZj~+B=EM^tkDsF*&qBQjdJQkLNzC9cf?bLc0lDJ*1bvUu)S}V6~=$wv9Y7aNlAzkx123eCK z{sBnGWSf>pi>vqdu1fmH!L0|ZN;Y-{eeL|=o!ELMyfPU7?{7A}b+dcMq`g|yN3OIV z85S+c-3?CA3aOQ?IC9-PNpEkP3Tazrz#~M`*`Ku*2BKyU&hCzeyD6#WUs;BvBHG_n zPonR#_8D~gVlFdGMGpFyR%(fZLn#ar`5G&m2iSenDz~v>=6ndu8RJXjKgFYa_nLmp zhDFrZA8x4c>WS}dk-{SXwS!K8B2 zlKggY92&9zol3>y5+T^$VUl)nE}Pck)~)6onuYp&+jDWMmZ$Th?`gUs5Yt8@6fEaB zXjA^Ipn&puDi=}a-G%ddoo}Qn0*J;AW#?RD^2L#sJ?HE3xvbxO5vKf$WuAR;6AfWX zd2Op6t2`17LlBOpM@f|Lqnq13yG#>g`Vd!rtH;`~SsO`Mr)8=?V`5{Fprx5cS@;UK zx1-?fic=F+VUV=T&~Z^izCcto-IjF~o8DO)UmoICB|zB!u&MHw z-jR>RG06O4}cZ=%L~5@!uW9x z2;=SMAdI({D$G8hhf!(a+FU}BV10tPNvZc-ld91=xEZV0XY)NEMh&e}J>t@Q$fp#-3QlS&cue_O& zF;m6xYXlhF5=}XI5%xG)(dG_v;RV0F#c+-AX7;v5zj$~v2iy_MZkHY^GXS>&T4~_# zTH?ZAX}qHno~|zX4L@KTqnEn=w_{mpg1~~{`i~@n3aG}JaLwX$y{a{k%9cXy5{%>T zN}IMcpN}L^*qh2K!VW6XkyZD{FXR08)`k+ETE7pvqj@6T-hLG->VO{hXDaymljsGi2_lWjhYS)OcoX$T|F3IedL)RDnkRKe{w13`? z9=^>8zFrXajZ{yGK70NSwwKvS=;reAf_*7pDF(up&33`NPZY#+N=BjcrcNT>pl{pM ze0zM4!D%9$tAGetIwhY_*eD5L5waV9fQ8p!dKSeKEMIhK&YNr_Y3xMcNN4p{Xs);VZY^PBHCDD9ODs=6pg@A9utn34 z43srnyi#jYlFE(Y8hDHChYVx-Shuvd%2MNZyT4Odqu&}tAF(8%#nc{e%(jrY%k9Ii z7E8rpwyjB{hW5|}4Sc4iGXK(2FRQ5zQ??DPZq8#HJAF0p0_VQs&?YrmJxr8}ck@x* zxi0$Au^o-vhQFmcLK@3&-|SHHcdX_-0%#WgIv7PbP_h2aHS=-mX7!J$+W@An=Dq4q zx0s{`ffnBcQZEB9$KmKkB?9wnj(8^c-*@~y674(7Zy__2y?W60c7BqKL!bRa zlGPNix+2k8hkq-=XR|an1giLj5Riwd}a3;14rY+lE?2O0O zjso!O(xv`!A~*$6X^kJ9fGQulgG`1vVuZISqz9FxPKSurO^U5sCN?=_WXNQ(rJHIt z8)>Q(ga-{Tm}L0Wp_|Ig?GxH z-O@xtsduVUa?BIW_Hg-*FW|SdJXNYfXuzT%Q&y{D+%5Gr4`Mow-vF@nkr*#H5>KSj zzAlT{Y{TXE6#e$|Phj#&TuMcZ5p+MWKibrBWVvu#^Ry(_q`hXSE9d_uv~%D83&vO5 z@eB?^@BWwbh$LM2ZRp%2#NX`bh{Nu2lPhm17+Xy`_gpA@WcTj#-ns5IjIl*o5(ck^ z84{hp<=a}i^JuaK3C{r6=m!%j4$j0?$)Pk@x`(f#2OT9N)tcwE0a*?TNx2@%f7xn} zMrwBF+Gw}dMO(l=$r`yJDs_Nf?iImSR+ZSOdDYlf;WiY%xCu!~NvVCohdHHgwdt3J z1zDM&{h`#R%F*AGsQab}OLH2)?#da#NSB~%T|T|aNGJ)$MyCLWVs3w>tnqvd$T*(0+bEJn z-6?d6Ak;X-Un)x=&fM+3CtIgmp7Ewf*@evBxMm&WM?6eKBxAkzrs3n|+zj=8No05P z3`Ij#$g}#iAjZTZL)`=vib-Z+JjyS#MjL7!3Hh;#l~5|;TGfhgxTDZk`dt;7-RnCY zn8&_#LD#_8Gx#^6ok=1EQ@|k{}Nyl0P~Xz$FyB(I)9E^l$B&pL?YZjU9(t9CaTADKD|fG^`Or_rea%6uk~NX znn{>%A74WLUIuKUro>tWP?v|>RkX8Z%MXe^&p%M&l*yuZIp0uj>ls6Kj_j^ay8ig8R&yPfkG4c2q`<+-Y*^wUW27H+YEY6ccA@o_xS*82L!&6(R(6Xb! z4aJ;blH$`p2TE~t4Gbqw>dzd8GvG-{mNk*EgPPsCkMaD(jvjbd|i!B%0+(N?zXMFER&j2?%itFg#y z$?31NJ%w?r)H zhHY;sOLy8>Gk@p0$9^N#8Z|$DaE?C!+4`cfwT*1Q4!7HBnlxa(Xu-t!>wLh%;M?5f z#SCGQ0aE4C_RcsEgC^e2-AXlWt9{9cDTqZphRYRCkkFf;O&>CMTa;c#V4nQealrJ` z?_4XSHIB1In3sj^1iGS$H)m|L`A4a69+3mA&S0$B(Ew^@_5VsJ^|`_0lbl zc~*@M_!g6C+EY@Q+2sYqO?8eqC+QIGelX92yRq|R@aDQUD{P2`ba=Fo1k@K^PV&pzXO?- zSgklgqRtgf`TG+qUflD16kJBe?IH13s97Y|YnOeY#)3a`U!nE4L@!@TS3rmC%9x7M zXw;h5p6G)KqP*~pU&-W6u009gacbs2jK76x!5)4S6a9mHl}Xgi*KGK zFXsVfWp*S9jFw4Yx%yl0FAq~cI51A5An?fiVDYG=;4!&1wsz7?#L@m(StE?ot!}?V`5zxCrQhtc)QDkpFYt z%E<~L2h|Vc2$Ia_3EhltTh31rO9a6bkMVYQI+{sU5Q7sl2Iqxw8iof%K+k1uDEZWD zoWcnc%tp%oNQLv&u~NL=7(&Cah0RC)8KsU>dsszP!u@VoU!(-J?jJkP@A_EZ9IO5q zzdq8(ua-SH&TsYBdhz#yJGMhUXaBaDa>=v{%t;DBXOGmo*Yr3BWwfjQ=;Vr;jjRzw ze}GVi8bq|xxi3O*C`Hc;L@<-6Ha1T{E$0!nJyoSE4) zBv4pNRRX_ng{6A_`&Mx%#JPgT(+MX(Lf5}UUMco5gAj}cKJtVPa@PES2@L6E5&RmI z^#s-q!52s$bP-Wd7ot9m^Q!T+a6ce;Up*91{BEObhWo-#8yjygSsK&H5sFH>gL%wd zL5VKinj`iAQ#Fht80owR_UzQk3&!VPQ{@?jIxSZWv1(oE*%J`Kq{3=;XaF}gDXD~u zJMD*<^lLCe%XCK5m-S0MzN=;AR>Kg-T zJa&Pq&`4AK4<|0jnDN>Tn60uKEh#n+X_vdJdYh$W2pg4kUE{?nY1+o`_=rz9c8qi( z6pZkn*UvPPw5ET9RTqf{kU~TlbV6GN^sN|1YR!t+5tt&S2>3{5<;&+1(|dj+mGbHdZn?4wxt1c3m}JEDjp)07ea}4GU980 z->cLB^VyflSBT$v_+gDQWyXt^;OM)Qgr^db%JNeM7pS(p3a;@d`&wn@6?sd!J<+Ii z!~D4SEOaO9AH3o`(3Flu2f+ES+u14f1C^zFQ$}GHo_QSwCfrD=e)7dqc)F%7w;rYm zN6Z9DjGuqpc+3yT*WJR=JDYBq-@B7Dja%KCeGTCDD6Jz*o(++S9T5lxP|!fu&0CF= zA1VMjlEFE`J)*_mgxNHoEDPRAe{lp9rY|^NS-f@b1z8AU`Y@z%z-s&z!8?x7+hfcMg5?2X*U}?x*cFwWTNgRa+K_`PXiSzIg>^w z*SRfdxVvm6OV_nQqkV3xo<|F?VI2Z6sr(dI@32Y{k&cglpNu@s`YNuweWzIUtw(ArOoaD59s?oOh$O8gOG&0O2jGfapff@moj6d9R$qh? zF)4-H*Is%GVP!26MDNl3&5fbaHC*EjE* zgu7{50D+XjrS30YRd~mv7_L7bb{VZHvv)EBr-;B8Nk;KtYt(6d(KA<|L zVV(L8cvuH^KGPk<2q}oIv@44}dBy{8L(12KFBWO5eeT>CSLYM#F4HLMt7NGcox+nF zW3+>v&Yi-t{bRJEncB^1fKe6$e{k#kR>Z8-i0HQJTD_P#AzdrP1v({clCi;R86Jw=>{5>XO52P7angtY_sFZaNHTBfek2J{vuO^e$5&3 zlg>m$(OFD5Bfc?H_esf%!bx_`^b7TvwhQc+GB0!+3RWu7{ctBc#Osu$a>ZXQ8q%o$ zvZ_ywlTl37OuYgz&ehJ=2L+Y-NL+`J@~0<<=pxzg`tj+~Q+-mZZE+V|6OCX;i~csp zR8{3U65u4h^4GR70>%gwHl=uYREp<>xoWv2iQ`yOx-}04-1V+5ST#t^J5i5K2gi>> ze>X=-mRvgmT53vFi#)l5gODhbz9WBzb9%Xvt!_vj#C45xz-Bs5QWMFl7xBEoNK&t` zuaEkO2Rv;MWP*RuW{owR;)%vH0uwF#^X1p+El9LwN@Is+>Vo`n#{ z#Gd6Y5R7=}C9K0_X>cN%Z%FE-zaq#HB8Avc>e$?5iRyY(){SN*n9J**jvp`z zB2!|XVEYYT3EbRygJu`rtC`(f-W~Mgm-qIxsPKpvRTLFFZLe^fI{N9uZ3O+R$An+s z#F|}Oe6F{kSo#c`SSR>;z-dvCEF?><{6Lu0^!U^9Jv+i41mx>2%wyc^Dd@S3 z&zKwfczB6LM_&HDFw5PT(z~BEoNhCpVU|NkcGPqdh!MdyhTLX!It8+bB9-9CYf)ar znG^t&xC536NFwon5^X>d<3JMIM-S`N4C}}t&yHPfEgF#pC35z|qS)-hWxhRI-XoP~B zcoNZWn;-Z;ggDbIgQ8)tr+VI*H;`EpPUejz@X23#v$dlrf9_)slgiUWJ9T#vZ-JIb zHvh@tRkXT3(bi+iJ?~y=3L#gk#v;4x#JjLndcG1R!X1;P>q` z5m?!41DW+aA5z2DS4;`Z0+9rtlB6!5)XeYZ@e-ZBE@%4OdqOVkx^DkQ|JGJ-<}yuc zeXjmmUU0iF2(gkrcckG4<;8=UOJvYio0B#A5{)E-)5dOtmNu?EAUF8{ zEp2eI*&-4p>ngcxyZaM?fWky8C%w4lP0b^hw5Xzvyred3X_0R&OvAz!%qTh?QM|pL zWLXHR3a_YwwvmnpeBE(**h!){H%^4T=qTK5M1EGzkbVvhAwwj*S4Ek|X( zv!cSkPHg;0tb@O4UO=ArYJ?A?}sdgU?WF?kJ>nkjrNo^x@M5FBs4TG#>i|JGPy z!oia04Mog&1svj9kFUX+Ucb@SRaX9Q&-5_`feFF!AD109pd;h7--_D(rhYA{TFvN= zmiKeau(=^~%5v{lF%4S>Y>e32x`k+Hg8A?#{}z&>w`8+qh_bD!HzVBMoM2&(o!_kb z;hfK4VQ#Ivdv{Nl=To9m{H*MWs5pqC1$S5#PqR8*M$Wk-jDJX&nJe>4pNDtiR8m;3 zxl{7$GsDIupqA<7Ewy*fuWj4halMCclkb}S_HOQe-Rh?@7VU7fS83-JeDCqnum$|8{^sGy zqG7{A+unMkiiV^pH1c{Z(LYVtiaNCwH%)SWNi3GSbn(`wGw{!?t(`c>O}$jN<9rV{ zrpQzWggd+Y9QALvL=P{(&f7SC zetJiaKVUU**<~>?nY6jW9j1*%xMV*iq^zQioEQtRST0^iH}B zXwHa_S+Pq8uL;hXBfve_kWGsZ>}?ToM8;*ci9WGK8iaG(VWvT?1%SA}muI>sYvt26 zS8y9=mMep6NmcVXW%Yth$FQrH6?_Q~Ns?tt+q($r`t_*Sl%*Lni<6DcFvf>#eaF5H%;sPa(rTiCsjdC`P2UTLAFHmsGynP;7 zBLJ0j%9@Xw*QH8#<_tBm#e*~fsxviOoyvlX2{A(4FX03(z$t>a#O3zDb(J7_^DeoU zAz@^WcfoCg#XZ5oMHiIJV!aoHy45I{!%gIar|j56>Hozmi=7mhYBP5G@$F^2lR|X{ z=GQ5a>;n)L(7QVQF9ZvO#n8p%#TC(6#syh*t>&d6?LW_hz1OH-1YZJxTiS7ZVOzJ; z>l6PDviUn68LM7YJYUy2)|tQ zp?UUpRL?^HvHjC&I`s`_CnShUxVj&bwkXU}t^mVuedUxijUBTDJ-8Lqfk6nvdZD*5 zkvS((K0)~k9DGd~Nw67UMx2gLB<`TK0&6&{F^=cc5JoX+!Q}qYfGKKINN|swi;7Xt z9HB8&D)jV<98;&=kyo`~5U5^tdR1+g$`G8=&lLSb(~zDFaum?T86}HGt>K+g1aeh*EzHsoueW{nC<0 zw{9a$4FI6(&nO|W2;$*`okT3PNvhQYl$(BJ(rbT_;;toRsr&u;&JKKTlPJ zysF7m)pN#iSVJ#YoaQ&MS1E~C!^~KeQDLD3t-OR6BbCIE>(~tCM{Yw|1PLe>Y8&D- zC8d_3`IbDk5r~;QnibJ+#yOwLbK`Zp1=kl4#j-S=B;qv#i9eo_n9*>x_-%nZ&nVJH zY;wa?7Oz`ay78x@ScB8|S3GzjzE+dupk?L8F#dU~+6p!yRjO8fpP}?4{7>oSx^2Ac z*ZA3xhtYL#KHgBcN@P)V%qcX?Xgx?w`Z_h|%!otNU@mu>b%sfYg+ttQzIrnTbQD^5 z)>b{{UEg%{oB2}&hBU?!AsT>tya#o1kuDo6GfZ6kpC%ieDUCATVR%vqu7HxSbHU!C zXz~1Hcq8STWexE#&Q`rgCX86~v@pZh0^*g!{Jw_74b&MpJvDsir-&e!sc>A?J{T6Z zZ*Xs(>*~L|#e_xXFdrsb`B1CDNhCyBBMG`+m{P^@uxcu0AXwz~Vkv+LMd3#WDHdjO zL*-RFeIN<9wAed5lHvx=5Y}O?wP|E`-$uhLD}=Ie2_50oI~x~$)I#?n?0}p;tJ5&R z_EmREF;OZo|IkBAV$1^BK6`R))WQJ=uOmJ>X9Y>dO>;dd$BUH}WE_S4vV&>BAl* zQ>vh~5=;UrI%1-gLD3GBpb*S}Q`~3}QOSX}L47Sf@F&m>?b=lg3Ctd(uscX$@NJO7 zl=blG%*9)u;Nfy`Lk77SP_Cd0{y!lkJ!V;l(Y)m54HRl&$~t1$dO@KUaaQd(AQOv2 zwvvUYdY8c6D?#B=AO~>)aA4C8#S}3dV(pi9`K7JDOmXwk$Wx58aqVNAsHfDpH!j)>bp_o->5$YU!rbflV(t^zS#a?F5rKDXX58AiZsR!ITSV# z1y&n=5cIsm&&W%N+x+GXa+3XSF534q7(gnLt^C3H41f=3wd$qbtU*vhF>$c{_e=p5 zFr*>lw88$h`$+v5ZfccP>biK_Xhc5o#M(&V+rmAVOx$1!iE2PpHL&9YUZBf0Rh$^v z)S&?u>Eqqu%)2qUx3-~v^LuBaLmiugJDc1ziNb@uLwlxzH{!ua%}i5;{&sE4>aj!m z{+%~`BDmd`wZq4F>piyP37bQTNhZMph(DsXi!wj5L@ibw_wvnDFFzfAY11RKvecsB zALh1Jm+i1KkB?XyzvLe2*TM*`K9IRJ@sv_NrJAB`jbf-bni--FjNpt|n5?YnFf;Yy z@6^8Qa)*cK*Z57~yFR_3OsLc4{E9@&`oPzz^I(PyAm7m_p>9L{Sjx!p%rQ{{QZT)T zkoejx9b`BZXdl2zlhSn{MYr1Xzom+7HN}wAo~7{VL2zs&uk7iYOC_cw0*!dwW~p0t z`W%mIFWZE3@4P=`9z-~xkXYh&>ow^7KYq<{wAlAR4$-NH1VBRN!Vhj-)c}SFS#$W; z5VVgC+Z#P2?Jd6e>#3#{-?RZh{z%lxNEe2`hj4f)-;QJCtpo;30TNN#GT-WzKH1Q9 zA^zdrZAb>?*iFRWguDT6wLbW|!~YxHtt|)TL#eb0Ekd(!)+Az_mw8ZiB`jXH%t(|Q#j<}q)*SqmdbDUwZi2@OKewm z)vQG+P0&MJ4)@o_sL#8ZtpC5~W!&P*I2|B0uel!~OOcA^-*i++_=Qq1tlad>d#Drfz z#nmbK-7nHUT>x>dwk`<8ppd|+roPW-mgw1rS)`;KHc%T7TIQey)Za=m0FcNFUpuP% zn7iETi?*9Ao*>>s4B{ZfHzXVg_|6fbzkg_4y)PVZpM8`4LH@jo12sUlyZQ z&3bb#8@2n}CI?Y}Qk{$r<#J5tUg(L6IY zp%HL-jl9?53j;mw2T?8oF0TMb8%_NOZu;*hI*z29`PTA3Z0SF);_%+r#(rT{-2Hqs z@S*C@!YwS>;M(k2ExgE_&3S`&cUJ&Wo3>Zn+|3ULGiN2!7 zPfKyu$|H%*(5$#Lfs<3koX-&PM=gQqkigBBZvu6j zC&SuNFK|ODbdi$LsI|Aj=@jxiRpzfY6&N02q{e5I=+kww@iO$&4s#v49 zXui9P#T4>w+7Qb9YqzElO)|8cGtPl%bd{V4AzH~VN3?vni2gkP$**d#sJzz2Xj{4* z&nHu#x0Joe4CGgD^|9SXrBd$qhuHE?=|wxRfxwuX1|EmE?c#F#{a9IPS@nZaLiqX& zon(AZJm+Cv3c(^LMrit02ZGw$bvPViccy@-|C;8riK+Wn($SfAUOVI+-}2YV(8cNl z`3?MY2GhN(!4Q>_%^M|Nn>RoD(ah++PxLyhCzLqHm+PN@$`r-QScM!_Fv&)~L*4xF zS1@E;C24QcnbFwcQb%t{{7(3zEz~n^CItPZ?XrU~birZsWI$|~n;ims%cLmV*DzC! z8waSX+n^5jNprZ{rVIY-DDcYterA<2ET&?1fGEu)-KbF-Nh!VJR{IZp%b*m`n0e?aBTGUK;_wK*fm$OWBeQGXr)WrVdwX-QY z_9$AO$VRhzw%;pfYbgG+cfo(+k-B9f2G~71C{IU1I$benk6TxULSimDx684Pwx~ezej+DWYUY)D z25R0v+s1u2`QM`iu!VLr?HA-+SARs(^OE)UwC#?h1dBYHb^E>9ob~1sGa}~&!ZG(k zf4D*Y?gk7K7~%wrBrQr@j;R73s9+Ne>*TjFo>q~#83i#bmZ8l^4!=~()^VA5t$Yp7 zFJ>v|cJ8Ob3T8r-g#0*R(!Fe{e1AKy3w){WP~&M(M4BL)G*)FvtDFDMrYQ++QJh2X zJZYnIliJr9^oREuf{TV%0-FXg&?ayNPD41g;{wpOi7UE%tn1pS(H+ok{d3w^0ev>& zv`3r{_ffY)Y&H-mVIuVS$1cl2aL5UUTpWsvxkNI|(VZqs)&id(OEdw_1F9ptl9SqB zI{K+C(8Tv|amQccS)QF%GPsHsdC@Yc03%dld$}<5m`eECl=4d6zf!4TS-Z7=qed`) zcMkwc0yE38Gr2q8lcBG{kKP>9?Ksx#vU^q!p~sn|6i4QzEz=g2!tHZ0o_zNZq2>KA zZR6dkPiF}JY^9{gI_gY?ik#-jkeGdMGL$Z-kn6C0{ifwO_!Yi&=8L*l3;kui+AX+X z42q&A9|3Z>aWE`v658vzjN_J*(NDqwY6(Ap8-2LXJR43dxGs_@=2u>`YOQSs4_r9@ zZN6P*UWi!<6Vzfx2pMIQNT5|z@KR)71Omr)Zr9Ck@Lv!$tl*41V>1&Unb|-Zq!ZWz zkGTo>pDW#;=3i_r|9f4;Bc$zDlx@^l*&$0-MihF<=FJjM7tK0oj|-?|R(=q`cL2MS z(t#bYx;@=5w+~Ya91tlfGlP>_SP|*qN`K9o*LR3j0@CaCl+8m;n%iEqn?4%jml%T) z*`wJ@jtL61M#6p>TJr(V@iWWUaH}&((dJiWyF~arDjjP(;6DT5=tD?36(av6;2y6Q ziQk0<(_FSOV-gVKS;2O?EM2{`BLkAX|3aCIwgPEkmV5o)gK2JW`Sk|}r_Ov4|Q|wJJ2-&}1$eluYEPi_$>sAFs*d6!rVs=lm zE5-KGt1F)nx?}U4ZJd;uFsB=XlViPE-DN1q?hXkiMp9V$=vkBoiyD8nGEtVjzA-h` z7#|oih7jG(l36%6E+JsFlhVWe76jvh>^Pc{V1Po4$T@ZLhZ_D4w0amMjm14w0gG-hatwG-$63R_jFU?{;t_j3@q4*ri%HFfshw zlWY_}p4eV2pbfIy!g+LN$j#v5CMasMo5upW>+D<7$t)wT92!Pe9$uc@NR4rmB}l3D zMY3aVp>%cw@*&p4s%R@P$Qa!bW&=2h(6SAAYf@8VY%l$1F9bu ze*xLl@~FUASmuf}zq>+6PuWM)8bp>Y5*KyKLj$ao+ItQDwD%gm%=;GcinEJty{bGv zA>fCoHU3X2DJ+eB!6pF&iN#A0B-TM46uHQN(xr~r3$etpL4avgLNe&BKhuB#fh7=J zE}$f)V3-hTSP*?sbCX%mH}-*P`c-g`?g?H_mV!NIG$VCKUiKft%?g(4kdEG_F!ef6 z@qY3!YaydK6s7iawH{sN<3gkQOp=G4U|_+uN^CZ{kiJe4uYev}hD0UTfEI&c^|nT4 zgzE3I3`R=W{mFf@cZ+s#XfNfiKbSfqlLO6{cWAefkk(jUl*khShmLNZkJ{tT}gTG&714MEC}xN>8eXdwtp7Ffy}fjlUh z*Ojm`9`vW#Q3@e--id;5j;v{5ePlY7zv&#e@@30K+YqE`ND^pa!yRO5wCwON6uQZp zQx$4B;niNqpHfaOM^ZQcGObMXnJz!|H6KxNPX#6*1h1|ItDl5Y=R?FCGjtoGt^DMPI%1Z_`fxmtO%n5H+o+!@ zwQ=P7{n#tO5jkB6C;UJyjCoSCum>e&Vbp~JuhfL2nEwti=T_~08Dpy}_Ykqdi)D-6n7}FXz7c&>%4mu_3a7idXy%HsJbW0rcJvCh^aV2Q@NR4l$ z7QJu!YaoGm@bG(Q@TvF`B-~KDx_Of!b)@VxZAxxT*2`e17C@eDiWik1$_xT^3@x=G zJYDW!Mt0umjGxv@JR(lat|d$(+-shW6hm6fg@pQTA?-_KYr_1eS(=hZo}UcmMx)K{(1(*vL8}$}V)5C3L%tnvP;6G^Aj{M{$ zoCVFp^j_tWPHQXFpH29yN-P(o^4Urku=0Itd+be$(wY`*`ar&>vJ1i`&3{uBCTObq z8GMQTro5L#YF4lc|L@b2g)S+o(g7``2?WzsP-j9w01h;i3!pH@QI{ni5FQW)%JC4b z$z82WL$w^t@k zXQ#9e&f2+?*f2fltF02MB|kd*yfqc)`j$~HZ;{A@W!!>PWu;a2E=Tj5s21p!7PyyK zimQ)E-2c7rPI+pQr8bzuS8HMbYHO`(6I;lo4Ev*$BMC}4CMTDu)=J6DV_T}ChNN21 zLGv_&rt?feie|sXGs$#25K2t?DaYpNTV=Xbr^n-udXP2=Qr?36(~~KlS9nwGxcU~` z!;LPczIW(u@0r}#^-MXbTNka12(mEY33rkSUigMD)Z)-3D?l}A@ewcr7udqhmTMCn z9!^)ckA1gprkfT22bw@-zf!uTlu%2UAb+@BMWy%7;vTW~!JaIS8lwrcu$aERF1ZEUGm)LC~EqS{F zcm~S_lq0jPJrd@c5QD8f_DRyaZGVb<)G`b{+vS;io{~;t1IG#JUWwtO#zYZbD;F&$ey58BEDuw~pxA0|UTF|6HFmc}ag9zgakZ{xYgUcr;J z#6)~J%pEh}(Iz|i1Z<70kN_aD&pUG(0(nZa@|6NSkUp2;XTqbwvnDB3_#|6Cos$)a2ennktEq%n#yFK6+FxOB+^O zIq?8S0^3AOlR~P{su|myF(tyo$^-HvPmX;%Y%YJw+Je6M^Wr;d3*3X~61)GvJzg9fiCWYbPeHdV~WpV6%A{8|{ zfiv`f1>^XWlYvnam+bEX6$3XiIFsSfDSuq+kKDEq|L(tH`%Ty6Xz?YAZc`vHr!CSn zO^gObk`KCFomc3d_9E@sHH!Z4of%Tk)$U2M*02G8p(u(RayXpfj}J|_dbtW$-#iKZ z^NSZxo<8T%igRYQ7ONMxt5~y8+Lcj?#a6FgY*s%9ud~DU>RM_Y9JVP&RItm+gMW+d zZ{4S4w{rA_`o9gJV98d{C?6sQLwZ=K~eX22eFuMcJ2mcuqHiHYlqi%xf? z2WSnlym^MXo`lQ_jl+hX-#q#H#gpHjaOmZ5#aGs{h_52e8CPbtzI%enf`8fA`k}Qd z($(#gf7Ao7Ppw5NVzD?TWlm9Ql{75mwq5k+U&GY~zQJH%(#EUTl=BXAJ6gNdk3g!! zhvG9RoMwlIf@vt&V@QRDMKT`QJ9RpdEM9urKX?TO0+!iGM5w7)sx z!&uZp69*e7PET_6Gl<;=&wt=k7vRidd9MU^P11XIf6t~9|PMyrdoj9amYy7Wm+P?x6YTy>dDVSj|WbQzkdE~k6V z2|ySoWVDC?`lKcZpeZ_60Fx<<5I~oqxdM<#mN{jsUuwG*_3W0g5lB9S4)u2HDVe3G z9W^^m^zj^|=W*~2nXS~DuqBDd2F(YM-T81~;?Cf1y&+zZcpM6{x6+%roZ<%xok3i; zQp!d7a+QLhZK3XfoqkUF?V*rU(E9|CgvweksTbL@)zQhD#V#4qcZkJs+L}W_^87$#3%z@$wh3@O3 z>#Ue-0!Xs8SyNfn+tw;(NAb-Ev|5R2wPKfEt;pbpM1Q}ha6{pnsp}LS8K$CTCWt<% z3HGTeI@dl;rZB=jbs3rs!I*-Wo8T#W7KUlVS*VP&O}FRZl8LxO-=|@TIEf;R7Ux$n z=IvKXxO2+RA;geIupx71aLE!AN`rWQyx}{r)DRUA8e~Be^N}539%%fID4pv9t6N=g ze)CvU7k{YfT_CxK$2o-qQ2WFRiv;)yC4X|hi%-Hx;Rza8RQ`7~pwyb_P%mOH`lKe< zi>ByYdoh{92z$|G=z>c&5wpl(H&_;0k7JtkyiZkwE_cDovY-G zRco1q5kpx?rk5GXJxUV>a$R!nIG##i#4zq~bAO>_k>pU8|9d0hXasuO|aOET<6C#?iavG?Hz_}ot5qofc z7=N*C8{zRzACv&d|BNVv6rNkNC^=9b@XonyaY>k~HfuSB8HKm44T7EDCg^Xvi*VGD zlEC#D4@279wjN1-=aO!!115Z_5h%XY5ENh5t&-ojGiUClK9$0k@sx0Eg?`e1Bgq-hRKLGTS5fct)X#6!`MbNt_+PUmtt@_u77i8 zo%{o5|7SOVLK;{^tF@bp@#Ae+n9P@ zzEzWT@(=8sJ+fOL4#5>j^k4^KqxZIy;VcHNSVAZJq$cQOQ*^FQPNpzIC%X(?2%>1q z;$>EbN2DeQpeZ_60Fx<<5I~oq_kRkfMDW!7BTgA0F7bA(p<^!y3kr7>jy;S=s~ifj z%A>R60ai(~hnrOrim&~t;lhY$7>2cX?)cJI9@?|zMR)FEzjK!_JtiK%gYb4$00`id z5velFhRe);eNq#QZ&P%x@tsUzgz@b%bYVowC0Kh7rq%y-`cG1&w6m_M?teZDx-cmM z`S?B?E}HIJ=LF@@4&OOwsSTB{j9EruPT>)96QOiKQk@5qvb96z_rCD)Q@zuLkHS56 z?y+%?6PsZzB7g5Be$gT6iM(+SeuN<1cG-!2vk}T9H4KeqkW8P{1Z8T9&Q+$#6hzBE%(z^{bRCfzFR)h8nF5P4k8} zunFD4J6sKU;Q8uJp4?^Y@+b1%!-Hqf9_}~EAw}avc8LgeyN4^qOcX)a5s7uO+hNm1 zj82HqeULCwu+MjIFb2jldxZ{`QukIfg_)=qFqL{Cu6zt(N`F$My*z2YaS?PsgkRFc zb-4F0o{w|gsvYX zOz|TDV%r3pUkg~!wPJW#uOEtZ<5JKIlq==4+;7QQR0-Wbe(@PC)wr>E;fwx<^raQ!JpT0MHyyr1#!8T&W72ogyq?-K_O0`aKP?s+8w%FhKa$BFTtv;0C zMv1R)OZ}z@IO3zSLW6_T_g~#SK!Dri-itmbb%U}mhV3d36@wL4We&f7mF9>(SmipwCWp1;T`Cy7apfz9~78NKo=mtmLP6iM;M zWugJx9;$vub1g&_Z3b=Z%#F4!bBw+WrNl{(J6US5jbu47pO-4c4nCzwUt%8@?#&N@ z!j-F}3LnUop|+LtMBCFsNND>4gjeSa@PEXFFd%&qGOlawXu}ie+|9FRWqRn0h;u+i zgaDW$T@g#XO?K`WP368YI`*N6*4@cI9qpHpBWzt}SNe$5c!b|7Iuqefr|>w!?=kf5 z{;TIug-{pV@eG4M6WNr)!pFyN0a_7!y6jG-0G+S?ngjKtu%Pg33SZTJcx?B6^MAM1 zVUKsOQ(cU1XH7l1MSp^^{^z-6{e5Zt!D3-qyS>?6Yqz$fc)9csA_xB`P;=L8;oFwR z|8e5}KG`1mh-v$dDW~q!TFoN6$mUd^(s)DIl$>b?Clh$w40gGBcUBM>5|=#psjoj4 zt*aMzOaCc%!3)n3*+xUQ(cQajUw==H$ut`OPjcBxZ*o@gVrd5?jme?4Eg2hUcs_vt z=xj{pB=&CK`agctW`L!?>@2}#-@VoE-|JS29Qgfvgek(?&dZz_^(l=vMNP?>rf4#O z$4ya}n+rQUjH4A^0{4eSXW$9KkU@Onz5gA-ljirYGx%iis7VO#DkSs1Mk*V>qiO5E z%yhs%8XW>f^?zQ&d&s!f7AsgwFmC)_i;O!ZV6^@p7XbetlYvnamxlcU6$3CeFq7fX zD1WtBZEvJD5dNND!KaFqx-16scKy_Aa;H?M_Iiy}RoAK_i#O0?VGC^1`}dtUv#{B; zdr|rY?6E!e%slgq!FTQ)-+6oC+qahm5w_|5_TsM#1#;g}PL_GGauTh)(9fLp_5#I$ zm!+Abl$S-3(-~)T@zXh~VlNFIt4f~IG=Eu{c)rS}OF#bZI|Yn=5Br2!>O9cQEzV|L zwevHmn%SY%Gc-JHj`9O9f`vy0X+QDeFg?>dX9pn2yf6x1Bml>%z90aHrOyq(7i%~p z0CR($8-Nhiddlf=&~`q&y?A|dv3e85PUdBC5IZ*;*f{ipEOwF*;-H^3AzJLM_OP@;tU##H_3YZ)8On(X>l^8~9jHw?TrM^ypa$s>9aq2%%JX?xwH%2>k zi&=yL4ods3C&J^ca5z!~&Wxa#5kyn>irV)Rc|-Dn+VALD(X*edI?S}Ix<{vpQ};JN z@`<><`j=zH`i%UsB=vY39pg4?u~dHKelthCyurz#qqG<5I6yBiRqE+bIe$y-Lmb7; zD)LZ?@_qNawpoPA9rE=+X|#HyVhJ{__nl=Bcq*2a*PF#MOaoxF0OO>P&anT0{k*~F zz>=ZGw{mY6%YdASou(bC-~3RULY9@Lk?FYffwfN7K?g)dWqO%b<^zw@T+$|_!?G3DH;l=04oCx$2YhEw$Qo& zFxcYsdp=566-GwEF(o({%qEvcYU)xIL;k}p$LBq-?oBhitNOt-2G(`2Ufr6zs)4}Z zF%VW1^AoXAsq%twRJ1iiDgNSPfQ|GP8wgL%GSsOT=yYzlVH<1!gMTD;Yd%uPy>*@U zJ(}b#mRhCm4MYxIl*SMflvh1ZoS!0rpjLIwLlOiQuk*SlZ^8h>0Hs4|STw@}3MLV@ zx@Pb=5zR@^5k5go9tlAZi2kuPHzydk$!E$4l&z%vSu%4t80@!!c?wbOG18iguPocL~ zPMyS<4*irf)=x)Frz56mv^))FKk_sX`jcR8%)>cQjx#UO;Yldt?i4sbwdQo(JD`?G z97Q8)$>1OXri+g(CMY9}!^pxIF)@^tpk%%~2pGaRX@oF}Eq{b@K$t9`SmUd~IFDFM zCC(_Y+fbN1_C^>W1OpXmA>9xPWsnJ7$H@3e=DzP*#8}Pdouca43*b_6plUsVFLrMC zRb6nCQVkn*b=&3LXY52^DyFj?KNau;g0rR6fMm z*BD+@2V~_#(&qJYsF3?L+#`1fH_|YN7hCHVB8qXsX;lODV~hC=hiX{%P*%0!x#T}= z47kSAbNbWzUUuI%P1W3arzlGBhm4AaP5V|aG=EG}aHHMud*pHI;kFgijc8yD z&U6%}AG-Z|XuG+pCxQzOhuSbk>GE@vZ>x3x3oM6_6sH2av}+#c7*jeIhE%eJYDO~g ztq_0CnbqzGo-KtSvECCY#Sq14$fRH-h++&vhcQ4f<8)hkl4KxO8Jjx{{ zJ-!mijekcrh}?e2nE;0MPfg3LPCW=+ zCzGv>k!zLqJ63k6&JovkoNbR+VEG9_i_AI!HYlKja1XkVNl&=!g8_beUy@UL2zhwP z@&h?c%V*xpvI!p}^&KE73os=2UN*H zeuuS5ZZR;r?-|-Ka!LO9`!mcq$rQgX;2MiGu47w}ur=ZgJItm!W|W}>d5&l#j-|k1 ztAF6bitWj0JFcu6J6n{F2*A<2TjPSV;>yc2Dp@)%*|c?GYt)=zj*MCrEgfR8EV}{^ zugYOtuTB;b4IiUQS$d)x?jJl80@?n#C&&%llgkaVb<6K|$KNB3h@U8O8V;F`MXqWJ z^S6h`I(4cT_)lp&mn#cvmtv|OUBM&x#(!2vl)1^rZ;7_621zi!2;Oq%w&SGfO?Ot_ zq>?wU_jmodH-=z(V+ali!o2VK^9fG^8s*+pNJhgAm>Z?(D+s7Lq&-gS46|6<$uw~N zR>(+bW#o~n@ApOsiU^%R_lZBV>?WOgb^3lXxyg%R#AA;)3=h5uR)3dy zQuw$v#xF~{sGP^3&E3tQ4;|+mw*ce6caHv zHaQ9}Ol59obZ9alF)%VYGnaAd1{4J`F*7$cli}Sbe~q*SP+aR0Eer`B9D>WB!C`QT z-~{*J&H#hV05iBd1Pku&E(s*Ky95a?A-Dx6I6QLfo_qhl>b;t(J$tpR{#Jk8n}J3} zon6cvY6_BuLg4H`4lZGUgrcG>kQ>0o#lykH#f`zhpaF*4g8sH+FuVgf!oX07@V_D? z96=`Ve@C073H&io5efmwIoSe$JOCiSFi=34iwnTb#U=E2AkKi2vC6~JW13;+rV39$W<4iK{gIfBhhAOJ-ZxE09mv7(uYEkGS= z1_r_1{)>X?r4<}*FU-m5;^M+#Vh7`ZI$FMFe`W)?fZ&L5_gO>Hu|F1%R?W2=ZsJ!k+-8e;nNeAT6c}FnLt?mp+)8BiJ4eyq6G&F_ub4*@#(!*< zAUJ@JOHhDEkRJeY0DxT0tT=xc&~UQ{fBoSE{x&~q@ba*S+5;>eWq`cE7NEyJ3=f!z zGY9~8bOL#K{M+&02m=TNn1jvW08@}97=rO1_D3_w;!pf||Bhf+fF9T5_yGZ2zkmO{ z89YvyITT{+_Mh-Su9#CzTvu6IlJzgi|2W0Pp{@WAb{-&rotuvf0OaE42M9dAe|Y^j z&p#dbTm2ta6%+7Zr{nq$qb$S%`pEOAipTc-t;G4S(O~*(Zsd+5N9qe->`?xFli_%f~@y2l8@o@&0KC!=%BkAafNk+|26F zVfy^_Ii1+{=z{lk^2f6++^8ii`2o(O90(jKye+96BI%533 zXaOz&r}S^rpGXM6sr(NTeDtaOgMR*r# zzzO~re5A7b4}2U$PRPIDBNg;tkQ=~h{}1GTWU~Jk74Wf;Zq12;>Sf!{^Z8{i=A3} z+mhP!!}P;1#BXsP7ZkM9IA0KQv=YUsgo_+|5L76`aof?~m|OO!e>32CzNqb*jdNin zES46K3u;zsZLcm)S0JJgdbhu-25&I!*Vy1YBYBavY8M@_7NH-Oq?Af4|FZQ8Bi5w~ zccpKze-W>nvLoD2&e?zCh&~vOCneHPA<2tc^=>g2`!=h{c`p^;!&HVqf=FF4henMA zqhBI7zTuEW|CSC_f7?1e%qk9Jj|8VBH+8GP3hJA5#lzPbAefZ(jW)#cy@&bBC22L^ z)`ppo!3pAvIpmeWb=zm{V@*uybe>k_#V0=ALt^UT*2$G-y6hZU*`R5HoNjy;7c;JB z7Y#DNq?fLlJ^3fetwF+?;EB075&HJe)m`M<>ln=~9}iV$e@zbDzv+Mcs0R38f^Tcn zmxN)dxgqNCUU;-jpa~`vj~bs4PrP~%?a66a|0XWl3OzIZ8QM6EH1u+F_e8+K8IFr7 z?zZ)PeM_ruePRsDVrBjLv!Gh{F?f=9>sZ%Fl-}NDieMwY#<^H1uSM0SA3;NA{>TLB zAW7EAf_%8%e=GVBUMX~i#zMy3n<>kbsg1xuMgjikjIU4b>#il4QqjF)1u1pRxBJ<0 zv~Cl`VY#1a=bOjhK<0$1rQdxIY@oS%KBisou}NcS=~>}?whZ*}Z+7L0#jEO$Gm^BY zZbT9;m(K@BWw;6elRX&*|+`e8}Y-aW?8ASAiZq_xwj0&bv5-T9K8tb$fo2RQRKB`4lP<@Ood|@+N7uJfGOf03brFh-cBd3fI zowDm3wtb|sH7`k?5YQuwPg#&Oc7&+8G$;7$e;GbC>&JF?qezB9E>5e#4T{d2MQgPo zLfUZL1du1NPEDC#lj$Amlv?ua+X?QI-8@Oks)u>&JmzquDZ-onO6x*4vP?h0^^MM* z-W!uVCQ+}vTD#<@fTGdKR^IXLLbQ`nL>AL1B=b>AxC}{F$IaH~=>G3*WYD>iKE(V+cC{z>k9hJ0N zWlR!Ru}C*%w^8WF@|nUr`)D(Q@r$dO@5%0q=R;Gf^^r_mGVgHKn8_;kgS4rQ6}>QoonUb^b}*s<%#3G8MQ!Zm1jv!@*wDddY~5{nYUbG zodV*iOdIyh?(4hl!L(XQ%z3dp>&)xH9W*Me>td)CiJ$9kADqyJjSz0XePmHwD>v8uOyZ>oHl4mt$c4) z^wzmXwCt1N6y>PC8*1Y&53KyAe_sweDSE1peMSZ{NA$|s2N>!NURjM5wS1MQsV;0Y zFAncaR{yRw`tjD`K`gj-lqV#PfLQV;+7P&C!s=G?7xs~g-!Y#(La?yN@<3SYn4aQ` zU?*aD=8fXLYNQXvt$;Z7_0(=eOH19+y^4ohEjfqGmpURDBVt0055uKef2Xdlbe_JG z_&wIGv#&u;K#aUEX?xMUW?wY(tJ6-c6nj~qeP;_9YU!Q(N_wKgIow-PBxF9zw4MUn zfyh{`2L?S>C)$oYsvi_yi$4@Ih~G%^TV^b3+cc%_SQW4|YJinPt!JkeW3sz5lt3c2 ztEKqF$vy~1qqV`Mam&mff6@*JH!r*m@SE$e-sT2wD<7@TO7rfPF*KYMqFjDQLWYPc zB@~uj=+_skcUkqdnwczYye-@9SQD`HzdP(RD<*UsIR+NxFojKt53q z)!f9Ko9PG|y^4{2!Lqb$8N2^$DM`0Mzag-B7``(=A>B*UGq{$Bf<#QZFvl+^SnMNO zd9hn0TRbn(MkjheuNLp&*u1cHiAt=iZbmc*#n;#?@zu}O?RIVG5-_zMM6d6w_c;w5P&B@0%)1pL$_$ehQ(zZW1&+HO02^FyT7SQV2e;B$(3*(-@JX_hbmPve2 zkXNX^az0zo@roS&=vyIuBSktgt)nxAe%k$x%@aI&zdq^Tr!f!A_9ZjXG;=Pee>&_M zaOkiZ%kk5gx>`1}OEdXqGYGd4g(+4$Ku_19z;jJOxUes_p(5kU3y;D;jqrF``Aa4o zW!G4&P)q(-e`!wWY$#iK*K@x6cB*PzqP?r4rW*3()wU^(n?Xa(+?xjAa-0i$pE9#6ns+*0 zZ+*b%uq>K5c`|Lt2&~`8mn3i_R=AmDC3+7zDPTe3f6LPUjt%^rn20Lg<$@Q-YP{NYAmRsjvo}_U~Nbo9_59Q1f%Y&K#XOX-Z|BqY8MM z)N6C$mBr=Qm|hlC3$^TomvZF%c+#bnwROkW*E6^gBV?HL&Ud_g+^F(iO$V&!@qrtz zf5q8#tb_An)3_O{`3NYpXLE(|)<{Zs_SpW?bZT7u-rn=H0>Y z!z2|mEm^{bndZ?rL@V*pA*;Sl|4MwKx0fFMB437xbEFmD`-0e9ZVsz;-?&~sArRUg zxw~Xin5@A~K*BRoeSvYJ&BPJ88~+^Ae>4FrT3>3(QvFWapbhd54;b5*;#1LWavF$QiQv>--yQ-mymHDv4amnksjT+ZH$k*BJ z1AF~Cf8aO_65rKk1*C~}CeO}a-r>vVh^hF%vJsbetl#$&*>w__zNp`c?Y@^!e=YS3 zTgZ#^@GvwGt3TY)PYoOtUybC{z1uA=qc%uQ)HXg-K=O%LW53+d_uhK^@Vw`%&Wy*t z?tB!&wmV7`wV&{dMU=F{i;B52YkP7}?90epa#0FRI$R;0uD+5tEJ{aUug|4kJPe@W zd&0R9-wG2t#w!vjxA;)r2;R7*DLY;p*d`3vCO>mhN<(92U|KkFev7icXzI#nL-&A70n24ksshc}53&?*Bj+~rzZB80okd8feZQM4Er+4O3}hKo2IW}ye;*9|-ZpUD zr}s^ku<-bQY_S+!Fecw?Ulu3N3H>1blfh@6U@e^#%r?T;H(-1Q!oue{~}Lqz!(L6|f|HEW;l_r8=^5@6tY{#XX6m`wHVD$Ro`x zeYrTd$o=+0O{p#q-^!TKAJLOMcA5Lx#S?{){L(W87iDr1m-a6~X_xj|6Ip@A9|?jZ z0|gy%v246hjoFn-&um}cj)WJGe?Z zQ#VMk3T&BJ<}s=+TS+hK*^P_hbGgD#kZ>QEF8A3KrgpfOo*&oQVWFpvxLdS*u&xg( zfXG+Nk|*pNXnh3re-WQ&75ULo&c>J-wb#k$KVk4af2tO<_DN!vnlBb^-%7*_ z@&o(O#CA3WKk$g@(I#42$G2JelFnIn&nM-tjh(yZnuG{Kuzm3M3zmZT1I9YC`agbkDiErU`_!-}IF zS>K{9#Nz$onnj}19Z$3?auXO~@iV&#Z&+sq|4&K;Wh>s!PQpyv(>CC&{Kxv`exAeC zmQt+tv7Z=uA4^_$zC;dj-J8>5p9$HcW2i2df8QyrAgwAxFG2;sa6Z&f>lgR%=s+k^ zvHyWKqbM3=(}i`d*?Ro)$T|1d;ZwKk19(JK=Dz!M2`UF8I~8m40t3!B8GbNx_Rj^n zpj-r66MLxEM0v;xokE;eFdCKrX_V{xR5H0{NwM2Pl|W{=L3ljZ^7O$lZXFM%~&kyXz0 zJ9*2Vz}SlAl(Z$i`nrX!Q<5a|Sm~!Djuh;vR)o}9-_WM_W?qPd2rd`Gr%yNAYh_N# z3mB$a*r`N#Rd+SVFa^+?*YMd@^e^tee|L@5!nS5!Oi7CTm^?`Z2iG{2ZaGdN+_7KK z1q9O3ShSp?;6|<>{F*8L+5B|juv8F3@9S5z5K)2&e_Ol=QYHgyq$P&}ysmw+2Z)~( ziReJklQ#ku?Xi z?Pr3SeIHp9r>5ptit77!7udAx6xT5;8d|A+$*RV^SXfO#l8e4vKf-G1emZ|Ee<0&K z_GrR?sWzu&I7+_Wf|3S$hjdoxLWSr>G^+`S=&T2&@ku3`PgdX2Gzj^(eAOZqwFyqF zv7hl_-cR0STJ@%Mqn+F+m?cX;fAZ{wwRYwel(K1kYF*cgN7jw}EWOr*XJtz-0LAk} ztnZ4-4_sF?z({_3b1Of6w4~AsL)2+y2pY0D(K)^Q?9NSyV zhcrc#60M_anXWJWlA;l$S`XNHFRM`47PVN&R-l{hA~RCe(W89Wl!uNrh~A0A;ueLe zI_Cn>nBO#Mq0s#tfUu^&e@gE-(SFwzo~%Lj8v+Lb`U~3l-hG zIo7yiQxM+lWPH^AndI13kW`t1@hky1Ck+4gcuJL(@J|+b|#kIw>0lA7X8fY zY3hAN%z3j_3+Htie|!f^;$PjF+2R&2EeI%Oe(7I&z=5y$bdcS?G(~)V6T=MJPph~p zp~22Z3QiQQ2TSbQc3#7#ZcgB7W!j zA(y_fR!MjgfA8qCa#+>YZ3wn=%hiv2^}%IQ4~o+TcE}8Ke`ISzZo+zEuV-80{E2at zztSo}A!|$mZ9=nihlscCViBVXdV0AejXFg@REjd!1kR9S4~h@EIcx5c*C;v3^s-;m zY>Y#;puceGDRhkclZLu*GQWcPigfIKv`ypJBI<*QMaz`B8ooL5Dl zrQ1UD&XB}ye<{UGw)E+IVk#15zn?Q@l{X3e@~=uaEMkgM#CZ%20l|=M>cKY zA$#pbab??+Q4}M8C$5$xn1^Bi)PW#4!V9!BWna+fcNyN=xhgFu#qX3sIT_H(EY6LI z{euI_aLrayRJt02w7Mq} zfAx=U$n|sMPgcNJOQ9#-nmd3ML+deN48c#PnZQ^@CCclj+;ct zu@je({VjE0)z=jQSksOUJgT>iHU$gkEv9F%i0Hh%#C(XGjF7jI)0=vc9tKH{ z1B0rUKJC9&Z^#xOnp`ke@~2KO7=UEJ-70!zRlhctehQgpsq$crP~tM z6nG=27fn2R&xyI!s{${{N>oqNk!u0TygEy`y;D>aMKaaXT&m=|9 z@s(KL|Kz=-l;mhbfFYhE+zkt#0Jk##WjHd%7!5NIAu^-8~!|?SweLj`Mbid>M1C#p9Z9Neensa%bJaABW`xL-L*!VI0dO<(z=z7 ze$Cba_$gQ#p@!$ux3HFSE#l#=61!8kEbc*&f4v(Lu&6UCp#)JKDiqQ~da7!q9FaWkF4Gty9pY^4c4eWcqy5Dff1@A9b+XPa z2UI`1`0~K>pQZL&j9{^l$FZpeR-NZfh{#VM$jZOp84}rO;L7HFKFpLg;%6OzQXIma z{h&2wSt7LSy|-{>37fdItHNn1nb^82v*6S>s{gc}z5E3}Qlo_`RFjiSz{sH}*R)8w zpG5y`j}_4~U72v+;o-%Ne?F^DA2yKS#_+?$?n4e!a7qw+>3y1k-m{vpVGZm~qjXKHVR}j4sJfhPj>%HHCz^E{c%mB%Y6~(S2=kviMHUTNhAZ z@J{~;ZV1_&J1{BJVb6CysG$_ou1BD6fpY0WUA+zSLfTSYUIsF*_7a776UDHvLMWEJQJF6Fq(=}su}3e8Pd;0 z$tqcTBemxJDS}KDzA-YGSP6KDOT@X-cfZk-7VN-Nmm42Ke>D}rRenw(ZTMk~<#;}P znz?M1nCy7DpGf#Z61LEOp6=4)nkd@!#I2X;O%Sdl09E8jl49TzWI+1_#$E5c-rJHx zlcU0b<3mq=U-7~=G^-3(KQXApoOJ5QAhFb~?*?a7FLdz(o3#4}X$sYCBrll;57h%X zR!^mz871C+f9rQ%TJc>S1h?ncR@CI@u#A<-3UVV4prmc(=rqwY#xJJJg9u4oKU2B2CJ$U;!BA^S=55^ennm(F44WSiu#dR= zz}_^8X*EgP`0ZS2!s?yvm#*L~5t`Y&A5m?-F8OZuf7Ca+O_m*_@42>YoY^ba$#*b>V_AItjG%n?ECO=I}|SX@&(y|FND6P&Fv_nrZtr>A9--IwFmMyX20-eR_8D6aHEW?rGYV)u{>9hr=P5zexxNpnI_SI{bTa z-0MxoN^pnM@t1NC*5E50pT^m~{Qv@Y@j8E_ka|+|M*a;MQrR%V3>32x_ss5+6Ss4r zXZ_2|gXCJWP;Zm5Dyr09oj{4B!bmv1MLYp7f7r%VUEYGSP>e>qsZ<@AjZ`vHX|gHN*Lubg5o1EV$9K>jC83c7B$orab(5e1 zf1+CJNcH6Xskx@7@x{zzwi1npNNPt)w#Brsrcv)<1$8qxM(vl0;8wU@3GT_aX+2#+=e|H~VgX(nZPB z`to$+{o4Hy!pCt=_hi^z0HJ0=bIGDtajlwFkT^`2Cv=F6xGIYYWmM7JD%V*#^>V<^ z590WpX(6!lD*gvoPHJ-b|7k+x?e`l2JK3{7EbX2mFSr{RoTNw5bvPwj5zoEzqwl#as zf0yOtt51+@CEv0cUBEvRpcrZ|If3x{$kOY)YP_r=EuW-PbU=@(=Vd?g39WtKkU^+v zdU9h$ds|6b03{<`q_??AUr4ltV-KZe!i>Xxz9Fiisqa%;);oymo9b{-QjMw^ccj{R(X=HP>bRy0?9VJy4JE%$OS`$^0M$rMmhR_1v4A zXRBBrDR#~I2xgP-EDdFM`53l8)2_eml1*KDdXD}|$O|$;wu4n!bEr-S^pd?c)>m5Dh#yB6 zLtI`lfbQS7a|HAQJZwMfinppIXyf;=n?t-v#S$A`!(Yr$C`_D92gR6mJ3|G)v)nU}J_tfX0Y8cVo@7!jM__sVI%i%yoOq|aWs ziKI9EnRw8D+!tYqf6KpJ!DnJ|Cn4#l&wJ%Sk=`)}wddq%z(;MbuD~&#pVtcg3XL%& zDrU9xR~qg3p8fE0Pgg^4o`|?A^s`N*f?MaNt}>LmnZ)K7iVQyg8BYU4v2t2?`CWXk zwt&L*`nvn;@GtQwfhQ3eR5}>eVXv{0Jop>UKqef$k(|p4e?^i%qru1O+6t8p*bfY) z9%O^Pi_1F)pIZn#n{6)nEz;GMnFSTH=T)`5Qdo!(jUr;Cw&rnwIgolnYp*T$)vv}? z8tBdelG)vZ>M;|Y2~@?oF;mZ_?>}gwD?A|Nh~v{g`4xN$`7DlAI!Zv_I-;8EXv?!5 z4>8$hEchOhe<3t192pgpdyV<}w%;%VGW>KB$i|GFoL*vaWR7)eh`@}g?Y?);&NChF<(OjN5Dd-;GKfbXys z3UpzU(z@_jhSmR{JSQpSl!;@1=zu|$IH5Hu}EFs@m z%-vEhf01l-7!lpGy?DV=EQR^#KUrQu(~I79sg@Rx1~<#=Qa9wLs>R>fh+B|cMLE`H z*W#+r9E!&FWK450>St(z{coRjNtHP0$t16Ud~5fNYKp!Z*lyI%B{@V1cR4ZX8dino z(rS^PenG2lW3=rcMki>RD*Gu+ol}q|z_P8|wr$&Ni{3oh`0kMF@4x2zG=~4zK9hJ ztsc$(Vx#&6GjI1=f?U!j)co9+*H(}U35S}zVks`rvgV~<(8FmhtWn~}ek=WBjYUCX zvTKx8bTOp(sX7ouN>eTr!bN0&W&o*6t-9aUD~x{Tahf`-z4n~j9DS3etgRjvCV{cr4RNr zJPE`yc~(C_fL9jxR3G_Qz|js!eCchER@fal?vvGKPVkV!D~)8Jw&X_b({9k9{uNma z8{ME0G(Jn&8Gr~HIF&}gK>xl4AO503b;WgzPG~cdv*CDA>*2|yJTa* zn8gXTo%?nJPQpDxIu(%PB#BIeI5$Eb0;b;O`n>X=7g~`Pk1BR$gH!2v)O`gU*8P;* z#zuGQB^cGefp@NXHxO2-!B0#x23({cLcCdc5_}qIw$#)V`yQ+qSc1qAe>2`Nh_Bm* zeC`ZQmWC|w(xtcpa$OT$dp_u1liKvR5axvxXH%%so0)|5#_#xef5q2KIWKKUwc_Sb zbPbRHF`Uip)fmuhm)5_CNL5l|{q;w+7ra3eB0-=+G;%Z{9fjYjZWKC*=}r3pf7knB zv*sDnd*_C>XpS@f>Nx3jM;9S7-ElTLl}nsj#i5s^1$GJn5FHa3z5+YsF_7Hkuxhgd zEgzSqk*w@jmz?MRq&-2bg1F|aqlV-W^VmNFZOAAs7$SIHRVgX|Z~r0cq?)PuRDoR8 zB0EfMLR)_zEY~`*F_0@xaOTTNfkeYrU+Rf??TM9DL4e)89M!Qi0HBt6r%~51rrC=) z4<}jm-j%roFtw+^Ic{*DaRUi{Kn?~K$JH$F&<(Xn$-n>WF`6m;+-h{UlFAjCNC_Mo z@5fnFn6Bs@FQ7al&eS0w;<{Tm|ybQzA$@Nxu*yHb(car{FoX?zj@Ezi5B=!uq6q~!_5+9dp8WpbX^QIONoggI@irGi6JvP9>#Nv$iU3_<_BoBoR;uE zqGu2euG9cna8wj#cCPfBkmn zoX;f!g<~3=WP;nmpQqNFpVtGKhaw?H0U;p{mn0>+Q|$5B`PtUKsnW7Bzve%=ba{!G z=r6VCC3S#pfT-xrl_c=f&jk}y(#bIZ0s@1%2MGXarK1Z)Dr9|S#7Z5)igFC<%|-di z2qFQ269#M>NfRAr<#52k%sRS5+`@vqijlpFk^2k!10hj;w~)dS11o}f3fcm%cLKp< zpye7(*727$mlM3}dP zW}U5cKq8Rg8-$xc=3$Ru#J&E!z1YT}q3v5@ts-`PP`!H2{sHY6f|v-Q-%iW#2fgsG z6&yf*`rm-l@5pa4uz+s_h_%&T-Cd$mPB3f4+90kV;C34APDw^GP9U(RuOldDx1g<| zAON2rl11E8*1%0h5D?9MEKn|Q0AS3eK}c{{l2e~E{DCpTr^oWTyb`WSEx4`KKTnc# z)8IuVkf@i#-R$M~V?m3OY7+JQW2FxPq^aqHynh*g+5#-3wLNGl`P;cI$nj_BvQN^V z2?+`f9TUV~57>|q7qZ*nF?8GU)`9eg5%4M>(8Gua0lB&r0rVkq+3POQ+HFsS$OIJO z2>J2xeG~eV?fCWv+>C@v){A3{7_k36;RhLX^__W>9_#M`OaOXg9!m)H`Sf;@GqmNg z)}K4Q{nP$)&6rbGAKw{|vqCuZvx(3-0s4ELcL<0x*`jdJ@2>1fn z{6wDz5COK}Um5dw77-wjen|JK-2fA}uQoKRKkHZsy#UtJ-fMAeIKv&wrL$?uJCK$;K(lEqCA-ZjMTQnPGQ@`Prrvjn8a{OU27+fPpzA@vEV#8yu(P+>3#l-AAP4!q1J?a<8i`61@fhOm zX&K1lHK6y$sAGc@x1{4`@Tyv)M{c*n_1!_*tQ3Cod1V_K>JN}06xb*(rU$1!NPj<& z!FLCE6S((Rwk;4LBU)%DEb!*o1LSHSQfm(n%{1a}gSfwKX0N+KKK^|w;0}@D74f?y z2!Jbk4boeE?H>J(i;MwuyVkdf`~xH`2t@dKT^8^irWF3e_}Jqk>>jZ@eQp0U9|8Kh z*~@^0oA#im^euFgACCaV^lEU(06UNR%ova5KLZ){3i??h&T$>y(Kx!J;-k^qGt)yz z!?X%(8`QxB*$@xsVheQv;HgP0c{*J4q5U;bZ*`v;G~y0CcjYJLpEazMfm$EQm8gL0 zEBEN6_xDTHK7McAy`>A9x1RJ!=|rKYqD1OlB_pf#;f5-d!r*e86Jh>f_6}>@?oF@b z9UGE2uchGGvKFni{SWdfdVIDwLa7%!f;vOA#H1bndO7;sU`Kf-;5dRc(icUSV?x<7 z>m&P|7$YIazK;jZltG-@Vx>iNyE-$f6 z;E&#wqKq50$v+GZVEor>Y2A5|AKAM7)o@h?T-%Z>h8^1S2h_mxXBI{xMGQ4PWks%DtrnugYnj-!92&fEGqNFClj zCYSXp^c`lEWxNgQHCp-2GFg(kB*_X}{=UO1X=IFCxdEX-Uv# zLDHEUn6|mcRWT z{9C_u0Dg1aO!@Z%+g;TF-`M{5!~+ye6x#hy4)V6!-IFgL%q|)P#^#A9Fm+&L1KQTD zOi&}Xqu4Q8l1nbA;ifO*F1Mw_M0xzn)Df^S#B;OghVc^WuHpu{z8yQuy|{U1xzBFd z{w%n;*cvm!Ulv897{a(rglR{kt)6{is8{!v0RL!JT~j-KJ+ulavgWbkq#%x`xIQ#Z zAFkyT*S;s$dABuTBg!n>_wGx_dSC3(4l{%9Mx$}(f~I*G+C9}w5}7o2$b?~ZoDXTx zg$fLV{2GsogTwB>J>RKPAA53l{_F0%qxcpDGR}m<(y+~v!IuhJ^1Pu-EiY1poId-?(#*>D1*MDVy#@og9Z3}$(CAK$C)Z$|y9cy_E63pgs z#a?6#OuTMJl%R7G22>E&A0MLq8u8=n5kNb5#-&h2R_8tW%{17;f)4i-8xJ6W~;h;N2JniItsFdoYxPz zu#m@zG~;)P-fde8wb!x#Ej_X*x$KNofgeldcyV&|QsIuhVH_-*e@f|oZQM=G;@kKk z8b2MXni8F|p5y4VYUoFVKjEExjs7>V&X7VlI{PgczvJfEi8M;jkwH0K4jW4;j0k zSU9+$^6xAVgSF7H6uB@<%)Nk@wD=~RM7DT)mpJa(n=eF63^we6YpIg1uPu_I z*l^m5dzCJi`7ssbdz0qh=UeW9gjJbb@OL_^HZ*ki@6ckwPbZ!PFLksUfW#F;wBL!n zU@qgBzF(SrF|k&DD%|;(%Z04y7xShM)%S6!?q|Xf0{5g0)YD(92QMmdHx)hZzx-l4sz<;HR>G6Yavjq=s;Pgq3k3!W22@yw0-GCWlM z+P$Cj9~Sv&*_>k<6kL0;V?4j9f+JI>JJ**#T8szM^P9}{Dl1D0N-6Z=<-&g5zOsB;(rgNB$ei^ zQT!q`6*o4^+?o)nD~`PVUzIV08|?&?Dn=6SCt+{rpKTPpYBc&PKbxkmcOU9v#`^PV zSvSm{ndBonT{JVR)Krz?JD-cPT{UgN5Ff>q59R4mNY?_(+Q_^{*RoxIL+EBJ$+c$L z)7#4M0EWscqDV76dbUSr_Y%C;)(Rv#6Q8Le&xh!qxL9?Wd2K9Hv%_sNyX1HYPJCDL zw-pX7#@cWD>x>Gc^VLQ^0%v+JUjssOahUf~&F?RRY@Lt)P3d>mMO%%1v zJbXTJMw45qj-{@KG&o{76+$ph4c=_h(U+as0UOg}n(LKV0;t#|z%&_%#BCDQW0Gau z`ohz*eE~pvp~L5YeT=A_sOd#zgIhFV)7K;DANT(Q&=qPsU6gBZZss$Nc$$t~E5`PkqPwcJqJViL&-$Lo_*S)!Kn%yq;xQ{FR4YF8|qj zR~>F3lUHq>5G-X<0NnJJ`|?`+QyWbnF9l7O0~D9n$qv6lL@Ym##=fHL1w|vzTeqQn z!dQ}+7uNZ1sq>@}_g@P$(y4-JrqtW6vRN@6EY( z$FuxGO8~iBIQq(`ySB3PU*6*=1^8bjwsNGh&kwFhbT_k<*y4& zOk?{ObM`|m;CF_4SCEAZfYwJyE`q{ivK^JXTvh@QCQ%!L$p;i80V7sg9^6O)X2ggw z%IJdFnDmDY5@d^^=`#W{%{q~AlPzoz< z5Eu$N6V_Dm(*|kpgxV@y7rj*`t}O4#xsrteb;Ej%V^7~L(=HO20E^A=G`c>Y;aJGU z{qVzDy>u?9X@vOX4}UC^ASPD10(kMaka(rz8vfhzBt&$5B7UktFVzy3vDaWqz(=gLXl&8msRr_7i z4*u?#Le|W*9Js}bk2Oz2@t_$$kUMIc8?u9Al)OWsK$Md5n22}*E|ARm`eDq*wZoib z`m+hDdDlv7op%Fm(N$~e)|NVNenMF*9pIVj5K&_>wJ)DYL#F1*-a6YsCYuK`-C+_&(T@giB(D7Z51x%F7!1OeGet$ zYgKx^BQmaa$rWA)Xrx94cs!#ftTS8GA>I|VCz+tmJxhMM@+;}nE>m*bc_pfYSGHC# zU)BCWmOT&W0D$m8X}m2`6Yj3b*p~n`U0M2^Bm&Bz<_`)7LvTFGh4#LspL%~?PHdsx zEWpQY{h7_Z$MY1@I%@FH_s#bK2U%2`oZ5wx&5$A$*eYk9aZcm)r=JOO0!e|Flv1{)oqy1pkRMmg@(A_9dmtqX z^(cg}OJO=WIqD-+`Md+|UZlQNepz_uwY;Gn=iknkj(yK#H*Q+3{pSN0#F5r6tY36X zGJ2*H;kg%0BY{OT!eE=z`fASj6l5#cnr9MiB!E5^J~32mvxm_hiZfNFmJ9)(P?!;x z)<3*orvglSUYNj2jXjd1)Bk1Lp{O?bqd(7K&i#U@<8_rBk743*s)7r2GV(-Kw`Zg6Mbv(o;3J`j3-GAV z38-}+u-o%o1X@OPpFFKX9cOg49~dfs=_<(X%vI%^7yM_kWUhDRIu~P}H>Amkb<;QP z6-d0Z@M8ZdiB|nupQ~9BRVXTwhwtGf?vq|c=%{q*OiO}|V-S6i_wqMLwdvW~S0y$w zq_%H5kX#588!v6PyG{Pcc7^;V_^T~W6kz_FLBOZ#Z(olX!}*!1&A>ao`A{7+_C=~Q zf^6}h7Q(>udgBv6XLMzjSPB?hp=@(?s>62=!%LkxEvjocomEFWNN|NAw_tW7=g=5E zwiR3J1(1yn5ia)%>D{ZI7D1p(sE6Dr8Qyn58&K@@XlgcPbCC~?C~^8TRvaO& z&_TOqoK`Sw{XG7Qi(YKAZ;V!J{j<7b7=&+ePmt#o?M~fJWAnEeZLAvIRf+Z|j8r`R zl}u0Hr{9NvK`x;=(98J9)3n58EucC?r*h5EJ6+botluG?sI)gWx1M_wO0@jS_ea(4(6$fwdDX}JBM`?bEfQYnwR}fOMqK%$NpB);Jc1Jayc?g|25n+ z|tkRa2tcDAixJTjLi$E=OWZUxO`lzR?38jQwF8iE27#OVf8MeUv+0I zzg>*xM=1CDhC~X7T<|_>j1XoVjH9seJ_Bmt&A-WjX)Qa43id^d{18Cnv^Q_>_?EC_qiD@h>mau*w$u zus*ySj1@`|iVE6_um^v`OyZJ4JWAj<+rM(^?TQnjM|Re}In-9X`=?pIV_du?-j2{X zY9wvIf9aI1KcP&Vd0bGM>R! z>y5)Yo&~R8^M76jh)e17O9@5Ad*$ap&D#v`qSYT4|D>7Oy@t-stb^l7&n3IHFY+i1G9uTa`EQB(4=SX;-XonGY}FYUyF2aUFvf88Blwn&I#%@5&HNo|Sox5wbIX znf$+w%~qTN;%J2?=)%jD1R=1ZBtk*1IH@X$RSvohkngWCTrDevIsN+}l!8Zw1VZpE35E|9(Dq(?g%2HH=aV`G`Q%%UXF9)cK*EYPS^!%maC6xdei zt86@ir~yr6D?K`o^M@Lf{-#XwIF<}L&oomiQ^gP)6rsehW0jt>z_{AlFBgxkVcVcu z)*`)-h*=J&W?+LO>ceTTC+Cd=-E~f(2CuAtmjPr|W2>+@bG*Xnb#d~#0jRNdNAp82 zHTc*&uxq9;UgQ(Atp~xZd5#ayBA6EJn_gASM}WLK*HmtdVG|m%CPeWX z><9RW>k96L&im_L2fP(g*JH?u98r6MSLx%5h{l#C+5Awj1UhUN28~Xhwp-srzyqrH zuUt8S=w(}&$`N-nH#!YY!k@LuMnx`vt7vP60lJZjsk%T1XST}4YpY5vgZPV#NZN|) zC_qWl`sc&^<^Y86Oz{e)TAE&px*N(;^Kl5HOGggWm3bBU$US}1bYJX3ZLP|ej1{Ej zg?qILD!cN{#&rCZQRPKXvup&i&x-U}D;+oA81hj)JKE)`c0-%eo|VPAd}VZshyLmb zD8Z>j!KT%i4--w#Nd~VDL){;D=2eyPQb2LXnKas?X5gNkckm!>1P1dtLG5QME{3ld z|8aPjfb&5Rv!N`Gg+k%_09`jU>0!F!0N#9|m=kA87JPqXl1q*A2e+DU3MrUHxq|%{ z27x$5DZJkzglagBXR6fL)T}K?&ss=hOP-? zfW#F0ArRC(2gAd(iwKwIvwu1D^_!Ps3`un*qx?HmUSz(VuLixtVuLn0FnUVxRWJ2e zk?WnG9zQ!4?~kfRGVv=D$)TJ)JHX`$7*>b6$h-wvT@E*O>7LKaZyMEia`Qo-WeMb~ z7VF1F%4ht!%AH#Pl7E#QehhPG)WUMFTH+TpFI*cz*tp@V@GDcypVUkKMn<5xL{yn@R@JaAt;H1Dpz8%&W2B3kbn0o@gU5Ln^ki>P|JtM zEOl1X&Ikyx)L1ns$odyK1o==j z$SBs(QzS|z9OWO#MAA=@ldV%!S&vPDJ0tobH((i|I|{5dL#^x)0E-C_F)4n1T7<)H ztNE`^6Doma;>)HB%u%e?Ff8g5W(JWhjTBEt1I~B$u-h?SxV-@R{8z`X8igG_&%-q= zR8SGa5gTn){*a2|7z21rI9D&Fnyx>UjXRabjEhHs4LBN_{AFEuTL;u9-aWU*G5PC* zeRDaD#&KP@o*OOU09YyEyx_447SDjk8%v4k?b(Pbf0}jg=BOC>JZTf+KvRXZCe_vH z6*01blaIsSrV88M7RgObtVd{AODQ?XS#spBT=o!UYsR`SplIu^q?N~58t$VBEKVxA ze-J8l`H{2=mVFFpeLV1LTaA08SZTbBiq-ZMBc!hYhB%5xfI0#F9^bL&dYR$C@)1k5 zv*`Dfzx!Zf5~wI{cb>OP&yWLMH-}0)9!HO=$5EY;RG~gMfB8SiX0-y^4?d&X)w06{ z)W#Xm(~5|twDd%$9!agFHE0b4!&%fn#q~g|hTIxicru~Wy1!BCRZ4F$S{kW{ceXFK zbfSmY@T}r(CN#JXKH;=r?$7yNq@9(sj9Is6>B9RQ|AM{iX%$60r z7pY#&vW*J$e+tp!9Mj^7PxgfAs2UG(G?V!6W&CXJq?fM*i*m|m12llbbD;OfE2y! z3-&>>lKfI-rONbvs@gV%*`IrMDk$M6OGRe&qbTV*DonL!skYq6SX2kKCoRu{%7DcK z;)}b+F!52)!)<_ur3!~20a5H+*=~~DT)BUp^COLD6!sPviA9tO@l$m zi_lP1fSwXEYB)nh@Hccc^cU+R#UrB!RURPPFTv89xjeW`YqUXS8@+(V@m*Ifl#k~# zW}Na=EOCaLmhCNYI02~7OD!K}xm}7q&8xIrRS+6{RSf{eWB^{Mnb_YGSEYph^{1>n z-@sL0O?GX!h1?c{!qjp4D1sgOl!P7FJbY2r$bqOS)W828OG`}IVlPKih|V?v?kqql z!S%2$KLK_Ttl@Q+62ng>fNmli_RzE*tk_|%E6Kv%RD2%nyKlc~UYVS-JN~~9fy>7=y9c$AVV#xd)ZlGV!&`=6d zNBgy-(3k?lg$4^91#3#o7^Ko7f_TB>7-cP#N^1-v%u?7?TZejk)Ns1D3_}TcG}$=% zIP!#oV=r;0HvGs+hii_+nu(GNgjvdk*f$&x?g~(ve4L8Jogz3WO^O_8%1R$EIkQkX z8d;{v+UDz>pX1AQo%C(=V#hi6QY=xjHFp*PqiM&B+O?1+J7ey>1)V|wOW^ts;dmpz zQ;`Y*5>1FWm2#MPa(mwFbeo6J^c6T72aO ze1Nwjfvs%5_gf@?40?gdVsC{Gl_!*k?w+d0hU+itC*V-;^Ch26nE;~@T|x6JtXaM& z0xz^AWelz{HNu=%bkyn~=o2NMx-?DRJzV+uHlfb6x~g_IqeG9Lx!?uE{yi1>wDKXo z(fCijzYj@YoWT2#{~)=Sx2<0Hq``5qpa3F2e4=jKUF5~(5WFXL2N1GV;5Z(LxaIW= zV5?|H6~&-Hq)n{cW$^ktFKAC7vY7oWTKXU4+AE&^X4~%W+6?G|sv0gyw7ID3J~eSm znEj((2N>%(w)`L6Ty-zUg(i#%AXRNh)yf>AfJOq{B!65G*&sz(b2R^zw9kKc0WhXW zeq*t~rpfLpolNFa(m`=DR<=YZ-px-dXj#OZ(rBKwS2J$E74%BL==^n=MkDQ(hKbW5 zpBP4FzY!g0r;zf;5}S(VBI???NC>T$I1{uT4GRJSJuuNvE3)N zt)sDXX>y#o^?fT_nG^QR{%Som)7jQ;;vhD$|6Y8zlp`>XIxzXfv(T}bLXvq?snz{A zX7BppR$%5F_8S|z=BjJIZnvp(@KLg|!`X*9*u^>G^DxmJ@V;_oY#!h$0{FQ68{Io} z9DlWdjTsQ1AUX_RrE45i)Y470Rdw4O4I?vXR^kq4PXHo&)Q`s0bgGM34~Dx5y7_9i zqi!x{5)?vj5HGzLk<>pP6}IHwSq78E`u;(g8!w80k#UT1&SXrwKvT>o^R842M7!YJ&(j|%p)#E5;^H=|j69in^JFMG6_;0E3O_YL4*~=TMT9 z=n1CKhW8N^mgnl~#2Dv^4=HLxNmb)BA6QUWf#kcD1}&T9zwKwIwi+%Aw}s@mpa|{y zFITnuP%Yq)(D4ZCVGn6;gj^_6F=X7JYhiD}oRx*-kW*E;FlLf~2D#%@P~WxQ?U5gk zkfe<9bV7!upr0qv0Qu+#arP1oLR^~3MDFGACV5p^f$VIsmEk~OX~_+jMZ!Xazrwl? z;!H0n5oKA`HY|gm|Y~5!zm)6Cb4*WW*Hx? z-^umAQ}`v`@==P*ivnrcLL&*bN3v~-`Z257w?(U2|2iY90L~Vg-$j?iJ*>8ZpLza{ zQ_)AK)SEHhC1tqeP5!kZ@^n-s#!Eek^h(vlp*=Dj;E+m` z@m=W=mZSNY1b9YjeRoVoGstR*@D0B4UKmY69(?{=sZy&K$jqX)p(u5o29sl>HySb% zQ2KZWfA!H=wU^&4S87ulH9zn67$rw>spx@8SsG)au=91r)^hDQU zD>B0&)j3tbpRdLCSfIJh6e)22)+%iCLAStFTXpMX2xuX2wX`I4ddlx?lHH-q{GbgD z_$6j+rLg2(J4Q60K3G1_`r@d>j#8CGE=a`q(;-ut@jQOnvjiA~2YLvfB&Rou#I_iTAuTT*qEOI$!!8iZGdF%RCwns2t;aUs&}Bbjl}$g=UWBQF#lyf4Rpe5p z!xC^y;t)+b_t!xOI?hqp({}x6 z6g%GPNwqmdyc^_p6?-t-;iz9`=phpvl+1<37qG5A*}r=Gmwg}WEAoKnUr9r# zISRj4tT!}R>!qj*3+6ZJb68=sq-FB{L?r#2`_BRE@FWXp(HyFIzJ^qPv}Z!0eH($Pu23(&311Z-^agl9Z)}x4c_qd;{hw zMa2ozEPk4*jM?}8DyNq{2G8~@(Xe?%O5MPC2P{aF-gtX;la~367{8?iS?!cqJ;gf+ zq@^y)m7XHg6f`E;qaGJv;&N?~P1n;oeZi1898Th{%Mv5=tpH#^-wT*wpxW^hCND>& z=8H53gi^V1Sq*42l4a8h_Oe{|mI1v=CL%L1a!U5R({{w2qdFB&X1@^YbMv5gLtkqJ&LF?_e37=a!lyhj)Dj+Q!M-tZuG)ooU>S>`^OMxB&J4GVD`a`@qfM zVPEtVEji+1aQee}q&8B6q`VauNszaO+wH(#qRi_R0o_@aUn(8$s|}sW`D=y0TKDfo z{NrP%U1Em*yx>c#&q?;{HQ?_@xcS`d!;-UU#~apstd(56#$j8q{F!`HGm`#cew`h8 zSKqN8*q-i~oQ(rw!cwaT59Un8Xp>j#7G?Xd5;Y8O0=rv<@Ce%5rA4uEY2gO)U-U(| zzAF!9VAJxdwkQU(h2t5fZ3Z<-(XG)RO2;KV;5CnIJ0}IlADb=DH~?}Hn4C9w|2^M8 z%hbCxbpwpf+0h#%(`|Z`_&?LlYHX0(b}gL~_xih?3J&p`BQu*E5j&rwiB-eGEkCBd z(_YLR&V537e){Y+=x0qkU)QD%%>W;stTCJ3k&ZCSwYHCk#H$a3E$_$EJXcGu)qgcr z;A88A1Ezy#g?*bO0FZfuvh=Ef>U&}utItpznf>AxOZfZ4VQ0_e4pnYIaf4na8d1R= z@%iN%uj|(-QNZq*mHR6mYSt;{mx?2IQs+k29Pc3D)b304C)fQc+pmiEOaA6U#J8~I zU6b(U;xGRkC1eNX&EuJXSI==2vj+zPf$x7$s5%zq)B$mZQf1%cJiXJjPqkqsUj)w>+SR@NA^>5a9l(@+JFInsWiTz&S%BEb=SZxjfjp$*PQM$t3n$g3Kh3c}8YXK}bJ9{}WnO0Z5dc|Jufv@?f7h zk15-UrC*FqiL!9Xf@{Yyn4 zMF@2_a6oVP@p^*D9d^TG+l-7pWGZ_`Uw%N-1cvedx9$6{U>?2YUuzem0L=WKJ`b&> zFCVPO5}38+UofEy%>JK4B5-CVCJyHRLx(eQu(JIZ9d74g@|%3K-p;n6U|N2@E-NNF z#_n=;wa#wCt=)tdf5VNZxoYKv_a&2e8`q&yK&`<%n%$=Qy=hcx@X9tzb@NIt?d&gh zS}XAQzI6Sht*tB&1%x`7vomrW^z2ywv^v_UX+OLoCo=?9#wuu<77(4R>?G775Hhc~ zdtAuhHUO&sc=$UZQm#2XTXSt45b)w<<&`d7)Ff~x0|P@KL(DWBk%eDqkK8x~1rVhR zs()EX6SSbHzL1KvJcuAUaS2QuQyn`na1}7jbm%gMI1n~0DXNYHsF~HiGkUdy3<|=^+Pm663T@0|j3X~k472Va42n|JKV_^$Y4^FkV24wd$ z003Fn)a>{Hc>WB;IfHyZ35_ma*0{+2gwo*+(QnE|q0?o4Yumvze%s6mw6>4+?1(K7 zuJ*4T?|e}JzFt4_huxZ&uYX*Qc9_50{t-gdbX8Qdo_k<#6|^RoN2gc&m*H|RA6I0E zMqhh+1>1 zkZCik{fo1**%XWPOd$-?Pumy8TTVGSmv?wadX)NRT*OGy?>P@Q_%{;Tt;oQK0qI2e zQPC3d!DkHn0_cfqX>Y1_om9sHE1_q4f@OPaSYtwZp$5D~HPv8Lvr!FZ$C;{Mj#Nh? zsfIBuR5l;*(aqQ`eC`&sLRB&m@p(@HruSjZD0b_7t-Jk-yH*z9By5b1xMvA?3Ok*- zn>&7tsuhJxWRAkoMRrF?3h}3Z0d|2Ri$R_QxBZg^^79siJ}2rYK@njk`eTdAsIyL^ z+W25feFwhgdnaq^p<*t-BIJ_%3^JKf)1T?~09w>*?0k}tzYNE$4{lXNwvSVq?9G3$Z9yP<9=%gzoJG&n`J6nRSz`K#el^* zIqCL^`9v7&IlrDMfK{wrY=Ix$)aY|MhYOe-d=?%qHyF~i(~*j0kysD8>^fD5;M>uD ztg;(NolykJ2c@y`;qK9p0qgvOj%PwkKx!+x&wya@a}`U|_Ry0C1ac5fR;ihO@q!V(QyyQyNhx#5|1K(UrG_X!A>}3!D;KCQQ|INn>4j;XNwuRVJxrc_&FUk%B?qe#l<3-s|THWm0{7s|nU%L<_J} zm|UUI)K;bng6{Z0fEvUpcwnSW+gZH?Haq?1fJMThsKtGwmHfbx2HFFTp^X;95sx{EpQ1EF78d!Qf*|H|4YfV6s#XNdj|};pKN)tq)Sp zNV2eU)D*$P3vvekOe#q2uq;09)WqJ1I@qlImW*=aZpKF&JcprQExVn-&Z6p>8 zpHiZ(7Honf-gjvV}2GG+h>L>WXYZv>Q5QtbTUM+*PYa zN9gZ6j9qAAz=E~IVFk8l97By;6tUON78$h15uNFK89w+KZ^0?4ozvLW5iEg#poYZM zo&Wup+buqn@e}(E4?|L4D->105x?DRET{m-M@&qNa!FVKP72NV1=scDb#t#-$6(I_ zMo(~R>B`F^m z_va%RNd=j&;*!;Wmz;8DxI@n`d1K$jv%es3^E@jcug7Bo<@$I!&-?NCZ&cB>?waW5wy z-j|pA2pGMiEKCv2G@&}GATd}Y^%)`dI=Ipdkn03AIa)<7r2@va;YN`&3-#iI2Z7#) zL?#6tk^iZdc{XAvrQc#=#l!g4qJ*8CawnpU`G{#NPx~hxPztbkED)>-ku;9sIYTS< zK{)N=3EBKLd{@c~Pga#WKUn%3p9@Ac6=S%oRXBSfkY$#?(rpM7_t9!hw3)3&Fyzk# zU>?vn%7kte-|eVa0pu47ge-t!w{I16X+>+{7Mek^uu?ntNQ`9B8noir+B;z`);9^2 zib1Hwl|K(n<5ECJXY%UAq8aMZXZnaKs{!>3&&xld>-DczQzB{TKStTxzQx3S++kS$ zc~Jjv0g-oQL++GR)ad=>)u15p9!tI`06C;iKu$zTo+igA50z#T%V2A*(F_89Uxtr> z&JhOZ2M;LUMB?#k)0}UWc14MUabB!k?OWrgPuT20}bb zRZ)I)=W??3T6X2+iya(=>5z{)Ep80`1kN#==p5|OtuCDsH62{u?Hd>sU68;6T=$f_P1Nki+5z*o~4H7 z&c zDSdDQhKV`83Xs;=V#Q%O04B zpJFqU#swt>tS6Q;2|yQkJzZB&Rz?U|`CN|erzZ*kb=%MaT22exn|AgvM=bA_QYiLB z>4ok;Ht=#nalZRmy)37(+)$j@{R>Bk@C=A7D$x5&3k`0{10L06dqQzwd>e+W81cE+eX92TCvsGwr$(C({c~Brzag!qLa0lSr)>~81b6^yhD<~|1$j_%H>sbrG zR2Zvi-+@VBGsOdp=DJjar$mPA0e3%ls#3Y6>v!=yTj%%f>iV$TjkcdV8W&2_h*+yG z^Y?^%PT_o+GSmIeKj6O5-)c5$4^5rrK43781T)N0%#a>W6#T0k;%TyZ>bsNr(XU}( zKMx`M;Pv^v=#EJ7V|*v!DF}a=9F3fg?BpU_TEqte#*8Oc)TK}DtC?)lM)+y#dtxY| zehy30|8&K4>lkd+QHJBDFuoO7gLTU3IpaKz=Yw%=LeWA;EKS2%ypuu0#TBvH<*})+ zvM9E{DPJAB`=*h4?PHwvr|;+wcLtwayH5ULN;yjl(t$M1O_!3!h2L)&YHacdC(c= ztDL$jXHA*86m{+c{t%psQ$YuTRv+3mT_QP<$JF_>eJk!3$s8P;TN;bjVln(VfI>f@ z2M`OY50~Q$;RV^=PGrY254ke0;pP>EvA_O$4}%CoqI>gSf`lX^H$*V~-mf}1XGzPt z!wnNtw`Z)J+(6_+`s=+S37x))BF}eGSY{o2 zlWT@I&S%}h+0ZG}krh@Ld>5kSHK6lGXBbzRVZ$EBVsJaC;Ozr}E!vJGZq@)nwQx-s$#wLJI~R_aP*4&LUp?L=1(e+Ta2 z_^nb4{I@lwvwBR_Y zo~YO@@S3J9xIym|mlkBs56^TIUlq{hFioYX)vhO|wWx9TQB%z*uM5$vkmj*p{Uu5m z+9lu0vGs|-`j-CyuGciz%?b*-(t~Y@SP8_I4HXtLGq)-~{Jbo$AhE8&5V<1*yb$6J z_lNbn7L|G0>>D*j#tgoIXB252PSk6!KgP9=OPu9IJ&rwi-b=Xb^?b8lHVL%xvxj8w z!{`3-JV$YGF3tsU1LY`E6A6xuyafiQ!kUqj>UT$(*EUpBT7NUu-Qb!F(8tTWG|PRc z%{n~>=FF2DTKS<|R7SsAlJ_=^j>4cJ<80UF(e-izz1_lF-G6ceZ5o8JaHC~)C8)Xc zdaU@Zg5w(TM#2+i@KBO}4$<~`bblZ}L`EQCTKzOxd%mzgbiI-ZTPTHv3rkhPoqL^t zHOW)J&&D_WDzh0;6tM)KI=oUhVvT!$1#^t6AB^$Ef(o_xzK{53WaC4v1EpwYkiunc zI-+6gSj<0<<`zc?e6;1h2snV;m)96G1ZcilwuLOlBVDW`j$MtCT}W#V6Sm%@#m*r` zGULW-e$mDm>4og_Ql7LrUYR%qe&p@PPve2dt$av5Ttoyv3{k7hyh6G$5NJqQ&Y4ka zeZOI}(*KF^RJm|S=}wzQXdHz+ty3wDan?)*xwDPbK+QP;&|h{&nIDVG4`mhnqkPem zRhO!geK3;Vz{$XsJI}X!z=cNL7Wbli{v>~@aOlJ- z-}{lipAh7S1{c6uG+#e0Iz-Jifr)8Mp3hVF=b6d%#$H$c2%~#`-BW|!aqrtm)@BlM zcChgdLd-!EU_E>4CK{Kcg%}T8U6F^!_8d;0BqDC6XKe)z&2p_Uv-^^`W;M`vifFh_ z+bn6v@V1uS?Yup+ly@VW7gug5luDDPc9m9AA~a_Oq2qD!W!>^5+kNsXQsMu8Yo)9X zXW!GrZ%@?qjjm$|)=|lEyDs%Q<(bBs3}Fkc1VNHb!~QOz1XwrSG6St ztkMZ~6GfxrPLPJ4L^DLA8yswuoU@iyb#XeR@@tJ#U7i9ei6?*7Q?}!p~5eb9J~76)vhX zEWv~n z>SY!b5*yB*9iyh|mFy(M=D8pdEotY-gEP!qLDhChYIm)*#lSa%r=7p5T~#Xd;>95K zn`{HdCLM%-p;(nRvh>kKFrBl@2YKg6?kLlN5*BQ$g59-lrpHY`{7@d1iQs=q;hoaO z4uTX^gFi;;c8%@|ZLh9ou7s=$qPS#Xmx@ec%Wo_C#8dxN3muSheW?Cm#OWF}zdd@D zvo}!mXBY&AK{NR;RW--^@gqsGX(9AdhWo*EkZda%;iJ2s5SEeSBq;6C3ln`a4Cf*M zr3Wk4gmQRVe{RwJ^0-N#z*jNk&Q=4*0i=&=N^}m&xv&|t6DYi9W}2Tc+zWGyHM1c) z+0q5)pt~d3gx?hzZ6#JWF&v8e=Ko<8^>I7(%cB+$V#0}xqCN*Sqt>VY3P5X%pD(=r z4y*c{e_=d6O>1+!#FN3XiXQ(5hYQ35%La&g) zG&;nTf*!nd7+OqVmyGz745zyqBR3}y^5LFNNu}XS$@cx|L<%z`E)W5x;8SyyntGp^ zI|J;`d2j?J*IM~{9c4K?{W3-;$(Q;|53L5utMvwMdkmdl5;39J3rQ}!{RB|~x`qZU ziSBxBZIVzQv&?)Qt$nJ*+wzIUFXipOSu+D|3012}uUtdq^d>o^NBJt@z?bp#!b!A8|Zr%hYjOJxQ=NZlw-o*8cD|f^9eI>ulPQFSG8%IWu}D zhlx6zJ#D&tO&vSYPX$t|WHC$vZwA>=wj`tI2N{K%-R4nc6DV85%&oP^pIFpYqCC5C zqytuaE*S$n{6)l;gJEUXko`C8CrPmy?Q6SXL8jvC3z(*zui@qMX7 z?^0=wXg%roxT)qiBX=Xdsq-wux7sn0h>VW@EGJ!e)mvmLds8!ZfOx|MVl28ObuZ8i zqUKJQ+C$aTOA%4OM_4Nte+?<6SC*IiqV2$d+Z!4WM{vvyvJgs&*YC%o8HY@DYYI4u zquy_6p%AaEuVS#liO;;By6Fy=aGrUqx!1{W68Rt%pnbl6E*j_RkkaxKJ|Vl$80KDO ztJ=bUT^Z&zV8I#BReHYx4(`>uP|JCf>v1$1c*;~poHA>Y@oI>LDyZ{%SsHVGB*#l~ zQ{OMkSP8?`H`o|G{(!JF9Ys#eImQ#nsX`u-Qr*YaFkUPmL-?x=7vjUur5Iz#a+73vkj5-Ns&2`09Zq`ZGA|3>& zn6n$i!;3Nb{z0Or9z{QNRRo``>*MFj*Z5I2@JkIzrGh^|b!@ddf-wzdps&veOh-$F z6Ow-ko>#4&fgi_^aXo5)l zW>Q$<#2CCPGR@Y{Cfh&at?2wNkVop`mXo*x`~d39&7P8 zkh4<^bj%@Lqr+q&o3fL%jWYv|S8!gl6t3A{HQXIb1}i!Nwb;5LUga32A&ET6FKXJL zu}VLO1z|k+baXbCD_1LUhcK{5F+}hzD8I&!TeIc?KSN^$FtUtKpBZbqHtt}GEpHc_ z^20WZJlTV~rIYFUaAkjV@bEOG83b2PY?VCE;E4VUCt6tFoHcML#|pINTO8#H`n;ILl42Mohd=FHC| zcfObbFsZ4K&DqlduMh>Cxx;Lxtpx1fA&ZK+!2S(9@}}2r>J?`iS~OEAlFUC}*wh_A zB`91;J7&kOOt=beU1N1q{6^+rN?Nv-!J@9_t9ww~tElWHiwzNOh_fB+&XGpKoDZiw z=H^QM?6cEDgUGD6+;@9}pEa5(Nh7f&du~^NPg=$ThTpKIKe4O@EyXw1WsRAs4XDgV zZ9JHmUhD{?Z7()1p4WoFzpW+2mSEZ2&b!qtfq?h>dXCoJQE1DzT!-!Vs$#Rcm@NB( zjnWcnF|hb!6@B`re`~k8R-e3oY93q4AIXMPpZfLFU0)N)piNMaPepi=3D&95r*|hCQVVaqNrphIB3?e9rlLgTY04Aea|5o)tf<0P$5y(%r`Q{ zZA$+ln+a12X-n+i7gmF=T&H0Y#z(d!Xhc~P!3IjnHgu>bRaoTTw_ZuIS3|pEi-*A4 z*Z(T4!h)nrS7c>tXxL0)- z5Y997*}ao(QeWBjSk%UP(n|#`_aJQ62L=*AEYHMKPtbZdmh`UzeL$157MiIvWGd8?(Pkr&0p{-Ef7D;tS5hCzRo47UVMyk+5f(hH8 zJKk=R+2J$19KRfP&3*!ykU3wT0x=*b#@`8B%OrWzRatMhNMCy%Sp{^GiTMPJYzs%d zC5B*L|N2t4HDG;h4yVKkBGQjW$G;$q)SP}38OC8AyqmosC=}K2;KX|Z@VpK$S}24& z&)f3d1QoeRkk2H@oQp)`Mu@j5yyblL%?&z5cvwzc$FL&&G18ys;-kne|QpVjiBJ{%RIy&rb2P`eG5!p**ygpNuz(ICoq1& zcM?Ep^A9z&ybnaODTn7jwvl;Pdl%bqur(sjzDY?OS2EOinLzfX znbr&|r93>Uplj&@xH2WnP=;zn+S+l6YZZ+n{nDQ=&#aMX;KhXUxniLVa>ZUnkuki; z<%3@%1Lvis^W28dr&h-gOPXjesE>!43CL=7)q`b>IubMgeEr6Xu68CA7Y8VpF8o+b z_#1Xd6zMOLo4Ws45GL{Xzb?%+#>?Y}$%io}is#pOPGDvNvdTbVBB(GsL%d>Y_e$OV(VQw zVPGf*zm$?Chg%`G*{m*x-!6kn2H=;B``kWA$)09ECWFHRc2{yTt^2uFlM5yA>=}** zott*XX55K@SMjkqThCaLbv7xz)5Ta9Ii7zej~>?OKc1#YOIQLW__?L7bzA+bf#t!q z{c#UWOM)d~$fG3)j6QLOv3_19gV5_zl7^{x1ND>_Ffx2{^hz?HYNnnYruF^}Z=#uq zL$vX-Ns8;=Nknekj>m3({B)k*rqmdYhjH*K2zBZQT81hu5L0j)qa+_U#mI;8~?wp|V31oN|tsp<0N3=MEKt zPNYt*C=fBpVmQhf6}@z;;$sRT@@;>x2`FwQ{CU}OPc@VlcGUz&q|)reJIym1 zeR{r1fG%B8v;QHGhJH-~Cc)jBwIo+L%^&xma5C9+F!tVa^MP@wQi%q0+GcD~p)D2LH)U;HV*)b}c_ z!ZJboYf0T1o@J;ajd2Xb52W>k8dg=vi2S_qI7YQ&$j63ogJFlKHGYgCS+jCR7G`@H z#eHRQR*KlORW~ssH(SC^A8D>)i+%AI00sT)cCOOMy4hAsn-r~vyrFl2%H9GoYHa}- z8+@#=^y+8a&M_~11w|&C>NAD0&XK-Z3+e~Gr9b1{M%$kY$qpL5f+HfPj3|O+IL#mK zb1P2q%$nOjM%t0gN{FNOY`YzK*7st1Osl2k8&pVw4xdJex@zbvXA>-f#~7{`AH4cWnC`Cku4~G5vDrs_YwB`1>JEv&_J5%}t3o5`su^sL7mte% zA95`M0+^WU!*V{|jqyJf_Fz>0P;y}jM_NA7GoWt&Y@X8pe7$s7Utp8V3(B|ftczRJ zZym+j2>IKsP9^%R^DqP zU6~L3hXB6?%5_O#0U6fso|iM-7uSDwL}0X2-%ox7(W#JWwYZ!$ z3q^yowx0&`q}sy+*#o_cz|~*jKPS20++2)qDXGGZRx4h+bm77J`q#xdxnrF3*mgS} zzD0JBKQhkN=#sP1+!aWPgIF!!5F;>Q&i~=>)~SXIo6~I^b))$bk0K&K>f&W-f_s~u$&Z4wey>pDe!M|d$Dy8Mt;uX8 z7#X*pWQV8-v+LD;89;B4t?A4EZSfr^Y4ZL8F)c=2{MJ7XJ9H^$dDyt#Mv-WNf%Nyr zUH0ug2cc*`Sa?i9gQ@0M;kx&H+5Sn$mhn*XnmEL^nJ-&RtGEg}ughzVvnLxkX=FNB zqk@wR=bTNJ{>KY%Ni}nzxT1qktr?nRlL)Dcomjm5Ozfc+0wtw;A+$zHQU4h{7(s*-FEZNq_4&DeM5dyjH=#%4(bLk zNA`_xU(5KO4g~4CL{o?eA(05*V z$f|`Tk2P_;Du!3wWi|8kJ*Zs%4Qgm4tUkE;$ce(^>g*Zz1fqEXi|)EYpkkMa+Djjk z2yVXz5{QXeX03(Kk#KDy<6cAKVS9@cJ@te`nL5Cr$iouGwMs~( zpt3AdaaB63;gkS_))Hq~J48#QQc><$74t@M!iJA;;D(t%2i+5ADCUiWV25}QRHU7| znvB#_oht2BKAjoY|7f0b|8PFKzY=8RZ@~;G2I^F6D+Y^req^8V=ID$@I^JVUFFRBc zmT2B8sy!wO`lAO!hf7aw{?z*HvL}<_EkF2HdkT^D3qxhIcsg;j9fj7f;N};o>Yi!I zB^v71Ro$HA0Po{P6fomRSr2$tz+m6$vN$)G+-YrMHe=s_>}o(sP{AnC5FTYTK# z01Ja9?Z|_g*C^^>$SOrZi!t9Bf`XBbqc=>yvhCkaFZ_=Iv8&fJQ;gI_o8=V5Py7^5 z3kyyJ;+QB8@dj-fZ}K-VmJ*-lJr~M#64#uKrC?8KvgHso^MPT0&MluSUiBbJl6-Wr zayiP`zciEgxOvzOc=`WA##b~p3@cF_fHaQgDSvD@KRI#mC(1*~!LG*pOm~y<-{&^b zrJ?GfV}{hlbOlC8kH6Hw2id|fPUH_{lB%Sd=i7UdBL7GaXHdMMC%lUK^xk@QA4w+l zL?V=Oi9qwRG1KD)!VPutjk;k8nlzEK^xC+WE5++NToB1pqcyIl^!v3HZe*i+J-n=p zLYG<1R3U`#9?(=YCZQ$6ZM>*%KjO*km(I#I>v+yzv6L6X%DyYR9c=cd%7lw*Cg;C^ z1W$#wvSC;Sx0sH5`!hE6h%O)(|5E!zk^0^sN>P$&i#OdUjm zwjU3WzXc&|aZ`@l4E__0IEgO|!R~dxBR8Nv48z5w=~ zKLHX}(!A<)2gVhs*92`sG$F(xW+!91ZsfLsB(3r!e0F&T1}(Di27c+@(_jo!V`BXAmZn6fWjs60;DhR%v?MROnvCLwT+wK&;Ah>)O;;HGUB>YbsA zAo@u=j&M#7)XpUK4rZIuQ9q%2TBpUhkN>tdbdk&%jf8_*YlQQxE9o+Vi4Eq~JxWB_ z)8`hBhom-=x0<@DWJECGmunp|3VrUBDNf?p#oW7=VcMPRSDb&E#qk{iQa`wV5jEtg z+Tc$Ug(#_QU#RICNlzqWe)DwVQZ|KThZPaz6n_E-)EcM7Dmbq4bhF=diYX8V%MA;@ zcl9Gmum`RH(Fe7>_-j$r_Pyb3*A@w4CwfNQvSrcmmv*q6@(4b4s zI6+&@(22M(;p-SRW*-F2pjjTM#xoFyd#uatWBb~J&8;4?7(C*`N$Bse zIm5_9CjJ*U)o0<vOsYnu=$kgQIy-CwM?jM zx9Fqf61NJMaekKVH(O$zc2@7*XyPUIl<ihl|Gb=UcIuIgiYy#fGO^8bfv|+=py{!R4JOB3~B%-AD%zd=%iO zNezF*j$mq_gBu}EW}821+-HQ2!I2cpKwY;WABm$Nuo?9$4@3)T-(6|6P_TFUWl}ZZ z7!AwP(1RHsgb>FS)m9^5?tv`mfZ(-a!oV){o*Ea~(~q!(CyPxgR z3!?w<^rSrhB$!_l5_W9`d{}%de7!xVVCB;!-Yd%j?&~|qSeGrsK{aBQGM^CzhNd;XyAsoCkR#2blIqQPa^2F(H1|bU4o;5`BztM79X>_Ut%YxaN5}jpi9| ziZKv4Q$uZ^7V8a~fobj;AzZi-A^z;%dlG=;l##E74D+S*!!@c&!Mj|T0eYkiYG){3 zBqYGnIgE8?ZM9Lw&~9;~s-wihBs)$F&zkK>yvtrvcN91c^nj$&tEMvMuZn4GDx&>P zxv*1Hk{Vu66SqdIN&_`@^n47Z2ui0rxxl|`_v=YQd&v9oU;0V^2r`h*F>xpx8H!Sn zDK|Z_W+VX-*1O+qv)dC)+(tZY+`gQXsQUf3#cB3pJFQ`5928Dr1vbi>68ke^G!$Kp z^%-DTvHzwDOaT$6q8Vt8jPfDMdf`6$Fs9p(ncr5A6AnO!1#*I}g}`6w(Z-?&aRvKa zelz~efPYWf{MF_v#W~2`HTB-x5;ZTMG=qoM3&Q>5fWz+{0K+3oVE;COS)8m+Z|nQ4 zqu~ByDLX%k#L8VP*MOd>{x;v^$^J%cY{OVbOe1E7IR!Y7QXWE$$P?N?dnUGE5Kdfz zJUv~sbS|07Q5qnofK_x5TzH)!A++&(R=emv2?^ll*U!w37iH!LBgBP+@C*q8GUG*> zsFKWBiRaeiL|Ioc+m+^YHltZ#WJLlwwDZ|X+f;3Kp67l;*7F!3-K@FwsGQ!#k) z-%fOqN&&?*{nG363UQ?(R)VZ5ZU;?OT#&Q2;LFLlx+#4up((sz<{S@oG$oGxe{mCY zHj8#}dZBLb8;V=#Iv*raWKUvh@7V1_3?aw{JzxNL}8J+G5 z5;RZh^d^^?wsa%8^^_|`T$>^!?jE)o-)q!=V7&f5N$?mw62f@60lsy4Mxa%JO&R4bFRW0c`6 zocm2bUc@Gm5a_w6bJPzVJ2xnn+IoN)e6;#3GoM7`1zJ8?d5nsKPA<_h!>F2i990p8 zO#Ia~6^A#XAkSLXek%)k?u>MKThKZ9pR@-7h2<1Q=pc%RVSci0prM? z&%J@6dU|y2RylGP-M8gjgEb)4-TqAY%O%AwCL?&>bU|2-}Fy`I75MJ(y0 zrOI9_Dtkl^Zq*tE*#e5?G5gaoOP0E{D>j;Fcn7+Mtn^mxjVFk1;td#u{C%q$1MAHx zgHpNgBJOyw8P|Q2c?1U->Iz)zp60DVK{l7T|2^2GL*nU$#%WwmCh$)2X$MQKBffbs zm*EW@1sv}u#B+30gY;4zzaKR4fqHn+kZ-zWd*k(HK=60|4ez2qI9QbR4-E1+4vbR@ zNYB}NImx7ej#&s|Xf5S==u*!Xa;@9-Hhys*;$oC%EQ7 z>de>loABlM&-k5vaSWCFF<2U555|U?BfdFO)MGanTcO1PZ#EF1vgtk*VCC}=31~{W z6Q;;BDLmsnR+VX%Tb*i3d((OMSuhj%)Pc;U+X$}a78ZICk>05{9@A{b%icN>)c7~f zhyLuqTivRew-BN7c=3*3V$m&%b=l~#wm`ocfQ#=-e)5GrJj>wkbXh$V?NInU_S6z^P|1U_&YC}>?1r< z<54W5f39-j)C`$Mb84H8H=@*CUcZtkZGZmMAI2)IYOo;p%v^Q$lsL4>;pM|DTnWwA zlbE^eKkxwW>2s92n38^ql`_SWiuMo88GetVCu*i>_&BB+VF=1HwNYe*IW@vM_7RQ! z0x@izHWjIv+Pfx$FK1UKVMnzIXJ^01&xl#(HETc3^l6Z@zqpx1rA7#c_u6D-0+;u= zmpjeFgG|e-$Y>sZBYB8$cA*a^Z`UmPoNbvzB$t3C%bdGo*6UN*<${GSe(oGv5sR1x zniH6WMQbYaAc(ZrPuEG;aWQGDc2cwCBrRl~PW@ zUKijI$2m7r-B1R(3q;C$h!k?GYm$%}L^T9GWDPKblsY4WG!Vm}r;g|wq!7~~I&GBT zWK3`z6e`%O`&fS0QMxD|#R)&$hezti6|*83B}2ShQA zx%;d^UH0av?I;s55_`}e>Jwa$ugAN`ngYTGCtPJ;x#KqZv`6ZD$R$k)8pTcL_+opx z6{H|3McDD0{hYd{R0VuJJ5YLo!*{!DSd1c}$24pZl*IRO!de<4dtl+8_8Jmdbz60? zOJg?6rhyXqubzn(hV(_-+OCPwb}JuupbOM91->J^#79USf}L`n%-y$5oA)%ZzX8IR zVvZJa-MKJ1w=ucb_JZjfXdlaX9+Z@8?5hdcT9O1VeT=tbNzt zrToM-gg9N9iagiyx|D_MHoydF%ES+7({4fvYLZolFqrj0Xee?v)}qwKYb@l6Z?h(5 z7j_*Z-$iI1!_tWbJNA26)}X)BumcJN3fdwDygn?wNj9)oK~v0|RN(EgAulT5x8*~N z8FRKBNP`DGUJ5b-XoRxc4^lpuaz^8@xUy}wT7;eL$lJ>XEtt4n;V1QLNq^Rtx-X$9WD@_xqw{@zScR$ z?{5#O@nbcnYI-kRYhawT6EY}pqB2Fk$qCn1jdc|vXff}36L1%84{4A;l#Z4su33KD z57v?51|9j}C1h-Vsx#Sx7SjmRJB>=_NZKqHI3Z~OLH1~_wn?3DOum>`u1<&+Sl7`m z3CKl9Gl+=A0(%aglyK_kssJk6bBiVegKLXRDV&%u&r4KQ%a0R-KYBr0J6w0%0Ft?~ zL1*2WDrv!SYX#$+S&63PI`VJJUovkMlv*0qp1;CJBDt@!cmLkv6wiwf2T${<&rm`b z!b|RsnFi)gK3m{=4X_V1aJ0kK8?QQ0jqBT11(4lu3q9yfDwR$A`2|R$D5AE|!u*uB ztnMcJA=|ZoF=XWFloGCgukUkHb1KL6j1%N0}Z0<|8VkaoAA+;O!&T5!$bGo?!AVsU@K zT)@3vqtA%9&<&SL3IqY`IZMFvbx=I01EoNjtjdZ0Ky^Z7N0IUEBfc@4AD#c#M!&8P z4}m)!sEhXBSBNq2a2$W)aa;!ly#t|?@LwjHS0i0TW`a|{&~E|%Z5nP2UzFhhr&z(2 zXuR0Pj}|{#*a8L11IkRr{OB7Ly>pLnXqP5*tLgIu4X(3M_{C(^uTh1UX)MwGdSQvy zMm?%tGFc%ZBUBnV+f@f%XKAqC#1%##Ki>&$A^Zi#YStZP;ax(Q)uwMH4o6}r<&VPm zUPT`WxWfimBL+r+Z@WWUHIDZ z6Y`NzDJ5}Ga7YJ6=3x2glXAAx;W@xWP<=;&0z*e8T&|NVz3Z>B8r#I3XJYn z^{U+v&D3w^a=Hq5%{NzWZIeW{sIO_PFxQj|pkgk~Dy&BBtm2`@<3mB}@DGbOXYDBRK+2 z8g1Xcz}97QVjIjhzI$Pd+kp75e8lB?K8Pv~?fdKtUO`vzt}|=sxS}5*dD?aYjBBd2s5}yM23@cG=pQ$#pW;%4Evgax8@ZqrDhswVT?6z6ILS1AXzMe=Wwv zTk?xC`+5tpC~rJ!?^7C{;7^R$)01y(CJWRrqdJq_Ex+{{GmDg4kY!GS7ZEyCe}B#R<{XWe;J|GJl!Wb7}_oH2T9_!4~dkk40<{&`BN{`3Q)6y~C0vNF7OHZ0z8Y&-a<9g7?1 zSs;}ClYq^EkXUQ#)f`3>Gez0F%bN7d`3P+E;*Y9Hev%^7!_T79o13Yuun&e#3R(bs zzTdZ~bcZ$4yd*|ZCF<@l;4i-mlifRw^}{nK0SQ{5A&43D05jrV!jEM|nyUNC(N}J4 z$p*SNOk~^5kWp~?l#S=s;<5eZixai>!0&tw_SmVLv!cj9ofLNSPT$xW>817Jh&J|E zU~T%h0@|Q(fr+u77hyVYepKqK6DGjes_F6jGOfUG>J>Si+M2-jnPw>zA^$Le=vREB zf>m_qHSA+Nc-`+YFA%F|Gx-Jev3QwoBIN?;g!esP07v~yq&L6&mkZAkZ6J#dmf}VX zbHF{Uv|tj+Q^;wzVgrY4A^B8PIC}XEjZqf2PpLq?@mKW8AswrmQ;N^`&w59lFD*H3Xh?9d$H5vk^{?7>-cIi!%7rA zVex7A8xnsmfvsT{BffCEbSBq+#8OSwlmF~XzDlRGdIiswxorxLC1h`GpC`Zf#cz_alMxB1 zO3|yWL$x^b!UNofP68tMBJ_X=!64)TWm$+$$l>>p%@DTiZwfyg4iK`P@L058%I!#y z_`PebJcl_m6!1;e(onP3u`ojpG_JX=1J{vSP{11uhGU>f7Se}V?6arHkdE(2opH*b zI?su@yXPW@N|qu<8;%1G8KjWr1;#k+2j#Pe*}frBBjNM(TS2tM&gB7!?Oqws5V{NW z_E0iHNGCQJc;_FBdB1X^o3fgAAIlUk%EQ|Qx;bv8U=Q9hii%D%e1(i*KKn(LD#Q#( z%b$k=hKh-%RoTsP=WkA^M7VLS$`%v5Jpw-PoHE~%>H%&%1+XA4J{#sMQZ1;5Mi1_> zGF&sEYY3WGaHInm+<73x%zA((dw{DwjMH@=%HaUX*E2*Aff(eG6+!Id9kZWVcbGYd zCFBO3k~#F-^q>w1s`v|EI1ZY0kkJ4_;>|Zz=`m*%;Wxe@$d4c^&p;rE`%SHD2M(3a zO#q>*_4atGE26vabVo3o^k*5@GW*Pocqio@wb|+*%40Qud@_LLnOsIk_{~g$5Se;! zyx79Q?2ay*nse^w9DI976l+RTjy?<3}h*vQq3g`gyq*o%+E zUE*E`5pJqb{6>H#sVZHwzB;qZbF_%&1^9q3Oe6S#%H znY{NCq#}{ISSq*(gjC-7dDN5&2B0;%V7sl?SsuE=vu&^uG+x9Pv@QBH#DBFxTOgt? zf0DBP+@PzGBzA+M>IHApo28krH-~-}m~yc&S%`GcxHw(;RBLFl^aZ39 zt`)|u^+>)~zXurZWjoZV1X)r{-Z2lt6BMQ{{kcFYG|31&0_lrhs2l60f8f)L0MjlX6!-_T(5rwrr zZORXN4F6&`f$E-1Ip65gp|t3Vv~BVCT%6;WY?%Qe3}z767li14Jz~_;RCY8-ZGJ;B zM^K{2L>to_N6Yjdr_Sqt~wwX0ds!^sj{g$%bKk-~y@zTAP zlhE}~gI@{5a^t^{3U=ZYbvkguA>R5VCfUoV!qO|yHA58Jre?f%P9g8WU!pyvWYqfR z5?v0&y42E!%L*ERHAal%FV0GT(}0_DUGlHc%^#GZD3Mh%;8DM0YI4u$qiuFompdr&f?|;xh|Lg6dFEbn1TRQBc5NqdVE@aCCmsm|3|2s25>@Ti&Kus(GOn zU5qP%d4&tVpB_}Md@Q%O_Y2x32W5|2gvJ2i)}hXclP{#xocmdMIm+iaPS{9`&OttZ z8D_3H?t2cmhPKez_jaufl53_eb#<^;H@UGNV?8>@($bI@+qGJ*7NhK$thRphjLp2Y zW@(+&IN;fPTvv1qbZWHbdSq|%92)u^YL#)tCaHZAh;hX>dUcWd?0QX};szA;7^MKv zqU!_S}< zZ!84}ky_d=ZK7yCf$AHCX(T+Dsh$Ou9Xto?|C*ocEu;-06Pqv>{X?oQ>EseZbi&M+ zY7TnRVyYb8CKJ}**=F6JNcAm{HGwd7SjQ<^;mI{yJEoGx#v>-N%8<6>?-mm~|7O*2 z?FeVFH;luJUD};bQX)ZiyVfLH^H8~CEDt^i&a`bLb zW@Qs8585V=B3r+rd<(I~#MjnyEY~JccDN&Ey$aXNhF6d}W@npxaGPsG#DOy21wAFw z#%R-%jfxBw2i^^p(?eBQTPrC?54?;xcJxG62BwzAiwyo{m%T=ln(yNP%CWuqrm3>k zSlfwJah^!<;g-(9AU^^`x(oX$$Z;_+s!%}?93!frAE z(9&BvbT|tK^B=A*7AE#^7HRT7pkYAS(>nH`NdXQ6I3_h4Zwq2pW)3(eEn+R za*MKZa58f<3ljhTTMQ8YFC3YJn}zs)ZfA-mIq75-9H{+20)O>CYL+PpW~M2#&P;7> zuxr?_SS>9}H7ylNOHf2m&=y8DOA;U$WOX50V9-RVt*y~TreJl&TVS?vF`Hq6zNgH* z&;CB}>H9JJoCh#kT1GSTb6EWj#+iouwxpseIw`{f77MSdJ>o~`T)+E%&OjAv4hdif zk%L_Hl}?zT1(moY!Q=QPLgU$LIa1J2Na$;e-kGFjL(!ATnP}Oy@Q6-ILt?+^_knN< zR?T$(OKfCKYb}S8*85QKPEFX%9Cp2q)Q@!r&V|3LtT&aDG99H2EE@2(W~w+EBKf@Q z>n&FW^Z>=}Vd{guAFGj4ssWVGl$k_{<)AK3cn8 zih&$9rf?zdxeV+ws_R6c{)L=eva^Y)WQ2GmpvG-n!ivXrSpQD|fdGF02+tmB@;P|5H&qS6>&~be zhIhF|)p>ZgdsJP3H~&-B2m;CPy0{_yM=ov%Oy5xi0{@0pIRsNRsyqZI>Qn^~d{wS0 zh~Rv+st`i0pHzhrnoFt5LwIyl75`=FD#9OJI!+P@XJXmsei*m^KXY~Ym)zn99t$!t MGBgS$B}Gq03NUA}ivR!s diff --git a/documentation/UserManual/ReactPhysics3D-UserManual.tex b/documentation/UserManual/ReactPhysics3D-UserManual.tex index 79ceb22c..ddf4c830 100644 --- a/documentation/UserManual/ReactPhysics3D-UserManual.tex +++ b/documentation/UserManual/ReactPhysics3D-UserManual.tex @@ -314,12 +314,8 @@ world.destroyCollisionBody(body); \subsection{Creating the Dynamics World} The first thing you have to do when you want to simulate the dynamics of rigid bodies in time is to create an instance - of the \texttt{DynamicsWorld}. You need to specify two parameters when constructing the world. The first one is the gravity acceleration vector (in $m / s^2$) in the - world and - the second one is the simulation time step (in seconds). Note that gravity is activated by default when you create the world. The time step is the fixed amount of time - used at each internal - physics tick. Note that multiple internal physics ticks can be taken at each frame. For real-time applications, a time step of $\frac{1}{60}$ seconds (60 Hz) is usually - used. Using a smaller time step makes the simulation more precise but also more expensive to compute. \\ + of the \texttt{DynamicsWorld}. You need to specify the gravity acceleration vector (in $m / s^2$) in the world as parameter. Note that gravity is + activated by default when you create the world. \\ Here is how to create the Dynamics World: \\ @@ -327,11 +323,8 @@ world.destroyCollisionBody(body); // Gravity vector rp3d::Vector3 gravity(0.0, -9.81, 0.0); -// Time step (in seconds) -rp3d::decimal timeStep = 1.0 / 60.0; - // Create the dynamics world -rp3d::DynamicsWorld world(gravity, timeStep); +rp3d::DynamicsWorld world(gravity); \end{lstlisting} \subsection{Customizing the Dynamics World} @@ -387,33 +380,58 @@ world.enableSleeping(false); \subsection{Updating the Dynamics World} - The first thing you have to do to simulate the dynamics of your world is to start the simulation using the following method: \\ + The \texttt{DynamicsWorld} is used to simulate physics through time. It has to be updated each time you want to simulate a step forward in time. Most of the time, + you want to update the world right before rendering a new frame in a real-time application. \\ + + To update the physics world, you need to use the \texttt{DynamicsWorld::update()} method. This method will perform collision detection and update the + position and orientation of the bodies and joints. After updating the world, you will be able to get the new position and orientation of your bodies for the next + frame to render. This method requires a \emph{timeStep} parameter. This is the amount of time you want to advance the physics simulation (in seconds). \\ + + The smaller the time step you pick, the more precise the simulation will be but it can also be more expensive to compute. For a real-time application, you + probably want a time step of at most $\frac{1}{60}$ seconds to + have at least a 60 Hz framerate. Most of the time, physics engines prefer to work with a constant time step. It means that you should always call + the \texttt{DynamicsWorld::update()} method with the same time step parameter. You do not want to use the time between two frames as your time step because it will + not be constant. \\ + + You can use the following technique. First, you choose a constant time step for the physics. Let say the time step is $\frac{1}{60}$ seconds. Then, at each frame, + you compute the time difference between the current frame and the previous one and you accumulate this difference in a variable called \emph{accumulator}. The accumulator + is initialized to zero at the beginning of your application and is updated at each frame. The idea is to divide the time in the accumulator in several constant time steps. + For instance, if your accumulator contains $0.145$ seconds, it means that we can take $8$ physics steps of $\frac{1}{60}$ seconds during the current frame. Note that + $0.012$ seconds will remain in the accumulator and will probably be used in the next frame. As you can see, multiple physics steps can be taken at each frame. It is + important to understand that each call to the \texttt{DynamicsWorld::update()} method is done using a constant time step that is not varying with the framerate. \\ + + Here is what the code looks like at each frame: \\ \begin{lstlisting} -// Start the simulation -world.start(); + +// Constant physics time step +const float timeStep = 1.0 / 60.0; + +// Get the current system time +long double currentFrameTime = getCurrentSystemTime(); + +// Compute the time difference between the two frames +long double deltaTime = currentFrameTime - previousFrameTime; + +// Update the previous time +previousFrameTime = currentFrameTime; + +// Add the time difference in the accumulator +accumulator += mDeltaTime; + +// While there is enough accumulated time to take +// one or several physics steps +while (accumulator >= timeStep) { + + // Update the Dynamics world with a constant time step + dynamicsWorld->update(timeStep); + + // Decrease the accumulated time + accumulator -= timeStep; +} + \end{lstlisting} - - \vspace{0.6cm} - - Then, each time you have to compute the next frame to render in your application, you need to update the state of the world. To do that, you simply need to call this method: \\ - - \begin{lstlisting} -// Update the world by taking a simulation step -world.update(); - \end{lstlisting} - - \vspace{0.6cm} - - When the \texttt{DynamicsWorld::update()} method is called, collision detection is performed and the position and orientation of the bodies are updated accordingly. - After updating the world, you will be able to get the updated position and orientation of the bodies for the next frame. Make sure that you call - the \texttt{DynamicsWorld::start()} method before calling the \texttt{DynamicsWorld::update()} method. \\ - - You can also use the \texttt{DynamicsWorld::stop()} method to stop the simulation. You will then be able to start it again and continue updating it. \\ - - Note that you can get the elapsed time (in seconds) from the beginning of the physics simulation using the \texttt{DynamicsWorld::getPhysicsTime()} method. - This can be useful to - create some animations. + \subsection{Destroying the Dynamics World} From 1bde11f245806de07a12b1cf6c33cdb83046b882 Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Thu, 13 Aug 2015 19:47:29 +0200 Subject: [PATCH 36/36] Fix compilation errors on Visual Studio --- testbed/CMakeLists.txt | 2 +- testbed/common/Cone.cpp | 2 +- testbed/common/ConvexMesh.cpp | 2 +- testbed/common/Cylinder.cpp | 2 +- testbed/common/Dumbbell.cpp | 2 +- testbed/common/VisualContactPoint.cpp | 2 +- testbed/opengl-framework/src/maths/Matrix4.h | 3 ++- testbed/scenes/raycast/RaycastScene.cpp | 4 ++-- 8 files changed, 10 insertions(+), 9 deletions(-) diff --git a/testbed/CMakeLists.txt b/testbed/CMakeLists.txt index 4d3ecdac..cd66c695 100644 --- a/testbed/CMakeLists.txt +++ b/testbed/CMakeLists.txt @@ -28,7 +28,7 @@ SET(CMAKE_CXX_FLAGS "-std=c++0x") #ADD_DEFINITIONS(-DGL3) # Headers -INCLUDE_DIRECTORIES("src/" "opengl-framework/src/" "glfw/include/" "common/" "scenes/" "imgui/") +INCLUDE_DIRECTORIES(${GLEW_INCLUDE_PATH} "src/" "opengl-framework/src/" "glfw/include/" "common/" "scenes/" "imgui/") # Testbed source files SET(TESTBED_SOURCES diff --git a/testbed/common/Cone.cpp b/testbed/common/Cone.cpp index 6657ed9d..079a6189 100644 --- a/testbed/common/Cone.cpp +++ b/testbed/common/Cone.cpp @@ -236,7 +236,7 @@ void Cone::createVBOAndVAO() { // Create th VBO for the indices data mVBOIndices.create(); mVBOIndices.bind(); - size_t sizeIndices = mIndices[0].size() * sizeof(uint); + size_t sizeIndices = mIndices[0].size() * sizeof(unsigned int); mVBOIndices.copyDataIntoVBO(sizeIndices, getIndicesPointer(), GL_STATIC_DRAW); mVBOIndices.unbind(); diff --git a/testbed/common/ConvexMesh.cpp b/testbed/common/ConvexMesh.cpp index cd766e5a..182c5940 100644 --- a/testbed/common/ConvexMesh.cpp +++ b/testbed/common/ConvexMesh.cpp @@ -260,7 +260,7 @@ void ConvexMesh::createVBOAndVAO() { // Create th VBO for the indices data mVBOIndices.create(); mVBOIndices.bind(); - size_t sizeIndices = mIndices[0].size() * sizeof(uint); + size_t sizeIndices = mIndices[0].size() * sizeof(unsigned int); mVBOIndices.copyDataIntoVBO(sizeIndices, getIndicesPointer(), GL_STATIC_DRAW); mVBOIndices.unbind(); diff --git a/testbed/common/Cylinder.cpp b/testbed/common/Cylinder.cpp index 2aa45923..bfc39092 100644 --- a/testbed/common/Cylinder.cpp +++ b/testbed/common/Cylinder.cpp @@ -237,7 +237,7 @@ void Cylinder::createVBOAndVAO() { // Create th VBO for the indices data mVBOIndices.create(); mVBOIndices.bind(); - size_t sizeIndices = mIndices[0].size() * sizeof(uint); + size_t sizeIndices = mIndices[0].size() * sizeof(unsigned int); mVBOIndices.copyDataIntoVBO(sizeIndices, getIndicesPointer(), GL_STATIC_DRAW); mVBOIndices.unbind(); diff --git a/testbed/common/Dumbbell.cpp b/testbed/common/Dumbbell.cpp index 630630ee..12bf37e7 100644 --- a/testbed/common/Dumbbell.cpp +++ b/testbed/common/Dumbbell.cpp @@ -273,7 +273,7 @@ void Dumbbell::createVBOAndVAO() { // Create th VBO for the indices data mVBOIndices.create(); mVBOIndices.bind(); - size_t sizeIndices = mIndices[0].size() * sizeof(uint); + size_t sizeIndices = mIndices[0].size() * sizeof(unsigned int); mVBOIndices.copyDataIntoVBO(sizeIndices, getIndicesPointer(), GL_STATIC_DRAW); mVBOIndices.unbind(); diff --git a/testbed/common/VisualContactPoint.cpp b/testbed/common/VisualContactPoint.cpp index b0d5351d..0014a980 100644 --- a/testbed/common/VisualContactPoint.cpp +++ b/testbed/common/VisualContactPoint.cpp @@ -161,7 +161,7 @@ void VisualContactPoint::createVBOAndVAO() { // Create th VBO for the indices data mVBOIndices.create(); mVBOIndices.bind(); - size_t sizeIndices = mMesh.getIndices(0).size() * sizeof(uint); + size_t sizeIndices = mMesh.getIndices(0).size() * sizeof(unsigned int); mVBOIndices.copyDataIntoVBO(sizeIndices, mMesh.getIndicesPointer(), GL_STATIC_DRAW); mVBOIndices.unbind(); diff --git a/testbed/opengl-framework/src/maths/Matrix4.h b/testbed/opengl-framework/src/maths/Matrix4.h index 9463b15b..1a504c38 100644 --- a/testbed/opengl-framework/src/maths/Matrix4.h +++ b/testbed/opengl-framework/src/maths/Matrix4.h @@ -33,6 +33,7 @@ #include "Vector3.h" #include "Vector4.h" #include "Matrix3.h" +#include "definitions.h" namespace openglframework { @@ -441,7 +442,7 @@ inline Matrix4 Matrix4::perspectiveProjectionMatrix(float near, float far, int w // Compute the aspect ratio float aspect = float(width) / float(height); - float top = near * tan((fieldOfView / 2.0f) * (float(M_PI) / 180.0f)); + float top = near * tan((fieldOfView / 2.0f) * (float(PI) / 180.0f)); float bottom = -top; float left = bottom * aspect; float right = top * aspect; diff --git a/testbed/scenes/raycast/RaycastScene.cpp b/testbed/scenes/raycast/RaycastScene.cpp index c437df5b..b2760012 100644 --- a/testbed/scenes/raycast/RaycastScene.cpp +++ b/testbed/scenes/raycast/RaycastScene.cpp @@ -139,8 +139,8 @@ void RaycastScene::createLines() { for (int i=0; i

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 diff --git a/documentation/UserManual/ReactPhysics3D-UserManual.tex b/documentation/UserManual/ReactPhysics3D-UserManual.tex index 2205e678..79ceb22c 100644 --- a/documentation/UserManual/ReactPhysics3D-UserManual.tex +++ b/documentation/UserManual/ReactPhysics3D-UserManual.tex @@ -228,7 +228,10 @@ rp3d::CollisionWorld world; Do not forget to destroy the \texttt{CollisionWorld} instance at the end of your program in order to release the allocated memory. If the object has been created statically, it will be destroyed automatically at the end of the scope in which it has been created. If the object has been created dynamically (using the \texttt{new} - operator), you need to destroy it with the \texttt{delete} operator. + operator), you need to destroy it with the \texttt{delete} operator. \\ + + When the \texttt{CollisionWorld} is destroyed, all the bodies that have been added into it and that have not been destroyed already will be destroyed. + Therefore, the pointers to the bodies of the world will become invalid after the existence of their \texttt{CollisionWorld}. \section{Collision Bodies} @@ -414,9 +417,12 @@ world.update(); \subsection{Destroying the Dynamics World} - Do not forget to destroy the \texttt{DynamicsWorld} instance at the end of your program in order to release the allocated memory. If the object has been created statically, it will - automatically be destroyed at the end of the scope in which it has been created. If the object has been created dynamically (using the \texttt{new} operator), you need to destroy - it with the \texttt{delete} operator. + Do not forget to destroy the \texttt{DynamicsWorld} instance at the end of your program in order to release the allocated memory. If the object has been created + statically, it will automatically be destroyed at the end of the scope in which it has been created. If the object has been created dynamically (using the + \texttt{new} operator), you need to destroy it with the \texttt{delete} operator. \\ + + When the \texttt{DynamicsWorld} is destroyed, all the bodies and joints that have been added into it and that have not been destroyed already will be destroyed. + Therefore, the pointers to the bodies and joints of the world will become invalid after the existence of their \texttt{DynamicsWorld}. \section{Rigid Bodies} \label{sec:rigidbody} @@ -1472,8 +1478,91 @@ bool isHit = proxyShape->raycast(ray, raycastInfo); In this example, you will see how to use the ray casting methods of the library. Several rays are thrown against the different collision shapes. It is possible to switch from a collision shape to another using the space key. - \section{Receiving Feedback} + \section{Retrieving contacts} + There are several ways to get the contacts information (contact point, normal, penetration depth, \dots) from the \texttt{DynamicsWorld}. \\ + + \subsection{Contacts of a given rigid body} + + If you are interested to retrieve all the contacts of a single rigid body, you can use the \texttt{RigidBody::getContactManifoldsList()} method. This method will + return a linked list with all the current contact manifolds of the body. A contact manifold can contains several contact points. \\ + + Here is an example showing how to get the contact points of a given rigid body: \\ + + \begin{lstlisting} +const ContactManifoldListElement* listElem; + +// Get the head of the linked list of contact manifolds of the body +listElem = rigidbody->getContactManifoldsList(); + +// For each contact manifold of the body +for (; listElem != NULL; listElem = listElem->next) { + ContactManifold* manifold = listElem->contactManifold; + + // For each contact point of the manifold + for (int i=0; igetNbContactPoints(); i++) { + + // Get the contact point + ContactPoint* point = manifold->getContactPoint(i); + + // Get the world-space contact point on body 1 + Vector3 pos = point->getWorldPointOnBody1(); + + // Get the world-space contact normal + Vector3 normal = point->getNormal(); + } +} + \end{lstlisting} + + \vspace{0.6cm} + + Note that this technique to retrieve the contacts, if you use it between the \texttt{DynamicsWorld::update()} calls, will only give you the contacts are the end of + each frame. You will probably miss several contacts that have occured in the physics internal sub-steps. In section \ref{sec:receiving_feedback}, you will + see how to get all the contact occuring in the physis sub-steps of the engine. Also note that a contact manifold contains some persistent contact points that + have may have been there for several frames. + + \subsection{All the contacts of the world} + + If you want to retrieve all the contacts of any rigid body in the world, you can use the \texttt{DynamicsWorld::getContactsList()} method. This method will + a \texttt{std::vector} with the list of all the current contact manifolds of the world. A contact manifold may contain several contact points. \\ + + The following example shows how to get all the contacts of the world using this method: \\ + + \begin{lstlisting} +std::vector manifolds; + +// Get all the contacts of the world +manifolds = dynamicsWorld->getContactsList(); +std::vector::iterator it; + +// For each contact manifold of the body +for (it = manifolds.begin(); it != manifolds.end(); ++it) { + ContactManifold* manifold = *it; + + // For each contact point of the manifold + for (int i=0; igetNbContactPoints(); i++) { + + // Get the contact point + ContactPoint* point = manifold->getContactPoint(i); + + // Get the world-space contact point on body 1 + Vector3 pos = point->getWorldPointOnBody1(); + + // Get the world-space contact normal + Vector3 normal = point->getNormal(); + } +} + \end{lstlisting} + + \vspace{0.6cm} + + Note that this technique to retrieve the contacts, if you use it between the \texttt{DynamicsWorld::update()} calls, will only give you the contacts are the end of + each frame. You will probably miss several contacts that have occured in the physics internal sub-steps. In section \ref{sec:receiving_feedback}, you will + see how to get all the contact occuring in the physis sub-steps of the engine. Also note that a contact manifold contains some persistent contact points that + have may have been there for several frames. + + \section{Receiving Feedback} + \label{sec:receiving_feedback} Sometimes, you want to receive notifications from the physics engine when a given event happens. The \texttt{EventListener} class can be used for that purpose. In order to use it, you need to create a new class that inherits from the \texttt{EventListener} class and overrides some methods that will be called by the ReactPhysics3D library when some events occur. You also need to register your class in the physics world using the \texttt{DynamicsWorld::setEventListener()} as in the following code: \\ From 345afc1a1dc61e42b0a93dcf1e3696b1a84d6ec0 Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Thu, 13 Aug 2015 07:19:15 +0200 Subject: [PATCH 34/36] Destroy bodies and joints in the destructor of CollisionWorld and DynamicsWorld --- src/engine/CollisionWorld.cpp | 9 +++++++++ src/engine/DynamicsWorld.cpp | 19 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/engine/CollisionWorld.cpp b/src/engine/CollisionWorld.cpp index c129c92a..41b8bf8b 100644 --- a/src/engine/CollisionWorld.cpp +++ b/src/engine/CollisionWorld.cpp @@ -40,6 +40,15 @@ CollisionWorld::CollisionWorld() // Destructor CollisionWorld::~CollisionWorld() { + + // Destroy all the collision bodies that have not been removed + std::set::iterator itBodies; + for (itBodies = mBodies.begin(); itBodies != mBodies.end(); ) { + std::set::iterator itToRemove = itBodies; + ++itBodies; + destroyCollisionBody(*itToRemove); + } + assert(mCollisionShapes.empty()); assert(mBodies.empty()); } diff --git a/src/engine/DynamicsWorld.cpp b/src/engine/DynamicsWorld.cpp index 7fe62461..f6594a08 100644 --- a/src/engine/DynamicsWorld.cpp +++ b/src/engine/DynamicsWorld.cpp @@ -59,6 +59,22 @@ DynamicsWorld::DynamicsWorld(const Vector3 &gravity) // Destructor DynamicsWorld::~DynamicsWorld() { + // Destroy all the joints that have not been removed + std::set::iterator itJoints; + for (itJoints = mJoints.begin(); itJoints != mJoints.end();) { + std::set::iterator itToRemove = itJoints; + ++itJoints; + destroyJoint(*itToRemove); + } + + // Destroy all the rigid bodies that have not been removed + std::set::iterator itRigidBodies; + for (itRigidBodies = mRigidBodies.begin(); itRigidBodies != mRigidBodies.end();) { + std::set::iterator itToRemove = itRigidBodies; + ++itRigidBodies; + destroyRigidBody(*itToRemove); + } + // Release the memory allocated for the islands for (uint i=0; i Date: Thu, 13 Aug 2015 19:12:51 +0200 Subject: [PATCH 35/36] Update documentation --- .../UserManual/ReactPhysics3D-UserManual.pdf | Bin 512961 -> 516869 bytes .../UserManual/ReactPhysics3D-UserManual.tex | 86 +++++++++++------- 2 files changed, 52 insertions(+), 34 deletions(-) diff --git a/documentation/UserManual/ReactPhysics3D-UserManual.pdf b/documentation/UserManual/ReactPhysics3D-UserManual.pdf index 10f744a2c90c2876edcda5068fde2f31b8003648..ad935b3fcf22a3787e123cf521b7b508dda59ee6 100644 GIT binary patch delta 136973 zcmZTvQ+(J#vke=ov28nPtj11b+islvW81dfB#mv`wr%J3`+fI5-M4+(Jv(#e%q*s- zgfM83FqRCAlPE>87K{oAQXG-%V?ypYqCHHNFh0e;>Hvj=`2Ib&8`1&V!kqLssl~5{ zD~C)~8f^tcf;GDvPZTC_P}i_$vksd08F~%01U9wVG@Pvwng3n%MMJ&DI1S8E z42eRhys-`IC7ZW*4sv&9cshxp@1LJ93ZqB~Ie>kN13frueF-SI0vIRLe=U2Uq2rYC z6V3anW*fycymgB(=8ulqYFJ5@dKhcMy+J_j00azrtk%PlYYJRlAoB3<)wuH#^s|p^ zKF>?O5J>kYg4@mPyjDKKoDVm#u#kgL{mJ&5tdeJF#S6*7pHfbCyf^%Bm@B-w!;D7e z;oDC)j4lKZOavB_VHqLqv7rEpB1G{v(Y(a7z#8^4;~gEe4Ufi86T>CgutJ&V@hWBc zewjW|Fw`2biTCBiFJB(2#R(-bTJRP6$aXek>UkW$FFC zd4#MiM6@`hJC7KPN3iW}i!n#WLJjYiI?C0>s;E{eAgD+C^8{E06MAkM@rrMu1~7iz zUr@zPzvXYsqBZb@#{hmLog=7s?7vl%&-Hpd0%eyZBdRuC5JM2UIO~H&7QLtzsqgqX z6kpcnO&-f7^8Iy%yZGkIbs!U;S6D(Q>(vXxf;MBo&T*f>EkP)h^!02hEWK60T<|#4 z+~bNYlvEPd_o`?SG_vKi%N@lGqBd1*FnnYd))$j?9ℑ%K(S7Qcxa6Z;y~Fk2%fC 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